iqm-pulla 11.0.0__tar.gz → 11.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/CHANGELOG.rst +16 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/PKG-INFO +1 -1
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/docs/Quick Start.ipynb +10 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/src/iqm/cpc/__init__.py +2 -19
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/src/iqm/cpc/compiler/compiler.py +70 -20
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/src/iqm/pulla/pulla.py +113 -53
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/src/iqm_pulla.egg-info/PKG-INFO +1 -1
- iqm_pulla-11.2.0/version.txt +1 -0
- iqm_pulla-11.0.0/version.txt +0 -1
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/AUTHORS.rst +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/LICENSE.txt +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/MANIFEST.in +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/README.rst +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/docs/API.rst +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/docs/Compilation Stages.ipynb +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/docs/Configuration and Usage.ipynb +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/docs/Custom Gates and Implementations.ipynb +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/docs/Example - Compilation With Local Calibration Set.ipynb +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/docs/Example - Executing QIR programs.ipynb +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/docs/Example - Measuring T1.ipynb +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/docs/Example - Randomized Benchmarking.ipynb +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/docs/Example - Simple Dynamical Decoupling.ipynb +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/docs/_static/images/favicon.ico +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/docs/_static/images/logo.png +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/docs/_templates/autosummary-class-template.rst +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/docs/_templates/autosummary-module-template.rst +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/docs/authors.rst +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/docs/changelog.rst +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/docs/common_errors.rst +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/docs/conf.py +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/docs/examples.rst +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/docs/index.rst +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/docs/license.rst +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/docs/migration_guide.rst +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/docs/readme.rst +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/docs/references.bib +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/docs/references.rst +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/docs/user_guides.rst +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/pyproject.toml +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/requirements/base.in +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/requirements/base.in.internal +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/requirements/base.txt +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/requirements/notebook.in +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/requirements/notebook.txt +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/requirements/qir.in +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/requirements/qir.txt +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/requirements/qiskit.in.internal +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/requirements/qiskit.txt +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/setup.cfg +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/setup.py +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/src/iqm/cpc/compiler/__init__.py +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/src/iqm/cpc/compiler/dd.py +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/src/iqm/cpc/compiler/errors.py +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/src/iqm/cpc/compiler/standard_stages.py +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/src/iqm/cpc/compiler/station_settings.py +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/src/iqm/cpc/interface/__init__.py +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/src/iqm/cpc/interface/compiler.py +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/src/iqm/cpc/py.typed +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/src/iqm/pulla/__init__.py +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/src/iqm/pulla/calibration.py +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/src/iqm/pulla/interface.py +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/src/iqm/pulla/py.typed +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/src/iqm/pulla/quantum_architecture.py +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/src/iqm/pulla/utils.py +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/src/iqm/pulla/utils_cirq.py +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/src/iqm/pulla/utils_dd.py +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/src/iqm/pulla/utils_qir.py +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/src/iqm/pulla/utils_qiskit.py +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/src/iqm_pulla.egg-info/SOURCES.txt +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/src/iqm_pulla.egg-info/dependency_links.txt +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/src/iqm_pulla.egg-info/requires.txt +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/src/iqm_pulla.egg-info/top_level.txt +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/tests/.pylintrc +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/tests/__init__.py +0 -0
- {iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/tests/conftest.py +0 -0
|
@@ -2,6 +2,22 @@
|
|
|
2
2
|
Changelog
|
|
3
3
|
=========
|
|
4
4
|
|
|
5
|
+
Version 11.2.0 (2025-09-12)
|
|
6
|
+
===========================
|
|
7
|
+
|
|
8
|
+
Features
|
|
9
|
+
--------
|
|
10
|
+
|
|
11
|
+
- Allow executing jobs in async fashion
|
|
12
|
+
|
|
13
|
+
Version 11.1.0 (2025-09-12)
|
|
14
|
+
===========================
|
|
15
|
+
|
|
16
|
+
Features
|
|
17
|
+
--------
|
|
18
|
+
|
|
19
|
+
- Postprocessing stages.
|
|
20
|
+
|
|
5
21
|
Version 11.0.0 (2025-09-11)
|
|
6
22
|
===========================
|
|
7
23
|
|
|
@@ -388,6 +388,16 @@
|
|
|
388
388
|
"print(f\"Qiskit result counts:\\n{qiskit_result.get_counts()}\\n\")"
|
|
389
389
|
]
|
|
390
390
|
},
|
|
391
|
+
{
|
|
392
|
+
"cell_type": "markdown",
|
|
393
|
+
"id": "1778cf4c",
|
|
394
|
+
"metadata": {},
|
|
395
|
+
"source": [
|
|
396
|
+
"By default, `execute()` submits the job and waits for its completion by polling the server every second, until interrupted. If you pass `wait_completion=False`, then the method will terminate immediately after submitting the job and return a `StationControlResult` object with the job id in `PENDING` status. \n",
|
|
397
|
+
"\n",
|
|
398
|
+
"You can then manually retrieve job results by calling `get_execution_result()`. It will also, by default, wait for the job to complete until interrupted. If you pass `wait_completion=False`, then `get_execution_result()` will query the server only once and return the current state; it is then up to you to call `get_execution_result()` until the job is completed."
|
|
399
|
+
]
|
|
400
|
+
},
|
|
391
401
|
{
|
|
392
402
|
"cell_type": "markdown",
|
|
393
403
|
"id": "2014d3e7",
|
|
@@ -14,26 +14,9 @@
|
|
|
14
14
|
"""IQM Circuit to Pulse Compiler.
|
|
15
15
|
|
|
16
16
|
IQM Circuit to Pulse Compiler is a Python-based library for converting quantum circuits
|
|
17
|
-
into :class:`instruction schedules <
|
|
18
|
-
(which map ``Station Control`` controller names to
|
|
17
|
+
into :class:`instruction schedules <iqm.pulse.playlist.schedule.Schedule>`
|
|
18
|
+
(which map ``Station Control`` controller names to lists of hardware instructions) and Station Control settings
|
|
19
19
|
required for circuit execution, using the calibration data it is given.
|
|
20
20
|
The generated schedules and settings can be sent to Station Control
|
|
21
21
|
for execution on real or simulated quantum hardware.
|
|
22
|
-
|
|
23
|
-
CPC is normally only accessed indirectly through Cocos or its reference client
|
|
24
|
-
`IQM client <https://docs.meetiqm.com/iqm-client/index.html>`_,
|
|
25
|
-
or a frontend such as
|
|
26
|
-
`Cirq on IQM <https://docs.meetiqm.com/iqm-client/user_guide_cirq.html>`_ or
|
|
27
|
-
`Qiskit on IQM <https://docs.meetiqm.com/iqm-client/user_guide_qiskit.html>`_.
|
|
28
22
|
"""
|
|
29
|
-
|
|
30
|
-
# from importlib.metadata import PackageNotFoundError, version
|
|
31
|
-
|
|
32
|
-
# try:
|
|
33
|
-
# # Change here if project is renamed and does not equal the package name
|
|
34
|
-
# DIST_NAME = "iqm-cocos"
|
|
35
|
-
# __version__ = version(DIST_NAME)
|
|
36
|
-
# except PackageNotFoundError: # pragma: no cover
|
|
37
|
-
# __version__ = "unknown"
|
|
38
|
-
# finally:
|
|
39
|
-
# del version, PackageNotFoundError
|
|
@@ -20,7 +20,7 @@ can be executed by the IQM server on quantum hardware.
|
|
|
20
20
|
|
|
21
21
|
from __future__ import annotations
|
|
22
22
|
|
|
23
|
-
from collections.abc import Callable, Iterable
|
|
23
|
+
from collections.abc import Callable, Collection, Iterable
|
|
24
24
|
from copy import deepcopy
|
|
25
25
|
import functools
|
|
26
26
|
import inspect
|
|
@@ -28,8 +28,10 @@ import logging
|
|
|
28
28
|
from typing import TYPE_CHECKING, Any
|
|
29
29
|
|
|
30
30
|
from opentelemetry import trace
|
|
31
|
+
from typing_extensions import deprecated
|
|
31
32
|
|
|
32
33
|
from exa.common.data.setting_node import SettingNode
|
|
34
|
+
from exa.common.helpers.deprecation import format_deprecated
|
|
33
35
|
from iqm.cpc.compiler.errors import CalibrationError, ClientError, InsufficientContextError
|
|
34
36
|
from iqm.cpc.interface.compiler import (
|
|
35
37
|
CircuitBoundaryMode,
|
|
@@ -187,13 +189,16 @@ class Compiler:
|
|
|
187
189
|
Args:
|
|
188
190
|
calibration_set: Calibration data.
|
|
189
191
|
chip_topology: Physical layout and connectivity of the quantum chip.
|
|
190
|
-
channel_properties:
|
|
191
|
-
component_channels: Mapping
|
|
192
|
-
|
|
192
|
+
channel_properties: Control channel properties for the station.
|
|
193
|
+
component_channels: Mapping from QPU component name to a mapping from ``('drive', 'flux', 'readout')``
|
|
194
|
+
to the name of the control channel responsible for that function of the component.
|
|
195
|
+
component_mapping: Mapping of logical QPU component names to physical QPU component names.
|
|
196
|
+
``None`` means the identity mapping.
|
|
193
197
|
options: Circuit execution options.
|
|
194
198
|
Defaults to STANDARD_CIRCUIT_EXECUTION_OPTIONS.
|
|
195
|
-
stages:
|
|
196
|
-
Note that
|
|
199
|
+
stages: Compilation stages to use. ``None`` means none.
|
|
200
|
+
Note that meaningful circuit compilation requires at least some stages.
|
|
201
|
+
pp_stages: Post-processing stages to use. ``None`` means none.
|
|
197
202
|
strict: If True, raises CalibrationError on calibration validation failures.
|
|
198
203
|
If False, only logs warnings. Defaults to False.
|
|
199
204
|
|
|
@@ -202,7 +207,7 @@ class Compiler:
|
|
|
202
207
|
|
|
203
208
|
"""
|
|
204
209
|
|
|
205
|
-
def __init__(
|
|
210
|
+
def __init__( # noqa: PLR0913
|
|
206
211
|
self,
|
|
207
212
|
*,
|
|
208
213
|
calibration_set: CalibrationSet,
|
|
@@ -211,13 +216,15 @@ class Compiler:
|
|
|
211
216
|
component_channels: dict[str, dict[str, str]],
|
|
212
217
|
component_mapping: dict[str, str] | None = None,
|
|
213
218
|
options: CircuitExecutionOptions = STANDARD_CIRCUIT_EXECUTION_OPTIONS,
|
|
214
|
-
stages:
|
|
219
|
+
stages: Collection[CompilationStage] | None = None,
|
|
220
|
+
pp_stages: Collection[CompilationStage] | None = None,
|
|
215
221
|
strict: bool = False, # consider extending to e.g. errors: Literal["raise", "warning", "ignore"] = "warning"
|
|
216
222
|
):
|
|
217
223
|
self._calibration_set = calibration_set
|
|
218
224
|
self.component_mapping = component_mapping
|
|
219
225
|
self.options = options
|
|
220
226
|
self.stages = stages or []
|
|
227
|
+
self.pp_stages = pp_stages or []
|
|
221
228
|
|
|
222
229
|
self.builder: ScheduleBuilder = initialize_schedule_builder(
|
|
223
230
|
calibration_set, chip_topology, channel_properties, component_channels
|
|
@@ -357,11 +364,12 @@ class Compiler:
|
|
|
357
364
|
)
|
|
358
365
|
self._refresh()
|
|
359
366
|
|
|
367
|
+
@deprecated(format_deprecated(old="`ready`", new=None, since="12.08.2025"))
|
|
360
368
|
def ready(self) -> bool:
|
|
361
369
|
"""Check if the compiler is ready to compile circuits. The compiler is ready if at least one stage is defined, and
|
|
362
370
|
all the stages are non-empty.
|
|
363
371
|
""" # noqa: E501
|
|
364
|
-
if
|
|
372
|
+
if not self.stages:
|
|
365
373
|
return False
|
|
366
374
|
for stage in self.stages:
|
|
367
375
|
if not stage.ready():
|
|
@@ -394,7 +402,7 @@ class Compiler:
|
|
|
394
402
|
full: Iff True, also print the docstring of each pass function.
|
|
395
403
|
|
|
396
404
|
"""
|
|
397
|
-
if
|
|
405
|
+
if not self.stages:
|
|
398
406
|
print("No stages defined.")
|
|
399
407
|
return
|
|
400
408
|
|
|
@@ -409,7 +417,10 @@ class Compiler:
|
|
|
409
417
|
print()
|
|
410
418
|
|
|
411
419
|
def compiler_context(self) -> dict[str, Any]:
|
|
412
|
-
"""Return initial compiler context dictionary.
|
|
420
|
+
"""Return initial compiler context dictionary.
|
|
421
|
+
|
|
422
|
+
Used automatically by :meth:`compile`.
|
|
423
|
+
"""
|
|
413
424
|
return {
|
|
414
425
|
"calibration_set": self._calibration_set,
|
|
415
426
|
"builder": self.builder,
|
|
@@ -422,27 +433,66 @@ class Compiler:
|
|
|
422
433
|
def compile(
|
|
423
434
|
self, data: Iterable[Any], context: dict[str, Any] | None = None
|
|
424
435
|
) -> tuple[Iterable[Any], dict[str, Any]]:
|
|
425
|
-
"""Run all compiler stages.
|
|
436
|
+
"""Run all compiler stages.
|
|
437
|
+
|
|
438
|
+
Initial context will be derived using :meth:`compiler_context` unless a custom
|
|
439
|
+
context dictionary is provided.
|
|
440
|
+
|
|
441
|
+
Args:
|
|
442
|
+
data: Circuits to be compiled.
|
|
443
|
+
context: Custom initial compiler context dictionary.
|
|
444
|
+
|
|
445
|
+
Returns:
|
|
446
|
+
Compiled ``data``, final context.
|
|
447
|
+
|
|
448
|
+
"""
|
|
449
|
+
cpc_logger.info("Running compilation stages...")
|
|
450
|
+
return self.run_stages(self.stages, data, context or self.compiler_context())
|
|
451
|
+
|
|
452
|
+
def postprocess(
|
|
453
|
+
self, data: Iterable[Any], context: dict[str, Any] | None = None
|
|
454
|
+
) -> tuple[Iterable[Any], dict[str, Any]]:
|
|
455
|
+
"""Run all post-processing stages.
|
|
456
|
+
|
|
457
|
+
Initial context will be derived using :meth:`compiler_context` unless a custom
|
|
426
458
|
context dictionary is provided.
|
|
427
459
|
|
|
428
460
|
Args:
|
|
429
|
-
data:
|
|
461
|
+
data: Any data, e.g. execution results derived from :meth:`Pulla.execute`
|
|
430
462
|
context: Custom initial compiler context dictionary.
|
|
431
463
|
|
|
464
|
+
Returns:
|
|
465
|
+
Postprocessed ``data``, final context.
|
|
466
|
+
|
|
432
467
|
""" # noqa: E501
|
|
433
|
-
|
|
434
|
-
|
|
468
|
+
cpc_logger.info("Running postprocessing stages...")
|
|
469
|
+
return self.run_stages(self.pp_stages, data, context or self.compiler_context())
|
|
470
|
+
|
|
471
|
+
def run_stages(
|
|
472
|
+
self, stages: Collection[CompilationStage], data: Iterable[Any], context: dict[str, Any]
|
|
473
|
+
) -> tuple[Iterable[Any], dict[str, Any]]:
|
|
474
|
+
"""Run the given stages in given order on the given data.
|
|
475
|
+
|
|
476
|
+
Args:
|
|
477
|
+
stages: Stages to run on ``data``.
|
|
478
|
+
data: The data to be processed.
|
|
479
|
+
context: Additional information that is passed to the first stage.
|
|
480
|
+
Each stage may make modifications to ``context`` before it is passed to the next stage.
|
|
435
481
|
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
context = self.compiler_context()
|
|
482
|
+
Returns:
|
|
483
|
+
Processed data, final context.
|
|
439
484
|
|
|
440
|
-
|
|
485
|
+
"""
|
|
486
|
+
if not stages:
|
|
487
|
+
raise RuntimeError("No stages defined.")
|
|
441
488
|
for stage in self.stages:
|
|
489
|
+
if not stage.ready():
|
|
490
|
+
raise RuntimeError(f"Stage {stage.name} is not ready.")
|
|
491
|
+
|
|
492
|
+
for stage in stages:
|
|
442
493
|
cpc_logger.info('Running stage "%s"...', stage.name)
|
|
443
494
|
data, context = stage.run(data, context)
|
|
444
495
|
|
|
445
|
-
cpc_logger.info("Compilation finished.")
|
|
446
496
|
return data, context
|
|
447
497
|
|
|
448
498
|
def build_settings(self, context: dict[str, Any], shots: int) -> tuple[SettingNode, dict[str, Any]]:
|
|
@@ -210,6 +210,7 @@ class Pulla:
|
|
|
210
210
|
context: dict[str, Any],
|
|
211
211
|
settings: SettingNode,
|
|
212
212
|
verbose: bool = True,
|
|
213
|
+
wait_completion: bool = True,
|
|
213
214
|
) -> StationControlResult:
|
|
214
215
|
"""Executes a quantum circuit on the remote quantum computer.
|
|
215
216
|
|
|
@@ -218,6 +219,7 @@ class Pulla:
|
|
|
218
219
|
context: Context object of the successful compiler run, containing the readout mappings.
|
|
219
220
|
settings: Station settings.
|
|
220
221
|
verbose: Whether to print results.
|
|
222
|
+
wait_completion: If True, returns immediately with job ID. If False, waits for completion.
|
|
221
223
|
|
|
222
224
|
Returns:
|
|
223
225
|
results of the execution
|
|
@@ -240,72 +242,130 @@ class Pulla:
|
|
|
240
242
|
)
|
|
241
243
|
)
|
|
242
244
|
job_id = uuid.UUID(sweep_response["job_id"])
|
|
243
|
-
try:
|
|
244
|
-
logger.info("Created job in queue with ID: %s", job_id)
|
|
245
|
-
if href := sweep_response.get("job_href"):
|
|
246
|
-
logger.info("Job link: %s", href)
|
|
247
245
|
|
|
248
|
-
|
|
246
|
+
logger.info("Created job in queue with ID: %s", job_id)
|
|
247
|
+
if href := sweep_response.get("job_href"):
|
|
248
|
+
logger.info("Job link: %s", href)
|
|
249
249
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
250
|
+
if wait_completion:
|
|
251
|
+
return self.get_execution_result(job_id, context, verbose, wait_completion=True)
|
|
252
|
+
else:
|
|
253
|
+
return StationControlResult(sweep_id=job_id, task_id=job_id, status=TaskStatus.PENDING)
|
|
253
254
|
|
|
254
|
-
|
|
255
|
-
|
|
255
|
+
def get_execution_result(
|
|
256
|
+
self,
|
|
257
|
+
job_id: uuid.UUID,
|
|
258
|
+
context: dict[str, Any],
|
|
259
|
+
verbose: bool = True,
|
|
260
|
+
wait_completion: bool = True,
|
|
261
|
+
) -> StationControlResult:
|
|
262
|
+
"""Get execution results.
|
|
256
263
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
sweep_data = self._station_control.get_sweep(job_id)
|
|
263
|
-
if job_data.job_status == JobExecutorStatus.READY:
|
|
264
|
-
logger.info("Sweep status: %s", str(sweep_data.job_status))
|
|
265
|
-
|
|
266
|
-
sc_result.status = TaskStatus.READY
|
|
267
|
-
sc_result.result = map_sweep_results_to_logical_qubits(
|
|
268
|
-
self._station_control.get_sweep_results(job_id),
|
|
269
|
-
context["readout_mappings"],
|
|
270
|
-
context["options"].heralding_mode,
|
|
271
|
-
)
|
|
272
|
-
sc_result.start_time = (
|
|
273
|
-
sweep_data.begin_timestamp.isoformat() if sweep_data.begin_timestamp else None
|
|
274
|
-
)
|
|
275
|
-
sc_result.end_time = sweep_data.end_timestamp.isoformat() if sweep_data.end_timestamp else None
|
|
264
|
+
Args:
|
|
265
|
+
job_id: The ID of the job to process.
|
|
266
|
+
context: Context object of the successful compiler run, containing the readout mappings.
|
|
267
|
+
verbose: Whether to print results.
|
|
268
|
+
wait_completion: If True, waits for job completion. If False, returns current status.
|
|
276
269
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
logger.info(sc_result.result)
|
|
270
|
+
Returns:
|
|
271
|
+
The processed station control result.
|
|
280
272
|
|
|
281
|
-
|
|
273
|
+
"""
|
|
274
|
+
sc_result = StationControlResult(sweep_id=job_id, task_id=job_id, status=TaskStatus.PENDING)
|
|
282
275
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
sweep_data.begin_timestamp.isoformat() if sweep_data.begin_timestamp else None
|
|
287
|
-
)
|
|
288
|
-
sc_result.end_time = sweep_data.end_timestamp.isoformat() if sweep_data.end_timestamp else None
|
|
289
|
-
sc_result.message = str(job_data.job_error)
|
|
290
|
-
logger.error("Submission failed! Error: %s", sc_result.message)
|
|
291
|
-
return sc_result
|
|
276
|
+
try:
|
|
277
|
+
if wait_completion:
|
|
278
|
+
logger.info("Waiting for the job to finish...")
|
|
292
279
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
280
|
+
while True:
|
|
281
|
+
job_data = self._station_control.get_job(job_id)
|
|
282
|
+
sc_result.status = TaskStatus.PENDING
|
|
283
|
+
|
|
284
|
+
if job_data.job_status <= JobExecutorStatus.EXECUTION_STARTED: # type: ignore[operator]
|
|
285
|
+
if wait_completion:
|
|
286
|
+
# Wait in the task queue while showing a progress bar
|
|
287
|
+
interrupted = self._station_control._wait_job_completion( # type: ignore[attr-defined]
|
|
288
|
+
str(job_id), get_progress_bar_callback()
|
|
289
|
+
)
|
|
290
|
+
if interrupted:
|
|
291
|
+
raise KeyboardInterrupt
|
|
292
|
+
else:
|
|
293
|
+
# Non-blocking check - return current status
|
|
294
|
+
sc_result.status = (
|
|
295
|
+
TaskStatus.PROGRESS
|
|
296
|
+
if job_data.job_status == JobExecutorStatus.EXECUTION_STARTED
|
|
297
|
+
else TaskStatus.PENDING
|
|
297
298
|
)
|
|
298
|
-
sc_result.end_time = sweep_data.end_timestamp.isoformat() if sweep_data.end_timestamp else None
|
|
299
|
-
sc_result.message = str(job_data.job_error)
|
|
300
|
-
logger.error("Submission was revoked!")
|
|
301
299
|
return sc_result
|
|
302
|
-
|
|
303
|
-
|
|
300
|
+
else:
|
|
301
|
+
# job is not in queue or executing, so we can query the sweep
|
|
302
|
+
result_or_nothing = self._get_result_of_started_job(
|
|
303
|
+
context, job_data, job_id, sc_result, wait_completion, verbose
|
|
304
|
+
)
|
|
305
|
+
if result_or_nothing is not None:
|
|
306
|
+
return result_or_nothing
|
|
307
|
+
|
|
308
|
+
if wait_completion:
|
|
309
|
+
time.sleep(1)
|
|
310
|
+
else:
|
|
311
|
+
break
|
|
304
312
|
|
|
305
313
|
except KeyboardInterrupt as exc:
|
|
306
|
-
|
|
307
|
-
|
|
314
|
+
if wait_completion:
|
|
315
|
+
logger.info("Caught KeyboardInterrupt, revoking job %s", job_id)
|
|
316
|
+
self._station_control.abort_job(job_id)
|
|
308
317
|
raise KeyboardInterrupt from exc
|
|
309
318
|
|
|
319
|
+
return sc_result
|
|
320
|
+
|
|
321
|
+
def _get_result_of_started_job(
|
|
322
|
+
self,
|
|
323
|
+
context: dict[str, Any],
|
|
324
|
+
job_data: Any,
|
|
325
|
+
job_id: uuid.UUID,
|
|
326
|
+
sc_result: StationControlResult,
|
|
327
|
+
wait_completion: bool,
|
|
328
|
+
verbose: bool,
|
|
329
|
+
) -> StationControlResult | None:
|
|
330
|
+
sweep_data = self._station_control.get_sweep(job_id)
|
|
331
|
+
if job_data.job_status == JobExecutorStatus.READY:
|
|
332
|
+
if wait_completion:
|
|
333
|
+
logger.info("Sweep status: %s", str(sweep_data.job_status))
|
|
334
|
+
|
|
335
|
+
sc_result.status = TaskStatus.READY
|
|
336
|
+
sc_result.result = map_sweep_results_to_logical_qubits(
|
|
337
|
+
self._station_control.get_sweep_results(job_id),
|
|
338
|
+
context["readout_mappings"],
|
|
339
|
+
context["options"].heralding_mode,
|
|
340
|
+
)
|
|
341
|
+
sc_result.start_time = sweep_data.begin_timestamp.isoformat() if sweep_data.begin_timestamp else None
|
|
342
|
+
sc_result.end_time = sweep_data.end_timestamp.isoformat() if sweep_data.end_timestamp else None
|
|
343
|
+
|
|
344
|
+
if verbose and wait_completion:
|
|
345
|
+
# TODO: Consider using just 'logger.debug' here and remove 'verbose'
|
|
346
|
+
logger.info(sc_result.result)
|
|
347
|
+
|
|
348
|
+
return sc_result
|
|
349
|
+
|
|
350
|
+
if job_data.job_status == JobExecutorStatus.FAILED:
|
|
351
|
+
sc_result.status = TaskStatus.FAILED
|
|
352
|
+
sc_result.start_time = sweep_data.begin_timestamp.isoformat() if sweep_data.begin_timestamp else None
|
|
353
|
+
sc_result.end_time = sweep_data.end_timestamp.isoformat() if sweep_data.end_timestamp else None
|
|
354
|
+
sc_result.message = str(job_data.job_error)
|
|
355
|
+
if wait_completion:
|
|
356
|
+
logger.error("Submission failed! Error: %s", sc_result.message)
|
|
357
|
+
return sc_result
|
|
358
|
+
|
|
359
|
+
if job_data.job_status == JobExecutorStatus.ABORTED:
|
|
360
|
+
sc_result.status = TaskStatus.FAILED
|
|
361
|
+
sc_result.start_time = sweep_data.begin_timestamp.isoformat() if sweep_data.begin_timestamp else None
|
|
362
|
+
sc_result.end_time = sweep_data.end_timestamp.isoformat() if sweep_data.end_timestamp else None
|
|
363
|
+
sc_result.message = str(job_data.job_error)
|
|
364
|
+
if wait_completion:
|
|
365
|
+
logger.error("Submission was revoked!")
|
|
366
|
+
return sc_result
|
|
367
|
+
|
|
368
|
+
return None
|
|
369
|
+
|
|
310
370
|
|
|
311
371
|
init_loggers({"iqm": "INFO"})
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
11.2.0
|
iqm_pulla-11.0.0/version.txt
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
11.0.0
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{iqm_pulla-11.0.0 → iqm_pulla-11.2.0}/docs/Example - Compilation With Local Calibration Set.ipynb
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|