Quantum Programs (qprog)

The divi.qprog module contains the core quantum programming abstractions for building and executing quantum algorithms.

Overview

The quantum programming module provides a high-level interface for quantum algorithm development, supporting both single-instance problems and large-scale hyperparameter sweeps. At its core is the QuantumProgram abstract base class that defines the common interface for all quantum algorithms.

Core Architecture

Core Classes

class QuantumProgram(backend, seed=None, progress_queue=None, **kwargs)[source]

Bases: ABC

Abstract base class for quantum programs.

This class defines the interface and provides common functionality for quantum algorithms. It handles circuit execution, result processing, and data persistence.

Subclasses must implement:
  • run(): Execute the quantum algorithm

  • _generate_circuits(): Generate quantum circuits for execution

  • _post_process_results(): Process execution results

backend

The quantum circuit execution backend.

Type:

CircuitRunner

_seed

Random seed for reproducible results.

Type:

int | None

_progress_queue

Queue for progress reporting.

Type:

Queue | None

_circuits

List of circuits to be executed.

Type:

list

Initialize the QuantumProgram.

Parameters:
  • backend (CircuitRunner) – Quantum circuit execution backend.

  • seed (int | None) – Random seed for reproducible results. Defaults to None.

  • progress_queue (Queue | None) – Queue for progress reporting. Defaults to None.

  • **kwargs – Additional keyword arguments for subclasses. program_id (str | None): Program identifier for progress reporting in batch operations. If provided along with progress_queue, enables queue-based progress reporting.

abstract run(**kwargs)[source]

Execute the quantum algorithm.

Parameters:

**kwargs – Additional keyword arguments for subclasses.

Returns:

A tuple containing:
  • int: Total number of circuits executed

  • float: Total runtime in seconds

Return type:

tuple[int, float]

property total_circuit_count: int

Get the total number of circuits executed.

Returns:

Cumulative count of circuits submitted for execution.

Return type:

int

property total_run_time: float

Get the total runtime across all circuit executions.

Returns:

Cumulative execution time in seconds.

Return type:

float

cancel_unfinished_job()[source]

Cancel the currently running cloud job if one exists.

This method attempts to cancel the job associated with the current ExecutionResult. It is best-effort and will log warnings for any errors (e.g., job already completed, permission denied) without raising exceptions.

This is typically called by ProgramBatch when handling cancellation to ensure cloud jobs are cancelled before local threads terminate.

class VariationalQuantumAlgorithm(backend, optimizer=None, seed=None, progress_queue=None, **kwargs)[source]

Bases: QuantumProgram

Base class for variational quantum algorithms.

This class provides the foundation for implementing variational quantum algorithms in Divi. It handles circuit execution, parameter optimization, and result management for algorithms that optimize parameterized quantum circuits to minimize cost functions.

Variational algorithms work by: 1. Generating parameterized quantum circuits 2. Executing circuits on quantum hardware/simulators 3. Computing expectation values of cost Hamiltonians 4. Using classical optimizers to update parameters 5. Iterating until convergence

_losses_history

History of loss values during optimization.

Type:

list[dict]

_final_params

Final optimized parameters.

Type:

npt.NDArray[np.float64]

_best_params

Parameters that achieved the best loss.

Type:

npt.NDArray[np.float64]

_best_loss

Best loss achieved during optimization.

Type:

float

_circuits

Generated quantum circuits.

Type:

list[Circuit]

_total_circuit_count

Total number of circuits executed.

Type:

int

_total_run_time

Total execution time in seconds.

Type:

float

_curr_params

Current parameter values.

Type:

npt.NDArray[np.float64]

_seed

Random seed for parameter initialization.

Type:

int | None

_rng

Random number generator.

Type:

np.random.Generator

_grad_mode

Whether currently computing gradients.

Type:

bool

_grouping_strategy

Strategy for grouping quantum operations.

Type:

str

_qem_protocol

Quantum error mitigation protocol.

Type:

QEMProtocol

_cancellation_event

Event for graceful termination.

Type:

Event | None

_meta_circuit_factory

Factory for creating MetaCircuit instances.

Type:

callable

Initialize the VariationalQuantumAlgorithm.

This constructor is specifically designed for hybrid quantum-classical variational algorithms. The instance variables n_layers and n_params must be set by subclasses, where: - n_layers is the number of layers in the quantum circuit. - n_params is the number of parameters per layer.

For exotic variational algorithms where these variables may not be applicable, the _initialize_params method should be overridden to set the parameters.

Parameters:
  • backend (CircuitRunner) – Quantum circuit execution backend.

  • optimizer (Optimizer | None) – The optimizer to use for parameter optimization. Defaults to MonteCarloOptimizer().

  • seed (int | None) – Random seed for parameter initialization. Defaults to None.

  • progress_queue (Queue | None) – Queue for progress reporting. Defaults to None.

Keyword Arguments:
  • initial_params (npt.NDArray[np.float64] | None) – Initial parameters with shape (n_param_sets, n_layers * n_params). If provided, these will be set as the current parameters via the curr_params setter (which includes validation). Defaults to None.

  • grouping_strategy (str) – Strategy for grouping operations in Pennylane transforms. Options: “default”, “wires”, “qwc”. Defaults to “qwc”.

  • qem_protocol (QEMProtocol | None) – Quantum error mitigation protocol to apply. Defaults to None.

  • precision (int) –

    Number of decimal places for parameter values in QASM conversion. Defaults to 8.

    Note: Higher precision values result in longer QASM strings, which increases the amount of data sent to cloud backends. For most use cases, the default precision of 8 decimal places provides sufficient accuracy while keeping QASM sizes manageable. Consider reducing precision if you need to minimize data transfer overhead, or increase it only if you require higher numerical precision in your circuit parameters.

__init__(backend, optimizer=None, seed=None, progress_queue=None, **kwargs)[source]

Initialize the VariationalQuantumAlgorithm.

This constructor is specifically designed for hybrid quantum-classical variational algorithms. The instance variables n_layers and n_params must be set by subclasses, where: - n_layers is the number of layers in the quantum circuit. - n_params is the number of parameters per layer.

For exotic variational algorithms where these variables may not be applicable, the _initialize_params method should be overridden to set the parameters.

Parameters:
  • backend (CircuitRunner) – Quantum circuit execution backend.

  • optimizer (Optimizer | None) – The optimizer to use for parameter optimization. Defaults to MonteCarloOptimizer().

  • seed (int | None) – Random seed for parameter initialization. Defaults to None.

  • progress_queue (Queue | None) – Queue for progress reporting. Defaults to None.

Keyword Arguments:
  • initial_params (npt.NDArray[np.float64] | None) – Initial parameters with shape (n_param_sets, n_layers * n_params). If provided, these will be set as the current parameters via the curr_params setter (which includes validation). Defaults to None.

  • grouping_strategy (str) – Strategy for grouping operations in Pennylane transforms. Options: “default”, “wires”, “qwc”. Defaults to “qwc”.

  • qem_protocol (QEMProtocol | None) – Quantum error mitigation protocol to apply. Defaults to None.

  • precision (int) –

    Number of decimal places for parameter values in QASM conversion. Defaults to 8.

    Note: Higher precision values result in longer QASM strings, which increases the amount of data sent to cloud backends. For most use cases, the default precision of 8 decimal places provides sufficient accuracy while keeping QASM sizes manageable. Consider reducing precision if you need to minimize data transfer overhead, or increase it only if you require higher numerical precision in your circuit parameters.

abstract property cost_hamiltonian: Operator

The cost Hamiltonian for the variational problem.

property total_circuit_count: int

Get the total number of circuits executed.

Returns:

Cumulative count of circuits submitted for execution.

Return type:

int

property total_run_time: float

Get the total runtime across all circuit executions.

Returns:

Cumulative execution time in seconds.

Return type:

float

property n_params

Get the total number of parameters in the quantum circuit.

Returns:

Total number of trainable parameters (n_layers * n_params_per_layer).

Return type:

int

property losses_history: list[dict]

Get a copy of the optimization loss history.

Each entry is a dictionary mapping parameter indices to loss values.

Returns:

Copy of the loss history. Modifications to this list

will not affect the internal state.

Return type:

list[dict]

property min_losses_per_iteration: list[float]

Get the minimum loss value for each iteration.

Returns a list where each element is the minimum (best) loss value across all parameter sets for that iteration.

Returns:

List of minimum loss values, one per iteration.

Return type:

list[float]

property final_params: ndarray[Any, dtype[float64]]

Get a copy of the final optimized parameters.

Returns:

Copy of the final parameters. Modifications to this array

will not affect the internal state.

Return type:

npt.NDArray[np.float64]

property best_params: ndarray[Any, dtype[float64]]

Get a copy of the parameters that achieved the best (lowest) loss.

Returns:

Copy of the best parameters. Modifications to this array

will not affect the internal state.

Return type:

npt.NDArray[np.float64]

property best_loss: float

Get the best loss achieved so far.

Returns:

The best loss achieved so far.

Return type:

float

property best_probs

Get a copy of the probability distribution for the best parameters.

Returns:

A copy of the best probability distribution.

Return type:

dict

property curr_params: ndarray[Any, dtype[float64]]

Get the current parameters.

These are the parameters used for optimization. They can be accessed and modified at any time, including during optimization.

Returns:

Current parameters. If not yet initialized,

they will be generated automatically.

Return type:

npt.NDArray[np.float64]

property meta_circuits: dict[str, MetaCircuit]

Get the meta-circuit templates used by this program.

Returns:

Dictionary mapping circuit names to their

MetaCircuit templates.

Return type:

dict[str, MetaCircuit]

save_state(checkpoint_config)[source]

Save the program state to a checkpoint directory.

Return type:

str

classmethod load_state(checkpoint_dir, backend, subdirectory=None, **kwargs)[source]

Load program state from a checkpoint directory.

Return type:

VariationalQuantumAlgorithm

get_expected_param_shape()[source]

Get the expected shape for initial parameters.

Returns:

Shape (n_param_sets, n_layers * n_params) that

initial parameters should have for this quantum program.

Return type:

tuple[int, int]

run(perform_final_computation=True, checkpoint_config=None, **kwargs)[source]

Run the variational quantum algorithm.

The outputs are stored in the algorithm object.

Parameters:
  • perform_final_computation (bool) – Whether to perform final computation after optimization completes. Typically, this step involves sampling with the best found parameters to extract solution probability distributions. Set this to False in warm-starting or pre-training routines where the final sampling step is not needed. Defaults to True.

  • checkpoint_config (CheckpointConfig | None) – Checkpoint configuration. If None, no checkpointing is performed.

  • **kwargs – Additional keyword arguments for subclasses.

Returns:

A tuple containing (total_circuit_count, total_run_time).

Return type:

tuple[int, float]

Algorithms

Divi provides implementations of popular quantum algorithms with a focus on scalability and ease of use.

VQE Algorithm

class VQE(hamiltonian=None, molecule=None, n_electrons=None, n_layers=1, ansatz=None, max_iterations=10, **kwargs)[source]

Bases: VariationalQuantumAlgorithm

Variational Quantum Eigensolver (VQE) implementation.

VQE is a hybrid quantum-classical algorithm used to find the ground state energy of a given Hamiltonian. It works by preparing a parameterized quantum state (ansatz) and optimizing the parameters to minimize the expectation value of the Hamiltonian.

The algorithm can work with either: - A molecular Hamiltonian (for quantum chemistry problems) - A custom Hamiltonian operator

ansatz

The parameterized quantum circuit ansatz.

Type:

Ansatz

n_layers

Number of ansatz layers.

Type:

int

n_qubits

Number of qubits in the system.

Type:

int

n_electrons

Number of electrons (for molecular systems).

Type:

int

cost_hamiltonian

The Hamiltonian to minimize.

Type:

qml.operation.Operator

loss_constant

Constant term extracted from the Hamiltonian.

Type:

float

molecule

The molecule object (if applicable).

Type:

qml.qchem.Molecule

optimizer

Classical optimizer for parameter updates.

Type:

Optimizer

max_iterations

Maximum number of optimization iterations.

Type:

int

current_iteration

Current optimization iteration.

Type:

int

Initialize the VQE problem.

Parameters:
  • hamiltonian (qml.operation.Operator | None) – A Hamiltonian representing the problem. Defaults to None.

  • molecule (qml.qchem.Molecule | None) – The molecule representing the problem. Defaults to None.

  • n_electrons (int | None) – Number of electrons associated with the Hamiltonian. Only needed when a Hamiltonian is given. Defaults to None.

  • n_layers (int) – Number of ansatz layers. Defaults to 1.

  • ansatz (Ansatz | None) – The ansatz to use for the VQE problem. Defaults to HartreeFockAnsatz.

  • max_iterations (int) – Maximum number of optimization iterations. Defaults to 10.

  • **kwargs – Additional keyword arguments passed to the parent class.

__init__(hamiltonian=None, molecule=None, n_electrons=None, n_layers=1, ansatz=None, max_iterations=10, **kwargs)[source]

Initialize the VQE problem.

Parameters:
  • hamiltonian (qml.operation.Operator | None) – A Hamiltonian representing the problem. Defaults to None.

  • molecule (qml.qchem.Molecule | None) – The molecule representing the problem. Defaults to None.

  • n_electrons (int | None) – Number of electrons associated with the Hamiltonian. Only needed when a Hamiltonian is given. Defaults to None.

  • n_layers (int) – Number of ansatz layers. Defaults to 1.

  • ansatz (Ansatz | None) – The ansatz to use for the VQE problem. Defaults to HartreeFockAnsatz.

  • max_iterations (int) – Maximum number of optimization iterations. Defaults to 10.

  • **kwargs – Additional keyword arguments passed to the parent class.

property n_params

Get the total number of parameters for the VQE ansatz.

Returns:

Total number of parameters (n_params_per_layer * n_layers).

Return type:

int

property eigenstate: ndarray[Any, dtype[int32]] | None

Get the computed eigenstate as a NumPy array.

Returns:

The array of bits of the lowest energy eigenstate,

or None if not computed.

Return type:

npt.NDArray[np.int32] | None

VQE.cost_hamiltonian

The cost Hamiltonian for the VQE problem.

QAOA Algorithm

class QAOA(problem, *, graph_problem=None, n_layers=1, initial_state='Recommended', max_iterations=10, **kwargs)[source]

Bases: VariationalQuantumAlgorithm

Quantum Approximate Optimization Algorithm (QAOA) implementation.

QAOA is a hybrid quantum-classical algorithm designed to solve combinatorial optimization problems. It alternates between applying a cost Hamiltonian (encoding the problem) and a mixer Hamiltonian (enabling exploration).

The algorithm can solve: - Graph problems (MaxCut, Max Clique, etc.) - QUBO (Quadratic Unconstrained Binary Optimization) problems - BinaryQuadraticModel from dimod

problem

The problem instance to solve.

Type:

GraphProblemTypes | QUBOProblemTypes

graph_problem

The graph problem type (if applicable).

Type:

GraphProblem | None

n_layers

Number of QAOA layers.

Type:

int

n_qubits

Number of qubits required.

Type:

int

cost_hamiltonian

The cost Hamiltonian encoding the problem.

Type:

qml.Hamiltonian

mixer_hamiltonian

The mixer Hamiltonian for exploration.

Type:

qml.Hamiltonian

initial_state

The initial quantum state.

Type:

str

problem_metadata

Additional metadata from problem setup.

Type:

dict | None

loss_constant

Constant term from the problem.

Type:

float

optimizer

Classical optimizer for parameter updates.

Type:

Optimizer

max_iterations

Maximum number of optimization iterations.

Type:

int

current_iteration

Current optimization iteration.

Type:

int

_n_params

Number of parameters per layer (always 2 for QAOA).

Type:

int

_solution_nodes

Solution nodes for graph problems.

Type:

list[int] | None

_solution_bitstring

Solution bitstring for QUBO problems.

Type:

npt.NDArray[np.int32] | None

Initialize the QAOA problem.

Parameters:
  • problem (GraphProblemTypes | QUBOProblemTypes) – The problem to solve, can either be a graph or a QUBO. For graph inputs, the graph problem to solve must be provided through the graph_problem variable.

  • graph_problem (GraphProblem | None) – The graph problem to solve. Defaults to None.

  • n_layers (int) – Number of QAOA layers. Defaults to 1.

  • initial_state (_SUPPORTED_INITIAL_STATES_LITERAL) – The initial state of the circuit. Defaults to “Recommended”.

  • max_iterations (int) – Maximum number of optimization iterations. Defaults to 10.

  • **kwargs – Additional keyword arguments passed to the parent class, including optimizer.

__init__(problem, *, graph_problem=None, n_layers=1, initial_state='Recommended', max_iterations=10, **kwargs)[source]

Initialize the QAOA problem.

Parameters:
  • problem (GraphProblemTypes | QUBOProblemTypes) – The problem to solve, can either be a graph or a QUBO. For graph inputs, the graph problem to solve must be provided through the graph_problem variable.

  • graph_problem (GraphProblem | None) – The graph problem to solve. Defaults to None.

  • n_layers (int) – Number of QAOA layers. Defaults to 1.

  • initial_state (_SUPPORTED_INITIAL_STATES_LITERAL) – The initial state of the circuit. Defaults to “Recommended”.

  • max_iterations (int) – Maximum number of optimization iterations. Defaults to 10.

  • **kwargs – Additional keyword arguments passed to the parent class, including optimizer.

property solution

Get the solution found by QAOA optimization.

Returns:

For graph problems, returns a list of selected node indices.

For QUBO problems, returns a list/array of binary values.

Return type:

list[int] | npt.NDArray[np.int32]

draw_solution()[source]

Visualize the solution found by QAOA for graph problems.

Draws the graph with solution nodes highlighted in red and other nodes in light blue. If the solution hasn’t been computed yet, it will be calculated first.

Raises:

RuntimeError – If called on a QUBO problem instead of a graph problem.

Note

This method only works for graph problems. For QUBO problems, access the solution directly via the solution property.

QAOA.cost_hamiltonian

The cost Hamiltonian for the QAOA problem.

QAOA.mixer_hamiltonian

The mixer Hamiltonian for the QAOA problem.

Graph Problem Types

class GraphProblem(pl_string, constrained_initial_state, unconstrained_initial_state)[source]

Enumeration of supported graph problems for QAOA.

Each problem type defines: - pl_string: The corresponding PennyLane function name - constrained_initial_state: Recommended initial state for constrained problems - unconstrained_initial_state: Recommended initial state for unconstrained problems

Initialize the GraphProblem enum value.

Parameters:
  • pl_string (str) – The corresponding PennyLane function name.

  • constrained_initial_state (str) – Recommended initial state for constrained problems.

  • unconstrained_initial_state (str) – Recommended initial state for unconstrained problems.

MAX_CLIQUE = ('max_clique', 'Zeros', 'Superposition')
MAX_INDEPENDENT_SET = ('max_independent_set', 'Zeros', 'Superposition')
MAX_WEIGHT_CYCLE = ('max_weight_cycle', 'Superposition', 'Superposition')
MAXCUT = ('maxcut', 'Superposition', 'Superposition')
MIN_VERTEX_COVER = ('min_vertex_cover', 'Ones', 'Superposition')
EDGE_PARTITIONING = ('', '', '')
__init__(pl_string, constrained_initial_state, unconstrained_initial_state)[source]

Initialize the GraphProblem enum value.

Parameters:
  • pl_string (str) – The corresponding PennyLane function name.

  • constrained_initial_state (str) – Recommended initial state for constrained problems.

  • unconstrained_initial_state (str) – Recommended initial state for unconstrained problems.

VQE Ansätze

class HartreeFockAnsatz[source]

Bases: Ansatz

Hartree-Fock-based ansatz for quantum chemistry.

This ansatz prepares the Hartree-Fock reference state and applies parameterized single and double excitation gates. It’s a simplified alternative to UCCSD, often used as a starting point for VQE calculations.

static n_params_per_layer(n_qubits, n_electrons, **kwargs)[source]

Calculate the number of parameters per layer for Hartree-Fock ansatz.

Parameters:
  • n_qubits (int) – Number of qubits in the circuit.

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

  • **kwargs – Additional unused arguments.

Returns:

Number of parameters (number of single + double excitations).

Return type:

int

build(params, n_qubits, n_layers, **kwargs)[source]

Build the Hartree-Fock ansatz circuit.

Parameters:
  • params – Parameter array for excitation amplitudes.

  • n_qubits (int) – Number of qubits.

  • n_layers (int) – Number of ansatz layers.

  • **kwargs – Additional arguments: n_electrons (int): Number of electrons in the system (required).

Returns:

List of operations representing the Hartree-Fock ansatz.

Return type:

list[qml.operation.Operator]

class UCCSDAnsatz[source]

Bases: Ansatz

Unitary Coupled Cluster Singles and Doubles (UCCSD) ansatz.

This ansatz is specifically designed for quantum chemistry calculations, implementing the UCCSD approximation which includes all single and double electron excitations from a reference state.

static n_params_per_layer(n_qubits, n_electrons, **kwargs)[source]

Calculate the number of parameters per layer for UCCSD ansatz.

Parameters:
  • n_qubits (int) – Number of qubits in the circuit.

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

  • **kwargs – Additional unused arguments.

Returns:

Number of parameters (number of single + double excitations).

Return type:

int

build(params, n_qubits, n_layers, **kwargs)[source]

Build the UCCSD ansatz circuit.

Parameters:
  • params – Parameter array for excitation amplitudes.

  • n_qubits (int) – Number of qubits.

  • n_layers (int) – Number of UCCSD layers (repeats).

  • **kwargs – Additional arguments: n_electrons (int): Number of electrons in the system (required).

Returns:

List of operations representing the UCCSD ansatz.

Return type:

list[qml.operation.Operator]

class QAOAAnsatz[source]

Bases: Ansatz

QAOA-style ansatz using PennyLane’s QAOAEmbedding.

Implements a parameterized ansatz based on the Quantum Approximate Optimization Algorithm structure, alternating between problem and mixer Hamiltonians.

static n_params_per_layer(n_qubits, **kwargs)[source]

Calculate the number of parameters per layer for QAOA ansatz.

Parameters:
  • n_qubits (int) – Number of qubits in the circuit.

  • **kwargs – Additional unused arguments.

Returns:

Number of parameters needed per layer.

Return type:

int

build(params, n_qubits, n_layers, **kwargs)[source]

Build the QAOA ansatz circuit.

Parameters:
  • params – Parameter array to use for the ansatz.

  • n_qubits (int) – Number of qubits.

  • n_layers (int) – Number of QAOA layers.

  • **kwargs – Additional unused arguments.

Returns:

List of operations representing the QAOA ansatz.

Return type:

list[qml.operation.Operator]

class HardwareEfficientAnsatz[source]

Bases: Ansatz

Hardware-efficient ansatz (not yet implemented).

This ansatz is designed to be easily implementable on near-term quantum hardware, typically using native gate sets and connectivity patterns.

Note

This class is a placeholder for future implementation.

static n_params_per_layer(n_qubits, **kwargs)[source]

Not yet implemented.

Return type:

int

build(params, n_qubits, n_layers, **kwargs)[source]

Not yet implemented.

Return type:

list[Operator]

class GenericLayerAnsatz(gate_sequence, entangler=None, entangling_layout=None)[source]

Bases: Ansatz

A flexible ansatz alternating single-qubit gates with optional entanglers.

Parameters:
  • gate_sequence (list[Callable]) – List of one-qubit gate classes (e.g., qml.RY, qml.Rot).

  • entangler (Callable) – Two-qubit entangling gate class (e.g., qml.CNOT, qml.CZ). If None, no entanglement is applied.

  • entangling_layout (str) – Layout for entangling layer (“linear”, “all_to_all”, etc.).

__init__(gate_sequence, entangler=None, entangling_layout=None)[source]
Parameters:
  • gate_sequence (list[Callable]) – List of one-qubit gate classes (e.g., qml.RY, qml.Rot).

  • entangler (Callable) – Two-qubit entangling gate class (e.g., qml.CNOT, qml.CZ). If None, no entanglement is applied.

  • entangling_layout (str) – Layout for entangling layer (“linear”, “all_to_all”, etc.).

n_params_per_layer(n_qubits, **kwargs)[source]

Total parameters = sum of gate.num_params per qubit per layer.

Return type:

int

build(params, n_qubits, n_layers, **kwargs)[source]

Builds the ansatz circuit and returns a list of operations.

Parameters:
  • params – Parameter array for the ansatz.

  • n_qubits (int) – Number of qubits in the circuit.

  • n_layers (int) – Number of ansatz layers.

  • **kwargs – Additional arguments specific to the ansatz.

Returns:

List of PennyLane operations representing the ansatz.

Return type:

list[qml.operation.Operator]

class Ansatz[source]

Bases: ABC

Abstract base class for all VQE ansätze.

property name: str

Returns the human-readable name of the ansatz.

abstract static n_params_per_layer(n_qubits, **kwargs)[source]

Returns the number of parameters required by the ansatz for one layer.

Return type:

int

abstract build(params, n_qubits, n_layers, **kwargs)[source]

Builds the ansatz circuit and returns a list of operations.

Parameters:
  • params – Parameter array for the ansatz.

  • n_qubits (int) – Number of qubits in the circuit.

  • n_layers (int) – Number of ansatz layers.

  • **kwargs – Additional arguments specific to the ansatz.

Returns:

List of PennyLane operations representing the ansatz.

Return type:

list[qml.operation.Operator]

Optimizers

Divi provides multiple optimization strategies for quantum algorithm parameter tuning, from classical gradient-based methods to quantum-inspired approaches.

class MonteCarloState(**data)[source]

Bases: BaseModel

Pydantic model for Monte Carlo optimizer state.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

population_size: int
n_best_sets: int
keep_best_params: bool
curr_iteration: int
population: list[list[float]]
evaluated_population: list[list[float]]
losses: list[float]
rng_state_b64: str
model_computed_fields: ClassVar[Dict[str, ComputedFieldInfo]] = {}

A dictionary of computed field names and their corresponding ComputedFieldInfo objects.

model_config: ClassVar[ConfigDict] = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_fields: ClassVar[Dict[str, FieldInfo]] = {'curr_iteration': FieldInfo(annotation=int, required=True), 'evaluated_population': FieldInfo(annotation=list[list[float]], required=True), 'keep_best_params': FieldInfo(annotation=bool, required=True), 'losses': FieldInfo(annotation=list[float], required=True), 'n_best_sets': FieldInfo(annotation=int, required=True), 'population': FieldInfo(annotation=list[list[float]], required=True), 'population_size': FieldInfo(annotation=int, required=True), 'rng_state_b64': FieldInfo(annotation=str, required=True)}

Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo] objects.

This replaces Model.__fields__ from Pydantic V1.

class PymooState(**data)[source]

Bases: BaseModel

Pydantic model for Pymoo optimizer state.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

method_value: str
population_size: int
algorithm_kwargs: dict[str, Any]
algorithm_obj_b64: str
model_computed_fields: ClassVar[Dict[str, ComputedFieldInfo]] = {}

A dictionary of computed field names and their corresponding ComputedFieldInfo objects.

model_config: ClassVar[ConfigDict] = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_fields: ClassVar[Dict[str, FieldInfo]] = {'algorithm_kwargs': FieldInfo(annotation=dict[str, Any], required=True), 'algorithm_obj_b64': FieldInfo(annotation=str, required=True), 'method_value': FieldInfo(annotation=str, required=True), 'population_size': FieldInfo(annotation=int, required=True)}

Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo] objects.

This replaces Model.__fields__ from Pydantic V1.

class Optimizer[source]

Bases: ABC

Abstract base class for all optimizers.

Warning

Thread Safety: Optimizer instances are not thread-safe. They maintain internal state (e.g., current population, iteration count, RNG state) that changes during optimization.

Do not share a single Optimizer instance across multiple QuantumProgram instances or threads running in parallel. Doing so will lead to race conditions, corrupted state, and potential crashes.

If you need to use the same optimizer configuration for multiple programs, create a separate instance for each program. You can use the helper function copy_optimizer() to create a fresh copy with the same configuration.

abstract property n_param_sets

Returns the number of parameter sets the optimizer can handle per optimization run. :returns: Number of parameter sets. :rtype: int

abstract optimize(cost_fn, initial_params, callback_fn=None, **kwargs)[source]

Optimize the given cost function starting from initial parameters.

Parameters:
  • cost_fn (Callable[[ndarray[Any, dtype[float64]]], float]) – The cost function to minimize.

  • initial_params (ndarray[Any, dtype[float64]]) – Initial parameters for the optimization.

  • callback_fn (Callable[[OptimizeResult], Any] | None) – Function called after each iteration with an OptimizeResult object.

  • **kwargs

    Additional keyword arguments for the optimizer:

    • max_iterations (int, optional): Total desired number of iterations. When resuming from a checkpoint, this represents the total iterations desired across all runs. The optimizer will automatically calculate and run only the remaining iterations needed. Defaults vary by optimizer (e.g., 5 for population-based optimizers, None for some scipy methods).

    • rng (np.random.Generator, optional): Random number generator for stochastic optimizers (PymooOptimizer, MonteCarloOptimizer). Defaults to a new generator if not provided.

    • jac (Callable, optional): Gradient/Jacobian function for gradient-based optimizers (only used by ScipyOptimizer with L_BFGS_B method). Defaults to None.

Return type:

OptimizeResult

Returns:

Optimized parameters.

abstract get_config()[source]

Get optimizer configuration for checkpoint reconstruction.

Returns:

Dictionary containing optimizer type and configuration parameters.

Return type:

dict[str, Any]

Raises:

NotImplementedError – If the optimizer does not support checkpointing.

abstract save_state(checkpoint_dir)[source]

Save the optimizer’s internal state to a checkpoint directory.

Parameters:

checkpoint_dir (str) – Directory path where the optimizer state will be saved.

Return type:

None

abstract classmethod load_state(checkpoint_dir)[source]

Load the optimizer’s internal state from a checkpoint directory.

Creates a new optimizer instance with the state restored from the checkpoint.

Parameters:

checkpoint_dir (str) – Directory path where the optimizer state is saved.

Returns:

A new optimizer instance with restored state.

Return type:

Optimizer

abstract reset()[source]

Reset the optimizer’s internal state to allow fresh optimization runs.

Clears any state accumulated during previous optimization runs, allowing the optimizer to be reused for new optimization problems without creating a new instance.

Return type:

None

class PymooMethod[source]

Bases: Enum

Supported optimization methods from the pymoo library.

CMAES = 'CMAES'
DE = 'DE'
class PymooOptimizer(method, population_size=50, **kwargs)[source]

Bases: Optimizer

Optimizer wrapper for pymoo optimization algorithms and CMA-ES.

Supports population-based optimization methods from the pymoo library (DE) and the cma library (CMAES).

Initialize a pymoo-based optimizer.

Parameters:
  • method (PymooMethod) – The optimization algorithm to use (CMAES or DE).

  • population_size (int, optional) – Size of the population for the algorithm. Defaults to 50.

  • **kwargs – Additional algorithm-specific parameters passed to pymoo/cma.

__init__(method, population_size=50, **kwargs)[source]

Initialize a pymoo-based optimizer.

Parameters:
  • method (PymooMethod) – The optimization algorithm to use (CMAES or DE).

  • population_size (int, optional) – Size of the population for the algorithm. Defaults to 50.

  • **kwargs – Additional algorithm-specific parameters passed to pymoo/cma.

property n_param_sets

Get the number of parameter sets (population size) used by this optimizer.

Returns:

Population size for the optimization algorithm.

Return type:

int

get_config()[source]

Get optimizer configuration for checkpoint reconstruction.

Returns:

Dictionary containing optimizer type and configuration parameters.

Return type:

dict[str, Any]

optimize(cost_fn, initial_params=None, callback_fn=None, **kwargs)[source]

Run the optimization algorithm.

Parameters:
  • cost_fn (Callable) – Function to minimize. Should accept a 2D array of parameter sets and return an array of cost values.

  • initial_params (npt.NDArray[np.float64], optional) – Initial parameter values as a 2D array of shape (n_param_sets, n_params). Should be None when resuming from a checkpoint.

  • callback_fn (Callable, optional) – Function called after each iteration with an OptimizeResult object. Defaults to None.

  • **kwargs

    Additional keyword arguments:

    • max_iterations (int): Total desired number of iterations. When resuming from a checkpoint, this represents the total iterations desired across all runs. The optimizer will automatically calculate and run only the remaining iterations needed. Defaults to 5.

    • rng (np.random.Generator): Random number generator.

Returns:

Optimization result with final parameters and cost value.

Return type:

OptimizeResult

save_state(checkpoint_dir)[source]

Save the optimizer’s internal state to a checkpoint directory.

Parameters:

checkpoint_dir (Path | str) – Directory path where the optimizer state will be saved.

Raises:

RuntimeError – If optimization has not been run (no state to save).

Return type:

None

classmethod load_state(checkpoint_dir)[source]

Load the optimizer’s internal state from a checkpoint directory.

Creates a new PymooOptimizer instance with the state restored from the checkpoint.

Parameters:

checkpoint_dir (Path | str) – Directory path where the optimizer state is saved.

Returns:

A new optimizer instance with restored state.

Return type:

PymooOptimizer

Raises:

FileNotFoundError – If the checkpoint file does not exist.

reset()[source]

Reset the optimizer’s internal state.

Clears the current algorithm object, allowing the optimizer to be reused for fresh optimization runs.

Return type:

None

class ScipyMethod[source]

Bases: Enum

Supported optimization methods from scipy.optimize.

NELDER_MEAD = 'Nelder-Mead'
COBYLA = 'COBYLA'
L_BFGS_B = 'L-BFGS-B'
class ScipyOptimizer(method)[source]

Bases: Optimizer

Optimizer wrapper for scipy.optimize methods.

Supports gradient-free and gradient-based optimization algorithms from scipy, including Nelder-Mead simplex, COBYLA, and L-BFGS-B.

Initialize a scipy-based optimizer.

Parameters:

method (ScipyMethod) – The optimization algorithm to use.

__init__(method)[source]

Initialize a scipy-based optimizer.

Parameters:

method (ScipyMethod) – The optimization algorithm to use.

property n_param_sets: int

Get the number of parameter sets used by this optimizer.

Returns:

Always returns 1, as scipy optimizers use single-point optimization.

Return type:

int

optimize(cost_fn, initial_params, callback_fn=None, **kwargs)[source]

Run the scipy optimization algorithm.

Parameters:
  • cost_fn (Callable) – Function to minimize. Should accept a 1D array of parameters and return a scalar cost value.

  • initial_params (npt.NDArray[np.float64]) – Initial parameter values as a 1D or 2D array. If 2D with shape (1, n_params), it will be squeezed to 1D.

  • callback_fn (Callable, optional) – Function called after each iteration with an OptimizeResult object. Defaults to None.

  • **kwargs

    Additional keyword arguments:

    • max_iterations (int, optional): Total desired number of iterations. Defaults to None (no limit for some methods).

    • jac (Callable): Gradient function (only used for L-BFGS-B).

Returns:

Optimization result with final parameters and cost value.

Return type:

OptimizeResult

save_state(checkpoint_dir)[source]

Save the optimizer’s internal state to a checkpoint directory.

Scipy optimizers do not support saving state mid-minimization as scipy.optimize does not provide access to the internal optimizer state.

Parameters:

checkpoint_dir (str) – Directory path where the optimizer state would be saved.

Raises:

NotImplementedError – Always raised, as scipy optimizers cannot save state.

Return type:

None

classmethod load_state(checkpoint_dir)[source]

Load the optimizer’s internal state from a checkpoint directory.

Scipy optimizers do not support loading state as they cannot save state.

Parameters:

checkpoint_dir (str) – Directory path where the optimizer state would be loaded from.

Raises:

NotImplementedError – Always raised, as scipy optimizers cannot load state.

Return type:

ScipyOptimizer

reset()[source]

Reset the optimizer’s internal state.

ScipyOptimizer does not maintain internal state between optimization runs, so this method is a no-op.

Return type:

None

get_config()[source]

Get optimizer configuration for checkpoint reconstruction.

Raises:

NotImplementedError – ScipyOptimizer does not support checkpointing.

Return type:

dict[str, Any]

class MonteCarloOptimizer(population_size=10, n_best_sets=3, keep_best_params=False)[source]

Bases: Optimizer

Monte Carlo-based parameter search optimizer.

This optimizer samples parameter space randomly, selects the best-performing samples, and uses them as centers for the next generation of samples with decreasing variance. This implements a simple but effective evolutionary strategy.

Initialize a Monte Carlo optimizer.

Parameters:
  • population_size (int, optional) – Size of the population for the algorithm. Defaults to 10.

  • n_best_sets (int, optional) – Number of top-performing parameter sets to use as seeds for the next generation. Defaults to 3.

  • keep_best_params (bool, optional) – If True, includes the best parameter sets directly in the new population. If False, generates all new parameters by sampling around the best ones. Defaults to False.

Raises:
  • ValueError – If n_best_sets is greater than population_size.

  • ValueError – If keep_best_params is True and n_best_sets equals population_size.

__init__(population_size=10, n_best_sets=3, keep_best_params=False)[source]

Initialize a Monte Carlo optimizer.

Parameters:
  • population_size (int, optional) – Size of the population for the algorithm. Defaults to 10.

  • n_best_sets (int, optional) – Number of top-performing parameter sets to use as seeds for the next generation. Defaults to 3.

  • keep_best_params (bool, optional) – If True, includes the best parameter sets directly in the new population. If False, generates all new parameters by sampling around the best ones. Defaults to False.

Raises:
  • ValueError – If n_best_sets is greater than population_size.

  • ValueError – If keep_best_params is True and n_best_sets equals population_size.

property population_size: int

Get the size of the population.

Returns:

Size of the population.

Return type:

int

property n_param_sets: int

Number of parameter sets (population size), per the Optimizer interface.

Returns:

The population size.

Return type:

int

property n_best_sets: int

Get the number of best parameter sets used for seeding the next generation.

Returns:

Number of best-performing sets kept.

Return type:

int

property keep_best_params: bool

Get whether the best parameters are kept in the new population.

Returns:

True if best parameters are included in new population, False otherwise.

Return type:

bool

get_config()[source]

Get optimizer configuration for checkpoint reconstruction.

Returns:

Dictionary containing optimizer type and configuration parameters.

Return type:

dict[str, Any]

optimize(cost_fn, initial_params, callback_fn=None, **kwargs)[source]

Perform Monte Carlo optimization on the cost function.

Parameters:
  • cost_fn (Callable[[ndarray[Any, dtype[float64]]], float]) – The cost function to minimize.

  • initial_params (ndarray[Any, dtype[float64]]) – Initial parameters for the optimization.

  • callback_fn (Callable[[OptimizeResult], Any] | None) – Optional callback function to monitor progress.

  • **kwargs

    Additional keyword arguments:

    • max_iterations (int, optional): Total desired number of iterations. When resuming from a checkpoint, this represents the total iterations desired across all runs. The optimizer will automatically calculate and run only the remaining iterations needed. Defaults to 5.

    • rng (np.random.Generator, optional): Random number generator for parameter sampling. Defaults to a new generator if not provided.

Return type:

OptimizeResult

Returns:

Optimized parameters.

save_state(checkpoint_dir)[source]

Save the optimizer’s internal state to a checkpoint directory.

Parameters:

checkpoint_dir (Path | str) – Directory path where the optimizer state will be saved.

Raises:

RuntimeError – If optimization has not been run (no state to save).

Return type:

None

classmethod load_state(checkpoint_dir)[source]

Load the optimizer’s internal state from a checkpoint directory.

Creates a new MonteCarloOptimizer instance with the state restored from the checkpoint.

Parameters:

checkpoint_dir (Path | str) – Directory path where the optimizer state is saved.

Returns:

A new optimizer instance with restored state.

Return type:

MonteCarloOptimizer

Raises:

FileNotFoundError – If the checkpoint file does not exist.

reset()[source]

Reset the optimizer’s internal state.

Clears all current optimization state (population, losses, iteration, RNG state), allowing the optimizer to be reused for fresh optimization runs.

Return type:

None

copy_optimizer(optimizer)[source]

Create a new optimizer instance with the same configuration as the given optimizer.

This function creates a fresh copy of an optimizer with identical configuration parameters but with reset internal state. This is useful when multiple programs need their own optimizer instances to avoid state contamination.

Tip

Use this function when preparing a batch of programs that will run in parallel. Pass a fresh copy of the optimizer to each program instance to ensure thread safety.

Parameters:

optimizer (Optimizer) – The optimizer to copy.

Return type:

Optimizer

Returns:

A new optimizer instance with the same configuration but fresh state.

Raises:

ValueError – If the optimizer type is not recognized.

Scipy Optimizer

class ScipyOptimizer(method)[source]

Bases: Optimizer

Optimizer wrapper for scipy.optimize methods.

Supports gradient-free and gradient-based optimization algorithms from scipy, including Nelder-Mead simplex, COBYLA, and L-BFGS-B.

Initialize a scipy-based optimizer.

Parameters:

method (ScipyMethod) – The optimization algorithm to use.

__init__(method)[source]

Initialize a scipy-based optimizer.

Parameters:

method (ScipyMethod) – The optimization algorithm to use.

property n_param_sets: int

Get the number of parameter sets used by this optimizer.

Returns:

Always returns 1, as scipy optimizers use single-point optimization.

Return type:

int

optimize(cost_fn, initial_params, callback_fn=None, **kwargs)[source]

Run the scipy optimization algorithm.

Parameters:
  • cost_fn (Callable) – Function to minimize. Should accept a 1D array of parameters and return a scalar cost value.

  • initial_params (npt.NDArray[np.float64]) – Initial parameter values as a 1D or 2D array. If 2D with shape (1, n_params), it will be squeezed to 1D.

  • callback_fn (Callable, optional) – Function called after each iteration with an OptimizeResult object. Defaults to None.

  • **kwargs

    Additional keyword arguments:

    • max_iterations (int, optional): Total desired number of iterations. Defaults to None (no limit for some methods).

    • jac (Callable): Gradient function (only used for L-BFGS-B).

Returns:

Optimization result with final parameters and cost value.

Return type:

OptimizeResult

save_state(checkpoint_dir)[source]

Save the optimizer’s internal state to a checkpoint directory.

Scipy optimizers do not support saving state mid-minimization as scipy.optimize does not provide access to the internal optimizer state.

Parameters:

checkpoint_dir (str) – Directory path where the optimizer state would be saved.

Raises:

NotImplementedError – Always raised, as scipy optimizers cannot save state.

Return type:

None

classmethod load_state(checkpoint_dir)[source]

Load the optimizer’s internal state from a checkpoint directory.

Scipy optimizers do not support loading state as they cannot save state.

Parameters:

checkpoint_dir (str) – Directory path where the optimizer state would be loaded from.

Raises:

NotImplementedError – Always raised, as scipy optimizers cannot load state.

Return type:

ScipyOptimizer

reset()[source]

Reset the optimizer’s internal state.

ScipyOptimizer does not maintain internal state between optimization runs, so this method is a no-op.

Return type:

None

get_config()[source]

Get optimizer configuration for checkpoint reconstruction.

Raises:

NotImplementedError – ScipyOptimizer does not support checkpointing.

Return type:

dict[str, Any]

Monte Carlo Optimizer

class MonteCarloOptimizer(population_size=10, n_best_sets=3, keep_best_params=False)[source]

Bases: Optimizer

Monte Carlo-based parameter search optimizer.

This optimizer samples parameter space randomly, selects the best-performing samples, and uses them as centers for the next generation of samples with decreasing variance. This implements a simple but effective evolutionary strategy.

Initialize a Monte Carlo optimizer.

Parameters:
  • population_size (int, optional) – Size of the population for the algorithm. Defaults to 10.

  • n_best_sets (int, optional) – Number of top-performing parameter sets to use as seeds for the next generation. Defaults to 3.

  • keep_best_params (bool, optional) – If True, includes the best parameter sets directly in the new population. If False, generates all new parameters by sampling around the best ones. Defaults to False.

Raises:
  • ValueError – If n_best_sets is greater than population_size.

  • ValueError – If keep_best_params is True and n_best_sets equals population_size.

__init__(population_size=10, n_best_sets=3, keep_best_params=False)[source]

Initialize a Monte Carlo optimizer.

Parameters:
  • population_size (int, optional) – Size of the population for the algorithm. Defaults to 10.

  • n_best_sets (int, optional) – Number of top-performing parameter sets to use as seeds for the next generation. Defaults to 3.

  • keep_best_params (bool, optional) – If True, includes the best parameter sets directly in the new population. If False, generates all new parameters by sampling around the best ones. Defaults to False.

Raises:
  • ValueError – If n_best_sets is greater than population_size.

  • ValueError – If keep_best_params is True and n_best_sets equals population_size.

property population_size: int

Get the size of the population.

Returns:

Size of the population.

Return type:

int

property n_param_sets: int

Number of parameter sets (population size), per the Optimizer interface.

Returns:

The population size.

Return type:

int

property n_best_sets: int

Get the number of best parameter sets used for seeding the next generation.

Returns:

Number of best-performing sets kept.

Return type:

int

property keep_best_params: bool

Get whether the best parameters are kept in the new population.

Returns:

True if best parameters are included in new population, False otherwise.

Return type:

bool

get_config()[source]

Get optimizer configuration for checkpoint reconstruction.

Returns:

Dictionary containing optimizer type and configuration parameters.

Return type:

dict[str, Any]

optimize(cost_fn, initial_params, callback_fn=None, **kwargs)[source]

Perform Monte Carlo optimization on the cost function.

Parameters:
  • cost_fn (Callable[[ndarray[Any, dtype[float64]]], float]) – The cost function to minimize.

  • initial_params (ndarray[Any, dtype[float64]]) – Initial parameters for the optimization.

  • callback_fn (Callable[[OptimizeResult], Any] | None) – Optional callback function to monitor progress.

  • **kwargs

    Additional keyword arguments:

    • max_iterations (int, optional): Total desired number of iterations. When resuming from a checkpoint, this represents the total iterations desired across all runs. The optimizer will automatically calculate and run only the remaining iterations needed. Defaults to 5.

    • rng (np.random.Generator, optional): Random number generator for parameter sampling. Defaults to a new generator if not provided.

Return type:

OptimizeResult

Returns:

Optimized parameters.

save_state(checkpoint_dir)[source]

Save the optimizer’s internal state to a checkpoint directory.

Parameters:

checkpoint_dir (Path | str) – Directory path where the optimizer state will be saved.

Raises:

RuntimeError – If optimization has not been run (no state to save).

Return type:

None

classmethod load_state(checkpoint_dir)[source]

Load the optimizer’s internal state from a checkpoint directory.

Creates a new MonteCarloOptimizer instance with the state restored from the checkpoint.

Parameters:

checkpoint_dir (Path | str) – Directory path where the optimizer state is saved.

Returns:

A new optimizer instance with restored state.

Return type:

MonteCarloOptimizer

Raises:

FileNotFoundError – If the checkpoint file does not exist.

reset()[source]

Reset the optimizer’s internal state.

Clears all current optimization state (population, losses, iteration, RNG state), allowing the optimizer to be reused for fresh optimization runs.

Return type:

None

Workflows

Divi provides workflow classes for managing large-scale quantum computations, including hyperparameter sweeps and graph partitioning.

VQE Hyperparameter Sweep

class VQEHyperparameterSweep(ansatze, molecule_transformer, optimizer=None, max_iterations=10, **kwargs)[source]

Bases: ProgramBatch

Allows user to carry out a grid search across different values for the ansatz and the bond length used in a VQE program.

Initialize a VQE hyperparameter sweep.

Parameters:
  • ansatze (Sequence[Ansatz]) – A sequence of ansatz circuits to test.

  • molecule_transformer (MoleculeTransformer) – A MoleculeTransformer object defining the configuration for generating the molecule variants.

  • optimizer (Optimizer) – The optimization algorithm for the VQE runs.

  • max_iterations (int) – The maximum number of optimizer iterations for each VQE run.

  • **kwargs (Forwarded to parent class.)

__init__(ansatze, molecule_transformer, optimizer=None, max_iterations=10, **kwargs)[source]

Initialize a VQE hyperparameter sweep.

Parameters:
  • ansatze (Sequence[Ansatz]) – A sequence of ansatz circuits to test.

  • molecule_transformer (MoleculeTransformer) – A MoleculeTransformer object defining the configuration for generating the molecule variants.

  • optimizer (Optimizer) – The optimization algorithm for the VQE runs.

  • max_iterations (int) – The maximum number of optimizer iterations for each VQE run.

  • **kwargs (Forwarded to parent class.)

create_programs()[source]

Create VQE programs for all combinations of ansätze and molecule variants.

Generates molecule variants using the configured MoleculeTransformer, then creates a VQE program for each (ansatz, molecule_variant) pair.

Note

Program IDs are tuples of (ansatz_name, bond_modifier_value).

aggregate_results()[source]

Find the best ansatz and bond configuration from all VQE runs.

Compares the final energies across all ansatz/molecule combinations and returns the configuration that achieved the lowest ground state energy.

Returns:

A tuple containing:
  • best_config (tuple): (ansatz_name, bond_modifier) of the best result.

  • best_energy (float): The lowest energy achieved.

Return type:

tuple

Raises:

RuntimeError – If programs haven’t been run or have empty losses.

visualize_results(graph_type='line')[source]

Visualize the results of the VQE problem.

class MoleculeTransformer(base_molecule, bond_modifiers, atom_connectivity=None, bonds_to_transform=None, alignment_atoms=None)[source]

Bases: object

A class for transforming molecular structures by modifying bond lengths.

This class generates variants of a base molecule by adjusting bond lengths according to specified modifiers. The modification mode is detected automatically.

base_molecule

The reference molecule used as a template for generating variants.

Type:

qml.qchem.Molecule

bond_modifiers

A list of values used to adjust bond lengths. The class will generate one new molecule for each modifier in this list. The modification mode is detected automatically: - Scale mode: If all values are positive, they are used as scaling factors (e.g., 1.1 for a 10% increase). - Delta mode: If any value is zero or negative, all values are treated as additive changes to the bond length, in Ångstroms.

Type:

Sequence[float]

atom_connectivity

A sequence of atom index pairs specifying the bonds in the molecule. If not provided, a chain structure will be assumed e.g.: [(0, 1), (1, 2), (2, 3), …].

Type:

Sequence[tuple[int, int]] | None

bonds_to_transform

A subset of atom_connectivity that specifies the bonds to modify. If None, all bonds will be transformed.

Type:

Sequence[tuple[int, int]] | None

alignment_atoms

Indices of atoms onto which to align the orientation of the resulting variants of the molecule. Only useful for visualization and debugging. If None, no alignment is carried out.

Type:

Sequence[int] | None

base_molecule: Molecule
bond_modifiers: Sequence[float]
atom_connectivity: Sequence[tuple[int, int]] | None = None
bonds_to_transform: Sequence[tuple[int, int]] | None = None
alignment_atoms: Sequence[int] | None = None
generate()[source]
Return type:

dict[float, Molecule]

__init__(base_molecule, bond_modifiers, atom_connectivity=None, bonds_to_transform=None, alignment_atoms=None)

Graph Partitioning QAOA

class GraphPartitioningQAOA(graph, graph_problem, n_layers, backend, partitioning_config, initial_state='Recommended', aggregate_fn=<function linear_aggregation>, optimizer=None, max_iterations=10, **kwargs)[source]

Bases: ProgramBatch

Initializes the graph partitioning class.

Parameters:
  • graph (nx.Graph | rx.PyGraph) – The input graph to be partitioned.

  • graph_problem (GraphProblem) – The type of graph partitioning problem (e.g., EDGE_PARTITIONING).

  • n_layers (int) – Number of layers for the QAOA circuit.

  • backend (CircuitRunner) – Backend used to run quantum/classical circuits.

  • partitioning_config (PartitioningConfig) – the configuration of the partitioning as to the algorithm and

  • output. (expected)

  • initial_state ("Zeros", "Ones", "Superposition", "Recommended", optional) – Initial state for the QAOA algorithm. Defaults to “Recommended”.

  • aggregate_fn (optional) – Aggregation function to combine results. Defaults to linear_aggregation.

  • optimizer (optional) – Optimizer to use for QAOA. Defaults to Optimizers.MONTE_CARLO.

  • max_iterations (int, optional) – Maximum number of optimization iterations. Defaults to 10.

  • **kwargs – Additional keyword arguments passed to the QAOA constructor.

__init__(graph, graph_problem, n_layers, backend, partitioning_config, initial_state='Recommended', aggregate_fn=<function linear_aggregation>, optimizer=None, max_iterations=10, **kwargs)[source]

Initializes the graph partitioning class.

Parameters:
  • graph (nx.Graph | rx.PyGraph) – The input graph to be partitioned.

  • graph_problem (GraphProblem) – The type of graph partitioning problem (e.g., EDGE_PARTITIONING).

  • n_layers (int) – Number of layers for the QAOA circuit.

  • backend (CircuitRunner) – Backend used to run quantum/classical circuits.

  • partitioning_config (PartitioningConfig) – the configuration of the partitioning as to the algorithm and

  • output. (expected)

  • initial_state ("Zeros", "Ones", "Superposition", "Recommended", optional) – Initial state for the QAOA algorithm. Defaults to “Recommended”.

  • aggregate_fn (optional) – Aggregation function to combine results. Defaults to linear_aggregation.

  • optimizer (optional) – Optimizer to use for QAOA. Defaults to Optimizers.MONTE_CARLO.

  • max_iterations (int, optional) – Maximum number of optimization iterations. Defaults to 10.

  • **kwargs – Additional keyword arguments passed to the QAOA constructor.

create_programs()[source]

Creates and initializes QAOA programs for each partitioned subgraph.

The main graph is partitioned into node-based subgraphs according to the specified partitioning configuration. Each subgraph is relabeled with integer node labels for QAOA compatibility, and a reverse index map is stored for later result aggregation.

Each program is assigned a unique program ID, which is a tuple of:
  • An uppercase letter (A, B, C, …) corresponding to the partition index.

  • The number of nodes in the subgraph.

Example program ID: (‘A’, 5) for the first partition with 5 nodes.

The created QAOA programs are stored in the self.programs dictionary, keyed by their program IDs.

aggregate_results()[source]

Aggregates the results from all QAOA subprograms to form a global solution.

This method collects the final bitstring solutions from each partitioned subgraph’s QAOA program, using the aggregation function specified at initialization (e.g., linear or dominance aggregation). It reconstructs the global solution by mapping each subgraph’s solution back to the original node indices using the stored reverse index maps.

The final solution is stored in self.solution as a list of node indices assigned to the selected partition.

Raises:

RuntimeError – If no programs exist, if programs have not been run, or if results are incomplete.

Returns:

The list of node indices in the final aggregated solution.

Return type:

list[int]

draw_partitions(pos=None, figsize=(10, 8), node_size=300)[source]

Draw a NetworkX graph with nodes colored by partition.

Parameters:

posdict, optional

Node positions. If None, uses spring layout

figsizetuple, optional

Figure size (width, height)

node_sizeint, optional

Size of nodes

draw_solution()[source]

Visualizes the main graph with nodes highlighted according to the final aggregated solution.

If the solution has not yet been computed, this method calls aggregate_results() to obtain it.

class PartitioningConfig(max_n_nodes_per_cluster=None, minimum_n_clusters=None, partitioning_algorithm='spectral')[source]

Bases: object

Configuration for graph partitioning algorithms.

This class defines the parameters and constraints for partitioning large graphs into smaller subgraphs for quantum algorithm execution. It supports multiple partitioning algorithms and allows specification of size constraints.

max_n_nodes_per_cluster

Maximum number of nodes allowed in each cluster. If None, no upper limit is enforced. Must be a positive integer.

minimum_n_clusters

Minimum number of clusters to create. If None, no lower limit is enforced. Must be a positive integer.

partitioning_algorithm

Algorithm to use for partitioning. Options are: - “spectral”: Spectral partitioning using Fiedler vector (default) - “metis”: METIS graph partitioning library - “kernighan_lin”: Kernighan-Lin algorithm

Note

At least one of max_n_nodes_per_cluster or minimum_n_clusters must be specified. Both constraints cannot be None.

Examples

>>> # Partition into clusters of at most 10 nodes
>>> config = PartitioningConfig(max_n_nodes_per_cluster=10)
>>> # Create at least 5 clusters using METIS
>>> config = PartitioningConfig(
...     minimum_n_clusters=5,
...     partitioning_algorithm="metis"
... )
>>> # Both constraints: clusters of max 8 nodes, min 3 clusters
>>> config = PartitioningConfig(
...     max_n_nodes_per_cluster=8,
...     minimum_n_clusters=3
... )
max_n_nodes_per_cluster: int | None = None
minimum_n_clusters: int | None = None
partitioning_algorithm: Literal['spectral', 'metis', 'kernighan_lin'] = 'spectral'
__init__(max_n_nodes_per_cluster=None, minimum_n_clusters=None, partitioning_algorithm='spectral')

QUBO Partitioning QAOA

class QUBOPartitioningQAOA(qubo, decomposer, n_layers, backend, composer=SplatComposer(), optimizer=None, max_iterations=10, **kwargs)[source]

Bases: ProgramBatch

Initialize a QUBOPartitioningQAOA instance for solving QUBO problems using partitioning and QAOA.

Parameters:
  • qubo (QUBOProblemTypes) – The QUBO problem to solve, provided as a supported type. Note: Variable types are assumed to be binary (not Spin).

  • decomposer (hybrid.traits.ProblemDecomposer) – The decomposer used to partition the QUBO problem into subproblems.

  • n_layers (int) – Number of QAOA layers to use for each subproblem.

  • backend (CircuitRunner) – Backend responsible for running quantum circuits.

  • composer (hybrid.traits.SubsamplesComposer, optional) – Composer to aggregate subsamples from subproblems. Defaults to hybrid.SplatComposer().

  • optimizer (Optimizer, optional) – Optimizer to use for QAOA. Defaults to Optimizer.MONTE_CARLO.

  • max_iterations (int, optional) – Maximum number of optimization iterations. Defaults to 10.

  • **kwargs – Additional keyword arguments passed to the QAOA constructor.

__init__(qubo, decomposer, n_layers, backend, composer=SplatComposer(), optimizer=None, max_iterations=10, **kwargs)[source]

Initialize a QUBOPartitioningQAOA instance for solving QUBO problems using partitioning and QAOA.

Parameters:
  • qubo (QUBOProblemTypes) – The QUBO problem to solve, provided as a supported type. Note: Variable types are assumed to be binary (not Spin).

  • decomposer (hybrid.traits.ProblemDecomposer) – The decomposer used to partition the QUBO problem into subproblems.

  • n_layers (int) – Number of QAOA layers to use for each subproblem.

  • backend (CircuitRunner) – Backend responsible for running quantum circuits.

  • composer (hybrid.traits.SubsamplesComposer, optional) – Composer to aggregate subsamples from subproblems. Defaults to hybrid.SplatComposer().

  • optimizer (Optimizer, optional) – Optimizer to use for QAOA. Defaults to Optimizer.MONTE_CARLO.

  • max_iterations (int, optional) – Maximum number of optimization iterations. Defaults to 10.

  • **kwargs – Additional keyword arguments passed to the QAOA constructor.

create_programs()[source]

Partition the main QUBO problem and instantiate QAOA programs for each subproblem.

This implementation: - Uses the configured decomposer to split the main QUBO into subproblems. - For each subproblem, creates a QAOA program with the specified parameters. - Stores each program in self.programs with a unique identifier.

Unique Identifier Format:
Each key in self.programs is a tuple of the form (letter, size), where:
  • letter: An uppercase letter (‘A’, ‘B’, ‘C’, …) indicating the partition index.

  • size: The number of variables in the subproblem.

Example: (‘A’, 5) refers to the first partition with 5 variables.

aggregate_results()[source]

Aggregate results from all QUBO subproblems into a global solution.

Collects solutions from each partitioned subproblem (both QAOA-optimized and trivial ones) and uses the hybrid framework composer to combine them into a final solution for the original QUBO problem.

Returns:

A tuple containing:
  • solution (npt.NDArray[np.int32]): Binary solution vector for the QUBO problem.

  • solution_energy (float): Energy/cost of the solution.

Return type:

tuple

Raises:

RuntimeError – If programs haven’t been run or if final probabilities haven’t been computed.

Checkpointing

Divi provides comprehensive checkpointing support for saving and resuming optimization state.

Checkpoint Configuration

class CheckpointConfig(checkpoint_dir=None, checkpoint_interval=None)[source]

Bases: object

Configuration for checkpointing during optimization.

checkpoint_dir

Directory path for saving checkpoints. - If None: No checkpointing. - If Path: Uses that directory.

Type:

Path | None

checkpoint_interval

Save checkpoint every N iterations. If None, saves every iteration (if checkpoint_dir is set).

Type:

int | None

checkpoint_dir: Path | None = None
checkpoint_interval: int | None = None
classmethod with_timestamped_dir(checkpoint_interval=None)[source]

Create CheckpointConfig with auto-generated directory name.

Parameters:

checkpoint_interval (int | None) – Save checkpoint every N iterations. If None, saves every iteration (default).

Returns:

A new CheckpointConfig with auto-generated directory.

Return type:

CheckpointConfig

__init__(checkpoint_dir=None, checkpoint_interval=None)

Checkpoint Information

class CheckpointInfo(path, iteration, timestamp, size_bytes, is_valid)[source]

Bases: object

Information about a checkpoint.

path

Path to the checkpoint subdirectory.

Type:

Path

iteration

Iteration number of this checkpoint.

Type:

int

timestamp

Modification time of the checkpoint directory.

Type:

datetime

size_bytes

Total size of the checkpoint in bytes.

Type:

int

is_valid

Whether the checkpoint is valid (has required files).

Type:

bool

path: Path
iteration: int
timestamp: datetime
size_bytes: int
is_valid: bool
__init__(path, iteration, timestamp, size_bytes, is_valid)

Checkpoint Utilities

resolve_checkpoint_path(main_dir, subdirectory=None)[source]

Resolve the path to a checkpoint subdirectory.

Parameters:
  • main_dir (Path | str) – Main checkpoint directory.

  • subdirectory (str | None) – Specific checkpoint subdirectory to load (e.g., “checkpoint_001”). If None, loads the latest checkpoint based on iteration number.

Returns:

Path to the checkpoint subdirectory.

Return type:

Path

Raises:

CheckpointNotFoundError – If the main directory or specified subdirectory does not exist.

get_checkpoint_info(checkpoint_path)[source]

Get information about a checkpoint.

Parameters:

checkpoint_path (Path) – Path to the checkpoint subdirectory.

Returns:

Information about the checkpoint.

Return type:

CheckpointInfo

Raises:

CheckpointNotFoundError – If the checkpoint directory does not exist.

list_checkpoints(main_dir)[source]

List all checkpoints in a main checkpoint directory.

Parameters:

main_dir (Path) – Main checkpoint directory.

Returns:

List of checkpoint information, sorted by iteration number.

Return type:

list[CheckpointInfo]

Raises:

CheckpointNotFoundError – If the main directory does not exist.

get_latest_checkpoint(main_dir)[source]

Get the path to the latest checkpoint.

Parameters:

main_dir (Path) – Main checkpoint directory.

Returns:

Path to the latest checkpoint, or None if no checkpoints exist.

Return type:

Path | None

cleanup_old_checkpoints(main_dir, keep_last_n)[source]

Remove old checkpoints, keeping only the most recent N.

Parameters:
  • main_dir (Path) – Main checkpoint directory.

  • keep_last_n (int) – Number of most recent checkpoints to keep.

Raises:
Return type:

None

Checkpoint Exceptions

exception CheckpointError[source]

Bases: Exception

Base exception for checkpoint-related errors.

exception CheckpointNotFoundError(message, main_dir=None, available_directories=None)[source]

Bases: CheckpointError

Raised when a checkpoint directory or file is not found.

__init__(message, main_dir=None, available_directories=None)[source]
exception CheckpointCorruptedError(message, file_path=None, details=None)[source]

Bases: CheckpointError

Raised when a checkpoint file is corrupted or invalid.

__init__(message, file_path=None, details=None)[source]

Exceptions

exception _CancelledError[source]

Bases: Exception

Internal exception to signal a task to stop due to cancellation.