Skip to content

[Tools] Run simulations in parallel - #227

Merged
tryuan99 merged 8 commits into
masterfrom
titan/run_parallel
May 12, 2026
Merged

tryuan99 merged 8 commits into
masterfrom
titan/run_parallel

Conversation

@tryuan99

@tryuan99 tryuan99 commented May 11, 2026 •

Copy link
Copy Markdown
Member

This PR allows batch simulation runs to be executed in parallel, up to the maximum number of parallel jobs given by the flag --max_parallel. This PR adds a Python orchestrator in run_batch.py that kicks off Unity subprocesses, each with its own simulation configuration, seed, and output directory.

Running batch_7_quadcopters.pbtxt with 16 simulations in parallel:
image

Example logs:

I0511 00:07:29.765498 8460310720 run_batch.py:271] Completed run 86 with seed 285.
I0511 00:07:33.417839 8460310720 run_batch.py:271] Completed run 89 with seed 288.
I0511 00:07:33.629183 8460310720 run_batch.py:271] Completed run 93 with seed 292.
I0511 00:07:33.734298 8460310720 run_batch.py:271] Completed run 91 with seed 290.
I0511 00:07:34.044881 8460310720 run_batch.py:271] Completed run 90 with seed 289.
I0511 00:07:35.274626 8460310720 run_batch.py:271] Completed run 88 with seed 287.
I0511 00:07:39.274260 8460310720 run_batch.py:271] Completed run 94 with seed 293.
I0511 00:07:39.890674 8460310720 run_batch.py:271] Completed run 96 with seed 295.
I0511 00:07:42.423452 8460310720 run_batch.py:271] Completed run 98 with seed 297.
I0511 00:07:42.528605 8460310720 run_batch.py:271] Completed run 92 with seed 291.
I0511 00:07:43.344181 8460310720 run_batch.py:271] Completed run 100 with seed 299.
I0511 00:07:48.762161 8460310720 run_batch.py:271] Completed run 97 with seed 296.
I0511 00:07:57.506463 8460310720 run_batch.py:271] Completed run 99 with seed 298.
I0511 00:08:31.071527 8460310720 run_batch.py:271] Completed run 95 with seed 294.
I0511 00:08:31.071632 8460310720 run_batch.py:330] All 100 runs completed successfully.

@stacklane-pr-stack-visualizer

stacklane-pr-stack-visualizer Bot commented May 11, 2026 •

Copy link
Copy Markdown

🧱 Stack PR · Base of stack

Stack Structure:

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors the simulation batching architecture, moving orchestration from Unity's RunManager to a Python script (Tools/run_batch.py) and introducing a RunWorker component for single-run execution. The update includes support for parallel runs via a new max_parallel configuration field, revised protobuf compilation, and updated documentation. Review feedback identifies an incorrect import path in the batch script and recommends enhancing error handling to ensure that a single worker failure does not terminate the entire batch process.

Comment thread Tools/run_batch.py Resolved
Comment thread Tools/run_batch.py Resolved
@coderabbitai

coderabbitai Bot commented May 11, 2026 •

Copy link
Copy Markdown

Review Change Stack

Warning

Rate limit exceeded

@tryuan99 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 47 minutes and 47 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: bd57cf36-c464-4223-96e9-553ad07f4fff

📥 Commits

Reviewing files that changed from the base of the PR and between 3a2aed9 and 4adf919.

📒 Files selected for processing (3)
  • Assets/Proto/Scripts/compile.sh
  • Tools/run_batch.py
  • docs/Simulation_Runner.md
📝 Walkthrough

Walkthrough

This PR replaces Unity-side batch execution (RunManager) with a Python-orchestrated architecture. RunConfig proto gains a max_parallel field to control concurrency. Build scripts now generate Python protobuf bindings separately in Tools/pb. A new RunWorker component bootstraps worker-mode execution when launched with --simulation_config, --seed, and --output_dir flags. SimManager and SimMonitor adapt to detect and handle worker mode. Tools/run_batch.py orchestrates parallel runs, spawning up to max_parallel Unity processes concurrently, validating exit codes, and managing cleanup. C++ and C# RunConfig loaders are removed. Documentation and logging utilities are updated to reflect batch workflow and log ordering semantics.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Possibly related PRs

Suggested reviewers

  • daniellovell
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 36.59% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title '[Tools] Run simulations in parallel' directly and clearly summarizes the main change: adding parallel execution support for batch simulations via the new run_batch.py orchestrator.
Description check ✅ Passed The description is related to the changeset, explaining the purpose of the new Python orchestrator, how it enables parallel runs, and providing concrete examples of logs from test execution.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch titan/run_parallel

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Tools/run_batch.py`:
- Line 14: The import path in run_batch.py is incorrect: replace the failing
`from proto.run_config_pb2 import run_config_pb2` with a proper import that
matches the generated module (e.g., `from pb import run_config_pb2`) or
move/rename the generated file to match `proto.run_config_pb2`; ensure Tools is
on sys.path when running `python3 Tools/run_batch.py` (or `python3
../../Tools/run_batch.py` from Build/<timestamp>) so `pb.run_config_pb2` can be
resolved — update the import in Tools/run_batch.py (the top-level import of
run_config_pb2) accordingly and verify both documented invocation paths succeed.
- Around line 11-14: The module google.protobuf.text_format is not imported so
calls like google.protobuf.text_format.Parse(...) will raise AttributeError; fix
by importing the submodule (e.g., add "from google.protobuf import text_format"
or "import google.protobuf.text_format" at the top alongside the existing
imports) and then either call text_format.Parse(...) or keep the existing
google.protobuf.text_format.Parse(...) after the explicit import so runs of
run_batch.py succeed.

In `@Tools/utils.py`:
- Line 28: The sort in find_all_files (return sorted(files, key=str)) is
redundant because callers like find_all_telemetry_files and find_all_event_logs
apply their own _run_log_sort_key; remove the in-function sorting so
find_all_files simply returns the list of found Path objects in discovery order,
and ensure any caller that requires deterministic ordering (e.g.,
find_latest_file) explicitly sorts or uses max(...) with the appropriate key;
update or confirm find_latest_file and other callers perform their own sorting
or selection logic using _run_log_sort_key where needed.
- Line 10: The regex stored in _RUN_DIRECTORY_PATTERN only captures the run
number and omits the trailing seed digits, so fullmatch fails for names like
"run_1_seed_200"; update _RUN_DIRECTORY_PATTERN to capture the seed digits as
well and anchor the end of the pattern (e.g., add a second capture for the seed
and a terminal anchor) so fullmatch will succeed for complete directory names.
- Around line 51-57: The regex used to detect run directories doesn't include
the seed number so _run_log_sort_key never matches real dirs; update the
_RUN_DIRECTORY_PATTERN definition to use the pattern r"run_(\d+)_seed_\d+"
(i.e., include \d+ after _seed_) so that _run_log_sort_key can match
parent.name, extract the run index via match.group(1), and return the intended
primary sort key instead of falling back to the secondary branch.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 84ab29dd-f5bf-452c-9ded-e24ae7cef940

📥 Commits

Reviewing files that changed from the base of the PR and between 645d003 and d0eebf9.

⛔ Files ignored due to path filters (6)
  • Assets/Resources/Prefabs/Managers/RunManager.prefab is excluded by !**/*.prefab
  • Assets/Scenes/MainScene.unity is excluded by !**/*.unity
  • Assets/Scripts/Generated/Proto/CommunicationConfig.cs is excluded by !**/generated/**
  • Assets/Scripts/Generated/Proto/CommunicationConfig.cs.meta is excluded by !**/generated/**
  • Assets/Scripts/Generated/Proto/RunConfig.cs is excluded by !**/generated/**
  • Assets/Scripts/Generated/Proto/RunConfig.cs.meta is excluded by !**/generated/**
📒 Files selected for processing (29)
  • .pre-commit-config.yaml
  • Assets/Proto/Configs/run_config.proto
  • Assets/Proto/Scripts/compile.sh
  • Assets/Resources/Prefabs/Managers/RunManager.prefab.meta
  • Assets/Scripts/Config/ConfigLoader.cs
  • Assets/Scripts/Managers/RunManager.cs
  • Assets/Scripts/Managers/RunManager.cs.meta
  • Assets/Scripts/Managers/RunWorker.cs
  • Assets/Scripts/Managers/RunWorker.cs.meta
  • Assets/Scripts/Managers/SimManager.cs
  • Assets/Scripts/Monitors/SimMonitor.cs
  • Assets/Scripts/Plugins/Protobuf.cs
  • Assets/Tests/EditMode/RunWorkerTests.cs
  • Assets/Tests/EditMode/RunWorkerTests.cs.meta
  • Assets/Tests/EditMode/SanityTests.cs
  • Assets/Tests/EditMode/SanityTests.cs.meta
  • Assets/Tests/PlayMode/RunWorkerTests.cs
  • Assets/Tests/PlayMode/RunWorkerTests.cs.meta
  • Assets/Tests/PlayMode/SanityTests.cs
  • Assets/Tests/PlayMode/SanityTests.cs.meta
  • ProjectSettings/Packages/com.unity.testtools.codecoverage/Settings.json
  • Tools/pb/run_config_pb2.py
  • Tools/run_batch.py
  • Tools/unity_utils.py
  • Tools/utils.py
  • docs/Simulation_Logging.md
  • docs/Simulation_Runner.md
  • plugins/protobuf/protobuf_plugin.cc
  • plugins/protobuf/protobuf_test.cc
💤 Files with no reviewable changes (10)
  • Assets/Tests/PlayMode/SanityTests.cs
  • Assets/Tests/EditMode/SanityTests.cs
  • plugins/protobuf/protobuf_plugin.cc
  • Assets/Scripts/Managers/RunManager.cs.meta
  • Assets/Tests/PlayMode/SanityTests.cs.meta
  • Assets/Tests/EditMode/SanityTests.cs.meta
  • Assets/Resources/Prefabs/Managers/RunManager.prefab.meta
  • Assets/Scripts/Config/ConfigLoader.cs
  • Assets/Scripts/Plugins/Protobuf.cs
  • Assets/Scripts/Managers/RunManager.cs

Comment thread Tools/run_batch.py Resolved
Comment thread Tools/run_batch.py Resolved
Comment thread Tools/utils.py Resolved
Comment thread Tools/utils.py Resolved
Comment thread Tools/utils.py Resolved

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Tools/run_batch.py`:
- Around line 226-245: Failure messages for runs lack the Unity log path; update
the error reporting in the loop that iterates running_workers (the block using
finished_run_index, run_index, descriptor, process) so that both RuntimeError
branches (non-zero exit_code and missing descriptor.output_dir) include the
per-run Unity log path constructed from unity_log_dir, run_index and
descriptor.seed (or descriptor.run_index/seed as appropriate). Build the
deterministic log filepath the same way other code does (use the existing
unity_log_dir variable and the run_index/seed values) and append it to the
f-string messages so users are pointed directly to the Unity log for debugging.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 84e75dd3-f4cd-4244-a507-5408c6df1827

📥 Commits

Reviewing files that changed from the base of the PR and between d0eebf9 and 15c63cb.

⛔ Files ignored due to path filters (4)
  • Assets/Plugins/assignment.dll is excluded by !**/*.dll
  • Assets/Plugins/libprotobuf.dylib is excluded by !**/*.dylib
  • Assets/Plugins/libprotobuf.so is excluded by !**/*.so
  • Assets/Plugins/protobuf.dll is excluded by !**/*.dll
📒 Files selected for processing (2)
  • Tools/run_batch.py
  • Tools/utils.py

Comment thread Tools/run_batch.py Resolved

@daniellovell daniellovell left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm!

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More docstrings/comments/documentation here would be useful imo

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Assets/Proto/Scripts/compile.sh`:
- Around line 31-43: The script currently deletes and then invokes protoc into
$PYTHON_OUTPUT_DIR without ensuring the directory exists; update the compile.sh
logic around the Python run config step to create $PYTHON_OUTPUT_DIR if missing
before removing or generating files (use $PYTHON_OUTPUT_DIR as the target), i.e.
add a directory creation guard prior to the rm -f
"$PYTHON_OUTPUT_DIR/run_config_pb2.py" and before the protoc call that generates
run_config_pb2.py so protoc has an existing output directory; keep references to
run_config_pb2.py, PYTHON_OUTPUT_DIR, and the protoc invocation in
Assets/Proto/Scripts/compile.sh.

In `@docs/Simulation_Runner.md`:
- Around line 63-64: Docs show inconsistent CLI flag names and example
invocations; update all occurrences to match the actual script interface by
choosing the canonical flag names used in the code (e.g., use --unity_path or
--binary_path consistently — replace any --binary_path/--binary-path variants
with the actual flag used by the runner, and unify --run-config vs --run_config
to the single canonical form), and fix example commands so the script filename
and working-directory paths match real usage; search for and replace the
inconsistent symbols (--binary_path, --unity_path, --run-config, --run_config
and any mismatched invocation paths) in the doc sections (including the other
mentions around lines noted) so every flag and example matches the implemented
CLI.

In `@Tools/run_batch.py`:
- Around line 135-145: The current _compute_max_parallel treats a proto3-unset
max_parallel (which is 0) as 1 and forces sequential runs; change the logic to
treat 0 as "unset" and substitute a sensible default (e.g., min(16,
run_config.num_runs)) before enforcing bounds; specifically, in
_compute_max_parallel check if run_config.max_parallel == 0 then set
requested_parallelism = min(16, run_config.num_runs) else set
requested_parallelism = max(1, run_config.max_parallel), and finally return
min(requested_parallelism, run_config.num_runs) so omitted proto fields result
in parallel execution instead of sequential.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 6e2927f0-64a7-4fe6-b311-814587e4a237

📥 Commits

Reviewing files that changed from the base of the PR and between 15c63cb and 3a2aed9.

⛔ Files ignored due to path filters (1)
  • Assets/StreamingAssets/Configs/MODULE.bazel.lock is excluded by !**/*.lock
📒 Files selected for processing (9)
  • Assets/Proto/Scripts/compile.sh
  • Assets/Scripts/Managers/RunWorker.cs
  • Assets/StreamingAssets/Configs/Runs/batch_5_swarms_1000_ucav.pbtxt
  • Assets/StreamingAssets/Configs/Runs/batch_5_swarms_100_ucav.pbtxt
  • Assets/StreamingAssets/Configs/Runs/batch_5_swarms_500_ucav.pbtxt
  • Assets/StreamingAssets/Configs/Runs/batch_7_quadcopters.pbtxt
  • Tools/run_batch.py
  • docs/Simulation_Runner.md
  • plugins/protobuf/protobuf_test.cc

Comment thread Assets/Proto/Scripts/compile.sh Resolved
Comment thread docs/Simulation_Runner.md Resolved
Comment thread Tools/run_batch.py Resolved
@tryuan99
tryuan99 merged commit 5ac057d into master May 12, 2026
18 checks passed
@tryuan99
tryuan99 deleted the titan/run_parallel branch May 12, 2026 06:29
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.

[Command Line] Parallelize run configuration runs

2 participants