Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions config/device-access.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ qpus:
fake-iqm-20q:
provider: fake-iqm
provider-device-id: fake-iqm-20q
backline-local:
provider: backline
provider-device-id: backline-local
ibm-156-nh:
provider: ibm
provider-device-id: ibm_156_nh
Expand Down
3 changes: 3 additions & 0 deletions config/qfw-slurm/plugin.conf
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,6 @@ service_id=shim-aws-qpm

[resource "fake-iqm-20q"]
service_id=fake-iqm

[resource "backline-local"]
service_id=backline-local
2 changes: 2 additions & 0 deletions config/qfw-slurm/resources.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ return {
["aws-ionq-aria-1"] = "shim-aws-qpm",
["aws-rigetti-ankaa"] = "shim-aws-qpm",
["fake-iqm-20q"] = "fake-iqm",
["backline-local"] = "backline-local",
},
partitions = {
normal = {
Expand All @@ -18,6 +19,7 @@ return {
["aws-ionq-aria-1"] = true,
["aws-rigetti-ankaa"] = true,
["fake-iqm-20q"] = true,
["backline-local"] = true,
},
},
},
Expand Down
9 changes: 9 additions & 0 deletions config/qpu-users.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
"fake-iqm-20q": {
"enabled": true
},
"backline-local": {
"enabled": true
},
"ibm-156-nh": {
"enabled": true,
"api_key": "",
Expand Down Expand Up @@ -48,6 +51,9 @@
"fake-iqm-20q": {
"enabled": true
},
"backline-local": {
"enabled": true
},
"ibm-156-nh": {
"enabled": true,
"api_key": "",
Expand Down Expand Up @@ -86,6 +92,9 @@
"fake-iqm-20q": {
"enabled": true
},
"backline-local": {
"enabled": true
},
"ibm-156-nh": {
"enabled": true,
"api_key": "",
Expand Down
15 changes: 15 additions & 0 deletions config/site-services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,21 @@ services:
provider-launch:
type: internal

# Client-executed: reserves Backline controllers, decoders and transports and
# returns a placement; the application runs the program itself.
- name: backline-local
credential-mode: no-secret
module: svc_backline_qpm
load-modules: svc_backline_qpm,api_launcher
environment-modules:
- backline
agent-prefix: qpm_backline
device-id: backline-local
listen-port: 8690
telnet-port: 8691
provider-launch:
type: internal

- name: iqm-ornl-20q
credential-mode: required
module: svc_iqm_qpm
Expand Down
23 changes: 23 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,29 @@ services:
networks:
- slurm-network

qec-backline-head:
<<: *slurmd-resources
image: ${IMAGE_NAME}:${IMAGE_TAG}
init: true
command: ["slurmd"]
hostname: qec-backline-head
container_name: qec-backline-head
volumes:
- root_ssh:/root/.ssh
- etc_munge:/etc/munge
- etc_slurm:/etc/slurm
- slurm_jobdir:/data
- var_log_slurm:/var/log/slurm
- ./shared-dir:/mnt:z
- ${QFW_CONTAINER_BASE}:/workspace/qfw-container-base:z
- ${QFW_CONTAINER_BASE}/home:/workspace/home:z
expose:
- "6818"
depends_on:
- "slurmctld"
networks:
- slurm-network

volumes:
etc_munge:
etc_slurm:
Expand Down
98 changes: 98 additions & 0 deletions docs/backline.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# Backline QPM (`backline-local`)

`backline-local` is a client-executed QPM (QFw `services/svc_backline_qpm`). A
reservation picks a Backline controller, QEC decoder coprocessor and
transport from the site inventory; the application reads that placement and runs its
PennyLane/Catalyst program on it. It never sends circuits through QRI.

It runs on `qec-backline-head` and is opt-in: `qfw-site-services start` (target `all`) does not
start it.

## Set up once

The Backline QPM is in [openQSE/QFw](https://github.com/openQSE/QFw). The image keeps its
stock QFw; the Backline QPM runs from a development override built from QFw `main` (see
"Build and use a development QFw override" in the README).

On the host:

```bash
git clone https://github.com/openQSE/QFw-SLURM-Cluster
cd QFw-SLURM-Cluster
SHARED=/path/to/shared-dir
./do_configure.sh --prefix "$SHARED"
git clone --recursive https://github.com/openQSE/QFw "$SHARED/QFw"
./do_build.sh
./do_startup.sh
./do_qfw_build.sh --clean # the override, in $SHARED/qfw-install
```

In the cluster:

```bash
./do_ssh.sh # into the cluster, as root
/path/to/QFw-SLURM-Cluster/tools/install-backline-venv.sh # shared venv: Catalyst 0.16.0b1 wheels
qfw-site-services start # directory, gateway and the default QPMs
export QFW_INSTALL_PREFIX=/workspace/qfw-container-base/qfw-install # the override
qfw-site-services --target backline start
qfw-site-services --target backline status
```

The `backline` environment module (`modulefiles/backline`) points `CATALYST_LIB` at the
shared venv, so the QPM's inventory finds the precompiled decoders.

### On an existing cluster

On a cluster that is already set up, pull this, then run these in place of `./do_build.sh` and
`./do_startup.sh` above; `./do_qfw_build.sh --clean` and the in-cluster steps are unchanged:

```bash
./do_build.sh # modulefiles/backline is copied into the image
./do_restart.sh --force-recreate # recreate the containers from it, adding qec-backline-head
./update_slurmfiles.sh slurm.conf # the etc_slurm volume keeps the old slurm.conf
./tools/provision-qfw-cluster.sh # now reaches qec-backline-head
```

## Run a Backline program

The job script is `qri-backline/examples/job.sh`, cloned to
`/workspace/qfw-container-base/qri-backline` by `tools/install-backline-venv.sh`. Submit it
as a provisioned test user, not root (root batch jobs may take slurmd down on this
cluster). qfw-slurm requires a Slurm account (`-A`); the test users use `qfw-test`:

```bash
./do_ssh.sh --user user-a
sbatch -A qfw-test /workspace/qfw-container-base/qri-backline/examples/job.sh
```

The job makes two requests:

1. **Quantum resources.** The `#SBATCH --qpu=backline-local ...` lines. qfw-slurm reserves
`backline-local`'s quantum budget while the job is allocated and passes the reservation to
each step in `QFW_RESERVATIONS`. The allocation's teardown releases it.
2. **Classical QEC resources.** The program asks the QPM for them against that reservation
(`reserve` with `for_reservation` and the `resource_intent` in
`intents/cpu-steane-memcpy.yaml`: a CPU controller, a Steane decoder, memcpy). The QPM
starts a `catalyst-executor` on `qec-backline-head` for the reservation and returns its
address in the placement; the program compiles locally and runs controller and decoder
there. The executor stops when the reservation ends.

`--max-qubits` counts logical qubits.

## Security

The `catalyst-executor` runs whatever compiled program a client sends it. It listens on
all interfaces and does not authenticate clients, so anyone who can reach its port can run
code as the user the QPM runs as, which is root on `qec-backline-head`. Use it only on a
trusted network until this is addressed.

## Files

| File | Role |
| --- | --- |
| `docker-compose.yml`, `slurm.conf`, `tools/provision-qfw-cluster.sh` | the `qec-backline-head` node |
| `config/site-services.yaml` | the `backline-local` service, loading the `backline` module |
| `config/device-access.yaml`, `config/qpu-users.json` | device record and user entitlement |
| `config/qfw-slurm/resources.lua`, `config/qfw-slurm/plugin.conf` | `--qpu=backline-local` |
| `modulefiles/backline`, `tools/install-backline-venv.sh` | the shared Backline venv and the demo checkout |
| `tools/qfw-site-services` | `--target backline` start, stop, status |
17 changes: 17 additions & 0 deletions modulefiles/backline
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#%Module1.0
##
## Backline (PennyLane + Catalyst) venv on the shared QFw volume, created by
## tools/install-backline-venv.sh. Loaded by the backline-local QPM, so its
## inventory finds the decoder libraries, and by Backline applications.
##

proc ModulesHelp { } {
puts stderr "Adds the shared Backline virtual environment to the environment."
}

module-whatis "Backline for QFw"

set venv /workspace/qfw-container-base/backline-venv

setenv BACKLINE_VENV $venv
setenv CATALYST_LIB $venv/lib/python3.12/site-packages/catalyst/lib
3 changes: 2 additions & 1 deletion slurm.conf
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,9 @@ NodeName=shim-head Features=qfw-service,shim,qpm,qpm-shim-ornl-20q CPUs=4 Socket
NodeName=ibm-156-nh Features=qfw-service,ibm,qpm,qpm-shim-ibm-156-nh CPUs=4 Sockets=1 CoresPerSocket=4 ThreadsPerCore=1 RealMemory=6000 State=UNKNOWN
NodeName=aws Features=qfw-service,aws,qpm,qpm-shim-aws-qpm CPUs=4 Sockets=1 CoresPerSocket=4 ThreadsPerCore=1 RealMemory=6000 State=UNKNOWN
NodeName=fake-iqm-head Features=qfw-service,fake-iqm,qpm,qpm-fake-iqm CPUs=4 Sockets=1 CoresPerSocket=4 ThreadsPerCore=1 RealMemory=6000 State=UNKNOWN
NodeName=qec-backline-head Features=qfw-service,backline,qpm,qpm-backline-local CPUs=4 Sockets=1 CoresPerSocket=4 ThreadsPerCore=1 RealMemory=6000 State=UNKNOWN

#
# PARTITIONS
PartitionName=normal Default=YES Nodes=c[1-8] Priority=50 DefMemPerCPU=200 OverSubscribe=EXCLUSIVE MaxTime=5-00:00:00 DefaultTime=5-00:00:00 State=UP
PartitionName=qfw-services Default=NO Nodes=nwqsim-head,nwqsim-worker-[1-2],iqm-head,shim-head,ibm-156-nh,aws,fake-iqm-head AllowGroups=root Priority=10 DefMemPerCPU=200 OverSubscribe=EXCLUSIVE MaxTime=1-00:00:00 DefaultTime=01:00:00 State=UP
PartitionName=qfw-services Default=NO Nodes=nwqsim-head,nwqsim-worker-[1-2],iqm-head,shim-head,ibm-156-nh,aws,fake-iqm-head,qec-backline-head AllowGroups=root Priority=10 DefMemPerCPU=200 OverSubscribe=EXCLUSIVE MaxTime=1-00:00:00 DefaultTime=01:00:00 State=UP
36 changes: 36 additions & 0 deletions tools/install-backline-venv.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#!/bin/bash
# Create the shared Backline venv used by the backline-local QPM and by Backline
# applications. Run once inside any cluster container (the volume is shared):
#
# docker exec slurmctld /mnt/../tools/install-backline-venv.sh # or ./do_ssh.sh, then run it
#
# The venv must use the same Python as the QFw venv (3.12 on the Rocky 10 image):
# applications run through qfw-srun, whose embedded DEFw interpreter checks this.
set -euo pipefail

venv="${BACKLINE_VENV:-/workspace/qfw-container-base/backline-venv}"
python="${PYTHON:-python3}"
release="https://github.com/PennyLaneAI"

"${python}" -c 'import sys; assert sys.version_info >= (3, 12), "Catalyst 0.16 wheels need Python 3.12+"'
"${python}" -m venv "${venv}"
"${venv}/bin/pip" install -q --upgrade pip
"${venv}/bin/pip" install -q pennylane-catalyst==0.16.0b1 \
-f "${release}/pennylane/releases/expanded_assets/v0.46.0b1" \
-f "${release}/pennylane-lightning/releases/expanded_assets/v0.46.0b1" \
-f "${release}/catalyst/releases/expanded_assets/v0.16.0b1"
# DEFw's client-side imports, for applications that reach QFw services.
"${venv}/bin/pip" install -q PyYAML "jsonschema>=4" netifaces psutil paramiko rich

lib="$("${venv}/bin/python" -c 'import importlib.util, pathlib; print(pathlib.Path(list(importlib.util.find_spec("catalyst").submodule_search_locations)[0]) / "lib")')"
test -f "${lib}/libsteane_coprocessor_cpu.so"
# The demo program, on the shared volume so jobs on any compute node can run it.
# Jobs run this code, we check out a fixed commit. QRI_BACKLINE_REF overrides it.
# TODO: move the demo under openQSE.
demo="${QRI_BACKLINE_DIR:-/workspace/qfw-container-base/qri-backline}"
demo_ref="${QRI_BACKLINE_REF:-fea211a3d9e282c70e37672e6cdf1d679b372000}"
if [ ! -d "${demo}/.git" ]; then
git clone -q https://github.com/josephleekl/qri-backline "${demo}"
git -C "${demo}" checkout -q "${demo_ref}"
fi
echo "backline venv ready: ${venv} (decoders in ${lib})"
2 changes: 1 addition & 1 deletion tools/provision-qfw-cluster.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ containers=(
slurmdbd slurmctld slurmrestd
c1 c2 c3 c4 c5 c6 c7 c8
nwqsim-head nwqsim-worker-1 nwqsim-worker-2
iqm-head shim-head ibm-156-nh aws fake-iqm-head
iqm-head shim-head ibm-156-nh aws fake-iqm-head qec-backline-head
)

die() {
Expand Down
Loading