Skip to content

converged-computing/quantum-wrappers

Repository files navigation

quantum-wrappers

Reusable Snakemake wrappers for running quantum tasks from HPC workflows, following the layout and conventions of the official snakemake-wrappers repository so that a quantum task becomes a normal rule in a workflow DAG.

Wrappers are organized by backend, as a domain tree like upstream snakemake-wrappers:

  • quantum/qrmi/QRMI, the vendor-agnostic Quantum Resource Management Interface used with the Slurm SPANK plugin.
  • quantum/braket/Amazon Braket, AWS's managed quantum service.

New backends slot in as additional quantum/<backend>/ domains.

Layout

Each wrapper is a self-contained directory with a wrapper.py, an environment.yaml, a meta.yaml, and a test/ case:

quantum/qrmi/
  sampler/      run a Qiskit SamplerV2 primitive on a QRMI resource
  estimator/    run a Qiskit EstimatorV2 primitive on a QRMI resource
  task/         run one raw QRMI Qiskit-primitive task (vendor-agnostic, low-level)
quantum/braket/
  authenticate/       verify AWS credentials / region (STS)
  device_properties/  connect to a device and report its status
  run/                run one circuit and wait for counts (submit + wait)
  submit/             submit a circuit, return the durable task ARN (no wait)
  poll/               recover a task by ARN and fetch its result
meta/quantum/
  qrmi-sampler-summary/    meta-wrapper: QRMI sampler + classical summary
  braket-run-summary/      meta-wrapper: Braket run + classical summary
workflows/      example workflows/apps that USE the wrappers in rules
test_wrappers.py  pytest harness that runs each wrapper's test

Each wrapper.py is self-contained: it uses the injected snakemake object and calls the backend SDK (qrmi / qrmi.primitives, or braket) directly. There is no shared helper package — copying a wrapper directory is enough to use it.

Install

You need Python 3.11+ and Snakemake. You can use the provided VSCode Devcontainer, or create a fresh environment:

# with conda/mamba (recommended)
conda create -n quantum-wrappers -c conda-forge -c bioconda python=3.12 snakemake
conda activate quantum-wrappers

# or with pip
pip install snakemake

Backend SDKs are declared per wrapper in each environment.yaml. There are two ways to get them:

  • Let Snakemake manage them (recommended). Run with --use-conda and Snakemake deploys each wrapper's environment.yaml into an isolated conda env the first time it runs:
  snakemake -c1 --use-conda
  • Install them yourself into the active environment, if you prefer not to use per-rule conda envs. For the offline path (local simulators, no QPU/AWS) that is just:
  pip install qiskit qiskit-aer amazon-braket-sdk qiskit_qasm3_import

Add qrmi[ibm] / qiskit-ibm-runtime for real QRMI hardware, or configure AWS credentials for real Braket devices.

To run the test suite (all offline):

pip install pytest
QRMI_WRAPPERS_SIMULATE=1 pytest -q

A ready-made dev container (.devcontainer/devcontainer.json) is included: open the repo in VS Code (or a Codespace) and "Reopen in Container" to get Python, Snakemake, and the offline backend SDKs preinstalled.

QRMI wrappers

Wrapper Unit of work Input Output
quantum/qrmi/sampler Qiskit SamplerV2 on a QRMI resource OpenQASM 3 circuit(s) with measurements per-circuit measurement counts
quantum/qrmi/estimator Qiskit EstimatorV2 on a QRMI resource OpenQASM 3 state-prep circuit + Pauli observables expectation values
quantum/qrmi/task Raw QRMI lifecycle (acquire → task_start → poll → task_result → release) provider primitive input payload raw result

Each wrapper encapsulates the full acquire → run → release lifecycle in a single process. That is deliberate: a QRMI lock is bound to the process that acquired it, so the correct granularity for one Snakemake rule (which runs as its own process) is one complete task — not a separate acquire rule and release rule. The sampler/estimator wrappers build the Qiskit Runtime primitive input for you; task submits a payload verbatim for any provider or program.

Using a wrapper in a rule

Here is locally:

rule sample:
    input:
        circuits="bell.qasm"       # OpenQASM 3, with measurements
    output:
        "counts.json"
    params:
        resource="ibm_marrakesh",  # or omit → first QRMI resource / Slurm SPANK
        shots=2048
    resources:
        qpu=1                      # serialise QPU access across the DAG
    wrapper:
        "file:../../quantum/qrmi/sampler"

And reference to use from GitHub:

rule sample:
    input:
        circuits="bell.qasm"
    output:
        "counts.json"
    params:
        resource="ibm_marrakesh",
        shots=2048
    resources:
        qpu=1
    wrapper:
        "github://converged-computing/quantum-wrappers/quantum/qrmi/sampler@main"

For reproducibility you would normally pin a released version instead of a local path, e.g. wrapper: "v0.1.0/quantum/qrmi/sampler" once this repo is tagged, and run Snakemake with --use-conda so each wrapper's environment.yaml is deployed automatically.

Example workflows

workflows/ contains runnable examples that use the wrappers in rules and demonstrate common patterns:

# Workflow Pattern
01 01_single_circuit linear: sample one circuit → post-process
02 02_parameter_sweep fan-out: sweep Ry(θ), one QPU task per angle, gather
03 03_scatter_gather discover circuits/*.qasm, sample each, gather a batch
04 04_vqe_estimator hybrid loop: an optimiser drives repeated EstimatorV2 evaluations while holding the resource

Workflow 04 is intentionally a single rule running a driver rather than per-iteration wrapper rules: a hybrid loop must keep the resource acquired across all evaluations, so it uses the QRMI estimator API directly in one process.

Running offline (no QPU, no credentials)

Every wrapper's real path talks to a QRMI resource. For development and CI, set QRMI_WRAPPERS_SIMULATE=1 to run the sampler/estimator paths (and the example workflows) on a local Qiskit Aer / statevector simulator instead. This is a test-only convenience; the default path is the real QRMI one, and the simulate branch never imports qrmi.

# one wrapper's test
cd quantum/qrmi/sampler/test && QRMI_WRAPPERS_SIMULATE=1 snakemake -c1

# an example workflow
cd workflows/02_parameter_sweep && QRMI_WRAPPERS_SIMULATE=1 snakemake -c1

# the whole test suite
QRMI_WRAPPERS_SIMULATE=1 pytest -q

The task wrapper has no simulate path (it submits an opaque provider payload), so its test runs only when a real resource is configured.

Running on real hardware / under Slurm

Untested - I (vsoch) do not have credentials still

Provide the resource and credentials via environment variables or a qrmi_config.json, then run without QRMI_WRAPPERS_SIMULATE:

export QRMI_RESOURCE_ID=ibm_marrakesh
export QRMI_IBM_QS_IAM_APIKEY=...  QRMI_IBM_QS_SERVICE_CRN=...  QRMI_IBM_QS_ENDPOINT=...
snakemake -c1 --use-conda

Under Slurm with the QRMI SPANK plugin, a job that requests a QPU (#SBATCH --qpu=<name>) has SLURM_JOB_QPU_RESOURCES and the credential variables injected automatically; the wrappers pick the resource up from there when params.resource is omitted, so the same workflow runs unchanged as an sbatch script.

Braket wrappers

The Braket wrappers cover a finer separation of concerns — authenticate, connect / check the device, submit, poll, and a combined run:

Wrapper Unit of work Offline (local sim)?
quantum/braket/authenticate verify AWS credentials + region (STS GetCallerIdentity) no (needs AWS)
quantum/braket/device_properties connect to a device, report name/status/provider/queue yes
quantum/braket/run run one OpenQASM 3 circuit and wait for counts (submit + wait) yes
quantum/braket/submit submit a circuit, return the durable task ARN, no wait yes (local)
quantum/braket/poll recover a task by ARN and fetch its result no (needs AWS)

All Braket wrappers take a device param that is either "local" / "local:<backend>" (the in-process Braket simulator, no AWS account needed) or an AWS device ARN such as arn:aws:braket:::device/quantum-simulator/amazon/sv1 or a QPU ARN. Because the local simulator is part of the real SDK, the run, submit, device_properties and meta-wrapper tests run fully offline against genuine Braket code — no mock.

rule run:
    input:
        circuit="bell.qasm"        # OpenQASM 3, Braket dialect, with measurements
    output:
        "counts.json"
    params:
        device="local:braket_sv",  # or an AWS device ARN
        shots=1000
    wrapper:
        "file:../../quantum/braket/run"

submit + poll: durable task ARNs

The submit and poll wrappers are deliberately separate units, unlike the single-process QRMI wrappers. A Braket quantum task is addressed by a durable ARN, so submit can record the ARN and a later poll rule — in a different process, Snakemake invocation, or Slurm job — can recover it with AwsQuantumTask(arn=...) and fetch the result. That decoupling is not possible with a QRMI lock, which is bound to the process that acquired it (hence the QRMI sampler/estimator/task wrappers each own the full lifecycle in one rule). The workflows/braket/submit_poll app demonstrates the two-rule pattern; it requires an AWS device ARN, since a local task ARN does not survive its process.

Running on AWS

Configure credentials the usual way (aws configure, environment variables, or an instance/role), then point device at an AWS ARN:

export AWS_ACCESS_KEY_ID=...  AWS_SECRET_ACCESS_KEY=...  AWS_REGION=us-east-1
cd workflows/braket/single_circuit
snakemake -c1 --config device=arn:aws:braket:::device/quantum-simulator/amazon/sv1

Backends: QRMI (https://github.com/qiskit-community/qrmi) and Amazon Braket (https://github.com/amazon-braket/amazon-braket-sdk-python).

License

DevTools is distributed under the terms of the MIT license. All new contributions must be made under this license.

See LICENSE, COPYRIGHT, and NOTICE for details.

SPDX-License-Identifier: (MIT)

LLNL-CODE- 842614

About

Reusable Snakemake wrappers for running quantum tasks from hybrid workflows

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors