iqm-client 31.8.0__tar.gz → 32.1.1__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-31.8.0 → iqm_client-32.1.1}/CHANGELOG.rst +25 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/INTEGRATION_GUIDE.rst +3 -16
- {iqm_client-31.8.0 → iqm_client-32.1.1}/PKG-INFO +1 -1
- {iqm_client-31.8.0 → iqm_client-32.1.1}/docs/index.rst +0 -3
- {iqm_client-31.8.0 → iqm_client-32.1.1}/docs/user_guide_cirq.rst +2 -13
- {iqm_client-31.8.0 → iqm_client-32.1.1}/docs/user_guide_qiskit.rst +30 -62
- {iqm_client-31.8.0 → iqm_client-32.1.1}/src/iqm/iqm_client/authentication.py +0 -3
- iqm_client-31.8.0/src/iqm/qiskit_iqm/examples/resonance_example.py → iqm_client-32.1.1/src/iqm/qiskit_iqm/examples/bell_measure.py +23 -26
- {iqm_client-31.8.0 → iqm_client-32.1.1}/src/iqm/qiskit_iqm/iqm_naive_move_pass.py +1 -1
- {iqm_client-31.8.0 → iqm_client-32.1.1}/src/iqm/qiskit_iqm/iqm_target.py +8 -2
- iqm_client-32.1.1/src/iqm/qiskit_iqm/iqm_transpilation.py +384 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/src/iqm/qiskit_iqm/qiskit_to_iqm.py +110 -38
- {iqm_client-31.8.0 → iqm_client-32.1.1}/src/iqm/qiskit_iqm/transpiler_plugins.py +11 -8
- {iqm_client-31.8.0 → iqm_client-32.1.1}/src/iqm_client.egg-info/PKG-INFO +1 -1
- {iqm_client-31.8.0 → iqm_client-32.1.1}/src/iqm_client.egg-info/SOURCES.txt +0 -7
- iqm_client-32.1.1/version.txt +1 -0
- iqm_client-31.8.0/docs/user_guide_cli.rst +0 -137
- iqm_client-31.8.0/src/iqm/iqm_client/cli/__init__.py +0 -14
- iqm_client-31.8.0/src/iqm/iqm_client/cli/auth.py +0 -168
- iqm_client-31.8.0/src/iqm/iqm_client/cli/cli.py +0 -798
- iqm_client-31.8.0/src/iqm/iqm_client/cli/models.py +0 -40
- iqm_client-31.8.0/src/iqm/iqm_client/cli/token_manager.py +0 -196
- iqm_client-31.8.0/src/iqm/qiskit_iqm/examples/bell_measure.py +0 -55
- iqm_client-31.8.0/src/iqm/qiskit_iqm/iqm_transpilation.py +0 -191
- iqm_client-31.8.0/version.txt +0 -1
- {iqm_client-31.8.0 → iqm_client-32.1.1}/AUTHORS.rst +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/CHANGELOG_cirq-iqm.rst +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/CHANGELOG_cortex-cli.rst +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/CHANGELOG_qiskit-iqm.rst +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/LICENSE.txt +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/MANIFEST.in +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/README.rst +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/docbuild +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/docs/API.rst +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/docs/_static/images/favicon.ico +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/docs/_static/images/logo.png +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/docs/_templates/autosummary-class-template.rst +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/docs/_templates/autosummary-module-template.rst +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/docs/authors.rst +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/docs/changelog.rst +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/docs/conf.py +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/docs/integration_guide.rst +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/docs/license.rst +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/docs/readme.rst +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/pyproject.toml +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/pytest.ini +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/requirements/base.in +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/requirements/base.in.internal +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/requirements/base.txt +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/requirements/cirq.in +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/requirements/cirq.txt +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/requirements/cli.in +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/requirements/cli.txt +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/requirements/qiskit.in +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/requirements/qiskit.txt +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/setup.cfg +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/setup.py +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/src/iqm/cirq_iqm/__init__.py +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/src/iqm/cirq_iqm/devices/__init__.py +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/src/iqm/cirq_iqm/devices/adonis.py +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/src/iqm/cirq_iqm/devices/aphrodite.py +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/src/iqm/cirq_iqm/devices/apollo.py +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/src/iqm/cirq_iqm/devices/iqm_device.py +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/src/iqm/cirq_iqm/devices/iqm_device_metadata.py +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/src/iqm/cirq_iqm/examples/demo_adonis.py +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/src/iqm/cirq_iqm/examples/demo_apollo.py +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/src/iqm/cirq_iqm/examples/demo_common.py +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/src/iqm/cirq_iqm/examples/demo_iqm_execution.py +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/src/iqm/cirq_iqm/examples/usage.ipynb +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/src/iqm/cirq_iqm/extended_qasm_parser.py +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/src/iqm/cirq_iqm/iqm_gates.py +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/src/iqm/cirq_iqm/iqm_sampler.py +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/src/iqm/cirq_iqm/optimizers.py +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/src/iqm/cirq_iqm/py.typed +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/src/iqm/cirq_iqm/serialize.py +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/src/iqm/cirq_iqm/transpiler.py +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/src/iqm/iqm_client/__init__.py +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/src/iqm/iqm_client/api.py +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/src/iqm/iqm_client/errors.py +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/src/iqm/iqm_client/iqm_client.py +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/src/iqm/iqm_client/models.py +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/src/iqm/iqm_client/py.typed +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/src/iqm/iqm_client/transpile.py +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/src/iqm/iqm_client/util.py +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/src/iqm/iqm_client/validation.py +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/src/iqm/qiskit_iqm/__init__.py +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/src/iqm/qiskit_iqm/examples/__init__.py +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/src/iqm/qiskit_iqm/examples/transpile_example.py +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/src/iqm/qiskit_iqm/fake_backends/__init__.py +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/src/iqm/qiskit_iqm/fake_backends/fake_adonis.py +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/src/iqm/qiskit_iqm/fake_backends/fake_aphrodite.py +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/src/iqm/qiskit_iqm/fake_backends/fake_apollo.py +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/src/iqm/qiskit_iqm/fake_backends/fake_deneb.py +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/src/iqm/qiskit_iqm/fake_backends/fake_garnet.py +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/src/iqm/qiskit_iqm/fake_backends/iqm_fake_backend.py +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/src/iqm/qiskit_iqm/iqm_backend.py +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/src/iqm/qiskit_iqm/iqm_circuit.py +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/src/iqm/qiskit_iqm/iqm_circuit_validation.py +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/src/iqm/qiskit_iqm/iqm_job.py +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/src/iqm/qiskit_iqm/iqm_move_layout.py +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/src/iqm/qiskit_iqm/iqm_provider.py +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/src/iqm/qiskit_iqm/move_gate.py +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/src/iqm/qiskit_iqm/py.typed +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/src/iqm_client.egg-info/dependency_links.txt +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/src/iqm_client.egg-info/entry_points.txt +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/src/iqm_client.egg-info/requires.txt +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/src/iqm_client.egg-info/top_level.txt +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/test +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/tests/__init__.py +0 -0
- {iqm_client-31.8.0 → iqm_client-32.1.1}/tests/conftest.py +0 -0
|
@@ -2,6 +2,31 @@
|
|
|
2
2
|
Changelog
|
|
3
3
|
=========
|
|
4
4
|
|
|
5
|
+
Version 32.1.1 (2025-10-27)
|
|
6
|
+
===========================
|
|
7
|
+
|
|
8
|
+
- Bump version for 4.3.1 release. No functional changes.
|
|
9
|
+
|
|
10
|
+
Version 32.1.0 (2025-10-13)
|
|
11
|
+
===========================
|
|
12
|
+
|
|
13
|
+
Features
|
|
14
|
+
--------
|
|
15
|
+
|
|
16
|
+
- Add support for the ``with circuit.if_test()`` construction for classical control in Qiskit :issue:`SW-1724`.
|
|
17
|
+
- Deprecate the ``c_if`` method in favor of the new ``if_test`` method for classical control in Qiskit :issue:`SW-1724`.
|
|
18
|
+
- Bugfix: Fixed the transpiler bug causing classical conditionals to be ignored in certain cases :issue:`SW-1856`.
|
|
19
|
+
- 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'])``.
|
|
20
|
+
|
|
21
|
+
Version 32.0.0 (2025-10-09)
|
|
22
|
+
===========================
|
|
23
|
+
|
|
24
|
+
Breaking changes
|
|
25
|
+
----------------
|
|
26
|
+
|
|
27
|
+
- Remove the Cortex CLI authentication utility. See the updated user guides.
|
|
28
|
+
- Remove :mod:`iqm.qiskit_iqm.examples.resonance_example`.
|
|
29
|
+
|
|
5
30
|
Version 31.8.0 (2025-10-06)
|
|
6
31
|
===========================
|
|
7
32
|
|
|
@@ -100,22 +100,9 @@ Authentication
|
|
|
100
100
|
--------------
|
|
101
101
|
|
|
102
102
|
IQM uses bearer token authentication to manage access to quantum computers.
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
1. The recommended way is to use :ref:`IQM Client CLI <User guide CLI>`
|
|
107
|
-
to manage the authentication tokens and store them into a file. IQM client can then read
|
|
108
|
-
the token from the file and use it for authentication. The file path can be provided to
|
|
109
|
-
IQM client in environment variable :envvar:`IQM_TOKENS_FILE`.
|
|
110
|
-
Alternatively, the tokens file path can be provided as argument ``tokens_file`` to
|
|
111
|
-
:class:`.IQMClient` constructor.
|
|
112
|
-
|
|
113
|
-
2. It is also possible to use plaintext token obtained from a server dashboard. These
|
|
114
|
-
tokens may have longer lifespan than access tokens generated by IQM Client CLI, and thus
|
|
115
|
-
IQM client won't attempt to refresh them. The generated token can be provided to IQM
|
|
116
|
-
client in environment variable :envvar:`IQM_TOKEN`.
|
|
117
|
-
Alternatively, the token can be provided as argument ``token`` to :class:`.IQMClient`
|
|
118
|
-
constructor.
|
|
103
|
+
Get your personal token from the web dashboard. The generated token can be provided to IQM
|
|
104
|
+
client via an environment variable :envvar:`IQM_TOKEN`.
|
|
105
|
+
Alternatively, the token can be provided as argument ``token`` to :class:`.IQMClient` constructor.
|
|
119
106
|
|
|
120
107
|
Circuit transpilation
|
|
121
108
|
---------------------
|
|
@@ -10,8 +10,6 @@ Includes `Qiskit <https://qiskit.org/>`_ and `Cirq <https://quantumai.google/cir
|
|
|
10
10
|
`IQM's <https://www.meetiqm.com>`_ quantum computers. See user guides for :ref:`Qiskit <User guide Qiskit>` and
|
|
11
11
|
:ref:`Cirq <User guide Cirq>` for introductions on how to install and use the adapters.
|
|
12
12
|
|
|
13
|
-
Also includes a :ref:`CLI utility <User guide CLI>` for managing user authentication when using IQM quantum computers.
|
|
14
|
-
|
|
15
13
|
Contents
|
|
16
14
|
========
|
|
17
15
|
|
|
@@ -21,7 +19,6 @@ Contents
|
|
|
21
19
|
readme
|
|
22
20
|
API
|
|
23
21
|
integration_guide
|
|
24
|
-
user_guide_cli
|
|
25
22
|
user_guide_qiskit
|
|
26
23
|
user_guide_cirq
|
|
27
24
|
license
|
|
@@ -435,23 +435,12 @@ as explained in the :ref:`routing` section above.
|
|
|
435
435
|
Authentication
|
|
436
436
|
^^^^^^^^^^^^^^
|
|
437
437
|
|
|
438
|
-
|
|
439
|
-
"""""""""""""
|
|
438
|
+
There are two options to authenticate:
|
|
440
439
|
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
1. Set the :envvar:`IQM_TOKEN` environment variable with the API token obtained from the Resonance dashboard.
|
|
440
|
+
1. Set the :envvar:`IQM_TOKEN` environment variable with the API token obtained from the web dashboard.
|
|
444
441
|
2. Pass the ``token`` parameter to :class:`.IQMSampler`. This will be forwarded to
|
|
445
442
|
:class:`~iqm.iqm_client.iqm_client.IQMClient`.
|
|
446
443
|
|
|
447
|
-
On-premises devices
|
|
448
|
-
"""""""""""""""""""
|
|
449
|
-
|
|
450
|
-
If the IQM server you are connecting to requires authentication, you may use
|
|
451
|
-
:ref:`IQM Client CLI <User guide CLI>` to retrieve and automatically refresh access tokens,
|
|
452
|
-
then set the :envvar:`IQM_TOKENS_FILE` environment variable, as instructed, to point to the tokens file.
|
|
453
|
-
See IQM Client CLI's `documentation <https://docs.meetiqm.com/iqm-client/user_guide_cli.html>`__ for details.
|
|
454
|
-
|
|
455
444
|
Batch execution
|
|
456
445
|
^^^^^^^^^^^^^^^
|
|
457
446
|
|
|
@@ -16,26 +16,22 @@ Hello, world!
|
|
|
16
16
|
-------------
|
|
17
17
|
|
|
18
18
|
Here's a quick and easy way to run a small computation on an IQM quantum computer to check that
|
|
19
|
-
things are set up correctly
|
|
20
|
-
through the IQM cloud service Resonance, or using an on-premises quantum computer.
|
|
19
|
+
things are set up correctly.
|
|
21
20
|
|
|
22
|
-
IQM Resonance
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
1. Login to `IQM Resonance <https://resonance.meetiqm.com>`_ with your credentials.
|
|
26
|
-
2. Upon your first visit to IQM Resonance, you can generate your unique, non-recoverable API token
|
|
21
|
+
1. Login to the web dashboard with your credentials. If you're using the IQM Resonance cloud service, go to
|
|
22
|
+
`IQM Resonance <https://resonance.meetiqm.com>`_.
|
|
23
|
+
2. Upon your first visit, you can generate your unique, non-recoverable API token
|
|
27
24
|
directly from the Dashboard page by selecting ``Generate token``. It's important to copy the token
|
|
28
25
|
immediately from the window, as you won't be able to do so once the window is closed. If you lose
|
|
29
26
|
your token, you have the option to regenerate it at any time. However, be aware that regenerating
|
|
30
27
|
your API token will invalidate any previously generated token.
|
|
31
|
-
3.
|
|
32
|
-
|
|
28
|
+
3. Store your API token in the environment variable :envvar:`IQM_TOKEN`.
|
|
29
|
+
4. Download one of the demo notebooks from `IQM Academy <https://www.iqmacademy.com/tutorials/>`_ or the
|
|
30
|
+
`bell_measure.py example file <https://raw.githubusercontent.com/iqm-finland/sdk/refs/heads/main/iqm_client/src/iqm/qiskit_iqm/examples/bell_measure.py>`_
|
|
33
31
|
(Save Page As...)
|
|
34
|
-
|
|
35
|
-
5. Add your API token to the example (either as the parameter ``token`` to the :class:`.IQMProvider`
|
|
36
|
-
constructor, or by setting the environment variable :envvar:`IQM_TOKEN`)
|
|
32
|
+
5. Install Qiskit on IQM as instructed below.
|
|
37
33
|
6. Run the Jupyter notebook (or run
|
|
38
|
-
``python
|
|
34
|
+
``python bell_measure.py --url https://<IQM server URL>``
|
|
39
35
|
if you decided to go for the Python script).
|
|
40
36
|
7. If you're connecting to a real quantum computer, the output should show almost half of the
|
|
41
37
|
measurements resulting in '00000' and almost half in '11111' - if this is the case, things are
|
|
@@ -45,20 +41,6 @@ You can find a video guide on how to set things up `here <https://www.iqmacademy
|
|
|
45
41
|
More ready-to-run examples can also be found at `IQM Academy <https://www.iqmacademy.com/tutorials/>`_.
|
|
46
42
|
|
|
47
43
|
|
|
48
|
-
On-premises device
|
|
49
|
-
~~~~~~~~~~~~~~~~~~
|
|
50
|
-
|
|
51
|
-
1. Download the `bell_measure.py example file <https://raw.githubusercontent.com/iqm-finland/sdk/refs/heads/main/iqm_client/src/iqm/qiskit_iqm/examples/bell_measure.py>`_ (Save Page As...).
|
|
52
|
-
2. Install Qiskit on IQM as instructed below.
|
|
53
|
-
3. Install IQM Client CLI and log in as instructed in the
|
|
54
|
-
`documentation <https://docs.meetiqm.com/iqm-client/user_guide_cli.html#installing-iqm-client-cli>`__
|
|
55
|
-
4. Set the environment variable as instructed by IQM Client CLI after logging in.
|
|
56
|
-
5. Run ``$ python bell_measure.py --url https://<YOUR IQM SERVER>`` - replace the example URL with the correct one.
|
|
57
|
-
6. If you're connecting to a real quantum computer, the output should show almost half of the
|
|
58
|
-
measurements resulting in '00' and almost half in '11' - if this is the case, things are set up
|
|
59
|
-
correctly!
|
|
60
|
-
|
|
61
|
-
|
|
62
44
|
Installation
|
|
63
45
|
------------
|
|
64
46
|
|
|
@@ -86,25 +68,13 @@ After installation, Qiskit on IQM can be imported in your Python code as follows
|
|
|
86
68
|
Authentication
|
|
87
69
|
--------------
|
|
88
70
|
|
|
89
|
-
|
|
90
|
-
~~~~~~~~~~~~~
|
|
91
|
-
|
|
92
|
-
If you are using IQM Resonance, you have two options to authenticate:
|
|
71
|
+
There are two options to authenticate:
|
|
93
72
|
|
|
94
|
-
1. Set the :envvar:`IQM_TOKEN` environment variable to the API token obtained from the
|
|
73
|
+
1. Set the :envvar:`IQM_TOKEN` environment variable to the API token obtained from the web dashboard.
|
|
95
74
|
2. Pass the ``token`` parameter to :class:`.IQMProvider`. This will be forwarded to
|
|
96
|
-
:class:`~iqm.iqm_client.iqm_client.IQMClient`. For an example, see
|
|
97
|
-
<https://raw.githubusercontent.com/iqm-finland/sdk/refs/heads/main/iqm_client/src/iqm/qiskit_iqm/examples/
|
|
75
|
+
:class:`~iqm.iqm_client.iqm_client.IQMClient`. For an example, see
|
|
76
|
+
`bell_measure.py <https://raw.githubusercontent.com/iqm-finland/sdk/refs/heads/main/iqm_client/src/iqm/qiskit_iqm/examples/bell_measure.py>`_
|
|
98
77
|
|
|
99
|
-
On-premises devices
|
|
100
|
-
~~~~~~~~~~~~~~~~~~~
|
|
101
|
-
|
|
102
|
-
If the IQM server you are connecting to requires authentication, you may use
|
|
103
|
-
:ref:`IQM Client CLI <User guide CLI>` to retrieve and automatically refresh access tokens,
|
|
104
|
-
then set the :envvar:`IQM_TOKENS_FILE` environment variable, as instructed, to point to the tokens file.
|
|
105
|
-
See IQM Client CLI's `documentation <https://docs.meetiqm.com/iqm-client/user_guide_cli.html>`__ for details.
|
|
106
|
-
|
|
107
|
-
You may also authenticate yourself by setting the access token in the the :envvar:`IQM_TOKEN` variable
|
|
108
78
|
|
|
109
79
|
Running quantum circuits on an IQM quantum computer
|
|
110
80
|
---------------------------------------------------
|
|
@@ -180,10 +150,9 @@ circuit(s) are sampled:
|
|
|
180
150
|
|
|
181
151
|
As of ``iqm-client >= 30.1.0``, structured quality metrics and calibration data are available to
|
|
182
152
|
``IQMTarget`` for improved transpilation. To import the latest valid quality metric data corresponding
|
|
183
|
-
to the default calibration set into ``IQMTarget``, set ``use_metrics`` to ``True`` when initializing the
|
|
153
|
+
to the default calibration set into ``IQMTarget``, set ``use_metrics`` to ``True`` when initializing the
|
|
184
154
|
class. For Resonance users, this data is not yet available via the Resonance API, so use the default setting
|
|
185
155
|
of ``use_metrics`` of ``False``.
|
|
186
|
-
|
|
187
156
|
|
|
188
157
|
You can optionally provide IQMBackend specific options as additional keyword arguments to
|
|
189
158
|
:meth:`.IQMBackend.run`, documented at :meth:`.IQMBackend.create_run_request`.
|
|
@@ -310,11 +279,11 @@ support currently has several limitations:
|
|
|
310
279
|
apply the gate if the bit is 1, and apply an identity gate if the bit is 0.
|
|
311
280
|
* The availability of the controlled gates depends on the instrumentation of the quantum computer.
|
|
312
281
|
|
|
313
|
-
The classical control can be applied on a circuit instruction using :meth:`~qiskit.circuit.
|
|
282
|
+
The classical control can be applied on a circuit instruction using :meth:`~qiskit.circuit.QuantumCircuit.if_test`:
|
|
314
283
|
|
|
315
284
|
.. code-block:: python
|
|
316
285
|
|
|
317
|
-
from qiskit import QuantumCircuit
|
|
286
|
+
from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister
|
|
318
287
|
|
|
319
288
|
qr = QuantumRegister(2, 'q')
|
|
320
289
|
cr = ClassicalRegister(1, 'c')
|
|
@@ -322,26 +291,27 @@ The classical control can be applied on a circuit instruction using :meth:`~qisk
|
|
|
322
291
|
|
|
323
292
|
circuit.h(0)
|
|
324
293
|
circuit.measure(0, cr[0])
|
|
325
|
-
circuit.
|
|
294
|
+
with circuit.if_test((cr[0], 1)):
|
|
295
|
+
circuit.x(1) # apply X gate on qubit 1 if cr[0] is 1
|
|
326
296
|
circuit.measure_all()
|
|
327
297
|
|
|
328
298
|
print(circuit.draw(output='text'))
|
|
329
299
|
|
|
330
300
|
::
|
|
331
301
|
|
|
332
|
-
┌───┐┌─┐
|
|
333
|
-
q_0: ┤ H ├┤M
|
|
334
|
-
└───┘└╥┘
|
|
335
|
-
q_1:
|
|
336
|
-
║
|
|
337
|
-
║
|
|
338
|
-
c: 1/══════╩═╡ 0x1
|
|
339
|
-
0
|
|
340
|
-
meas: 2
|
|
341
|
-
|
|
302
|
+
┌───┐┌─┐ ░ ┌─┐
|
|
303
|
+
q_0: ┤ H ├┤M├───────────────────────────░─┤M├───
|
|
304
|
+
└───┘└╥┘ ┌────── ┌───┐ ───────┐ ░ └╥┘┌─┐
|
|
305
|
+
q_1: ──────╫───┤ If-0 ─┤ X ├ End-0 ├──░──╫─┤M├
|
|
306
|
+
║ └──╥─── └───┘ ───────┘ ░ ║ └╥┘
|
|
307
|
+
║ ┌────╨────┐ ║ ║
|
|
308
|
+
c: 1/══════╩═╡ c_0=0x1 ╞═══════════════════╬══╬═
|
|
309
|
+
0 └─────────┘ ║ ║
|
|
310
|
+
meas: 2/══════════════════════════════════════╩══╩═
|
|
311
|
+
0 1
|
|
342
312
|
|
|
343
313
|
|
|
344
|
-
The first measurement operation stores its result in the
|
|
314
|
+
The first measurement operation stores its result in the classical register ``c``. If the
|
|
345
315
|
result is 1, the ``X`` gate will be applied. If it is zero, an identity gate of corresponding
|
|
346
316
|
duration is applied instead.
|
|
347
317
|
|
|
@@ -350,9 +320,7 @@ between the '00 0' and '11 1' bins of the histogram (even though the state itsel
|
|
|
350
320
|
|
|
351
321
|
.. note::
|
|
352
322
|
|
|
353
|
-
|
|
354
|
-
in a 1-bit classical register, ``c`` in the above example.
|
|
355
|
-
|
|
323
|
+
``if_test`` blocks cannot be nested.
|
|
356
324
|
|
|
357
325
|
Resetting qubits
|
|
358
326
|
~~~~~~~~~~~~~~~~
|
|
@@ -22,9 +22,6 @@ from typing import Any
|
|
|
22
22
|
|
|
23
23
|
from iqm.iqm_client.errors import ClientAuthenticationError, ClientConfigurationError
|
|
24
24
|
|
|
25
|
-
AUTH_CLIENT_ID = "iqm_client"
|
|
26
|
-
AUTH_REALM = "cortex"
|
|
27
|
-
AUTH_REQUESTS_TIMEOUT = float(os.environ.get("IQM_CLIENT_REQUESTS_TIMEOUT", 60.0))
|
|
28
25
|
REFRESH_MARGIN_SECONDS = 60
|
|
29
26
|
|
|
30
27
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright
|
|
1
|
+
# Copyright 2023 Qiskit on IQM developers
|
|
2
2
|
#
|
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
# you may not use this file except in compliance with the License.
|
|
@@ -11,44 +11,45 @@
|
|
|
11
11
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
|
-
"""
|
|
15
|
-
|
|
14
|
+
"""An example on using Qiskit on IQM to run a simple quantum circuit on an IQM quantum computer.
|
|
15
|
+
|
|
16
16
|
See the Qiskit on IQM user guide for instructions:
|
|
17
17
|
https://docs.meetiqm.com/iqm-client/user_guide_qiskit.html
|
|
18
18
|
"""
|
|
19
19
|
|
|
20
20
|
import argparse
|
|
21
21
|
|
|
22
|
-
from iqm.qiskit_iqm import IQMProvider
|
|
22
|
+
from iqm.qiskit_iqm.iqm_provider import IQMProvider
|
|
23
23
|
from qiskit import QuantumCircuit, transpile
|
|
24
24
|
|
|
25
25
|
|
|
26
|
-
def
|
|
27
|
-
"""
|
|
26
|
+
def bell_measure(server_url: str, token: str | None = None, shots: int = 1000) -> dict[str, int]:
|
|
27
|
+
"""Execute a quantum circuit that prepares and measures a generalized Bell (aka GHZ) state.
|
|
28
28
|
|
|
29
29
|
Args:
|
|
30
|
-
server_url: URL of the IQM
|
|
31
|
-
|
|
30
|
+
server_url: URL of the IQM server used for execution
|
|
31
|
+
token: API token for authentication. If not given, uses :env:`IQM_TOKEN`.
|
|
32
|
+
shots: Requested number of shots.
|
|
32
33
|
|
|
33
34
|
Returns:
|
|
34
|
-
|
|
35
|
+
Mapping of bitstrings representing qubit measurement results to counts for each result.
|
|
35
36
|
|
|
36
37
|
"""
|
|
37
|
-
|
|
38
|
-
|
|
38
|
+
print(f"Executing a circuit on {server_url}")
|
|
39
39
|
# Initialize a backend without metrics as IQMClient._get_calibration_quality_metrics is not supported by resonance
|
|
40
|
-
backend = IQMProvider(server_url, token=
|
|
40
|
+
backend = IQMProvider(server_url, token=token).get_backend()
|
|
41
|
+
if backend.num_qubits < 2:
|
|
42
|
+
raise ValueError("We need two qubits for the Bell state.")
|
|
41
43
|
|
|
42
44
|
# Just to make sure that "get_static_quantum_architecture" method works
|
|
43
45
|
static_quantum_architecture = backend.client.get_static_quantum_architecture()
|
|
44
46
|
print(f"static_quantum_architecture={static_quantum_architecture}")
|
|
45
47
|
|
|
46
|
-
# Define a quantum circuit
|
|
47
|
-
|
|
48
|
-
qc = QuantumCircuit(
|
|
49
|
-
|
|
48
|
+
# Define a quantum circuit for a GHZ state
|
|
49
|
+
n_qubits = min(backend.num_qubits, 5) # use at most 5 qubits
|
|
50
|
+
qc = QuantumCircuit(n_qubits)
|
|
50
51
|
qc.h(0)
|
|
51
|
-
for qb in range(1,
|
|
52
|
+
for qb in range(1, n_qubits):
|
|
52
53
|
qc.cx(0, qb)
|
|
53
54
|
qc.barrier()
|
|
54
55
|
qc.measure_all()
|
|
@@ -58,26 +59,22 @@ def resonance_example(server_url: str, api_token: str | None) -> dict[str, int]:
|
|
|
58
59
|
print(qc_transpiled.draw(output="text"))
|
|
59
60
|
|
|
60
61
|
# Run the circuit
|
|
61
|
-
job = backend.run(qc_transpiled, shots=
|
|
62
|
+
job = backend.run(qc_transpiled, shots=shots)
|
|
62
63
|
return job.result().get_counts()
|
|
63
64
|
|
|
64
65
|
|
|
65
66
|
if __name__ == "__main__":
|
|
66
67
|
argparser = argparse.ArgumentParser()
|
|
67
68
|
argparser.add_argument(
|
|
68
|
-
"--url",
|
|
69
|
-
help="URL of the IQM Resonance QC",
|
|
70
|
-
# For example https://cocos.resonance.meetiqm.com/garnet
|
|
71
|
-
default="https://cocos.resonance.meetiqm.com/<RESONANCE QC NAME>",
|
|
69
|
+
"--url", required=True, help='IQM server URL, for example "https://cocos.resonance.meetiqm.com/garnet"'
|
|
72
70
|
)
|
|
73
71
|
argparser.add_argument(
|
|
74
72
|
"--token",
|
|
75
|
-
help="
|
|
73
|
+
help="API token for authentication",
|
|
76
74
|
# Provide the API token explicitly or set it as an environment variable
|
|
77
75
|
# following the https://docs.meetiqm.com/iqm-client/user_guide_qiskit.html#authentication
|
|
78
|
-
default="<INSERT YOUR TOKEN>",
|
|
79
76
|
)
|
|
80
77
|
|
|
81
78
|
args = argparser.parse_args()
|
|
82
|
-
|
|
83
|
-
print(
|
|
79
|
+
counts = bell_measure(args.url, args.token)
|
|
80
|
+
print(counts)
|
|
@@ -98,7 +98,7 @@ class IQMNaiveResonatorMoving(TransformationPass):
|
|
|
98
98
|
# Convert the circuit to the IQMClientCircuit format and run the transpiler.
|
|
99
99
|
iqm_circuit = IQMClientCircuit(
|
|
100
100
|
name="Transpiling Circuit",
|
|
101
|
-
instructions=tuple(serialize_instructions(circuit, self.idx_to_component)),
|
|
101
|
+
instructions=tuple(serialize_instructions(circuit, self.idx_to_component, overwrite_layout=layout)),
|
|
102
102
|
metadata=None,
|
|
103
103
|
)
|
|
104
104
|
try:
|
|
@@ -26,7 +26,7 @@ from iqm.iqm_client import (
|
|
|
26
26
|
ObservationFinder,
|
|
27
27
|
)
|
|
28
28
|
from iqm.qiskit_iqm.move_gate import MoveGate
|
|
29
|
-
from qiskit.circuit import Delay, Gate, Parameter, Reset
|
|
29
|
+
from qiskit.circuit import Delay, Gate, IfElseOp, Parameter, Reset
|
|
30
30
|
from qiskit.circuit.library import CZGate, IGate, Measure, RGate
|
|
31
31
|
from qiskit.providers import QubitProperties
|
|
32
32
|
from qiskit.transpiler import InstructionProperties, Target
|
|
@@ -44,6 +44,7 @@ _QISKIT_IQM_GATE_MAP: dict[str, Gate] = {
|
|
|
44
44
|
"cz": CZGate(),
|
|
45
45
|
"move": MoveGate(),
|
|
46
46
|
"id": IGate(),
|
|
47
|
+
"if_else": IfElseOp,
|
|
47
48
|
}
|
|
48
49
|
"""Maps IQM native operation names to corresponding Qiskit gate objects."""
|
|
49
50
|
|
|
@@ -126,8 +127,13 @@ class IQMTarget(Target):
|
|
|
126
127
|
if "prx" in op_loci:
|
|
127
128
|
add_gate("prx")
|
|
128
129
|
|
|
129
|
-
# HACK reset gate shares cc_prx loci for now, until reset is also in the DQA/metrics
|
|
130
130
|
if "cc_prx" in op_loci:
|
|
131
|
+
# IfElseOp is a global 'gate' so it's slightly different from the others.
|
|
132
|
+
self.add_instruction(
|
|
133
|
+
instruction=_QISKIT_IQM_GATE_MAP["if_else"],
|
|
134
|
+
name="if_else",
|
|
135
|
+
)
|
|
136
|
+
# HACK reset gate shares cc_prx loci for now, until reset is also in the DQA/metrics
|
|
131
137
|
self.add_instruction(
|
|
132
138
|
_QISKIT_IQM_GATE_MAP["reset"],
|
|
133
139
|
{self.locus_to_idx(locus): None for locus in op_loci["cc_prx"]},
|