iqm-benchmarks 2.43__py3-none-any.whl → 2.44__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.
@@ -145,7 +145,6 @@ def fidelity_ghz_coherences(dataset: xr.Dataset, qubit_layout: List[int], circui
145
145
  phases = [np.pi * i / (num_qubits + 1) for i in range(2 * num_qubits + 2)]
146
146
  idx = BenchmarkObservationIdentifier(qubit_layout).string_identifier
147
147
  transpiled_circuits = circuits["transpiled_circuits"]
148
- num_shots = dataset.attrs["shots"]
149
148
  num_circuits = len(transpiled_circuits[f"{qubit_layout}_native_ghz"].circuits)
150
149
 
151
150
  # Computing the phase acquired by the |11...1> component for each interval
@@ -155,8 +154,9 @@ def fidelity_ghz_coherences(dataset: xr.Dataset, qubit_layout: List[int], circui
155
154
  counts = xrvariable_to_counts(dataset, f"{idx}", num_circuits)
156
155
  all_zero_probability_list = [] # An ordered list for storing the probabilities of returning to the |00..0> state
157
156
  for count in counts[1:]:
157
+ normalization = np.sum(list(count.values()))
158
158
  if "0" * num_qubits in count.keys():
159
- probability = count["0" * num_qubits] / num_shots
159
+ probability = count["0" * num_qubits] / normalization
160
160
  else:
161
161
  probability = 0
162
162
  all_zero_probability_list.append(probability)
@@ -165,7 +165,7 @@ def fidelity_ghz_coherences(dataset: xr.Dataset, qubit_layout: List[int], circui
165
165
  i_n = np.abs(np.dot(complex_coefficients, np.array(all_zero_probability_list))) / (len(phases))
166
166
 
167
167
  # Extracting the probabilities of the 00...0 and 11...1 bit strings
168
- probs_direct = {label: count / num_shots for label, count in counts[0].items()}
168
+ probs_direct = {label: count / np.sum(list(counts[0].values())) for label, count in counts[0].items()}
169
169
 
170
170
  # Computing GHZ state fidelity from i_n and the probabilities according to the method in [Mooney, 2021]
171
171
  p0 = probs_direct["0" * num_qubits] if "0" * num_qubits in probs_direct.keys() else 0
@@ -439,34 +439,29 @@ def plot_max_negativities_graph(
439
439
  fig = plt.figure()
440
440
  ax = plt.axes()
441
441
 
442
- if station is not None:
443
- if station.lower() in GraphPositions.predefined_stations:
444
- qubit_positions = GraphPositions.predefined_stations[station.lower()]
445
- else:
446
- graph_backend = backend_coupling_map.graph.to_undirected(multigraph=False)
447
- qubit_positions = GraphPositions.create_positions(graph_backend)
448
- else:
449
- graph_backend = backend_coupling_map.graph.to_undirected(multigraph=False)
450
- if num_qubits in (20, 7):
451
- station = "garnet" if num_qubits == 20 else "deneb"
452
- qubit_positions = GraphPositions.predefined_stations[station]
453
- else:
454
- qubit_positions = GraphPositions.create_positions(graph_backend)
442
+ qubit_positions = GraphPositions.get_positions(
443
+ station=station, graph=backend_coupling_map.graph.to_undirected(multigraph=False), num_qubits=num_qubits
444
+ )
455
445
 
456
446
  # Normalize negativity values to the range [0, 1] for color mapping
457
447
  norm = plt.Normalize(vmin=cast(float, min(negativity_values)), vmax=cast(float, max(negativity_values)))
458
- edge_colors = [cmap(norm(negativity_edges[edge])) for edge in qubit_pairs]
448
+ edge_colors = [
449
+ cmap(norm(negativity_edges[edge])) if edge in qubit_pairs else "lightgray" for edge in backend_coupling_map
450
+ ] #
451
+ nodes = list(set(v for edge in backend_coupling_map for v in edge))
452
+ active_nodes = list(set(v for edge in qubit_pairs for v in edge))
453
+ node_colors = ["lightgray" if v not in active_nodes else "k" for v in nodes]
459
454
 
460
455
  nx.draw_networkx(
461
456
  rx_to_nx_graph(backend_coupling_map),
462
457
  pos=qubit_positions,
463
- nodelist=list(range(num_qubits)),
464
- labels={x: qubit_names[x] for x in range(num_qubits)},
458
+ nodelist=nodes,
459
+ edgelist=list(backend_coupling_map),
460
+ labels={x: qubit_names[x] for x in nodes},
465
461
  font_size=6.5,
466
- edgelist=qubit_pairs,
467
462
  width=4.0,
468
463
  edge_color=edge_colors,
469
- node_color="k",
464
+ node_color=node_colors,
470
465
  font_color="w",
471
466
  ax=ax,
472
467
  )
@@ -490,6 +485,8 @@ def plot_max_negativities_graph(
490
485
  f"{shots_string}; Bootstraps: {num_bootstraps}"
491
486
  f"\n{timestamp}"
492
487
  )
488
+ # Invert y-axis to match the intended qubit positions
489
+ plt.gca().invert_yaxis()
493
490
  plt.close()
494
491
 
495
492
  return fig_name, fig
@@ -955,7 +952,7 @@ def negativity_analysis(run: BenchmarkRunResult) -> BenchmarkAnalysisResult:
955
952
  dataset = run.dataset.copy(deep=True)
956
953
  qcvv_logger.info("Dataset imported OK")
957
954
  backend_name = dataset.attrs["backend_name"]
958
- coupling_map = dataset.attrs["coupling_map"]
955
+ coupling_map_full = dataset.attrs["coupling_map_full"]
959
956
  qubit_names = dataset.attrs["qubit_names"]
960
957
  execution_timestamp = dataset.attrs["execution_timestamp"]
961
958
  tomography = dataset.attrs["tomography"]
@@ -1004,7 +1001,7 @@ def negativity_analysis(run: BenchmarkRunResult) -> BenchmarkAnalysisResult:
1004
1001
 
1005
1002
  fig_name, fig = plot_max_negativities_graph(
1006
1003
  negativities=max_negativities,
1007
- backend_coupling_map=coupling_map,
1004
+ backend_coupling_map=coupling_map_full,
1008
1005
  qubit_names=qubit_names,
1009
1006
  timestamp=execution_timestamp,
1010
1007
  tomography=tomography,
@@ -1066,8 +1063,11 @@ class GraphStateBenchmark(Benchmark):
1066
1063
  dataset.attrs["execution_timestamp"] = self.execution_timestamp
1067
1064
  dataset.attrs["backend_configuration_name"] = self.backend_configuration_name
1068
1065
  dataset.attrs["backend_name"] = self.backend.name
1069
- dataset.attrs["qubit_names"] = {qubit: self.backend.index_to_qubit_name(qubit) for qubit in self.qubits}
1066
+ dataset.attrs["qubit_names"] = {
1067
+ qubit: self.backend.index_to_qubit_name(qubit) for qubit in np.arange(self.backend.num_qubits)
1068
+ }
1070
1069
  dataset.attrs["coupling_map"] = self.coupling_map
1070
+ dataset.attrs["coupling_map_full"] = self.backend.coupling_map
1071
1071
 
1072
1072
  for key, value in self.configuration:
1073
1073
  if key == "benchmark": # Avoid saving the class object
@@ -21,7 +21,6 @@ from math import floor, pi
21
21
  from time import perf_counter, strftime
22
22
  from typing import Any, Dict, List, Sequence, Tuple, Type
23
23
 
24
- import matplotlib as mpl
25
24
  from matplotlib.figure import Figure
26
25
  import matplotlib.pyplot as plt
27
26
  import numpy as np
@@ -178,8 +177,8 @@ def retrieve_clops_elapsed_times(job_meta: Dict[str, Dict[str, Any]]) -> Dict[st
178
177
  # submit_i = datetime.strptime(x["submit_start"], job_time_format)
179
178
  execution_f = datetime.strptime(x["execution_end"], job_time_format)
180
179
  execution_i = datetime.strptime(x["execution_start"], job_time_format)
181
- job_f = datetime.strptime(x["job_end"], job_time_format)
182
- job_i = datetime.strptime(x["job_start"], job_time_format)
180
+ job_f = datetime.strptime(x["ready"], job_time_format)
181
+ job_i = datetime.strptime(x["received"], job_time_format)
183
182
 
184
183
  all_job_elapsed[update][batch] = {
185
184
  "job_total": job_f - job_i,
@@ -5,6 +5,7 @@ Error Per Layered Gate (EPLG).
5
5
  from time import strftime
6
6
  from typing import Dict, Optional, Sequence, Tuple, Type, cast
7
7
 
8
+ from matplotlib.colors import to_rgba
8
9
  from matplotlib.figure import Figure
9
10
  import matplotlib.pyplot as plt
10
11
  import networkx as nx
@@ -76,38 +77,35 @@ def plot_layered_fidelities_graph(
76
77
  fig = plt.figure()
77
78
  ax = plt.axes()
78
79
 
79
- if station is not None:
80
- if station.lower() in GraphPositions.predefined_stations:
81
- qubit_positions = GraphPositions.predefined_stations[station.lower()]
82
- else:
83
- if num_qubits in (20, 7):
84
- station = "garnet" if num_qubits == 20 else "deneb"
85
- qubit_positions = GraphPositions.predefined_stations[station]
86
- else:
87
- graph_backend = backend_coupling_map.graph.to_undirected(multigraph=False)
88
- qubit_positions = GraphPositions.create_positions(graph_backend)
89
- else:
90
- graph_backend = backend_coupling_map.graph.to_undirected(multigraph=False)
91
- if num_qubits in (20, 7):
92
- station = "garnet" if num_qubits == 20 else "deneb"
93
- qubit_positions = GraphPositions.predefined_stations[station]
94
- else:
95
- qubit_positions = GraphPositions.create_positions(graph_backend)
80
+ qubit_positions = GraphPositions.get_positions(
81
+ station=station, graph=backend_coupling_map.graph.to_undirected(multigraph=False), num_qubits=num_qubits
82
+ )
96
83
 
97
84
  # Normalize fidelity values to the range [0, 1] for color mapping
98
85
  norm = plt.Normalize(vmin=cast(float, min(fidelity_values)), vmax=cast(float, max(fidelity_values)))
99
- edge_colors = [cmap(norm(fidelity_edges[edge])) for edge in qubit_pairs]
86
+ edge_colors = []
87
+ for edge in backend_coupling_map:
88
+ if edge in fidelity_edges:
89
+ edge_colors.append(cmap(norm(fidelity_edges[edge])))
90
+ elif (edge[1], edge[0]) in fidelity_edges:
91
+ edge_colors.append(cmap(norm(fidelity_edges[(edge[1], edge[0])])))
92
+ else:
93
+ edge_colors.append(to_rgba("lightgray"))
94
+
95
+ nodes = list(set(v for edge in backend_coupling_map for v in edge))
96
+ active_nodes = list(set(v for edge in qubit_pairs for v in edge))
97
+ node_colors = ["lightgray" if v not in active_nodes else "k" for v in nodes]
100
98
 
101
99
  nx.draw_networkx(
102
100
  rx_to_nx_graph(backend_coupling_map),
103
101
  pos=qubit_positions,
104
- nodelist=list(range(num_qubits)),
105
- labels={x: qubit_names[x] for x in range(num_qubits)},
102
+ nodelist=nodes,
103
+ edgelist=list(backend_coupling_map),
104
+ labels={x: qubit_names[x] for x in nodes},
106
105
  font_size=6.5,
107
- edgelist=qubit_pairs,
108
106
  width=4.0,
109
107
  edge_color=edge_colors,
110
- node_color="k",
108
+ node_color=node_colors,
111
109
  font_color="w",
112
110
  ax=ax,
113
111
  )
@@ -116,7 +114,7 @@ def plot_layered_fidelities_graph(
116
114
  sm = plt.cm.ScalarMappable(cmap=cmap, norm=norm)
117
115
  sm.set_array([])
118
116
  cbar = fig.colorbar(sm, ax=ax, shrink=0.5, label="Layered Fidelity (%)", format="%.2f")
119
- cbar.set_ticks(np.linspace(min(fidelity_values), max(fidelity_values), 5, endpoint=True))
117
+ cbar.set_ticks(tuple(np.linspace(min(fidelity_values), max(fidelity_values), 5, endpoint=True)))
120
118
 
121
119
  station_string = "IQM Backend" if station is None else station.capitalize()
122
120
 
@@ -124,6 +122,7 @@ def plot_layered_fidelities_graph(
124
122
  f"EPLG estimate: {eplg_estimate['value']:.2e} +/- {eplg_estimate['uncertainty']:.2e}\n" if eplg_estimate else ""
125
123
  )
126
124
  plt.title(f"Layered fidelities for qubit pairs in {station_string}\n" f"{eplg_string}{timestamp}")
125
+ plt.gca().invert_yaxis()
127
126
  plt.close()
128
127
 
129
128
  return fig_name, fig
@@ -190,8 +189,8 @@ def eplg_analysis(run: BenchmarkRunResult) -> BenchmarkAnalysisResult:
190
189
  backend_num_qubits=backend_num_qubits,
191
190
  edge_list=edges,
192
191
  timestamp=timestamp,
193
- disjoint_layers=disjoint_layers,
194
192
  station=backend_configuration_name,
193
+ disjoint_layers=disjoint_layers,
195
194
  qubit_names=qubit_names,
196
195
  is_eplg=True,
197
196
  )
iqm/benchmarks/utils.py CHANGED
@@ -48,6 +48,9 @@ from iqm.qiskit_iqm.iqm_job import IQMJob
48
48
  from iqm.qiskit_iqm.iqm_provider import IQMProvider
49
49
 
50
50
 
51
+ # pylint: disable=too-many-lines
52
+
53
+
51
54
  def timeit(f):
52
55
  """Calculates the amount of time a function takes to execute.
53
56
 
@@ -283,12 +286,18 @@ def get_active_qubits(qc: QuantumCircuit) -> List[int]:
283
286
  return list(active_qubits)
284
287
 
285
288
 
286
- def extract_fidelities(cal_url: str) -> tuple[list[list[int]], list[float], str]:
289
+ def extract_fidelities(cal_url: str, all_metrics: bool = False) -> Union[
290
+ Tuple[List[List[int]], List[float], str, Dict[int, int]],
291
+ Tuple[List[List[int]], List[float], str, Dict[int, int], Dict[str, Dict[Union[int, Tuple[int, int]], float]]],
292
+ ]:
287
293
  """Returns couplings and CZ-fidelities from calibration data URL
288
294
 
289
295
  Args:
290
296
  cal_url: str
291
297
  The url under which the calibration data for the backend can be found
298
+ all_metrics: bool
299
+ If True, returns a dictionary with all metrics from the calibration data
300
+ Default is False
292
301
  Returns:
293
302
  list_couplings: List[List[int]]
294
303
  A list of pairs, each of which is a qubit coupling for which the calibration
@@ -297,6 +306,13 @@ def extract_fidelities(cal_url: str) -> tuple[list[list[int]], list[float], str]
297
306
  A list of CZ fidelities from the calibration url, ordered in the same way as list_couplings
298
307
  topology: str
299
308
  Name of the chip topology layout, currently either "star" or "crystal"
309
+ qubit_mapping: Dict[int, int]
310
+ Enumerating all calibrated qubits starting from 0. For instance if on a 5 qubit chip the qubits 2, 3 are calibrated,
311
+ the mapping will be {2: 0, 3: 1}.
312
+ metrics_dict: Dict
313
+ Dictionary of all metrics (returned only if all_metrics=True)
314
+ Format: {metric_name: {qubit: value}} for single qubit metrics
315
+ Format: {metric_name: {(qubit_1, qubit_2): value}} for two qubit metrics
300
316
  """
301
317
  headers = {"Accept": "application/json", "Authorization": "Bearer " + os.environ["IQM_TOKEN"]}
302
318
  r = requests.get(cal_url, headers=headers, timeout=60)
@@ -304,6 +320,7 @@ def extract_fidelities(cal_url: str) -> tuple[list[list[int]], list[float], str]
304
320
  cal_keys = {
305
321
  el2["key"]: (i, j) for i, el1 in enumerate(calibration["calibrations"]) for j, el2 in enumerate(el1["metrics"])
306
322
  }
323
+ resonator_names = ["COMPR", "COMP_R", "MPR1", "MPR_1"]
307
324
  list_couplings = []
308
325
  list_fids = []
309
326
  if "double_move_gate_fidelity" in cal_keys.keys():
@@ -313,18 +330,65 @@ def extract_fidelities(cal_url: str) -> tuple[list[list[int]], list[float], str]
313
330
  i, j = cal_keys["cz_gate_fidelity"]
314
331
  topology = "crystal"
315
332
  for item in calibration["calibrations"][i]["metrics"][j]["metrics"]:
316
- qb1 = int(item["locus"][0][2:]) if item["locus"][0] != "COMP_R" else 0
317
- qb2 = int(item["locus"][1][2:]) if item["locus"][1] != "COMP_R" else 0
318
- if topology == "star":
319
- list_couplings.append([qb1, qb2])
320
- else:
321
- list_couplings.append([qb1 - 1, qb2 - 1])
333
+ qb1 = (
334
+ int(item["locus"][0][2:])
335
+ if not any(resonator in item["locus"][0] for resonator in resonator_names)
336
+ else 0
337
+ )
338
+ qb2 = (
339
+ int(item["locus"][1][2:])
340
+ if not any(resonator in item["locus"][1] for resonator in resonator_names)
341
+ else 0
342
+ )
343
+ list_couplings.append([qb1, qb2])
322
344
  list_fids.append(float(item["value"]))
323
345
  calibrated_qubits = set(np.array(list_couplings).reshape(-1))
346
+
347
+ # Process all metrics if all_metrics is True
348
+ metrics_dict: Dict[str, Dict[Union[int, Tuple[int, int]], float]] = {}
349
+ for metric_key, (i, j) in cal_keys.items():
350
+ metric_data = calibration["calibrations"][i]["metrics"][j]["metrics"]
351
+ metrics_dict[metric_key] = {}
352
+
353
+ for item in metric_data:
354
+ # Determine if it's a single or two-qubit metric
355
+ if "component" in item:
356
+ # Single qubit metric
357
+ component = item["component"]
358
+ if not any(resonator in component for resonator in resonator_names):
359
+ qb = int(component[2:])
360
+ metrics_dict[metric_key][qb] = float(item["value"])
361
+ calibrated_qubits.add(qb) # Add qubits that have a single qubit metric
362
+ if "locus" in item and len(item["locus"]) == 2:
363
+ # Two qubit metric
364
+ locus = item["locus"]
365
+ if not (any(resonator in locus[0] for resonator in resonator_names) or any(resonator in locus[1] for resonator in resonator_names)):
366
+ qb1 = int(locus[0][2:])
367
+ qb2 = int(locus[1][2:])
368
+ metrics_dict[metric_key][(qb1, qb2)] = float(item["value"])
369
+
370
+ # Enumerate all calibrated qubits starting from 0
324
371
  qubit_mapping = {qubit: idx for idx, qubit in enumerate(calibrated_qubits)}
325
372
  list_couplings = [[qubit_mapping[edge[0]], qubit_mapping[edge[1]]] for edge in list_couplings]
326
373
 
327
- return list_couplings, list_fids, topology
374
+ # Apply the qubit mapping to metrics_dict
375
+ remapped_metrics_dict = {}
376
+ for metric_key, metric_values in metrics_dict.items():
377
+ remapped_metrics_dict[metric_key] = {}
378
+ for key, value in metric_values.items():
379
+ if isinstance(key, tuple):
380
+ # Two-qubit metric
381
+ remapped_metrics_dict[metric_key][(qubit_mapping[key[0]], qubit_mapping[key[1]])] = value
382
+ else:
383
+ # Single-qubit metric
384
+ remapped_metrics_dict[metric_key][qubit_mapping[key]] = value
385
+ metrics_dict = remapped_metrics_dict
386
+
387
+ # If all_metrics is False, only return everything related to CZ fidelites
388
+ if not all_metrics:
389
+ return list_couplings, list_fids, topology, qubit_mapping
390
+
391
+ return list_couplings, list_fids, topology, qubit_mapping, metrics_dict
328
392
 
329
393
 
330
394
  # pylint: disable=too-many-branches
@@ -17,9 +17,10 @@ Plotting and visualization utility functions
17
17
  """
18
18
  from dataclasses import dataclass
19
19
  import os
20
- from typing import Dict, List, Literal, Optional, Sequence, Tuple
20
+ from typing import Dict, List, Literal, Optional, Sequence, Tuple, cast
21
21
 
22
22
  from matplotlib.figure import Figure
23
+ from matplotlib.patches import Circle, FancyBboxPatch
23
24
  import matplotlib.pyplot as plt
24
25
  import networkx as nx
25
26
  import numpy as np
@@ -40,9 +41,9 @@ class GraphPositions:
40
41
  provides methods to generate positions for different layout types.
41
42
 
42
43
  Attributes:
43
- garnet_positions (Dict[int, Tuple[int, int]]): Mapping of node indices to (x,y) positions for Garnet chip.
44
- deneb_positions (Dict[int, Tuple[int, int]]): Mapping of node indices to (x,y) positions for Deneb chip.
45
- predefined_stations (Dict[str, Dict[int, Tuple[int, int]]]): Mapping of chip names to their position dictionaries.
44
+ garnet_positions (Dict[int, Tuple[float, float]]): Mapping of node indices to (x,y) positions for Garnet chip.
45
+ deneb_positions (Dict[int, Tuple[float, float]]): Mapping of node indices to (x,y) positions for Deneb chip.
46
+ predefined_stations (Dict[str, Dict[int, Tuple[float, float]]]): Mapping of chip names to their position dictionaries.
46
47
  """
47
48
 
48
49
  garnet_positions = {
@@ -68,15 +69,116 @@ class GraphPositions:
68
69
  19: (3.0, 1.0),
69
70
  }
70
71
 
72
+ emerald_positions = {
73
+ 0: (10, 10),
74
+ 1: (11, 9),
75
+ 2: (7, 11),
76
+ 3: (8, 10),
77
+ 4: (9, 9),
78
+ 5: (10, 8),
79
+ 6: (11, 7),
80
+ 7: (5, 11),
81
+ 8: (6, 10),
82
+ 9: (7, 9),
83
+ 10: (8, 8),
84
+ 11: (9, 7),
85
+ 12: (10, 6),
86
+ 13: (11, 5),
87
+ 14: (3, 11),
88
+ 15: (4, 10),
89
+ 16: (5, 9),
90
+ 17: (6, 8),
91
+ 18: (7, 7),
92
+ 19: (8, 6),
93
+ 20: (9, 5),
94
+ 21: (10, 4),
95
+ 22: (2, 10),
96
+ 23: (3, 9),
97
+ 24: (4, 8),
98
+ 25: (5, 7),
99
+ 26: (6, 6),
100
+ 27: (7, 5),
101
+ 28: (8, 4),
102
+ 29: (9, 3),
103
+ 30: (10, 2),
104
+ 31: (2, 8),
105
+ 32: (3, 7),
106
+ 33: (4, 6),
107
+ 34: (5, 5),
108
+ 35: (6, 4),
109
+ 36: (7, 3),
110
+ 37: (8, 2),
111
+ 38: (9, 1),
112
+ 39: (1, 7),
113
+ 40: (2, 6),
114
+ 41: (3, 5),
115
+ 42: (4, 4),
116
+ 43: (5, 3),
117
+ 44: (6, 2),
118
+ 45: (7, 1),
119
+ 46: (1, 5),
120
+ 47: (2, 4),
121
+ 48: (3, 3),
122
+ 49: (4, 2),
123
+ 50: (5, 1),
124
+ 51: (1, 3),
125
+ 52: (2, 2),
126
+ 53: (3, 1),
127
+ }
128
+
129
+ sirius_positions = {
130
+ # Even nodes on the bottom
131
+ 2: (1, 5),
132
+ 4: (3, 5),
133
+ 6: (5, 5),
134
+ 8: (7, 5),
135
+ 10: (9, 5),
136
+ 12: (11, 5),
137
+ 14: (13, 5),
138
+ 16: (15, 5),
139
+ 18: (17, 5),
140
+ 20: (19, 5),
141
+ 22: (21, 5),
142
+ 24: (23, 5),
143
+ # Odd nodes on the top
144
+ 1: (1, 1),
145
+ 3: (3, 1),
146
+ 5: (5, 1),
147
+ 7: (7, 1),
148
+ 9: (9, 1),
149
+ 11: (11, 1),
150
+ 13: (13, 1),
151
+ 15: (15, 1),
152
+ 17: (17, 1),
153
+ 19: (19, 1),
154
+ 21: (21, 1),
155
+ 23: (23, 1),
156
+ }
157
+ # Add dummy indices for the resonator
158
+ max_qubit_number = np.max(list(sirius_positions.keys()))
159
+ previous_nodes = list(sirius_positions.keys())
160
+ for node in previous_nodes:
161
+ sirius_positions.update({node + max_qubit_number: (sirius_positions[node][0], 3)})
162
+ # Node 0 in the middle
163
+ sirius_positions.update({0: (16.5, 3)})
164
+
71
165
  deneb_positions = {
72
- 0: (2.0, 2.0),
73
- 1: (1.0, 1.0),
74
- 3: (2.0, 1.0),
75
- 5: (3.0, 1.0),
76
- 2: (1.0, 3.0),
77
- 4: (2.0, 3.0),
78
- 6: (3.0, 3.0),
166
+ # Even nodes on the bottom
167
+ 2: (1, 5),
168
+ 4: (3, 5),
169
+ 6: (5, 5),
170
+ # Odd nodes on the top
171
+ 1: (1, 1),
172
+ 3: (3, 1),
173
+ 5: (5, 1),
79
174
  }
175
+ # Add dummy indices for the resonator
176
+ max_qubit_number = np.max(list(deneb_positions.keys()))
177
+ previous_nodes = list(deneb_positions.keys())
178
+ for node in previous_nodes:
179
+ deneb_positions.update({node + max_qubit_number: (deneb_positions[node][0], 3)})
180
+ # Node 0 in the middle
181
+ deneb_positions.update({0: (2.5, 3)})
80
182
 
81
183
  predefined_stations = {
82
184
  "garnet": garnet_positions,
@@ -85,6 +187,8 @@ class GraphPositions:
85
187
  "deneb": deneb_positions,
86
188
  "fakedeneb": deneb_positions,
87
189
  "iqmfakedeneb": deneb_positions,
190
+ "emerald": emerald_positions,
191
+ "sirius": sirius_positions,
88
192
  }
89
193
 
90
194
  @staticmethod
@@ -128,6 +232,40 @@ class GraphPositions:
128
232
  }
129
233
  return pos
130
234
 
235
+ @staticmethod
236
+ def get_positions(
237
+ station: Optional[str] = None, graph: Optional[PyGraph] = None, num_qubits: Optional[int] = None
238
+ ) -> Dict[int, Tuple[float, float]]:
239
+ """Get predefined positions for a specific station or generate positions for a custom graph.
240
+
241
+ Args:
242
+ station (Optional[str]): The name of the station to get predefined positions for.
243
+ If None, positions will be generated algorithmically.
244
+ graph (Optional[PyGraph]): The graph to generate positions for if no predefined positions exist.
245
+ Used only when station is None and num_qubits doesn't match any predefined layout.
246
+ num_qubits (Optional[int]): The number of qubits to get a layout for.
247
+ If matches a known system, predefined positions will be used.
248
+
249
+ Returns:
250
+ Dict[int, Tuple[float, float]]: A dictionary mapping node indices to (x,y) coordinates.
251
+
252
+ Raises:
253
+ ValueError: If none of station, graph, or num_qubits are provided, or if num_qubits doesn't
254
+ match any predefined layout and graph is None.
255
+ """
256
+ if station is not None and station.lower() in GraphPositions.predefined_stations:
257
+ qubit_positions = cast(Dict[int, Tuple[float, float]], GraphPositions.predefined_stations[station.lower()])
258
+ else:
259
+ qubit_station_dict = {6: "deneb", 7: "deneb", 20: "garnet", 24: "sirius", 17: "sirius", 54: "emerald"}
260
+ if num_qubits is not None and num_qubits in qubit_station_dict:
261
+ station = qubit_station_dict[num_qubits]
262
+ qubit_positions = cast(Dict[int, Tuple[float, float]], GraphPositions.predefined_stations[station])
263
+ elif graph is not None:
264
+ qubit_positions = GraphPositions.create_positions(graph)
265
+ else:
266
+ raise ValueError("Either a station name, a graph, or a qubit count must be provided to get positions.")
267
+ return qubit_positions
268
+
131
269
 
132
270
  def draw_graph_edges(
133
271
  backend_coupling_map: CouplingMap,
@@ -165,23 +303,7 @@ def draw_graph_edges(
165
303
  fig = plt.figure()
166
304
  ax = plt.axes()
167
305
 
168
- if station is not None:
169
- if station.lower() in GraphPositions.predefined_stations:
170
- qubit_positions = GraphPositions.predefined_stations[station.lower()]
171
- else:
172
- if backend_num_qubits in (6, 20):
173
- station = "garnet" if backend_num_qubits == 20 else "deneb"
174
- qubit_positions = GraphPositions.predefined_stations[station]
175
- else:
176
- graph_backend = backend_coupling_map.graph.to_undirected(multigraph=False)
177
- qubit_positions = GraphPositions.create_positions(graph_backend)
178
- else:
179
- graph_backend = backend_coupling_map.graph.to_undirected(multigraph=False)
180
- if backend_num_qubits in (6, 20):
181
- station = "garnet" if backend_num_qubits == 20 else "deneb"
182
- qubit_positions = GraphPositions.predefined_stations[station]
183
- else:
184
- qubit_positions = GraphPositions.create_positions(graph_backend)
306
+ qubit_positions = GraphPositions.get_positions(station=station, graph=None, num_qubits=backend_num_qubits)
185
307
 
186
308
  label_station = station if station is not None else f"{backend_num_qubits}-qubit IQM Backend"
187
309
  if disjoint_layers is None:
@@ -226,6 +348,7 @@ def draw_graph_edges(
226
348
  f"\n{timestamp}"
227
349
  )
228
350
  ax.set_aspect(0.925)
351
+ plt.gca().invert_yaxis()
229
352
  plt.close()
230
353
 
231
354
  return fig_name, fig
@@ -302,8 +425,55 @@ def evaluate_hamiltonian_paths(
302
425
  return path_costs
303
426
 
304
427
 
428
+ def calculate_node_radii(metric_dict: Dict[str, Dict[int, float]], qubit_nodes: List[int], sq_metric: str) -> np.ndarray:
429
+ """Calculate node radii based on the specified single qubit metric. For the coherence metric, the fidelity is calculated as the idling fidelity of a single qubit gate duration.
430
+
431
+ Args:
432
+ metric_dict (Dict[str, Dict[int, float]]): Dictionary containing various qubit metrics.
433
+ qubit_nodes (List[int]): List of qubits to calculate the radius for.
434
+ sq_metric (str): Metric to use for radius calculation.
435
+ Options: "fidelity", "coherence", or "readout".
436
+
437
+ Returns:
438
+ numpy.ndarray: Array of radii values for each qubit node.
439
+
440
+ Raises:
441
+ ValueError: If an unsupported metric type is provided.
442
+ """
443
+ if sq_metric == "fidelity":
444
+ radii = -np.log(np.array([metric_dict["fidelity_1qb_gates_averaged"][node] for node in qubit_nodes]))
445
+ if "fidelity_1qb_gates_averaged" not in metric_dict:
446
+ raise ValueError(
447
+ "The metric 'fidelity_1qb_gates_averaged' is not available in the backend metrics."
448
+ )
449
+ elif sq_metric == "coherence":
450
+ if "t1_time" not in metric_dict or "t2_time" not in metric_dict:
451
+ raise ValueError(
452
+ "At least one of the metrics 't1_time' and 't2_time' is not available in the backend metrics."
453
+ )
454
+ sqg_time = 32e-9
455
+ t1_times = [metric_dict["t1_time"][node] for node in qubit_nodes]
456
+ t2_times = [metric_dict["t2_time"][node] for node in qubit_nodes]
457
+ idle_fidelities = (3 + np.exp(-sqg_time / np.array(t1_times)) + 2 * np.exp(-sqg_time / np.array(t2_times))) / 6
458
+ radii = -np.log(idle_fidelities)
459
+ elif sq_metric == "readout":
460
+ if "single_shot_readout_fidelity" not in metric_dict:
461
+ raise ValueError(
462
+ "The metric 'single_shot_readout_fidelity' is both available in the backend metrics."
463
+ )
464
+ readout_fidelities = [metric_dict["single_shot_readout_fidelity"][node] for node in qubit_nodes]
465
+ radii = -np.log(readout_fidelities)
466
+ else:
467
+ raise ValueError(
468
+ f"Unsupported single qubit metric: {sq_metric}, supported metrics are: fidelity, coherence, readout"
469
+ )
470
+ return radii
471
+
305
472
  def plot_layout_fidelity_graph(
306
- cal_url: str, qubit_layouts: Optional[list[list[int]]] = None, station: Optional[str] = None
473
+ cal_url: str,
474
+ qubit_layouts: Optional[list[list[int]]] = None,
475
+ station: Optional[str] = None,
476
+ sq_metric: Optional[str] = "coherence",
307
477
  ):
308
478
  """Plot a graph showing the quantum chip layout with fidelity information.
309
479
 
@@ -316,57 +486,75 @@ def plot_layout_fidelity_graph(
316
486
  qubit_layouts: List of qubit layouts where each layout is a list of qubit indices
317
487
  station: Name of the quantum computing station to use predefined positions for.
318
488
  If None, positions will be generated algorithmically.
489
+ sq_metric: Optional single qubit metric to use for the visualization, can be either "fidelity", "coherence",
490
+ or "readout".
319
491
 
320
492
  Returns:
321
493
  matplotlib.figure.Figure: The generated figure object containing the graph visualization
322
494
  """
323
- edges_cal, fidelities_cal, topology = extract_fidelities(cal_url)
324
- weights = -np.log(np.array(fidelities_cal))
325
- edges_graph = [tuple(edge) + (weight,) for edge, weight in zip(edges_cal, weights)]
326
-
327
- graph = PyGraph()
328
-
329
- # Add nodes
330
- nodes: set[int] = set()
331
- for edge in edges_graph:
332
- nodes.update(edge[:2])
333
- graph.add_nodes_from(list(nodes))
495
+ # pylint: disable=unbalanced-tuple-unpacking, disable=too-many-statements
496
+ edges_cal, fidelities_cal, topology, qubit_mapping, metric_dict = extract_fidelities(cal_url, all_metrics=True)
497
+ if topology == "star":
498
+ idx_to_qubit = {idx: qubit for qubit, idx in qubit_mapping.items()}
499
+ qubit_nodes = list(idx_to_qubit.keys())[1:]
500
+ fig, ax = plt.subplots(figsize=(len(qubit_nodes), 3))
501
+ else:
502
+ # For other topologies, qubits are indexed starting from 0 as per the Qiskit convention
503
+ idx_to_qubit = {idx: qubit - 1 for qubit, idx in qubit_mapping.items()}
504
+ qubit_nodes = list(idx_to_qubit.keys())
505
+ fig, ax = plt.subplots(figsize=(1.5 * np.sqrt(len(qubit_nodes)), 1.5 * np.sqrt(len(qubit_nodes))))
334
506
 
335
- # Add edges
336
- graph.add_edges_from(edges_graph)
507
+ weights = -np.log(np.array(fidelities_cal))
508
+ calibrated_nodes = list(idx_to_qubit.keys())
337
509
 
338
510
  # Define qubit positions in plot
339
- if station is not None and station.lower() in GraphPositions.predefined_stations:
340
- pos = GraphPositions.predefined_stations[station.lower()]
341
- else:
342
- pos = GraphPositions.create_positions(graph, topology)
511
+ qubit_positions = GraphPositions.get_positions(station=station, graph=None, num_qubits=len(calibrated_nodes))
343
512
 
344
- # Define node colors
345
- node_colors = ["lightgrey" for _ in range(len(nodes))]
346
- if qubit_layouts is not None:
347
- for qb in {qb for layout in qubit_layouts for qb in layout}:
348
- node_colors[qb] = "orange"
349
-
350
- plt.subplots(figsize=(1.5 * np.sqrt(len(nodes)), 1.5 * np.sqrt(len(nodes))))
513
+ graph = PyGraph()
514
+ nodes = list(set(qubit_positions.keys()))
515
+ graph.add_nodes_from(nodes)
516
+ for edge, weight in zip(edges_cal, weights):
517
+ if topology == "star":
518
+ max_qubit_number = (np.max(list(qubit_positions.keys())) + 1) // 2
519
+ graph.add_edge(idx_to_qubit[edge[0]], idx_to_qubit[edge[0]] + max_qubit_number, weight)
520
+ else:
521
+ graph.add_edge(idx_to_qubit[edge[0]], idx_to_qubit[edge[1]], weight)
351
522
 
352
- # Draw the graph
523
+ # Draw the main graph
353
524
  visualization.mpl_draw(
354
525
  graph,
526
+ ax=ax,
355
527
  with_labels=True,
356
- node_color=node_colors,
357
- pos=pos,
528
+ node_color="none", # No node color since we're using circles
529
+ pos=qubit_positions,
358
530
  labels=lambda node: node,
359
- width=7 * weights / np.max(weights),
531
+ font_color="white",
532
+ width=graph.edges() / np.max(graph.edges()) * 10,
360
533
  ) # type: ignore[call-arg]
361
534
 
535
+ # Draw nodes as circles with varying radii given by the single qubit metric
536
+ radii = calculate_node_radii(metric_dict, qubit_nodes, sq_metric)
537
+ node_colors = ["darkgray" for _ in range(len(nodes))]
538
+ if qubit_layouts is not None:
539
+ for qb in {qb for layout in qubit_layouts for qb in layout}:
540
+ node_colors[qb] = "orange"
541
+ max_radius = 0.12 + np.max(radii) / np.max(radii) / 2.5
542
+
543
+ for idx, node in enumerate(qubit_nodes):
544
+ position = qubit_positions[idx_to_qubit[node]]
545
+ radius = 0.12 + radii[idx] / np.max(radii) / 2.5
546
+ circle = Circle(position, radius=radius, color=node_colors[idx_to_qubit[node]], fill=True, alpha=1)
547
+ ax.add_patch(circle)
548
+
362
549
  # Add edge labels using matplotlib's annotate
363
- for edge in edges_graph:
364
- x1, y1 = pos[edge[0]]
365
- x2, y2 = pos[edge[1]]
550
+ # for idx, edge in enumerate(edges_cal):
551
+ for edge, weight in zip(list(graph.edge_list()), graph.edges()):
552
+ x1, y1 = qubit_positions[edge[0]]
553
+ x2, y2 = qubit_positions[edge[1]]
366
554
  x = (x1 + x2) / 2
367
555
  y = (y1 + y2) / 2
368
556
  plt.annotate(
369
- f"{edge[2]:.1e}",
557
+ f"{weight:.1e}",
370
558
  xy=(x, y),
371
559
  xytext=(0, 0),
372
560
  textcoords="offset points",
@@ -375,12 +563,68 @@ def plot_layout_fidelity_graph(
375
563
  bbox={"boxstyle": "round,pad=0.2", "fc": "white", "ec": "none", "alpha": 0.6},
376
564
  )
377
565
 
378
- plt.gca().invert_yaxis()
379
- plt.title(
380
- "Chip layout with selected qubits in orange\n"
381
- + "and gate errors indicated by edge thickness (thinner is better)"
566
+ # Add horizontal bar representing resonator
567
+ if topology == "star":
568
+ resonator_height = 3
569
+ resonator_thickness = 0.8
570
+ x_min = 0.5
571
+ x_max = qubit_positions[idx_to_qubit[qubit_nodes[-1]]][0] + 0.5
572
+ resonator_width = x_max - x_min
573
+
574
+ # Create rectangle with rounded corners
575
+ resonator = FancyBboxPatch(
576
+ (x_min, resonator_height - resonator_thickness / 2),
577
+ resonator_width,
578
+ resonator_thickness,
579
+ boxstyle="round,pad=0.01,rounding_size=0.3",
580
+ color="lightsteelblue",
581
+ zorder=10,
582
+ )
583
+ ax.add_patch(resonator)
584
+
585
+ # Add "Resonator" label in the center
586
+ plt.annotate(
587
+ "Resonator",
588
+ xy=((x_min + x_max) / 2, resonator_height),
589
+ xytext=(0, 0),
590
+ textcoords="offset points",
591
+ ha="center",
592
+ va="center",
593
+ color="black",
594
+ fontsize=10,
595
+ zorder=11,
596
+ bbox={"boxstyle": "round,pad=0.2", "fc": "white", "ec": "none", "alpha": 0.8},
597
+ )
598
+
599
+ # Calculate axis limits to ensure all circles are visible
600
+ all_x = [pos[0] for pos in qubit_positions.values()]
601
+ all_y = [pos[1] for pos in qubit_positions.values()]
602
+ x_min, x_max = min(all_x), max(all_x)
603
+ y_min, y_max = min(all_y), max(all_y)
604
+
605
+ # Add padding for circles
606
+ padding = max_radius * 1.5
607
+ ax.set_xlim(x_min - padding, x_max + padding)
608
+ ax.set_ylim(y_min - padding, y_max + padding)
609
+
610
+ # Adjust layout first
611
+ plt.tight_layout(pad=2.0)
612
+ ax.set_aspect("equal")
613
+ ax.invert_yaxis()
614
+
615
+ plt.figtext(
616
+ 0.5,
617
+ 0.99, # x=0.5 (center), y=0.01 (bottom)
618
+ f"Qubit connectivity with selected qubits in orange\n"
619
+ f"CZ errors -log(F) indicated by edge thickness (thinner is better)\n"
620
+ f"Single qubit errors -log(F) shown as node size with F computed from {sq_metric} metrics",
621
+ fontsize=10,
622
+ ha="center",
623
+ wrap=True,
382
624
  )
625
+
383
626
  plt.show()
627
+ return fig
384
628
 
385
629
 
386
630
  def rx_to_nx_graph(backend_coupling_map: CouplingMap) -> nx.Graph:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: iqm-benchmarks
3
- Version: 2.43
3
+ Version: 2.44
4
4
  Summary: A package for implementation of Quantum Characterization, Verification and Validation (QCVV) techniques on IQM's hardware at gate level abstraction
5
5
  Author-email: IQM Finland Oy <developers@meetiqm.com>, Adrian Auer <adrian.auer@meetiqm.com>, Raphael Brieger <raphael.brieger@meetiqm.com>, Alessio Calzona <alessio.calzona@meetiqm.com>, Pedro Figueroa Romero <pedro.romero@meetiqm.com>, Amin Hosseinkhani <amin.hosseinkhani@meetiqm.com>, Miikka Koistinen <miikka@meetiqm.com>, Nadia Milazzo <nadia.milazzo@meetiqm.com>, Vicente Pina Canelles <vicente.pina@meetiqm.com>, Aniket Rath <aniket.rath@meetiqm.com>, Jami Rönkkö <jami@meetiqm.com>, Stefan Seegerer <stefan.seegerer@meetiqm.com>
6
6
  Project-URL: Homepage, https://github.com/iqm-finland/iqm-benchmarks
@@ -4,8 +4,8 @@ iqm/benchmarks/benchmark_definition.py,sha256=e4xe0wlWKZqj48_6-zTglMaMeoiA9aGkHr
4
4
  iqm/benchmarks/circuit_containers.py,sha256=anEtZEsodYqOX-34oZRmuKGeEpp_VfgG5045Mz4-4hI,7562
5
5
  iqm/benchmarks/logging_config.py,sha256=U7olP5Kr75AcLJqNODf9VBhJLVqIvA4AYR6J39D5rww,1052
6
6
  iqm/benchmarks/readout_mitigation.py,sha256=Q2SOGWTNgmklOYkNxepAaSaXlxSj0QQyymYY1bOkT8A,11756
7
- iqm/benchmarks/utils.py,sha256=sItoMsfUYiMWTSCNOTe_RWi2l1xTf2slvXkFiEMRwKU,41091
8
- iqm/benchmarks/utils_plots.py,sha256=Q4h7gcKXf8Eizm13P0yL2I_P-QobHVFr9JCV83wrUi8,14942
7
+ iqm/benchmarks/utils.py,sha256=kJz9T9nJXpLl_iFYYUDtSq83N-Y3JFQBuvW1o7-AVSM,44137
8
+ iqm/benchmarks/utils_plots.py,sha256=CaqA9fJNgRnrbYqwBdpzFUlhwvKw5lhZX3KfRlroQV4,24420
9
9
  iqm/benchmarks/utils_shadows.py,sha256=e77PV_uaAO5m_woox9lAzompKAvFeDJ-0AKJrNJ7NFg,9728
10
10
  iqm/benchmarks/coherence/__init__.py,sha256=yeyhk-_Lp8IbJ-f5lQj0HP5Q1HSKK_FzuXHazotUrVY,704
11
11
  iqm/benchmarks/coherence/coherence.py,sha256=zX_6A8vCS2zeWesMDXPFZBfrJ8wUG90JI9_tFsonwXk,21191
@@ -13,12 +13,12 @@ iqm/benchmarks/compressive_gst/__init__.py,sha256=LneifgYXtcwo2jcXo7GdUEHL6_peip
13
13
  iqm/benchmarks/compressive_gst/compressive_gst.py,sha256=2kiRttog4jR-vtMHu847GTFe5qL_i_uYr_4WMGqt9Ww,25653
14
14
  iqm/benchmarks/compressive_gst/gst_analysis.py,sha256=g0kEovWbetoDRvX7JFrS9oOoNrqBxaFmprujJi7qQbU,36297
15
15
  iqm/benchmarks/entanglement/__init__.py,sha256=sHVVToRWRCz0LSntk1rQaoSNNeyZLPoiTjUKWZWrk1E,778
16
- iqm/benchmarks/entanglement/ghz.py,sha256=12bf9ANfgzyR7Vs8REO-Xm68gisqn8Q7_WSfaNnAmOk,41213
17
- iqm/benchmarks/entanglement/graph_states.py,sha256=7GMxuhbOeQXc3hn3yAwp51S-F-1qaP0AYXm6JtuL9gA,62560
16
+ iqm/benchmarks/entanglement/ghz.py,sha256=nJ0gsLRfl50mcGrBVWjx22gXY9fwn9-sO3St2SbM4MA,41254
17
+ iqm/benchmarks/entanglement/graph_states.py,sha256=saoAw2QF8j7W4nZMOElnjuNylqDAbY9cBwBypWZKUz8,62521
18
18
  iqm/benchmarks/optimization/__init__.py,sha256=_ajW_OibYLCtzU5AUv5c2zuuVYn8ZNeZUcUUSIGt51M,747
19
19
  iqm/benchmarks/optimization/qscore.py,sha256=D2BVVNAqO32uGu5_kLVl2XJUOBlRl1C-c6zYenaCBMg,37259
20
20
  iqm/benchmarks/quantum_volume/__init__.py,sha256=i-Q4SpDWELBw7frXnxm1j4wJRcxbIyrS5uEK_v06YHo,951
21
- iqm/benchmarks/quantum_volume/clops.py,sha256=fLY0aPHjNbW33SuVM9brAgBYFncDHjY5Bwh6iXzbjiU,31099
21
+ iqm/benchmarks/quantum_volume/clops.py,sha256=QS9iK-gtop0zix6IBeUumQeG01-0dXsv0jsYSDhgEu0,31071
22
22
  iqm/benchmarks/quantum_volume/quantum_volume.py,sha256=pro7Lz-A5pPpT9UZ8wtXKTyhdWmTjQjRHt4BylDR-3U,36553
23
23
  iqm/benchmarks/randomized_benchmarking/__init__.py,sha256=IkKo-7zUChxZZd3my_csQCJfJfZNsV3-JTvdG8uqys4,734
24
24
  iqm/benchmarks/randomized_benchmarking/clifford_1q.pkl,sha256=yrmSJqhv7Lb1yqiqU9-2baqTljJPNmTUPQR-AH6GGfc,7800
@@ -30,12 +30,12 @@ iqm/benchmarks/randomized_benchmarking/clifford_rb/clifford_rb.py,sha256=IGBrq_a
30
30
  iqm/benchmarks/randomized_benchmarking/direct_rb/__init__.py,sha256=lCIIeWMFZHnMUUEUTjUBvrhhUur6uBTHIVkxFBSfHC4,681
31
31
  iqm/benchmarks/randomized_benchmarking/direct_rb/direct_rb.py,sha256=Cbx6B9q8Sqc_uPalX6fUEWJX6UEHCfWRof9u4brtx5A,48977
32
32
  iqm/benchmarks/randomized_benchmarking/eplg/__init__.py,sha256=1MeGZTErElXJypQV2rQf7hwqLLvIp_JNVbwNhaP5vyI,696
33
- iqm/benchmarks/randomized_benchmarking/eplg/eplg.py,sha256=WZ3OwQ4C3K8SzudILAUwt71lb24vQQO9vaT0C9GCSOc,17215
33
+ iqm/benchmarks/randomized_benchmarking/eplg/eplg.py,sha256=3A_gxzAs6mi3APKvqCwYDcNwRogIZNy5SDL33Cro89E,17036
34
34
  iqm/benchmarks/randomized_benchmarking/interleaved_rb/__init__.py,sha256=sq6MgN_hwlpkOj10vyCU4e6eKSX-oLcF2L9na6W2Gt4,681
35
35
  iqm/benchmarks/randomized_benchmarking/interleaved_rb/interleaved_rb.py,sha256=TaR1YFWBhOgm1hmEQzuwLYpp0yl0Xpuo3jAT6YhiXpc,28471
36
36
  iqm/benchmarks/randomized_benchmarking/mirror_rb/__init__.py,sha256=jRKbivWCZ3xdO1k0sx-ygC3s5DUkGSModd975PoAtcg,692
37
37
  iqm/benchmarks/randomized_benchmarking/mirror_rb/mirror_rb.py,sha256=n_5gt9636ZDMsM9hC3Zm5qP2bQr2sy41zxGhOh0XMjI,32932
38
- iqm_benchmarks-2.43.dist-info/licenses/LICENSE,sha256=2Ncb40-hqkTil78RPv3-YiJfKaJ8te9USJgliKqIdSY,11558
38
+ iqm_benchmarks-2.44.dist-info/licenses/LICENSE,sha256=2Ncb40-hqkTil78RPv3-YiJfKaJ8te9USJgliKqIdSY,11558
39
39
  mGST/LICENSE,sha256=TtHNq55cUcbglb7uhVudeBLUh_qPdUoAEvU0BBwFz-k,1098
40
40
  mGST/README.md,sha256=v_5kw253csHF4-RfE-44KqFmBXIsSMRmOtN0AUPrRxE,5050
41
41
  mGST/additional_fns.py,sha256=_SEJ10FRNM7_CroysT8hCLZTfpm6ZhEIDCY5zPTnhjo,31390
@@ -46,7 +46,7 @@ mGST/optimization.py,sha256=YHwkzIkYvsZOPjclR-BCQWh24jeqjuXp0BB0WX5Lwow,10559
46
46
  mGST/qiskit_interface.py,sha256=ajx6Zn5FnrX_T7tMP8xnBLyG4c2ddFRm0Fu2_3r1t30,10118
47
47
  mGST/reporting/figure_gen.py,sha256=6Xd8vwfy09hLY1YbJY6TRevuMsQSU4MsWqemly3ZO0I,12970
48
48
  mGST/reporting/reporting.py,sha256=B8NWfpZrrSmyH7lwZxd0EbZMYLsAGK1YsHRB4D5qXH4,26002
49
- iqm_benchmarks-2.43.dist-info/METADATA,sha256=ezkJGO1628fD-X8lXDqtZUeEK9y7kIsfZjDw-JqZBzs,10872
50
- iqm_benchmarks-2.43.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
51
- iqm_benchmarks-2.43.dist-info/top_level.txt,sha256=3G23Z-1LGf-IOzTCUl6QwWqiQ3USz25Zt90Ihq192to,9
52
- iqm_benchmarks-2.43.dist-info/RECORD,,
49
+ iqm_benchmarks-2.44.dist-info/METADATA,sha256=g7tbfF4edqqPEnS50lTJ_0pdp9KzCKMs4RNUQeCxUcU,10872
50
+ iqm_benchmarks-2.44.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
51
+ iqm_benchmarks-2.44.dist-info/top_level.txt,sha256=3G23Z-1LGf-IOzTCUl6QwWqiQ3USz25Zt90Ihq192to,9
52
+ iqm_benchmarks-2.44.dist-info/RECORD,,