Repository navigation
Troubleshooting and FAQ
Use this guide to isolate installation, execution, result-reading, and training problems before opening an issue.
Scope: FlagQuantum 0.3.1. The two complete Python examples below were verified on October 20, 2026 with Python 3.12.14, PyTorch 2.13.0, and macOS ARM64 using CPU statevector execution. Accelerator and multi-node remedies describe diagnostic steps; they were not validated on accelerator hardware in this guide. Main-branch documentation can describe features newer than this release.
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.
| Symptom | First check | Detailed guide |
|---|---|---|
| Installation fails or import cannot find the package | Python version, active interpreter, wheel architecture, dependency constraints | Installation and Compatibility |
| CPU works but an accelerator fails | Device visibility in the intended PyTorch runtime and supported execution path | Accelerator Setup |
| Probabilities or bitstrings appear reversed | Qubit 0 is the most-significant bit; requested qubit order matters | Qubit Ordering and Result Conventions |
| Loss has no gradient or training does not change parameters | Tensor connectivity, scalar loss, parameter ownership, optimizer step | Training Parameterized Circuits |
| A classical layer learns but the quantum layer does not | Gradients and optimizer membership for every parameter group | Hybrid Classical-Quantum Models |
| Simulation runs out of memory | Qubit count, batch size, dtype, output size, autograd storage | Choosing a Simulation Method |
| Distributed workers hang or disagree | Run the two-worker collective preflight before training | Distributed Simulation and Training |
Run commands using the same interpreter as your application or notebook kernel. Save this script as faq_diagnostics.py:
import importlib.metadata as metadata
import platform
import sys
print('Python:', sys.version.split()[0])
print('Platform:', platform.system(), platform.machine())
print('Interpreter:', sys.executable)
for package in ('flagquantum', 'torch'):
try:
print(f'{package}:', metadata.version(package))
except metadata.PackageNotFoundError:
print(f'{package}: NOT INSTALLED in this interpreter')
import torch
import flagquantum as fq
print('CUDA build:', torch.version.cuda)
print('CUDA available:', torch.cuda.is_available())
print('Distributed available:', torch.distributed.is_available())
options = fq.ExecutionOptions(mode='statevector', backend='pytorch', device='cpu')
circuit = fq.Circuit(2).h(0).cx(0, 1)
probabilities = fq.run(circuit, outputs=fq.probabilities(), options=options).probabilities
expected = torch.tensor([[0.5, 0.0, 0.0, 0.5]], dtype=probabilities.dtype)
assert probabilities.shape == (1, 4)
assert torch.allclose(probabilities.cpu(), expected, atol=1e-6)
print('Bell probabilities:', [round(x, 6) for x in probabilities[0].tolist()])
print('CPU smoke test passed.')Run:
python faq_diagnostics.pyExample output from the verified CPU environment:
Python: 3.12.14
Platform: Darwin arm64
Interpreter: /path/to/your/environment/bin/python
flagquantum: 0.3.1
torch: 2.13.0
CUDA build: None
CUDA available: False
Distributed available: True
Bell probabilities: [0.5, 0.0, 0.0, 0.5]
CPU smoke test passed.
The interpreter path, platform, versions, and runtime availability depend on your environment. CUDA available: False is expected for this CPU-only example. Distributed available: True reports that PyTorch includes distributed support; it does not prove that networking, a process group, or any distributed FlagQuantum workload works.
The assertions verify the Bell-state probabilities and the leading batch dimension. If an import fails, the preceding package and interpreter information still helps locate an environment mismatch. A successful test verifies this small CPU path only.
FlagQuantum 0.3.1 declares Python >=3.10,<3.13 and publishes wheels for macOS ARM64, Linux x86-64 with compatible manylinux/glibc support, and Windows x64. Check the interpreter and architecture:
python --version
python -c "import platform, sys; print(sys.executable); print(platform.system(), platform.machine())"
python -m pip --versionUse a supported 64-bit interpreter. On Apple Silicon, use an ARM64 interpreter for the ARM64 wheel. A published source archive does not establish that an unsupported platform can build or run the package.
For a fresh upstream CPU environment, after creating and activating a Python 3.10–3.12 virtual environment:
python -m pip install --upgrade pip
python -m pip install "torch>=2.13,<2.15"
python -m pip install --only-binary=flagquantum "flagquantum==0.3.1" numpy
python -m pip checkThese commands use the default package index; on Linux or Windows, use the CPU-wheel index instructions in Installation and Compatibility if you specifically want CPU-only PyTorch. Retain the vendor-provided runtime when working inside a managed accelerator environment.
Check that installation and execution use the same interpreter:
python -m pip show flagquantum torch
python -c "import sys, flagquantum; print(sys.executable); print(flagquantum.__file__)"In a notebook, inspect sys.executable in the notebook itself and select the intended environment's kernel. Restart that kernel after changing binary dependencies. Also check for local files or directories named flagquantum.py, flagquantum, or torch.py that shadow installed packages.
For a binary loading error, keep the complete traceback and check that Python architecture, wheel, OS, and PyTorch runtime agree. Reproduce in a clean supported environment before replacing shared system libraries.
The core release requires torch>=2.10,<2.15; the invertible extra narrows this to torch>=2.13,<2.14. A 2.14.x environment therefore cannot satisfy that extra. Choose a compatible environment or omit an unused extra rather than bypassing dependency checks.
Run python -m pip check after installation. In vendor-managed environments, preview resolution with python -m pip install --dry-run "flagquantum==0.3.1" and follow the vendor setup guide. Replacing vendor PyTorch with upstream PyTorch can remove accelerator support.
In the intended environment, run:
python -c "import torch; print('PyTorch:', torch.__version__); print('CUDA build:', torch.version.cuda); print('Available:', torch.cuda.is_available()); print('Visible GPUs:', torch.cuda.device_count())"A CPU-only PyTorch build does not become CUDA-enabled by installing a system CUDA toolkit. For NVIDIA execution, install a compatible CUDA-enabled PyTorch build and driver using the official PyTorch instructions linked in Accelerator Setup. Check container GPU access and visibility settings as applicable. The FlagQuantum cuda extra supplies an optional dependency; it does not install drivers or select a CUDA-enabled PyTorch build.
Start with explicit ExecutionOptions(mode="statevector", backend="pytorch", device="cpu") and the CPU smoke test. Then use an explicitly supported accelerator path and place circuit parameters, inputs, and targets on the same device. A device exposed by one runtime is not automatically available through another backend.
For domestic accelerators, follow the matching vendor and Torch-FL setup. The documented logical flagos path requires its compatible runtime and supported operator path. Do not invent a device alias or infer support from the device name alone. Some Torch-FL environments require importing torch_fl before torch; follow the environment's documented import order.
Apple's PyTorch device name mps and the matrix product state simulation method are separate concepts. Availability of Apple's MPS backend does not establish FlagQuantum support for that accelerator path.
A result tensor on an accelerator, or disabling backend fallback, does not by itself prove that every provider operation avoids host staging. Check the specific workload's capability evidence.
Qubit 0 is the most-significant bit. For two qubits, applying x(0) to the zero state produces |10> at index 2, while x(1) produces |01> at index 1. Account for the other framework's convention when comparing results. See the runnable ordering examples in Qubit Ordering and Result Conventions.
A single circuit normally retains a leading batch dimension. The smoke test returns probabilities of shape (1, 4) for two qubits. A Pauli-Z expectation in the gradient example below has shape (1,). Check shapes before combining predictions and targets; unintended broadcasting can construct a different loss while still producing valid tensors.
Use the result accessors shown in the tutorials:
probabilities = result.probabilities # property
# For a result containing the corresponding requested outputs:
# value = result.expectation() # method
# state = result.statevector() # method
# counts = result.counts # propertyRequest the needed output in fq.run(..., outputs=...) first. Samples, counts, probabilities, and expectations are different result types; do not assume that requesting one materializes every other output.
Finite-shot measurement is random. Exact simulator probabilities are not integer counts, and counts need not match probability times shot count exactly. Use assertions about total shots and allowed outcomes, and statistical tolerances when comparing frequencies. Record shots, seeds, method, device, and versions; a fixed seed does not guarantee identical sampling across different runtimes or devices.
For a Pauli-Z measurement, P(0) = (1 + <Z>)/2. An expectation of 0.25 is therefore not a probability of 0.25.
| Formula | Code in faq_gradients.py | Diagnostic |
|---|---|---|
(1 + prediction) / 2 |
Probability conversion only; prediction is the Z expectation. | |
loss = (prediction - target).square().mean() |
Require a real scalar with requires_grad=True. | |
expected_gradient = -2 * (torch.cos(theta.detach()) - target) * torch.sin(theta.detach()) |
The script compares theta.grad before updating parameters. | |
optimizer.step() |
SGD is configured with lr=0.1; the post-update loss must decrease in this bounded example. |
Save this minimal trainability check as faq_gradients.py:
import torch
import flagquantum as fq
options = fq.ExecutionOptions(mode='statevector', backend='pytorch', device='cpu')
theta = torch.nn.Parameter(torch.tensor(0.6))
optimizer = torch.optim.SGD([theta], lr=0.1)
target = torch.tensor(0.25)
def predict():
circuit = fq.Circuit(1).ry(0, theta)
return fq.run(circuit, outputs=fq.expectation(fq.Z(0)), options=options).expectation()
optimizer.zero_grad()
prediction = predict()
loss = (prediction - target).square().mean()
assert loss.ndim == 0 and loss.requires_grad
before = loss.item()
loss.backward()
assert theta.grad is not None and torch.isfinite(theta.grad).all()
expected_gradient = -2 * (torch.cos(theta.detach()) - target) * torch.sin(theta.detach())
assert torch.allclose(theta.grad, expected_gradient, atol=1e-6)
gradient = theta.grad.item()
optimizer.step()
with torch.no_grad():
after = (predict() - target).square().mean().item()
assert after < before
print('Output shape:', tuple(prediction.shape))
print('Differentiable scalar loss:', loss.requires_grad and loss.ndim == 0)
print(f'Gradient: {gradient:.6f}')
print(f'Loss before update: {before:.6f}')
print(f'Loss after update: {after:.6f}')
print('Autograd and optimizer checks passed.')Run python faq_gradients.py. Expected application output:
Output shape: (1,)
Differentiable scalar loss: True
Gradient: -0.649718
Loss before update: 0.331011
Loss after update: 0.288298
Autograd and optimizer checks passed.
The gradient assertion checks an independent analytical expression. The fresh forward pass after the update verifies that the optimizer reduced this particular loss.
- Keep trainable angles as floating-point tensors or registered parameters.
.item(),float(...), and.detach()inside the forward computation break the parameter's connection to autograd. - Check
loss.requires_grad, reduce a vector loss intentionally, and call backward on a real scalar tensor. - Put every trainable parameter group in the optimizer. For an
fq.Module, use its registeredparameters(); for a complete hybrid model, optimize the outer model's parameters. - Clear gradients, run a fresh forward computation, call backward, and then step. Reusing a consumed graph can cause a second-backward error; rebuilding the forward pass is the normal training pattern.
-
torch.no_grad()is appropriate for final evaluation, but disables the graph needed during training.
A non-leaf intermediate tensor does not normally retain .grad; inspect the leaf parameter or use PyTorch's explicit gradient-retention facilities when debugging intermediates.
A zero gradient can be correct. For RY(theta) followed by <Z>, the derivative is -sin(theta), which is zero at theta=0. Try a nonzero initialization and compare against the analytical example before concluding that autograd is disconnected. Also inspect whether the objective actually depends on each parameter.
In the documented fq.train workflow, recorded losses and last_execution come from the forward pass before the corresponding optimizer update. Run a fresh evaluation after training to inspect the final parameter values. fq.train accepts an fq.Module; train a general outer PyTorch hybrid model with a regular PyTorch loop.
Integer samples and count dictionaries do not provide an ordinary pathwise autograd connection to circuit parameters. Use the supported differentiable expectation workflow for these tutorials; hardware or sampled-gradient workflows need their own estimator and support contract.
The state alone has B * 2**n complex amplitudes for batch size B and qubit count n. A complex64 state needs approximately 8 * B * 2**n bytes; complex128 doubles that. For 30 qubits and batch size 1, the complex64 state alone is 8 GiB. Gate temporaries, requested outputs, autograd storage, and runtime allocations add to this amount.
Start with fewer qubits and smaller batches. Request only the outputs you need, and avoid retaining graph-connected results from every training step. Use torch.no_grad() for inference when gradients are unnecessary. A smaller diagnostic case helps separate capacity limits from API failures.
MPS can help when the circuit's entanglement structure keeps bond dimensions small. It can still become expensive; truncation can introduce approximation error. A tensor-network method can also face expensive contractions. Neither method guarantees that an arbitrary large circuit will fit. See Choosing a Simulation Method.
Small workloads can be dominated by dispatch, transfer, initialization, and synchronization costs. Measure representative circuits after warmup and include the operations your application needs. Accelerator timings must account for asynchronous execution through the runtime's supported synchronization or timing facilities. A tiny Bell-state test verifies correctness, not useful speedup.
Before distributed training, run the collective preflight from Distributed Simulation and Training. That page provides complete two-worker launch commands and a separate analytical training check.
| Symptom | What to inspect |
|---|---|
| Rendezvous times out | Every worker was launched, matching world configuration, node ranks, reachable master address, and matching rendezvous port. |
| Another node cannot connect | Use node 0's reachable address, not 127.0.0.1; check the required inter-node transport and firewall configuration. Rendezvous connectivity alone does not establish collective connectivity. |
| Address already in use | Check whether an earlier job still owns the port; choose a free port consistently across the new job. |
| CUDA or collective backend initialization fails | GPU visibility, local rank-to-device assignment, compatible PyTorch build, backend availability, and runtime/network configuration. |
| Workers disagree about imports or results | Match package versions, scripts, dtype, inputs, and launch settings on all nodes. |
| A job appears stuck | Read logs from every rank; one rank may have failed while others wait in a collective. Stop the failed job's remaining workers before retrying. |
The published tutorial intentionally requires exactly two workers for its example. Do not increase the worker count without adapting and validating the workload. Its JSON reports are diagnostics, not resumable checkpoints. A passing two-worker CPU run does not certify multi-node scalability, GPU behavior, or another distributed simulation method. Preserve any blockers and claim restrictions returned by the execution summary.
Use the issue tracker and include:
- Expected behavior and observed behavior, including the complete traceback.
- A minimal script, exact launch command, and the smallest failing circuit or batch.
- Diagnostic output from section 2, plus
python -m pip checkand relevant optional package versions. - Execution mode, backend, device, dtype, requested outputs, shots, and random seeds where applicable.
- For accelerators: model, driver, runtime, and container details. For distributed jobs: all-rank logs, topology, backend, and the preflight result.
- Whether the same case passes on CPU and which package release or source commit you tested.
Inspect logs before posting and remove credentials, access tokens, private endpoints, or other sensitive data. Avoid posting a full environment dump when a targeted diagnostic report is sufficient.
- FlagQuantum 0.3.1 package metadata and release files
- Release installation and API examples
- Release dependency declarations
- Release capability catalog
- Quick Start · Installation and Compatibility
- Core Concepts · Building and Simulating Circuits
- Training Parameterized Circuits · Hybrid Classical-Quantum Models
- Accelerator Setup · Distributed Simulation and Training
- Installation and Compatibility
- Quick Start
- Install and Run
- Qubit Ordering and Result Conventions
- Runnable Examples
- Building and Simulating Circuits
- Training Parameterized Circuits
- Hybrid Classical-Quantum Models
- Core Concepts
- From Papers and Equations to FlagQuantum Code
- Reproducing Molecular Hydrogen VQE
- Fundamentals
- Tutorials
- Choosing a Simulation Method
- Accelerator Setup
- Distributed Simulation and Training
- Execution
- Circuit Compilation and Interoperability
- Noise and Open-System Simulation
- Quantum Error Correction Experiments
- Cloud and Quantum Hardware Execution
- QPU Digital Twins
- Advanced Topics
- Support and Contribution
All 21 guides are linked in the navigation sections. The Wiki Directory lists published guides and current repository resources.
- Troubleshooting and FAQ
- Reproducibility and Benchmarks
- Development and Contribution Guide
- Documentation Guide
Documentation, capability, and contribution links in this section follow current main; the guides above target 0.3.1.