Repository navigation
[DSE] Run trials in parallel - #1143
Draft
podkidyshev wants to merge 7 commits into
Draft
podkidyshev wants to merge 7 commits into
podkidyshev wants to merge 7 commits into
Conversation
Interfaces for running DSE trials in parallel; the wave logic and BaseRunner.run_trials are not implemented yet. - agent_parallelism test setting, next to agent and agent_steps - BaseAgent.select_batch and BaseGym.evaluate_batch; the default agent loop is built on them - CloudAIGymEnv owns the step allowance and constraint retries; the progress property is removed and step() is a one-proposal batch - BaseRunner.run_trials for independent concurrent trials - pin_nodes and single-sbatch DSE reject agent_parallelism > 1 Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Contributor
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: truePre-merge checks:
|
Replaces the agent_parallelism test setting, which changed the generated reference of every test definition. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
- poll_jobs checks every tracked job once per pass and returns the finished ones with their status; monitor_jobs applies the scenario policy on top. The running state is polled only while a run is still published as pending or a start_post_init dependent waits for it. - run_trials runs independent DSE trials concurrently on the same polling; a failed trial does not stop its siblings. - A submission error kills outstanding jobs and raises JobSubmissionError instead of exiting the process. - DSE no longer rewrites the runner's scenario or resets its shutdown flag. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
- CloudAIGymEnv.evaluate_batch fills waves of at most max_parallelism trials from the agent's proposals, runs them on the runner's submit_test and poll_jobs, and records results in proposal order. Cached, duplicate and constraint-rejected proposals take no slot. - A failed trial does not stop its wave. A trial that cannot be prepared for submission is a failed trial; a job submission error or a polling error kills the wave and aborts the sweep. - Cancelling stops the sweep: the interrupted wave is killed and not recorded, and the DSE returns a non-zero code. - The default select_batch is lazy, so select_action is not called once the step allowance is exhausted. - BaseRunner.handle_job_completion no longer special-cases DSE steps. - Standalone jobs close their process pipes on completion. - Tests: probe workload with a scripted in-memory runner and real standalone processes; runner polling and policy tests. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Runner: - poll_jobs yields finished jobs one at a time, so the caller handles a job before the next one is checked. Polling everything first broke start_post_init dependents with iterations and end_post_comp dependents finishing together with their source. - shutdown() is the cancel path only; abandon_jobs() terminates and untracks jobs after an error, so an aborted run is published as failed, not cancelled. Killing iterates a snapshot and survives a job that cannot be terminated. - Nothing is started once the runner is shutting down, and a job whose submission overlapped the shutdown is terminated. - A job submission error propagates to the CLI, which exits with 1. DSE: - An error while waiting for a wave fails the trials that were still running and terminates their jobs; the sweep goes on. - BaseGym.evaluate_batch has a serial default built on step(), so environments that only implement step keep working. - Proposals are copied when pulled; a cached trial's output path is the directory of the trial whose result it reuses. - Standalone jobs close their pipes on completion instead of reading them. Tests: separate failure modes in the probe workload, abort and cancel paths, runner regression tests, CLI exit code. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
| logging.error(f"Step {job.test_run.step} failed: {job_status.error_message}") | ||
| if self.runner.jobs: | ||
| time.sleep(self.runner.monitor_interval) | ||
| except BaseException as e: |
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
DSE trials can run in parallel.
max_parallelism(default1, set underagent_config) is the maximum number of trials CloudAI keeps outstanding at once.max_parallelismtrials start, all of them finish, then the next wave starts. Proposals rejected by the constraint check, already in the trajectory, or identical to a trial of the same wave take no slot.BaseAgent.select_batch, which returns every proposal the agent can make before it needs feedback; it may be an endless generator. The default wrapsselect_action, so existing agents stay serial.grid_searchproposes the whole grid.CloudAIGymEnv.evaluate_batchowns the sweep bookkeeping (step allowance, trial numbers, constraint retries, skipped steps) and returns one result per proposal, in proposal order.step()is a one-proposal batch. The trajectory and the set of executed trials do not depend onmax_parallelism.BaseRunnerseparates job polling from scenario policy.poll_jobsyields finished jobs with their status;monitor_jobsapplies iterations, dependencies and fail-fast on top; the DSE usessubmit_testandpoll_jobsdirectly. A job now costs one status query per pass instead of three, plus one more only while its run is published as pending or astart_post_initdependent waits for it.pin_nodescannot be combined withmax_parallelism > 1, and single-sbatch DSE rejects the setting.Test Plan
CI passed.
The DSE cases (
tests/dse) run a probe workload on an in-memory system where the duration of every trial, in polling passes, and its outcome are scripted, so the composition of each wave is asserted exactly.max_parallelism; the next wave starts only after the slowest trial of the current one; the trajectory keeps proposal order when trials finish in reverse; every trial gets its own output directory; the trajectory is the same formax_parallelism1, 2, 3, 5 and 16;env_paramsare sampled per trial whatever the parallelism.max_consecutive_rejected_proposals, and the skipped step consumes a trial number.select_batchstays serial; an agent gets the feedback of a whole batch before it proposes the next one;step()is a one-proposal batch.1.pin_nodesis rejected withmax_parallelism > 1and works with1; single-sbatch DSE rejects the setting.tests/test_base_runner.py):poll_jobsasks for completion once per job and pass, only reports a failed job, and lets the caller handle a finished job before the next one is checked;monitor_jobsstops the scenario on a failed job, resubmits per iteration, submits astart_post_initdependent once per iteration and does not iterate anend_post_compdependent that finished with its source; nothing starts after shutdown, and shutdown terminates every job even if one cannot be terminated.Manual: real
cloudai runon the standalone system with the Aiconfigurator workload, grid of 9 trials: 36.0 s withmax_parallelism = 1, 13.8 s withmax_parallelism = 3, identicaltrajectory.csv. Nothing was run on Slurm; node allocation for several trials submitted at once is untested there.Additional Notes
Compatibility changes:
JobSubmissionError(now exported fromcloudai.core) instead of callingexit(1): outstanding jobs are terminated, the CLI still exits with1,cloudai.api.run_experimentraises it.BaseRunner.check_start_post_init_dependenciesis removed;monitor_jobscovers it.handle_job_completionno longer removes the job fromjobsandtestrun_to_job_map;poll_jobsdoes.BaseGym.progressandCloudAIGymEnv.progressare removed.BaseAgent.runcallsenv.evaluate_batch;BaseGymprovides a serial default built onstep, so environments that only implementstepkeep working, but a wrapper that only overridesstepis bypassed by the default loop.update_policykeeps the existing keys and addsstatus,step,output_pathandenv_params.env.test_run.output_pathis the directory of the trial whose result is reused.🤖 Generated with Claude Code