DPDispatcher Task Grouping#
Overview#
DPDispatcher organizes work at three levels: Tasks (a single command), Jobs (a scheduler submission unit containing one or more tasks), and Submissions (a collection of all jobs for a given workload). Two Resources parameters control how tasks map to jobs and how they execute within each job:
group_sizeβ how many tasks are packed into one scheduler jobpara_degβ how many tasks within a job run in parallel at any moment
Both live in the Resources class in dpdispatcher/submission.py.
group_size: Tasks β Jobs#
Submission.generate_jobs() is where grouping happens. It:
- Shuffles all tasks with a fixed seed (42) for load-balance reproducibility.
- Slices the shuffled list into chunks of
group_size. - Creates one
Jobper chunk.
Key edge cases :
group_size = 0β treated as infinity (all tasks in one job).group_size < 0or non-integer β raisesRuntimeError.
The docstring for group_size in Resources.arginfo() summarizes this concisely:
"How many tasks are packed into one scheduler job. For example, 20 tasks with group_size=5 are typically split into 4 jobs. Use 1 for the simplest one-task workflow. 0 means no explicit upper limit in the grouping logic."
para_deg: Parallelism Within a Job#
All task commands in the generated script run as background processes (&) . para_deg controls the cadence of wait barriers between them.
gen_script_wait() implements this:
- Increments an internal counter
resources.task_in_paraafter each task. - When the counter reaches
para_deg, it resets to 0 and emits"wait \n". - Otherwise it emits nothing (tasks keep accumulating in the background).
A final wait at the end of every script ensures all processes complete before job-completion tags are checked.
The para_deg docstring distinguishes it from group_size clearly :
"
group_sizecontrols how many tasks are bundled into a job, whilepara_degcontrols concurrency within that job. Keeppara_deg=1for the safest default."
Multi-GPU: if_cuda_multi_devices#
When strategy["if_cuda_multi_devices"] = True, gen_script_wait() also manages GPU assignment :
- Before each task,
gen_command_env_cuda_devices()prependsexport CUDA_VISIBLE_DEVICES=<gpu_index>;based ongpu_in_use % gpu_per_node. - A
waitbarrier is only emitted whentask_in_para >= para_degand thegpu_in_usecounter wraps aroundgpu_per_nodeβ i.e., all GPUs on the node have been cycled through.
Constraints enforced at Resources.__init__() : if_cuda_multi_devices requires gpu_per_node >= 1 and number_node == 1.
Practical Patterns#
| Scenario | group_size | para_deg | Notes |
|---|---|---|---|
| Conservative HPC (one task per job) | 1 | 1 | Simplest; each task is its own scheduler job |
| All tasks in one job, sequential | 0 | 1 | Single job, tasks run one at a time |
| Multi-GPU workstation (8 GPUs, 6 tasks/GPU) | 0 | 6 | if_cuda_multi_devices=True; one job handles everything |
| Balanced HPC batching | 20 | 4 | 20-task jobs, 4 tasks running in parallel at any time |
The workstation example is documented at Running multiple MD tasks on a GPU workstation .
Key Source References#
| File | Purpose |
|---|---|
dpdispatcher/submission.py | Submission.generate_jobs(), Resources class definition |
dpdispatcher/machine.py | gen_script_wait(), gen_command_env_cuda_devices(), script templates |
| Resources parameters (docs) | Official parameter reference |