Overview
Maestro provides a uniform interface to multiple quantum simulation algorithms and engines. You can explicitly select the simulator backend and method via SimulatorConfig.
Statevector Simulation
Full 2^N amplitude statevector simulation. Recommended for high entanglement circuits with up to 30 qubits on CPU or 36+ on GPU.
config = maestro.SimulatorConfig(
simulator_type=maestro.SimulatorType.QCSim,
simulation_type=maestro.SimulationType.Statevector,
)
result = maestro.simple_execute(qasm, config=config, shots=2000)
Matrix Product State (MPS)
MPS enables simulation of circuits with hundreds of qubits when entanglement is bounded (1D area law).
mps_config = maestro.SimulatorConfig(
simulator_type=maestro.SimulatorType.QCSim,
simulation_type=maestro.SimulationType.MatrixProductState,
max_bond_dimension=64,
singular_value_threshold=1e-10,
lookahead_depth=3,
disable_optimized_swapping=False,
)
result = maestro.simple_execute(qasm, config=mps_config, shots=1000)
print(result["method"])
Truncation Mode
singular_value_threshold is interpreted differently depending on truncation_mode:
- "discarded_weight" (the default on every backend): discard the smallest singular values until their cumulative squared weight, normalized by the total, would reach the threshold. This matches Qiskit Aer's and ITensor's convention, so it's the mode to use when comparing bond-dimension growth against an external ITensor run.
- "relative_max": discard singular values below threshold * sigma_max (the largest singular value at that bond). This was the historical default for the QCSim and GPU backends before discarded_weight became the default everywhere.
Only the QCSim and GPU backends support "relative_max"; the Aer backend always implements "discarded_weight" and raises ValueError if "relative_max" is requested.
mps_config = maestro.SimulatorConfig(
simulator_type=maestro.SimulatorType.QCSim,
simulation_type=maestro.SimulationType.MatrixProductState,
singular_value_threshold=1e-10,
truncation_mode="relative_max",
)
GPU SVD Algorithm Selection
For GPU MPS, MPO, and Tensor Network simulations, you can select the underlying cuSOLVER SVD algorithm to balance precision against execution speed:
- mps_use_gesvd: Standard QR-based SVD (gesvd), the current GPU plugin default.
- mps_use_gesvdj: Jacobi-based SVD (gesvdj), optimal for small to medium bond dimensions.
- mps_use_gesvdp: Polar-decomposition SVD (gesvdp).
- mps_use_gesvdr: Randomized SVD (gesvdr) for fixed-rank truncation. Tensor Network execution falls back to GESVD when this is selected.
Corresponding flags exist for MPO (mpo_use_gesvd*) and Tensor Networks (tensor_network_use_gesvd*). All Python selection flags default to False, meaning no explicit override; the installed GPU plugin supplies the default (currently GESVD for all three). Set a flag to True to select that algorithm explicitly.
Stabilizer (Clifford-only)
Ultra-fast polynomial-time simulation for circuits comprising only Clifford gates (H, S, CX, CZ, X, Y, Z). Scales to thousands of qubits.
clifford_qasm = """
OPENQASM 2.0;
include "qelib1.inc";
qreg q[100];
creg c[100];
h q[0];
cx q[0], q[1];
cx q[1], q[2];
measure q -> c;
"""
stab_config = maestro.SimulatorConfig(
simulator_type=maestro.SimulatorType.QCSim,
simulation_type=maestro.SimulationType.Stabilizer,
)
result = maestro.simple_execute(clifford_qasm, config=stab_config, shots=10000)
Backend Compatibility Matrix
| SimulationType | QCSim | Qiskit Aer | GPU | QuEST |
| Statevector | Yes | Yes | Yes | Yes |
| MatrixProductState | Yes | Yes | Yes | No |
| Stabilizer | Yes | Yes | No | No |
| TensorNetwork | Yes | Yes | Yes | No |
| PauliPropagator | Yes | No | Yes | No |
| ExtendedStabilizer | No | Yes | No | No |
Distributed Execution:
- QCSim and Qiskit Aer support p-block composite simulation via CompositeQCSim / CompositeQiskitAer.
- QuEST natively supports MPI-distributed statevector simulation across cluster nodes.
Object-Oriented Simulator Control
For full low-level control over the simulation lifecycle, use the Maestro engine directly:
import maestro
m = maestro.Maestro()
handle = m.create_simulator(
maestro.SimulatorType.QCSim,
maestro.SimulationType.Statevector
)
sim = m.get_simulator(handle)
m.destroy_simulator(handle)