iqm-pulla 9.0.0__tar.gz → 9.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.
Files changed (75) hide show
  1. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/CHANGELOG.rst +16 -0
  2. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/PKG-INFO +2 -2
  3. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/docs/Custom Gates and Implementations.ipynb +1 -1
  4. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/docs/Example - Executing QIR programs.ipynb +3 -17
  5. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/requirements/qiskit.txt +2 -2
  6. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/src/iqm/pulla/utils_qir.py +37 -8
  7. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/src/iqm/pulla/utils_qiskit.py +6 -2
  8. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/src/iqm_pulla.egg-info/PKG-INFO +2 -2
  9. iqm_pulla-9.2.0/version.txt +1 -0
  10. iqm_pulla-9.0.0/version.txt +0 -1
  11. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/AUTHORS.rst +0 -0
  12. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/LICENSE.txt +0 -0
  13. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/MANIFEST.in +0 -0
  14. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/README.rst +0 -0
  15. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/docs/API.rst +0 -0
  16. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/docs/Compilation Stages.ipynb +0 -0
  17. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/docs/Configuration and Usage.ipynb +0 -0
  18. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/docs/Example - Compilation With Local Calibration Set.ipynb +0 -0
  19. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/docs/Example - Measuring T1.ipynb +0 -0
  20. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/docs/Example - Randomized Benchmarking.ipynb +0 -0
  21. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/docs/Example - Simple Dynamical Decoupling.ipynb +0 -0
  22. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/docs/Quick Start.ipynb +0 -0
  23. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/docs/_static/images/favicon.ico +0 -0
  24. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/docs/_static/images/logo.png +0 -0
  25. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/docs/_templates/autosummary-class-template.rst +0 -0
  26. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/docs/_templates/autosummary-module-template.rst +0 -0
  27. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/docs/authors.rst +0 -0
  28. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/docs/changelog.rst +0 -0
  29. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/docs/common_errors.rst +0 -0
  30. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/docs/conf.py +0 -0
  31. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/docs/examples.rst +0 -0
  32. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/docs/index.rst +0 -0
  33. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/docs/license.rst +0 -0
  34. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/docs/migration_guide.rst +0 -0
  35. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/docs/readme.rst +0 -0
  36. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/docs/references.bib +0 -0
  37. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/docs/references.rst +0 -0
  38. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/docs/user_guides.rst +0 -0
  39. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/pyproject.toml +0 -0
  40. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/requirements/base.in +0 -0
  41. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/requirements/base.txt +0 -0
  42. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/requirements/notebook.in +0 -0
  43. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/requirements/notebook.txt +0 -0
  44. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/requirements/qir.in +0 -0
  45. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/requirements/qir.txt +0 -0
  46. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/requirements/qiskit.in +0 -0
  47. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/setup.cfg +0 -0
  48. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/setup.py +0 -0
  49. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/src/iqm/cpc/__init__.py +0 -0
  50. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/src/iqm/cpc/compiler/__init__.py +0 -0
  51. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/src/iqm/cpc/compiler/circuit_compilation_request_handler.py +0 -0
  52. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/src/iqm/cpc/compiler/compiler.py +0 -0
  53. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/src/iqm/cpc/compiler/dd.py +0 -0
  54. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/src/iqm/cpc/compiler/errors.py +0 -0
  55. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/src/iqm/cpc/compiler/standard_stages.py +0 -0
  56. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/src/iqm/cpc/compiler/station_settings.py +0 -0
  57. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/src/iqm/cpc/interface/__init__.py +0 -0
  58. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/src/iqm/cpc/interface/compiler.py +0 -0
  59. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/src/iqm/cpc/py.typed +0 -0
  60. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/src/iqm/pulla/__init__.py +0 -0
  61. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/src/iqm/pulla/calibration.py +0 -0
  62. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/src/iqm/pulla/interface.py +0 -0
  63. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/src/iqm/pulla/pulla.py +0 -0
  64. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/src/iqm/pulla/py.typed +0 -0
  65. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/src/iqm/pulla/quantum_architecture.py +0 -0
  66. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/src/iqm/pulla/utils.py +0 -0
  67. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/src/iqm/pulla/utils_cirq.py +0 -0
  68. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/src/iqm/pulla/utils_dd.py +0 -0
  69. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/src/iqm_pulla.egg-info/SOURCES.txt +0 -0
  70. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/src/iqm_pulla.egg-info/dependency_links.txt +0 -0
  71. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/src/iqm_pulla.egg-info/requires.txt +1 -1
  72. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/src/iqm_pulla.egg-info/top_level.txt +0 -0
  73. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/tests/.pylintrc +0 -0
  74. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/tests/__init__.py +0 -0
  75. {iqm_pulla-9.0.0 → iqm_pulla-9.2.0}/tests/conftest.py +0 -0
@@ -2,6 +2,22 @@
2
2
  Changelog
3
3
  =========
4
4
 
5
+ Version 9.2.0 (2025-07-31)
6
+ ==========================
7
+
8
+ Features
9
+ --------
10
+
11
+ - Support iqm-client with QIR support
12
+
13
+ Version 9.1.0 (2025-07-30)
14
+ ==========================
15
+
16
+ Features
17
+ --------
18
+
19
+ - Require compiler instead of Pulla in qir_to_pulla
20
+
5
21
  Version 9.0.0 (2025-07-16)
6
22
  ==========================
7
23
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: iqm-pulla
3
- Version: 9.0.0
3
+ Version: 9.2.0
4
4
  Summary: Client library for pulse-level access to an IQM quantum computer
5
5
  Author-email: IQM Finland Oy <developers@meetiqm.com>
6
6
  License: Apache License
@@ -239,8 +239,8 @@ Provides-Extra: qiskit
239
239
  Requires-Dist: iqm-exa-common<27,>=26; extra == "qiskit"
240
240
  Requires-Dist: iqm-station-control-client<10,>=9; extra == "qiskit"
241
241
  Requires-Dist: iqm-pulse<11,>=10; extra == "qiskit"
242
- Requires-Dist: iqm-client<30,>=29; extra == "qiskit"
243
242
  Requires-Dist: iqm-client[qiskit]<30,>=29; extra == "qiskit"
243
+ Requires-Dist: iqm-client<30,>=29; extra == "qiskit"
244
244
 
245
245
  IQM Pulla
246
246
  #########
@@ -589,7 +589,7 @@
589
589
  "outputs": [],
590
590
  "source": [
591
591
  "circuits, compiler = qiskit_to_pulla(p, backend, example_qiskit_circuit())\n",
592
- "compiler.add_implementation('custom_x', 'StretchedX', StretchedX, quantum_op=QuantumOp(params=('angle_t', 'phase_t')))\n",
592
+ "compiler.add_implementation('custom_x', 'StretchedX', StretchedX, quantum_op=QuantumOp('custom_x', params=('angle_t', 'phase_t')))\n",
593
593
  "\n",
594
594
  "c = circuits[0]\n",
595
595
  "for inst in c.instructions:\n",
@@ -21,7 +21,7 @@
21
21
  "from iqm.qiskit_iqm import IQMProvider\n",
22
22
  "from iqm.pulla.pulla import Pulla\n",
23
23
  "from iqm.pulla.utils_qiskit import station_control_result_to_qiskit\n",
24
- "from iqm.pulla.utils_qir import qir_to_pulla\n",
24
+ "from iqm.pulla.utils_qir import qir_to_pulla, generate_qiskit_qir_qubit_mapping\n",
25
25
  "from qiskit_qir import to_qir_module"
26
26
  ]
27
27
  },
@@ -158,21 +158,7 @@
158
158
  "outputs": [],
159
159
  "source": [
160
160
  "# qiskit-qir has a bug, which causes qubit pointers to not be generated correctly\n",
161
- "# according to the final_layout. So we replicate this logic here and generate a new mapping.\n",
162
- "# Then we assign qiskit-qir index to the qiskit logic qubit idx.\n",
163
- "\n",
164
- "# For simplicity, reverse the mapping\n",
165
- "layout_reverse_mapping = {bit: idx for idx, bit in qc_transpiled.layout.final_layout.get_physical_bits().items()}\n",
166
- "qiskit_qir_mapping = {}\n",
167
- "# Replicate qiskit-qir logic for defining qubit pointer indices\n",
168
- "for register in qc_transpiled.qregs:\n",
169
- " qiskit_qir_mapping.update(\n",
170
- " {layout_reverse_mapping[bit]: n + len(qiskit_qir_mapping) for n, bit in enumerate(register)}\n",
171
- ")\n",
172
- "\n",
173
- "# In the generated QIR qubit pointers will use qiskit-qir qubit labels,\n",
174
- "# but we already know how to map them to IQM physical qubits, through qiskit logical qubit indices.\n",
175
- "qubits_mapping = {qiskit_qir_mapping[i]: backend.index_to_qubit_name(i) for i in range(qc_transpiled.num_qubits)}"
161
+ "qubits_mapping = generate_qiskit_qir_qubit_mapping(qc_transpiled, backend)"
176
162
  ]
177
163
  },
178
164
  {
@@ -221,7 +207,7 @@
221
207
  "p = Pulla(station_control_url)\n",
222
208
  "# Pass qubit mapping to qir_to_pulla coverter to correctly interpret opaque qubit pointer indices in QIR\n",
223
209
  "# and convert them to physical IQM qubit names.\n",
224
- "circuits, compiler = qir_to_pulla(p, qir, qubits_mapping)\n",
210
+ "circuits, compiler = qir_to_pulla(p.get_standard_compiler(), qir, qubits_mapping)\n",
225
211
  "\n",
226
212
  "playlist, context = compiler.compile(circuits)\n",
227
213
  "\n",
@@ -1,5 +1,5 @@
1
1
  iqm-exa-common>=26,<27
2
2
  iqm-station-control-client>=9,<10
3
3
  iqm-pulse>=10,<11
4
- iqm-client>=29,<30
5
- iqm-client[qiskit]>=29,<30
4
+ iqm-client[qiskit]>=29,<30
5
+ iqm-client>=29,<30
@@ -34,10 +34,11 @@ from pyqir import (
34
34
  required_num_results,
35
35
  result_id,
36
36
  )
37
+ from qiskit import QuantumCircuit
38
+ from qiskit.providers import BackendV2
37
39
 
38
40
  from iqm.cpc.compiler.compiler import Compiler
39
41
  from iqm.cpc.interface.compiler import Circuit as CPC_Circuit
40
- from iqm.pulla.pulla import Pulla
41
42
  from iqm.pulse.builder import CircuitOperation
42
43
 
43
44
  qir_logger = logging.getLogger(__name__)
@@ -147,19 +148,20 @@ def _parse_double(value: str) -> float:
147
148
 
148
149
 
149
150
  def qir_to_pulla( # noqa: PLR0915, PLR0912
150
- pulla: Pulla, qir: str | bytes, qubit_mapping: dict[int, str] | None = None
151
+ compiler: Compiler, qir: str | bytes, qubit_mapping: dict[str, str] | None = None
151
152
  ) -> tuple[list[CPC_Circuit], Compiler]:
152
153
  """Convert a QIR module to a CPC circuit.
153
154
 
154
155
  Args:
155
- pulla: The Pulla instance to get compiler from.
156
+ compiler: compiler to use
156
157
  qir: The QIR source or bitcode to convert to a circuit.
157
158
  qubit_mapping: A dictionary mapping QIR qubit indexes to physical qubit names,
158
159
  None will assume opaque pointers match physical names.
159
160
 
160
161
  Returns:
161
162
  str: The QIR program name,
162
- tuple[CircuitOperation, ...]: The circuit operations extracted from the QIR code.
163
+ tuple[list[Circuit], Compiler]:
164
+ Circuits extracted from the QIR module and the compiler with updated component_mapping
163
165
 
164
166
  Raises:
165
167
  ValueError: If the QIR program has more than one basic block.
@@ -240,14 +242,11 @@ def qir_to_pulla( # noqa: PLR0915, PLR0912
240
242
  circuits = [CPC_Circuit(name=name, instructions=circuit_instructions)]
241
243
  qir_logger.debug("Converted circuit: %s", circuits)
242
244
 
243
- # Create a compiler containing all the required station information
244
- compiler = pulla.get_standard_compiler()
245
-
246
245
  if qubit_mapping:
247
246
  # QIR programs reference to qubits as opaque pointer indexes,
248
247
  # however, for example qiskit is using logical names for qubits,
249
248
  # so we need to map these indexes to physical qubit names
250
- compiler.component_mapping = {f"{i}": qubit_mapping[i] for i in range(_required_num_qubits)}
249
+ compiler.component_mapping = {f"{i}": qubit_mapping[str(i)] for i in range(_required_num_qubits)}
251
250
  else:
252
251
  # QIR programs reference to qubits as opaque pointer indexes,
253
252
  # we expect these indexes to match physical qubit names,
@@ -256,3 +255,33 @@ def qir_to_pulla( # noqa: PLR0915, PLR0912
256
255
  compiler.component_mapping = {f"{i}": f"QB{i + 1}" for i in range(_required_num_qubits)}
257
256
 
258
257
  return circuits, compiler
258
+
259
+
260
+ def generate_qiskit_qir_qubit_mapping(qiskit_circuit: QuantumCircuit, qiskit_backend: BackendV2) -> dict[str, str]:
261
+ """qiskit-qir has a bug, which causes qubit pointers to not be generated correctly
262
+ according to the final_layout. So we replicate this logic here and generate a new mapping.
263
+ Then we assign qiskit-qir index to the qiskit logic qubit idx.
264
+
265
+ Args:
266
+ qiskit_circuit: Qiskit circuit to generate the mapping for.
267
+ qiskit_backend: Qiskit backend object to be used for qubit name generation.
268
+
269
+ Returns:
270
+ A dictionary mapping Qiskit qubit indices to QIR qubit pointers.
271
+
272
+ """
273
+ # For simplicity, reverse the mapping
274
+ layout_reverse_mapping = {bit: idx for idx, bit in qiskit_circuit.layout.final_layout.get_physical_bits().items()}
275
+ qiskit_qir_mapping: dict[int, int] = {}
276
+
277
+ # Replicate qiskit-qir logic for defining qubit pointer indices
278
+ for register in qiskit_circuit.qregs:
279
+ qiskit_qir_mapping.update(
280
+ {layout_reverse_mapping[bit]: n + len(qiskit_qir_mapping) for n, bit in enumerate(register)}
281
+ )
282
+
283
+ # In the generated QIR qubit pointers will use qiskit-qir qubit labels,
284
+ # but we already know how to map them to IQM physical qubits, through qiskit logical qubit indices.
285
+ return {
286
+ str(qiskit_qir_mapping[i]): str(qiskit_backend.index_to_qubit_name(i)) for i in range(qiskit_circuit.num_qubits)
287
+ }
@@ -19,6 +19,7 @@ from collections import Counter
19
19
  from collections.abc import Collection, Sequence
20
20
  from typing import TYPE_CHECKING
21
21
 
22
+ from iqm.iqm_client import Circuit
22
23
  from iqm.qiskit_iqm.iqm_backend import IQMBackendBase
23
24
  from iqm.qiskit_iqm.iqm_job import IQMJob
24
25
  from iqm.qiskit_iqm.qiskit_to_iqm import serialize_instructions
@@ -32,7 +33,7 @@ from iqm.pulla.interface import StationControlResult, TaskStatus
32
33
  from iqm.pulse.builder import CircuitOperation
33
34
 
34
35
  if TYPE_CHECKING:
35
- from iqm.iqm_client import Circuit, Instruction
36
+ from iqm.iqm_client import Instruction
36
37
  from iqm.qiskit_iqm.iqm_backend import DynamicQuantumArchitecture
37
38
  from iqm.qiskit_iqm.iqm_provider import IQMBackend
38
39
 
@@ -137,7 +138,10 @@ def qiskit_to_pulla(
137
138
  else {m.logical_name: m.physical_name for m in run_request.qubit_mapping}
138
139
  )
139
140
 
140
- circuits = [_circuit_to_dataclass(c) for c in run_request.circuits]
141
+ # We can be certain run_request contains only Circuit objects, because we created it
142
+ # right in this method with qiskit.QuantumCircuit objects
143
+ run_request_iqm_circuits: list[Circuit] = [c for c in run_request.circuits if isinstance(c, (Circuit))]
144
+ circuits = [_circuit_to_dataclass(c) for c in run_request_iqm_circuits]
141
145
  return circuits, compiler
142
146
 
143
147
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: iqm-pulla
3
- Version: 9.0.0
3
+ Version: 9.2.0
4
4
  Summary: Client library for pulse-level access to an IQM quantum computer
5
5
  Author-email: IQM Finland Oy <developers@meetiqm.com>
6
6
  License: Apache License
@@ -239,8 +239,8 @@ Provides-Extra: qiskit
239
239
  Requires-Dist: iqm-exa-common<27,>=26; extra == "qiskit"
240
240
  Requires-Dist: iqm-station-control-client<10,>=9; extra == "qiskit"
241
241
  Requires-Dist: iqm-pulse<11,>=10; extra == "qiskit"
242
- Requires-Dist: iqm-client<30,>=29; extra == "qiskit"
243
242
  Requires-Dist: iqm-client[qiskit]<30,>=29; extra == "qiskit"
243
+ Requires-Dist: iqm-client<30,>=29; extra == "qiskit"
244
244
 
245
245
  IQM Pulla
246
246
  #########
@@ -0,0 +1 @@
1
+ 9.2.0
@@ -1 +0,0 @@
1
- 9.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
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
@@ -24,5 +24,5 @@ iqm-qiskit-qir==0.8.0
24
24
  iqm-exa-common<27,>=26
25
25
  iqm-station-control-client<10,>=9
26
26
  iqm-pulse<11,>=10
27
- iqm-client<30,>=29
28
27
  iqm-client[qiskit]<30,>=29
28
+ iqm-client<30,>=29
File without changes
File without changes
File without changes