Warning, /AID2E-framework/docs/user-guide/schedulers.md is written in an unsupported language. File is not indexed.
0001 # Schedulers
0002
0003 ## Overview
0004
0005 The scheduler configuration defines how AID2E executes optimization jobs. The framework supports three execution backends:
0006
0007 1. **JobLibRunner** - Local parallel execution using Python's joblib library
0008 2. **SlurmRunner** - HPC cluster execution through the Slurm workload manager
0009 3. **PanDAiDDSRunner** - Distributed execution across multiple sites via PanDA iDDS
0010
0011 ## Configuration
0012
0013 The `scheduler` section in your configuration file defines runner settings:
0014
0015 ```yaml
0016 scheduler:
0017 runner_type: "JobLibRunner" # or "SlurmRunner" or "PanDAiDDSRunner"
0018 parameters: {} # Runner-specific settings
0019 ```
0020
0021 `SchedulerConfiguration` also accepts:
0022
0023 - `max_retries` (`int`, default `3`): Caps the stage `retry_max` policy passed to scheduler runners. The current runners do not resubmit jobs from this setting.
0024 - `output_location` (`str`, default `"./scheduler_output"`): Common output setting; execution directories currently come from the problem and workflow runtime.
0025 - `monitor_interval` (`int`, default `30`): Common monitoring setting; runner or stage polling settings control the actual polling interval.
0026
0027 ### Scheduler Cascade
0028
0029 Schedulers can be set globally or for a workflow, branch, or stage. A stage scheduler overrides the branch, workflow, and global schedulers, in that order. See the [workflow guide](workflows.md#scheduler-cascade) for examples.
0030
0031 ### Parallelism and Failure Behavior
0032
0033 Workflow stages define `parallelism.max_concurrent`, `parallelism.retry_max`, `parallelism.timeout_sec`, and `parallelism.poll_interval`. `DAGExecutor` forwards these values to `run_stage()` as a parallelism policy.
0034
0035 - JobLib applies `max_concurrent`, but only logs `retry_max`; it does not retry failed jobs. `JobLibRunnerConfig.timeout` applies to command subprocesses, but not Python callable jobs. The stage `timeout_sec` is not currently used.
0036 - Slurm uses the stage `poll_interval` while waiting for terminal job states. It does not currently apply `max_concurrent`, retries, or `timeout_sec`.
0037 - PanDA uses `poll_interval` while waiting for submitted function jobs and `max_concurrent` to limit concurrent multistage graphs. It does not currently resubmit failed jobs from `retry_max`.
0038
0039 For scheduler-backed stages, `DAGExecutor` forwards the stage `poll_interval` (default `5` seconds), overriding the runner default.
0040
0041 Direct workflow execution has an attempt loop. A failed scheduler stage is returned to `DAGExecutor` and fails the workflow. Optimizer-level failed-trial handling is documented separately in the [optimizer guide](optimizers.md#failed-and-penalized-trials).
0042
0043 `aid2e optimize` rejects a configuration without a scheduler at runtime because optimization execution requires a scheduler.
0044
0045 ## JobLib
0046
0047 **Best for:** Single-machine parallel execution with multiple CPU cores
0048
0049 ### Configuration
0050
0051 - `n_jobs` (`int`, default `-1`): Number of jobs to run in parallel. `-1` uses all available processors.
0052 - `backend` (`str`, default `"loky"`): JobLib backend, normally `loky`, `threading`, or `multiprocessing`.
0053 - `timeout` (`int` or `None`, default `None`): Timeout for command jobs; not applied to Python callable jobs.
0054 - `verbose` (`int`, default `0`): Verbosity level from 0 to 11 for joblib logging.
0055
0056 Example:
0057
0058 ```yaml
0059 scheduler:
0060 runner_type: "JobLibRunner"
0061 parameters:
0062 n_jobs: 8 # Use 8 CPU cores
0063 backend: "loky" # Robust multiprocessing backend
0064 timeout: 3600 # 1 hour timeout per job
0065 verbose: 1 # Joblib logging
0066 ```
0067
0068 ### When to Use
0069
0070 - Development and testing on local machines
0071 - Single-node multi-core systems
0072 - Quick prototyping with manageable problem sizes
0073 - Integration testing in CI/CD pipelines
0074
0075 ### JobLib Tips
0076
0077 - Python `function` jobs with `params` and command jobs both execute locally.
0078 - `run_stage()` returns after every job has completed or failed.
0079 - A stage's `parallelism.max_concurrent` setting caps the configured `n_jobs` value when that limit is present.
0080
0081 ## Slurm
0082
0083 **Best for:** HPC cluster execution with job queuing and resource allocation
0084
0085 ### Configuration
0086
0087 - `partition` (`str` or `None`, default `None`): Slurm partition or queue name.
0088 - `account` (`str` or `None`, default `None`): Slurm account to charge.
0089 - `qos` (`str` or `None`, default `None`): Slurm quality-of-service value.
0090 - `nodes` (`int`, default `1`): Number of nodes requested.
0091 - `ntasks` (`int`, default `1`): Number of tasks to run.
0092 - `cpus_per_task` (`int` or `None`, default `None`): CPU cores per task.
0093 - `mem` (`str` or `None`, default `None`): Memory request, for example `4G`.
0094 - `time` (`str` or `None`, default `None`): Wall clock time limit in `HH:MM:SS` format.
0095 - `gres` (`str` or `None`, default `None`): Generic resource, for example `gpu:1` for one GPU.
0096 - `constraint` (`str` or `None`, default `None`): Optional node constraint.
0097 - `job_name_prefix` (`str`, default `"aid2e"`): Prefix for generated Slurm job names for tracking.
0098 - `setup_commands` (`list[str]`, default `[]`): Commands written before the workload command.
0099 - `submit_working_dir` (`str` or `None`, default `None`): Directory used for `sbatch` and generated scripts.
0100 - `runtime_working_dir` (`str` or `None`, default `None`): Directory used by the workload at runtime.
0101 - `poll_interval` (`int`, default `5`): Stage status polling interval in seconds.
0102 - `sbatch_extra_args` (`list[str]`, default `[]`): Additional `sbatch` command arguments.
0103 - `capture_stdout` (`bool`, default `true`): Write scheduler-owned standard-output logs.
0104 - `capture_stderr` (`bool`, default `true`): Write scheduler-owned standard-error logs.
0105
0106 `SchedulerConfigLoader` also accepts `template_file` inside Slurm parameters. The file must contain a JSON object. Its values are loaded first and inline parameters override them before `SlurmRunnerConfig` validation. Individual job resource values can override the corresponding runner-level resource fields.
0107
0108 Example:
0109
0110 ```yaml
0111 scheduler:
0112 runner_type: "SlurmRunner"
0113 parameters:
0114 partition: "gpu"
0115 nodes: 1
0116 ntasks: 1
0117 cpus_per_task: 8
0118 mem: "32G"
0119 time: "12:00:00"
0120 gres: "gpu:1"
0121 poll_interval: 60
0122 ```
0123
0124 ### When to Use
0125
0126 - Production runs on HPC clusters
0127 - Large-scale optimization problems
0128 - GPU-accelerated evaluations
0129 - Jobs requiring specific resource constraints
0130 - When you need job queuing and fair scheduling
0131
0132 ### Slurm Tips
0133
0134 Command jobs and Python `function` jobs with `params` are submitted through `sbatch`. The submission host requires `sbatch`, `squeue`, and `sacct`; cancellation uses `scancel`. Callable jobs require an importable module function and JSON-serializable parameters. The Python environment and handoff paths must also be available on compute nodes.
0135
0136 Useful Slurm commands:
0137
0138 - Check available partitions: `sinfo`
0139 - Monitor submitted jobs: `squeue`
0140 - View available GPUs: `sinfo --gres`
0141 - Inspect a job: `scontrol show job <job_id>`
0142
0143 ## PanDA/iDDS
0144
0145 **Best for:** Distributed execution across multiple computing sites with automated load balancing
0146
0147 ### Client Setup
0148
0149 For the checked-in PanDA examples, initialize the client environment before running the CLI:
0150
0151 ```bash
0152 source examples/dtlz2/schedulers/panda-idds/setup_panda.sh
0153 export PANDA_USERNAME=your_panda_username # Optional account-name override
0154 aid2e optimize examples/dtlz2/configurations/dtlz2_ax_panda.yml
0155 ```
0156
0157 The setup script contains shared BNL PanDA endpoint and OIDC settings. It does not set a personal PanDA username.
0158
0159 ### Configuration
0160
0161 | Field | Type | Default | Description |
0162 |-------|------|---------|-------------|
0163 | `name` | string | auto-generated | Job name; explicit names must start with `user.` |
0164 | `init_env` | string/list/callable | None | Worker environment initialization; no setup commands are prepended |
0165 | `post_script` | string/callable | cleanup command | Worker cleanup; defaults to `rm -fr .local .venv src examples tests docs` |
0166 | `working_group` | string | "AID2E" | PanDA working group |
0167 | `task_type` | string | "AID2E" | Type of processing (PanDA classification) |
0168 | `cloud` | string | None | PanDA cloud/region |
0169 | `queue` | string | None | PanDA queue; choose one available to your account |
0170 | `init_env_file` | path | None | YAML list or plain-text file of environment commands, resolved relative to the scheduler config file; mutually exclusive with `init_env` |
0171 | `source_dir` | string | cwd/src or cwd | Directory to upload; `PANDA_SOURCE_DIR` overrides the default |
0172 | `max_walltime` | int | None | Maximum walltime in seconds |
0173 | `core_count` | int | 1 | CPU cores per job |
0174 | `total_memory` | int | 4000 | Memory in MB per job |
0175 | `enable_separate_log` | bool | true | Enable separate log files |
0176 | `job_dir` | string | None | Job working directory |
0177 | `source_dir_parent_level` | int | 1 | Parent levels to include |
0178 | `exclude_source_files` | list | See config defaults below | File patterns to exclude (.venv, venv, .git included) |
0179
0180 ### Example
0181
0182 ```yaml
0183 scheduler:
0184 runner_type: "PanDAiDDSRunner"
0185 parameters:
0186 name: "user.scientist.experiment" # Must start with 'user.'
0187 cloud: "US"
0188 queue: "BNL_PanDA_1"
0189 source_dir: null # cwd/src when present, otherwise cwd
0190 source_dir_parent_level: 1
0191 exclude_source_files:
0192 - "(^|/)\\..*" # Hidden files
0193 - ".*\\.log"
0194 - "__pycache__"
0195 max_walltime: 7200
0196 core_count: 4
0197 total_memory: 8000
0198 enable_separate_log: true
0199 job_dir: "/tmp/panda_jobs"
0200 ```
0201
0202 ### Generated Names and Worker Environment
0203
0204 When `name` is omitted, it becomes `user.<username>.aid2e_job`. The username comes from `PANDA_USERNAME`, or the system account when unset. Set `name` explicitly for a different suffix.
0205
0206 `source_dir` defaults to `PANDA_SOURCE_DIR` if set, then `cwd/src` when that directory exists, otherwise `cwd`. Set it explicitly if workers also need examples or other files outside `src`. `exclude_source_files` controls archive exclusions; inspect the [config defaults](https://github.com/aid2e/AID2E-framework/blob/main/src/aid2e/schedulers/PanDAiDDS/config.py) before packaging inputs.
0207
0208 Worker setup must be provided through `init_env` or `init_env_file`; no setup script is automatically prepended. A command list is joined with spaces, so include shell separators where needed:
0209
0210 ```yaml
0211 parameters:
0212 init_env:
0213 - "source setup_aid2e.sh &&"
0214 - "export MY_VAR=value"
0215 ```
0216
0217 `init_env_file` accepts a YAML list, a YAML string or `init_env` mapping, or a plain-text file of commands. Its path is relative to the configuration file. Do not specify both `init_env` and `init_env_file`.
0218
0219 ### All-to-One Dataset Inputs
0220
0221 For an `all2one` dataset dependency, YAML may group multiple parent datasets under the callable argument that should receive their files:
0222
0223 ```yaml
0224 dep_type: "datasets"
0225 dep_map: "all2one"
0226 input_datasets:
0227 input_file_names:
0228 - "user.example.simreco.a"
0229 - "user.example.simreco.b"
0230 ```
0231
0232 The PanDA adapter expands this list into separate string-valued iDDS input maps during submission. On the worker, it combines the injected file lists and calls the evaluator with `input_file_names=[...]`. This translation applies only to `all2one`; ordinary string-valued dataset mappings are unchanged.
0233
0234 ### Examples and Queues
0235
0236 See the [scheduler configuration](https://github.com/aid2e/AID2E-framework/blob/main/examples/dtlz2/schedulers/panda-idds/panda_scheduler_config.yml) and [CLI workflow](https://github.com/aid2e/AID2E-framework/blob/main/examples/dtlz2/configurations/dtlz2_ax_panda.yml). The checked-in examples use BNL settings; choose a queue and cloud available to your account with your PanDA administrator.
0237
0238 ### Inspecting Requests, Tasks, and Jobs
0239
0240 The read-only diagnostic script follows the iDDS/PanDA identifier chain from a request to its transforms, JEDI tasks, and PanDA jobs. Source the project and PanDA environments first:
0241
0242 ```bash
0243 source setup_aid2e.sh
0244 source examples/dtlz2/schedulers/panda-idds/setup_panda.sh
0245 ```
0246
0247 Query a complete iDDS request:
0248
0249 ```bash
0250 python examples/dtlz2/schedulers/panda-idds/check_panda_jobs.py --request-id 3665
0251 ```
0252
0253 The script also accepts narrower identifiers:
0254
0255 ```bash
0256 python examples/dtlz2/schedulers/panda-idds/check_panda_jobs.py --request-id 3665 --transform-id 32469
0257 python examples/dtlz2/schedulers/panda-idds/check_panda_jobs.py --jedi-task-id 40758
0258 python examples/dtlz2/schedulers/panda-idds/check_panda_jobs.py --job-id 4879003
0259 ```
0260
0261 `--task-id` and `--runtaskid` are aliases for `--request-id`, not JEDI task IDs. Use `--max-jobs N` to bound job-detail queries. The output is JSON so it can also be filtered with tools such as `jq`.
0262
0263 ## Python API
0264
0265 See [scheduler notes](notes/schedulers.md#python-api) for loading scheduler configurations and constructing runner configuration objects in Python.
0266
0267 ## Troubleshooting
0268
0269 ### Invalid Runner Type
0270
0271 Check spelling and case. Valid values are:
0272
0273 - `JobLibRunner`
0274 - `SlurmRunner`
0275 - `PanDAiDDSRunner`
0276
0277 ### JobLib Command Timeout
0278
0279 If the command needs more time, increase `timeout`. This setting does not interrupt Python callable jobs:
0280
0281 ```yaml
0282 scheduler:
0283 runner_type: "JobLibRunner"
0284 parameters:
0285 timeout: 7200 # Increase to 2 hours
0286 ```
0287
0288 ### Slurm Job Not Starting
0289
0290 Check partition availability and resource requests:
0291
0292 ```bash
0293 sinfo # Check available partitions
0294 sinfo --gres # Check GPU availability
0295 ```
0296
0297 ### PanDA Task Failure
0298
0299 Inspect the request and worker logs using the [PanDA diagnostic script](#inspecting-requests-tasks-and-jobs). If the job exceeded its walltime, adjust:
0300
0301 ```yaml
0302 scheduler:
0303 runner_type: "PanDAiDDSRunner"
0304 parameters:
0305 max_walltime: 7200
0306 ```
0307
0308 ## See Also
0309
0310 - [Configuration Guide](configuration.md)
0311 - [Workflow Guide](workflows.md)
0312 - [Optimizer Guide](optimizers.md)
0313 - [DTLZ2 configuration](https://github.com/aid2e/AID2E-framework/blob/main/examples/dtlz2/configurations/dtlz2_ax_constraints.yml)
0314 - [dRICH workflow](https://github.com/aid2e/AID2E-framework/blob/main/examples/epic/drich/workflow.yml)
0315 - [PanDA Documentation](https://panda-wms.readthedocs.io/)
0316 - [iDDS Documentation](https://idds.readthedocs.io/)