Distribute Arena Experiment Runs on OSMO#920
Conversation
Signed-off-by: Clemens Volk <cvolk@nvidia.com>
Signed-off-by: Clemens Volk <cvolk@nvidia.com>
| @@ -29,6 +30,8 @@ class Pi0ArenaExperimentWorkflow(Workflow): | |||
|
|
|||
| lead_list = [True, False] | |||
There was a problem hiding this comment.
🔵 lead_list / task_cls_list no longer drive rendering
After the fan-out, _get_group_dicts builds every task directly with hard-coded lead= flags, so lead_list and task_cls_list no longer shape what this workflow renders — they only satisfy the base __init__ asserts (_assert_single_lead_task, len(task_cls_list) > 0), which still describe a single 2-task group rather than the N groups actually emitted. Are they still meaningful here, or is there a cleaner way to satisfy the base contract without leaving these two attrs describing a shape the workflow no longer produces?
🤖 Isaac Lab-Arena Review BotSummaryThis PR fans a single-group Experiment workflow out into one OSMO group per Run (each Pi0 Run gets a dedicated server), then adds an I verified the likely risk areas and they hold up: Findings🔵 Improvement: Test CoverageGood. VerdictShip it |
Greptile SummaryThis PR distributes each Arena Experiment Run into its own independent OSMO group, replacing the previous single-group design where all Runs shared one Experiment Runner and one Pi0 policy server. Each Run now gets a singleton
Confidence Score: 4/5Safe to merge; the distributed fan-out design is well-tested and the changes are structurally sound. The group_name constructor parameter on Pi0ArenaExperimentWorkflow is accepted and stored but never read by the overriding _get_group_dicts(), making it a silent no-op that could mislead future callers. Additionally, aggregate_experiment_outputs.py contains a redundant mkdir call on a directory that was already created moments earlier. Neither issue affects correctness in the current codebase, but the misleading API surface on the workflow class is worth addressing before this pattern gets copied. osmo/workflows/arena_experiment_workflow.py (group_name parameter) and isaaclab_arena/evaluation/aggregate_experiment_outputs.py (redundant mkdir) Important Files Changed
Sequence Diagram%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant Caller as Caller / CLI
participant W as Pi0ArenaExperimentWorkflow
participant G0 as arena-run-0 Group
participant Gn as arena-run-N Group
participant Agg as aggregate-results Group
Caller->>W: Pi0ArenaExperimentWorkflow(experiment_cfg)
W->>W: deepcopy(experiment_cfg)
W->>W: _assert_pi0_server_compatible()
Caller->>W: generate_workflow()
W->>W: _get_group_dicts()
loop For each Run
W->>W: deepcopy(run_cfg) to singleton_experiment
alt Pi0RemotePolicy
W->>G0: ExperimentRunnerTask + Pi0ServerTask
else Local policy
W->>Gn: ExperimentRunnerTask only
end
end
W->>Agg: ExperimentResultsTask(run_task_names)
W-->>Caller: workflow dict
Note over G0,Gn: OSMO runs groups in parallel
G0->>Agg: task output dir
Gn->>Agg: task output dir
Agg->>Agg: aggregate_experiment_outputs.py
Agg-->>Caller: combined report at DATASET_SWIFT_URL
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant Caller as Caller / CLI
participant W as Pi0ArenaExperimentWorkflow
participant G0 as arena-run-0 Group
participant Gn as arena-run-N Group
participant Agg as aggregate-results Group
Caller->>W: Pi0ArenaExperimentWorkflow(experiment_cfg)
W->>W: deepcopy(experiment_cfg)
W->>W: _assert_pi0_server_compatible()
Caller->>W: generate_workflow()
W->>W: _get_group_dicts()
loop For each Run
W->>W: deepcopy(run_cfg) to singleton_experiment
alt Pi0RemotePolicy
W->>G0: ExperimentRunnerTask + Pi0ServerTask
else Local policy
W->>Gn: ExperimentRunnerTask only
end
end
W->>Agg: ExperimentResultsTask(run_task_names)
W-->>Caller: workflow dict
Note over G0,Gn: OSMO runs groups in parallel
G0->>Agg: task output dir
Gn->>Agg: task output dir
Agg->>Agg: aggregate_experiment_outputs.py
Agg-->>Caller: combined report at DATASET_SWIFT_URL
Reviews (1): Last reviewed commit: "Distribute Arena Runs across OSMO groups" | Re-trigger Greptile |
| run_output_dir = output_dir / run_name | ||
| assert not run_output_dir.exists(), f"Run output destination already exists: '{run_output_dir}'" | ||
| run_output_dir.parent.mkdir(parents=True, exist_ok=True) | ||
| shutil.copytree(result_paths[0].parent, run_output_dir) |
There was a problem hiding this comment.
The
run_output_dir.parent is always output_dir, which was already created unconditionally with mkdir(parents=True, exist_ok=True) three lines earlier. This call is a no-op in every execution path.
| run_output_dir = output_dir / run_name | |
| assert not run_output_dir.exists(), f"Run output destination already exists: '{run_output_dir}'" | |
| run_output_dir.parent.mkdir(parents=True, exist_ok=True) | |
| shutil.copytree(result_paths[0].parent, run_output_dir) | |
| run_output_dir = output_dir / run_name | |
| assert not run_output_dir.exists(), f"Run output destination already exists: '{run_output_dir}'" | |
| shutil.copytree(result_paths[0].parent, run_output_dir) |
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
| @@ -46,23 +49,67 @@ def __init__( | |||
| group_name=group_name, | |||
| ) | |||
There was a problem hiding this comment.
group_name parameter is silently ignored
Pi0ArenaExperimentWorkflow.__init__ accepts and forwards group_name to Workflow.__init__, where it is stored as self.group_name. However, the overridden _get_group_dicts() never reads self.group_name — it unconditionally emits "arena-run-{index}" and "aggregate-results". A caller passing group_name="my-exp" gets groups named arena-run-0, arena-run-1, etc. with no indication that the parameter was ignored. Consider either removing the parameter from this subclass's signature or using self.group_name as a prefix in the generated names.
Signed-off-by: Clemens Volk <cvolk@nvidia.com>
Summary
Distribute Arena Experiment Runs across independent OSMO groups.
Detailed description