Skip to content

Accelerator Setup

FlagQuantum edited this page Oct 20, 2026 · 4 revisions

Accelerator Setup

Configure a CPU, NVIDIA CUDA, or provisioned domestic-accelerator environment, detect the available runtime, and check that circuit outputs and gradients are on the requested device.

Scope: FlagQuantum 0.3.1. The CPU examples and unavailable-CUDA error path were verified on macOS Apple Silicon with Python 3.12.14 and PyTorch 2.14.1. Successful CUDA and FlagOS outputs below are conditional examples, not measurements from this machine. A successful local smoke test does not certify every operation, precision, or simulation method on that accelerator.

Formula/code review — October 20, 2026: The equations are paired with code excerpts, and the local CPU examples were re-run with Python 3.12.14 and PyTorch 2.13.0. See the review record for executed commands, distributed checks, and untested hardware/provider paths. Earlier environment and output records are retained.

1. Select the Runtime Path

Target Environment Device used in this guide Requirements
CPU Upstream PyTorch cpu Compatible Python, PyTorch, and FlagQuantum wheel
NVIDIA GPU CUDA-enabled upstream PyTorch and a compatible NVIDIA driver cuda:0 Visible GPU, suitable driver/runtime pairing, supported package platform
Domestic accelerator Vendor-provisioned drivers, SDK/PyTorch stack, and a validated integration flagos:0 for the optional Torch-FL path Matching Torch-FL build and required workload evidence; support is specific to the hardware/software tuple

backend="pytorch" identifies the tensor backend. device= identifies the execution device. mode="statevector" identifies the simulation representation. These are separate choices: selecting an accelerator does not automatically select MPS, tensor-network simulation, or distributed execution.

Use explicit indices such as cuda:0 and flagos:0 in the scripts below. The index is local to the devices visible to the Python process. Container and scheduler visibility settings can make a host card appear as index 0 inside a job.

2. Version and Platform Requirements

Component Requirement for FlagQuantum 0.3.1
Python >=3.10,<3.13: Python 3.10, 3.11, or 3.12
Core PyTorch dependency >=2.10,<2.15; compatible local vendor version labels are accepted
New upstream CPU/CUDA environment Release README recommends PyTorch 2.13.x or 2.14.x
invertible extra Narrows PyTorch to >=2.13,<2.14
cuda extra Adds triton>=3.1,<4; does not install a GPU driver or select a CUDA-enabled PyTorch build
Torch-FL A separately provisioned build matched to the exact PyTorch/runtime environment; not a core dependency
Native binary platforms Published 0.3.1 wheels cover Apple Silicon macOS, Linux x86-64, and Windows x64

See Installation and Compatibility for wheel tags, Python-environment creation, and source-build considerations. A package version satisfying the dependency range is necessary but does not establish compatibility with every driver, SDK, device architecture, or optional integration.

3. CPU Environment

Create and activate a fresh Python 3.10–3.12 virtual environment as described in the installation guide.

On Linux or Windows, install CPU-only PyTorch followed by FlagQuantum:

python -m pip install "torch>=2.13,<2.15" --index-url https://download.pytorch.org/whl/cpu
python -m pip install --only-binary=flagquantum "flagquantum==0.3.1" numpy
python -m pip check

On Apple Silicon macOS, use the default package index for PyTorch:

python -m pip install "torch>=2.13,<2.15"
python -m pip install --only-binary=flagquantum "flagquantum==0.3.1" numpy
python -m pip check

The --only-binary=flagquantum option requests a matching FlagQuantum wheel instead of an implicit source build. These steps configure CPU execution on macOS; they do not establish Apple GPU support. Apple's mps device name is also separate from FlagQuantum's matrix-product-state simulation mode.

4. NVIDIA GPU Environment

  1. Provision a supported NVIDIA GPU and driver. Run nvidia-smi on the machine or inside the intended container to check device and driver visibility.
  2. Create a supported Python environment.
  3. Use the official PyTorch installation selector or version-specific installation commands to install a CUDA-enabled PyTorch 2.13.x or 2.14.x build compatible with the host driver and GPU. Do not use the CPU-only index from the preceding section.
  4. Install FlagQuantum:
python -m pip install --only-binary=flagquantum "flagquantum==0.3.1" numpy
python -m pip check

Driver, PyTorch CUDA build, and GPU architecture must be compatible. Follow the chosen PyTorch build's requirements rather than assuming one CUDA version works on every machine. The toolkit/compiler requirements for custom source builds can differ from a binary installation.

Run the detection script below and confirm that torch.cuda.is_available() is true. Then run the explicit cuda:0 execution test. GPU visibility alone does not prove that circuit kernels, gradients, or optimizer updates work.

Install the optional cuda extra only if the intended workload requires Triton and its platform requirements are met. The basic execution script below does not require adding that extra.

5. Domestic Accelerator Environments

The release README lists vendor-provided PyTorch environments for Hygon DCU, Moore Threads MUSA, MetaX, and Biren. Keep the vendor environment intact. The release's accelerator-runtime reference separately describes Torch-FL as the owner of cross-vendor integration through the logical flagos device.

Hardware family listed in the README What the environment provider must supply
Hygon DCU Compatible DCU driver/runtime, vendor PyTorch distribution, and the validated integration path
Moore Threads MUSA Compatible driver/MUSA stack, vendor PyTorch distribution, and the validated integration path
MetaX Compatible driver/SDK stack, vendor PyTorch distribution, and the validated integration path
Biren Compatible driver/SDK stack, vendor PyTorch distribution, and the validated integration path

There is no universal per-card driver/SDK version or generic Torch-FL installation command established by the FlagQuantum core dependency range. Obtain the driver + SDK + Python + PyTorch + integration build matrix from the vendor or environment owner. Do not guess that device names such as musa:0 or a vendor brand string are interchangeable with flagos:0; use the device contract documented for the validated integration.

Preserve the Vendor Runtime

Start in the provider's environment or container, then inspect the installation plan:

python -c "import sys, torch; print(sys.version); print(torch.__version__)"
python -m pip install --dry-run "flagquantum==0.3.1"

If dependency resolution retains the compatible vendor runtime, install using the provider's index/wheel guidance:

python -m pip install "flagquantum==0.3.1"
python -m pip check

A version such as 2.10.0+metax3.8.1.0 is accepted by the core PyTorch requirement. It does not, by itself, establish hardware execution support. Avoid replacing a managed vendor runtime with upstream CPU/CUDA PyTorch, using eager upgrades, or forcing an incompatible installation with --no-deps.

Use the Optional FlagOS Path When Provisioned

For the Torch-FL path, the provider must supply a compatible Torch-FL distribution and the runtime/operator evidence required for the requested workload. The release's statevector_local_p0 gate checks evidence before local FlagOS statevector execution. Device discovery alone is insufficient.

Torch-FL distributions can require import before PyTorch. The scripts below perform that explicit import before PyTorch when FlagOS activation is requested. Normal CPU/CUDA use does not import Torch-FL.

The release documents CUDA-backed Torch-FL reference evidence, including a locked PyTorch 2.11.0+cu130 reference environment. That reference is a development harness, not a generic end-user installation prescription or domestic-card certification. See the release accelerator runtime reference and operator profiles for the exact boundary.

6. Detect the Python Runtime and Available Platforms

Save as detect_runtime.py:

import argparse
import importlib.util
from importlib.metadata import version
import platform
import sys

parser = argparse.ArgumentParser()
parser.add_argument("--flagos", action="store_true", help="Explicitly activate the provisioned Torch-FL runtime")
args = parser.parse_args()
if args.flagos:
    import torch_fl  # Import before PyTorch when required by the Torch-FL distribution.

import torch
import flagquantum as fq
from flagquantum.compute import list_platform_status

print("Python:", sys.version.split()[0])
print("Platform:", platform.system(), platform.machine())
print("FlagQuantum:", version("flagquantum"))
print("PyTorch:", torch.__version__)
print("torch.version.cuda:", torch.version.cuda)
print("torch.version.hip:", getattr(torch.version, "hip", None))
print("torch.cuda available:", torch.cuda.is_available())
print("torch.cuda device count:", torch.cuda.device_count())
print("Torch-FL installed:", importlib.util.find_spec("torch_fl") is not None)
for status in list_platform_status():
    print(f"{status['device_type']}: activated={status['activated']}, available={status['available']}")
for index in range(torch.cuda.device_count()):
    print(f"CUDA API device {index}: {torch.cuda.get_device_name(index)}")

Run without activating optional providers:

python detect_runtime.py

Output recorded on the CPU verification machine:

Python: 3.12.14
Platform: Darwin arm64
FlagQuantum: 0.3.1
PyTorch: 2.14.1
torch.version.cuda: None
torch.version.hip: None
torch.cuda available: False
torch.cuda device count: 0
Torch-FL installed: False
cpu: activated=True, available=True
cuda: activated=True, available=False
flagos: activated=False, available=None

An activated built-in CUDA adapter with available=False does not mean a GPU exists. FlagOS available=None means an inactive optional provider was not probed; it is different from a successful negative hardware check.

On a working CUDA environment, the version/build fields will differ, torch.cuda available should be True, and visible devices will be listed. Some vendor runtimes expose CUDA-compatible APIs; a torch.cuda result alone is not proof of NVIDIA hardware identity. Record the actual driver, provider, and hardware alongside it.

To explicitly activate a provisioned Torch-FL installation:

python detect_runtime.py --flagos

Conditional successful activation includes Torch-FL installed: True and flagos: activated=True, available=True. Missing Torch-FL can raise ModuleNotFoundError; an incompatible build or missing device can fail during activation or discovery. These are configuration failures, not reasons to silently substitute CPU execution.

7. Execute a Circuit and Verify Its Gradient

This script creates the parameter and circuit on the selected device, requests explicit CPU/CUDA/FlagOS execution, checks residency of the returned probabilities, loss, and gradient, and compares the numerical results with analytical references.

Formula-to-Code Checks on the Selected Device

Formula Corresponding code in execute_device.py Validation
$\lvert\psi\rangle=\cos(\theta/2)\lvert00\rangle+\sin(\theta/2)\lvert11\rangle$ fq.Circuit(2, device=device).ry(0, theta).cx(0, 1) Parameters, circuit, result, and gradient must reside on the requested device.
$p=(\cos^2(\theta/2),0,0,\sin^2(\theta/2))$ expected_probabilities Compare all four entries with the analytical tensor, with atol=1e-5.
$E=\langle Z_0\rangle=\cos\theta$ loss = result.expectation().mean() Compare against torch.cos(reference), at theta=0.6.
$dE/d\theta=-\sin\theta$ loss.backward() Compare theta.grad against -torch.sin(reference).

The CPU example is runnable without accelerator hardware. CUDA and FlagOS commands require their documented devices and runtime installations; an analytical match on CPU does not validate those devices.

Save as execute_device.py:

import argparse

parser = argparse.ArgumentParser()
parser.add_argument("--device", default="cpu")
args = parser.parse_args()
if args.device.split(":", 1)[0] == "flagos":
    import torch_fl  # Preserve the provider's required import order.

import torch
import flagquantum as fq
from flagquantum.compute import get_platform_runtime
from flagquantum.runtime import resolve_device

device = resolve_device(args.device, backend="pytorch", require_accelerator=args.device.split(":", 1)[0] != "cpu")
theta = torch.tensor(0.6, device=device, requires_grad=True)
circuit = fq.Circuit(2, device=device).ry(0, theta).cx(0, 1)
result = fq.run(
    circuit,
    outputs=[fq.probabilities(), fq.expectation(fq.Z(0))],
    options=fq.ExecutionOptions(
        mode="statevector",
        backend="pytorch",
        device=str(device),
        precision="complex64",
        allow_backend_fallback=False,
        allow_approximate=False,
    ),
)
loss = result.expectation().mean()
loss.backward()
get_platform_runtime(device.type).synchronize(device)
probabilities = result.probabilities[0]
resident = all(value.device == device for value in (probabilities, loss, theta.grad))
assert resident
reference = torch.tensor(0.6)
expected_probabilities = torch.tensor([torch.cos(reference / 2).square(), 0.0, 0.0, torch.sin(reference / 2).square()])
assert torch.allclose(probabilities.detach().cpu(), expected_probabilities, atol=1e-5)
assert abs(loss.item() - torch.cos(reference).item()) < 1e-5
assert abs(theta.grad.item() + torch.sin(reference).item()) < 1e-5

print("Requested device:", args.device)
print("Resolved device:", device)
print("Result device:", probabilities.device)
print("Probabilities:", [round(p.item(), 6) for p in probabilities])
print(f"<Z0>: {loss.item():.6f}")
print(f"Gradient: {theta.grad.item():.6f}")
print("Result and gradient on requested device:", resident)
print("Execution and gradient checks passed.")

Run the locally tested CPU path:

python execute_device.py --device cpu

Expected CPU output:

Requested device: cpu
Resolved device: cpu
Result device: cpu
Probabilities: [0.912668, 0.0, 0.0, 0.087332]
<Z0>: 0.825336
Gradient: -0.564642
Result and gradient on requested device: True
Execution and gradient checks passed.

On a configured NVIDIA GPU, run:

python execute_device.py --device cuda:0

On an appropriately provisioned and accepted FlagOS path, run:

python execute_device.py --device flagos:0

For a successful accelerator run, the three device lines should all show the selected indexed device, and the numerical checks should pass with approximately the same values. These successful accelerator outputs were not locally measured. The assertions allow numerical tolerance rather than requiring identical final decimal digits.

On the verification machine, requesting cuda:0 failed with ValueError: Backend 'pytorch' does not expose device 'cuda'. It did not run on CPU. Error wording can differ in another runtime.

Logical tensor residency and a passing numerical test do not prove the absence of internal host staging or fallback within a provider. The script disables FlagQuantum backend fallback; stronger no-host-fallback or performance claims require provider tracing and workload evidence. The .cpu() reference comparisons and .item() printing are intentional reporting transfers after execution.

8. Check a Trainable Module and Optimizer Update

Construct the model on the selected device before constructing the optimizer. Match the circuit, module parameters, input data, targets, and execution-policy device when extending to a hybrid model.

Save as train_device.py:

import argparse

parser = argparse.ArgumentParser()
parser.add_argument("--device", default="cpu")
args = parser.parse_args()
if args.device.split(":", 1)[0] == "flagos":
    import torch_fl  # Preserve the provider's required import order.

import torch
import flagquantum as fq
from flagquantum.compute import get_platform_runtime
from flagquantum.runtime import resolve_device

device = resolve_device(args.device, backend="pytorch", require_accelerator=args.device.split(":", 1)[0] != "cpu")

def build_circuit(parameters):
    return fq.Circuit(2, device=parameters.device).ry(0, parameters[0]).cx(0, 1)

model = fq.Module(
    build_circuit,
    n_parameters=1,
    init=torch.tensor([0.6]),
    device=device,
    policy=fq.RuntimePolicy(
        execution_options=fq.ExecutionOptions(
            mode="statevector", backend="pytorch", device=str(device),
            allow_backend_fallback=False, allow_approximate=False,
        ),
        observable="z", observable_qubits=(0,),
    ),
)
optimizer = torch.optim.SGD(model.parameters(), lr=0.1)
optimizer.zero_grad()
loss = model().mean()
before = loss.item()
loss.backward()
parameter = next(model.parameters())
assert parameter.device == device and parameter.grad.device == device and loss.device == device
gradient = parameter.grad.item()
optimizer.step()
with torch.no_grad():
    after = model().mean().item()
get_platform_runtime(device.type).synchronize(device)
assert after < before

print("Training device:", parameter.device)
print(f"Before step: {before:.6f}")
print(f"Gradient: {gradient:.6f}")
print(f"After step: {after:.6f}")
print("Optimizer update check passed.")

Run:

python train_device.py --device cpu

Expected CPU output:

Training device: cpu
Before step: 0.825336
Gradient: -0.564642
After step: 0.792155
Optimizer update check passed.

After the forward/gradient execution check succeeds, the same script can be attempted with --device cuda:0 or --device flagos:0 in the corresponding validated environment. Conditional successful output reports that device and a decreased objective. This one-step check does not establish convergence, high-precision support, or support for MPS, tensor-network, noise, or distributed training on the same hardware.

9. Troubleshooting and Reproducibility

Symptom Next check
nvidia-smi cannot see a GPU Check driver installation, container device exposure, and scheduler allocation.
PyTorch reports CUDA unavailable Check whether you installed CPU-only PyTorch, the selected CUDA build, and driver/device compatibility.
A vendor runtime is replaced during installation Stop and review dependency resolution with the environment owner; preserve the matched vendor PyTorch build.
Torch-FL imports but FlagOS is unavailable Check the exact Torch-FL/PyTorch pairing, driver exposure, and required import order.
Device discovery passes but execution fails Inspect the failing operator, precision support, and required FlagOS workload/profile evidence.
Unsupported vendor device name Use the validated integration's documented device contract rather than inventing an alias.
Parameters or outputs unexpectedly reside on CPU Use explicit circuit/module devices and check tensor residency; do not infer execution device from a GPU's presence.
Device mismatch in a hybrid model Keep classical layers, encoded inputs, quantum parameters, targets, and execution policy on a consistent device.
Out of memory Reduce circuit width or batch size and account for backward/working storage; a statevector holds 2**n complex amplitudes per batch entry.
Results differ from CPU beyond tolerance Preserve the failing example and inspect precision, complex operators, runtime identity, and fallback behavior.

Record Python, FlagQuantum and PyTorch versions, vendor build labels, driver/SDK/container identity, device visibility, simulation method, precision, and the exact test commands. pip freeze alone does not capture drivers or physical hardware.

Continue Learning and Sources

Clone this wiki locally