iqm-client 32.0.0__tar.gz → 33.0.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_client-32.0.0 → iqm_client-33.0.0}/CHANGELOG.rst +57 -4
- iqm_client-33.0.0/INTEGRATION_GUIDE.rst +228 -0
- iqm_client-33.0.0/MANIFEST.in +4 -0
- {iqm_client-32.0.0/src/iqm_client.egg-info → iqm_client-33.0.0}/PKG-INFO +4 -14
- iqm_client-33.0.0/docs/changelog.rst +8 -0
- {iqm_client-32.0.0 → iqm_client-33.0.0}/docs/index.rst +1 -2
- {iqm_client-32.0.0 → iqm_client-33.0.0}/docs/user_guide_cirq.rst +6 -4
- {iqm_client-32.0.0 → iqm_client-33.0.0}/docs/user_guide_qiskit.rst +50 -56
- {iqm_client-32.0.0 → iqm_client-33.0.0}/pyproject.toml +3 -4
- iqm_client-33.0.0/requirements/base.txt +7 -0
- iqm_client-33.0.0/requirements/cirq.txt +7 -0
- iqm_client-33.0.0/requirements/cli.txt +6 -0
- iqm_client-33.0.0/requirements/qiskit.in +2 -0
- iqm_client-33.0.0/requirements/qiskit.txt +3 -0
- {iqm_client-32.0.0 → iqm_client-33.0.0}/src/iqm/cirq_iqm/devices/iqm_device_metadata.py +2 -1
- {iqm_client-32.0.0 → iqm_client-33.0.0}/src/iqm/cirq_iqm/examples/demo_common.py +1 -1
- {iqm_client-32.0.0 → iqm_client-33.0.0}/src/iqm/cirq_iqm/examples/demo_iqm_execution.py +3 -3
- {iqm_client-32.0.0 → iqm_client-33.0.0}/src/iqm/cirq_iqm/iqm_sampler.py +47 -29
- {iqm_client-32.0.0 → iqm_client-33.0.0}/src/iqm/cirq_iqm/serialize.py +1 -1
- {iqm_client-32.0.0 → iqm_client-33.0.0}/src/iqm/cirq_iqm/transpiler.py +3 -1
- {iqm_client-32.0.0 → iqm_client-33.0.0}/src/iqm/iqm_client/__init__.py +0 -2
- {iqm_client-32.0.0 → iqm_client-33.0.0}/src/iqm/iqm_client/errors.py +6 -17
- iqm_client-33.0.0/src/iqm/iqm_client/iqm_client.py +538 -0
- iqm_client-33.0.0/src/iqm/iqm_client/models.py +403 -0
- iqm_client-33.0.0/src/iqm/iqm_client/py.typed +0 -0
- {iqm_client-32.0.0 → iqm_client-33.0.0}/src/iqm/iqm_client/transpile.py +11 -8
- {iqm_client-32.0.0 → iqm_client-33.0.0}/src/iqm/iqm_client/validation.py +18 -9
- iqm_client-33.0.0/src/iqm/iqm_server_client/__init__.py +14 -0
- iqm_client-33.0.0/src/iqm/iqm_server_client/errors.py +6 -0
- iqm_client-33.0.0/src/iqm/iqm_server_client/iqm_server_client.py +755 -0
- iqm_client-33.0.0/src/iqm/iqm_server_client/models.py +179 -0
- iqm_client-33.0.0/src/iqm/iqm_server_client/py.typed +0 -0
- {iqm_client-32.0.0 → iqm_client-33.0.0}/src/iqm/qiskit_iqm/__init__.py +8 -0
- {iqm_client-32.0.0 → iqm_client-33.0.0}/src/iqm/qiskit_iqm/examples/bell_measure.py +2 -2
- {iqm_client-32.0.0 → iqm_client-33.0.0}/src/iqm/qiskit_iqm/examples/transpile_example.py +9 -4
- {iqm_client-32.0.0 → iqm_client-33.0.0}/src/iqm/qiskit_iqm/fake_backends/fake_adonis.py +2 -1
- {iqm_client-32.0.0 → iqm_client-33.0.0}/src/iqm/qiskit_iqm/fake_backends/fake_aphrodite.py +2 -1
- {iqm_client-32.0.0 → iqm_client-33.0.0}/src/iqm/qiskit_iqm/fake_backends/fake_apollo.py +2 -1
- {iqm_client-32.0.0 → iqm_client-33.0.0}/src/iqm/qiskit_iqm/fake_backends/fake_deneb.py +2 -1
- {iqm_client-32.0.0 → iqm_client-33.0.0}/src/iqm/qiskit_iqm/fake_backends/iqm_fake_backend.py +8 -7
- {iqm_client-32.0.0 → iqm_client-33.0.0}/src/iqm/qiskit_iqm/iqm_backend.py +3 -4
- {iqm_client-32.0.0 → iqm_client-33.0.0}/src/iqm/qiskit_iqm/iqm_circuit_validation.py +8 -7
- {iqm_client-32.0.0 → iqm_client-33.0.0}/src/iqm/qiskit_iqm/iqm_job.py +106 -88
- {iqm_client-32.0.0 → iqm_client-33.0.0}/src/iqm/qiskit_iqm/iqm_move_layout.py +2 -1
- {iqm_client-32.0.0 → iqm_client-33.0.0}/src/iqm/qiskit_iqm/iqm_naive_move_pass.py +115 -56
- {iqm_client-32.0.0 → iqm_client-33.0.0}/src/iqm/qiskit_iqm/iqm_provider.py +49 -36
- {iqm_client-32.0.0 → iqm_client-33.0.0}/src/iqm/qiskit_iqm/iqm_target.py +12 -8
- iqm_client-33.0.0/src/iqm/qiskit_iqm/iqm_transpilation.py +384 -0
- iqm_client-33.0.0/src/iqm/qiskit_iqm/py.typed +0 -0
- {iqm_client-32.0.0 → iqm_client-33.0.0}/src/iqm/qiskit_iqm/qiskit_to_iqm.py +150 -41
- {iqm_client-32.0.0 → iqm_client-33.0.0}/src/iqm/qiskit_iqm/transpiler_plugins.py +11 -8
- {iqm_client-32.0.0 → iqm_client-33.0.0/src/iqm_client.egg-info}/PKG-INFO +4 -14
- {iqm_client-32.0.0 → iqm_client-33.0.0}/src/iqm_client.egg-info/SOURCES.txt +8 -4
- iqm_client-33.0.0/src/iqm_client.egg-info/requires.txt +23 -0
- iqm_client-33.0.0/tests/__init__.py +0 -0
- iqm_client-33.0.0/tests/conftest.py +219 -0
- iqm_client-33.0.0/version.txt +1 -0
- iqm_client-32.0.0/INTEGRATION_GUIDE.rst +0 -202
- iqm_client-32.0.0/MANIFEST.in +0 -9
- iqm_client-32.0.0/docbuild +0 -1
- iqm_client-32.0.0/docs/changelog.rst +0 -2
- iqm_client-32.0.0/requirements/base.txt +0 -7
- iqm_client-32.0.0/requirements/cirq.txt +0 -7
- iqm_client-32.0.0/requirements/cli.txt +0 -8
- iqm_client-32.0.0/requirements/qiskit.in +0 -2
- iqm_client-32.0.0/requirements/qiskit.txt +0 -5
- iqm_client-32.0.0/src/iqm/iqm_client/api.py +0 -90
- iqm_client-32.0.0/src/iqm/iqm_client/authentication.py +0 -206
- iqm_client-32.0.0/src/iqm/iqm_client/iqm_client.py +0 -941
- iqm_client-32.0.0/src/iqm/iqm_client/models.py +0 -994
- iqm_client-32.0.0/src/iqm/qiskit_iqm/iqm_transpilation.py +0 -191
- iqm_client-32.0.0/src/iqm_client.egg-info/requires.txt +0 -33
- iqm_client-32.0.0/test +0 -1
- iqm_client-32.0.0/tests/conftest.py +0 -149
- iqm_client-32.0.0/version.txt +0 -1
- {iqm_client-32.0.0 → iqm_client-33.0.0}/AUTHORS.rst +0 -0
- {iqm_client-32.0.0 → iqm_client-33.0.0}/CHANGELOG_cirq-iqm.rst +0 -0
- {iqm_client-32.0.0 → iqm_client-33.0.0}/CHANGELOG_cortex-cli.rst +0 -0
- {iqm_client-32.0.0 → iqm_client-33.0.0}/CHANGELOG_qiskit-iqm.rst +0 -0
- {iqm_client-32.0.0 → iqm_client-33.0.0}/LICENSE.txt +0 -0
- {iqm_client-32.0.0 → iqm_client-33.0.0}/README.rst +0 -0
- {iqm_client-32.0.0 → iqm_client-33.0.0}/docs/API.rst +0 -0
- {iqm_client-32.0.0 → iqm_client-33.0.0}/docs/_static/images/favicon.ico +0 -0
- {iqm_client-32.0.0 → iqm_client-33.0.0}/docs/_static/images/logo.png +0 -0
- {iqm_client-32.0.0 → iqm_client-33.0.0}/docs/_templates/autosummary-class-template.rst +0 -0
- {iqm_client-32.0.0 → iqm_client-33.0.0}/docs/_templates/autosummary-module-template.rst +0 -0
- {iqm_client-32.0.0 → iqm_client-33.0.0}/docs/authors.rst +0 -0
- {iqm_client-32.0.0 → iqm_client-33.0.0}/docs/conf.py +0 -0
- {iqm_client-32.0.0 → iqm_client-33.0.0}/docs/integration_guide.rst +0 -0
- {iqm_client-32.0.0 → iqm_client-33.0.0}/docs/license.rst +0 -0
- {iqm_client-32.0.0 → iqm_client-33.0.0}/docs/readme.rst +0 -0
- {iqm_client-32.0.0 → iqm_client-33.0.0}/pytest.ini +0 -0
- {iqm_client-32.0.0 → iqm_client-33.0.0}/requirements/base.in +0 -0
- {iqm_client-32.0.0 → iqm_client-33.0.0}/requirements/base.in.internal +0 -0
- {iqm_client-32.0.0 → iqm_client-33.0.0}/requirements/cirq.in +0 -0
- /iqm_client-32.0.0/src/iqm/cirq_iqm/py.typed → /iqm_client-33.0.0/requirements/cirq.in.internal +0 -0
- {iqm_client-32.0.0 → iqm_client-33.0.0}/requirements/cli.in +0 -0
- /iqm_client-32.0.0/src/iqm/iqm_client/py.typed → /iqm_client-33.0.0/requirements/cli.in.internal +0 -0
- /iqm_client-32.0.0/src/iqm/qiskit_iqm/py.typed → /iqm_client-33.0.0/requirements/qiskit.in.internal +0 -0
- {iqm_client-32.0.0 → iqm_client-33.0.0}/setup.cfg +0 -0
- {iqm_client-32.0.0 → iqm_client-33.0.0}/setup.py +0 -0
- {iqm_client-32.0.0 → iqm_client-33.0.0}/src/iqm/cirq_iqm/__init__.py +0 -0
- {iqm_client-32.0.0 → iqm_client-33.0.0}/src/iqm/cirq_iqm/devices/__init__.py +0 -0
- {iqm_client-32.0.0 → iqm_client-33.0.0}/src/iqm/cirq_iqm/devices/adonis.py +0 -0
- {iqm_client-32.0.0 → iqm_client-33.0.0}/src/iqm/cirq_iqm/devices/aphrodite.py +0 -0
- {iqm_client-32.0.0 → iqm_client-33.0.0}/src/iqm/cirq_iqm/devices/apollo.py +0 -0
- {iqm_client-32.0.0 → iqm_client-33.0.0}/src/iqm/cirq_iqm/devices/iqm_device.py +0 -0
- {iqm_client-32.0.0 → iqm_client-33.0.0}/src/iqm/cirq_iqm/examples/demo_adonis.py +0 -0
- {iqm_client-32.0.0 → iqm_client-33.0.0}/src/iqm/cirq_iqm/examples/demo_apollo.py +0 -0
- {iqm_client-32.0.0 → iqm_client-33.0.0}/src/iqm/cirq_iqm/examples/usage.ipynb +0 -0
- {iqm_client-32.0.0 → iqm_client-33.0.0}/src/iqm/cirq_iqm/extended_qasm_parser.py +0 -0
- {iqm_client-32.0.0 → iqm_client-33.0.0}/src/iqm/cirq_iqm/iqm_gates.py +0 -0
- {iqm_client-32.0.0 → iqm_client-33.0.0}/src/iqm/cirq_iqm/optimizers.py +0 -0
- /iqm_client-32.0.0/tests/__init__.py → /iqm_client-33.0.0/src/iqm/cirq_iqm/py.typed +0 -0
- {iqm_client-32.0.0 → iqm_client-33.0.0}/src/iqm/iqm_client/util.py +0 -0
- {iqm_client-32.0.0 → iqm_client-33.0.0}/src/iqm/qiskit_iqm/examples/__init__.py +0 -0
- {iqm_client-32.0.0 → iqm_client-33.0.0}/src/iqm/qiskit_iqm/fake_backends/__init__.py +0 -0
- {iqm_client-32.0.0 → iqm_client-33.0.0}/src/iqm/qiskit_iqm/fake_backends/fake_garnet.py +0 -0
- {iqm_client-32.0.0 → iqm_client-33.0.0}/src/iqm/qiskit_iqm/iqm_circuit.py +0 -0
- {iqm_client-32.0.0 → iqm_client-33.0.0}/src/iqm/qiskit_iqm/move_gate.py +0 -0
- {iqm_client-32.0.0 → iqm_client-33.0.0}/src/iqm_client.egg-info/dependency_links.txt +0 -0
- {iqm_client-32.0.0 → iqm_client-33.0.0}/src/iqm_client.egg-info/entry_points.txt +0 -0
- {iqm_client-32.0.0 → iqm_client-33.0.0}/src/iqm_client.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,59 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
Version 33.0.0 (2025-11-19)
|
|
2
|
+
===========================
|
|
3
|
+
|
|
4
|
+
Breaking changes
|
|
5
|
+
----------------
|
|
6
|
+
|
|
7
|
+
- :class:`.IQMClient` now connects to IQM Server instead of directly to Station Control service.
|
|
8
|
+
- The ``url`` init parameter for :class:`.IQMClient` is replaced by ``iqm_server_url``.
|
|
9
|
+
In addition the class can take the ``quantum_computer`` parameter to connect to a specific
|
|
10
|
+
quantum computer on a server with several. If your IQM Server instance only has one quantum computer,
|
|
11
|
+
you can leave this parameter to its default value.
|
|
12
|
+
- The ``timeout_secs`` parameter is removed for all :class:`.IQMClient` methods, value from the
|
|
13
|
+
:envvar:`IQM_CLIENT_REQUESTS_TIMEOUT` environment variable is used instead (default 120 seconds).
|
|
14
|
+
- :meth:`IQMClient.get_quality_metric_set` and :meth:`IQMClient.get_calibration_set` now return
|
|
15
|
+
slightly different data models with more complete observation data.
|
|
16
|
+
- Circuit and job related models have been moved to :mod:`iqm.station_control.interface.models`
|
|
17
|
+
from IQM client models, to avoid code duplication and use the same models in all SW
|
|
18
|
+
components. Imports have to be updated.
|
|
19
|
+
- :meth:`IQMClient.submit_circuits` no longer has the parameter ``custom_settings``. Use Pulla if
|
|
20
|
+
you need this functionalty.
|
|
21
|
+
- :meth:`IQMClient.submit_circuits` and :meth:`IQMClient.submit_run_request` now return a
|
|
22
|
+
:class:`.CircuitJob` object instead of the plain job ID. The job object contains the job ID,
|
|
23
|
+
and provides methods for monitoring the job's state and retrieving its results.
|
|
24
|
+
- :meth:`IQMClient.get_run` is replaced by :meth:`IQMClient.get_job`, which returns a
|
|
25
|
+
:class:`.CircuitJob` object. The job results can be queried using :class:`CircuitJob.result`.
|
|
26
|
+
- :meth:`IQMClient.get_run_status` is removed, you can check the job object for its status using
|
|
27
|
+
:class:`CircuitJob.update`.
|
|
28
|
+
- :meth:`IQMClient.wait_for_compilation` and :meth:`IQMClient.wait_for_results` are removed,
|
|
29
|
+
use :class:`CircuitJob.wait_for_completion` instead.
|
|
30
|
+
- :meth:`IQMClient.get_run_counts` is replaced by :meth:`IQMClient.get_job_measurement_counts`.
|
|
31
|
+
- :meth:`IQMClient.abort_job` is replaced by :meth:`IQMClient.cancel_job`.
|
|
32
|
+
- The :mod:`iqm.iqm_server_client.authentication` module including :class:`TokenManager` has been moved to
|
|
33
|
+
:mod:`iqm.station_control.client.authentication`, and its API has slightly changed.
|
|
34
|
+
|
|
35
|
+
Features
|
|
36
|
+
--------
|
|
37
|
+
|
|
38
|
+
- ``iqm-client`` integration guide updated.
|
|
39
|
+
- :meth:`IQMClient.submit_circuits` and :meth:`IQMClient.submit_run_request` have a new parameter,
|
|
40
|
+
``use_timeslot``, which indicates if the job should be submitted to a timeslot queue or the
|
|
41
|
+
shared on-demand queue.
|
|
42
|
+
- Minimal changes to support Qiskit v2.0 and v2.1 :issue:`SW-1735`.
|
|
43
|
+
- Deprecation warning for Qiskit versions < 2.0.
|
|
44
|
+
- Bugfix in the transpile example to select qubits from the largest connected subgraph of the backend so that the code works when running against a disconnected graph.
|
|
45
|
+
- Identified potential bug with semantic equivalence of transpiled circuits when using the IQMNaiveMovePass. Tests are temporarily marked as expected to fail. :issue:`SW-1999`.
|
|
46
|
+
|
|
47
|
+
Version 32.1.0 (2025-10-13)
|
|
48
|
+
===========================
|
|
49
|
+
|
|
50
|
+
Features
|
|
51
|
+
--------
|
|
52
|
+
|
|
53
|
+
- Add support for the ``with circuit.if_test()`` construction for classical control in Qiskit :issue:`SW-1724`.
|
|
54
|
+
- Deprecate the ``c_if`` method in favor of the new ``if_test`` method for classical control in Qiskit :issue:`SW-1724`.
|
|
55
|
+
- Bugfix: Fixed the transpiler bug causing classical conditionals to be ignored in certain cases :issue:`SW-1856`.
|
|
56
|
+
- Using one of our transpiler plugins that do not apply MoveGate routing, no longer raises an error when the target backend is not set in the transpiler. e.g. ``transpile(circuit, scheduling_method="only_rz_optimization", basis_gates=['r','cz', 'if_else'])``.
|
|
4
57
|
|
|
5
58
|
Version 32.0.0 (2025-10-09)
|
|
6
59
|
===========================
|
|
@@ -462,7 +515,7 @@ Version 23.1.0 (2025-04-07)
|
|
|
462
515
|
Features
|
|
463
516
|
--------
|
|
464
517
|
|
|
465
|
-
- Fix package version in published docs footers, :issue:`SW-1392`.
|
|
518
|
+
- Fix package version in published docs footers, :issue:`SW-1392`.
|
|
466
519
|
|
|
467
520
|
Version 23.0.0 (2025-04-04)
|
|
468
521
|
===========================
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
=================
|
|
2
|
+
Integration Guide
|
|
3
|
+
=================
|
|
4
|
+
|
|
5
|
+
``iqm-client`` is the Python client for connecting to IQM's quantum computers, for application-level
|
|
6
|
+
quantum computing frameworks. For examples of integrations maintained by IQM, please refer to the
|
|
7
|
+
:ref:`Qiskit <User guide Qiskit>` and :ref:`Cirq <User guide Cirq>` packages.
|
|
8
|
+
|
|
9
|
+
IQM client offers the functionality to submit quantum circuit execution jobs to the quantum computer,
|
|
10
|
+
track the statuses of jobs, and query various properties of the quantum computer.
|
|
11
|
+
|
|
12
|
+
The following sections illustrate how to integrate IQM quantum computers into your quantum computing
|
|
13
|
+
framework.
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
Authentication
|
|
17
|
+
--------------
|
|
18
|
+
|
|
19
|
+
IQM uses bearer token authentication to manage access to quantum computers.
|
|
20
|
+
Get your personal API token from the IQM Server web dashboard. The generated token can be provided to
|
|
21
|
+
IQM client via an environment variable :envvar:`IQM_TOKEN`.
|
|
22
|
+
Alternatively, the token can be provided as the ``token`` argument to :class:`.IQMClient` constructor.
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
Code example
|
|
26
|
+
------------
|
|
27
|
+
|
|
28
|
+
The connection to an IQM Server instance is managed by an :class:`.IQMClient` instance.
|
|
29
|
+
Initialization is simple, and in case you perform the authentication
|
|
30
|
+
using the :envvar:`IQM_TOKEN` environment variable, it only requires the URL of IQM Server:
|
|
31
|
+
|
|
32
|
+
.. code-block:: python
|
|
33
|
+
|
|
34
|
+
from iqm.iqm_client import IQMClient
|
|
35
|
+
|
|
36
|
+
server_url = "https://<IQM_SERVER_URL>"
|
|
37
|
+
iqm_client = IQMClient(server_url)
|
|
38
|
+
|
|
39
|
+
To submit a quantum circuit for execution, it has to be specified using the
|
|
40
|
+
:class:`iqm.pulse.Circuit` class. The available native instructions are documented in
|
|
41
|
+
:mod:`iqm.iqm_client.models` and in :class:`iqm.pulse.CircuitOperation`.
|
|
42
|
+
|
|
43
|
+
.. code-block:: python
|
|
44
|
+
|
|
45
|
+
from math import pi
|
|
46
|
+
|
|
47
|
+
from iqm.pulse.builder import CircuitOperation
|
|
48
|
+
from iqm.pulse.circuit_operations import Circuit
|
|
49
|
+
|
|
50
|
+
instructions = (
|
|
51
|
+
CircuitOperation(
|
|
52
|
+
name="prx", locus=("QB1",), args={"phase": 1.4 * pi, "angle": 0.5 * pi}
|
|
53
|
+
),
|
|
54
|
+
CircuitOperation(name="cz", locus=("QB1", "QB2"), args={}),
|
|
55
|
+
CircuitOperation(name="measure", locus=("QB2",), args={"key": "Qubit 2"}),
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
circuit = Circuit(name="quantum_circuit", instructions=instructions)
|
|
59
|
+
|
|
60
|
+
Then the circuit(s) can be submitted to the server using :meth:`.IQMClient.submit_circuits`.
|
|
61
|
+
Upon successful submission the method returns a :class:`.CircuitJob` object that can be used
|
|
62
|
+
to track the progress of the job. This is a convenience, the only thing that is really needed
|
|
63
|
+
to access the job on IQM Server is the unique job ID in :attr:`.CircuitJob.job_id`.
|
|
64
|
+
You can pass the job ID to :meth:`.IQMClient.get_job` to get a new :class:`.CircuitJob` object for the job.
|
|
65
|
+
|
|
66
|
+
To query the status of the job, use :meth:`.CircuitJob.update`. It will update the job object and
|
|
67
|
+
return its current status. The different job statuses are documented in :class:`.JobStatus`.
|
|
68
|
+
|
|
69
|
+
.. code-block:: python
|
|
70
|
+
|
|
71
|
+
job = iqm_client.submit_circuits([circuit], shots=1000)
|
|
72
|
+
print(job.job_id)
|
|
73
|
+
|
|
74
|
+
job_status = job.update()
|
|
75
|
+
print(job_status)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
Eventually the job will end up in one of the terminal statuses:
|
|
79
|
+
``"completed"``, ``"failed"``, or ``"cancelled"``.
|
|
80
|
+
You can either periodically query the status, or use :meth:`.CircuitJob.wait_for_completion`
|
|
81
|
+
which will block and poll the job status until it hits a terminal status, which is then returned.
|
|
82
|
+
|
|
83
|
+
When the status is ``"completed"``, you can use :meth:`.CircuitJob.result` to get the job results:
|
|
84
|
+
|
|
85
|
+
.. code-block:: python
|
|
86
|
+
|
|
87
|
+
job_status = job.wait_for_completion()
|
|
88
|
+
print(job_status)
|
|
89
|
+
job_result = job.result()
|
|
90
|
+
|
|
91
|
+
A job can be cancelled by calling :meth:`.CircuitJob.cancel`.
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
Job payload
|
|
95
|
+
-----------
|
|
96
|
+
|
|
97
|
+
A ``dict[str, Any]`` containing arbitrary metadata can be attached to :class:`iqm.pulse.Circuit`
|
|
98
|
+
before submitting it for execution.
|
|
99
|
+
The attached metadata should consist only of values of JSON serializable datatypes.
|
|
100
|
+
A utility function :func:`~.iqm_client.util.to_json_dict` can be used to convert supported datatypes,
|
|
101
|
+
e.g. :class:`numpy.ndarray`, to equivalent JSON serializable types.
|
|
102
|
+
|
|
103
|
+
The server stores the job payload (including the metadata), and it can be queried using
|
|
104
|
+
:meth:`.CircuitJob.payload`, which returns the submitted circuits (with their metadata), and
|
|
105
|
+
the various job parameters used.
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
Job metadata and errors
|
|
109
|
+
-----------------------
|
|
110
|
+
|
|
111
|
+
The server attaches its own metadata to the job, including details related to the compilation
|
|
112
|
+
and execution of the job. Important metadata items include
|
|
113
|
+
|
|
114
|
+
* :attr:`.CircuitJob.data.errors`: list of errors for a ``"failed"`` job
|
|
115
|
+
* :attr:`.CircuitJob.data.messages`: list of informational messages
|
|
116
|
+
* :attr:`.CircuitJob.data.timeline`: list of execution steps reached with their timestamps
|
|
117
|
+
* :attr:`.CircuitJob.data.compilation.calibration_set_id`: ID of the calibration set used in the execution
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
Job timeline
|
|
121
|
+
~~~~~~~~~~~~
|
|
122
|
+
|
|
123
|
+
Each item in :attr:`.CircuitJob.data.timeline` is a :class:`.TimelineEntry`,
|
|
124
|
+
containing an execution step reached, a timestamp, and the source of the entry.
|
|
125
|
+
The steps in the timeline are more detailed than the job statuses.
|
|
126
|
+
For example, when the job is accepted, IQM Server adds a timestamp with the status ``"created"``.
|
|
127
|
+
|
|
128
|
+
The timeline entries also contain information about the lower-level job processing steps by
|
|
129
|
+
Station Control. For example, before the circuits can be executed they are compiled into instruction
|
|
130
|
+
schedules, indicated by the ``"compilation_started"`` and ``"compilation_ended"`` timestamps.
|
|
131
|
+
The actual execution of the job on the quantum hardware is indicated by the
|
|
132
|
+
``"execution_started"`` and ``"execution_ended"`` timestamps.
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
Circuit transpilation
|
|
136
|
+
---------------------
|
|
137
|
+
|
|
138
|
+
IQM does not provide an open source circuit transpilation library, so this will have to be supplied
|
|
139
|
+
by the quantum computing framework or a third party library. To obtain the necessary information
|
|
140
|
+
for circuit transpilation, :meth:`.IQMClient.get_dynamic_quantum_architecture` returns the names of the
|
|
141
|
+
QPU components (qubits and computational resonators), and the native operations available
|
|
142
|
+
in the given calibration set. This information should enable circuit transpilation for the
|
|
143
|
+
IQM Crystal quantum architectures.
|
|
144
|
+
|
|
145
|
+
The notable exception is the transpilation for the IQM Star quantum architectures, which have
|
|
146
|
+
computational resonators in addition to qubits. Some specialized transpilation logic involving
|
|
147
|
+
the MOVE gates specific to these architectures is provided, in the form of the functions
|
|
148
|
+
:func:`.transpile_insert_moves` and :func:`.transpile_remove_moves`.
|
|
149
|
+
See :mod:`iqm.iqm_client.transpile` for the details.
|
|
150
|
+
|
|
151
|
+
A typical Star architecture use case would look something like this:
|
|
152
|
+
|
|
153
|
+
.. code-block:: python
|
|
154
|
+
|
|
155
|
+
from iqm.iqm_client import IQMClient, simplify_architecture, transpile_insert_moves, transpile_remove_moves
|
|
156
|
+
from iqm.pulse.circuit_operations import Circuit
|
|
157
|
+
|
|
158
|
+
client = IQMClient(URL_TO_STAR_SERVER)
|
|
159
|
+
dqa = client.get_dynamic_quantum_architecture()
|
|
160
|
+
simplified_dqa = simplify_architecture(dqa)
|
|
161
|
+
|
|
162
|
+
# circuit valid for simplified_dqa
|
|
163
|
+
circuit = Circuit(name="quantum_circuit", instructions=[...])
|
|
164
|
+
|
|
165
|
+
# intended use
|
|
166
|
+
circuit_with_moves = transpile_insert_moves(circuit, dqa)
|
|
167
|
+
job = client.submit_circuits([circuit_with_moves])
|
|
168
|
+
|
|
169
|
+
# back to simplified dqa
|
|
170
|
+
circuit_without_moves = transpile_remove_moves(circuit_with_moves)
|
|
171
|
+
# circuit_without_moves is equivalent to circuit
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
Note on qubit mapping
|
|
175
|
+
---------------------
|
|
176
|
+
|
|
177
|
+
We encourage to transpile circuits to use the physical IQM qubit names before submitting them to IQM
|
|
178
|
+
quantum computers. In case the quantum computing framework does not allow for this, providing a
|
|
179
|
+
qubit mapping can do the translation from the framework qubit names to IQM qubit names. Note that
|
|
180
|
+
qubit mapping is not supposed to be associated with individual circuits, but rather with the entire
|
|
181
|
+
job request to IQM Server. Typically, you would have some local representation of the QPU and
|
|
182
|
+
transpile the circuits against that representation, then use qubit mapping along with the generated
|
|
183
|
+
circuits to map from the local representation to the IQM representation of qubit names.
|
|
184
|
+
We discourage exposing this feature to end users of the quantum computing framework.
|
|
185
|
+
|
|
186
|
+
Note on circuit duration check
|
|
187
|
+
------------------------------
|
|
188
|
+
|
|
189
|
+
Before performing circuit execution, IQM Server checks how long it would take to run each circuit.
|
|
190
|
+
If any circuit in a job would take too long to execute compared to the T2 time of the qubits,
|
|
191
|
+
the server will disqualify the job, not execute any circuits, and return a detailed error message.
|
|
192
|
+
In some special cases, it makes sense to adjust or disable this check using
|
|
193
|
+
the :attr:`max_circuit_duration_over_t2` attribute of :class:`.CircuitCompilationOptions`,
|
|
194
|
+
and then passing the options to :meth:`.IQMClient.submit_circuits`.
|
|
195
|
+
|
|
196
|
+
Note on environment variables
|
|
197
|
+
-----------------------------
|
|
198
|
+
|
|
199
|
+
Set :envvar:`IQM_CLIENT_REQUESTS_TIMEOUT` environment variable to override the network request
|
|
200
|
+
default timeout value (in seconds) for :class:`.IQMClient` methods. The default value is 120
|
|
201
|
+
seconds and might not be sufficient e.g. when fetching the results of a larger circuit job through
|
|
202
|
+
a slow network connection.
|
|
203
|
+
|
|
204
|
+
On Linux:
|
|
205
|
+
|
|
206
|
+
.. code-block:: bash
|
|
207
|
+
|
|
208
|
+
$ export IQM_CLIENT_REQUESTS_TIMEOUT=300
|
|
209
|
+
|
|
210
|
+
On Windows:
|
|
211
|
+
|
|
212
|
+
.. code-block:: batch
|
|
213
|
+
|
|
214
|
+
set IQM_CLIENT_REQUESTS_TIMEOUT=300
|
|
215
|
+
|
|
216
|
+
Set :envvar:`IQM_CLIENT_SECONDS_BETWEEN_CALLS` to control the polling interval (in seconds) when
|
|
217
|
+
waiting for a job to complete with :meth:`.CircuitJob.wait_for_completion`.
|
|
218
|
+
The default value is 1 second.
|
|
219
|
+
|
|
220
|
+
Set :envvar:`IQM_CLIENT_DEBUG=1` to print the run request when it is submitted for execution in
|
|
221
|
+
:meth:`.IQMClient.submit_circuits` or :meth:`.IQMClient.submit_run_request`. To inspect the run
|
|
222
|
+
request without sending it for execution, use :meth:`.IQMClient.create_run_request`.
|
|
223
|
+
|
|
224
|
+
Integration testing
|
|
225
|
+
-------------------
|
|
226
|
+
|
|
227
|
+
IQM provides a demo environment to test the integration against a mock quantum computer. If you'd
|
|
228
|
+
like to request access to that environment, please contact `IQM <info@meetiqm.com>`_.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: iqm-client
|
|
3
|
-
Version:
|
|
3
|
+
Version: 33.0.0
|
|
4
4
|
Summary: Client library for accessing an IQM quantum computer
|
|
5
5
|
Author-email: IQM Finland Oy <developers@meetiqm.com>
|
|
6
6
|
License: Apache License
|
|
@@ -216,35 +216,25 @@ Requires-Python: <3.13,>=3.10
|
|
|
216
216
|
Description-Content-Type: text/x-rst
|
|
217
217
|
License-File: LICENSE.txt
|
|
218
218
|
License-File: AUTHORS.rst
|
|
219
|
-
Requires-Dist: iqm-station-control-client<12,>=11
|
|
220
|
-
Requires-Dist: iqm-exa-common<28,>=27
|
|
221
|
-
Requires-Dist: iqm-pulse<13,>=12
|
|
222
219
|
Requires-Dist: numpy<3.0,>=1.26.4
|
|
223
220
|
Requires-Dist: packaging==24.1
|
|
224
221
|
Requires-Dist: pydantic<3.0,>=2.9.2
|
|
225
222
|
Requires-Dist: requests==2.32.3
|
|
223
|
+
Requires-Dist: iqm-pulse
|
|
224
|
+
Requires-Dist: iqm-station-control-client
|
|
226
225
|
Provides-Extra: cirq
|
|
227
|
-
Requires-Dist: iqm-station-control-client<12,>=11; extra == "cirq"
|
|
228
|
-
Requires-Dist: iqm-exa-common<28,>=27; extra == "cirq"
|
|
229
|
-
Requires-Dist: iqm-pulse<13,>=12; extra == "cirq"
|
|
230
226
|
Requires-Dist: cirq-core[contrib]~=1.2; extra == "cirq"
|
|
231
227
|
Requires-Dist: ply==3.11; extra == "cirq"
|
|
232
228
|
Requires-Dist: llvmlite>=0.44.0; extra == "cirq"
|
|
233
229
|
Requires-Dist: numba>=0.61.0; extra == "cirq"
|
|
234
230
|
Provides-Extra: cli
|
|
235
|
-
Requires-Dist: iqm-station-control-client<12,>=11; extra == "cli"
|
|
236
|
-
Requires-Dist: iqm-exa-common<28,>=27; extra == "cli"
|
|
237
|
-
Requires-Dist: iqm-pulse<13,>=12; extra == "cli"
|
|
238
231
|
Requires-Dist: click<9,>=8.1.6; extra == "cli"
|
|
239
232
|
Requires-Dist: jsonschema>=4.6.0; extra == "cli"
|
|
240
233
|
Requires-Dist: psutil>=5.9.2; extra == "cli"
|
|
241
234
|
Requires-Dist: types-psutil; extra == "cli"
|
|
242
235
|
Requires-Dist: python-daemon>=2.3.0; extra == "cli"
|
|
243
236
|
Provides-Extra: qiskit
|
|
244
|
-
Requires-Dist:
|
|
245
|
-
Requires-Dist: iqm-exa-common<28,>=27; extra == "qiskit"
|
|
246
|
-
Requires-Dist: iqm-pulse<13,>=12; extra == "qiskit"
|
|
247
|
-
Requires-Dist: qiskit<=1.4.2,>=1.0; extra == "qiskit"
|
|
237
|
+
Requires-Dist: qiskit<2.2,>=1.0; extra == "qiskit"
|
|
248
238
|
Requires-Dist: qiskit-aer<0.18,>=0.13.1; extra == "qiskit"
|
|
249
239
|
|
|
250
240
|
IQM Client
|
|
@@ -349,7 +349,7 @@ In this subsection we demonstrate how to run them on an IQM quantum computer.
|
|
|
349
349
|
|
|
350
350
|
Cirq on IQM provides :class:`.IQMSampler`, a subclass of :class:`cirq.work.Sampler`, which is used
|
|
351
351
|
to execute quantum circuits and decompose/route them for the architecture of the quantum computer.
|
|
352
|
-
Once you have access to an IQM
|
|
352
|
+
Once you have access to an IQM Server you can create an :class:`.IQMSampler` instance and use its
|
|
353
353
|
:meth:`~.IQMSampler.run` method to send a circuit for execution and retrieve the results:
|
|
354
354
|
|
|
355
355
|
.. code-block:: python
|
|
@@ -358,7 +358,7 @@ Once you have access to an IQM server you can create an :class:`.IQMSampler` ins
|
|
|
358
358
|
|
|
359
359
|
# circuit = ...
|
|
360
360
|
|
|
361
|
-
sampler = IQMSampler(iqm_server_url)
|
|
361
|
+
sampler = IQMSampler(iqm_server_url, quantum_computer=quantum_computer)
|
|
362
362
|
routed_circuit, _, _ = sampler.device.route_circuit(circuit)
|
|
363
363
|
decomposed_circuit = sampler.device.decompose_circuit(routed_circuit)
|
|
364
364
|
result = sampler.run(decomposed_circuit, repetitions=10)
|
|
@@ -366,7 +366,9 @@ Once you have access to an IQM server you can create an :class:`.IQMSampler` ins
|
|
|
366
366
|
|
|
367
367
|
|
|
368
368
|
Note that the code snippet above assumes that you have set the variable ``iqm_server_url`` to the URL
|
|
369
|
-
of the IQM
|
|
369
|
+
of the IQM Server, and ``quantum_computer`` to the name of the quantum computer to use, if the IQM Server
|
|
370
|
+
has several. Leave it to ``None`` to use the default (or only) quantum computer of the server.
|
|
371
|
+
Additionally, you can pass IQM backend specific options to the :class:`.IQMSampler` class.
|
|
370
372
|
The below table summarises the currently available options:
|
|
371
373
|
|
|
372
374
|
|
|
@@ -381,7 +383,7 @@ The below table summarises the currently available options:
|
|
|
381
383
|
* - :attr:`calibration_set_id`
|
|
382
384
|
- :class:`uuid.UUID`
|
|
383
385
|
- "f7d9642e-b0ca-4f2d-af2a-30195bd7a76d"
|
|
384
|
-
- Indicates the calibration set to use. Defaults to ``None``, which means the IQM
|
|
386
|
+
- Indicates the calibration set to use. Defaults to ``None``, which means the IQM Server will use the
|
|
385
387
|
current default calibration set automatically.
|
|
386
388
|
* - :attr:`compiler_options`
|
|
387
389
|
- :class:`~iqm.iqm_client.models.CircuitCompilationOptions`
|
|
@@ -31,7 +31,7 @@ things are set up correctly.
|
|
|
31
31
|
(Save Page As...)
|
|
32
32
|
5. Install Qiskit on IQM as instructed below.
|
|
33
33
|
6. Run the Jupyter notebook (or run
|
|
34
|
-
``python bell_measure.py --url https://<IQM
|
|
34
|
+
``python bell_measure.py --url https://<IQM Server URL>``
|
|
35
35
|
if you decided to go for the Python script).
|
|
36
36
|
7. If you're connecting to a real quantum computer, the output should show almost half of the
|
|
37
37
|
measurements resulting in '00000' and almost half in '11111' - if this is the case, things are
|
|
@@ -115,7 +115,8 @@ Let's consider the following quantum circuit which prepares and measures a GHZ s
|
|
|
115
115
|
|
|
116
116
|
|
|
117
117
|
To run this circuit on an IQM quantum computer you need to initialize an :class:`.IQMProvider`
|
|
118
|
-
instance with the IQM
|
|
118
|
+
instance with the IQM Server URL (and possibly a quantum computer name, if there are several),
|
|
119
|
+
use it to retrieve an :class:`.IQMBackend` instance representing
|
|
119
120
|
the quantum computer, and use Qiskit's :func:`~qiskit.compiler.transpile` function
|
|
120
121
|
followed by :meth:`.IQMBackend.run` as usual. ``shots`` denotes the number of times the quantum
|
|
121
122
|
circuit(s) are sampled:
|
|
@@ -126,7 +127,8 @@ circuit(s) are sampled:
|
|
|
126
127
|
from iqm.qiskit_iqm import IQMProvider
|
|
127
128
|
|
|
128
129
|
iqm_server_url = "https://<IQM SERVER>" # Replace this with the correct URL
|
|
129
|
-
|
|
130
|
+
quantum_computer = "<NAME>"
|
|
131
|
+
provider = IQMProvider(iqm_server_url, quantum_computer=quantum_computer)
|
|
130
132
|
backend = provider.get_backend()
|
|
131
133
|
|
|
132
134
|
transpiled_circuit = transpile(circuit, backend=backend)
|
|
@@ -151,8 +153,7 @@ circuit(s) are sampled:
|
|
|
151
153
|
As of ``iqm-client >= 30.1.0``, structured quality metrics and calibration data are available to
|
|
152
154
|
``IQMTarget`` for improved transpilation. To import the latest valid quality metric data corresponding
|
|
153
155
|
to the default calibration set into ``IQMTarget``, set ``use_metrics`` to ``True`` when initializing the
|
|
154
|
-
class.
|
|
155
|
-
of ``use_metrics`` of ``False``.
|
|
156
|
+
class.
|
|
156
157
|
|
|
157
158
|
You can optionally provide IQMBackend specific options as additional keyword arguments to
|
|
158
159
|
:meth:`.IQMBackend.run`, documented at :meth:`.IQMBackend.create_run_request`.
|
|
@@ -189,48 +190,42 @@ The results of a job that was executed on the IQM quantum computer, represented
|
|
|
189
190
|
print(result.get_counts())
|
|
190
191
|
print(result.get_memory())
|
|
191
192
|
|
|
192
|
-
The result comes with some metadata, such as the
|
|
193
|
-
produced it
|
|
194
|
-
|
|
193
|
+
The result comes with some metadata, such as the contents of the request that
|
|
194
|
+
produced it. The executed circuit batch (in the native IQM format) can be found in ``result.circuits``,
|
|
195
|
+
and various execution parameters can be found in ``result.parameters``:
|
|
195
196
|
|
|
196
197
|
.. code-block:: python
|
|
197
198
|
|
|
198
|
-
print(result.
|
|
199
|
-
print(result.
|
|
199
|
+
print(result.parameters.shots)
|
|
200
|
+
print(result.parameters.calibration_set_id)
|
|
200
201
|
|
|
201
202
|
::
|
|
202
203
|
|
|
203
|
-
|
|
204
|
-
SingleQubitMapping(logical_name='0', physical_name='QB1'),
|
|
205
|
-
SingleQubitMapping(logical_name='1', physical_name='QB2'),
|
|
206
|
-
SingleQubitMapping(logical_name='2', physical_name='QB3')
|
|
207
|
-
]
|
|
204
|
+
1000
|
|
208
205
|
1320eae6-f4e2-424d-b299-ef82d556d2c3
|
|
209
206
|
|
|
210
207
|
Another piece of useful metadata are the timestamps of the various steps of processing the job. The
|
|
211
|
-
timestamps are stored in the
|
|
208
|
+
timestamps are stored in the list ``result.timeline``. The actual job processing has three main steps,
|
|
212
209
|
|
|
213
|
-
* ``
|
|
214
|
-
* ``
|
|
215
|
-
* ``
|
|
210
|
+
* ``compilation`` where the circuits are converted to instruction schedules,
|
|
211
|
+
* ``execution`` where the instruction schedules are executed and the measurement results are returned, and
|
|
212
|
+
* ``post_processing`` where the results are converted to the format expected by the client.
|
|
216
213
|
|
|
217
|
-
The
|
|
218
|
-
For example, the timestamp of starting the circuit compilation is stored with
|
|
219
|
-
In the same way the other steps have their own timestamps with
|
|
220
|
-
``
|
|
221
|
-
``
|
|
214
|
+
The list contains a timestamp for the start and end of each step.
|
|
215
|
+
For example, the timestamp of starting the circuit compilation is stored with the status ``compilation_started``.
|
|
216
|
+
In the same way the other steps have their own timestamps with statuses consisting of the step name and a ``_started``
|
|
217
|
+
or ``_ended`` suffix. In addition to processing step timestamps, there are also timestamps for the job itself,
|
|
218
|
+
``created`` for when the job request was accepted by the server and ``completed`` for when the job processing
|
|
222
219
|
was finished.
|
|
223
220
|
|
|
224
221
|
If the processing of the job is terminated before it is complete, for example due to an error, the timestamps of
|
|
225
|
-
processing steps that were not taken are not present
|
|
222
|
+
processing steps that were not taken are not present.
|
|
226
223
|
|
|
227
224
|
For example:
|
|
228
225
|
|
|
229
226
|
.. code-block:: python
|
|
230
227
|
|
|
231
|
-
print(result.
|
|
232
|
-
print(result.timestamps['compile_start'])
|
|
233
|
-
print(result.timestamps['execution_end'])
|
|
228
|
+
print(result.timeline)
|
|
234
229
|
|
|
235
230
|
|
|
236
231
|
Backend properties
|
|
@@ -279,11 +274,11 @@ support currently has several limitations:
|
|
|
279
274
|
apply the gate if the bit is 1, and apply an identity gate if the bit is 0.
|
|
280
275
|
* The availability of the controlled gates depends on the instrumentation of the quantum computer.
|
|
281
276
|
|
|
282
|
-
The classical control can be applied on a circuit instruction using :meth:`~qiskit.circuit.
|
|
277
|
+
The classical control can be applied on a circuit instruction using :meth:`~qiskit.circuit.QuantumCircuit.if_test`:
|
|
283
278
|
|
|
284
279
|
.. code-block:: python
|
|
285
280
|
|
|
286
|
-
from qiskit import QuantumCircuit
|
|
281
|
+
from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister
|
|
287
282
|
|
|
288
283
|
qr = QuantumRegister(2, 'q')
|
|
289
284
|
cr = ClassicalRegister(1, 'c')
|
|
@@ -291,26 +286,27 @@ The classical control can be applied on a circuit instruction using :meth:`~qisk
|
|
|
291
286
|
|
|
292
287
|
circuit.h(0)
|
|
293
288
|
circuit.measure(0, cr[0])
|
|
294
|
-
circuit.
|
|
289
|
+
with circuit.if_test((cr[0], 1)):
|
|
290
|
+
circuit.x(1) # apply X gate on qubit 1 if cr[0] is 1
|
|
295
291
|
circuit.measure_all()
|
|
296
292
|
|
|
297
293
|
print(circuit.draw(output='text'))
|
|
298
294
|
|
|
299
295
|
::
|
|
300
296
|
|
|
301
|
-
┌───┐┌─┐
|
|
302
|
-
q_0: ┤ H ├┤M
|
|
303
|
-
└───┘└╥┘
|
|
304
|
-
q_1:
|
|
305
|
-
║
|
|
306
|
-
║
|
|
307
|
-
c: 1/══════╩═╡ 0x1
|
|
308
|
-
0
|
|
309
|
-
meas: 2
|
|
310
|
-
|
|
297
|
+
┌───┐┌─┐ ░ ┌─┐
|
|
298
|
+
q_0: ┤ H ├┤M├───────────────────────────░─┤M├───
|
|
299
|
+
└───┘└╥┘ ┌────── ┌───┐ ───────┐ ░ └╥┘┌─┐
|
|
300
|
+
q_1: ──────╫───┤ If-0 ─┤ X ├ End-0 ├──░──╫─┤M├
|
|
301
|
+
║ └──╥─── └───┘ ───────┘ ░ ║ └╥┘
|
|
302
|
+
║ ┌────╨────┐ ║ ║
|
|
303
|
+
c: 1/══════╩═╡ c_0=0x1 ╞═══════════════════╬══╬═
|
|
304
|
+
0 └─────────┘ ║ ║
|
|
305
|
+
meas: 2/══════════════════════════════════════╩══╩═
|
|
306
|
+
0 1
|
|
311
307
|
|
|
312
308
|
|
|
313
|
-
The first measurement operation stores its result in the
|
|
309
|
+
The first measurement operation stores its result in the classical register ``c``. If the
|
|
314
310
|
result is 1, the ``X`` gate will be applied. If it is zero, an identity gate of corresponding
|
|
315
311
|
duration is applied instead.
|
|
316
312
|
|
|
@@ -319,9 +315,7 @@ between the '00 0' and '11 1' bins of the histogram (even though the state itsel
|
|
|
319
315
|
|
|
320
316
|
.. note::
|
|
321
317
|
|
|
322
|
-
|
|
323
|
-
in a 1-bit classical register, ``c`` in the above example.
|
|
324
|
-
|
|
318
|
+
``if_test`` blocks cannot be nested.
|
|
325
319
|
|
|
326
320
|
Resetting qubits
|
|
327
321
|
~~~~~~~~~~~~~~~~
|
|
@@ -454,7 +448,7 @@ Starting from the :ref:`GHZ circuit <GHZ_circuit>` we created above:
|
|
|
454
448
|
from qiskit.compiler import transpile
|
|
455
449
|
from iqm.qiskit_iqm import IQMProvider
|
|
456
450
|
|
|
457
|
-
resonator_backend = IQMProvider("https://
|
|
451
|
+
resonator_backend = IQMProvider("https://resonance.meetiqm.com", quantum_computer="sirius").get_backend()
|
|
458
452
|
transpiled_circuit = transpile(circuit, resonator_backend)
|
|
459
453
|
|
|
460
454
|
print(transpiled_circuit.draw(output='text', idle_wires=False))
|
|
@@ -706,17 +700,16 @@ a copy of the IQMFakeBackend instance with an updated error profile:
|
|
|
706
700
|
Running a quantum circuit on a facade backend
|
|
707
701
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
708
702
|
|
|
709
|
-
Circuits can be executed against a *mock environment*: an IQM
|
|
703
|
+
Circuits can be executed against a *mock environment*: an IQM Server that has no real quantum computer hardware.
|
|
710
704
|
Results from such executions are just random bits. This may be useful when developing and testing software integrations.
|
|
711
705
|
|
|
712
706
|
.. note::
|
|
713
707
|
|
|
714
708
|
IQM Resonance typically provides a mock environment for each real quantum computer it has.
|
|
715
|
-
For example, the
|
|
716
|
-
|
|
717
|
-
whereas https://cocos.resonance.meetiqm.com/garnet:mock refers to the corresponding mock environment.
|
|
709
|
+
For example, the name ``"garnet"`` refers to a real quantum computer named Garnet, whereas
|
|
710
|
+
``"garnet:mock"`` refers to the corresponding mock environment.
|
|
718
711
|
|
|
719
|
-
On-premises users should ask their admin whether a mock environment is available, and which IQM
|
|
712
|
+
On-premises users should ask their admin whether a mock environment is available, and which IQM Server
|
|
720
713
|
URL to use.
|
|
721
714
|
|
|
722
715
|
Qiskit on IQM contains :class:`.IQMFacadeBackend`, which allows to combine a mock remote execution with a local
|
|
@@ -734,7 +727,7 @@ static quantum architecture (i.e. names of qubits, their connectivity, and the n
|
|
|
734
727
|
|
|
735
728
|
.. important::
|
|
736
729
|
|
|
737
|
-
When using a facade backend, the IQM
|
|
730
|
+
When using a facade backend, the IQM Server URL of :class:`IQMProvider` should always point to a mock environment
|
|
738
731
|
rather than a real quantum computer, as the execution results from the server will be discarded and replaced by
|
|
739
732
|
a locally simulated result generated by Qiskit Aer. If you use a real quantum computer with a facade backend,
|
|
740
733
|
you will just waste your credits and/or computation time.
|
|
@@ -750,8 +743,9 @@ static quantum architecture (i.e. names of qubits, their connectivity, and the n
|
|
|
750
743
|
circuit.cx(0, 1)
|
|
751
744
|
circuit.measure_all()
|
|
752
745
|
|
|
753
|
-
iqm_server_url = "https://
|
|
754
|
-
|
|
746
|
+
iqm_server_url = "https://resonance.meetiqm.com"
|
|
747
|
+
quantum_computer = "garnet:mock" # Replace this with the correct mock env name
|
|
748
|
+
provider = IQMProvider(iqm_server_url, quantum_computer=quantum_computer)
|
|
755
749
|
backend = provider.get_backend('facade_garnet')
|
|
756
750
|
transpiled_circuit = transpile(circuit, backend=backend)
|
|
757
751
|
job = backend.run(transpiled_circuit, shots=1000)
|
|
@@ -760,7 +754,7 @@ static quantum architecture (i.e. names of qubits, their connectivity, and the n
|
|
|
760
754
|
.. note::
|
|
761
755
|
|
|
762
756
|
When a classical register is added to the circuit, Qiskit fills it with classical bits of value 0 by default. If the
|
|
763
|
-
register is not used later, and the circuit is submitted to the IQM
|
|
764
|
-
0-filled bits. To make sure the facade backend returns results in the same format as a real IQM
|
|
757
|
+
register is not used later, and the circuit is submitted to the IQM Server, the results will not contain those
|
|
758
|
+
0-filled bits. To make sure the facade backend returns results in the same format as a real IQM Server,
|
|
765
759
|
:meth:`.IQMFacadeBackend.run` checks for the presence of unused classical registers, and fails with an error if there
|
|
766
760
|
are any.
|