Backends

The divi.backends module provides interfaces for running quantum circuits on different backends, from local simulators to cloud-based quantum hardware.

Backend Architecture

All backends implement the CircuitRunner interface, providing a consistent API for circuit execution. This abstraction allows switching between different execution environments without changing quantum program code.

class CircuitRunner(shots)[source]

Bases: ABC

A generic interface for anything that can “run” quantum circuits.

__init__(shots)[source]
property shots

Get the number of measurement shots for circuit execution.

Returns:

Number of shots configured for this runner.

Return type:

int

abstract submit_circuits(circuits, **kwargs)[source]

Submit quantum circuits for execution.

This abstract method must be implemented by subclasses to define how circuits are executed on their respective backends (simulator, hardware, etc.).

Parameters:
  • circuits (dict[str, str]) – Dictionary mapping circuit labels to their OpenQASM string representations.

  • **kwargs – Additional backend-specific parameters for circuit execution.

Returns:

The return type depends on the backend implementation. Typically returns measurement results or a job identifier.

Core Backend Classes

class ParallelSimulator(n_processes=2, shots=5000, simulation_seed=None, qiskit_backend=None, noise_model=None, _deterministic_execution=False)[source]

Bases: CircuitRunner

A parallel wrapper around Qiskit’s AerSimulator using Qiskit’s built-in parallelism.

Parameters:
  • n_processes (int, optional) – Number of parallel processes to use for transpilation and simulation. Defaults to 2. This sets both the transpile num_processes and AerSimulator’s max_parallel_experiments.

  • shots (int, optional) – Number of shots to perform. Defaults to 5000.

  • simulation_seed (int, optional) – Seed for the random number generator to ensure reproducibility. Defaults to None.

  • qiskit_backend (Backend | Literal["auto"] | None, optional) – A Qiskit backend to initiate the simulator from.

  • passed (If "auto" is)

  • circuit. (the best-fit most recent fake backend will be chosen for the given)

  • None (Defaults to)

  • simulation. (resulting in noiseless)

  • noise_model (NoiseModel, optional) – Qiskit noise model to use in simulation. Defaults to None.

__init__(n_processes=2, shots=5000, simulation_seed=None, qiskit_backend=None, noise_model=None, _deterministic_execution=False)[source]

A parallel wrapper around Qiskit’s AerSimulator using Qiskit’s built-in parallelism.

Parameters:
  • n_processes (int, optional) – Number of parallel processes to use for transpilation and simulation. Defaults to 2. This sets both the transpile num_processes and AerSimulator’s max_parallel_experiments.

  • shots (int, optional) – Number of shots to perform. Defaults to 5000.

  • simulation_seed (int, optional) – Seed for the random number generator to ensure reproducibility. Defaults to None.

  • qiskit_backend (Backend | Literal["auto"] | None, optional) – A Qiskit backend to initiate the simulator from.

  • passed (If "auto" is)

  • circuit. (the best-fit most recent fake backend will be chosen for the given)

  • None (Defaults to)

  • simulation. (resulting in noiseless)

  • noise_model (NoiseModel, optional) – Qiskit noise model to use in simulation. Defaults to None.

set_seed(seed)[source]

Set the random seed for circuit simulation.

Parameters:

seed (int) – Seed value for the random number generator used in simulation.

submit_circuits(circuits)[source]

Submit multiple circuits for parallel simulation using Qiskit’s built-in parallelism.

Uses Qiskit’s native batch transpilation and execution, which handles parallelism internally.

Parameters:

circuits (dict[str, str]) – Dictionary mapping circuit labels to OpenQASM string representations.

Returns:

List of result dictionaries, each containing:
  • ’label’ (str): Circuit identifier

  • ’results’ (dict): Measurement counts as {bitstring: count}

Return type:

list[dict]

static estimate_run_time_single_circuit(circuit, qiskit_backend, **transpilation_kwargs)[source]

Estimate the execution time of a quantum circuit on a given backend, accounting for parallel gate execution.

Parameters:
  • circuit (str) – The quantum circuit to estimate execution time for as a QASM string.

  • qiskit_backend (Union[Backend, Literal['auto']]) – A Qiskit backend to use for gate time estimation.

Returns:

Estimated execution time in seconds.

Return type:

float

static estimate_run_time_batch(circuits=None, precomputed_durations=None, n_qpus=5, **transpilation_kwargs)[source]

Estimate the execution time of a quantum circuit on a given backend, accounting for parallel gate execution.

Parameters:
  • circuits (list[str]) – The quantum circuits to estimate execution time for, as QASM strings.

  • precomputed_durations (list[float]) – A list of precomputed durations to use.

  • n_qpus (int) – Number of QPU nodes in the pre-supposed cluster we are estimating runtime against.

Returns:

Estimated execution time in seconds.

Return type:

float

class QoroService(auth_token=None, polling_interval=3.0, max_retries=5000, shots=1000, qpu_system_name=None, use_circuit_packing=False)[source]

Bases: CircuitRunner

__init__(auth_token=None, polling_interval=3.0, max_retries=5000, shots=1000, qpu_system_name=None, use_circuit_packing=False)[source]
property qpu_system_name: str | QPUSystem | None
test_connection()[source]

Test the connection to the Qoro API.

Sends a simple GET request to verify that the API is reachable and the authentication token is valid.

Returns:

The response from the API ping endpoint.

Return type:

requests.Response

Raises:

requests.exceptions.HTTPError – If the connection fails or authentication is invalid.

fetch_qpu_systems()[source]

Get the list of available QPU systems from the Qoro API.

Return type:

list[QPUSystem]

Returns:

List of QPUSystem objects.

submit_circuits(circuits, tag='default', job_type=JobType.SIMULATE, qpu_system_name=None, override_circuit_packing=None)[source]

Submit quantum circuits to the Qoro API for execution.

This method first initializes a job and then sends the circuits in one or more chunks, associating them all with a single job ID.

Parameters:
  • circuits (dict[str, str]) – Dictionary mapping unique circuit IDs to QASM circuit strings.

  • tag (str, optional) – Tag to associate with the job for identification. Defaults to “default”.

  • job_type (JobType, optional) – Type of job to execute (e.g., SIMULATE, EXECUTE, ESTIMATE, CIRCUIT_CUT). Defaults to JobType.SIMULATE.

  • qpu_system_name (str | None, optional) – The name of the QPU system to use. Overrides the service’s default.

  • override_circuit_packing (bool | None, optional) – Whether to use circuit packing optimization. Overrides the service’s default.

Raises:
  • ValueError – If more than one circuit is submitted for a CIRCUIT_CUT job, or if any circuit is not valid QASM.

  • requests.exceptions.HTTPError – If any API request fails.

Returns:

The job ID for the created job.

Return type:

str

delete_job(job_id)[source]

Delete a job from the Qoro Database.

Parameters:

job_id (str) – The ID of the job to be deleted.

Returns:

The response from the API.

Return type:

requests.Response

get_job_results(job_id)[source]

Get the results of a job from the Qoro Database.

Parameters:

job_id (str) – The ID of the job to get results from.

Returns:

The results of the job, with histograms decoded.

Return type:

list[dict]

poll_job_status(job_id, loop_until_complete=False, on_complete=None, verbose=True, poll_callback=None)[source]

Get the status of a job and optionally execute a function on completion.

Parameters:
  • job_id (str) – The ID of the job to check.

  • loop_until_complete (bool) – If True, polls until the job is complete or failed.

  • on_complete (Callable, optional) – A function to call with the final response object when the job finishes.

  • verbose (bool, optional) – If True, prints polling status to the logger.

  • poll_callback (Callable, optional) – A function for updating progress bars. Takes (retry_count, status).

Returns:

The current job status as a string if not looping, or a JobStatus enum member (COMPLETED or FAILED) if looping.

Return type:

str | JobStatus

Job Management

class JobStatus(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)[source]
PENDING = 'PENDING'
RUNNING = 'RUNNING'
COMPLETED = 'COMPLETED'
FAILED = 'FAILED'
CANCELLED = 'CANCELLED'
class JobType(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)[source]
EXECUTE = 'EXECUTE'
SIMULATE = 'SIMULATE'
ESTIMATE = 'ESTIMATE'
CIRCUIT_CUT = 'CIRCUIT_CUT'