ADR-0015 No Numba Runtime And Explicit NumPy Leaf Boundaries¶
语言: 简体中文
Status: Accepted
Date: 2026-10-10
Owners: Env / Manager / Training / Backend maintainers
Supersedes: None
Superseded by: None
Roadmap: Issue #2124
Context¶
ADR-0011 removed the NumPy environment lifecycle and ADR-0012 made the Manager runtime tensor-only. Two migration-era remnants nevertheless remain in UniLab:
G1 motion tracking still contains CPU/NumPy command kernels implemented with Numba. Importing the tensor motion terms also imports and configures those kernels, so even a tensor owner is not Numba-free.
Generic Manager, MDP, reset/event, entity-facade, and locomotion task paths still expose NumPy carriers and hidden Torch/NumPy conversions.
The current unisim-core base wheel has no Numba implementation or dependency.
Its body_state helper is intentionally NumPy-only. The only remaining source
of a Numba installation, after UniLab removes its direct requirement, is the
optional Genesis engine dependency. That transitive package dependency does not
make Numba part of UniLab’s or UniSim’s runtime contract.
Repository evidence at decision time:
Numba production imports:
src/unilab/tasks/motion_tracking/common/kernels.pyandsrc/unilab/base/cpu_runtime.py.Direct Numba requirements:
pyproject.tomlandpyproject.rocm.toml.NumPy is imported by 62 production Python files across Manager, env, task, utility, terrain, training, and visualization owners.
ADR-0012 requires Torch carriers for the Manager public lifecycle and allows NumPy only behind a host-bridge backend adapter boundary.
Decision¶
UniLab has no Numba runtime¶
UniLab production code must not import, compile, configure, tune, or transitively require Numba. In particular:
delete the G1 motion-tracking Numba kernels and their CPU command owner;
all G1 motion tracking production owners build the tensor command;
EnvCfg.cpu_idsowns Linux process and existing-thread affinity only;no generic runtime component calls
numba.set_num_threadsor interpretsNUMBA_NUM_THREADS.
The default and ROCm dependency profiles remove UniLab’s direct Numba requirement. A Genesis installation may still transitively contain Numba, but UniLab neither imports it nor takes responsibility for tuning its engine-private thread pools.
Legacy NumPy backend APIs are not UniLab runtime APIs¶
UniLab task, Manager, env, and training code must not consume legacy NumPy
SimBackend methods such as NumPy stepping/reset, base/body getters, or named
sensor data. CPU-authoritative exchange is negotiated through public tensor
lifecycle operations and packed host-bridge plans. UniSim 1.7.16 removed the
legacy public lifecycle without aliases; UniLab consumes the tensor/entity
replacement directly and its architecture gate rejects reintroduction.
NumPy is allowed only in explicit leaf owners¶
Outside the concrete CPU backend adapter, NumPy may appear only in:
the adapter-private host boundary, where CPU-authoritative backend adapters convert the public torch DR payloads into engine host formats (for example UniSim’s
unisim.dr._hosthelpers) and play APIs still exchange host formats;cold asset/materialization work, such as NPZ motion ingestion and terrain generation;
serialization and external interop, such as ONNX Runtime and diagnostic NPZ;
playback/rendering/visualization host formats.
Those leaves own their imports and conversions internally. They must not return mutable NumPy authoritative carriers to the Manager runtime or training hot path. Cold-path NumPy is not authorization for step/reset parsing, asset metadata branching, terrain regeneration, or host fallback dispatch.
Public reset and interval DR payloads are not NumPy leaves: since UniSim’s
torch-first DR payload decision (issue #2410) the public payload family
(TensorResetRandomizationPayload, TensorIntervalPayload) is torch-only,
and NumPy conversion exists only inside the adapter-private boundary above.
Stable Contracts¶
Contract |
Evidence owner |
|---|---|
Production source contains no Numba import or tuning |
architecture boundary tests |
Manager execution, terms, RNG, and row selectors are Torch-only |
Manager/env suites |
G1 motion production owners build the tensor command |
owner config tests |
|
CPU runtime tests |
Default and ROCm profiles have no direct UniLab Numba requirement |
dependency-profile tests and locks |
UniLab runtime does not call legacy NumPy backend APIs |
architecture/backend contract tests |
Remaining NumPy imports appear only in the explicit leaf allowlist |
architecture boundary tests |
Manager seed/reset reproducibility is Torch-RNG based |
reproducibility tests |
Alternatives Considered¶
Keep the CPU/NumPy motion command as a hidden fallback. Rejected: it preserves the NpEnv-era dual contract and forces every tensor owner to import Numba.
Let
EnvCfg.cpu_idstune any engine-private pool installed by an optional extra. Rejected: generic runtime code would depend on an unrelated engine implementation and could not define a stable failure policy.Allow NumPy throughout task and Manager code while merely deleting Numba. Rejected: hidden host conversions and dual term branches would continue to spread and violate ADR-0012.
Preserve a compatibility layer for legacy NumPy backend APIs. Rejected by the roadmap decision: the replacement is a deliberate breaking boundary.
Consequences¶
CPU
MotionCommandand its Numba kernels disappear without aliases.Existing NumPy-stream runs are not bit-compatible with Torch-RNG runs.
Backend work that still lacks a public packed tensor replacement fails closed rather than falling back to a NumPy path.
Genesis is not considered production runtime support merely because its extra transitively installs Numba.
Review rejects new Manager/task NumPy imports,
.numpy()hot-path conversions, andtorch.from_numpycompatibility bridges outside the allowlisted leaf owners.
Evidence In Repo¶
Historical Numba kernels: removed by this decision; the path
src/unilab/tasks/motion_tracking/common/kernels.pyno longer exists and is intentionally not cited as current evidence.Current NumPy leaf boundaries:
src/unilab/tasks/motion_tracking/common/manager_terms.py,src/unilab/tasks/motion_tracking/common/motion_loader.py,src/unilab/tasks/motion_tracking/common/tensor_sampler.py, andsrc/unilab/base/cpu_runtime.pysrc/unilab/envs/manager_based_rl_env.pysrc/unilab/managers/pyproject.tomlpyproject.rocm.tomltests/tasks/test_package_boundary.py