Repository navigation
roadmap: macOS tensor runtime for MuJoCo/mjbatch off-policy training #2055
Copy link
Copy link
Closed
Description
Summary
- Goal: run the completed npenv→torchenv runtime switch on macOS (Apple Silicon) for the MuJoCo/mjbatch backend, and deliver working off-policy training on macOS: SAC +
g1_walk_flatand FlashSAC +g1_motion_tracking. Final acceptance is one full SACg1_walk_flattraining run on macOS. - Recommended path: one integration branch per repo (
dev/issue-<N>-macos-tensor-runtime) based ondevelop/tensor-runtime(siblings based on thetensor_runtime_workspace.jsonpins); materialize the workspace; fix macOS breakages in the owner layers behind device/platform gates; iterate withalgo.max_iterations=100smoke trainings; finish with the repo gate and the full acceptance run. - Delivery boundary: no npenv-runtime revert, no np-rng revert, no contract crossings, no
mainordevelop/tensor-runtimemutation in any repo, no PyPI publication, no CUDA performance/runnability regression, no training-semantics change. Multi-GPU DP stays CUDA-only. No macOS CI job is added (follow-up candidate). - Estimated review scale: small-to-medium; expected mostly config/platform-gate fixes across UniLab, unisim, unilab_rl; mjbatch_uni expected zero or minimal changes.
- Durable responsibility: UniLab owns training/runtime glue and owner YAML;
uni_rlowns learners/collectors/replay/IPC; unisim owns the SimBackend tensor contract and the mujoco adapter; mjbatch_uni owns the CPU batch executor. - Decisions required: (1) accept MPS as the macOS off-policy learner/replay device (uni_rl rejects a pure-CPU learner by design:
require_offpolicy_replay_deviceacceptscuda|mpsonly); a pure-CPU off-policy learner is out of scope; (2) sibling bases are the workspace manifest pins, not branch tips; (3) macOS CI coverage deferred.
Repository evidence
develop/tensor-runtime(90068b8) completed the npenv→torchenv switch; the old NpEnv runtime and the tensor-runtime switch are removed (ae851eb4,759153cd).- MuJoCo/mjbatch is a
HOST_BRIDGEbackend: the Manager env is CPU-tensor authoritative by design on every platform (src/unilab/envs/manager_based_rl_env.py:372-377); unisim declaresmacos_tensor_profile = "CPU-authoritative host bridge only"for mujoco (unisim/support.py, tensor-runtime branch). - macOS learner path exists:
get_default_device()resolves cuda → xpu → mps → cpu (src/unilab/utils/device.py:17-25); uni_rl implements an MPS replay pipeline and MPS fused optimizers, tested on CPU-only torch builds. - mjbatch-uni 0.2.4 already builds and steps on macOS arm64 (verified: editable arm64
.so, live 4-sim CPUBatch.step());cpu_idsaffinity is Linux-only there. - Current blocker on a macOS workstation: sibling checkouts on
mainlack the tensor-runtime API (HostBridgeTransferPlanet al.), sounilab.base.torch_envfails to import; the workspace manifest pinsdevelop/tensor-runtimecommits (unisim09d5caed, unilab-rl75680c23, mjbatch-unib3a3b480). - No macOS job exists in CI; the heaviest integration coverage for the two tasks lives in the
slowlane.
Scope
Included:
- Workspace materialization on macOS: integration branches from the declared bases,
uv sync, import gates green. - macOS adaptations in owner layers only, behind device/platform gates, with CUDA behavior preserved: env/learner device resolution, replay device gates, CPU-affinity degradation, viewer/playback guards as needed.
- Training enablement and iteration-efficiency smoke runs (
algo.max_iterations=100):uv run train --algo sac --task g1_walk_flat --sim mujocouv run train --algo flashsac --task g1_motion_tracking --sim mujoco
- Repo gates on the integration head:
make check,make test, focused slow contract tests for the two tasks;make test-allbefore the final PR. - Acceptance: one full SAC
g1_walk_flat--sim mujoco training run on macOS (owner YAML defaultalgo.max_iterations), normal shutdown, metrics/logs inspected.
Explicitly excluded: pure-CPU off-policy learner device, multi-GPU on macOS, new public contracts, new ADRs unless a structural decision emerges, macOS CI jobs, PyPI publication, main/develop/tensor-runtime mutation.
Acceptance criteria
-
import unilab.base.torch_envand backend construction succeed on macOS with the workspace materialized. - SAC +
g1_walk_flat--sim mujoco trains on macOS (CPU physics, MPS learner) foralgo.max_iterations=100with normal shutdown and expected metric schema. - FlashSAC +
g1_motion_tracking--sim mujoco trains on macOS foralgo.max_iterations=100with normal shutdown. -
make check,make test, and focused slow tests for the two tasks pass on the integration head. - Full SAC
g1_walk_flat--sim mujoco training completes on macOS (default iteration budget, normal shutdown, collector exit 0, no residual processes). - No diff touches npenv-runtime, np-rng, CUDA paths' behavior,
main, ordevelop/tensor-runtime.
Governance
Declared base: develop/tensor-runtime (UniLab) and the tensor_runtime_workspace.json sibling pins. Integration branch per repo: dev/issue-<N>-macos-tensor-runtime. No PyPI release. Related: #1706 (NpEnv removal), #2052 (Newton canonical tensor runtime), tensor-runtime sibling dependency transition policy in 5-contributing_workflow.md.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels
Activity
TATP-233 commentedon Oct 4, 2026
Progress update (macOS bring-up complete, acceptance run in flight)
Root cause of the first macOS failure
flashsac + g1_motion_tracking --sim mujocofailed at the first autoreset withRuntimeError: ManagerBased tensor reset-state mutation requires an active reset(
TensorMotionCommand._resample_command→write_motion_state_tensor_to_sim).Diagnosis: the env-side reset dispatch in
ManagerBasedRlEnv.resetonly opens atensor transaction through the packed host bridge when
ResetStateTransaction.can_commit_packed()is true. That probe duck-typesSimBackend.get_public_state_widths(), which did not exist at the siblingcommits pinned by
tensor_runtime_workspace.json(unisim09d5caed). Thecontract exists at the
develop/tensor-runtimebranch tips (unisim5e835923,PublicStateWidths+ mujoco/genesis/mjwarp implementations; themujoco host plan's
apply_resetalready validates(rows, nq=36)/(rows, nv=35)parity with the Manager layout). The stale pins also predated unilab-rl
single-device/inference-transport fixes (
1d83704,e5b3488).Base realignment (recorded decision)
Sibling integration branches are based on the
develop/tensor-runtimebranchtips, not the stale manifest pins; the manifest was updated on the UniLab
integration branch (commit
d2950202). This matches UniLab HEAD's own testexpectations (
tests/envs/test_env_configs.pycallsbackend.get_public_state_widths()), so the pins were stale relative to thedeclared base branch. Bases now:
5e835923(= tip), unilab-rl036fcba6(= tip), mjbatch-unib3a3b480(= tip == main, unchanged)dev/issue-2055-macos-tensor-runtimefromdevelop/tensor-runtime(90068b82)With this,
can_commit_packed() == Truefor the mujoco G1 owners and the resetdispatch takes
scoped_device_event_tensor_with_host_commit— no UniLabruntime code change was needed for the training path itself.
Training evidence (macOS arm64, torch 2.14.0, MPS learner, CPU physics)
uv run train --algo sac --task g1_walk_flat --sim mujoco algo.max_iterations=100normal_completion, collector exit 0, cleanup errors[]uv run train --algo flashsac --task g1_motion_tracking --sim mujoco algo.max_iterations=100normal_completion, collector exit 0run_summary.jsonconfirmsenv_public_device=cpu,learner_device=mps,cuda_context_initialized=false,tensor_native_env=true,cuda_graph.backend=eager(correctly inert off CUDA),metric_schema_version=1.No residual collector processes after either run. SAC re-run after the base
change: same green result.
Gates on the integration head
make check: pass (ruff, mypy 144 files, pyright 0 errors).make test(non-slow): 1801 passed, 59 skipped — was 1724 passed /62 failed / 18 errors before the test-layer fixes (commit
f2fb4519):(genesis/isaacgym/isaacsim/fixed-variants) now bypass the factory
platform gate (which has dedicated coverage in
test_cuda_backend_platform_preflight.py), restoring 58 failed + 18errored tests on all CUDA-less hosts;
test, Linux-
/procsoak resource test; dropped the never-committedoutputs/velb_compare/micro_velb.pybenchmark-scope entry.test_env_configs.py -k mujoco5 passed (now includes anew selected-row reset regression case through the packed host-bridge tensor
command commit, commit
b6c293fe), G1 owner contract 17 passed / 4 skipped(newton cases now skip off-CUDA), flashsac owner contract 10 passed.
Acceptance
Full-budget
sac + g1_walk_flat --sim mujoco(owner defaultalgo.max_iterations=5000) is running unattended withtraining.play_render_mode=record(avoids the interactive mjpython viewer;playback + ONNX export still exercised). Result follows.
TATP-233 commentedon Oct 4, 2026
Acceptance complete — roadmap delivered on the integration head
Full-budget acceptance run on macOS arm64 (torch 2.14.0, CPU physics + MPS learner):
457,760 replay rows/s) —
normal_completion, collectorexitcode 0,cleanup errors
[], no residual processes.episode length 946.85 (from ~49 at init).
(
max_diff 7.84e-07), 800-frame playback video rendered(
play_render_mode=recordto avoid the interactive mjpython viewer in anunattended run; playback + export paths fully exercised).
run_summary.json:env_public_device=cpu,learner_device=mps,cuda_context_initialized=false,cuda_graph.backend=eager,metric_schema_version=1.Pre-PR gate on the integration head:
make test-allpass (check + coveragelane + benchmark smoke 35/35, 36/36).
PR: #2061 (
dev/issue-2055-macos-tensor-runtime→develop/tensor-runtime).Sibling repos (unisim, unilab_rl, mjbatch_uni) required zero code changes —
their integration branches track the
develop/tensor-runtimetips recorded inthe updated
tensor_runtime_workspace.json. All acceptance criteria checked.Remote CI will run when the PR to
mainis opened later (per workflow, localresults + review are the gate for a non-
mainbase).chore(workspace): realign sibling pins with develop/tensor-runtime heads
test(platform): make the non-slow suite pass on CUDA-less hosts
test(g1): cover mujoco motion selected reset and skip newton cases of…