Gaël Cousin
03/18/2026, 2:53 PMNate
03/18/2026, 5:05 PMMarvin
03/18/2026, 5:06 PMMarvin
03/18/2026, 5:06 PMNate
03/18/2026, 5:06 PMMarvin
03/18/2026, 5:06 PMMarvin
03/18/2026, 5:09 PMprefect work-pool create slurm-process-pool --type process
- Submit Slurm jobs that just start a worker (use arrays to scale N workers):
#!/bin/bash
#SBATCH --job-name=prefect-worker
#SBATCH --partition=compute
#SBATCH --time=08:00:00
#SBATCH --cpus-per-task=8
#SBATCH --mem=32G
#SBATCH --output=/path/to/logs/prefect-%A_%a.out
module load python/3.11 # if needed
source /path/to/venv/bin/activate
export PREFECT_API_URL="<https://api.prefect.cloud/api/accounts/.../workspaces/...>"
export PREFECT_API_KEY="***"
# Optionally pin to a specific work queue and concurrency limit
prefect worker start --pool slurm-process-pool --limit 1
- Scale by submitting an array (e.g., --array=1-10) so you get 10 workers.
- Pros: No custom code; leverages Slurm to schedule worker capacity; very stable.
- Tradeoff: Each flow run does not get its own Slurm job; runs share the allocation of the worker that picks them up.
2) Custom Slurm worker that submits each flow run as an sbatch job
- When to use: you want one Slurm job per flow run with Slurm-native isolation (partition/account/time/mem) and lifecycle tracking.
- How it looks (outline):
- Implement a BaseWorker subclass that:
- Builds an sbatch script using the flow run’s command and your Slurm params
- Calls sbatch to submit
- Monitors status via squeue/sacct/scontrol
- Returns a BaseWorkerResult with the Slurm job ID and exit code
- Minimal skeleton:
```
from pydantic import Field
from prefect.workers.base import BaseWorker, BaseJobConfiguration, BaseVariables, BaseWorkerResult
import anyio, asyncio
class SlurmJobConfiguration(BaseJobConfiguration):
partition: str = Field(default="compute")
time_limit: str = Field(default="010000")
cpus_per_task: int = Field(default=1)
mem: str = Field(default="4G")
class SlurmVariables(BaseVariables):
partition: str = Field(default="compute")
time_limit: str = Field(default="010000")
cpus_per_task: int = Field(default=1)
mem: str = Field(default="4G")
class SlurmWorkerResult(BaseWorkerResult):
slurm_job_id: str | None = None
class SlurmWorker(BaseWorker):
type = "slurm"
job_configuration = SlurmJobConfiguration
job_configuration_variables = SlurmVariables
async def run(self, flow_run, configuration, task_status=anyio.TASK_STATUS_IGNORED):
sbatch_script = self._build_sbatch_script(configuration, command=configuration.command)
job_id, submit_out = await self._submit_sbatch(sbatch_script)
if task_status:
task_status.started(job_id)
exit_code = await self._wait_for_completion(job_id)
return SlurmWorkerResult(status_code=exit_code, identifier=job_id, slurm_job_id=job_id)
def _build_sbatch_script(self, cfg, command: str) -> str:
lines = [
"#!/bin/bash",
f"#SBATCH --job-name={cfg.name or 'prefect-flow'}",
f"#SBATCH --partition={cfg.partition}",
f"#SBATCH --time={cfg.time_limit}",
f"#SBATCH --cpus-per-task={cfg.cpus_per_task}",
f"#SBATCH --mem={cfg.mem}",
]
for k, v in (cfg.env or {}).items():
lines.append(f"export {k}={v}")
lines.append(command)
return "\n".join(lines) + "\n"Marvin
03/18/2026, 5:09 PM- Register via entry points so the CLI discovers it, then:
prefect work-pool create slurm-pool --type slurm
prefect worker start --pool slurm-pool
```
- Pros: True “one flow run = one Slurm job”; native resource controls per run.
- Tradeoff: You maintain a small plugin.
Helpful docs:
- Custom worker guide: Developing a custom worker (Prefect 3)
- Work pools and base job templates: Manage work pools
- Worker concepts: Workers concept
Quick check of CLI:
- Create a pool: prefect work-pool create NAME --type <type> (verified with --help)
- Start a worker: prefect worker start --pool NAME (type comes from the pool)
Which model are you aiming for?
- A) Workers themselves scheduled by Slurm (simplest; use process pool + sbatch)
- B) Each flow run is a Slurm job (requires a small custom worker)
If you pick one, I can sketch a minimal repo (pyproject + worker class + template) or an sbatch array script tailored to your cluster config.