iqm-client 29.9.0__py3-none-any.whl → 29.11.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.
@@ -25,7 +25,7 @@ import warnings
25
25
  import cirq
26
26
  from iqm.cirq_iqm.devices.iqm_device import IQMDevice, IQMDeviceMetadata
27
27
  from iqm.cirq_iqm.serialize import serialize_circuit
28
- from iqm.iqm_client import CircuitCompilationOptions, IQMClient, JobAbortionError, RunRequest
28
+ from iqm.iqm_client import CircuitBatch, CircuitCompilationOptions, IQMClient, JobAbortionError, RunRequest
29
29
  import numpy as np
30
30
 
31
31
 
@@ -151,7 +151,7 @@ class IQMSampler(cirq.work.Sampler):
151
151
  if isinstance(programs, cirq.Circuit):
152
152
  programs, _ = self._resolve_parameters(programs, params)
153
153
 
154
- serialized_circuits = [serialize_circuit(circuit) for circuit in programs]
154
+ serialized_circuits: CircuitBatch = [serialize_circuit(circuit) for circuit in programs]
155
155
 
156
156
  if not self._client:
157
157
  raise RuntimeError("Cannot submit circuits since session to IQM client has been closed.")
@@ -45,6 +45,7 @@ from iqm.iqm_client.models import (
45
45
  ClientLibrary,
46
46
  ClientLibraryDict,
47
47
  DynamicQuantumArchitecture,
48
+ QIRCode,
48
49
  QualityMetricSet,
49
50
  QuantumArchitectureSpecification,
50
51
  RunCounts,
@@ -64,6 +65,7 @@ import requests
64
65
  from requests import HTTPError
65
66
 
66
67
  from iqm.station_control.client.iqm_server.iqm_server_client import IqmServerClient
68
+ from iqm.station_control.client.qon import ObservationFinder
67
69
  from iqm.station_control.client.utils import init_station_control
68
70
  from iqm.station_control.interface.models import ObservationLite
69
71
  from iqm.station_control.interface.station_control import StationControlInterface
@@ -232,6 +234,8 @@ class IQMClient:
232
234
 
233
235
  for i, circuit in enumerate(circuits):
234
236
  try:
237
+ if isinstance(circuit, (QIRCode)):
238
+ continue
235
239
  # validate the circuit against the static information in iqm.iqm_client.models._SUPPORTED_OPERATIONS
236
240
  validate_circuit(circuit)
237
241
  except ValueError as e:
@@ -904,3 +908,33 @@ class IQMClient:
904
908
  except json.decoder.JSONDecodeError as e:
905
909
  raise EndpointRequestError(f"Invalid response: {response.text}, {e!r}") from e
906
910
  return model
911
+
912
+ def get_structured_metrics(self, calibration_set_id: UUID | None = None) -> ObservationFinder:
913
+ """Retrieve the given calibration set and related quality metrics from the server.
914
+
915
+ Args:
916
+ calibration_set_id: ID of the calibration set to retrieve.
917
+ If ``None``, the current default calibration set is retrieved.
918
+
919
+ Returns:
920
+ Requested calibration set and related quality metrics in a searchable structure.
921
+
922
+ Raises:
923
+ EndpointRequestError: did not understand the endpoint response
924
+ ClientAuthenticationError: no valid authentication provided
925
+ HTTPException: HTTP exceptions
926
+
927
+ """
928
+ if isinstance(self._station_control, IqmServerClient):
929
+ raise ValueError("The get_structured_metrics method is not supported by IqmServerClient.")
930
+
931
+ if not calibration_set_id:
932
+ # find out the default calset id
933
+ default_calset = self._station_control.get_default_calibration_set()
934
+ calibration_set_id = default_calset.observation_set_id
935
+
936
+ calset_obs = self._station_control.get_observation_set_observations(calibration_set_id)
937
+ quality_metrics = self._station_control.get_calibration_set_quality_metrics(calibration_set_id)
938
+ qm_obs = quality_metrics.observations
939
+
940
+ return ObservationFinder(list(calset_obs) + qm_obs)
iqm/iqm_client/models.py CHANGED
@@ -459,7 +459,10 @@ class Circuit(BaseModel):
459
459
  return instructions
460
460
 
461
461
 
462
- CircuitBatch = list[Circuit]
462
+ QIRCode = str
463
+ """QIR program code in string representation"""
464
+
465
+ CircuitBatch = list[Circuit | QIRCode]
463
466
  """Type that represents a list of quantum circuits to be executed together in a single batch."""
464
467
 
465
468
 
@@ -473,7 +476,12 @@ def validate_circuit(circuit: Circuit) -> None:
473
476
  pydantic.error_wrappers.ValidationError: validation failed
474
477
 
475
478
  """
476
- Circuit.model_validate(circuit.__dict__)
479
+ if isinstance(circuit, Circuit):
480
+ Circuit.model_validate(circuit.__dict__)
481
+ elif isinstance(circuit, QIRCode):
482
+ pass
483
+ else:
484
+ raise ValueError("Every circuit in a batch should be of type <Circuit> or <QIRCode>")
477
485
 
478
486
 
479
487
  class SingleQubitMapping(BaseModel):
@@ -706,6 +714,20 @@ class GateInfo(BaseModel):
706
714
  loci_sorted = sorted(loci_set, key=lambda locus: tuple(map(_component_sort_key, locus)))
707
715
  return tuple(loci_sorted)
708
716
 
717
+ def get_default_implementation(self, locus: Locus) -> str:
718
+ """Default implementation of this gate for the given locus.
719
+
720
+ Args:
721
+ locus: gate locus
722
+
723
+ Returns:
724
+ Name of the default implementation of this gate for ``locus``.
725
+
726
+ """
727
+ if (impl := self.override_default_implementation.get(locus)) is not None:
728
+ return impl
729
+ return self.default_implementation
730
+
709
731
 
710
732
  class DynamicQuantumArchitecture(BaseModel):
711
733
  """Dynamic quantum architecture as returned by server.
@@ -18,6 +18,7 @@ from iqm.iqm_client.models import (
18
18
  DynamicQuantumArchitecture,
19
19
  Instruction,
20
20
  MoveGateValidationMode,
21
+ QIRCode,
21
22
  )
22
23
 
23
24
 
@@ -49,6 +50,8 @@ def validate_qubit_mapping(
49
50
 
50
51
  # check if qubit mapping covers all qubits in the circuits
51
52
  for i, circuit in enumerate(circuits):
53
+ if isinstance(circuit, (QIRCode)):
54
+ continue
52
55
  diff = circuit.all_qubits() - set(qubit_mapping)
53
56
  if diff:
54
57
  raise CircuitValidationError(
@@ -86,6 +89,9 @@ def validate_circuit_instructions(
86
89
 
87
90
  """
88
91
  for index, circuit in enumerate(circuits):
92
+ if isinstance(circuit, QIRCode):
93
+ continue
94
+
89
95
  measurement_keys: set[str] = set()
90
96
  for instr in circuit.instructions:
91
97
  validate_instruction(architecture, instr, qubit_mapping)
iqm/qiskit_iqm/iqm_job.py CHANGED
@@ -24,6 +24,7 @@ import warnings
24
24
  from iqm.iqm_client import (
25
25
  DEFAULT_TIMEOUT_SECONDS,
26
26
  APITimeoutError,
27
+ Circuit,
27
28
  CircuitMeasurementResults,
28
29
  HeraldingMode,
29
30
  IQMClient,
@@ -79,8 +80,11 @@ class IQMJob(JobV1):
79
80
  expect_exact_shots = iqm_result.metadata.heralding_mode == HeraldingMode.NONE
80
81
 
81
82
  return [
82
- (circuit.name, self._format_measurement_results(measurements, requested_shots, expect_exact_shots))
83
- for measurements, circuit in zip(iqm_result.measurements, iqm_result.metadata.circuits)
83
+ (
84
+ circuit.name if isinstance(circuit, Circuit) else f"circuit_{i}",
85
+ self._format_measurement_results(measurements, requested_shots, expect_exact_shots),
86
+ )
87
+ for i, (measurements, circuit) in enumerate(zip(iqm_result.measurements, iqm_result.metadata.circuits))
84
88
  ]
85
89
 
86
90
  @staticmethod
@@ -194,7 +198,9 @@ class IQMJob(JobV1):
194
198
  # was created manually from a job_id. In that case retrieve circuit metadata from
195
199
  # RunResult.metadata.request.circuits[n].metadata
196
200
  if self.circuit_metadata is None and results.metadata.request is not None:
197
- self.circuit_metadata = [c.metadata for c in results.metadata.circuits]
201
+ self.circuit_metadata = [
202
+ c.metadata if isinstance(c, Circuit) else {} for c in results.metadata.circuits
203
+ ]
198
204
 
199
205
  result_dict = {
200
206
  "backend_name": None,
@@ -23,6 +23,7 @@ import warnings
23
23
 
24
24
  from iqm.iqm_client import (
25
25
  Circuit,
26
+ CircuitBatch,
26
27
  CircuitCompilationOptions,
27
28
  CircuitValidationError,
28
29
  IQMClient,
@@ -111,7 +112,7 @@ class IQMBackend(IQMBackendBase):
111
112
  run_request = self.create_run_request(run_input, **options)
112
113
  job_id = self.client.submit_run_request(run_request)
113
114
  job = IQMJob(self, str(job_id), shots=run_request.shots)
114
- job.circuit_metadata = [c.metadata for c in run_request.circuits]
115
+ job.circuit_metadata = [c.metadata if isinstance(c, Circuit) else {} for c in run_request.circuits]
115
116
  return job
116
117
 
117
118
  def create_run_request(
@@ -181,7 +182,7 @@ class IQMBackend(IQMBackendBase):
181
182
  if circuit_callback:
182
183
  circuit_callback(circuits)
183
184
 
184
- circuits_serialized: list[Circuit] = [self.serialize_circuit(circuit, qubit_mapping) for circuit in circuits]
185
+ circuits_serialized: CircuitBatch = [self.serialize_circuit(circuit, qubit_mapping) for circuit in circuits]
185
186
 
186
187
  if self._use_default_calibration_set:
187
188
  default_calset_id = self.client.get_dynamic_quantum_architecture(None).calibration_set_id
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: iqm-client
3
- Version: 29.9.0
3
+ Version: 29.11.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
@@ -1,7 +1,7 @@
1
1
  iqm/cirq_iqm/__init__.py,sha256=QpdI1542qLHx9eTMy3CFJ7oj2BwVZ_LWKe6KxQAh5Zc,1107
2
2
  iqm/cirq_iqm/extended_qasm_parser.py,sha256=csDzfHLhy_9maGbappLbnFo2NHQjQeyd-1F8P380Mbk,1917
3
3
  iqm/cirq_iqm/iqm_gates.py,sha256=xnZex5ZfNOk_WSsFjVCRybc14FlGNbmwOs3mIfOE_F8,2488
4
- iqm/cirq_iqm/iqm_sampler.py,sha256=KLz6j9JcN91GdCAW6fawK99Eyipml3zY89USMVFv2rc,11428
4
+ iqm/cirq_iqm/iqm_sampler.py,sha256=MLHB5FiBXsTCnxjlNJV8LhrIuZ2RS6946zEhI6OBmh4,11456
5
5
  iqm/cirq_iqm/optimizers.py,sha256=vJ7BzTLlfULJq-zt3tHQJGv0LzQAdMVlzQxpuw8JdH0,8550
6
6
  iqm/cirq_iqm/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
7
  iqm/cirq_iqm/serialize.py,sha256=tRkNrzef24va8UMq_Z-TKCsmP7xXtHm3R5qB2VyiIt4,8141
@@ -21,12 +21,12 @@ iqm/iqm_client/__init__.py,sha256=D-8W54EcQIxk_1JZo_86GYlR1YitHhPIiFwwLJ2IfGE,14
21
21
  iqm/iqm_client/api.py,sha256=_c6OVuv2dyzBF7J2XlK_qxisTSPyOiI4gYokZPsuaJY,3083
22
22
  iqm/iqm_client/authentication.py,sha256=kHFqPI6w3OAk9k5ioPxi-FrD2EP-vjn8Z_wZYccJVyE,12259
23
23
  iqm/iqm_client/errors.py,sha256=ty2P-sg80zlAoL3_kC3PlprgDUv4PI-KFhmmxaaapS0,1429
24
- iqm/iqm_client/iqm_client.py,sha256=dZo6do3Q562X-wDTXdeLKzlTjjr_00J7CMU04ldYP-I,39450
25
- iqm/iqm_client/models.py,sha256=PdqpI_6MVCRzQozl6-qGD2LaR-gTdW0at8Lw5KcTBnU,50895
24
+ iqm/iqm_client/iqm_client.py,sha256=yrrpJlSW4N9TCp5zeokHk2lU8N5guYpU643HCMX5oOI,40994
25
+ iqm/iqm_client/models.py,sha256=Sdx_J7wBCM7E_arusU3eC6dQfqu5dpADywr-9JmFvsY,51597
26
26
  iqm/iqm_client/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
27
  iqm/iqm_client/transpile.py,sha256=eEv9eY5QG94Lke7Xp6BkQapl1rvlmlVQ_IkQFopPNQ8,36981
28
28
  iqm/iqm_client/util.py,sha256=FLRUhhi0YDxomVtilCVPJLixyijFtU10PVefIx-eelw,1516
29
- iqm/iqm_client/validation.py,sha256=vIwRx9ZjMpR2lciWX0Dlexoozv_KRrZXbu0whvcxIq4,11772
29
+ iqm/iqm_client/validation.py,sha256=IKXBxnhLLnEuUCU2J0q6VEYn9k-O9z_MI4ys7mpFZdE,11912
30
30
  iqm/iqm_client/cli/__init__.py,sha256=zzLDDz5rc3lJke3OKU8zxR5zQyQoM9oI2bLJ2YKk_zQ,692
31
31
  iqm/iqm_client/cli/auth.py,sha256=SCOZ6QHw9l8oE-A1QSYfAKYuqZxkZkYrwaNWzGFY1AU,6363
32
32
  iqm/iqm_client/cli/cli.py,sha256=YhTgOGrvNXPwCdCKHcwLHeE_6C3n91MxFhvgQYT78C4,28633
@@ -36,10 +36,10 @@ iqm/qiskit_iqm/__init__.py,sha256=Mv9V_r8ZcmGC8Ke5S8-7yLOx02vjZ1qiVx8mtbOpwnY,14
36
36
  iqm/qiskit_iqm/iqm_backend.py,sha256=LhyhccB9u_Y4lyFTzAQkYfX7CI_hbBx3CQHwbwR3wlA,13975
37
37
  iqm/qiskit_iqm/iqm_circuit.py,sha256=fFQW8SRlgZjqZUOLfyuJhhXEDp5I1jopFWa1k4rb7ac,1384
38
38
  iqm/qiskit_iqm/iqm_circuit_validation.py,sha256=vE5CNyJOQ7OMRpQV-xsO1uf_NNFE8v6-TSzboFSrGYM,1721
39
- iqm/qiskit_iqm/iqm_job.py,sha256=_JF2DANalsRu4b0r-XxMmTNOqmaShjp1rmU7h44DKRo,11466
39
+ iqm/qiskit_iqm/iqm_job.py,sha256=Q26hk4JuZP48Xw3qVk4b44LrHbgNQp-mq_itF9umkqg,11666
40
40
  iqm/qiskit_iqm/iqm_move_layout.py,sha256=pHqV1G4bri3rFEsMBN6FrtQ0FXVNQG-Ymm4v7zdnilQ,10787
41
41
  iqm/qiskit_iqm/iqm_naive_move_pass.py,sha256=HoLPgkRK7X2g8KM2ML5-rggNE5HIfGEzq4vkthYSPyg,12398
42
- iqm/qiskit_iqm/iqm_provider.py,sha256=TjrpZZIAI2_K3pWG6sn30M3jFfEDAWp64_4pDis0OU8,16589
42
+ iqm/qiskit_iqm/iqm_provider.py,sha256=5L2-GFbTqMlW7JTagRxl2pV2kw0KKA4hw2YGLYsoUvk,16640
43
43
  iqm/qiskit_iqm/iqm_transpilation.py,sha256=2bwvVd8NwBRU6gwlPOsovhyAmUnm8thKokvkuCwfWC8,8915
44
44
  iqm/qiskit_iqm/move_gate.py,sha256=QU9RKKVvbGq33qcIi9AKLcvQVQMibkgW4ibjzk-oVy4,2808
45
45
  iqm/qiskit_iqm/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -56,10 +56,10 @@ iqm/qiskit_iqm/fake_backends/fake_apollo.py,sha256=eT2vd3kQBi1rrvxCpePymBCfFK84d
56
56
  iqm/qiskit_iqm/fake_backends/fake_deneb.py,sha256=RzQXmLXmBARDiMKVxk5Aw9fVbc6IYlW0A5jibk9iYD0,3156
57
57
  iqm/qiskit_iqm/fake_backends/fake_garnet.py,sha256=GI0xafTCj1Um09qVuccO6GPOGBm6ygul_O40Wu220Ys,5555
58
58
  iqm/qiskit_iqm/fake_backends/iqm_fake_backend.py,sha256=wJtfsxjPYbDKmzaz5R4AuaXvvPHa21WyPtRgNctL9eY,16785
59
- iqm_client-29.9.0.dist-info/AUTHORS.rst,sha256=qsxeK5A3-B_xK3hNbhFHEIkoHNpo7sdzYyRTs7Bdtm8,795
60
- iqm_client-29.9.0.dist-info/LICENSE.txt,sha256=2DXrmQtVVUV9Fc9RBFJidMiTEaQlG2oAtlC9PMrEwTk,11333
61
- iqm_client-29.9.0.dist-info/METADATA,sha256=nk6c2OpBQlMAuR1Vt8IuSn3KdF_H1VtM_LXpOMH2-WI,17590
62
- iqm_client-29.9.0.dist-info/WHEEL,sha256=y4mX-SOX4fYIkonsAGA5N0Oy-8_gI4FXw5HNI1xqvWg,91
63
- iqm_client-29.9.0.dist-info/entry_points.txt,sha256=Kk2qfRwk8vbIJ7qCAvmaUogfRRn6t92_hBFhe6kqAE4,1317
64
- iqm_client-29.9.0.dist-info/top_level.txt,sha256=NB4XRfyDS6_wG9gMsyX-9LTU7kWnTQxNvkbzIxGv3-c,4
65
- iqm_client-29.9.0.dist-info/RECORD,,
59
+ iqm_client-29.11.0.dist-info/AUTHORS.rst,sha256=qsxeK5A3-B_xK3hNbhFHEIkoHNpo7sdzYyRTs7Bdtm8,795
60
+ iqm_client-29.11.0.dist-info/LICENSE.txt,sha256=2DXrmQtVVUV9Fc9RBFJidMiTEaQlG2oAtlC9PMrEwTk,11333
61
+ iqm_client-29.11.0.dist-info/METADATA,sha256=yvcSPUwsECazAvq9XipwpCL511HB2NGswPmSdlflKn4,17591
62
+ iqm_client-29.11.0.dist-info/WHEEL,sha256=y4mX-SOX4fYIkonsAGA5N0Oy-8_gI4FXw5HNI1xqvWg,91
63
+ iqm_client-29.11.0.dist-info/entry_points.txt,sha256=Kk2qfRwk8vbIJ7qCAvmaUogfRRn6t92_hBFhe6kqAE4,1317
64
+ iqm_client-29.11.0.dist-info/top_level.txt,sha256=NB4XRfyDS6_wG9gMsyX-9LTU7kWnTQxNvkbzIxGv3-c,4
65
+ iqm_client-29.11.0.dist-info/RECORD,,