Skip to content

Results are limited to the current section : Qoolqit

qoolqit.execution

QoolQit module to execute quantum programs on QPUs or local/remote emulators.

Modules:

  • backends
  • compilation_functions
  • job
  • sequence_compiler

Classes:

  • LocalEmulator

    Run QoolQit QuantumPrograms on a Pasqal local emulator backends.

  • QPU

    Execute QoolQit QuantumPrograms on Pasqal quantum processing units.

  • RemoteEmulator

    Run QoolQit QuantumPrograms on a Pasqal remote emulator backends.

  • SequenceCompiler

    Compiles a QoolQit Register and Drive to a Device.

Functions:

  • get_batch_id

    Return the batch ID associated with a remote job.

  • retrieve_remote_job

    Retrieve a previously submitted remote job by its identifiers.

Attributes:

  • JobStatus (TypeAlias) –

    Alias for :class:~pulser.backend.remote.JobStatus.

JobStatus: TypeAlias = remote.JobStatus module-attribute

Section titled “ JobStatus: TypeAlias = remote.JobStatus module-attribute ”

Alias for :class:~pulser.backend.remote.JobStatus.

Terminal states (where :meth:Job.has_ended returns True):

  • :attr:~remote.JobStatus.DONE
  • :attr:~remote.JobStatus.ERROR
  • :attr:~remote.JobStatus.CANCELED

LocalEmulator(*, backend_type: type[EmulatorBackend] = QutipBackendV2, emulation_config: EmulationConfig | None = None, num_shots: int | None = None)

Section titled “ LocalEmulator(*, backend_type: type[EmulatorBackend] = QutipBackendV2, emulation_config: EmulationConfig | None = None, num_shots: int | None = None) ”

Run QoolQit QuantumPrograms on a Pasqal local emulator backends.

This class serves as a primary interface between tools written using QoolQit (including solvers) and local emulator backends.

Parameters:

(type, default:QutipBackendV2) –

backend type. Must be a subtype of pulser.backend.EmulatorBackend.

(EmulationConfig, default:None) –

optional configuration object emulators.

(int, default:None) –

number of bitstring samples to collect from the final quantum state.

Examples:

from qoolqit.execution import LocalEmulator, BackendType
backend = LocalEmulator(backend_type=BackendType.QutipBackendV2)
result = backend.run(program)

Methods:

Source code in qoolqit/execution/backends.py
def __init__(
self,
*,
backend_type: type[EmulatorBackend] = QutipBackendV2,
emulation_config: EmulationConfig | None = None,
num_shots: int | None = None,
) -> None:
"""Instantiates a LocalEmulator."""
super().__init__(num_shots=num_shots)
if not issubclass(backend_type, EmulatorBackend):
raise TypeError(
"Error in `LocalEmulator`: `backend_type` must be a EmulatorBackend type."
)
self._backend_type = backend_type
self._emulation_config = self.validate_emulation_config(emulation_config)

Return a unique emulation config for all emulators.

Defaults to a configuration that asks for the final bitstring, sampled num_shots times.

Source code in qoolqit/execution/backends.py
def default_emulation_config(self) -> EmulationConfig:
"""Return a unique emulation config for all emulators.
Defaults to a configuration that asks for the final bitstring, sampled `num_shots` times.
"""
return EmulationConfig(observables=(BitStrings(num_shots=self._num_shots),))

run(program: QuantumProgram) -> job.Job[Results]

Section titled “ run(program: QuantumProgram) -> job.Job[Results] ”

Run a compiled QuantumProgram and return the results.

Source code in qoolqit/execution/backends.py
def run(self, program: QuantumProgram) -> job.Job[Results]:
"""Run a compiled QuantumProgram and return the results."""
self._backend = self._backend_type(program.compiled_sequence, config=self._emulation_config)
results = self._backend.run()
assert isinstance(results, Results)
return job._LocalJob(results)

validate_emulation_config(emulation_config: EmulationConfig | None) -> EmulationConfig

Section titled “ validate_emulation_config(emulation_config: EmulationConfig | None) -> EmulationConfig ”

Returns a valid config for emulator backends, if needed.

Parameters:

(EmulationConfig | None) –

optional base configuration class for all emulators backends. If no config is provided to an emulator backend, the backend default will used.

Source code in qoolqit/execution/backends.py
def validate_emulation_config(
self, emulation_config: EmulationConfig | None
) -> EmulationConfig:
"""Returns a valid config for emulator backends, if needed.
Args:
emulation_config: optional base configuration class for all emulators backends.
If no config is provided to an emulator backend, the backend default will used.
"""
if emulation_config is None:
emulation_config = self.default_emulation_config()
else:
has_bitstrings = any(
isinstance(obs, BitStrings) for obs in emulation_config.observables
)
if not has_bitstrings:
updated_obs = (*emulation_config.observables, BitStrings(num_shots=self._num_shots))
emulation_config = emulation_config.with_changes(observables=updated_obs)
if self._num_shots is not None:
emulation_config = emulation_config.with_changes(default_num_shots=self._num_shots)
return emulation_config

QPU(*, connection: RemoteConnection, num_shots: int | None = None)

Section titled “ QPU(*, connection: RemoteConnection, num_shots: int | None = None) ”

Execute QoolQit QuantumPrograms on Pasqal quantum processing units.

This class provides the primary interface for running quantum programs on actual QPU hardware. It requires authenticated credentials through a connection object to submit and execute programs on remote quantum processors.

Parameters:

(RemoteConnection) –

Authenticated connection to the remote QPU backend.

(int | None, default:None) –

Number of bitstring samples to collect from the final quantum state.

Examples:

Using Pasqal Cloud:

from pulser_pasqal import PasqalCloud
from qoolqit.execution import QPU
connection = PasqalCloud(
username="your_username",
password="your_password",
project_id="your_project_id"
)
backend = QPU(connection=connection)
remote_results = backend.submit(program)

Using Atos MyQML:

from pulser_myqlm import PulserQLMConnection
from qoolqit.execution import QPU
connection = PulserQLMConnection()
backend = QPU(connection=connection)
results = backend.run(program)
Note

Methods:

  • run

    Run a compiled QuantumProgram and return a job handler.

  • validate_connection

    Validate the required connection to instantiate a RemoteBackend.

Source code in qoolqit/execution/backends.py
def __init__(
self,
*,
connection: RemoteConnection,
num_shots: int | None = None,
) -> None:
"""Instantiates a QPU backend."""
self._backend_type = QPUBackend
self._connection = self.validate_connection(connection)
if num_shots is None:
raise ValueError(
"""Number of shots must be provided to use the QPU backend.
Please specify `num_shots` when creating the QPU instance.
For example: QPU(connection=..., num_shots=100)""",
)
self._config = BackendConfig(default_num_shots=num_shots)

run(program: QuantumProgram) -> job.Job[Results]

Section titled “ run(program: QuantumProgram) -> job.Job[Results] ”

Run a compiled QuantumProgram and return a job handler.

The returned handler Job can be used to retrieve results with job.results()

Parameters:

(QuantumProgram) –

the compiled quantum program to run.

Source code in qoolqit/execution/backends.py
def run(self, program: QuantumProgram) -> job.Job[Results]:
"""Run a compiled QuantumProgram and return a job handler.
The returned handler `Job` can be used to retrieve results with `job.results()`
Args:
program (QuantumProgram): the compiled quantum program to run.
"""
self._backend = self._backend_type(
program.compiled_sequence, connection=self._connection, config=self._config
)
remote_results = self._backend.run(wait=False)
# If in open-batch mode, the job should be the last one in the batch ?
return job._RemoteJob._from_remote_results(remote_results, -1)

validate_connection(connection: RemoteConnection) -> RemoteConnection staticmethod

Section titled “ validate_connection(connection: RemoteConnection) -> RemoteConnection staticmethod ”

Validate the required connection to instantiate a RemoteBackend.

Remote emulators and QPUs require a pulser.backend.remote.RemoteConnection or derived to send jobs. Validation also happens inside the backend. Early validation just makes the error easier to understand.

Source code in qoolqit/execution/backends.py
@staticmethod
def validate_connection(connection: RemoteConnection) -> RemoteConnection:
"""Validate the required connection to instantiate a RemoteBackend.
Remote emulators and QPUs require a `pulser.backend.remote.RemoteConnection` or derived
to send jobs. Validation also happens inside the backend. Early validation just makes the
error easier to understand.
"""
if not isinstance(connection, RemoteConnection):
raise TypeError(f"""Error in `PulserRemoteBackend`:
`connection` must be of type {RemoteConnection}.""")
return connection

RemoteEmulator(*, backend_type: type[RemoteEmulatorBackend] = EmuFreeBackendV2, connection: RemoteConnection, emulation_config: EmulationConfig | None = None, num_shots: int | None = None)

Section titled “ RemoteEmulator(*, backend_type: type[RemoteEmulatorBackend] = EmuFreeBackendV2, connection: RemoteConnection, emulation_config: EmulationConfig | None = None, num_shots: int | None = None) ”

Run QoolQit QuantumPrograms on a Pasqal remote emulator backends.

This class serves as a primary interface between tools written using QoolQit (including solvers) and remote emulator backends. The behavior is similar to LocalEmulator, but here, requires credentials through a connection to submit/run a program. To get your credentials and to create a connection object, please refer to the Pasqal Cloud interface documentation (external).

Parameters:

(type, default:EmuFreeBackendV2) –

backend type. Must be a subtype of pulser_pasqal.backends.RemoteEmulatorBackend.

(RemoteConnection) –

connection to execute the program on remote backends.

(EmulationConfig, default:None) –

optional configuration object emulators.

(int, default:None) –

number of bitstring samples to collect from the final quantum state.

Examples:

from pulser_pasqal import PasqalCloud
from qoolqit.execution import RemoteEmulator, BackendType
connection = PasqalCloud(username=..., password=..., project_id=...)
backend = RemoteEmulator(backend_type=BackendType.EmuFreeBackendV2, connection=connection)
then
remote_results = backend.submit(program)
or
results = backend.run(program)

Methods:

Source code in qoolqit/execution/backends.py
def __init__(
self,
*,
backend_type: type[RemoteEmulatorBackend] = EmuFreeBackendV2,
connection: RemoteConnection,
emulation_config: EmulationConfig | None = None,
num_shots: int | None = None,
) -> None:
"""Instantiates a RemoteEmulator."""
super().__init__(num_shots=num_shots)
if not issubclass(backend_type, RemoteEmulatorBackend):
raise TypeError(
"Error in `RemoteEmulator`: `backend_type` must be a RemoteEmulatorBackend type."
)
self._backend_type = backend_type
self._connection = self.validate_connection(connection)
self._emulation_config = self.validate_emulation_config(emulation_config)

Return a unique emulation config for all emulators.

Defaults to a configuration that asks for the final bitstring, sampled num_shots times.

Source code in qoolqit/execution/backends.py
def default_emulation_config(self) -> EmulationConfig:
"""Return a unique emulation config for all emulators.
Defaults to a configuration that asks for the final bitstring, sampled `num_shots` times.
"""
return EmulationConfig(observables=(BitStrings(num_shots=self._num_shots),))

run(program: QuantumProgram) -> job.Job[Results]

Section titled “ run(program: QuantumProgram) -> job.Job[Results] ”

Run a compiled QuantumProgram and return a job handler.

The returned handler Job can be used to retrieve results with job.results()

Parameters:

(QuantumProgram) –

the compiled quantum program to run.

Source code in qoolqit/execution/backends.py
def run(self, program: QuantumProgram) -> job.Job[Results]:
"""Run a compiled QuantumProgram and return a job handler.
The returned handler `Job` can be used to retrieve results with `job.results()`
Args:
program (QuantumProgram): the compiled quantum program to run.
"""
# Instantiate backend
self._backend = self._backend_type(
program.compiled_sequence,
connection=self._connection,
config=self._emulation_config,
)
remote_results = self._backend.run(wait=False)
# If in open-batch mode, the job should be the last one in the batch ?
return job._RemoteJob._from_remote_results(remote_results, -1)

validate_connection(connection: RemoteConnection) -> RemoteConnection staticmethod

Section titled “ validate_connection(connection: RemoteConnection) -> RemoteConnection staticmethod ”

Validate the required connection to instantiate a RemoteBackend.

Remote emulators and QPUs require a pulser.backend.remote.RemoteConnection or derived to send jobs. Validation also happens inside the backend. Early validation just makes the error easier to understand.

Source code in qoolqit/execution/backends.py
@staticmethod
def validate_connection(connection: RemoteConnection) -> RemoteConnection:
"""Validate the required connection to instantiate a RemoteBackend.
Remote emulators and QPUs require a `pulser.backend.remote.RemoteConnection` or derived
to send jobs. Validation also happens inside the backend. Early validation just makes the
error easier to understand.
"""
if not isinstance(connection, RemoteConnection):
raise TypeError(f"""Error in `PulserRemoteBackend`:
`connection` must be of type {RemoteConnection}.""")
return connection

validate_emulation_config(emulation_config: EmulationConfig | None) -> EmulationConfig

Section titled “ validate_emulation_config(emulation_config: EmulationConfig | None) -> EmulationConfig ”

Returns a valid config for emulator backends, if needed.

Parameters:

(EmulationConfig | None) –

optional base configuration class for all emulators backends. If no config is provided to an emulator backend, the backend default will used.

Source code in qoolqit/execution/backends.py
def validate_emulation_config(
self, emulation_config: EmulationConfig | None
) -> EmulationConfig:
"""Returns a valid config for emulator backends, if needed.
Args:
emulation_config: optional base configuration class for all emulators backends.
If no config is provided to an emulator backend, the backend default will used.
"""
if emulation_config is None:
emulation_config = self.default_emulation_config()
else:
has_bitstrings = any(
isinstance(obs, BitStrings) for obs in emulation_config.observables
)
if not has_bitstrings:
updated_obs = (*emulation_config.observables, BitStrings(num_shots=self._num_shots))
emulation_config = emulation_config.with_changes(observables=updated_obs)
if self._num_shots is not None:
emulation_config = emulation_config.with_changes(default_num_shots=self._num_shots)
return emulation_config

SequenceCompiler(register: Register, drive: Drive, device: Device, profile: CompilerProfile, device_max_duration_ratio: float | None = None)

Section titled “ SequenceCompiler(register: Register, drive: Drive, device: Device, profile: CompilerProfile, device_max_duration_ratio: float | None = None) ”

Compiles a QoolQit Register and Drive to a Device.

Parameters:

(Register) –

the QoolQit Register.

(Drive) –

the QoolQit Drive.

(Device) –

the QoolQit Device.

(CompilerProfile) –

the CompilerProfile to use.

(float | None, default:None) –

optionally set the program duration to a fraction of the device's maximum allowed duration.

Source code in qoolqit/execution/sequence_compiler.py
def __init__(
self,
register: Register,
drive: Drive,
device: Device,
profile: CompilerProfile,
device_max_duration_ratio: float | None = None,
) -> None:
"""Initializes the compiler.
Args:
register: the QoolQit Register.
drive: the QoolQit Drive.
device: the QoolQit Device.
profile: the CompilerProfile to use.
device_max_duration_ratio: optionally set the program duration to a fraction
of the device's maximum allowed duration.
"""
self._register = register
self._drive = drive
self._device = device
self._target_device = device._device
self._profile = profile
self._device_max_duration_ratio = device_max_duration_ratio
self._compilation_function: Callable = basic_compilation

Return the batch ID associated with a remote job.

Temporary utility for cases where batch_id must be persisted and later passed to :func:retrieve_remote_job. Will be deprecated once RemoteConnection supports direct job lookup by job ID alone.

Parameters:

(Job[Results]) –

Any :class:Job instance.

Returns:

  • str ( str ) –

    The batch ID if job is a :class:_RemoteJob,

  • str

    otherwise an empty string.

Source code in qoolqit/execution/job.py
def get_batch_id(job: Job[Results]) -> str:
"""Return the batch ID associated with a remote job.
Temporary utility for cases where *batch_id* must be persisted
and later passed to :func:`retrieve_remote_job`. Will be
deprecated once ``RemoteConnection`` supports direct job lookup
by job ID alone.
Args:
job (Job[Results]): Any :class:`Job` instance.
Returns:
str: The batch ID if *job* is a :class:`_RemoteJob`,
otherwise an empty string.
"""
if isinstance(job, _RemoteJob):
return job._batch_id
return ""

retrieve_remote_job(connection: remote.RemoteConnection, job_id: str, *, batch_id: str = '') -> Job[Results]

Section titled “ retrieve_remote_job(connection: remote.RemoteConnection, job_id: str, *, batch_id: str = '') -> Job[Results] ”

Retrieve a previously submitted remote job by its identifiers.

Use this to reconnect to a job in a new session, or to monitor a job submitted outside the current context.

Note

Parameters:

(RemoteConnection) –

The remote connection through which to query the job.

(str) –

The UUID of the job to retrieve.

(str, default:'') –

The batch identifier the job belongs to. Defaults to an empty string.

Returns:

  • Job[Results]

    Job[Results]: A :class:_RemoteJob connected to the

  • Job[Results]

    specified job.

Source code in qoolqit/execution/job.py
def retrieve_remote_job(
connection: remote.RemoteConnection,
job_id: str,
*,
batch_id: str = "",
) -> Job[Results]:
"""Retrieve a previously submitted remote job by its identifiers.
Use this to reconnect to a job in a new session, or to monitor a
job submitted outside the current context.
Note:
The *batch_id* argument is required by some
``RemoteConnection`` implementations (e.g.
``PasqalCloudConnection``) to query job progress. Use
:func:`get_batch_id` to recover the batch ID from an existing
:class:`Job` if needed.
This dependency on *batch_id* is temporary and will be removed
once ``RemoteConnection`` supports direct lookup by job ID
alone.
Args:
connection (remote.RemoteConnection): The remote connection
through which to query the job.
job_id (str): The UUID of the job to retrieve.
batch_id (str): The batch identifier the job belongs to.
Defaults to an empty string.
Returns:
Job[Results]: A :class:`_RemoteJob` connected to the
specified job.
"""
return _RemoteJob(connection, job_id, batch_id=batch_id)