qoolqit.execution
execution
Section titled “
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:
backend_type
Section titled “ backend_type
”type, default:QutipBackendV2)
–backend type. Must be a subtype of pulser.backend.EmulatorBackend.
emulation_config
Section titled “ emulation_config
”EmulationConfig, default:None)
–optional configuration object emulators.
num_shots
Section titled “ num_shots
”int, default:None)
–number of bitstring samples to collect from the final quantum state.
Examples:
from qoolqit.execution import LocalEmulator, BackendTypebackend = LocalEmulator(backend_type=BackendType.QutipBackendV2)result = backend.run(program)Methods:
-
default_emulation_config–Return a unique emulation config for all emulators.
-
run–Run a compiled QuantumProgram and return the results.
-
validate_emulation_config–Returns a valid config for emulator backends, if needed.
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)
default_emulation_config() -> EmulationConfig
Section titled “
default_emulation_config() -> EmulationConfig
”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:
emulation_config
Section titled “ emulation_config
”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:
connection
Section titled “ connection
”RemoteConnection)
–Authenticated connection to the remote QPU backend.
num_shots
Section titled “ num_shots
”int | None, default:None)
–Number of bitstring samples to collect from the final quantum state.
Examples:
Using Pasqal Cloud:
from pulser_pasqal import PasqalCloudfrom 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 PulserQLMConnectionfrom 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:
program
Section titled “ program
”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
@staticmethoddef 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:
backend_type
Section titled “ backend_type
”type, default:EmuFreeBackendV2)
–backend type. Must be a subtype of
pulser_pasqal.backends.RemoteEmulatorBackend.
connection
Section titled “ connection
”RemoteConnection)
–connection to execute the program on remote backends.
emulation_config
Section titled “ emulation_config
”EmulationConfig, default:None)
–optional configuration object emulators.
num_shots
Section titled “ num_shots
”int, default:None)
–number of bitstring samples to collect from the final quantum state.
Examples:
from pulser_pasqal import PasqalCloudfrom qoolqit.execution import RemoteEmulator, BackendTypeconnection = PasqalCloud(username=..., password=..., project_id=...)backend = RemoteEmulator(backend_type=BackendType.EmuFreeBackendV2, connection=connection)remote_results = backend.submit(program)results = backend.run(program)Methods:
-
default_emulation_config–Return a unique emulation config for all emulators.
-
run–Run a compiled QuantumProgram and return a job handler.
-
validate_connection–Validate the required connection to instantiate a RemoteBackend.
-
validate_emulation_config–Returns a valid config for emulator backends, if needed.
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)
default_emulation_config() -> EmulationConfig
Section titled “
default_emulation_config() -> EmulationConfig
”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:
program
Section titled “ program
”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
@staticmethoddef 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:
emulation_config
Section titled “ emulation_config
”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
Section titled “ register
”Register)
–the QoolQit Register.
drive
Section titled “ drive
”Drive)
–the QoolQit Drive.
device
Section titled “ device
”Device)
–the QoolQit Device.
profile
Section titled “ profile
”CompilerProfile)
–the CompilerProfile to use.
device_max_duration_ratio
Section titled “ device_max_duration_ratio
”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
get_batch_id(job: Job[Results]) -> str
Section titled “
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.
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:
connection
Section titled “ connection
”RemoteConnection)
–The remote connection through which to query the job.
job_id
Section titled “ job_id
”str)
–The UUID of the job to retrieve.
batch_id
Section titled “ batch_id
”str, default:'')
–The batch identifier the job belongs to. Defaults to an empty string.
Returns:
-
Job[Results]–Job[Results]: A :class:
_RemoteJobconnected 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)