Hitesh Sahu
Hitesh SahuHitesh Sahu
  1. Home
  2. ›
  3. posts
  4. ›
  5. …

  6. ›
  7. 2 12 Slurm

Loading ⏳
Fetching content, this won’t take long…


💡 Did you know?

🐙 Octopuses have three hearts and blue blood.

🍪 This website uses cookies

No personal data is stored on our servers however third party tools Google Analytics cookies to measure traffic and improve your website experience. Learn more

Loading ⏳
Fetching content, this won’t take long…


💡 Did you know?

🦈 Sharks existed before trees 🌳.
AI-Infrastructure

    AI-AgenticAI

    AI-DeepLearning

    AI-GenAI

    AI-Infrastructure
    • NVIDIA AI Infrastructure and Operations Fundamentals

    • AI Infra Computing : GPU, DPU, Virtualization, DGX Systems

    • AI Programming Model

    • Pinned Memory (Page-Locked Memory) in CUDA and GPU Computing

    • RAPIDS and GPU Accelerated Data Science: cuDF, cuML, CUDA, NCCL and Distributed AI Pipelines

    • NVIDIA DCGM: GPU Health, Diagnostics, and Prometheus Metrics

    • NVIDIA Base Command Manager: Provisioning and Operating GPU Clusters

    • Slurm: The HPC Workload Manager Behind AI Training Clusters

    • TensorRT and High-Performance AI Inference: CUDA, ONNX, TensorRT-LLM and GPU Optimization

    • NCCL and Distributed GPU Communication: CUDA, AllReduce, Multi-GPU and AI Cluster Networking

    • ONNX (Open Neural Network Exchange): Portable AI Models, TensorRT and Cross-Framework Inference

    • LangChain and AI Agent Orchestration: RAG, LLM Workflows, Vector Databases and Tool Calling

    • NVIDIA NeMo and Enterprise AI Platforms: Distributed LLM Training, RAG and TensorRT-LLM

    • Megatron-LM and Distributed LLM Training: Tensor Parallelism, NCCL and Trillion-Scale AI Models

    • NVIDIA Triton Inference Server: TensorRT-LLM, GPU Serving and Production AI Inference

    • NVIDIA Riva: Real-Time Conversational AI with ASR, NLP and Text-to-Speech

    • NVIDIA NGC Catalog: GPU Optimized Containers, AI Models and Enterprise AI Infrastructure

    • AI Infra Networking: GPU Clusters, InfiniBand, RoCE, and DPU Integration

    • AI Infra Storage: NVMe, Parallel File Systems, Object Storage, and GPUDirect Storage

    • AI/ML Operations

    • AI-Infrastructure Index


    AI-Machine-Learning

    AI-Math

    AWS

    Azure

    Hobbies

    kubernetes

    Management

    Programming

    Terraform

    Z_Appendix

    0-root

Cover Image for Slurm: The HPC Workload Manager Behind AI Training Clusters
AI-Infrastructure

Slurm: The HPC Workload Manager Behind AI Training Clusters

Slurm from the ground up — the controller/node-daemon architecture, partitions and QOS, job submission with sbatch/srun/salloc, GPU allocation with GRES, multi-node MPI jobs, running containers under Slurm with enroot and pyxis, multifactor job priority, preemption, job arrays and dependencies, node health and cgroup enforcement, topology-aware scheduling, the slurmrestd API, Slurm vs Kubernetes, and a set of interview questions with answers.

Slurm
HPC
NVIDIA
MPI
GPU
Job Scheduling
Next →

NVIDIA Base Command Manager: Provisioning and Operating GPU Clusters

Slurm

Slurm is a HPC workload management system behind AI Training Clusters

Kubernetes schedules long-running services.

Large-scale AI training jobs and HPC simulations are the opposite shape — a job runs to completion across hundreds of nodes and then exits.

Slurm (Simple Linux Utility for Resource Management) is the scheduler purpose-built for that shape, and it's still the default on most supercomputers and dedicated AI training clusters, DGX SuperPODs included.

  • Slurm Official Docs

  • Developed originally at the Lawrence Livermore National Laboratory.


Why Not Just Use Kubernetes?

Kubernetes' scheduling unit is a Pod that's expected to run indefinitely, restarted on failure, load-balanced by a Service.

A Slurm job is the opposite: submitted once, allocated a fixed set of nodes for its duration, and expected to finish — there's no restart policy because there's no "desired state" to reconcile back to, just a batch of work that either completes or fails.

Slurm Kubernetes
Primary purpose Batch job scheduling Container orchestration
Typical AI phase Training Inference / serving
Execution model Run-to-completion Always-on, self-healing
Scheduling unit Job (nodes, CPUs, GPUs) Pod
Resource allocation Whole nodes / GPUs per job Containers / requests-limits
Multi-node coordination Native (MPI-aware launch) Requires an operator (PyTorchJob, MPIJob)
Interface sbatch, srun, squeue kubectl, Helm, APIs
Typical users HPC/research teams Platform/DevOps/MLOps teams

Neither replaces the other on a real DGX cluster — it's common to run Slurm for the training partition and Kubernetes for the inference partition of the same physical hardware, with NVIDIA Base Command Manager provisioning both from one head node.


Architecture

flowchart TD

    User["Researcher <br/> sbatch train.sh"]
    User-->slurmctld["slurmctld <br/> (controller — scheduling decisions)"]
    slurmctld-->slurmdbd["slurmdbd <br/> (accounting database)"]

    slurmctld-->Node1["slurmd <br/> Compute Node 1"]
    slurmctld-->Node2["slurmd <br/> Compute Node 2"]
    slurmctld-->NodeN["slurmd <br/> Compute Node N"]
Component Role
slurmctld The controller — makes all scheduling decisions, tracks node/partition state
slurmd Runs on every compute node — launches and monitors the job's processes locally
slurmdbd Accounting database — job history, usage, fair-share tracking
Partition A named subset of nodes (e.g. gpu, cpu, debug) jobs are submitted into

A job never talks to slurmd directly — it's submitted to slurmctld, which decides which nodes' slurmd processes actually launch it.


Submitting Jobs

Slurm has both a graphical interface and command line tools for submitting, monitoring, modifying and deleting jobs

It is normally used with job scripts to submit and execute jobs.

Various settings can be put in the job script, such as

  • number of processors
  • resource usage
  • application specific variables.

The steps for running a job through Slurm are to:

  • Create the script or executable that will be handled as a job
  • Create a job script that sets the resources for the script/executable
  • Submit the job script to the workload management system

Three commands cover almost everything:

Command Use
sbatch Submit a batch script, runs asynchronously, returns immediately with a job ID
srun Run a command interactively/synchronously, optionally inside an sbatch script to launch the actual parallel job step
salloc Allocate resources for an interactive session without running a script

A minimal GPU training job:

#!/bin/bash
#SBATCH --job-name=llama3-train
#SBATCH --partition=gpu
#SBATCH --nodes=4
#SBATCH --ntasks-per-node=8
#SBATCH --gres=gpu:8
#SBATCH --cpus-per-task=16
#SBATCH --time=24:00:00
#SBATCH --output=train-%j.log

srun python train.py --model llama3-70b --nodes $SLURM_NNODES
sbatch train.sh          # submit — returns a job ID immediately
squeue                   # see queued/running jobs
sinfo                    # see node/partition state
scancel 12345            # cancel a job
sacct -j 12345 --format=JobID,Elapsed,State,MaxRSS   # accounting history

--gres=gpu:8 is a Generic Resource (GRES) request — Slurm's mechanism for allocating non-CPU resources (GPUs, but also things like Infiniband adapters) per job, the same underlying concept as nvidia.com/gpu resource requests in Kubernetes, just at the node-allocation level rather than the container level.


Multi-Node MPI Jobs

MPI (Message Passing Interface) is the standard API for processes running on different nodes to exchange data — point-to-point sends/receives and collective operations like broadcast and all-reduce. Distributed training across many nodes needs exactly this: every rank starting at the same time, knowing its rank and world size, and able to talk to every other rank. Slurm handles the launch and rank-discovery side of that natively.

Two Ways to Launch an MPI Job Under Slurm

Approach How it works
Native srun launch Slurm itself launches one process per task directly via srun, and exports rank/size information through the PMI (Process Management Interface) so the MPI library initializes against Slurm's own launch mechanism
mpirun inside an allocation salloc/sbatch only reserves the nodes; Open MPI's own mpirun launcher (running inside that allocation) does the actual process launch and rank assignment, using Slurm only as the resource allocator underneath
# Approach 1: native srun launch — Slurm launches every rank directly
#SBATCH --nodes=4
#SBATCH --ntasks-per-node=8
srun --mpi=pmix ./mpi_app

# Approach 2: mpirun inside a Slurm allocation — Open MPI does its own launch
#SBATCH --nodes=4
#SBATCH --ntasks-per-node=8
mpirun -np 32 ./mpi_app

Native srun launch is generally preferred at scale — it avoids mpirun having to SSH into every node itself, since Slurm already has a process on every allocated node ready to launch the job.

PMI, PMI2, and PMIx

The Process Management Interface is the actual protocol Slurm and the MPI runtime use to agree on ranks and exchange the connection information each process needs to find every other process:

Version Notes
pmi (v1) Original protocol, limited scalability
pmi2 Improved scalability, still widely supported
pmix Current standard — faster startup at large rank counts, and what NCCL's Slurm integration also relies on

srun --mpi=list shows exactly which PMI versions a given Slurm installation was built with support for — mismatching this against what the MPI library expects is a common source of "job hangs at startup with zero output" failures.

A Real MPI Example

Before the PyTorch-specific launcher, the same rank/size pattern in raw MPI, using mpi4py:

#!/bin/bash
#SBATCH --nodes=4
#SBATCH --ntasks-per-node=8
#SBATCH --gres=gpu:8

srun --mpi=pmix python -c "
from mpi4py import MPI
comm = MPI.COMM_WORLD
print(f'Rank {comm.Get_rank()} of {comm.Get_size()} on {MPI.Get_processor_name()}')
"

Every task prints its own rank and the total world size — 32 lines of output, one per task across the 4 nodes, with no explicit hostfile: Slurm already told each mpi4py process its rank and how to reach the others via PMIx.

The GPU training case is the same launch mechanism, just with a deep learning framework instead of raw MPI collectives:

#!/bin/bash
#SBATCH --nodes=8
#SBATCH --ntasks-per-node=8      # 8 GPUs per node = 8 tasks per node
#SBATCH --gres=gpu:8

# srun launches one task per GPU across all 8 nodes simultaneously,
# and sets up the process ranks MPI/NCCL need to find each other.
srun --mpi=pmix python -m torch.distributed.run \
    --nnodes=$SLURM_NNODES \
    --nproc_per_node=8 \
    train.py

Slurm's --mpi=pmix flag wires up PMIx so an MPI runtime — or NCCL, which is not MPI but bootstraps its own rank/host discovery through the same PMIx handshake — can establish collective communication across all 64 GPUs without a separate discovery step. This is the same rank-0/AllReduce coordination problem covered in Multi-Node Distributed Training on Kubernetes, just solved at the scheduler level instead of via a Kubernetes operator.

Slurm vs MPI Environment Variables

Both Slurm and the MPI runtime expose rank/size information, under different variable names — worth knowing which is which when debugging a launch:

Concept Slurm variable Typical Open MPI variable
This process's rank SLURM_PROCID OMPI_COMM_WORLD_RANK
Total number of ranks SLURM_NTASKS OMPI_COMM_WORLD_SIZE
Rank within this node SLURM_LOCALID OMPI_COMM_WORLD_LOCAL_RANK
Node count SLURM_NNODES —

Frameworks like PyTorch's torch.distributed.run read whichever set is present to figure out RANK/WORLD_SIZE/LOCAL_RANK — which is why the same launch script works whether Slurm or mpirun did the actual process spawning underneath it.


Running Containers Under Slurm: enroot and pyxis

HPC clusters didn't traditionally run Docker — no root daemon, no arbitrary privilege escalation on shared supercomputers.

NVIDIA's answer is two pieces that plug directly into Slurm:

flowchart TD

    Image["Container image <br/> (Docker/OCI)"]
    Image-->|"enroot import"| Squashfs["Unprivileged squashfs <br/> root filesystem"]
    Squashfs-->|"enroot start"| Sandbox["Unprivileged container <br/> (no root daemon)"]

    Pyxis["pyxis <br/> (Slurm SPANK plugin)"]
    Pyxis-->|"wires enroot into srun"| Sandbox

1. enroot

Converts a standard container image into an unprivileged sandbox a regular user can run

  • with no root daemon
  • no elevated privileges required, unlike Docker.

2. pyxis

A Slurm SPANK plugin that adds container-aware flags directly to srun, so launching a containerized job looks like any other Slurm job:

srun --container-image=nvcr.io/nvidia/pytorch:24.01-py3 \
     --container-mounts=/data:/data \
     python train.py

This is the direct HPC-world equivalent of a Kubernetes Pod's container spec — same idea (run this image, mount this volume), different enforcement model (unprivileged squashfs instead of a container runtime daemon)

Because the constraint is "thousands of untrusted users share this supercomputer" rather than "one team owns this cluster."


Scheduling: Partitions, QOS, and Fair-Share

Slurm's scheduler has to decide, across potentially thousands of queued jobs, whose job runs next:

Concept What it controls
Partition Which pool of nodes a job can run on (gpu, cpu, debug)
QOS (Quality of Service) Priority tier, max job time, max resources per user/QOS
Fair-share Users/groups who've consumed less cluster time recently get scheduled ahead of heavy recent users
Backfill scheduling Smaller/shorter jobs get slotted into gaps ahead of a large job still waiting for enough free nodes, without delaying that large job's eventual start

Backfill is what keeps utilization high on a cluster with a mix of quick debug jobs and week-long training runs — without it, a single queued 512-GPU job would leave every smaller job waiting behind it even while most of the cluster sits idle.


Job Priority — The Multifactor Plugin

"Fair-share" is one input into a larger formula. Slurm's default scheduler plugin computes a single priority number per job from several weighted factors:

Job Priority = (Age Weight × Age Factor)
             + (Fair-share Weight × Fair-share Factor)
             + (QOS Weight × QOS Factor)
             + (Partition Weight × Partition Factor)
             + (Job Size Weight × Size Factor)
Factor Grows as…
Age A job sits in the queue longer — prevents starvation
Fair-share A user/group has consumed less recent cluster time than their allocated share
QOS The job's Quality of Service tier is weighted higher (e.g. qos=urgent outranks qos=normal)
Partition The partition itself carries a configured weight (a debug partition might be weighted low)
Job size Configurable either way — some clusters favor large jobs to keep utilization high, others favor small jobs to reduce turnaround time

sprio -l shows the actual computed breakdown per queued job — the single most useful command for answering "why is my job still waiting" when several hundred jobs are queued ahead of it.


Preemption

On a shared cluster, a lower-priority job already running can be told to make way for a higher-priority one, rather than the higher-priority job simply waiting:

Preemption Mode What happens to the lower-priority job
SUSPEND Frozen in place (process suspended), resumed later when resources free up
REQUEUE Killed and re-submitted from the start — only safe for jobs that checkpoint or are cheap to restart
CANCEL Killed outright, not resubmitted

Preemption is configured per-QOS (PreemptMode, GraceTime in slurm.conf) — a common pattern is a low qos=preemptible tier for exploratory/best-effort jobs that get suspended the moment a qos=production training job needs those nodes, similar in spirit to how Kubernetes Pod priority/preemption evicts lower-priority Pods, just enforced against whole-node batch jobs instead of Pods.


Job Arrays and Dependencies

Two patterns come up constantly in ML workflows: sweeping many similar jobs, and chaining stages that depend on each other.

Job arrays — one sbatch submission, many independent tasks (a hyperparameter sweep is the canonical example):

#!/bin/bash
#SBATCH --job-name=hparam-sweep
#SBATCH --array=0-9                # 10 tasks, indices 0..9
#SBATCH --gres=gpu:1

LR_VALUES=(0.001 0.003 0.01 0.03 0.1 0.0003 0.0001 0.03 0.3 1.0)
srun python train.py --lr ${LR_VALUES[$SLURM_ARRAY_TASK_ID]}

Each array task gets its own $SLURM_ARRAY_TASK_ID, its own log file, and is scheduled independently — a failure in task 7 doesn't affect the other nine.

Job dependencies — chain a pipeline so evaluation only starts after training actually succeeds:

TRAIN_JOB=$(sbatch --parsable train.sh)
sbatch --dependency=afterok:$TRAIN_JOB evaluate.sh

afterok only releases the dependent job if the upstream job exited with status 0 — afterany runs regardless of exit status, afternotok runs only if it failed (useful for an alerting/cleanup job).


Node States and Health

Every node Slurm manages is in exactly one state, and the scheduler only places jobs on nodes in a schedulable state:

State Meaning
IDLE No jobs running, available
ALLOCATED Fully allocated to running job(s)
MIXED Partially allocated — some CPUs/GPUs free, some in use
DOWN Unreachable or failed — slurmd isn't responding
DRAINING Currently running jobs finish normally, but no new jobs will be scheduled here
DRAIN Manually marked unschedulable, whether or not anything is running
# Drain a node before hardware service — running jobs finish, no new ones start
scontrol update NodeName=dgx-node-04 State=DRAIN Reason="GPU RMA pending"

# See why a node is drained
sinfo -R

This is the same node-health concept covered in NVIDIA DCGM — in practice, a Node Health Check (NHC) script runs between jobs (or on a timer) and can automatically drain a node the moment it sees a DCGM XID error or a failed dcgmi diag, so a flaky GPU pulls itself out of the schedulable pool before it silently corrupts the next job placed on it.


Resource Enforcement with cgroups

Requesting --gres=gpu:2 --cpus-per-task=8 doesn't just influence scheduling — Slurm actually enforces it. The task/cgroup plugin creates a cgroup per job step and constrains it to exactly the CPUs, memory, and GPU devices (via /dev/nvidia* cgroup device rules) that were allocated, so one job can't quietly consume a GPU a neighboring job on the same node was granted.

slurmd (task/cgroup plugin)
        │
        ▼
  cgroup created per job step
        │
   ┌────┴────┬──────────┐
   ▼         ▼          ▼
 cpuset   memory    devices (GPU)
 (pin to  (limit    (only allocated
 alloc'd  to req)   /dev/nvidia* visible)
 cores)

This is the exact same enforcement mechanism described in Kubelet Internals — cgroups turning a resource request into a kernel-enforced guarantee — just applied by slurmd against a whole job step instead of by the kubelet against a container.


Topology-Aware Scheduling

On a DGX SuperPod, which specific nodes a multi-node job lands on matters — nodes on the same NVLink/InfiniBand leaf switch communicate far faster than nodes across the fabric. Slurm's optional topology.conf describes the physical network tree, and the topology/tree plugin uses it to prefer placing a job's nodes as close together in that tree as possible:

switch.top:
  SwitchName=leaf1 Nodes=dgx[01-08]
  SwitchName=leaf2 Nodes=dgx[09-16]
  SwitchName=spine1 Switches=leaf1,leaf2

Given a choice between eight free nodes scattered across two leaf switches versus eight free nodes all under one leaf switch, topology-aware scheduling picks the latter — minimizing the inter-switch hops an AllReduce has to cross, the same NVLink-vs-InfiniBand bandwidth cliff covered in NVIDIA Network Operator.


The Slurm REST API

slurmrestd exposes the same job submission and query operations as sbatch/squeue over HTTP, which is what CI/CD pipelines and higher-level orchestration tools use instead of shelling out to CLI commands:

# Submit a job via the REST API instead of sbatch
curl -X POST http://slurm-head:6820/slurm/v0.0.40/job/submit \
  -H "X-SLURM-USER-NAME: ci-bot" \
  -H "X-SLURM-USER-TOKEN: $SLURM_JWT" \
  -H "Content-Type: application/json" \
  -d '{"job": {"partition": "gpu", "name": "ci-train", "script": "#!/bin/bash\nsrun python train.py"}}'

This is the same pattern as BCM's REST API and cmsh — every interactive CLI operation on the cluster has a scriptable HTTP equivalent, which is what actually makes "trigger a training run from a CI/CD pipeline" (see CI/CD Pipelines) possible without a human running sbatch by hand.


Key Takeaways

Concept Summary
slurmctld / slurmd / slurmdbd Controller makes scheduling decisions; per-node daemon launches/monitors; accounting DB tracks usage
sbatch / srun / salloc Submit async, run a parallel step, or allocate interactively
GRES Generic Resource — how Slurm allocates GPUs (and other non-CPU resources) per job
MPI / PMIx srun --mpi=pmix bootstraps rank discovery so NCCL/MPI collectives can start across nodes
enroot + pyxis Unprivileged container execution under Slurm — no root daemon, wired into srun via a SPANK plugin
Partition / QOS / fair-share / backfill The mechanisms that decide whose job runs next on a shared, heavily-queued cluster
Multifactor priority Age + fair-share + QOS + partition + job-size weights combine into one priority number per job
Preemption SUSPEND / REQUEUE / CANCEL — how a higher-priority job takes resources from a running lower-priority one
Job arrays / dependencies --array for parameter sweeps, --dependency=afterok: for pipeline chaining
Node states + NHC IDLE/MIXED/DRAIN/DOWN; a Node Health Check script can auto-drain a node on a DCGM XID error
cgroups enforcement task/cgroup constrains each job step to exactly its allocated CPUs, memory, and GPU devices
Topology-aware scheduling topology.conf places multi-node jobs on physically nearby nodes to minimize AllReduce hops
slurmrestd HTTP equivalent of sbatch/squeue, for CI/CD and orchestration tools to trigger jobs programmatically
vs Kubernetes Run-to-completion batch jobs vs always-on self-healing services — different execution models for training vs inference

Slurm's entire design center is a queue of jobs that will eventually finish, on hardware shared fairly across many users — which is exactly the opposite assumption Kubernetes makes, and exactly why supercomputers and DGX training clusters still run Slurm even in a Kubernetes-everywhere world.


Interview Questions

Q: Why would an HPC/AI training cluster use Slurm instead of Kubernetes? A: Kubernetes' scheduling unit is a Pod expected to run indefinitely and be restarted on failure — it reconciles toward a desired state that persists. A Slurm job is the opposite shape: submitted once, allocated a fixed set of nodes, and expected to run to completion and exit, with no restart policy because there's no ongoing desired state to reconcile toward. Slurm also natively coordinates multi-node MPI rank discovery at launch time, which on Kubernetes requires an additional operator (PyTorchJob, MPIJob). Large training clusters often run both — Slurm for the training partition, Kubernetes for the inference partition — provisioned from the same head node by something like NVIDIA Base Command Manager.

Q: What's the difference between sbatch, srun, and salloc? A: sbatch submits a batch script asynchronously and returns immediately with a job ID — the normal way to submit a job that doesn't need a human watching it run. srun runs a command as a job step, either standalone (interactive/synchronous) or inside an sbatch script to launch the actual parallel process across allocated nodes. salloc allocates resources for an interactive session without running any script — useful for interactive debugging on allocated GPUs.

Q: How does Slurm decide which of several thousand queued jobs runs next? A: Through the multifactor priority plugin — a weighted sum of an age factor (prevents starvation of long-queued jobs), a fair-share factor (users who've consumed less recent cluster time rank higher), a QOS factor (priority tier), a partition factor, and a job-size factor. sprio -l shows the actual computed breakdown per job. Backfill scheduling additionally lets smaller/shorter jobs slot into gaps ahead of a large job still waiting for enough free nodes, without delaying that large job's eventual start.

Q: How would you take a GPU node out of service for maintenance without killing what's currently running on it? A: scontrol update NodeName=<node> State=DRAIN Reason="..." — this puts the node into DRAINING if a job is currently running on it (letting it finish normally) or straight to DRAIN if idle, and the scheduler simply stops placing any new jobs there. This is also what an automated Node Health Check script does when it detects a DCGM XID error or a failed diagnostic — draining the node before a bad GPU can silently corrupt the next job placed on it.

Q: How does Slurm actually enforce that a job only uses the CPUs, memory, and GPUs it was allocated? A: The task/cgroup plugin creates a Linux cgroup per job step and constrains it to exactly the allocated CPU set, memory limit, and GPU devices (via cgroup device rules restricting which /dev/nvidia* nodes are visible) — the same cgroup-based enforcement mechanism the kubelet uses for container resource limits, just applied by slurmd against a batch job step instead of a container.

Q: Why would you configure topology.conf, and what does it actually change? A: It describes the physical network tree (which nodes sit under which leaf switch, up to the spine) so the topology/tree scheduling plugin can prefer placing a multi-node job's nodes as physically close together as possible — e.g. all under one leaf switch rather than scattered across two. This matters because inter-switch hops are slower than intra-switch ones; a distributed training job's AllReduce step is only as fast as the slowest link between any two of its ranks, so topology-aware placement directly affects training throughput on a fabric like NVLink/InfiniBand.

Q: What are enroot and pyxis, and why does HPC need them instead of just using Docker? A: Traditional HPC clusters don't run a Docker daemon — that would mean a root-privileged service on shared supercomputers with thousands of untrusted users, which is an unacceptable security posture. enroot converts a standard OCI/Docker image into an unprivileged squashfs-based sandbox a regular user can run without any daemon or elevated privileges. pyxis is a Slurm SPANK plugin that adds container-aware flags directly onto srun (--container-image, --container-mounts), so launching a containerized job looks and schedules exactly like any other Slurm job.

Q: How would you chain a training job and an evaluation job so evaluation only runs if training actually succeeds? A: Submit training first with --parsable to capture its job ID cleanly, then submit the evaluation job with --dependency=afterok:<train_job_id>. afterok only releases the dependent job if the upstream job exited with status 0; afternotok is the inverse (useful for a cleanup/alert job), and afterany runs regardless of exit status.

Q: How would a CI/CD pipeline trigger a Slurm training job without a human running sbatch manually? A: Through slurmrestd, which exposes job submission, status queries, and cancellation over HTTP — the same operations sbatch/squeue/scancel perform from the CLI, just callable from a pipeline step with a JWT auth token instead of an interactive shell session.


Related Posts

  • NVIDIA Base Command Manager — provisions and manages the same cluster Slurm schedules jobs onto
  • Multi-Node Distributed Training on Kubernetes — the same rank/AllReduce coordination problem, solved via a Kubernetes operator instead of srun
  • Kubernetes Scheduler Internals — where Kueue fits as the closest Kubernetes-native equivalent to Slurm's queueing model
  • Kueue: Batch Job Scheduling — Kubernetes-native gang scheduling and quotas, for clusters that run training on Kubernetes instead of Slurm
  • NVIDIA DCGM: GPU Health, Diagnostics, and Prometheus Metrics — the GPU health signal Slurm jobs depend on before and during a multi-node run
Hitesh Sahu
Written by Hitesh Sahu, a passionate developer and blogger.

Thu Jul 30 2026

Share This on

Next →

NVIDIA Base Command Manager: Provisioning and Operating GPU Clusters

AI-Infrastructure/2-12-Slurm
Let's work together
+49 176-2019-2523
hiteshkrsahu@gmail.com
WhatsApp
Skype
Munich 🥨, Germany 🇩🇪, EU
Playstore
Hitesh Sahu's apps on Google Play Store
Need Help?
Let's Connect
Navigation
  Home/About
  Skills
  Work/Projects
  Lab/Experiments
  Contribution
  Awards
  Art/Sketches
  Thoughts
  Contact
Links
  Sitemap
  Legal Notice
  Privacy Policy

Made with

NextJS logo

NextJS by

hitesh Sahu

| © 2026 All rights reserved.