A sign error in a rotation gate is the kind of bug that doesn’t crash — it just quietly gives you the wrong physics. QuantRS2 0.2.1 fixes one, along with a phase-estimation routine that took hours when it should have taken milliseconds.
Today we released QuantRS2 0.2.1 — a correctness-and-performance release. The headline fix: RotationZ, CRZ, and ParametricRotationZ were using a reversed diagonal and disagreeing with the IBM/Qiskit/OpenQASM-3 standard on every circuit that used them. Alongside it: Quantum Phase Estimation goes from hours to milliseconds, D-Wave chain-break decoding and AWS Braket request signing move from placeholder to real, and a new pure-Rust oxicuda backend lands.
No C. No Fortran. No CUDA toolkit required at build time. QuantRS2 is a comprehensive, modular, pure-Rust quantum computing framework — a Rust-native alternative to Qiskit, Cirq, and PennyLane. SymEngine’s C++ symbolic core stays replaced by the 100%-Rust quantrs2-symengine-pure; OpenBLAS stays replaced by the pure-Rust OxiBLAS backend. Default features remain 100% Pure Rust, and the whole framework still compiles to Linux, macOS, Windows, and WASM as a single static binary.
Why QuantRS2 0.2.1 is a game changer
Two failure modes plague quantum SDKs, and they’re both worse than a crash:
- Silent sign-convention bugs. Get a rotation gate’s sign backwards and your circuit still runs, still returns probabilities that sum to one, and still looks plausible — it’s just physically wrong. These bugs survive for releases because nothing obviously breaks.
- “Integration” code that’s actually a placeholder. Chain-break decoding that never recomputes real energy, request signing that isn’t real signing, cost estimators that return static labels — all common in scaffolding that shipped fast and never got finished.
QuantRS2 0.2.1 closes both gaps:
Rz/CRZ/ParametricRotationZnow match IBM/Qiskit/OpenQASM-3. The gates previously useddiag(e^{+iλ/2}, e^{-iλ/2}); they now use the standarddiag(e^{-iλ/2}, e^{+iλ/2}). This is a behaviour change — simulation results for any circuit using these gates differ from 0.2.0 (they’re now correct) — and it was also silently corruptingdecompose_u_gateand single-qubit ZYZ reconstruction. Caught independently by @cleitonaugusto via the CleitonForge symbolic-verification framework (DOI 10.5281/zenodo.21210972) and tracked as issue #32.- Quantum Phase Estimation: hours → milliseconds.
EnhancedPhaseEstimationbuilt each controlled-U^(2^i)power by literally applying the base unitary2^itimes — at 18 phase qubits, that’s 262,143 full-state-vector passes. It now builds the operator as a dense matrix once and forms each power by repeated squaring: O(phase_qubits) matrix multiplies instead of O(2^phase_qubits) state-vector applications. - D-Wave chain-break decoding is real now.
decode_embedded_solutionunembeds chains and recomputes the actual problem energy from the unembedded assignment, instead of returning a placeholder. - AWS Braket requests are actually signed. Real AWS Signature Version 4, replacing a placeholder.
- CSP linear constraints compile.
add_linear_constraintturnsΣ aᵢ·xᵢ ⋈ rhsinto the QUBO via the quadratic penalty method with binary-encoded slack variables — it used to just returnUnsupportedConstraint. - A broad ML/Python-binding stub sweep replaced fabricated outputs with real computation: Lamport-signature-over-SHA-256 crypto and blockchain verification, SPSA-gradient training, statevector-based GNN message passing, real ONNX layer export, and AST-based (not string-matched) symbolic pattern matching.
This lands on 1,025,832 total lines of code, 836,324 Rust lines across 2,759 files, with 5,762 tests passing (0 failures, 74 skipped).
Technical Deep Dive
(a) Correctness — core/src/gate/functions.rs, core/src/parametric.rs, core/src/decomposition.rs. The Rz-family sign fix is a two-line diagonal change with a wide blast radius: it also fixes decompose_u_gate and ZYZ single-qubit reconstruction, which had been silently disagreeing between the internal simulator and OpenQASM export. Regression coverage lives in core/src/gate/functions.rs, core/src/parametric.rs, core/src/decomposition.rs, and a new sim/tests/issue_32_rz_convention.rs.
(b) Performance — sim/src/quantum_algorithms/types.rs, core/src/batch/operations.rs, device/src/photonic/cv_gates.rs. EnhancedPhaseEstimation now materializes the system-register operator once and forms U^(2^i) by repeated squaring. A related bug is fixed alongside it: PhaseEstimationResult::precisions was always length 1 regardless of how many eigenvalues were reported — it now has one entry per eigenvalue. Separately, apply_gate_sequence_batch detects fixed (non-parameterized) gates by name and caches their compiled matrices per sequence, so repeated CNOT chains or Hadamard layers compile once instead of once per application. Photonic CV gate optimization now coalesces adjacent same-mode PhaseRotation and Displacement operations.
(c) Real integrations — anneal/src/dwave/functions.rs, anneal/src/braket.rs, anneal/src/csp_compiler.rs, anneal/src/universal_annealing_compiler/, anneal/src/solution_clustering/. Beyond chain-break decoding, SigV4 signing, and CSP linear constraints: a new CostOptimizer does cross-platform cost estimation and cheapest-platform recommendation, a new PerformancePredictor models per-platform performance and confidence from recorded results, and SolutionClusteringAnalyzer gained real k-means clustering with structural feature extraction. solution_clustering/analyzer.rs was split into an analyzer/ module directory (mod.rs + quality.rs) to stay under the workspace’s 2,000-line file policy.
(d) Numerical foundation. The stack rides SciRS2 0.6.5 (up from 0.5.0), PyO3 0.29.0, and wgpu 30.0.0. New this release: oxicuda 0.5.5 — a pure-Rust CUDA replacement (driver/memory/launch/ptx/webgpu features) that loads libcuda.so at runtime, so no CUDA Toolkit is required at build time — plus pollster for synchronous wgpu adapter/device queries.
Getting Started
cargo add quantrs2-core quantrs2-circuit quantrs2-sim
use quantrs2_circuit::builder::Circuit;
use quantrs2_sim::statevector::StateVectorSimulator;
fn main() {
// Create a circuit with 2 qubits
let mut circuit = Circuit::<2>::new();
// Build a Bell state circuit: H(0) followed by CNOT(0, 1)
circuit.h(0).unwrap()
.cnot(0, 1).unwrap();
// Run the circuit on the state vector simulator
let simulator = StateVectorSimulator::new();
let result = circuit.run(simulator).unwrap();
// Print the resulting probabilities
for (i, prob) in result.probabilities().iter().enumerate() {
let bits = format!("{:02b}", i);
println!("|{}⟩: {:.6}", bits, prob);
}
}
What’s New in 0.2.1
Added
- QASM3
const-expression register sizes:qubit[n]/bit[n]now resolvenfrom a declaredconstexpression — literals, variable lookups, full binary/unary/function arithmetic — instead of only integer literals. - CSP linear constraints, D-Wave chain-break decoding, AWS Braket SigV4 signing — see above.
- Cost/performance prediction and solution clustering:
CostOptimizer,PerformancePredictor, and real k-means inSolutionClusteringAnalyzer.
Changed
- SciRS2 family 0.5.0 → 0.6.5; PyO3 0.28.3 → 0.29.0; wgpu 29.0.3 → 30.0.0; oxicode 0.2.4 → 0.2.6; numrs2 0.4.0 → 0.4.1; pandrs 0.4.0 → 0.4.1. Added
oxicuda0.5.5 andpollster0.4.0. - Platform capability detection now wires
PlatformCapabilities::detect()into bothdetect_platform_capabilitiesanddetect_simd_capabilities, with AVX512 upgraded from compile-time to runtime detection. - Batch gate execution and photonic CV gate-sequence optimization — see above.
Fixed
- Rz/CRZ/ParametricRotationZ sign convention (behaviour change) and the QPE performance/precisions bug — see above.
- wgpu 30 adapter request compatibility, a
PyStateTomographyPyDictconversion bug, and honest (non-fabricated) GPU specs and Metal availability reporting in the Tytan and Sim GPU backends. - Quantum Boltzmann Machine gradients and penalty-optimization constraint tracking now use real computation instead of placeholder values.
Tips
- Re-baseline any golden-output tests that use
Rz,CRZ, orParametricRotationZ. Results from 0.2.0 and earlier will differ — they were wrong before; they’re correct now. - Running Quantum Phase Estimation at high qubit counts? Upgrade — an 18-phase-qubit run that used to take hours now completes via matrix squaring, and
PhaseEstimationResult::precisionsnow correctly returns one entry per eigenvalue. - Building a QUBO from constraints?
add_linear_constraintnow actually compiles≤/≥/</>/=linear constraints instead of returningUnsupportedConstraint. - Picking between D-Wave, Braket, and Fujitsu? Try the new
CostOptimizerandPerformancePredictorin the universal annealing compiler before you commit to a platform. - Want CUDA without installing the CUDA Toolkit? Enable
oxicuda’sdriver/memory/launch/ptxfeatures — it loadslibcuda.soat runtime.
This is the foundation
QuantRS2 0.2.1 builds on SciRS2 0.6.5 (arrays, linalg, FFT-via-OxiFFT, optimize), the pure-Rust OxiBLAS backend, the new pure-Rust oxicuda GPU backend, NumRS2 0.4.1 and PandRS 0.4.1 for data, and Oxicode 0.2.6 plus OxiARC (oxiarc-deflate / oxiarc-lz4) for pure-Rust serialization and compression. The result stays an end-to-end, C/C++/Fortran-free quantum stack — from circuit construction through simulation, annealing, and hardware integration.
Repository: https://github.com/cool-japan/quantrs
Star the repo if a bug-for-bug-correct, pure-Rust path to quantum computing is something you want to see grow — and file an issue if you spot another sign convention we got backwards.
The era of silent quantum-simulation bugs is over. Pure Rust quantum computing is here — fast, safe, and sovereign.
— KitaSan at COOLJAPAN OÜ August 30, 2026