Repository navigation
Description
Phase 4A:MJWarp collector CUDA graph candidate hot-path profiling baseline
Summary
#2274 的直接前置已经完成:
- refactor(reset): sink reset composition into UniSim packed transaction #2302 / refactor(reset): migrate or sink ResetStateTransaction host composer #2275:UniSim public packed transaction 成为 reset composition 唯一 owner;
- fix(env): restore G1 reset observation boundaries #2305 / Bug: G1 walk reset owner skips phase observation reset and publishes stale action observation #2303:G1 phase observation reset 与 post-reset
last_actionordering 已修复; - diagnostics(runtime): persist MJWarp CUDA graph state in run manifest #2278 / test(runtime): add CUDA Manager carrier placement contracts #2279:backend graph diagnostics 与 CUDA placement contracts 已建立。
本 issue 只做 Phase 4A profiling / attribution,不实现 collector CUDA graph,不修改 public multi-step contract。
Fixed baseline
- UniLab head:
8542371a - default / ROCm dependency floor:
unisim-core>=1.7.17unilab-rl==1.4.12
- profiling 时必须记录:
- GPU / driver / CUDA runtime;
- PyTorch / Warp / MJWarp / unisim-core / unilab-rl versions;
- task / algorithm / num_envs / substeps / action dependency;
- effective collector step block K;
- profiler command 与 warmup / measured window;
runtime_manifest.backend_diagnostics,特别是cuda_graph.requested/enabled/disable_reason。
Fixed-K baseline
Current SAC / FlashSAC off-policy owners are semantically K=1:
training.env_steps_per_sync: 1;training.inference_slot_capacity: 1;- FlashSAC TD
algo.algo_params.n_step: 1is return bootstrapping, not the action-block size.
Therefore the first graph candidate must preserve K=1. Any K>1 public multi-step
carrier requires the Phase 5 action-dependency decision (pre-committed action
sequence versus explicit inference overlap) and cannot be inferred from
updates_per_step, policy_frequency, replay capacity, or MPS mode. K is an
explicit semantic contract, not an implementation tunable.
CUDA MPS attribution matrix
CUDA MPS is already an execution-sharing variable, not merely a deployment
detail. The profiler must collect both modes separately:
training.cuda_process_sharing: null— independent learner/collector CUDA contexts;training.cuda_process_sharing: mps— validated single-rank Linux/NVIDIA/MJWarp MPS mode.
Requirements:
- Do not mix null and MPS samples in one latency distribution.
- Use repeated, interleaved arms on the same host and daemon topology where possible.
- Record
cuda_process_sharingruntime-manifest evidence alongside backend graph diagnostics. - Keep learner and collector physical GPU UUID, MPS control pipe/server PID, daemon settings, and active-thread policy if set.
- Explain whether apparent collector gains come from shorter collector work, learner/collector overlap, queueing changes, or reduced context arbitration.
- Treat MPS-on and MPS-off as separate Phase 5 go/no-go evidence; neither result may be extrapolated to the other.
This is required because #2065 / ADR-0013 already showed large E2E changes from
MPS, and CUDA graph replay scheduling/stream ownership can behave differently
under shared execution.
Representative workloads
- Primary:released-dependency MJWarp / FlashSAC / G1 motion tracking route,对齐 chore(deps): bump unilab-rl to 1.4.12 in the ROCm profile #2301 的 diagnostics baseline。
- Secondary attribution only:MJWarp / SAC / G1 walk route,用于区分 reset density、G1 walk owner lifecycle 与 motion-tracking lifecycle。
不得把 collector-only microbenchmark 结果当作 E2E acceptance。
Profiling boundary
按 collector lifecycle 采集并归因:
policy action publication
→ action apply / control transform
→ physics step
→ scene tensor read refresh
→ observation
→ reward
→ termination
→ metrics / episode counters
→ events / commands
→ reset mask
→ packed reset
→ post-reset observation
→ replay / inference publication
每个 phase 必须区分:
- wall time;
- GPU kernel time;
- CPU launch / Python dispatch;
- queue wait / sync wait;
- allocation;
- H2D / D2H;
- global synchronize;
- data-dependent Python branch。
Required inventory
在 current main 上重新审计并标注 hot path / interval path / cold path:
bool(tensor.any()).item().cpu()/.tolist()/.numpy()masked_selectnonzero()- host bool reduction
- temporary allocation
- Python term-by-term manager dispatch
- validation and diagnostics
- event interval / circular buffer branch
- reward / metrics / termination episode publication
- reset count and manual reset branches
- replay / inference publication
输出表格必须包含:
- owner file / function;
- call frequency;
- tensor shape / device;
- sync kind;
- whether inside candidate capture boundary;
- proposed disposition:
- device-resident counter;
- fixed-shape pack;
- interval publication;
- move outside capture;
- keep eager;
- requires Phase 5 public contract。
Deliverables
- Environment / version provenance record.
- Real manifests for null and MPS modes showing backend graph and CUDA process-sharing state.
- Lifecycle phase timing tables for primary and secondary workloads, split by MPS mode.
- Ranked host-sync / allocation / Python-dispatch blockers.
- Candidate capture boundary proposal with explicit inside/outside lists.
- Reconciliation with diagnostics(runtime): persist MJWarp CUDA graph state in run manifest #2278 diagnostics and existing timing attribution.
- Split Phase 4B–4D implementation into small owner-level child issues.
- Phase 5 go / no-go recommendation based on measured collector overhead.
Explicit non-goals
- No CUDA graph implementation.
- No public multi-step API change.
- No removal of semantic logs or episode statistics.
- No backend-private API probing.
- No support / performance claim from stale perf(mjwarp): quantify removing dynamic reset row flow for CUDA graph safety #2285 evidence after Bug: G1 walk reset owner skips phase observation reset and publishes stale action observation #2303.
- No E2E acceptance from collector-only benchmarks.
Definition of done
- Profiling evidence is reproducible from the recorded head, commands, environment, and manifest.
- The effective K is recorded explicitly; the first candidate preserves current K=1 semantics.
- MPS-on and MPS-off attribution are separated and reconciled with runtime-manifest evidence.
- Every known D2H / host sync / dynamic branch in the candidate boundary is either removed from the proposed boundary, assigned to a child issue, or justified as interval/cold path.
- Ranked results identify whether collector外围 overhead is large enough to justify Phase 4 implementation and Phase 5 ADR.
- If expected benefit is not supported by evidence, close this route with a no-go recommendation instead of starting graph MVP.
Activity
TATP-233 commentedon Oct 12, 2026
Part of #2274 Phase 4A.
当前 baseline 对应
main@8542371a:#2302 packed reset ownership 与 #2305 reset semantic fix 均已合并。若 profiling 开始前main又前进,需要在 issue 中重新声明 head,并确认没有改变 collector hot path / reset semantics。TATP-233 commentedon Oct 12, 2026
补充两个 profiling 变量:
K=1(env_steps_per_sync=1、inference_slot_capacity=1;FlashSACn_step=1是 TD return,不是 action block)。首个 graph candidate 必须保持 K=1;K>1 必须等 Phase 5 明确 action dependency policy,不能从updates_per_step/policy_frequency/ replay 容量推导。cuda_process_sharing=null与mps作为独立、交错采集的 attribution arm,并同时记录 backend graph 与 process-sharing manifest。不能把两种模式的 latency 混在一起,也不能把任一模式结果外推到另一模式。TATP-233 commentedon Oct 12, 2026
Superseded by #2307.
No profiling implementation has started. #2307 absorbs the full Phase A scope, including K=1, separate
cuda_process_sharing=null/ validatedmpsinterleaved arms, manifests, lifecycle attribution, ranked blockers, and separate go/no-go recommendations.