JobRegistry & the Sub-Tool Process Model
All symbols, byte offsets, and addresses on this page apply to
neuronx_cc2.24.5133.0+58f8de22 (cp310 Cython modules underneuronxcc/driver/, build root/opt/workspace/KaenaCompilerNativeBuild-310/build/private/src-3.10.16). The Job classes are*.cpython-310-x86_64-linux-gnu.soELF — not stripped, withdebug_info— so method-level reconstruction is from__pyx_*interned constants, qualnames, and disasm. Other wheels differ; treat every address as version-pinned.
Abstract
A neuronx_cc compile is a sequence of Jobs. 3.3 describes how CompileCommand.buildPipeline concatenates three collectors into an ordered list of job-name strings; this page describes the other half: how JobRegistry turns each name into a Job instance, and how each instance actually runs — either in-process (pure Python/Cython, no fork) or by spawning a standalone tool ELF out of neuronxcc/starfish/bin/ and waiting on it.
Two mechanisms carry the whole model. First, discovery: JobRegistry.loadAllJobs walks neuronxcc.driver.jobs with pkgutil.iter_modules, and JobRegistry.__getJobFactory imports each module wrapped in sys.setdlopenflags(... | RTLD_DEEPBIND) — a per-job dlopen flag that lets every job .so carry its own statically-linked copy of XLA/penguin/walrus symbols without clashing in the one process. Second, resolution + spawn: a native-spawning Job stores only a bare tool name (e.g. walrus_driver); Job.getFullyQualifiedLocation resolves it with shutil.which over starfish/bin/private then starfish/bin (private searched first), and Job.shellCommand runs the resolved path through subprocess.Popen.
Of the eleven shipped Job classes, exactly seven spawn a native tool (HLOToTensorizer, WalrusDriver, BIRVerifier, NeffWrapper, XLAInferGoldens, Backend, Watchpoint) and the rest run in-process (Frontend, StaticIOTranspose, Kelper, SaveTemps). The private/ search arm is a dormant hook: no shipped Job names a tool that lives only there — in this build it holds a single GoogleTest harness that no Job invokes. That dormancy is a structural finding, tagged below.
| Registry class | JobRegistry — neuronxcc/driver/JobRegistry.cpython-310…so (BuildID 4949b3ac… family; not stripped) |
| Base class | Job / SingleInputJob — neuronxcc/driver/Job.cpython-310…so (22 methods) |
| Discovery | JobRegistry.loadAllJobs @ 0x14390 → pkgutil.iter_modules over neuronxcc.driver.jobs |
| Per-job dlopen | JobRegistry.__getJobFactory @ 0x10c00 → getdlopenflags / setdlopenflags(│RTLD_DEEPBIND) / import_module |
| Bin resolver | Job.getFullyQualifiedLocation @ 0x242e0 → shutil.which(path=pathsep.join([…/private, …/bin])) |
| Spawn | Job.shellCommand @ 0x1bed0 → subprocess.Popen(stdout=PIPE, …, shell=False) |
| Native-spawning Jobs | 7: HLOToTensorizer, WalrusDriver, BIRVerifier, NeffWrapper, XLAInferGoldens, Backend, Watchpoint |
| In-process Jobs | 4: Frontend, StaticIOTranspose, Kelper, SaveTemps |
| Native tools dir | neuronxcc/starfish/bin/ (+ dormant starfish/bin/private/) |
1. The two execution classes
Every Job ultimately runs through Job.run → runOnState → runSingleInput (Job.so). What differs is what runSingleInput does per input: build an argv and fork a tool, or call into a Cython/Python routine in this same process. The split is structural and visible in the binary — a native-spawning Job references both getFullyQualifiedLocation (to resolve the tool) and a Popen/shellCommand site; an in-process Job references neither.
The reference count is unambiguous. Grepping each driver/jobs/*.so for the resolver and the spawn primitive:
Job getFullyQualifiedLocation refs spawn refs ⇒ class
HLOToTensorizer 3 3 native
WalrusDriver 3 3 native
BIRVerifier 3 3 native
NeffWrapper 3 3 native
XLAInferGoldens 3 3 native
Backend 3 3 native (experimental)
Watchpoint 3 3 native (debug)
StaticIOTranspose 0 0 in-process
SaveTemps 0 0 in-process
Kelper 0 3 (import) in-process†
Frontend 0 3 (import) in-process†
GOTCHA — "references
subprocess" ≠ "spawns a tool".KelperandFrontend(†) each carry a handful ofsubprocesssymbol references, but zerogetFullyQualifiedLocationreferences and noPopen/shellCommandcall site of their own — thesubprocesshits are module-level imports, not native-tool spawns. The discriminating evidence isgetFullyQualifiedLocation: only the seven native Jobs call it. A reimplementer must classify by the resolver call, never by animport subprocessline. (Confidence HIGH — ref counts read directly off the.soliteral pools.)
In-process Jobs — what they do without forking
| Job | In-process work (verbatim symbols) | Inputs → Outputs |
|---|---|---|
Frontend | runs the penguin / XLA HLO frontend: runPenguin, runXLAFrontend, neuronxcc.starfish.penguin.Penguin — writes HH-IR (Generated HH IR key), merged tensor map, static io_transposes. No hlo-opt/opt-driver/Popen string exists in Frontend.so. | input HLO → HH-IR key, penguin partitions, *.kelp, merged tensor map |
StaticIOTranspose | dumpTransposedFiles / simplifyWeightTransform / link_root_npys_to_sg — emits io_transposes.json via Python json | penguin io_transpose map → per-sg io_transposes.json |
Kelper | assembles the NEFF/kelf: genKelfFiles, add_{pwp,dve,one_pwp,ucode_lib}_files, addKelpHeader, calcNeffVersion, computeKelpMetrics | per-sg neff.json, def.json, pwp/dve ucode → final NEFF + kelf metrics |
SaveTemps | run copies temp files when isUsingTemp | work dir → preserved temps |
CORRECTION (vs S2-01 §3 call tree) —
Frontenddoes not spawnhlo-opt. An earlier call tree claimedFrontend.so → hlo-optandStaticIOTranspose.so → io_transpose JSON produceras native handoffs. Both are false in this binary:Frontend.so's only frontend symbols arerunPenguin/runXLAFrontend/Penguin(verified: 4 / 15 / 5 references; zeroPopen, zerogetFullyQualifiedLocation), andStaticIOTransposewritesio_transposes.jsonwith Pythonjson. Thehlo-optELF ships instarfish/bin/but no Job in this driver invokes it. (Confidence HIGH.) 3.3 reads theFrontendrow of the pipeline table ashlo-opt (--passes=…); that describes the conceptual HLO-optimization stage, not a fork fromFrontend.so— the two pages are consistent once the in-process detail is separated from the IR-descent label.
2. The job table — name → class → tool → resolver
Each native-spawning Job stores its tool basename as a __pyx_n_s_* / __pyx_k_* interned literal in its own .so. The basenames below are read straight from those literal pools.
| Job class | Native tool (basename literal) | argv built by | spawn site | Gate |
|---|---|---|---|---|
HLOToTensorizer | hlo2penguin | own subprocess.Popen (STDOUT-merged, universal_newlines) | proc h2p_proc | always |
WalrusDriver | walrus_driver (or in-proc libwalrus.so) | base shellCommand (×3) | ./sg%02d/ per subgraph | always |
BIRVerifier | walrus_driver (verify-only) | base shellCommand (×3) | — | unless --internal-disable-birverifier-validation |
XLAInferGoldens | xla_infergoldens | base shellCommand (×3) | — | framework-gated |
NeffWrapper | hlo-neff-wrapper | own subprocess.Popen (STDOUT-merged) | proc neff_wrapper_proc | --enable-internal-neff-wrapper |
Backend | nn_executor (main) + kgraph2dot (SVG only) | base shellCommand (×3) | ulimit -t … && nn_executor … | --enable-internal-new-backend / --enable-experimental-bir-backend |
Watchpoint | watchpoint_insert | base shellCommand (×3) | — | --mode-gated (debug) |
CORRECTION (vs D-A06 §9.3) —
Backend's main executable namenn_executorIS a literal. The earlier report readnn_executoras a config-driven local var with "no__pyx_n_u_string". InBackend.cpython-310…soit is present as both__pyx_n_s_nn_executorand__pyx_k_nn_executor— an interned identifier and a raw string constant. The samenn_executorbasename also appears inWalrusDriver.so. SoBackend's argv (ulimit -t <sec> && nn_executor --bir backend.bir --tensor_map <…> --sunda --json <…> …, confirmed by thebackend.bir/--sunda/ulimitliterals) names a concrete tool — it merely is not shipped in this wheel'sstarfish/bin/. (Confidence HIGH — string presence is direct.)
NOTE — three of the seven native tools are absent from this wheel.
starfish/bin[/private]ships onlywalrus_driver,hlo2penguin,hlo-neff-wrapper,xla_infergoldens,hlo-opt,snapshot-unpack,coloring_allocator_with_loop,full_unroll,walrus_bugpoint_driver(+private/tensor_indirect_test).nn_executor,kgraph2dot, andwatchpoint_insertare not present, soBackend(new-backend path) andWatchpoint(debug) would failgetFullyQualifiedLocation("Could not find …") unless an internal build drops those bins in. They are experimental/debug Jobs, off by default. See 3.6/3.7 for the four production tools' internals.
HLOToTensorizer and NeffWrapper are the two Jobs that do not route through the base shellCommand — each opens its own subprocess.Popen with stderr=STDOUT merged and universal_newlines=True. The other five native Jobs share the base Job.shellCommand path (§4).
3. The bin resolver — Job.getFullyQualifiedLocation (private-first)
This is the single source of native-binary resolution. It is the only routine in the wheel that carries the two path constants u"starfish/bin" and u"starfish/bin/private" (Job.so is the sole binary holding them). The decompiled call sequence at 0x242e0 is, in order: getPackageDir → get_exec_path → os.path.join → os.pathsep → os.path.join → shutil.which.
# Job.getFullyQualifiedLocation (pyx_pw_…_21getFullyQualifiedLocation @ 0x242e0)
# locals: relPath, packageDirectory, pathDirectories
def getFullyQualifiedLocation(self, executableLocation):
relPath = executableLocation
if os.path.isabs(relPath):
return relPath # absolute → use as-is
packageDirectory = self.getPackageDir() # dir of neuronxcc package, via __file__
pathDirectories = [
os.path.join(packageDirectory, "starfish/bin/private"), # SEARCHED FIRST
os.path.join(packageDirectory, "starfish/bin"),
]
found = shutil.which(relPath, path=os.pathsep.join(pathDirectories))
if found is None:
raise CompilerInvalidInputException("Could not find " + relPath)
return found
The two os.path.join calls (disasm 0x24700, 0x248a1) bracket the single os.pathsep load (0x24860), and exactly one shutil.which follows (0x24943) — matching "build two dirs, join with os.pathsep, run one which." On miss the routine loads __pyx_kp_u_Could_not_find (0x25b38) and raises.
STRONG —
private/is searched beforestarfish/bin. The ordering is fixed by the Cython string-pool layout. Cython lays out__pyx_k_*raw-string constants in first-textual-use order, and the data-section symbol addresses settle it:__pyx_k_starfish_bin_privateresides at0x35d90,__pyx_k_starfish_binat0x363f8—privateis emitted first, so it is the first element ofpathDirectoriesand the first segment of theos.pathsep-joinedwhichpath. The raw string bytes corroborate (starfish/bin/privateat file offset220560<starfish/binat222200). Ashutil.whichscans itspathleft-to-right and returns the first hit, so any tool present in both dirs resolves out ofprivate/—privateoverrides the shipped tool.
CORRECTION (reconciles D-A10 §3) — the resolver is
which-over-a-joined-path, not a manualos.path.existsloop. A sibling inventory pass (D-A10) reconstructedgetAbsPathasfor d in ["starfish/bin","starfish/bin/private"]: if os.path.exists(...)— i.e. bin-first, hand-rolled. The actualgetFullyQualifiedLocationbody disproves both halves: it referencesshutil/which/pathsep/get_exec_path(4 / 5 / 4 / 4 times respectively inJob.so) — ashutil.whichover a singleos.pathsep-joined string — and the constant ordering makes it private-first.getAbsPathis a different method (§4) that normalizes user-supplied command-line paths against the launch directory; it is not the bin resolver. (Confidence HIGH — disproved by symbol presence + the0x242e0call sequence.)
NOTE — the build-root string is not a runtime path.
Job.soalso embeds/opt/workspace/KaenaCompilerNativeBuild-310/build/private/src-3.10.16— that is the Cython-embedded build-machine source root, not a search directory. Do not conflate its…/private/…substring with thestarfish/bin/privateruntime arm.
getPackageDir / getAbsPath — the two path helpers it leans on
Both are docstring-confirmed in Job.so:
getPackageDir("Return full path of neuronxcc python package, e.g. to access data files") — derives the package root from__file__viadirname, giving the prefix the twostarfish/bin*segments hang off.getAbsPath("Returns an absolute path for paths and filenames specified on the command line … relative to the neuronx-cc launch directory, not the CWD which changes during execution") — usesgetLaunchDir/isabs/join. This is for user paths (the CWD changes as the driverchdirs intosg%02d/dirs), and is unrelated to tool resolution.
4. The spawn — Job.shellCommand → Popen
Five of the seven native Jobs (WalrusDriver, BIRVerifier, XLAInferGoldens, Backend, Watchpoint) reach the child through the shared base Job.shellCommand (0x1bed0). Its keyword surface and call shape are read from the expose_stderr / propagate_exit / useShell / close_fds / communicate / Popen literals in Job.so.
# Job.shellCommand (pyx_pw_…_25shellCommand @ 0x1bed0; nested log_fn @ 0x16760)
def shellCommand(self, cmd, *, env=None, useShell=False,
expose_stderr=False, propagate_exit=True, use_logger=True):
self.log("Executing " + cmd) # also "Working directory is " + cwd
args = ["/bin/bash", "-c", cmd] if useShell else cmd
proc = subprocess.Popen(args,
stdout=subprocess.PIPE,
stderr=(subprocess.STDOUT if expose_stderr else subprocess.PIPE),
stdin=…, close_fds=…, env=env, shell=False)
out, err = proc.communicate()
if propagate_exit and proc.returncode != 0:
raise CalledProcessError(...) # 'Child process job "%s" exited abnormally!'
return out, err
Anchored literals: "Executing ", "Working directory is ", /bin/bash (the useShell wrapper, e.g. for Backend's ulimit -t … && nn_executor …), "Child process job \"%s\" exited abnormally!", and four CalledProcessError references.
- No per-Job env vars. Confirmed negative: no Job sets a bespoke
os.environ[...]=beforePopen; children inheritos.environ. (The daemon's process-wideOMP_NUM_THREADS=1stands, but it is set outside any Job.) shell=Falsealways. Even theuseShellbranch passes an explicit["/bin/bash","-c",cmd]argv withshell=False— there is noshell=Trueinjection surface.- Replay.
Job.getReplayCommandLine(nestedaddquotes,0x15c70) re-quotes the same argv withshlex.quoteand emits'Replay this job by calling: %s %s'— the source ofreplay_walrus.sh.
For the full per-Job argv templates (the ~200-flag walrus_driver corpus, the hlo2penguin flag set, etc.), see 3.5.
5. Discovery & per-job dlopen — JobRegistry
JobRegistry.__init__ (0xf200) builds a collections.defaultdict-with-key map job_factories whose __missing__ (the nested default_dict_with_key) raises a keyed error for unknown job names, then runs discovery. Discovery is two methods working together: loadAllJobs enumerates module names, and __getJobFactory does the actual RTLD_DEEPBIND-wrapped import per name.
# JobRegistry.loadAllJobs (pyx_pw_…_1loadAllJobs @ 0x14390)
def loadAllJobs(self):
pkg = neuronxcc.driver.jobs # via importlib.util / find_spec
for _, modname, is_pkg in pkgutil.iter_modules(pkg.__path__):
if modname in self.rejected_job_names: # skip rejects
continue
self.__getJobFactory(modname) # ← the per-job import
# JobRegistry.__getJobFactory (pyx_pw_…_3__getJobFactory @ 0x10c00)
def __getJobFactory(self, name):
old = sys.getdlopenflags()
sys.setdlopenflags(old | os.RTLD_DEEPBIND) # isolate native .so symbols
try:
mod = importlib.import_module("neuronxcc.driver.jobs." + name)
self.log.debug("Found " + name + " at " + inspect.getfile(mod))
except ImportError as exception:
sys.setdlopenflags(old) # restore on failure
warning("Could not import '" + name + "'"); return None
finally:
sys.setdlopenflags(old) # restore on success
for cls in inspect.getmro(...): # walk to the Job subclass
...; cls.RegisterArgs(...) # register --<job> argparse switches
self.job_factories[name] = cls
return cls
CORRECTION (vs D-A06 §8) — the
RTLD_DEEPBINDdance lives in__getJobFactory, notloadAllJobs. D-A06 placed thesetdlopenflags(│RTLD_DEEPBIND)wrap around the wholeloadAllJobsenumeration loop. The binary puts it inside__getJobFactory(0x10c00): that method's interned-symbol stream is, in order,getdlopenflags → setdlopenflags → RTLD_DEEPBIND → "neuronxcc.driver.jobs." → import_module → getfile → "Found"/"at" → "Could not import" → setdlopenflags (×2 restore).loadAllJobsitself references no RTLD/setdlopenflagssymbol — it only carriesfind_spec/get_filename/iter_modulesand a call toJobRegistry__getJobFactory. So the deep-bind flag is toggled per job import (set → import → restore), threesetdlopenflagssites in all (set-deepbind, restore-on-success, restore-on-except). The effect is the same — each job.sois dlopened underRTLD_DEEPBIND— but the scope is per-job, not per-loop. (Confidence HIGH — the symbol stream is read directly from__getJobFactory's disasm.)
RTLD_DEEPBIND makes the dynamic linker prefer a loaded object's own symbol definitions over already-loaded globals. Each driver/jobs/*.so statically links its slice of XLA / penguin / walrus C++ symbols; without deep-bind, the first job loaded would export those globals and later jobs would silently bind to the wrong copy. With it, every job's import is symbol-isolated. This is why the jobs can be Cython .sos with overlapping statically-linked C++ surfaces in one Python process.
The rest of the registry is name→instance plumbing:
| Method | Role |
|---|---|
__getJobFactory / __getJob | name → factory → instance; raises CompilerInvalidInputException / "Could not import '" on miss |
makePipeline(names) | neuronxcc.driver.Pipeline([self.__getJob(n) for n in names]) |
RegisterArgs | argparse --<job> switches; Input files / is an input metavars |
6. The dormant private/ branch — structural finding
The starfish/bin/private arm of getFullyQualifiedLocation (§3) is a latent extension point that never fires in this build. The evidence chain:
starfish/bin/ → 6 pipeline ELF + small backend tools + 4 .py helpers
starfish/bin/private/ → EXACTLY ONE file: tensor_indirect_test (8,902,064 B, stripped ELF)
tensor_indirect_test is a GoogleTest unit-test harness for the walrus dynamic-DMA / TensorIndirect access-pattern backend (source neuronxcc/walrus/bir_sim/test/tensor_indirect_test.cpp; gtest fingerprints "All tests in the same test suite must use the same test fixture", "--gtest_filter="; system-under-test symbols assignIndirectPattern<…INDIRECT12B/16B/20B>, LowerDMAImpl::createDescForReadVarAddr, generateDynamicDMA). It links the backend simulator stack (libBIRSimulator.so, libpwp_sim.so, libBIR.so) via two-level RUNPATH $ORIGIN/../../lib — consistent with living one directory deeper than bin/.
STRONG (structural finding) — no shipped Job resolves into
private/. All four production native tools (hlo2penguin,walrus_driver,hlo-neff-wrapper,xla_infergoldens) live in plainstarfish/bin/and resolve on the first existing matchwhichfinds — which, even with private searched first, lands inbin/because none of them exists inprivate/. None of{tensor_indirect_test, bir_roundtrip, nki_klr_sim, loop_optimization, sb_size_legalization}appears as anexecutableLocationliteral in anydriver/jobs/*.so. Therefore theprivate/search arm is dead in this build — a dormant hook, most plausibly for internal AWS builds that drop additional gated bins there so they override the shipped ones (per the private-first ordering of §3). The single file actually underprivate/is a test binary the compile pipeline never executes. (Confidence: CERTAIN thatprivate/holds onlytensor_indirect_testand that no Job names a private-only tool — both are direct directory + literal-pool reads; INFERRED for the intent "extension point for internal builds.")
NOTE — the four "phantom" dev tools are not in
private/.bir_roundtrip,loop_optimization,sb_size_legalization,nki_klr_simlive in the wheel data-payloadneuronx_cc-2.24.5133.0+58f8de22.data/data/bin/(pip-installed onto$VENV/bin/), reachable only via the venv PATH, never via the Job machinery.loop_optimizationandsb_size_legalizationare alsoBackendPassgenerators compiled intolibwalrus.so(register_generator_loop_optimization,register_generator_sb_size_legalization); the standalone bins are thin CLI front-ends. None is pipeline-invoked.
7. Reimplementation contract
To rebuild this layer, a reimplementer needs:
- A
Jobbase exposinggetPackageDir(package root from__file__),getFullyQualifiedLocation(name)(the private-firstshutil.whichof §3, raising"Could not find "on miss),shellCommand(cmd, *, env, useShell, expose_stderr, propagate_exit, use_logger)(thePopenof §4, alwaysshell=False, inherited env), andgetReplayCommandLine(shlex.quotereplay). - Eleven Job subclasses split into the seven native-spawning (each storing one tool basename and routing through
shellCommand, exceptHLOToTensorizer/NeffWrapperwhich own theirPopen) and the four in-process (Frontend/StaticIOTranspose/Kelper/SaveTemps, calling Cython/Python directly with no fork). - A
JobRegistrywhoseloadAllJobsdoespkgutil.iter_modulesoverneuronxcc.driver.jobs(honoringrejected_job_names) and whose__getJobFactoryimports each module wrapped insetdlopenflags(│RTLD_DEEPBIND)(set → import → restore, per job), indexing theJobsubclass into a key-raisingdefaultdictjob_factories, plusmakePipeline(names)building aPipelineof instances. - The dormant private arm kept as the first
pathDirectoriesentry, even though no shipped Job uses it — to preserve the override semantics for gated internal bins.
Cross-references: 3.3 — the CompileCommand pipeline (who builds the name list); 3.5 — sub-tool argv templates (the full per-Job flag corpus); 3.6 / 3.7 (the four production tool ELFs' internals).