Repository navigation
perf: end-to-end MJWarp training throughput gate and tensor-native closeout #2023
Description
perf: end-to-end MJWarp training throughput gate and tensor-native closeout
Objective
Close the remaining #1811 runtime work using end-to-end training throughput as the decisive performance gate. The canonical production behavior is the real uv run train path—not a collector-only microbenchmark and not a final single iteration.
Canonical workloads
Both workloads are mandatory and run on MJWarp:
- FlashSAC /
g1_motion_trackinguv run train \ --algo flashsac \ --task g1_motion_tracking \ --sim mjwarp
- SAC /
g1_walk_flatuv run --extra mjwarp train \ --algo sac \ --task g1_walk_flat \ --sim mjwarp
Measurement contract
The acceptance metric is the new runner-owned:
run_summary.json:tail_env_steps_per_sec
from unilab-rl #74.
Definition:
sum(env steps represented by the final 20 completed training iterations)
/
sum(wall time of those iterations)
Rules:
- It is an aggregate-rate over one bounded window, not the mean of per-iteration rates.
- The window is 20 iterations: large enough to suppress single-iteration jitter, small enough not to extend development loops.
- Startup, backend materialization, Torch compilation, graph capture, replay fill, and first-update warm-up are excluded.
- Existing
final_env_steps_per_secis diagnostic only and is not acceptance evidence. - Collector scripts under
scripts/benchmarkare diagnostic attribution tools only. They must never replace the end-to-end train gate.
Current local feasibility evidence
Local RTX 4090, 160 iterations, 2048 envs, no playback/ONNX, CUDA_VISIBLE_DEVICES unset:
| Workload | tail steps/s | final-iter steps/s |
|---|---|---|
FlashSAC / g1_motion_tracking / MJWarp |
104,652 | 104,797 |
SAC / g1_walk_flat / MJWarp |
96,383 | 82,203 |
This proves the metric is feasible and demonstrates why the final iteration is unsuitable: SAC's final iteration reports 82k while its bounded tail is 96k.
Artifacts: /tmp/flashsac-tail-contract/run_summary.json and /tmp/sac-tail-contract/run_summary.json.
Acceptance targets
Local workstation
- Local results establish feasibility and guide optimization.
- FlashSAC motion already exceeds 100k steps/s.
- SAC walk must reach ≥100,000 tail steps/s.
592 / RTX 5090 server
Both canonical workloads must reach:
tail_env_steps_per_sec >= 100,000
A performance claim requires repeated interleaved end-to-end training runs under the same contract. A single run is not acceptance evidence.
Backend and architecture scope
Active runtime scope:
mjwarpmujoco
Shelved for this effort:
- Genesis
- all other adapters
Non-negotiable runtime invariants
The following must remain true after every change:
- Manager-Based API is the sole training entry point.
- No direct environment mode.
- No task-owned direct runtime registration.
- No rollback to a generic NumPy Manager.
- No rollback to a NumPy RNG owner.
- The Manager-owned Torch RNG remains authoritative.
- No re-introduction of
env.tensor_runtime/env.tensor_runtime_device.- Placement is derived from actual public env carrier placement and backend capabilities.
- No backend-private probing from task/env/training code.
- Backend behavior must remain behind declared
SimBackendpublic capabilities/APIs.
- Backend behavior must remain behind declared
- No compatibility layer or legacy NumPy owner path for MJWarp.
- Tensor-native is the only MJWarp execution path.
- NumPy is permitted only at the explicit MuJoCo HOST_BRIDGE D2H/H2D boundary.
- MJWarp owners must not use NumPy state carriers, NumPy reset composers, or host RNG reset paths.
Required tensor-native migration
A. g1_walk_flat host-composer removal
This is the primary architectural blocker and the nearest local performance gap.
Remove the NumPy host owner paths from the canonical MJWarp SAC owner:
UniformVelocityCommand/G1VelocityCommand- remove NumPy command mirrors such as
vel_command_b,vel_command_w,heading_target,heading_error; - remove NumPy
is_heading_env,is_standing_env,is_world_env,is_forward_envmasks; - remove selected-row D2H and
_host_uniformreset sampling; - execute resampling, dead-zone filtering, and update using Torch rows and Manager Torch RNG.
- remove NumPy command mirrors such as
G1GaitPhase.reset- remove selected-row D2H and NumPy RNG sampling;
- sample phases on the public device using Manager Torch RNG.
- Reset events
- replace canonical
reset_root_state_uniformandreset_scene_to_defaultusage with their tensor event peers; - remove the
origins_tensor.abs().max().item()hot-path synchronization by making origin applicability a cold-path owner fact or otherwise device-resident branch.
- replace canonical
G1PenaltyCurriculum/EpisodeLengthTracker- keep episode-length statistics and scaling device-resident during steady training;
- convert to host scalar only at the unavoidable reward-weight mutation boundary, and avoid doing so on every reset.
- G1 walk sensor/reward owners
- remove capability fallbacks that silently select a NumPy host reader on MJWarp;
- fail closed if a required sensor is absent from the public tensor read plan.
B. MJWarp motion owner residual cleanup
The FlashSAC motion owner is already largely tensor-native, but closeout must verify and, where needed, remove:
- legacy
MotionCommandbase-class NumPy methods still reachable from an MJWarp owner; - capability fallbacks that select host readers on a DEVICE_RESIDENT backend;
- remaining selected-reset NumPy row mirrors;
- reward/log host publication outside the interval-controlled collector contract.
C. Legacy path removal
No dormant MJWarp NumPy fallback should remain:
- remove unreachable NumPy execution branches for MJWarp owners rather than preserving them as compatibility;
- do not add an owner-level tensor/NumPy execution switch;
- do not preserve “legacy behavior” in config comments or runtime dispatch.
MuJoCo HOST_BRIDGE remains a production backend, so its public NumPy boundary is not a fallback and is not deleted.
Benchmark governance
scripts/benchmark must be updated to remain useful but subordinate to the end-to-end gate:
- mirror the canonical two-workload set;
- exclude warmup/compile;
- report a bounded tail aggregate rate;
- preserve detailed phase attribution for optimization decisions;
- clearly label results as diagnostic, not acceptance evidence.
Any benchmark change must not lengthen the canonical loop merely to produce a more impressive number.
Required validations
Each child PR must run the smallest relevant checks, and the final head must run the full gate.
Minimum final gates:
make check
make test
make test-all
Mandatory end-to-end runs:
uv run train \
--algo flashsac \
--task g1_motion_tracking \
--sim mjwarp \
algo.max_iterations=160 \
algo.num_envs=2048 \
training.no_play=true \
training.export_onnx=false
uv run --extra mjwarp train \
--algo sac \
--task g1_walk_flat \
--sim mjwarp \
algo.max_iterations=160 \
algo.num_envs=2048 \
training.no_play=true \
training.export_onnx=falseRecord for each run:
- UniLab commit
- unisim commit
- unilab-rl commit
- GPU and CUDA visibility
completed_iterationstotal_env_stepstail_env_steps_per_sectail_iteration_counttraining_wall_time_sec- run artifact path
Governance
- Integration branch:
dev/issue-1811-tensor-manager. - Do not modify
main. - Final integration target:
develop/tensor-runtime. - No PyPI release.
- Direct changes to local sibling repositories are authorized:
unisimunilab_rl
- Sibling changes require their own reviewable PR, tests, and linked evidence; they must not become hidden dependencies of a UniLab PR.
- Maintain ADR-0012 and the support matrix as scope and behavior change.
- Do not close this issue merely because local throughput improves. Server repeated end-to-end evidence and the tensor-native architecture boundary are both mandatory.
Success criteria
- MJWarp tensor-native is the sole execution path for both canonical tasks.
- No canonical MJWarp owner uses a NumPy host composer, host RNG reset path, or hidden NumPy state mirror.
- Local SAC /
g1_walk_flat/ MJWarp reaches ≥100,000 tail steps/s. - 592 / RTX 5090 repeated runs show both canonical tasks at ≥100,000 tail steps/s.
- Diagnostic benchmarks mirror the end-to-end contract and clearly remain non-acceptance tools.
-
make check,make test, andmake test-allpass on the final head. - Both canonical 160-iteration training runs complete with normal shutdown and no residual collector process.
- Manager-only factory, scoped backends, tensor-switch removal, Torch RNG owner, and no-direct-mode invariants remain intact.
- Documentation, ADR-0012, and generated support matrix reflect the final runtime.
Part of #1811 closeout.
Activity
TATP-233 commentedon Oct 3, 2026
Merged tensor-native velocity command: #2024 —
perf(velocity): make command owner tensor-native(headb200ed24; integration merge990cbb01).Change
UniformVelocityCommandno longer owns NumPy state mirrors:vel_command_b,vel_command_w,heading_target,heading_error;is_heading_env,is_standing_env,is_world_env,is_forward_env;_host_uniform, NumPy mask indexing, and full-width NumPy→Torch publication.It now owns Torch command/world/heading/mask carriers and uses device int64 rows. With the Manager Torch RNG, resampling and mask sampling are fully device-resident.
RoughVelocityCommandalso loses its legacy NumPy fallback.The only remaining NumPy RNG branch is the explicit CPU/HOST_BRIDGE reference fallback when
env.torch_rngis absent; it uploads once directly to the owner carrier and does not keep a hidden NumPy owner mirror.Correctness
make check: passed.Local end-to-end tail-throughput result
Both canonical workloads, 160 iterations, 2048 envs, no playback/ONNX, CUDA mask unset:
g1_motion_tracking/ MJWarpg1_walk_flat/ MJWarpArtifacts:
/tmp/flashsac-tensor-command-check/run_summary.json/tmp/sac-tensor-command/run_summary.jsonBoth canonical local gates now exceed the 100,000
tail_env_steps_per_sectarget. This is a single local run, not server acceptance evidence; repeated 592 runs are still required.TATP-233 commentedon Oct 3, 2026
Merged tensor-native G1 walk reset events: #2025 —
perf(walk): select tensor reset events on mjwarp(head645e47ec; integration merge3079216c).Change
All G1 walk MJWarp owners now select the tensor reset events:
Covered owners: SAC, FlashSAC, PPO, WarpSAC.
The tensor root event's immutable-origin applicability is now resolved once on cold-path origin-table materialization and cached as a boolean. The prior hot-path
origins_tensor.abs().max().item()synchronization is removed. MuJoCo retains its explicit HOST_BRIDGE NumPy reset boundary.Correctness
make check: passed.Local end-to-end gate
SAC /
g1_walk_flat/ MJWarp, 160 iterations, 2048 envs:Artifact:
/tmp/sac-tensor-reset-events/run_summary.json.The local gate remains above 100k. No server or repeated-run claim is made.
TATP-233 commentedon Oct 3, 2026
Merged tensor-native G1 gait phase reset: #2026 —
perf(gait): make phase reset tensor-native(head0988f13c; integration merge8a77a5663).Change
The shared G1 gait phase carrier is now always a Torch tensor on the environment device. Reset uses device int64 rows, Manager Torch RNG sampling, and direct
index_copy_; it no longer converts selected rows to NumPy or uploads host-built phase samples.The explicit CPU/HOST_BRIDGE reference fallback remains for owners without Torch RNG and uploads selected rows once to the public phase carrier. HOST_BRIDGE gait rewards convert shared Torch phase targets once at their public NumPy sensor boundary.
Correctness
make check: passed.Local end-to-end gate
SAC /
g1_walk_flat/ MJWarp, 160 iterations, 2048 envs:The variation is within the single-run local band and remains above the 100k target. No server or repeated-run claim is made.
TATP-233 commentedon Oct 3, 2026
Merged tensor-native G1 penalty curriculum: #2027 —
perf(curriculum): track episode lengths on device(headcdef9765; integration mergee4b0aa5c).Change
EpisodeLengthTrackernow stores its recursive weighted average as a float64 Torch scalar on the environment device.G1PenaltyCurriculumselects done rows on device, updates without per-reset D2H, removes the NumPy episode-length fallback, and publishes one host scalar per curriculum update. That publication is required because reward weights remain public Python floats.Correctness
make check: passed.Local end-to-end gate
SAC /
g1_walk_flat/ MJWarp, 160 iterations, 2048 envs:Artifact:
/tmp/sac-tensor-curriculum/run_summary.json.No server or repeated-run performance claim is made.
TATP-233 commentedon Oct 3, 2026
Merged DEVICE_RESIDENT sensor fail-closed negotiation: #2028 —
fix(env): fail closed on missing device tensor sensors(head15a4931f; integration merge027c29f4).Change
Declared
tensor_sensor_nameson observation, command, reward, and termination terms are now mandatory on DEVICE_RESIDENT backends. Names absent from the audited public tensor-sensor set fail at read-plan construction with an explicitNotImplementedErrornaming backend, missing sensors, manager, and term.Previously unavailable names could be filtered from the read plan, after which a term's hot path silently selected its host/cache reader. That hidden NumPy fallback is removed for MJWarp and other DEVICE_RESIDENT runtimes. HOST_BRIDGE negotiation remains explicit and unchanged.
Correctness
make check: passed.g1_walk_flat/ MJWarp completed normally at 99,638 tail steps/s, confirming all canonical task sensor declarations are satisfied.No server performance claim is made.
TATP-233 commentedon Oct 3, 2026
Merged diagnostic benchmark tail throughput: #2029 —
perf(benchmark): report diagnostic tail throughput(head49288cf6; integration merge613c21d8).Change
scripts/benchmark/rl/benchmark_offpolicy_collector_active.pynow reports an aggregate bounded-tail rate:Controls/outputs:
--tail-steps(default 20, clamped to measure steps);tail_step_count;tail_active_steps_per_sec;tail/s=<rate>(<count>);This mirrors the runner-owned aggregate-tail definition while remaining explicitly diagnostic. It does not replace end-to-end training
tail_env_steps_per_secas the acceptance gate.Correctness
make check: passed.Local diagnostic run
SAC /
g1_walk_flat/ MJWarp, 2048 envs, warmup 10 / measure 100 / tail 20:Artifact:
/tmp/bench-tail2/results.{json,csv}.TATP-233 commentedon Oct 3, 2026
Merged G1 walk fused tensor reset owner: #2030 —
perf(walk): fuse G1 tensor reset owner(headaae38031; integration merge70b2a50e).Change
The MJWarp SAC G1 walk owner now uses a Manager-owned
G1WalkResetOwner:reset_command_statewithpublish_metrics=false;UniformVelocityCommandand the Manager Torch RNG is present.No NumPy owner, host RNG reset path, compatibility layer, or backend-private probe was added.
Correctness
make check: passed.Diagnostic reset attribution (local 4090; non-acceptance evidence)
reset_done_msmeanServer baseline
Before #2030, repeated 592/RTX 5090 160×2048 end-to-end runs under the new contract completed at:
Commits: UniLab
613c21d8, unisim2eb70e9, unilab-rl72a50b3;CUDA_VISIBLE_DEVICES=0.TATP-233 commentedon Oct 3, 2026
592/RTX 5090 result after #2030
UniLab
70b2a50e, unisim2eb70e9, unilab-rl72a50b3,CUDA_VISIBLE_DEVICES=0, 160 iterations × 2048 envs.SAC /
g1_walk_flat/ MJWarp completed at 66,527.91 tail env steps/s (baseline band 65,715–65,900).The PR improves local fast-host reset dispatch substantially but does not close the server gap. Diagnostic collector attribution on the same server shows:
reset_done_msThe remaining server reset time is not primarily generic Manager dispatch:
set_state: ~1.31 ms.The much larger end-to-end deficit is the learner/collector overlap profile: training remains around 66.5k while the collector-only hot loop is around 106k. The next required attribution is therefore the end-to-end iteration phase breakdown on 592, not another generic Manager micro-optimization.
TATP-233 commentedon Oct 3, 2026
End-to-end 592 phase attribution and #2031
Attribution method
Analyzed the runner TensorBoard event files from the three repeated 592/RTX 5090 baseline runs and compared them with local RTX 4090 runs under the same head and workload.
Server-specific SAC bottleneck
Tail mean, SAC /
g1_walk_flat/ MJWarp:The server CPU is not uniformly slow: it is substantially faster in backend wall time, but the full-width indexed control publication costs ~11 ms there versus ~0.5 ms locally.
Fix
#2031
perf(action): bypass indexed full-width control write(head579aee43; integration mergec40b5e21).Entity._write_tensor_ctrlnow recognizes the exact full-width case—all rows, all configured entity actuators, actuator order unchanged—and publishes through one contiguouscontrol.copy_(values). Partial/reordered writes retain the validated indexed path. Actuator IDs are cached once per device.Results
Local RTX 4090, 160×2048:
592/RTX 5090, 160×2048:
The server
apply_actiontelemetry did not improve as expected, so #2031 is retained as a correct full-width fast path but is not yet the decisive server fix. The remaining 592 SAC tail profile is approximately:Next attribution target is the call graph inside
apply_action: action-manager finite validation/history copies versusEntity.set_joint_position_targetand control publication.TATP-233 commentedon Oct 3, 2026
Refined 592 action-path attribution
Isolated CUDA action-operation benchmark on 592, RTX 5090, 2048×29 tensors, 1000 iterations after warmup:
isfinite(...).all()host checkindex_selectThis shows why
apply_actionremains ~11 ms per step on 592 and ~0.5 ms locally: the slow-frequency Xeon host pays roughly one CUDA launch/synchronization tax per small kernel and the canonical action path performs several small full-batch kernels plus host finite checks. The indexed control scatter was only one contributor; #2031's contiguous copy remains valid but cannot remove the other launch and synchronization points.The next optimization must reduce the number of separate action kernels/validations, not optimize one indexed write in isolation. Candidate direction is a fused tensor action boundary for the canonical full-width joint-position action:
ActionManager.process_actionand_write_tensor_ctrl;index_selectwhen the target order is contiguous;This requires a narrowly scoped owner change and explicit tests proving validation remains fail-closed.
TATP-233 commentedon Oct 3, 2026
Current execution head:
c40b5e21(#2030 + #2031). Remaining mandatory closeout: fused action-boundary optimization/re-attribution, Genesis scope reduction, final full test gate, repeated server acceptance runs, docs/ADR/support-matrix closeout.TATP-233 commentedon Oct 3, 2026
Merged device-resident encoder bias: #2032 —
perf(action): keep device encoder bias resident(headbb414129; integration mergee3dea302).Change
EntityData.encoder_bias_tensornow owns a persistent device-resident carrier when the entity has a Torch control plane.RandomizeEncoderBiassamples selected rows/joints directly into that carrier using the Manager Torch RNG and no D2H. CPU/HOST_BRIDGE owners retain the existing NumPy carrier.Local validation
make check— passed592/RTX 5090 repeated runs after #2032
g1_walk_flatg1_motion_trackingTail phase means remain:
Important attribution correction: the canonical
g1_walk_flatowner does not configureRandomizeEncoderBias, and itsJointPositionActionstill performs an encoder-biasindex_selectagainst the device carrier. The canonical FlashSAC motion owner does not configure the reset event either, but benefits from removing the per-action temporary.to(device)conversion. This explains the local/motion gain and the negligible SAC server gain.Next server-side targets remain SAC action-path kernel-count reduction and reset/update-state dispatch reduction; no server performance claim is made from #2032.
TATP-233 commentedon Oct 3, 2026
Merged single action finite boundary: #2033 —
perf(action): remove duplicate finite synchronization(heade67b9a2b; integration merge014d9b34).Change
ActionManager.process_actionremains the authoritative whole-action finite check. Affine action owners exposevalidate_actions()and no longer perform a second full-tensor host synchronization on their own slices. The motion latency owner validates the raw input actually used after latency adjustment.Validation
make check— passed592 result
A single SAC / walk run after #2033 completed at 66,662.68 tail steps/s. This confirms the remaining ~11 ms server
apply_actioncost is dominated by multiple small CUDA launches (history copies, affine, bias selection, subtraction, control copy), not merely duplicate finite synchronization.Current integration head is
014d9b34(#2030–#2033). Server tail remains below the 100k gate; fused action publication remains the next candidate optimization.TATP-233 commentedon Oct 3, 2026
Execution checkpoint: integration head
014d9b34contains #2030–#2033. Local gates pass for both workloads; repeated 592 gate remains below target (SAC ~66.7k, FlashSAC ~70.1–71.2k). Remaining closeout: fused canonical action publication, reset/update-state kernel-count reduction, Genesis scope reduction, final full test gate, repeated server acceptance, docs/ADR/support matrix.TATP-233 commentedon Oct 3, 2026
Merged full-width joint target publication: #2034 —
perf(action): fuse full-width joint target publication(heade464113a; integration mergee61eb38a).Change
Entity.set_full_width_joint_position_targetis an explicit all-joints/all-rows Torch target boundary. It validates the immutable all-joint/one-actuator mapping once and writes directly into the control plane, replacing the generic path's actuator mapping, index-tensor reconstruction, equality check, finite reduction, and indexed scatter.JointPositionActionselects it only for the exact natural full-joint order.Validation
make check— passed592 result
SAC / walk after #2034: 66,264.16 tail env steps/s.
Tail phase means changed as expected for the targeted path:
*The backend-step shift shows the CPU-side action phase previously overlapped queued backend work; reducing its wall time exposes more backend launch time rather than producing an equal end-to-end saving.
This confirms the launch-count reduction is real, but also that per-control-step kernel-count reduction alone cannot recover the server gate. The next necessary direction is batching multiple control steps per collector/learner coordination boundary (currently
env_steps_per_sync=1) or reducing update/reset launch counts equivalently.21 remaining items
TATP-233 commentedon Oct 3, 2026
Merged MJWarp duplicate control barrier removal: unisim #336 —
perf(mjwarp): remove duplicate control barrier(heade8c5249; merge9e2119e).Change
MjwarpBackend.step_tensorpreviously:synchronize_device().The first explicit stream barrier was redundant because the caller owns the public action tensor and cannot mutate it until
step_tensorreturns. The copy and physics launches now share one ordered Torch CUDA stream, and the method waits once on that stream.The public contract remains synchronous return-after-completion; only duplicate/barrier scope is removed.
Validation
c4231907— 65,508.07 tail steps/s, within the existing ~63–65k bandNo server performance claim is made; this is another launch/barrier-count reduction that the larger per-step lifecycle dominates.
TATP-233 commentedon Oct 3, 2026
Execution checkpoint: UniLab
c4231907, unisim9e2119e, unilab-rl036fcba. Server SAC remains ~65.5k after removing the duplicate MJWarp control barrier. The bottleneck is confirmed structural per-control-step lifecycle dispatch, not a remaining micro-barrier.TATP-233 commentedon Oct 3, 2026
Merged G1 walk termination pack: #2041 —
perf(gait): fuse G1 walk termination pack(head49d0ce00; integration merge702d1795).Change
G1WalkTerminationPackfuses the canonical tilt and base-height failure terms into one public tensor read:upvector_z < cos(max_tilt_rad)is algebraically equivalent toacos(upvector_z) > max_tilt_rad;Validation
make check— passed592 result
SAC / walk: 65,395.94 tail steps/s. Env-step and update-state means are essentially unchanged from the preceding run; the small FPS shift is within run variation. The fused term is structurally correct but does not materially move the server ceiling.
TATP-233 commentedon Oct 3, 2026
Execution checkpoint: UniLab
702d1795, unisim9e2119e, unilab-rl036fcba. Termination pack merged; server SAC remains ~65.4k. Full repo gates remain clean onc4231907; final-headmake test-allmust be rerun after #2041 before closeout.TATP-233 commentedon Oct 3, 2026
Rejected experiment: G1 walk observation pack
I prototyped an actor-side
G1WalkObservationPackanalogous toMotionObservationPack, replacing the seven canonical actor terms with one concatenated carrier. The work was stopped and the branch deleted before PR; no integration head was affected.Reasons:
This is not a safe #2023 closeout change under the current scope. It should be a separate owner-contract issue if pursued.
TATP-233 commentedon Oct 3, 2026
Final-head repository gate rerun after #2041
UniLab
702d1795, unilab-rl036fcba, unisim9e2119e:make checkis included and passes. Repository gates remain clean on the current integration head.Rejected experiment: actor-side
G1WalkObservationPackwas prototyped and discarded without a PR/merge. The Manager cold-probe/read-plan ordering, exact policy width (100), actor-only noise semantics, and need for a critic peer make it a separate owner-contract scope rather than a safe #2023 patch.Remaining unresolved acceptance item: repeated 592 end-to-end throughput is still below 100k.
TATP-233 commentedon Oct 3, 2026
Current status summary: architecture, tensor-native boundary, scope/docs, and full repository gates are complete on UniLab
702d1795+ unisim9e2119e+ unilab-rl036fcba. The only unresolved #2023 acceptance blocker is repeated 592 throughput (SAC ~65k, FlashSAC ~70k), which evidence shows requires a new multi-step/lifecycle-batching scope rather than further single-owner micro-optimization.TATP-233 commentedon Oct 3, 2026
Merged non-synchronizing tensor root validation: #2042 —
perf(reset): validate tensor root payload without host sync(headd308da82; integration merge82973d5e).Change
The ordinary tensor root reset previously forced two Python bool conversions (finite reduction plus quaternion-norm reduction) on every selected reset. It now combines both predicates into one device boolean and compares it with
torch.equalagainst a same-device true scalar, matching the existing fused motion-write success-path pattern.Invalid payloads still synchronize and retain the exact existing NaN/quaternion diagnostics.
Validation
make check— passed592 result
SAC / walk: 65,497.80 tail steps/s, within the established ~65k band. The removed host sync is correct launch/synchronization reduction but does not overcome the per-control-step lifecycle ceiling.
TATP-233 commentedon Oct 3, 2026
Final-head repository gate after #2042
UniLab
82973d5e, unisim9e2119e, unilab-rl036fcba:All repository quality gates and tensor-native architecture/scope/docs criteria remain satisfied. The unresolved acceptance blocker is still repeated 592 throughput below 100k.
TATP-233 commentedon Oct 3, 2026
Execution checkpoint: UniLab
82973d5e(#2030–#2042), unisim9e2119e(#334–#336), unilab-rl036fcba(#73–#75). Repository gates pass. Server SAC remains ~65.5k; only throughput acceptance is unresolved.TATP-233 commentedon Oct 3, 2026
Final repeated 592 acceptance audit (authoritative closeout evidence)
Commits: UniLab
82973d5e, unisim9e2119e, unilab-rl036fcba.GPU: RTX 5090,
CUDA_VISIBLE_DEVICES=0. 160 iterations × 2048 envs, no play/ONNX. Runs interleaved in three full SAC/FlashSAC blocks.All runs completed 160/160 iterations. Post-run process/GPU-compute inspection found no residual collector/training process.
Acceptance result
Final attribution summary
The server deficit is not explained by NumPy owners, host RNG, command/reward/termination per-term dispatch, action indexing, encoder-bias host mirrors, duplicate finite/control barriers, reset table caching, ring capacity, collector thread count, CPU/NUMA affinity, or a single missing owner kernel. Each was measured and, where structurally sound, fixed/merged (#2030–#2042, unisim #334–#336, unilab-rl #73–#75). Repeated results remain ~65–71k.
The remaining cost is the per-control-step environment lifecycle itself: action, backend step, update-state, reset, observation rebuild, and learner/collector coordination are each individually small but collectively launch/dispatch-bound on the slow-frequency Xeon host. Closing the remaining gap requires a new public multi-step/lifecycle-batching or graph-execution scope, not another single-owner patch.
Everything else in #2023 is complete on this head:
make test-all: 1,864 passed, 20 skipped; benchmark imports 35/35 and 36/36;Issue #2023 should remain open until a successor scope delivers the required server throughput mechanism; it cannot be truthfully closed as passing its stated server acceptance gate.
TATP-233 commentedon Oct 3, 2026
Successor scope opened: #2043
perf: public multi-step MJWarp lifecycle execution for slow-host servers. It preserves the #2023 measurement contract and invariants and covers the remaining launch/dispatch-bound lifecycle gap that blocks the server throughput gate.TATP-233 commentedon Oct 3, 2026
Development branch convergence status
Current heads
dev/issue-1811-tensor-manager82973d5eroadmap/issue-1811-tensor-manager9e2119edevelop/tensor-runtime036fcbaUniLab integration is 453 commits ahead of its declared final target
develop/tensor-runtimeand has no unique target-side commits. No PR to the final target has been opened yet.Convergence cleanup performed
82973d5e.origin/roadmap/issue-1811-tensor-manager.tensorremote from unisim.test/genesis-torch-global-isolationbranch. Its PR test(genesis): isolate torch global mutation #2011 was closed unmerged; its test passes on the current head without that patch and Genesis is now shelved, so no action is pending.Remaining local branches
UniLab:
dev/issue-1811-tensor-manager— current integrationdevelop/tensor-runtime— declared final targetmain— untouched long-lived baseunisim:
roadmap/issue-1811-tensor-managerdev/ray-querymainunilab-rl:
develop/tensor-runtimefix/capture-compile(local-only)mainrelease/1.4.4Open work
develop/tensor-runtimewhen the perf: public multi-step MJWarp lifecycle execution for slow-host servers #2043 successor scope decision is made.TATP-233 commentedon Oct 3, 2026
Maintainer decision accepts the measured 592/RTX 5090 throughput result for the completed tensor-native runtime boundary. The integration branch was merged into the declared tensor-runtime target by #2044 (merge commit
f1ce4399).\n\nCompleted: tensor-native MJWarp sole path, architecture invariants, scope/docs/support matrix, benchmark contract, full repository gates, normal canonical-run shutdown, and local ≥100k targets.\n\nNot met: original 100k server throughput gate. Repeated final-head results were SAC 63,930–66,529 and FlashSAC 69,349–70,972. The remaining launch/dispatch-bound lifecycle work continues under #2043 using the same measurement contract.\n\nSibling heads: unisim9e2119e, unilab-rl036fcba. No changes were made tomain; no PyPI release.