iqm-pulla 8.3.0__py3-none-any.whl → 9.1.0__py3-none-any.whl
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/cpc/compiler/compiler.py +15 -17
- iqm/pulla/utils.py +1 -1
- iqm/pulla/utils_qir.py +37 -8
- {iqm_pulla-8.3.0.dist-info → iqm_pulla-9.1.0.dist-info}/METADATA +6 -6
- {iqm_pulla-8.3.0.dist-info → iqm_pulla-9.1.0.dist-info}/RECORD +9 -9
- {iqm_pulla-8.3.0.dist-info → iqm_pulla-9.1.0.dist-info}/AUTHORS.rst +0 -0
- {iqm_pulla-8.3.0.dist-info → iqm_pulla-9.1.0.dist-info}/LICENSE.txt +0 -0
- {iqm_pulla-8.3.0.dist-info → iqm_pulla-9.1.0.dist-info}/WHEEL +0 -0
- {iqm_pulla-8.3.0.dist-info → iqm_pulla-9.1.0.dist-info}/top_level.txt +0 -0
iqm/cpc/compiler/compiler.py
CHANGED
|
@@ -49,7 +49,7 @@ from iqm.pulla.utils import (
|
|
|
49
49
|
)
|
|
50
50
|
from iqm.pulse.builder import ScheduleBuilder
|
|
51
51
|
from iqm.pulse.gate_implementation import GateImplementation, Locus
|
|
52
|
-
from iqm.pulse.gates import register_implementation
|
|
52
|
+
from iqm.pulse.gates import register_implementation, register_operation
|
|
53
53
|
|
|
54
54
|
# from iqm.pulse.gates.move import apply_move_gate_phase_corrections, validate_move_instructions
|
|
55
55
|
from iqm.pulse.quantum_ops import QuantumOp
|
|
@@ -323,38 +323,36 @@ class Compiler:
|
|
|
323
323
|
self,
|
|
324
324
|
op_name: str,
|
|
325
325
|
impl_name: str,
|
|
326
|
-
|
|
326
|
+
impl_class: type[GateImplementation],
|
|
327
327
|
*,
|
|
328
328
|
set_as_default: bool = False,
|
|
329
329
|
overwrite: bool = False,
|
|
330
|
-
|
|
330
|
+
quantum_op: QuantumOp | None = None,
|
|
331
331
|
) -> None:
|
|
332
|
-
"""Adds a new implementation
|
|
332
|
+
"""Adds a new implementation for a quantum operation (gate).
|
|
333
333
|
|
|
334
334
|
Refreshes the compiler after adding a new implementation.
|
|
335
335
|
|
|
336
336
|
Args:
|
|
337
|
-
op_name: The
|
|
338
|
-
impl_name: The "human-readable" name with which the new
|
|
339
|
-
|
|
340
|
-
set_as_default: Whether to set the new implementation as the default implementation for the
|
|
341
|
-
overwrite: If True,
|
|
342
|
-
|
|
337
|
+
op_name: The name of the quantum operation for which to register a new implementation.
|
|
338
|
+
impl_name: The "human-readable" name with which the new implementation will be found e.g. in settings.
|
|
339
|
+
impl_class: The class of the new implementation to be added.
|
|
340
|
+
set_as_default: Whether to set the new implementation as the default implementation for the operation.
|
|
341
|
+
overwrite: If True, replaces any existing implementation of the same name for the operation.
|
|
342
|
+
quantum_op: The quantum operation this gate represents. If a QuantumOp is given, it is used as is.
|
|
343
343
|
If None is given and the same gate has been registered before, the previously registered properties are
|
|
344
|
-
used.
|
|
345
|
-
Otherwise, the given dict values are given to the constructor of
|
|
346
|
-
:class:`~iqm.pulse.quantum_ops.QuantumOp`.
|
|
347
|
-
For any missing constructor values, some defaults suitable for a 1-QB gate are used.
|
|
344
|
+
used. Existing operations cannot be replaced or modified.
|
|
348
345
|
|
|
349
346
|
"""
|
|
347
|
+
if quantum_op is not None:
|
|
348
|
+
register_operation(self.builder.op_table, quantum_op)
|
|
350
349
|
register_implementation(
|
|
351
350
|
operations=self.builder.op_table,
|
|
352
|
-
|
|
351
|
+
op_name=op_name,
|
|
353
352
|
impl_name=impl_name,
|
|
354
|
-
impl_class=
|
|
353
|
+
impl_class=impl_class,
|
|
355
354
|
set_as_default=set_as_default,
|
|
356
355
|
overwrite=overwrite,
|
|
357
|
-
quantum_op_specs=quantum_op_specs,
|
|
358
356
|
)
|
|
359
357
|
self._refresh()
|
|
360
358
|
|
iqm/pulla/utils.py
CHANGED
|
@@ -86,7 +86,7 @@ def iqm_circuit_to_gate_implementation(circuit: CPC_Circuit, qubit_mapping: dict
|
|
|
86
86
|
# TODO This method does not heed GateImplementation.locus, and will always apply the
|
|
87
87
|
# gate on fixed qubits. It just pastes ``circuit`` contents, with the qubits mapped using
|
|
88
88
|
# the likewise fixed mapping, into a TimeBox.
|
|
89
|
-
registered_gates =
|
|
89
|
+
registered_gates = tuple({instr.name for instr in circuit.instructions})
|
|
90
90
|
|
|
91
91
|
def __call__(self):
|
|
92
92
|
boxes = []
|
iqm/pulla/utils_qir.py
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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[
|
|
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
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: iqm-pulla
|
|
3
|
-
Version:
|
|
3
|
+
Version: 9.1.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
|
|
@@ -218,29 +218,29 @@ License-File: LICENSE.txt
|
|
|
218
218
|
License-File: AUTHORS.rst
|
|
219
219
|
Requires-Dist: iqm-exa-common <27,>=26
|
|
220
220
|
Requires-Dist: iqm-station-control-client <10,>=9
|
|
221
|
-
Requires-Dist: iqm-pulse <10
|
|
221
|
+
Requires-Dist: iqm-pulse <11,>=10
|
|
222
222
|
Requires-Dist: iqm-data-definitions <3.0,>=2.13
|
|
223
223
|
Requires-Dist: pylatexenc ==2.10
|
|
224
224
|
Requires-Dist: pydantic <3.0,>=2.10.4
|
|
225
225
|
Provides-Extra: notebook
|
|
226
226
|
Requires-Dist: iqm-exa-common <27,>=26 ; extra == 'notebook'
|
|
227
227
|
Requires-Dist: iqm-station-control-client <10,>=9 ; extra == 'notebook'
|
|
228
|
-
Requires-Dist: iqm-pulse <10
|
|
228
|
+
Requires-Dist: iqm-pulse <11,>=10 ; extra == 'notebook'
|
|
229
229
|
Requires-Dist: notebook <7,>=6.4.11 ; extra == 'notebook'
|
|
230
230
|
Requires-Dist: matplotlib <4,>=3.6.3 ; extra == 'notebook'
|
|
231
231
|
Requires-Dist: nbclient ~=0.5.10 ; extra == 'notebook'
|
|
232
232
|
Provides-Extra: qir
|
|
233
233
|
Requires-Dist: iqm-exa-common <27,>=26 ; extra == 'qir'
|
|
234
234
|
Requires-Dist: iqm-station-control-client <10,>=9 ; extra == 'qir'
|
|
235
|
-
Requires-Dist: iqm-pulse <10
|
|
235
|
+
Requires-Dist: iqm-pulse <11,>=10 ; extra == 'qir'
|
|
236
236
|
Requires-Dist: iqm-pyqir ==0.12.0 ; extra == 'qir'
|
|
237
237
|
Requires-Dist: iqm-qiskit-qir ==0.8.0 ; extra == 'qir'
|
|
238
238
|
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
|
-
Requires-Dist: iqm-pulse <10
|
|
242
|
-
Requires-Dist: iqm-client[qiskit] <30,>=29 ; extra == 'qiskit'
|
|
241
|
+
Requires-Dist: iqm-pulse <11,>=10 ; extra == 'qiskit'
|
|
243
242
|
Requires-Dist: iqm-client <30,>=29 ; extra == 'qiskit'
|
|
243
|
+
Requires-Dist: iqm-client[qiskit] <30,>=29 ; extra == 'qiskit'
|
|
244
244
|
|
|
245
245
|
IQM Pulla
|
|
246
246
|
#########
|
|
@@ -2,7 +2,7 @@ iqm/cpc/__init__.py,sha256=qw_SFgwld1YOYYyBE-NSticm60xx5aCAw5LJJzjou8Y,1745
|
|
|
2
2
|
iqm/cpc/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
3
|
iqm/cpc/compiler/__init__.py,sha256=ieYyHzb2IyevDm5swU--rPMsh5GdUtLrw8773Cd0ens,678
|
|
4
4
|
iqm/cpc/compiler/circuit_compilation_request_handler.py,sha256=Es3VoO1kOG2XHcJ5ntmT6-aMo7GiCUYkMJGILrUjkfg,4409
|
|
5
|
-
iqm/cpc/compiler/compiler.py,sha256=
|
|
5
|
+
iqm/cpc/compiler/compiler.py,sha256=KsxRrpfPawZYqg3gvTYch58GXlSW8mr3p-11hejbZ_0,20383
|
|
6
6
|
iqm/cpc/compiler/dd.py,sha256=j4onTod24RPxRwwsM3EMBBgX4hDO0k_nW9R762AocXo,21674
|
|
7
7
|
iqm/cpc/compiler/errors.py,sha256=tz-8g1QtDvCAPmAjjCYK3FoULrazkpSTmXIvyqukaT4,1949
|
|
8
8
|
iqm/cpc/compiler/standard_stages.py,sha256=W3CizQJDpxyz_4iHsQ-dxv7DxGxL_MMwOlIiiBjO6KY,33858
|
|
@@ -15,14 +15,14 @@ iqm/pulla/interface.py,sha256=yymQo4REHYcUOWgPxPYq9IixS9bBZ27LXLQgJhzET58,5400
|
|
|
15
15
|
iqm/pulla/pulla.py,sha256=IpW6VLbpx7Qroy47sbybmNmv4jVr2fyd_zx-sdKMklA,14109
|
|
16
16
|
iqm/pulla/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
17
17
|
iqm/pulla/quantum_architecture.py,sha256=mJH9e9fdkblg6LrgN7qd-Ui3Igawf-hGd2Z7ZclQg04,6260
|
|
18
|
-
iqm/pulla/utils.py,sha256=
|
|
18
|
+
iqm/pulla/utils.py,sha256=TTAOFhNW59VFAjnu6ZicmHXvp-GI_f66oh6IC1zFQKE,24732
|
|
19
19
|
iqm/pulla/utils_cirq.py,sha256=8SBy6w7cr4AmnCgKwh7dBWwBGfGKxnoEMv9-1yfKs0A,777
|
|
20
20
|
iqm/pulla/utils_dd.py,sha256=SxYAuRBgvYELKjeXpFbP4mM0xCCivDk7WUHw7oEXfMo,1695
|
|
21
|
-
iqm/pulla/utils_qir.py,sha256=
|
|
21
|
+
iqm/pulla/utils_qir.py,sha256=c4LiKdUnHZSQsI4fzc2wp59-qIH1s2sTyfBEf0MTxkk,11495
|
|
22
22
|
iqm/pulla/utils_qiskit.py,sha256=SyL9zz9xZ3mEi8t5uJVLxe3ipgNf4REZURMJQRr2E-E,10108
|
|
23
|
-
iqm_pulla-
|
|
24
|
-
iqm_pulla-
|
|
25
|
-
iqm_pulla-
|
|
26
|
-
iqm_pulla-
|
|
27
|
-
iqm_pulla-
|
|
28
|
-
iqm_pulla-
|
|
23
|
+
iqm_pulla-9.1.0.dist-info/AUTHORS.rst,sha256=iCStz7WP5Jk7uMnn9jRA4ybS14X4yeUW2SsWE-OTaRk,328
|
|
24
|
+
iqm_pulla-9.1.0.dist-info/LICENSE.txt,sha256=cCj_biRA4Q8A77vxR8AuvAf-DZ5G79yxR_3lYY6TrmA,11333
|
|
25
|
+
iqm_pulla-9.1.0.dist-info/METADATA,sha256=9sARQGBwq1vzFWWvzDTHgOFN7ek76ZXgF95q1K_FP2M,17695
|
|
26
|
+
iqm_pulla-9.1.0.dist-info/WHEEL,sha256=y4mX-SOX4fYIkonsAGA5N0Oy-8_gI4FXw5HNI1xqvWg,91
|
|
27
|
+
iqm_pulla-9.1.0.dist-info/top_level.txt,sha256=NB4XRfyDS6_wG9gMsyX-9LTU7kWnTQxNvkbzIxGv3-c,4
|
|
28
|
+
iqm_pulla-9.1.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|