Skip to content

perf: single-dispatch MuJoCo per-substep control via control_callback (#1259 M1b) - #1275

Merged
TATP-233 merged 1 commit into
dev/issue-1042-manager-based-apifrom
perf/issue-1267-mujoco-single-dispatch
Aug 24, 2026
Merged

perf: single-dispatch MuJoCo per-substep control via control_callback (#1259 M1b)#1275
TATP-233 merged 1 commit into
dev/issue-1042-manager-based-apifrom
perf/issue-1267-mujoco-single-dispatch

Conversation

@TATP-233

Copy link
Copy Markdown
Collaborator

Parent: #1259 (Wave 2, M1b). Closes #1267. Upstream: unilabsim/mujoco_uni#1(已发布 mujoco-uni-runtime==0.4.0)。

改动

  • MuJoCoBackend._step_with_pre_step_control:从每 substep 一次 pool.step(nstep=1)(sim_substeps 次 dispatch)改为单次 pool.step(nstep=N, control_callback=...)。upstream callback 在每个 substep 前重算 MBA action,数值语义与逐调用完全等效(warmstart/warning 逐 substep 清零、post_step_forward_sensor 按 gather 轮应用、pending xfrc 逐 substep concat;parity 由 upstream 测试 atol=1e-12, rtol=0 保证)。
  • callback_sensordata=False:跳过逐 substep 的 sensordata gather/refresh。语义依据:现有全部 action term(JointPositionAction/MotionJointPositionAction/RoughJointPositionAction/FootstandIncrementalAction/AllegroIncrementalPositionAction/StewartTiltAction/Go2WMixedAction)在 apply_actions 中只读 physics-state 支持的 getter(joint pos/vel)或静态 buffer(encoder_bias),没有 term 读 sensor 支持的 body-state 视图;_sensor_data 仍由最终步返回刷新一次,post-step observation/metric term 消费路径不变。逐 substep 的 _physics_state 刷新保留(action term 依赖)。
  • pin:mujoco-uni-runtime==0.3.1==0.4.0(pyproject.toml / pyproject.rocm.toml / uv.lock / uv.rocm.lock)。
  • 测试:tests/base/test_backend_pre_step_control.py fake pool 实现 callback 协议;断言单次 dispatch、逐 substep control 序列、_physics_state 逐 substep 可见、_sensor_data 仅最终刷新、pending xfrc 逐 substep concat 与清零。

不新增 SimBackend 方法,不保留多 dispatch fallback,Motrix/其他 backend 不动。

Validation

  • 最终提交 a8c93060,本地 make test-all 通过(check + 2194 passed/28 skipped + benchmark smoke 33/34)。
  • Benchmark(既有入口 scripts/benchmark/rl/benchmark_offpolicy_collector_active.py,8192 envs,同机 before/after,各 100 measure steps):
Case physics ms/vector step collector steps/s
flashsac/g1_walk_flat/mujoco 104.7 → 98.4(-6.1%) 63214 → 68487(+8.3%)
sac/g1_motion_tracking/mujoco 85.2 → 83.6(-1.9%) 56527 → 57699(+2.1%)

单次运行,本机运行间漂移可达数个百分点,正式 7-case × ≥3 runs 验收归 #1263

行为影响

  • MuJoCo:physics 数值与逐调用路径逐 bit 等效(upstream parity 测试);pre-step control fn 观察到的 _sensor_data 在 substep 间不再刷新(无现有 consumer,见上);physics_ms 计时口径不变(不含 callback 内的 control 计算)。
  • Motrix / drake / mjwarp:无改动。

#1259 本地-only gate:不触发、不等待远程 CI。

…#1267)

Rewrite MuJoCoBackend._step_with_pre_step_control from one
BatchEnvPool.step(nstep=1) call per physics substep to a single
pool.step(nstep=N, control_callback=...) dispatch (mujoco-uni-runtime
0.4.0, unilabsim/mujoco_uni#1). The upstream callback recomputes the
Manager-Based action before every substep with identical numerics
(warmstart/warnings cleared per substep, post_step_forward_sensor
applied per gathered round).

callback_sensordata=False skips the per-substep sensordata
gather/refresh: all current action terms only read physics-state-backed
getters (joint pos/vel, encoder_bias buffer), and _sensor_data keeps
being refreshed once from the final-step return for post-step
observation/metric terms.

Local evidence (offpolicy_collector_active, 8192 envs, this machine):
- flashsac/g1_walk_flat/mujoco: physics 104.7 -> 98.4 ms (-6.1%),
  collector 63214 -> 68487 steps/s (+8.3%)
- sac/g1_motion_tracking/mujoco: physics 85.2 -> 83.6 ms (-1.9%),
  collector 56527 -> 57699 steps/s (+2.1%)

Refs #1259 (Wave 2, M1b). Motrix and other backends unchanged.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant