Core API

QPE Engine

Quantum Phase Estimation (QPE) implementation for molecular systems.

Phase 2: Standard QPE circuit with: - HF state preparation via qml.BasisState - Controlled time evolution via qml.TrotterProduct - Inverse QFT via qml.adjoint(qml.QFT)

Phase 4: Catalyst @qjit integration for JIT compilation support.

class q2m3.core.qpe.QPEEngine(n_qubits, n_iterations=8, mapping='jordan_wigner', device='default.qubit', device_type='lightning.qubit', use_catalyst=False, **kwargs)[source]

Bases: object

Iterative Quantum Phase Estimation engine for QM/MM calculations.

Implements the iterative QPE algorithm optimized for near-term quantum devices, targeting early fault-tolerant quantum computers (EFTQC).

Parameters:
  • n_qubits (int)

  • n_iterations (int)

  • mapping (str)

  • device (str)

  • device_type (str)

  • use_catalyst (bool)

__init__(n_qubits, n_iterations=8, mapping='jordan_wigner', device='default.qubit', device_type='lightning.qubit', use_catalyst=False, **kwargs)[source]

Initialize QPE engine.

Parameters:
  • n_qubits (int) – Number of system qubits

  • n_iterations (int) – Number of QPE iterations (5-10 for POC)

  • mapping (str) – Fermion-to-qubit mapping (‘jordan_wigner’ or ‘bravyi_kitaev’)

  • device (str) – PennyLane device name (deprecated, use device_type instead)

  • device_type (str) – Device selection strategy: - “auto”: Auto-select best available (GPU > lightning.qubit > default.qubit) - “default.qubit”: Standard PennyLane simulator - “lightning.qubit”: High-performance CPU simulator (default) - “lightning.gpu”: GPU-accelerated simulator (requires cuQuantum)

  • use_catalyst (bool) – Enable Catalyst @qjit compilation (requires pennylane-catalyst)

  • **kwargs – Additional device configuration

estimate_ground_state_energy(hamiltonian_data, initial_state=None)[source]

Estimate ground state energy using classical simulation (POC).

This is a classical simulation that mimics QPE behavior for POC purposes. Uses PySCF Hartree-Fock results as approximation.

Parameters:
  • hamiltonian_data (dict[str, Any]) – Dictionary containing molecular data from PySCF

  • initial_state (ndarray | None) – Initial quantum state preparation (unused in classical sim)

Returns:

  • energy: Ground state energy in Hartree

  • convergence: Convergence information

  • density_matrix: Electronic density matrix

Return type:

Dictionary containing

static compute_optimal_base_time(energy_estimate, safety_margin=None)[source]

Compute optimal base_time to avoid phase overflow in QPE.

For QPE, the relationship is: phi = |E| * t / (2*pi). To avoid overflow, we need phi < 1, i.e., t < 2*pi / |E|.

Parameters:
  • energy_estimate (float) – Estimated ground state energy (e.g., HF energy)

  • safety_margin (float) – Safety factor (default: PHASE_SAFETY_MARGIN = 0.8)

Returns:

Optimal base_time that avoids phase overflow

Return type:

float

static compute_shifted_qpe_params(target_resolution=0.001, energy_range=0.2, safety_margin=None)[source]

Compute optimal QPE parameters for energy-shifted QPE.

In energy-shifted QPE, the Hamiltonian is transformed as H’ = H - E_ref * I, where E_ref is typically the HF energy. This allows QPE to measure ΔE = E - E_ref instead of the absolute energy E, enabling higher precision for detecting small energy changes like MM embedding effects.

Physics: - QPE measures phase: φ = |ΔE| * t / (2π) - For n-bit precision: resolution = / (2^n * t) - Energy range: ΔE_max = / t (to avoid phase overflow)

This method calculates the optimal n_estimation_wires and base_time to achieve the target resolution while covering the expected energy range.

Parameters:
  • target_resolution (float) – Target energy resolution in Hartree (default: 0.001 Ha ≈ 0.63 kcal/mol)

  • energy_range (float) – Expected energy range around E_ref in Hartree (default: ±0.1 Ha)

  • safety_margin (float) – Safety factor for phase overflow (default: PHASE_SAFETY_MARGIN)

Returns:

  • n_estimation_wires: Number of estimation qubits for target precision

  • base_time: Optimal base evolution time

  • resolution: Actual energy resolution achieved

  • max_energy_range: Maximum measurable energy range

  • phase_cycles: Number of phase cycles for ΔE at edge of range

Return type:

Dictionary containing

Example

>>> params = QPEEngine.compute_shifted_qpe_params(
...     target_resolution=0.001,  # 0.63 kcal/mol
...     energy_range=0.2,         # ±0.1 Ha range
... )
>>> print(f"Use {params['n_estimation_wires']} estimation qubits")
Use 7 estimation qubits
>>> print(f"base_time = {params['base_time']:.4f}")
base_time = 49.0874
draw_qpe_circuit(hamiltonian, hf_state, n_estimation_wires=4, base_time=0.3, n_trotter_steps=5, max_display_wires=8, use_pennylane_draw=True)[source]

Generate text visualization of QPE circuit structure.

Uses qml.draw() with decimals=None and level=0 for clean output, showing circuit structure without parameter clutter.

Parameters:
  • hamiltonian (LinearCombination) – PennyLane molecular Hamiltonian

  • hf_state (ndarray) – HF reference state binary array

  • n_estimation_wires (int) – Number of estimation qubits

  • base_time (float) – Base evolution time

  • n_trotter_steps (int) – Trotter steps per evolution

  • max_display_wires (int) – Max wires for full circuit display (default: 8)

  • use_pennylane_draw (bool) – Use qml.draw() for visualization (default: True)

Returns:

String representation of the circuit

Return type:

str

QM/MM System

QM/MM system builder for molecular simulations.

class q2m3.core.qmmm_system.Atom(symbol, position, charge=0.0, is_qm=True)[source]

Bases: object

Represents an atom with position and properties.

Parameters:
  • symbol (str)

  • position (ndarray)

  • charge (float)

  • is_qm (bool)

class q2m3.core.qmmm_system.QMMMSystem(qm_atoms, mm_model='tip3p', solvation_shells=1, num_waters=8)[source]

Bases: object

Build and manage QM/MM system for H3O+ in water environment.

Handles the partitioning of QM and MM regions, and sets up the embedding potential for quantum calculations.

Parameters:
  • qm_atoms (list[Atom])

  • mm_model (str)

  • solvation_shells (int)

  • num_waters (int)

__init__(qm_atoms, mm_model='tip3p', solvation_shells=1, num_waters=8)[source]

Initialize QM/MM system.

Parameters:
  • qm_atoms (list[Atom]) – List of atoms in QM region (H3O+)

  • mm_model (str) – Water model for MM region

  • solvation_shells (int) – Number of solvation shells

  • num_waters (int) – Number of water molecules in MM region

get_embedding_potential()[source]

Calculate embedding potential from MM charges.

Returns:

Tuple of (charges, coordinates) for MM point charges

Return type:

tuple[ndarray, ndarray]

get_total_charge()[source]

Get total system charge.

Return type:

int

get_qm_coords()[source]

Get QM atom coordinates as numpy array.

Return type:

ndarray

to_pyscf_mol()[source]

Convert to PySCF molecule format.

Returns:

Dictionary with atom positions and basis set info

Return type:

dict[str, Any]

Quantum QM/MM Orchestrator

Main Quantum-QM/MM interface combining all components.

class q2m3.core.quantum_qmmm.QuantumQMMM(qm_atoms, mm_waters=8, qpe_config=None, use_catalyst=False, rdm_config=None)[source]

Bases: object

Main interface for Quantum-QM/MM calculations.

Coordinates the workflow between PySCF classical calculations, PennyLane quantum circuits, and QM/MM embedding.

Parameters:
  • qm_atoms (list[Atom])

  • mm_waters (int)

  • qpe_config (dict[str, Any])

  • use_catalyst (bool)

  • rdm_config (dict[str, Any] | None)

__init__(qm_atoms, mm_waters=8, qpe_config=None, use_catalyst=False, rdm_config=None)[source]

Initialize Quantum-QM/MM calculator.

Parameters:
  • qm_atoms (list[Atom]) – Atoms in the QM region

  • mm_waters (int) – Number of water molecules in MM region

  • qpe_config (dict[str, Any]) – Configuration for QPE algorithm

  • use_catalyst (bool) – Enable Catalyst @qjit compilation for QPE circuits

  • rdm_config (dict[str, Any] | None) – Configuration for RDM measurement (default: enabled with defaults) - enabled: Enable RDM measurement (default: True) - n_shots: Measurement shots (default: 1000) - include_off_diagonal: Measure off-diagonal elements (default: True) - symmetrize: Enforce Hermitian symmetry (default: True)

compute_ground_state(include_resource_estimation=False)[source]

Compute ground state properties using QPE.

Parameters:

include_resource_estimation (bool) – If True, include EFTQC resource estimation in the output. Uses PennyLane’s DoubleFactorization to estimate logical qubits, Toffoli gates, and QPE iterations. Default: False.

Returns:

  • energy: Ground state energy (Hartree)

  • energy_hf: HF reference energy (Hartree)

  • energy_difference: |E_QPE - E_HF| (Hartree)

  • density_matrix: Electronic density matrix

  • atomic_charges: Mulliken charges

  • convergence: Convergence information

  • eftqc_resources: (optional) EFTQC resource estimation if requested

  • timing: Fine-grained timing breakdown for performance analysis

Return type:

Dictionary containing

draw_circuits()[source]

Generate text visualizations of QPE and RDM circuits.

Returns:

  • “qpe”: QPE circuit visualization

  • ”rdm”: RDM measurement circuit visualization

Return type:

Dictionary with keys

Reduced Density Matrix

Reduced Density Matrix (RDM) estimation from quantum states.

Implements 1-RDM measurement using Pauli expectation values after Jordan-Wigner transformation of fermionic operators.

Key formulas:

Diagonal: gamma_pp = <a_p†a_p> = (1 - <Z_p>) / 2
Off-diagonal (p < q):
    gamma_pq = 1/4 * [<X_p Z... X_q> + <Y_p Z... Y_q>
                      + i(<X_p Z... Y_q> - <Y_p Z... X_q>)]

Performance optimization (Phase 7): - Batched measurement: single QNode returns all observables (120x → 1x execution) - GPU acceleration via device_utils - Catalyst @qjit support

class q2m3.core.rdm.RDMEstimator(n_qubits, n_electrons, config=None)[source]

Bases: object

1-RDM measurement from quantum states using Pauli expectation values.

Measures the one-particle reduced density matrix (1-RDM) from a quantum state prepared by Trotter time evolution. Uses Jordan-Wigner transformation to convert fermionic operators to Pauli observables.

Performance optimization: Uses batched measurement (single QNode) instead of individual QNodes per observable for 10-50x speedup.

Parameters:
  • n_qubits (int)

  • n_electrons (int)

  • config (dict[str, Any] | None)

__init__(n_qubits, n_electrons, config=None)[source]

Initialize RDM estimator.

Parameters:
  • n_qubits (int) – Number of spin orbitals (qubits in Jordan-Wigner)

  • n_electrons (int) – Number of electrons in the system

  • config (dict[str, Any] | None) – Optional configuration dictionary with keys: - n_shots: Number of measurement shots (default: 1000) - include_off_diagonal: Measure off-diagonal elements (default: True) - symmetrize: Enforce Hermitian symmetry (default: True) - output_basis: “spin” or “spatial” (default: “spin”)

measure_1rdm(hamiltonian, hf_state, base_time, n_trotter_steps, device_type='default.qubit', use_catalyst=False)[source]

Measure 1-RDM from Trotter-evolved state using batched measurement.

Prepares |HF> , applies TrotterProduct time evolution, then measures all 1-RDM elements as Pauli expectation values in a single QNode.

Parameters:
  • hamiltonian (LinearCombination) – PennyLane molecular Hamiltonian

  • hf_state (ndarray) – Hartree-Fock reference state binary array

  • base_time (float) – Evolution time for Trotter

  • n_trotter_steps (int) – Number of Trotter steps

  • device_type (str) – Device selection strategy: - “auto”: Auto-select best (GPU > lightning.qubit > default.qubit) - “default.qubit”: Standard PennyLane simulator - “lightning.qubit”: High-performance CPU simulator - “lightning.gpu”: GPU-accelerated simulator

  • use_catalyst (bool) – Enable Catalyst @qjit compilation

Returns:

1-RDM as numpy array of shape (n_qubits, n_qubits)

Return type:

ndarray

build_rdm_observables()[source]

Build Pauli observables for all 1-RDM elements (legacy interface).

Returns:

Dictionary mapping (p, q) indices to PennyLane observables. For p == q: number operator observable For p < q: tuple of 4 Pauli observables for real/imag parts

Return type:

dict[tuple[int, int], Any]

enforce_physical_constraints(rdm_raw)[source]

Enforce physical constraints on 1-RDM.

Constraints: 1. Hermiticity: γ_pq = γ_qp* 2. Positive semi-definiteness: all eigenvalues >= 0 3. Trace normalization: Tr(γ) = N_electrons

Parameters:

rdm_raw (ndarray) – Raw 1-RDM from measurement

Returns:

Physically valid 1-RDM

Return type:

ndarray

draw_rdm_circuit(hamiltonian, hf_state, base_time, n_trotter_steps, max_observables=4, use_pennylane_draw=True)[source]

Generate text visualization of RDM measurement circuit.

Uses qml.draw() with decimals=None and level=0 for clean output, showing circuit structure without parameter clutter.

Parameters:
  • hamiltonian (LinearCombination) – PennyLane molecular Hamiltonian

  • hf_state (ndarray) – HF reference state binary array

  • base_time (float) – Evolution time for Trotter

  • n_trotter_steps (int) – Number of Trotter steps

  • max_observables (int) – Max observables to show (default: 4)

  • use_pennylane_draw (bool) – Use qml.draw() for visualization (default: True)

Returns:

String representation of the circuit

Return type:

str

spin_to_spatial_rdm(spin_rdm)[source]

Convert spin-orbital 1-RDM to spatial-orbital 1-RDM.

For restricted systems, spatial RDM = sum of alpha and beta spin blocks.

Parameters:

spin_rdm (ndarray) – 1-RDM in spin-orbital basis, shape (2*n_spatial, 2*n_spatial)

Returns:

1-RDM in spatial-orbital basis, shape (n_spatial, n_spatial)

Return type:

ndarray

active_mo_to_ao_rdm(active_spatial_rdm, mo_coeff, mo_occ, active_electrons, active_orbitals)[source]

Convert active space spatial-orbital 1-RDM to AO basis.

Steps: 1. Embed active space RDM into full MO RDM 2. Transform from MO to AO basis: P_AO = C @ P_MO @ C^T

Parameters:
  • active_spatial_rdm (ndarray) – 1-RDM in active MO basis, shape (active_orbitals, active_orbitals)

  • mo_coeff (ndarray) – MO coefficient matrix from HF, shape (n_ao, n_mo)

  • mo_occ (ndarray) – MO occupation numbers from HF, shape (n_mo,)

  • active_electrons (int) – Number of active electrons

  • active_orbitals (int) – Number of active orbitals

Returns:

1-RDM in AO basis, shape (n_ao, n_ao)

Return type:

ndarray

q2m3.core.rdm.measure_rdm_from_qpe_state(hamiltonian, hf_state, n_electrons, base_time, n_trotter_steps, config=None, device_type='default.qubit', use_catalyst=False)[source]

Convenience function to measure 1-RDM from QPE-like state.

Parameters:
  • hamiltonian (LinearCombination) – PennyLane molecular Hamiltonian

  • hf_state (ndarray) – Hartree-Fock reference state

  • n_electrons (int) – Number of electrons

  • base_time (float) – Evolution time

  • n_trotter_steps (int) – Trotter steps

  • config (dict[str, Any] | None) – Optional RDM configuration

  • device_type (str) – PennyLane device selection

  • use_catalyst (bool) – Enable Catalyst @qjit compilation

Returns:

1-RDM numpy array

Return type:

ndarray

Resource Estimation

EFTQC resource estimation module.

Provides structured dataclass results for Early Fault-Tolerant Quantum Computer (EFTQC) resource estimation, wrapping PySCFPennyLaneConverter.estimate_qpe_resources().

class q2m3.core.resource_estimation.EmbeddingDiagnostics(active_indices, delta_h_diag_fro, delta_h_offdiag_fro, delta_h_offdiag_to_diag, delta_h_hermitian_max_abs, delta_h_trace_ha, delta_nuclear_mm_ha, delta_core_constant_ha, fixed_mo, two_electron_tensor_fixed)[source]

Bases: object

Scalar diagnostics for an MM one-electron embedding resource row.

Parameters:
  • active_indices (tuple[int, ...])

  • delta_h_diag_fro (float)

  • delta_h_offdiag_fro (float)

  • delta_h_offdiag_to_diag (float | None)

  • delta_h_hermitian_max_abs (float)

  • delta_h_trace_ha (float)

  • delta_nuclear_mm_ha (float)

  • delta_core_constant_ha (float)

  • fixed_mo (bool)

  • two_electron_tensor_fixed (bool)

active_indices

Vacuum molecular-orbital indices used for the active block.

Type:

tuple[int, …]

delta_h_diag_fro

Frobenius norm of the diagonal active-space perturbation.

Type:

float

delta_h_offdiag_fro

Frobenius norm of the off-diagonal perturbation.

Type:

float

delta_h_offdiag_to_diag

Ratio of off-diagonal to diagonal norms.

Type:

float | None

delta_h_hermitian_max_abs

Maximum anti-Hermitian residual.

Type:

float

delta_h_trace_ha

Trace of the active-space perturbation in Hartree.

Type:

float

delta_nuclear_mm_ha

MM-induced nuclear constant difference in Hartree.

Type:

float

delta_core_constant_ha

Frozen-core one-electron plus nuclear MM constant.

Type:

float

fixed_mo

Whether the perturbation is represented in the vacuum MO frame.

Type:

bool

two_electron_tensor_fixed

Whether the two-electron tensor is held at vacuum values.

Type:

bool

class q2m3.core.resource_estimation.EFTQCResources(hamiltonian_1norm, logical_qubits, toffoli_gates, n_terms, target_error, n_system_qubits, basis, n_mm_charges, embedding_mode='none', embedding_diagnostics=None)[source]

Bases: object

Resource estimation result for a single EFTQC configuration.

Parameters:
  • hamiltonian_1norm (float)

  • logical_qubits (int)

  • toffoli_gates (int)

  • n_terms (int | None)

  • target_error (float)

  • n_system_qubits (int)

  • basis (str)

  • n_mm_charges (int)

  • embedding_mode (str)

  • embedding_diagnostics (EmbeddingDiagnostics | None)

hamiltonian_1norm

Lambda (1-norm) of the Hamiltonian in Hartree.

Type:

float

logical_qubits

Number of logical qubits required.

Type:

int

toffoli_gates

Non-Clifford (Toffoli) gate count.

Type:

int

n_terms

Number of Hamiltonian terms. None when DoubleFactorization resource estimation is used (it does not construct the full PennyLane Hamiltonian object).

Type:

int | None

target_error

Target energy error in Hartree.

Type:

float

n_system_qubits

System register size = n_orbitals * 2 (Jordan-Wigner).

Type:

int

basis

Basis set used (e.g. “sto-3g”).

Type:

str

n_mm_charges

Number of MM point charges; 0 for vacuum.

Type:

int

embedding_mode

Effective embedding state (“none”, “diagonal”, or “full_oneelectron”).

Type:

str

embedding_diagnostics

Optional scalar diagnostics for fixed-MO one-electron embedding.

Type:

q2m3.core.resource_estimation.EmbeddingDiagnostics | None

class q2m3.core.resource_estimation.ResourceComparisonResult(vacuum, solvated, delta_lambda_percent, delta_gates_percent)[source]

Bases: object

Comparison of EFTQC resources between vacuum and solvated systems.

Parameters:
vacuum

Resource estimate with no MM embedding.

Type:

q2m3.core.resource_estimation.EFTQCResources

solvated

Resource estimate with MM point charge embedding.

Type:

q2m3.core.resource_estimation.EFTQCResources

delta_lambda_percent

Percentage change in Hamiltonian 1-norm due to solvation: (solvated - vacuum) / vacuum * 100.

Type:

float

delta_gates_percent

Percentage change in Toffoli gate count due to solvation: (solvated - vacuum) / vacuum * 100.

Type:

float

q2m3.core.resource_estimation.estimate_resources(symbols, coords, charge=0, basis='sto-3g', active_electrons=None, active_orbitals=None, target_error=0.0016, mm_charges=None, mm_coords=None, embedding_mode='full_oneelectron')[source]

Estimate EFTQC resource requirements for a molecular system.

Wraps PySCFPennyLaneConverter.estimate_qpe_resources() and returns a structured, immutable EFTQCResources dataclass instead of a raw dict.

Parameters:
  • symbols (list[str]) – List of atomic symbols (e.g. [‘H’, ‘H’]).

  • coords (ndarray) – Atomic coordinates in Angstrom, shape (n_atoms, 3).

  • charge (int) – Total molecular charge (default: 0).

  • basis (str) – Basis set name (default: “sto-3g”).

  • active_electrons (int | None) – Active space electrons (optional).

  • active_orbitals (int | None) – Active space orbitals (optional).

  • target_error (float) – Target energy error in Hartree (default: 0.0016 = 1 kcal/mol).

  • mm_charges (ndarray | None) – MM point charges array (optional, enables solvated Hamiltonian).

  • mm_coords (ndarray | None) – MM charge coordinates in Angstrom, shape (n_mm, 3).

  • embedding_mode (str) – MM embedding mode for resource rows. Defaults to the historical full fixed-MO one-electron resource behavior.

Returns:

EFTQCResources dataclass with all resource fields populated.

Return type:

EFTQCResources

q2m3.core.resource_estimation.compare_vacuum_solvated(symbols, coords, charge=0, basis='sto-3g', active_electrons=None, active_orbitals=None, mm_charges=None, mm_coords=None, target_error=0.0016, embedding_mode='full_oneelectron')[source]

Compare EFTQC resource requirements between vacuum and solvated systems.

Calls estimate_resources() twice: once without MM charges (vacuum) and once with MM charges (solvated), then computes the percentage deltas.

Parameters:
  • symbols (list[str]) – List of atomic symbols.

  • coords (ndarray) – Atomic coordinates in Angstrom, shape (n_atoms, 3).

  • charge (int) – Total molecular charge (default: 0).

  • basis (str) – Basis set name (default: “sto-3g”).

  • active_electrons (int | None) – Active space electrons (optional).

  • active_orbitals (int | None) – Active space orbitals (optional).

  • mm_charges (ndarray | None) – MM point charges for the solvated estimate.

  • mm_coords (ndarray | None) – MM charge coordinates in Angstrom for the solvated estimate.

  • target_error (float) – Target energy error in Hartree (default: 0.0016).

  • embedding_mode (str) – MM embedding mode for the solvated resource row.

Returns:

ResourceComparisonResult with both estimates and derived deltas.

Return type:

ResourceComparisonResult

q2m3.core.resource_estimation.derive_t_resources(toffoli_gates)[source]

Derive T-count and conservative T-depth from Toffoli count.

DoubleFactorization returns Toffoli count and logical qubits but not the T-depth that surface-code-style analyses require. Use the standard fault-tolerant relation T-count = 7 * Toffoli-count and a conservative sequential upper bound for depth.

Parameters:

toffoli_gates (int) – Total Toffoli gate count from DoubleFactorization.

Returns:

  • t_count: 7 * toffoli_gates

  • toffoli_depth: conservative sequential upper bound (= toffoli_gates)

  • t_depth: T_PER_TOFFOLI * toffoli_depth (sequential upper bound)

Return type:

Dict with

q2m3.core.resource_estimation.estimate_eftqc_runtime(qpe_iterations, toffoli_gates, toffoli_cycle_microseconds=1.0)[source]

Estimate wall-clock runtime for an EFTQC QPE execution.

Assumes a fixed Toffoli cycle time and that QPE serially repeats the same fault-tolerant block qpe_iterations times. This is a coarse upper bound: real EFTQC implementations may amortize cost across iterations.

Parameters:
  • qpe_iterations (int) – Number of QPE iterations (= ceil(lambda / target_error)).

  • toffoli_gates (int) – Toffoli count per QPE iteration.

  • toffoli_cycle_microseconds (float) – Wall-clock time per Toffoli (default 1 us, commonly cited for fault-tolerant superconducting estimates).

Returns:

Dict with runtime in seconds, hours, and days.

Return type:

dict[str, float]

Device Utilities

Quantum device selection and management utilities.

Provides unified device selection logic for QPE and RDM modules, with GPU acceleration support and Catalyst compatibility.

IMPORTANT: There are TWO separate GPU support systems in q2m3:

  1. PennyLane Lightning GPU (cuQuantum/CUDA): - Used by standard QPE circuits (without @qjit) - Detected by HAS_LIGHTNING_GPU flag - Requires: pennylane-lightning[gpu], cuQuantum, CUDA

  2. JAX/Catalyst GPU (jaxlib[cuda]): - Used by Catalyst @qjit compiled circuits - Detected by HAS_JAX_CUDA flag - Requires: jax[cuda11_pip] or jax[cuda12_pip]

When Catalyst @qjit is enabled, even with lightning.gpu device, the actual execution backend is determined by JAX, NOT PennyLane. If JAX lacks CUDA support, Catalyst runs on CPU regardless of device name.

q2m3.core.device_utils.get_best_available_device()[source]

Return the name of the best available device.

Priority: lightning.gpu > lightning.qubit > default.qubit

Returns:

Device name string

Return type:

str

q2m3.core.device_utils.get_catalyst_backend_info()[source]

Get detailed information about Catalyst execution backend.

IMPORTANT: Catalyst @qjit uses JAX as its execution backend, which is SEPARATE from PennyLane device selection. Even if device=”lightning.gpu”, Catalyst will run on CPU if JAX lacks CUDA support.

Returns:

  • jax_backend: JAX default backend (“cpu”, “cuda”, “gpu”)

  • has_jax_cuda: Whether JAX has CUDA support

  • effective_device: Actual execution device for Catalyst

  • warning: Optional warning message if GPU expected but unavailable

Return type:

Dictionary with

q2m3.core.device_utils.get_effective_catalyst_device_label()[source]

Get the effective device label for Catalyst execution.

Unlike get_best_available_device() which returns the PennyLane device name, this returns what Catalyst actually runs on (CPU/GPU based on JAX backend).

Returns:

CPU)” or “lightning.gpu (JAX: GPU)”

Return type:

Human-readable label like “lightning.gpu (JAX

q2m3.core.device_utils.get_catalyst_effective_backend()[source]

Get human-readable Catalyst execution backend label.

Returns:

String like “GPU (JAX CUDA)” or “CPU (JAX)”

Return type:

str

q2m3.core.device_utils.select_device(device_type, n_wires, use_catalyst=False, seed=None)[source]

Select quantum device based on device_type parameter.

NOTE: As of PennyLane v0.43, setting shots on device is deprecated. Use qml.set_shots() transform on QNode instead.

Parameters:
  • device_type (str) – Device selection strategy: - “auto”: Auto-select best available (GPU > lightning.qubit > default.qubit) - “default.qubit”: Standard PennyLane simulator - “lightning.qubit”: High-performance CPU simulator - “lightning.gpu”: GPU-accelerated simulator (requires cuQuantum)

  • n_wires (int) – Number of qubits

  • use_catalyst (bool) – If True, ensure Catalyst-compatible fallback (lightning.qubit instead of default.qubit)

  • seed (int | None) – Optional device seed for reproducible shot-based sampling

Returns:

PennyLane device instance

Hamiltonian Utilities

PennyLane Hamiltonian operator utilities.

Provides helper functions for decomposing PennyLane Sum/Hamiltonian objects (PennyLane 0.44+ compatible) and building operator index maps for efficient coefficient updates in QM/MM simulations.

q2m3.core.hamiltonian_utils.decompose_hamiltonian(H)[source]

Extract (coeffs, ops) from PennyLane Sum/Hamiltonian.

PennyLane 0.44+ returns Sum of SProd from qml.qchem.molecular_hamiltonian. We need separate coefficients and operators for qml.dot(coeffs, ops).

Parameters:

H – PennyLane Hamiltonian (Sum of SProd operators)

Returns:

Tuple of (coefficients, operators) where coefficients are floats and operators are PennyLane operator instances.

Return type:

tuple[list[float], list]

q2m3.core.hamiltonian_utils.build_operator_index_map(ops, n_system_qubits, coeffs)[source]

Scan ops to find Identity and single-Z(wire) indices for MM coefficient updates.

If any Z(wire) for wire in range(n_system_qubits) is missing, appends a coeff=0.0 placeholder to ensure all spin orbitals can receive MM corrections.

Parameters:
  • ops (list) – List of PennyLane operators (from decompose_hamiltonian)

  • n_system_qubits (int) – Number of system qubits (= 2 * active_orbitals)

  • coeffs (list[float]) – Corresponding coefficient list (may be extended)

Returns:

  • index_map: {“identity_idx”: int, “z_wire_idx”: {wire: idx, …}}

  • extended_coeffs: coefficients with any missing Z terms appended

  • extended_ops: operators with any missing Z terms appended

Return type:

Tuple of (index_map, extended_coeffs, extended_ops) where

Solver Extension Point

Quantum Solver Interface for Ground State Energy Estimation.

Abstract base class for quantum solvers used in QM/MM simulations. Concrete implementations (QPE, VQE, etc.) are in separate modules.

This is a self-contained module — not exported from core/__init__.py. Future VQE/QAOA solvers can import directly:

from q2m3.core.quantum_solver import QuantumSolver, SolverResult
class q2m3.core.quantum_solver.SolverResult(energy, phase, raw_measurements, metadata=<factory>)[source]

Bases: object

Universal result container for quantum solvers.

Parameters:
  • energy (float)

  • phase (float)

  • raw_measurements (Any)

  • metadata (dict)

energy

Estimated ground state energy in Hartree.

Type:

float

phase

Estimated phase value from QPE.

Type:

float

raw_measurements

Algorithm-specific measurement data.

Type:

Any

metadata

Additional algorithm-specific information.

Type:

dict

class q2m3.core.quantum_solver.QuantumSolver[source]

Bases: ABC

Abstract base class for quantum ground state solvers.

Implementations should provide: - solve(): Execute the algorithm and return energy estimate - compile(): Pre-compile circuit for repeated execution

abstractmethod solve(hamiltonian_data)[source]

Estimate ground state energy of the Hamiltonian.

Parameters:

hamiltonian_data (dict) – Dict containing Hamiltonian operator, HF state, qubit count, and reference energy.

Returns:

SolverResult with energy and measurement data.

Return type:

SolverResult

abstractmethod compile(**kwargs)[source]

Pre-compile circuit for repeated execution.

Some solvers (like QPE) support circuit pre-compilation for reuse across MC steps with the same Hamiltonian.

Parameters:

kwargs (Any)

Return type:

None