Slurm SPANK Plugin¶
The Slurm SPANK plugin for QDMI-on-IQM simplifies running quantum jobs on
clusters by automatically propagating IQM_* environment variables to job
steps. This avoids manual export statements in job scripts and enables
administrators to configure global defaults and partition-gated access.
For Users¶
The plugin registers --iqm-* command-line options for standard Slurm
submission tools (srun, sbatch, salloc). When these options are provided,
the plugin translates them into the corresponding environment variables for the
job tasks.
Supported Options¶
Option |
Environment Variable |
Description |
|---|---|---|
|
|
The endpoint URL of the IQM service. |
|
|
Path to the file containing your access tokens. |
|
|
The unique identifier of the target quantum computer. |
|
|
The alias of the target quantum computer. |
Credential Security¶
Direct token passing is intentionally unsupported on the command line. Slurm command arguments may be captured in shell history, process listings, scheduler logs, or accounting records.
To run authenticated jobs:
Save your tokens to a secure file.
Pass the path to this file using the
--iqm-tokens-fileoption.Ensure the token file is readable on the compute nodes where the tasks execute.
Example¶
The IQMBackend class automatically resolves
configuration values from the environment variables injected by the plugin.
bell_state.py
from iqm.qdmi.qiskit import IQMBackend
from qiskit import QuantumCircuit, transpile
# Initialize the backend (resolves URL and auth from Slurm environment)
backend = IQMBackend()
print(f"Connected to: {backend.name}")
# Create a simple Bell state circuit
qc = QuantumCircuit(2)
qc.h(0)
qc.cx(0, 1)
qc.measure_all()
# Transpile and execute
transpiled_qc = transpile(qc, backend)
job = backend.run(transpiled_qc, shots=100)
print(f"Job ID: {job.job_id()}")
# Retrieve results
result = job.result()
counts = result.get_counts()
print(f"Counts: {counts}")
To run this job:
srun --partition=quantum --iqm-qc-alias=emerald python bell_state.py
Limiting Concurrent Access to a QC¶
If your administrator has configured a Slurm license for the target QC (see
Limiting Concurrent Access with Slurm Licenses
below), request it alongside --iqm-qc-alias using Slurm’s native
--licenses/-L option:
srun --partition=quantum --iqm-qc-alias=emerald --licenses=iqm_qc_emerald:1 python bell_state.py
This matters most for on-premise QCs: like Resonance, an on-premise setup
still runs its own internal queue, but it typically fronts single-tenant
hardware, so uncontrolled Slurm-side concurrency puts unnecessary pressure on
that queue. Requesting the license lets Slurm regulate that pressure itself,
ahead of the QC’s own queue. If you omit --licenses on a cluster where it’s
expected, the plugin logs a warning (or, if the administrator has set
iqm_require_license=1, fails your job step at launch instead — after it has
already been allocated, not at submission time).
Executing via CLI Scripts¶
Alternatively, if you already have serialized circuits (in QPY format), you can execute them directly on the cluster using the packaged CLI scripts (see the Sampler and Estimator CLI Utilities documentation for details) without writing any custom Python code:
# Run a serialized circuit using the sampler CLI
srun --partition=quantum --iqm-qc-alias=emerald iqm-sampler bell.qpy --shots 100
# Estimate parameters using the estimator CLI
srun --partition=quantum --iqm-qc-alias=emerald iqm-estimator ansatz.qpy observable.pkl --maxiter 10
For HPC Administrators¶
The SPANK plugin is a lightweight C++ module that intercepts job launches to parse options and inject environment variables. It does not implement scheduler policy or handle backend-side queue management.
Compatibility and Requirements¶
Slurm Version: Slurm 17.11 or newer. The optional Slurm license alignment check (see Limiting Concurrent Access with Slurm Licenses) additionally requires Slurm 23.02 or newer, since it relies on the
SLURM_JOB_LICENSESjob environment variable; on older Slurm versions it is a silent no-op.C++ Compiler: C++20 standard library support (GCC 13+ or Clang 16+).
Compilation Constraint: SPANK plugins are tied to the Slurm daemon ABI. You must compile the plugin against the target cluster’s Slurm header files (
slurm/spank.h) and rebuild the plugin after any major/minor Slurm upgrades.
Installation¶
To compile and install the plugin from the repository root:
cmake -S . -B build-spank -DBUILD_IQM_SPANK=ON
cmake --build build-spank --target iqm-spank-plugin --parallel
sudo cmake --install build-spank --component iqm-spank-plugin
This installs the compiled .so file to the Slurm plugin directory and places
the template configuration in plugstack.conf.d/.
Deploy the plugin on login/submit nodes (for srun/sbatch command line
parsing) and on compute nodes running slurmd/slurmstepd. Controller-only
nodes do not require the plugin.
Configuration¶
Configure the plugin in plugstack.conf. Global defaults defined here can be
overridden by users at submission time.
/etc/slurm/plugstack.conf.d/iqm-qdmi.conf
required /usr/lib/slurm/iqm-spank-plugin.so \
iqm_base_url=https://resonance.iqm.tech \
iqm_tokens_file=/etc/iqm/tokens.json \
partitions=quantum,debug \
iqm_license_prefix=iqm_qc_ \
iqm_require_license=1
iqm_base_url: Default API endpoint.iqm_tokens_file: Path to the shared token file.partitions: Comma-separated list of partitions where this plugin will run. If omitted, the plugin evaluates all partitions.iqm_license_prefix: Prefix used to derive the expected Slurm license name fromIQM_QC_ALIAS(default:iqm_qc_). See Limiting Concurrent Access with Slurm Licenses.iqm_require_license: When set to a truthy value (1/true/yes/on/enabled, case-insensitive), fails at launch jobs whose Slurm license request does not match the derived name, instead of only logging a warning (default: off). See Limiting Concurrent Access with Slurm Licenses for the exact semantics. An unrecognized value logs a warning and is treated as off.
Ensure your main /etc/slurm/plugstack.conf includes your drop-in configuration
directory:
include /etc/slurm/plugstack.conf.d/*.conf
After modifying the configuration, apply changes to the cluster:
sudo scontrol reconfigure
Limiting Concurrent Access with Slurm Licenses¶
Note
“Slurm license” here refers to Slurm’s native Licenses=/--licenses
capacity-limiting scheduler resource — unrelated to the GPLv3/Apache-2.0
software licensing described elsewhere in this repository.
Each QC can be modeled as a flat, cluster-wide Slurm license so that Slurm itself enforces a concurrency limit, rather than relying on jobs to behave. This is especially important for on-premise QCs: like Resonance, an on-premise setup still runs its own internal queue, but it typically fronts single-tenant hardware, so uncontrolled concurrency puts unnecessary pressure on that queue and risks real hardware contention. A Slurm license lets the cluster regulate that pressure itself, ahead of the QC’s own queue.
Define a license pool for each QC in
/etc/slurm/slurm.conf(a flat, cluster-wide pool, not tied to specific nodes — the QC is reached over the network from any node in the partition):Licenses=iqm_qc_emerald:4
Users request the license alongside
--iqm-qc-alias(see Limiting Concurrent Access to a QC):srun --iqm-qc-alias=emerald --licenses=iqm_qc_emerald:1 ...
The plugin derives the expected license name as
<iqm_license_prefix><alias>(default prefixiqm_qc_). Since QC aliases may themselves contain a colon (e.g.emerald:mock, as seen in the Qiskit Integration examples), and Slurm’sname:countlicense syntax reserves:as a separator, the plugin replaces:and,in the alias with_when deriving the name (e.g. aliasemerald:mock→ licenseiqm_qc_emerald_mock).By default, a mismatch (or a missing
--licensesrequest) only logs a warning. Settingiqm_require_license=1instead fails the job step at launch — after the job has already been allocated, not at submission time — and only takes effect if the plugin is declaredrequired(notoptional) inplugstack.conf.Optionally, add the license name to
AccountingStorageTRESinslurm.confto track its usage in Slurm accounting.
Troubleshooting¶
The plugin logs to the standard slurmd.log on compute nodes. Successful
activation prints a log entry when a job starts on an active partition:
[iqm_spank_plugin] job=12345 partition=quantum base_url=set auth=tokens_file tokens_file_ok=yes license=iqm_qc_emerald:ok
Common Issues:
“Plugin metadata symbol missing”: The plugin was compiled with incompatible headers or toolchain. Rebuild the plugin from source on the target environment.
Options/variables not showing up: Verify that
scontrol show config | grep PlugStackConfigreferences yourplugstack.confdirectory and that the drop-in file is read-permitted.Permission Denied: The
slurmdprocess user must have read access to the compiled.solibrary and the specifiediqm_tokens_file.
Testing with Docker¶
To test the SPANK plugin locally without installing Slurm or configuring services on your host machine, you can run the test suite inside an isolated Docker container.
First, build the Docker image from the repository root:
docker build -t qdmi-spank-tests -f spank/Dockerfile .
Then, run the tests:
docker run --rm qdmi-spank-tests
To run integration tests targeting the Resonance backend, pass your IQM_TOKEN
as an environment variable:
docker run --rm -e IQM_TOKEN="your-token" qdmi-spank-tests
For a faster development loop, you can bind-mount your local workspace. This avoids rebuilding the image when you make changes to the code or test scripts:
docker run --rm -v "$(pwd):/workspace" qdmi-spank-tests