iqm-benchmarks 2.25__py3-none-any.whl → 2.27__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.

Potentially problematic release.


This version of iqm-benchmarks might be problematic. Click here for more details.

@@ -81,10 +81,7 @@ class CompressiveGST(Benchmark):
81
81
  if configuration.opt_method not in ["GD", "SFN", "auto"]:
82
82
  raise ValueError("Invalid optimization method, valid options are: GD, SFN, auto")
83
83
  if configuration.opt_method == "auto":
84
- if (self.num_qubits == 2 and configuration.rank > 2) or self.num_qubits > 2:
85
- self.opt_method = "GD"
86
- else:
87
- self.opt_method = "SFN"
84
+ self.opt_method = "GD" # Currently the fastest method in all cases
88
85
  else:
89
86
  self.opt_method = configuration.opt_method
90
87
 
@@ -160,17 +157,23 @@ class CompressiveGST(Benchmark):
160
157
  "Qubit layouts can't overlap when parallel_execution is enabled, please choose non-overlapping layouts."
161
158
  )
162
159
  raw_qc_list_parallel = []
160
+ if "move" in self.backend.operation_names:
161
+ backend_qubits = np.arange(1, self.backend.num_qubits)
162
+ qubit_layouts = [[q - 1 for q in layout] for layout in self.qubit_layouts]
163
+ else:
164
+ backend_qubits = np.arange(self.backend.num_qubits)
165
+ qubit_layouts = self.qubit_layouts
163
166
  for circ in raw_qc_list:
164
- circ_parallel = QuantumCircuit(self.backend.num_qubits, len(set(all_qubits)))
167
+ circ_parallel = QuantumCircuit(len(backend_qubits), len(set(all_qubits)))
165
168
  clbits = np.arange(self.num_qubits)
166
- for qubit_layout in self.qubit_layouts:
169
+ for qubit_layout in qubit_layouts:
167
170
  circ_parallel.compose(circ, qubits=qubit_layout, clbits=clbits, inplace=True)
168
171
  clbits += self.num_qubits
169
172
  raw_qc_list_parallel.append(circ_parallel)
170
173
  transpiled_qc_list, _ = perform_backend_transpilation(
171
174
  raw_qc_list_parallel,
172
175
  self.backend,
173
- qubits=np.arange(self.backend.num_qubits),
176
+ qubits=backend_qubits,
174
177
  coupling_map=self.backend.coupling_map,
175
178
  qiskit_optim_level=0,
176
179
  optimize_sqg=False,
@@ -388,7 +391,7 @@ def parse_gate_set(
388
391
  gate_set: List[QuantumCircuit]
389
392
  A list of gates defined as quantum circuit objects
390
393
  gate_labels_dict: Dict[str, Dict[int, str]]
391
- The names of gates, i.e. "Rx(pi/2)" for a pi/2 rotation around the x-axis.
394
+ The names of gates, i.e. "Rx_pi_2" for a pi/2 rotation around the x-axis.
392
395
  num_gates: int
393
396
  The number of gates in the gate set
394
397
 
@@ -447,7 +450,7 @@ def create_predefined_gate_set(
447
450
  gates: List[QuantumCircuit]
448
451
  The gate set as a list of circuits
449
452
  gate_labels_dict: Dict[str, Dict[int, str]]
450
- The names of gates, i.e. "Rx(pi/2)" for a pi/2 rotation around the x-axis.
453
+ The names of gates, i.e. "Rx_pi_2" for a pi/2 rotation around the x-axis.
451
454
  num_gates: int
452
455
  The number of gates in the gate set
453
456
 
@@ -460,7 +463,7 @@ def create_predefined_gate_set(
460
463
  gate_qubits = [[0], [0], [0]]
461
464
  for i, gate in enumerate(gate_list):
462
465
  gates[i].append(gate, gate_qubits[i])
463
- gate_labels = ["Idle", "Rx(pi/2)", "Ry(pi/2)"]
466
+ gate_labels = ["Idle", "Rx_pi_2", "Ry_pi_2"]
464
467
  elif gate_set == "2QXYCZ":
465
468
  gate_qubits = [[0], [1], [0], [1], [0, 1]]
466
469
  gates = [QuantumCircuit(num_qubits, 0) for _ in range(5)]
@@ -469,7 +472,7 @@ def create_predefined_gate_set(
469
472
  gates[2].append(RGate(0.5 * np.pi, np.pi / 2), [0])
470
473
  gates[3].append(RGate(0.5 * np.pi, np.pi / 2), [1])
471
474
  gates[4].append(CZGate(), [0, 1])
472
- gate_labels = ["Rx(pi/2)", "Rx(pi/2)", "Ry(pi/2)", "Ry(pi/2)", "CZ"]
475
+ gate_labels = ["Rx_pi_2", "Rx_pi_2", "Ry_pi_2", "Ry_pi_2", "cz"]
473
476
  elif gate_set == "2QXYCZ_extended":
474
477
  gate_qubits = [[0], [1], [0], [1], [0, 1], [0, 1], [0, 1], [0, 1], [0, 1]]
475
478
  gates = [QuantumCircuit(num_qubits, 0) for _ in range(9)]
@@ -487,14 +490,14 @@ def create_predefined_gate_set(
487
490
  gates[7].append(RGate(0.5 * np.pi, np.pi / 2), [1])
488
491
  gates[8].append(CZGate(), [[0], [1]])
489
492
  gate_labels = [
490
- "Rx(pi/2)",
491
- "Rx(pi/2)",
492
- "Ry(pi/2)",
493
- "Ry(pi/2)",
494
- "Rx(pi/2)-Rx(pi/2)",
495
- "Rx(pi/2)-Ry(pi/2)",
496
- "Ry(pi/2)-Rx(pi/2)",
497
- "Ry(pi/2)-Ry(pi/2)",
493
+ "Rx_pi_2",
494
+ "Rx_pi_2",
495
+ "Ry_pi_2",
496
+ "Ry_pi_2",
497
+ "Rx_pi_2-Rx_pi_2",
498
+ "Rx_pi_2-Ry_pi_2",
499
+ "Ry_pi_2-Rx_pi_2",
500
+ "Ry_pi_2-Ry_pi_2",
498
501
  "CZ",
499
502
  ]
500
503
  elif gate_set == "3QXYCZ":
@@ -512,7 +515,7 @@ def create_predefined_gate_set(
512
515
  gate_qubits = [[0], [1], [2], [0], [1], [2], [0, 1], [0, 2]]
513
516
  for i, gate in enumerate(gate_list):
514
517
  gates[i].append(gate, gate_qubits[i])
515
- gate_labels = ["Rx(pi/2)", "Rx(pi/2)", "Rx(pi/2)", "Ry(pi/2)", "Ry(pi/2)", "Ry(pi/2)", "CZ", "CZ"]
518
+ gate_labels = ["Rx_pi_2", "Rx_pi_2", "Rx_pi_2", "Ry_pi_2", "Ry_pi_2", "Ry_pi_2", "cz", "cz"]
516
519
  else:
517
520
  raise ValueError(
518
521
  f"Invalid gate set, choose among 1QXYI, 2QXYCZ, 2QXYCZ_extended,"
@@ -528,6 +531,6 @@ def create_predefined_gate_set(
528
531
  iqm_qubits = [f"QB{q + 1}" for q in qubit_layout]
529
532
  gate_qubits_iqm = [(iqm_qubits[q] for q in qubits) for qubits in gate_qubits]
530
533
  for key, value in layout_label_dict.items():
531
- layout_label_dict[key] = value + ":" + "-".join(gate_qubits_iqm[key])
534
+ layout_label_dict[key] = value + ":" + "__".join(gate_qubits_iqm[key])
532
535
  gate_label_dict.update({BenchmarkObservationIdentifier(qubit_layout).string_identifier: layout_label_dict})
533
536
  return gates, gate_label_dict, len(gates)
@@ -2,6 +2,7 @@
2
2
  Data analysis code for compressive gate set tomography
3
3
  """
4
4
 
5
+ import ast
5
6
  from itertools import product
6
7
  from time import perf_counter
7
8
  from typing import Any, List, Tuple, Union
@@ -218,16 +219,16 @@ def generate_non_gate_results(
218
219
  percentiles_o_low, percentiles_o_high = np.nanpercentile(df_o_array, [2.5, 97.5], axis=0)
219
220
  df_o_final = DataFrame(
220
221
  {
221
- f"Mean TVD: estimate - data": reporting.number_to_str(
222
+ f"mean_total_variation_distance_estimate_data": reporting.number_to_str(
222
223
  df_o.values[0, 1].copy(), [percentiles_o_high[0, 1], percentiles_o_low[0, 1]], precision=5
223
224
  ),
224
- f"Mean TVD: target - data": reporting.number_to_str(
225
+ f"mean_total_variation_distance_target_data": reporting.number_to_str(
225
226
  df_o.values[0, 2].copy(), [percentiles_o_high[0, 2], percentiles_o_low[0, 2]], precision=5
226
227
  ),
227
- f"POVM - diamond dist.": reporting.number_to_str(
228
+ f"povm_diamond_distance": reporting.number_to_str(
228
229
  df_o.values[0, 3].copy(), [percentiles_o_high[0, 3], percentiles_o_low[0, 3]], precision=5
229
230
  ),
230
- f"State - trace dist.": reporting.number_to_str(
231
+ f"state_trace_distance": reporting.number_to_str(
231
232
  df_o.values[0, 4].copy(), [percentiles_o_high[0, 4], percentiles_o_low[0, 4]], precision=5
232
233
  ),
233
234
  },
@@ -236,10 +237,14 @@ def generate_non_gate_results(
236
237
  else:
237
238
  df_o_final = DataFrame(
238
239
  {
239
- f"Mean TVD: estimate - data": reporting.number_to_str(df_o.values[0, 1].copy(), precision=5),
240
- f"Mean TVD: target - data": reporting.number_to_str(df_o.values[0, 2].copy(), precision=5),
241
- f"POVM - diamond dist.": reporting.number_to_str(df_o.values[0, 3].copy(), precision=5),
242
- f"State - trace dist.": reporting.number_to_str(df_o.values[0, 4].copy(), precision=5),
240
+ f"mean_total_variation_distance_estimate_data": reporting.number_to_str(
241
+ df_o.values[0, 1].copy(), precision=5
242
+ ),
243
+ f"mean_total_variation_distance_target_data": reporting.number_to_str(
244
+ df_o.values[0, 2].copy(), precision=5
245
+ ),
246
+ f"povm_diamond_distance": reporting.number_to_str(df_o.values[0, 3].copy(), precision=5),
247
+ f"state_trace_distance": reporting.number_to_str(df_o.values[0, 4].copy(), precision=5),
243
248
  },
244
249
  index=[""],
245
250
  )
@@ -290,13 +295,13 @@ def generate_unit_rank_gate_results(
290
295
 
291
296
  df_g_final = DataFrame(
292
297
  {
293
- r"Avg. gate fidelity": [
298
+ r"average_gate_fidelity": [
294
299
  reporting.number_to_str(
295
300
  df_g.values[i, 0], [percentiles_g_high[i, 0], percentiles_g_low[i, 0]], precision=5
296
301
  )
297
302
  for i in range(len(dataset.attrs["gate_labels"][identifier]))
298
303
  ],
299
- r"Diamond distance": [
304
+ r"diamond_distance": [
300
305
  reporting.number_to_str(
301
306
  df_g.values[i, 1], [percentiles_g_high[i, 1], percentiles_g_low[i, 1]], precision=5
302
307
  )
@@ -338,10 +343,10 @@ def generate_unit_rank_gate_results(
338
343
  else:
339
344
  df_g_final = DataFrame(
340
345
  {
341
- "Avg. gate fidelity": [
346
+ "average_gate_fidelity": [
342
347
  reporting.number_to_str(df_g.values[i, 0], precision=5) for i in range(dataset.attrs["num_gates"])
343
348
  ],
344
- "Diamond distance": [
349
+ "diamond_distance": [
345
350
  reporting.number_to_str(df_g.values[i, 1], precision=5) for i in range(dataset.attrs["num_gates"])
346
351
  ],
347
352
  }
@@ -442,19 +447,19 @@ def generate_gate_results(
442
447
 
443
448
  df_g_final = DataFrame(
444
449
  {
445
- r"Avg. gate fidelity": [
450
+ r"average_gate_fidelity": [
446
451
  reporting.number_to_str(
447
452
  df_g.values[i, 0], [percentiles_g_high[i, 0], percentiles_g_low[i, 0]], precision=5
448
453
  )
449
454
  for i in range(dataset.attrs["num_gates"])
450
455
  ],
451
- r"Diamond distance": [
456
+ r"diamond_distance": [
452
457
  reporting.number_to_str(
453
458
  df_g.values[i, 1], [percentiles_g_high[i, 1], percentiles_g_low[i, 1]], precision=5
454
459
  )
455
460
  for i in range(dataset.attrs["num_gates"])
456
461
  ],
457
- r"Unitarity": [
462
+ r"unitarity": [
458
463
  reporting.number_to_str(
459
464
  reporting.unitarities(X_opt_pp)[i],
460
465
  [percentiles_u_high[i], percentiles_u_low[i]],
@@ -468,15 +473,15 @@ def generate_gate_results(
468
473
  else:
469
474
  df_g_final = DataFrame(
470
475
  {
471
- "Avg. gate fidelity": [
476
+ "average_gate_fidelity": [
472
477
  reporting.number_to_str(df_g.values[i, 0].copy(), precision=5)
473
478
  for i in range(len(dataset.attrs["gate_labels"][identifier]))
474
479
  ],
475
- "Diamond distance": [
480
+ "diamond_distance": [
476
481
  reporting.number_to_str(df_g.values[i, 1].copy(), precision=5)
477
482
  for i in range(len(dataset.attrs["gate_labels"][identifier]))
478
483
  ],
479
- "Unitarity": [
484
+ "unitarity": [
480
485
  reporting.number_to_str(reporting.unitarities(X_opt_pp)[i], precision=5)
481
486
  for i in range(len(dataset.attrs["gate_labels"][identifier]))
482
487
  ],
@@ -574,11 +579,12 @@ def pandas_results_to_observations(
574
579
  """
575
580
  observation_list: list[BenchmarkObservation] = []
576
581
  err = dataset.attrs["bootstrap_samples"] > 0
582
+ qubits = "__".join([f"QB{i+1}" for i in ast.literal_eval(identifier.string_identifier)])
577
583
  for idx, gate_label in enumerate(dataset.attrs["gate_labels"][identifier.string_identifier].values()):
578
584
  observation_list.extend(
579
585
  [
580
586
  BenchmarkObservation(
581
- name=f"{name} - {gate_label}",
587
+ name=f"{name}_{gate_label}:crosstalk_components={qubits}",
582
588
  identifier=identifier,
583
589
  value=result_str_to_floats(df_g[name].iloc[idx], err)[0],
584
590
  uncertainty=result_str_to_floats(df_g[name].iloc[idx], err)[1],
@@ -754,6 +760,7 @@ def mgst_analysis(run: BenchmarkRunResult) -> BenchmarkAnalysisResult:
754
760
  dataset = run.dataset
755
761
  pdim = dataset.attrs["pdim"]
756
762
  plots = {}
763
+ observations = []
757
764
  for i, qubit_layout in enumerate(dataset.attrs["qubit_layouts"]):
758
765
  identifier = BenchmarkObservationIdentifier(qubit_layout).string_identifier
759
766
 
@@ -820,8 +827,10 @@ def mgst_analysis(run: BenchmarkRunResult) -> BenchmarkAnalysisResult:
820
827
  plots[f"layout_{qubit_layout}_gate_metrics"] = fig_g
821
828
  plots[f"layout_{qubit_layout}_other_metrics"] = fig_o
822
829
 
823
- observation_list = pandas_results_to_observations(
824
- dataset, df_g_final, df_o_final, BenchmarkObservationIdentifier(qubit_layout)
830
+ observations.extend(
831
+ pandas_results_to_observations(
832
+ dataset, df_g_final, df_o_final, BenchmarkObservationIdentifier(qubit_layout)
833
+ )
825
834
  )
826
835
 
827
836
  dataset.attrs["results_layout_" + identifier].update(
@@ -865,4 +874,4 @@ def mgst_analysis(run: BenchmarkRunResult) -> BenchmarkAnalysisResult:
865
874
  )
866
875
  plt.close("all")
867
876
 
868
- return BenchmarkAnalysisResult(dataset=dataset, observations=observation_list, plots=plots)
877
+ return BenchmarkAnalysisResult(dataset=dataset, observations=observations, plots=plots)
@@ -205,7 +205,8 @@ def fidelity_analysis(run: BenchmarkRunResult) -> BenchmarkAnalysisResult:
205
205
  dataset = run.dataset
206
206
  routine = dataset.attrs["fidelity_routine"]
207
207
  qubit_layouts = dataset.attrs["custom_qubits_array"]
208
- backend_name = dataset.attrs["backend_name"]
208
+ backend_topology = dataset.attrs["backend_topology"]
209
+ backend_num_qubits = dataset.attrs["backend_num_qubits"]
209
210
 
210
211
  observation_list: list[BenchmarkObservation] = []
211
212
  for qubit_layout in qubit_layouts:
@@ -218,7 +219,7 @@ def fidelity_analysis(run: BenchmarkRunResult) -> BenchmarkAnalysisResult:
218
219
  for qc in all_circuits:
219
220
  qc_copy = qc.copy()
220
221
  qc_copy.remove_final_measurements()
221
- deflated_qc = reduce_to_active_qubits(qc_copy, backend_name)
222
+ deflated_qc = reduce_to_active_qubits(qc_copy, backend_topology, backend_num_qubits)
222
223
  ideal_probabilities.append(
223
224
  dict(sorted(ideal_simulator.run(deflated_qc).result().get_counts().items()))
224
225
  )
@@ -374,11 +375,11 @@ def generate_ghz_spanning_tree(
374
375
  participating_qubits = set(qubit for pair in cx_map[: n_state - 1] for qubit in pair)
375
376
 
376
377
  relabeling = {idx_old: idx_new for idx_new, idx_old in enumerate(participating_qubits)}
377
- n_state_register = QuantumRegister(n_state)
378
- qc = QuantumCircuit(n_state_register, name="ghz")
378
+ qc = QuantumCircuit(n_state, name="ghz")
379
379
  qc.h([relabeling[cx_map[0][0]]])
380
380
  for _, pair in zip(np.arange(n_state - 1), cx_map):
381
381
  relabeled_pair = [relabeling[pair[0]], relabeling[pair[1]]]
382
+ # This barrier prevents Hadamards from being put at the beginning of the circuit, which would make it more susceptible to phase errors
382
383
  qc.barrier(relabeled_pair)
383
384
  qc.cx(*relabeled_pair)
384
385
  qc.measure_active()
@@ -620,14 +621,11 @@ class GHZBenchmark(Benchmark):
620
621
  qcvv_logger.warning(
621
622
  f"The current backend is a star architecture for which a suboptimal state generation routine is chosen. Consider setting state_generation_routine={routine}."
622
623
  )
623
- effective_coupling_map = [[x, y] for x in qubit_layout for y in qubit_layout if x != y]
624
- else:
625
- effective_coupling_map = self.backend.coupling_map
626
624
  if self.cal_url:
627
625
  edges_cal, fidelities_cal, _ = extract_fidelities(self.cal_url)
628
- graph = get_edges(effective_coupling_map, qubit_layout, edges_cal, fidelities_cal)
626
+ graph = get_edges(self.backend.coupling_map, qubit_layout, edges_cal, fidelities_cal)
629
627
  else:
630
- graph = get_edges(effective_coupling_map, qubit_layout)
628
+ graph = get_edges(self.backend.coupling_map, qubit_layout)
631
629
  ghz, _ = generate_ghz_spanning_tree(graph, qubit_layout, qubit_count)
632
630
  circuit_group.add_circuit(ghz)
633
631
  ghz_native_transpiled, _ = perform_backend_transpilation(
@@ -670,7 +668,7 @@ class GHZBenchmark(Benchmark):
670
668
  else:
671
669
  index_min_depth = np.argmin([c.depth() for c in ghz_native_transpiled])
672
670
  final_ghz = ghz_native_transpiled[index_min_depth]
673
- circuit_group.add_circuit([ghz_log[index_min_depth]])
671
+ circuit_group.add_circuit(ghz_log[index_min_depth])
674
672
  self.circuits["untranspiled_circuits"].circuit_groups.append(circuit_group)
675
673
  return CircuitGroup(name=f"{qubit_layout}_native_ghz", circuits=[final_ghz[0]])
676
674
 
@@ -821,6 +819,8 @@ class GHZBenchmark(Benchmark):
821
819
  else:
822
820
  dataset.attrs[key] = value
823
821
  dataset.attrs[f"backend_name"] = self.backend.name
822
+ dataset.attrs[f"backend_topology"] = "star" if "move" in self.backend.operation_names else "crystal"
823
+ dataset.attrs[f"backend_num_qubits"] = self.backend.num_qubits
824
824
  dataset.attrs[f"execution_timestamp"] = self.execution_timestamp
825
825
  dataset.attrs["fidelity_routine"] = self.fidelity_routine
826
826
 
@@ -475,23 +475,24 @@ def qscore_analysis(run: BenchmarkRunResult) -> BenchmarkAnalysisResult:
475
475
  qcvv_logger.info(
476
476
  f"Q-Score = {num_nodes} failed with approximation ratio (Beta) {approximation_ratio:.4f} < 0.2; Avg MaxCut size: {np.mean(cut_sizes_list):.4f}"
477
477
  )
478
+ qubit_indices = dataset.attrs[num_nodes]["qubit_set"][0]
478
479
  observations.extend(
479
480
  [
480
481
  BenchmarkObservation(
481
482
  name="mean_approximation_ratio",
482
483
  value=approximation_ratio,
483
484
  uncertainty=std_of_approximation_ratio,
484
- identifier=BenchmarkObservationIdentifier(num_nodes),
485
+ identifier=BenchmarkObservationIdentifier(qubit_indices),
485
486
  ),
486
487
  BenchmarkObservation(
487
488
  name="is_succesful",
488
489
  value=str(success),
489
- identifier=BenchmarkObservationIdentifier(num_nodes),
490
+ identifier=BenchmarkObservationIdentifier(qubit_indices),
490
491
  ),
491
492
  BenchmarkObservation(
492
493
  name="Qscore_result",
493
494
  value=qscore if success else 1,
494
- identifier=BenchmarkObservationIdentifier(num_nodes),
495
+ identifier=BenchmarkObservationIdentifier(qubit_indices),
495
496
  ),
496
497
  ]
497
498
  )
@@ -751,7 +752,7 @@ class QScoreBenchmark(Benchmark):
751
752
  else:
752
753
  nqubits = self.backend.num_qubits
753
754
 
754
- if self.custom_qubits_array is not None:
755
+ if self.choose_qubits_routine == "custom":
755
756
  if self.use_virtual_node:
756
757
  node_numbers = [len(qubit_layout) + 1 for qubit_layout in self.custom_qubits_array]
757
758
  else:
@@ -765,7 +766,7 @@ class QScoreBenchmark(Benchmark):
765
766
  max_num_nodes = nqubits
766
767
  else:
767
768
  max_num_nodes = self.max_num_nodes
768
- node_numbers = range(self.min_num_nodes, max_num_nodes + 1)
769
+ node_numbers = list(range(self.min_num_nodes, max_num_nodes + 1))
769
770
 
770
771
  dataset.attrs.update({"max_num_nodes": node_numbers[-1]})
771
772
  dataset.attrs.update({"node_numbers": node_numbers})
@@ -855,7 +856,7 @@ class QScoreBenchmark(Benchmark):
855
856
  else:
856
857
  qcvv_logger.setLevel(logging.WARNING)
857
858
  # Account for all-to-all connected backends like Deneb
858
- if "move" in self.backend.operation_names:
859
+ if "move" in backend.architecture.gates:
859
860
  # If the circuit is defined on a subset of qubit_set, choose the first qubtis in the set
860
861
  active_qubit_set = qubit_set[: len(qc.qubits)]
861
862
  # All-to-all coupling map on the active qubits
@@ -514,7 +514,7 @@ class CLOPSBenchmark(Benchmark):
514
514
  parameters = self.generate_random_parameters()
515
515
 
516
516
  # Star can't use optimize_sqg as is, yet -> complains about MOVE gate not being IQM native!
517
- if optimize_sqg and "move" not in self.backend.operation_names:
517
+ if optimize_sqg and "move" not in self.backend.architecture.gates:
518
518
  sorted_dict_parametrized[k].append(
519
519
  optimize_single_qubit_gates( # Optimize SQG seems worth it AFTER assignment
520
520
  qc.assign_parameters(
@@ -125,13 +125,18 @@ def clifford_rb_analysis(run: BenchmarkRunResult) -> BenchmarkAnalysisResult:
125
125
  fidelity = rb_fit_results.params["fidelity_per_clifford"]
126
126
 
127
127
  processed_results = {
128
- "avg_gate_fidelity": {"value": fidelity.value, "uncertainty": fidelity.stderr},
128
+ "average_gate_fidelity": {"value": fidelity.value, "uncertainty": fidelity.stderr},
129
129
  }
130
130
 
131
131
  if len(qubits) == 1:
132
132
  fidelity_native = rb_fit_results.params["fidelity_per_native_sqg"]
133
133
  processed_results.update(
134
- {"avg_native_gate_fidelity": {"value": fidelity_native.value, "uncertainty": fidelity_native.stderr}}
134
+ {
135
+ "average_native_gate_fidelity": {
136
+ "value": fidelity_native.value,
137
+ "uncertainty": fidelity_native.stderr,
138
+ }
139
+ }
135
140
  )
136
141
 
137
142
  dataset.attrs[qubits_idx].update(
@@ -140,8 +145,8 @@ def clifford_rb_analysis(run: BenchmarkRunResult) -> BenchmarkAnalysisResult:
140
145
  "fit_amplitude": {"value": popt["amplitude"].value, "uncertainty": popt["amplitude"].stderr},
141
146
  "fit_offset": {"value": popt["offset"].value, "uncertainty": popt["offset"].stderr},
142
147
  "fidelities": fidelities[str(qubits)],
143
- "avg_fidelities_nominal_values": average_fidelities,
144
- "avg_fidelities_stderr": stddevs_from_mean,
148
+ "average_fidelities_nominal_values": average_fidelities,
149
+ "average_fidelities_stderr": stddevs_from_mean,
145
150
  "fitting_method": str(rb_fit_results.method),
146
151
  "num_function_evals": int(rb_fit_results.nfev),
147
152
  "data_points": int(rb_fit_results.ndata),
@@ -173,14 +173,14 @@ def interleaved_rb_analysis(run: BenchmarkRunResult) -> BenchmarkAnalysisResult:
173
173
  )
174
174
 
175
175
  processed_results[rb_type] = {
176
- "avg_gate_fidelity": {"value": fidelity.value, "uncertainty": fidelity.stderr},
176
+ "average_gate_fidelity": {"value": fidelity.value, "uncertainty": fidelity.stderr},
177
177
  }
178
178
 
179
179
  if len(qubits) == 1 and rb_type == "clifford":
180
180
  fidelity_native = rb_fit_results.params["fidelity_per_native_sqg"]
181
181
  processed_results[rb_type].update(
182
182
  {
183
- "avg_gate_fidelity_native": {
183
+ "average_gate_fidelity_native": {
184
184
  "value": fidelity_native.value,
185
185
  "uncertainty": fidelity_native.stderr,
186
186
  }
@@ -190,7 +190,7 @@ def interleaved_rb_analysis(run: BenchmarkRunResult) -> BenchmarkAnalysisResult:
190
190
  fidelity_native_sqg = rb_fit_results.params["fidelity_per_native_sqg"]
191
191
  processed_results[rb_type].update(
192
192
  {
193
- "avg_gate_fidelity_native_sqg": {
193
+ "average_gate_fidelity_native_sqg": {
194
194
  "value": fidelity_native_sqg.value,
195
195
  "uncertainty": fidelity_native_sqg.stderr,
196
196
  }
@@ -200,7 +200,7 @@ def interleaved_rb_analysis(run: BenchmarkRunResult) -> BenchmarkAnalysisResult:
200
200
  observations.extend(
201
201
  [
202
202
  BenchmarkObservation(
203
- name=f"{key}_{rb_type}" if "native" not in key else f"{key}",
203
+ name=f"{key}_{interleaved_gate}" if "native" not in key else f"{key}",
204
204
  identifier=BenchmarkObservationIdentifier(qubits),
205
205
  value=values["value"],
206
206
  uncertainty=values["uncertainty"],
@@ -216,8 +216,8 @@ def interleaved_rb_analysis(run: BenchmarkRunResult) -> BenchmarkAnalysisResult:
216
216
  "fit_amplitude": {"value": popt["amplitude"].value, "uncertainty": popt["amplitude"].stderr},
217
217
  "fit_offset": {"value": popt["offset"].value, "uncertainty": popt["offset"].stderr},
218
218
  "fidelities": fidelities[str(qubits)][rb_type],
219
- "avg_fidelities_nominal_values": average_fidelities,
220
- "avg_fidelities_stderr": stddevs_from_mean,
219
+ "average_fidelities_nominal_values": average_fidelities,
220
+ "average_fidelities_stderr": stddevs_from_mean,
221
221
  "fitting_method": str(rb_fit_results.method),
222
222
  "num_function_evals": int(rb_fit_results.nfev),
223
223
  "data_points": int(rb_fit_results.ndata),
@@ -332,7 +332,7 @@ def generate_pauli_dressed_mrb_circuits(
332
332
 
333
333
  # Add measurements to transpiled - before!
334
334
  circ.measure_all()
335
- if "move" in retrieved_backend.operation_names:
335
+ if "move" in retrieved_backend.architecture.gates:
336
336
  # All-to-all coupling map on the active qubits
337
337
  effective_coupling_map = [[x, y] for x in qubits for y in qubits if x != y]
338
338
  else:
@@ -522,7 +522,7 @@ def mrb_analysis(run: BenchmarkRunResult) -> BenchmarkAnalysisResult:
522
522
  fidelity = rb_fit_results.params["fidelity_mrb"]
523
523
 
524
524
  processed_results = {
525
- "avg_gate_fidelity": {"value": fidelity.value, "uncertainty": fidelity.stderr},
525
+ "average_gate_fidelity": {"value": fidelity.value, "uncertainty": fidelity.stderr},
526
526
  }
527
527
 
528
528
  dataset.attrs[qubits_idx].update(
@@ -531,8 +531,8 @@ def mrb_analysis(run: BenchmarkRunResult) -> BenchmarkAnalysisResult:
531
531
  "fit_amplitude": {"value": popt["amplitude"].value, "uncertainty": popt["amplitude"].stderr},
532
532
  "fit_offset": {"value": popt["offset"].value, "uncertainty": popt["offset"].stderr},
533
533
  "polarizations": polarizations,
534
- "avg_polarization_nominal_values": average_polarizations,
535
- "avg_polatization_stderr": stddevs_from_mean,
534
+ "average_polarization_nominal_values": average_polarizations,
535
+ "average_polatization_stderr": stddevs_from_mean,
536
536
  "fitting_method": str(rb_fit_results.method),
537
537
  "num_function_evals": int(rb_fit_results.nfev),
538
538
  "data_points": int(rb_fit_results.ndata),
@@ -637,11 +637,11 @@ def plot_rb_decay(
637
637
  str(q): dataset.attrs[q_idx]["polarizations"] for q_idx, q in enumerate(qubits_array, qubits_index)
638
638
  }
639
639
  average_polarizations[identifier] = {
640
- str(q): dataset.attrs[q_idx]["avg_polarization_nominal_values"]
640
+ str(q): dataset.attrs[q_idx]["average_polarization_nominal_values"]
641
641
  for q_idx, q in enumerate(qubits_array, qubits_index)
642
642
  }
643
643
  stddevs_from_mean[identifier] = {
644
- str(q): dataset.attrs[q_idx]["avg_polatization_stderr"]
644
+ str(q): dataset.attrs[q_idx]["average_polatization_stderr"]
645
645
  for q_idx, q in enumerate(qubits_array, qubits_index)
646
646
  }
647
647
  else: # identifier == "clifford"
@@ -653,28 +653,28 @@ def plot_rb_decay(
653
653
  str(q): dataset.attrs[q_idx]["fidelities"] for q_idx, q in enumerate(qubits_array, qubits_index)
654
654
  }
655
655
  average_polarizations[identifier] = {
656
- str(q): dataset.attrs[q_idx]["avg_fidelities_nominal_values"]
656
+ str(q): dataset.attrs[q_idx]["average_fidelities_nominal_values"]
657
657
  for q_idx, q in enumerate(qubits_array, qubits_index)
658
658
  }
659
659
  stddevs_from_mean[identifier] = {
660
- str(q): dataset.attrs[q_idx]["avg_fidelities_stderr"]
660
+ str(q): dataset.attrs[q_idx]["average_fidelities_stderr"]
661
661
  for q_idx, q in enumerate(qubits_array, qubits_index)
662
662
  }
663
663
  fidelity_native1q_value[identifier] = {
664
- str(q): observations[q_idx]["avg_native_gate_fidelity"]["value"] if len(q) == 1 else np.nan
664
+ str(q): observations[q_idx]["average_native_gate_fidelity"]["value"] if len(q) == 1 else np.nan
665
665
  for q_idx, q in enumerate(qubits_array, qubits_index)
666
666
  }
667
667
  fidelity_native1q_stderr[identifier] = {
668
- str(q): observations[q_idx]["avg_native_gate_fidelity"]["uncertainty"] if len(q) == 1 else np.nan
668
+ str(q): observations[q_idx]["average_native_gate_fidelity"]["uncertainty"] if len(q) == 1 else np.nan
669
669
  for q_idx, q in enumerate(qubits_array, qubits_index)
670
670
  }
671
671
  # These are common to both MRB and standard Clifford
672
672
  fidelity_value[identifier] = {
673
- str(q): observations[q_idx]["avg_gate_fidelity"]["value"]
673
+ str(q): observations[q_idx]["average_gate_fidelity"]["value"]
674
674
  for q_idx, q in enumerate(qubits_array, qubits_index)
675
675
  }
676
676
  fidelity_stderr[identifier] = {
677
- str(q): observations[q_idx]["avg_gate_fidelity"]["uncertainty"]
677
+ str(q): observations[q_idx]["average_gate_fidelity"]["uncertainty"]
678
678
  for q_idx, q in enumerate(qubits_array, qubits_index)
679
679
  }
680
680
  decay_rate[identifier] = {
@@ -699,19 +699,19 @@ def plot_rb_decay(
699
699
  for q_idx, q in enumerate(qubits_array, qubits_index)
700
700
  }
701
701
  average_polarizations[rb_type] = {
702
- str(q): dataset.attrs[q_idx][rb_type]["avg_fidelities_nominal_values"]
702
+ str(q): dataset.attrs[q_idx][rb_type]["average_fidelities_nominal_values"]
703
703
  for q_idx, q in enumerate(qubits_array, qubits_index)
704
704
  }
705
705
  stddevs_from_mean[rb_type] = {
706
- str(q): dataset.attrs[q_idx][rb_type]["avg_fidelities_stderr"]
706
+ str(q): dataset.attrs[q_idx][rb_type]["average_fidelities_stderr"]
707
707
  for q_idx, q in enumerate(qubits_array, qubits_index)
708
708
  }
709
709
  fidelity_value[rb_type] = {
710
- str(q): observations[q_idx][rb_type]["avg_gate_fidelity"]["value"]
710
+ str(q): observations[q_idx][rb_type]["average_gate_fidelity"]["value"]
711
711
  for q_idx, q in enumerate(qubits_array, qubits_index)
712
712
  }
713
713
  fidelity_stderr[rb_type] = {
714
- str(q): observations[q_idx][rb_type]["avg_gate_fidelity"]["uncertainty"]
714
+ str(q): observations[q_idx][rb_type]["average_gate_fidelity"]["uncertainty"]
715
715
  for q_idx, q in enumerate(qubits_array, qubits_index)
716
716
  }
717
717
  decay_rate[rb_type] = {
iqm/benchmarks/utils.py CHANGED
@@ -45,7 +45,6 @@ from iqm.qiskit_iqm.fake_backends.fake_apollo import IQMFakeApollo
45
45
  from iqm.qiskit_iqm.iqm_backend import IQMBackendBase
46
46
  from iqm.qiskit_iqm.iqm_job import IQMJob
47
47
  from iqm.qiskit_iqm.iqm_provider import IQMProvider
48
- from iqm.qiskit_iqm.iqm_transpilation import optimize_single_qubit_gates
49
48
 
50
49
 
51
50
  def timeit(f):
@@ -169,6 +168,9 @@ def count_native_gates(
169
168
  backend = backend_arg
170
169
 
171
170
  native_operations = backend.operation_names
171
+
172
+ if "move" in backend.architecture.gates:
173
+ native_operations.append("move")
172
174
  # Some backends may not include "barrier" in the operation_names attribute
173
175
  if "barrier" not in native_operations:
174
176
  native_operations.append("barrier")
@@ -301,21 +303,22 @@ def perform_backend_transpilation(
301
303
  initial_layout=qubits if aux_qc is None else None,
302
304
  routing_method=routing_method,
303
305
  )
304
- if optimize_sqg:
305
- transpiled = optimize_single_qubit_gates(transpiled, drop_final_rz=drop_final_rz)
306
- if "move" in backend.operation_names:
306
+ if "move" in backend.architecture.gates:
307
307
  transpiled = transpile_to_IQM(
308
308
  qc, backend=backend, optimize_single_qubits=optimize_sqg, remove_final_rzs=drop_final_rz
309
309
  )
310
310
  if aux_qc is not None:
311
- if "move" in backend.operation_names:
312
- if 0 in qubits:
311
+ if "move" in backend.architecture.gates:
312
+ if backend.num_qubits in qubits:
313
313
  raise ValueError(
314
- "Label 0 is reserved for Resonator - Please specify computational qubit labels (1,2,...)"
314
+ f"Label {backend.num_qubits} is reserved for Resonator - "
315
+ f"Please specify computational qubit labels {np.arange(backend.num_qubits)}"
315
316
  )
316
- backend_name = "IQMNdonisBackend"
317
- transpiled = reduce_to_active_qubits(transpiled, backend_name)
318
- transpiled = aux_qc.compose(transpiled, qubits=[0] + qubits, clbits=list(range(qc.num_clbits)))
317
+ backend_topology = "star"
318
+ transpiled = reduce_to_active_qubits(transpiled, backend_topology, backend.num_qubits)
319
+ transpiled = aux_qc.compose(
320
+ transpiled, qubits=qubits + [backend.num_qubits], clbits=list(range(qc.num_clbits))
321
+ )
319
322
  else:
320
323
  transpiled = aux_qc.compose(transpiled, qubits=qubits, clbits=list(range(qc.num_clbits)))
321
324
 
@@ -323,25 +326,31 @@ def perform_backend_transpilation(
323
326
 
324
327
  qcvv_logger.info(
325
328
  f"Transpiling for backend {backend.name} with optimization level {qiskit_optim_level}, "
326
- f"{routing_method} routing method{' and SQG optimization' if optimize_sqg else ''} all circuits"
329
+ f"{routing_method} routing method{' including SQG optimization' if qiskit_optim_level>0 else ''} all circuits"
327
330
  )
328
331
 
329
332
  if coupling_map == backend.coupling_map:
330
333
  transpiled_qc_list = [transpile_and_optimize(qc) for qc in qc_list]
331
334
  else: # The coupling map will be reduced if the physical layout is to be fixed
332
- aux_qc_list = [QuantumCircuit(backend.num_qubits, q.num_clbits) for q in qc_list]
335
+ if "move" in backend.architecture.gates:
336
+ aux_qc_list = [QuantumCircuit(backend.num_qubits + 1, q.num_clbits) for q in qc_list]
337
+ else:
338
+ aux_qc_list = [QuantumCircuit(backend.num_qubits, q.num_clbits) for q in qc_list]
333
339
  transpiled_qc_list = [transpile_and_optimize(qc, aux_qc=aux_qc_list[idx]) for idx, qc in enumerate(qc_list)]
334
340
 
335
341
  return transpiled_qc_list
336
342
 
337
343
 
338
- def reduce_to_active_qubits(circuit: QuantumCircuit, backend_name: Optional[str] = None) -> QuantumCircuit:
344
+ def reduce_to_active_qubits(
345
+ circuit: QuantumCircuit, backend_topology: Optional[str] = None, backend_num_qubits=None
346
+ ) -> QuantumCircuit:
339
347
  """
340
348
  Reduces a quantum circuit to only its active qubits.
341
349
 
342
350
  Args:
343
- backend_name (Optional[str]): The backend name, if any, in which the circuits are defined.
351
+ backend_topology (Optional[str]): The backend topology to execute the benchmark on.
344
352
  circuit (QuantumCircuit): The original quantum circuit.
353
+ backend_num_qubits (int): The number of qubits in the backend.
345
354
 
346
355
  Returns:
347
356
  QuantumCircuit: A new quantum circuit containing only active qubits.
@@ -351,9 +360,9 @@ def reduce_to_active_qubits(circuit: QuantumCircuit, backend_name: Optional[str]
351
360
  for instruction in circuit.data:
352
361
  for qubit in instruction.qubits:
353
362
  active_qubits.add(circuit.find_bit(qubit).index)
354
- if backend_name is not None and backend_name == "IQMNdonisBackend" and 0 not in active_qubits:
363
+ if backend_topology == "star" and backend_num_qubits not in active_qubits:
355
364
  # For star systems, the resonator must always be there, regardless of whether it MOVE gates on it or not
356
- active_qubits.add(0)
365
+ active_qubits.add(backend_num_qubits)
357
366
 
358
367
  # Create a mapping from old qubits to new qubits
359
368
  active_qubits = set(sorted(active_qubits))
@@ -453,12 +462,12 @@ def set_coupling_map(
453
462
  ValueError: if the physical layout is not "fixed" or "batching".
454
463
  """
455
464
  if physical_layout == "fixed":
456
- if "move" in backend.operation_names:
457
- if 0 in qubits:
458
- raise ValueError(
459
- "Label 0 is reserved for Resonator - Please specify computational qubit labels (1,2,...)"
460
- )
461
- return backend.coupling_map.reduce(mapping=[0] + list(qubits))
465
+ # if "move" in backend.architecture.gates:
466
+ # if 0 in qubits:
467
+ # raise ValueError(
468
+ # "Label 0 is reserved for Resonator - Please specify computational qubit labels (1,2,...)"
469
+ # )
470
+ # return backend.coupling_map.reduce(mapping=[0] + list(qubits))
462
471
  return backend.coupling_map.reduce(mapping=qubits)
463
472
  if physical_layout == "batching":
464
473
  return backend.coupling_map
@@ -561,7 +570,7 @@ def submit_execute(
561
570
  qcvv_logger.warning(
562
571
  "Both max_gates_per_batch and max_circuits_per_batch are not None. Selecting the one giving the smallest batches."
563
572
  )
564
- batching_size = min(max_circuits_per_batch, max(1, floor(max_gates_per_batch / avg_gates_per_qc)))
573
+ batching_size = min(max_circuits_per_batch, max(1, floor(max_gates_per_batch / avg_gates_per_qc))) # type: ignore
565
574
  if batching_size == max_circuits_per_batch:
566
575
  restriction = "max_circuits_per_batch"
567
576
  else:
@@ -637,13 +646,13 @@ class GraphPositions:
637
646
  }
638
647
 
639
648
  deneb_positions = {
640
- 0: (2.0, 2.0),
641
- 1: (1.0, 1.0),
642
- 3: (2.0, 1.0),
643
- 5: (3.0, 1.0),
644
- 2: (1.0, 3.0),
649
+ 6: (2.0, 2.0),
650
+ 0: (1.0, 1.0),
651
+ 1: (2.0, 1.0),
652
+ 2: (3.0, 1.0),
653
+ 3: (1.0, 3.0),
645
654
  4: (2.0, 3.0),
646
- 6: (3.0, 3.0),
655
+ 5: (3.0, 3.0),
647
656
  }
648
657
 
649
658
  predefined_stations = {
@@ -665,15 +674,15 @@ class GraphPositions:
665
674
  n_nodes = len(graph.node_indices())
666
675
 
667
676
  if topology == "star":
668
- # Place center node at (0,0)
669
- pos = {0: (0.0, 0.0)}
677
+ # Place resonator node with index n_nodes-1 at (0,0)
678
+ pos = {n_nodes - 1: (0.0, 0.0)}
670
679
 
671
680
  if n_nodes > 1:
672
681
  # Place other nodes in a circle around the center
673
682
  angles = np.linspace(0, 2 * np.pi, n_nodes - 1, endpoint=False)
674
683
  radius = 1.0
675
684
 
676
- for i, angle in enumerate(angles, start=1):
685
+ for i, angle in enumerate(angles):
677
686
  x = radius * np.cos(angle)
678
687
  y = radius * np.sin(angle)
679
688
  pos[i] = (x, y)
@@ -686,7 +695,7 @@ class GraphPositions:
686
695
  # Get spring layout with one fixed position
687
696
  pos = {
688
697
  int(k): (float(v[0]), float(v[1]))
689
- for k, v in spring_layout(graph, scale=2, pos=fixed_pos, num_iter=300, fixed={0}).items()
698
+ for k, v in spring_layout(graph, scale=2, pos=fixed_pos, num_iter=500, k=0.15, fixed={0}).items()
690
699
  }
691
700
  return pos
692
701
 
@@ -721,23 +730,21 @@ def extract_fidelities(cal_url: str) -> tuple[list[list[int]], list[float], str]
721
730
  i, j = cal_keys["cz_gate_fidelity"]
722
731
  topology = "crystal"
723
732
  for item in calibration["calibrations"][i]["metrics"][j]["metrics"]:
724
- qb1 = int(item["locus"][0][2:]) if item["locus"][0] != "COMP_R" else 0
725
- qb2 = int(item["locus"][1][2:]) if item["locus"][1] != "COMP_R" else 0
726
- if topology == "star":
727
- list_couplings.append([qb1, qb2])
728
- else:
729
- list_couplings.append([qb1 - 1, qb2 - 1])
733
+ qb1 = int(item["locus"][0][2:]) if "COMP" not in item["locus"][0] else 0
734
+ qb2 = int(item["locus"][1][2:]) if "COMP" not in item["locus"][1] else 0
735
+ list_couplings.append([qb1 - 1, qb2 - 1])
730
736
  list_fids.append(float(item["value"]))
731
737
  calibrated_qubits = set(np.array(list_couplings).reshape(-1))
732
- qubit_mapping = {qubit: idx for idx, qubit in enumerate(calibrated_qubits)}
738
+ qubit_mapping = {}
739
+ if topology == "star":
740
+ qubit_mapping.update({-1: len(calibrated_qubits)}) # Place resonator qubit as last qubit
741
+ qubit_mapping.update({qubit: idx for idx, qubit in enumerate(calibrated_qubits)})
733
742
  list_couplings = [[qubit_mapping[edge[0]], qubit_mapping[edge[1]]] for edge in list_couplings]
734
743
 
735
744
  return list_couplings, list_fids, topology
736
745
 
737
746
 
738
- def plot_layout_fidelity_graph(
739
- cal_url: str, qubit_layouts: Optional[list[list[int]]] = None, station: Optional[str] = None
740
- ):
747
+ def plot_layout_fidelity_graph(cal_url: str, qubit_layouts: Optional[list[list[int]]] = None):
741
748
  """Plot a graph showing the quantum chip layout with fidelity information.
742
749
 
743
750
  Creates a visualization of the quantum chip topology where nodes represent qubits
@@ -747,8 +754,6 @@ def plot_layout_fidelity_graph(
747
754
  Args:
748
755
  cal_url: URL to retrieve calibration data from
749
756
  qubit_layouts: List of qubit layouts where each layout is a list of qubit indices
750
- station: Name of the quantum computing station to use predefined positions for.
751
- If None, positions will be generated algorithmically.
752
757
 
753
758
  Returns:
754
759
  matplotlib.figure.Figure: The generated figure object containing the graph visualization
@@ -768,6 +773,10 @@ def plot_layout_fidelity_graph(
768
773
  # Add edges
769
774
  graph.add_edges_from(edges_graph)
770
775
 
776
+ # Extract station name from URL
777
+ parts = cal_url.strip("/").split("/")
778
+ station = parts[-2].capitalize()
779
+
771
780
  # Define qubit positions in plot
772
781
  if station in GraphPositions.predefined_stations:
773
782
  pos = GraphPositions.predefined_stations[station]
@@ -780,21 +789,7 @@ def plot_layout_fidelity_graph(
780
789
  for qb in {qb for layout in qubit_layouts for qb in layout}:
781
790
  node_colors[qb] = "orange"
782
791
 
783
- # Ensuring weights are in correct order for the plot
784
- edge_list = graph.edge_list()
785
- weights_dict = {}
786
- edge_pos = set()
787
-
788
- # Create a mapping between edge positions as defined in rustworkx and their weights
789
- for e, w in zip(edge_list, weights):
790
- pos_tuple = (tuple(pos[e[0]]), tuple(pos[e[1]]))
791
- weights_dict[pos_tuple] = w
792
- edge_pos.add(pos_tuple)
793
-
794
- # Get corresponding weights in the same order
795
- weights_ordered = np.array([weights_dict[edge] for edge in list(edge_pos)])
796
-
797
- plt.subplots(figsize=(6, 6))
792
+ plt.subplots(figsize=(1.5 * np.sqrt(len(nodes)), 1.5 * np.sqrt(len(nodes))))
798
793
 
799
794
  # Draw the graph
800
795
  visualization.mpl_draw(
@@ -803,7 +798,7 @@ def plot_layout_fidelity_graph(
803
798
  node_color=node_colors,
804
799
  pos=pos,
805
800
  labels=lambda node: node,
806
- width=7 * weights_ordered / np.max(weights_ordered),
801
+ width=5 * weights / np.max(weights),
807
802
  ) # type: ignore[call-arg]
808
803
 
809
804
  # Add edge labels using matplotlib's annotate
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: iqm-benchmarks
3
- Version: 2.25
3
+ Version: 2.27
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
@@ -16,10 +16,11 @@ Requires-Dist: matplotlib<4,>=3.6.3
16
16
  Requires-Dist: more-itertools<11.0.0,>=10.1.0
17
17
  Requires-Dist: mthree<2.7,>=2.6
18
18
  Requires-Dist: networkx<4.0,>=3.3
19
- Requires-Dist: rustworkx>=0.15.1
19
+ Requires-Dist: rustworkx>=0.16.0
20
20
  Requires-Dist: numpy<2.0,>=1.25.2
21
- Requires-Dist: qiskit<2.0,>=1.0
22
- Requires-Dist: qiskit-iqm<16.0,>=15.1
21
+ Requires-Dist: qiskit<2.0,>=1.2.4
22
+ Requires-Dist: qiskit-iqm<18.0,>=17.8
23
+ Requires-Dist: iqm-client>=22.7
23
24
  Requires-Dist: scikit-optimize<0.11.0,>=0.10.2
24
25
  Requires-Dist: tabulate<1.0.0,>=0.9.0
25
26
  Requires-Dist: uncertainties<3.3.0,>=3.2.2
@@ -50,6 +51,7 @@ Provides-Extra: docs
50
51
  Requires-Dist: sphinx==7.2.6; extra == "docs"
51
52
  Requires-Dist: sphinx-book-theme==1.1.2; extra == "docs"
52
53
  Requires-Dist: myst-parser<5,>=4.0.0; extra == "docs"
54
+ Dynamic: license-file
53
55
 
54
56
  # IQM Benchmarks
55
57
 
@@ -4,40 +4,40 @@ 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=3k3YkLfqHByedVlnSRCeKnt65J60msylGR18mz8sYAA,33435
7
+ iqm/benchmarks/utils.py,sha256=4Yd1Qa5v8JKW8wEu8b4a1a30twJUOWlY0K-JlW9h5k4,33328
8
8
  iqm/benchmarks/compressive_gst/__init__.py,sha256=LneifgYXtcwo2jcXo7GdUEHL6_peipukShhkrdaTRCA,929
9
- iqm/benchmarks/compressive_gst/compressive_gst.py,sha256=G9vw5esrSwTVFuFNzL-Oyb1vYuA-HKmdnmnfgV74L54,25459
10
- iqm/benchmarks/compressive_gst/gst_analysis.py,sha256=2qY46e-euAcdThcits_Wo7hGb0m69mDZY0d1Qv_wq4M,36104
9
+ iqm/benchmarks/compressive_gst/compressive_gst.py,sha256=2kiRttog4jR-vtMHu847GTFe5qL_i_uYr_4WMGqt9Ww,25653
10
+ iqm/benchmarks/compressive_gst/gst_analysis.py,sha256=jA1MaXIyPBwxbN36mTjn_jKaRO5-NdoG0YV-RaujU3s,36450
11
11
  iqm/benchmarks/entanglement/__init__.py,sha256=9T7prOwqMmFWdb4t6ETAHZXKK5o6FvU2DvVb6WhNi-U,682
12
- iqm/benchmarks/entanglement/ghz.py,sha256=jSPcdFf1Xsq09EJXKCVHzNXjQIdAoDg859279wKGjaQ,41075
12
+ iqm/benchmarks/entanglement/ghz.py,sha256=RGA6ynJFsfaCJv0nKccsiIzPk2G-iHHvIeW8LVu30HY,41249
13
13
  iqm/benchmarks/optimization/__init__.py,sha256=_ajW_OibYLCtzU5AUv5c2zuuVYn8ZNeZUcUUSIGt51M,747
14
- iqm/benchmarks/optimization/qscore.py,sha256=59iGjk7foCHlYRs0j8ZVFvvxnEGhr4u2SSpOW3TLNU4,38047
14
+ iqm/benchmarks/optimization/qscore.py,sha256=KOw8fjXeMwCjYvKukpX7IiAqRQrVTkrnIgKjNCPVWdw,38130
15
15
  iqm/benchmarks/quantum_volume/__init__.py,sha256=i-Q4SpDWELBw7frXnxm1j4wJRcxbIyrS5uEK_v06YHo,951
16
- iqm/benchmarks/quantum_volume/clops.py,sha256=xlziaxjhJUNyHjBCMzMLeJ9PcFNBtDO7urKvCTBb4sI,31471
16
+ iqm/benchmarks/quantum_volume/clops.py,sha256=fD_eh10qHv_W-_mCA-PjPDIxNJ5sqD7yDkK1UjRsAAo,31474
17
17
  iqm/benchmarks/quantum_volume/quantum_volume.py,sha256=4ll3R8AX-BA599TEaMBzE2rJtAzHLtCkq8CaSkJfA0Y,36626
18
18
  iqm/benchmarks/randomized_benchmarking/__init__.py,sha256=IkKo-7zUChxZZd3my_csQCJfJfZNsV3-JTvdG8uqys4,734
19
- iqm/benchmarks/randomized_benchmarking/clifford_1q.pkl,sha256=vvSd0pRWxtzyirohO9yf_58mjevkc2-pbuWIEb-4gaw,46928
20
- iqm/benchmarks/randomized_benchmarking/clifford_2q.pkl,sha256=ZipqU3crPhz2T35qGFgB4GvMyoi_7pnu8NqW5ZP8NXg,90707258
19
+ iqm/benchmarks/randomized_benchmarking/clifford_1q.pkl,sha256=yrmSJqhv7Lb1yqiqU9-2baqTljJPNmTUPQR-AH6GGfc,7800
20
+ iqm/benchmarks/randomized_benchmarking/clifford_2q.pkl,sha256=mJQLubWPOb-DbmFi4oKYJqAMW_Yyo3eJjRjLGl9Sqmo,10282247
21
21
  iqm/benchmarks/randomized_benchmarking/multi_lmfit.py,sha256=Se1ygR4mXn_2_P82Ch31KBnCmY-g_A9NKzE9Ir8nEvw,3247
22
- iqm/benchmarks/randomized_benchmarking/randomized_benchmarking_common.py,sha256=6sOGPoeJFVCrvTVhDjxbJPrD728pXTzbhuApEgQH1rc,42304
22
+ iqm/benchmarks/randomized_benchmarking/randomized_benchmarking_common.py,sha256=pe9wSFvQ6Vh7rWZNZalIKOeaHoXc8iT4pkvrcLmY75g,42352
23
23
  iqm/benchmarks/randomized_benchmarking/clifford_rb/__init__.py,sha256=bTDA156LAl7OLGcMec--1nzDrV1XpPRVq3CquTmucgE,677
24
- iqm/benchmarks/randomized_benchmarking/clifford_rb/clifford_rb.py,sha256=ksa-R8CMDwXniVNvPky5pogCDmifOqjHd5KNEqGzujs,18560
24
+ iqm/benchmarks/randomized_benchmarking/clifford_rb/clifford_rb.py,sha256=IGBrq_a9eaVPknkBLKHKS4BOcumHn6TZdasUNKTZjGI,18685
25
25
  iqm/benchmarks/randomized_benchmarking/interleaved_rb/__init__.py,sha256=sq6MgN_hwlpkOj10vyCU4e6eKSX-oLcF2L9na6W2Gt4,681
26
- iqm/benchmarks/randomized_benchmarking/interleaved_rb/interleaved_rb.py,sha256=lhv8703QJY5j-CUMgAyG9RxVhQKrGljejJaxL5GbILg,28442
26
+ iqm/benchmarks/randomized_benchmarking/interleaved_rb/interleaved_rb.py,sha256=TaR1YFWBhOgm1hmEQzuwLYpp0yl0Xpuo3jAT6YhiXpc,28471
27
27
  iqm/benchmarks/randomized_benchmarking/mirror_rb/__init__.py,sha256=ZekEqI_89nXzGO1vjM-b5Uwwicy59M4fYHXfA-f0MIg,674
28
- iqm/benchmarks/randomized_benchmarking/mirror_rb/mirror_rb.py,sha256=X5rcmCePbVZ9tsMmh8xw3pTskdMKuHrqW_-pGkX0klg,34982
28
+ iqm/benchmarks/randomized_benchmarking/mirror_rb/mirror_rb.py,sha256=_xdp8XLPcZyuqy7Xz8-K8H7zjgRo9ZxFiDgCXE72gaE,34997
29
+ iqm_benchmarks-2.27.dist-info/licenses/LICENSE,sha256=2Ncb40-hqkTil78RPv3-YiJfKaJ8te9USJgliKqIdSY,11558
29
30
  mGST/LICENSE,sha256=TtHNq55cUcbglb7uhVudeBLUh_qPdUoAEvU0BBwFz-k,1098
30
31
  mGST/README.md,sha256=v_5kw253csHF4-RfE-44KqFmBXIsSMRmOtN0AUPrRxE,5050
31
32
  mGST/additional_fns.py,sha256=_SEJ10FRNM7_CroysT8hCLZTfpm6ZhEIDCY5zPTnhjo,31390
32
- mGST/algorithm.py,sha256=SRwC1sVFShRVxQDfH1bhUvnquvgwJFLSiZ70qo5SwxE,26314
33
+ mGST/algorithm.py,sha256=QnxLJtxZysggLUtbZE-c2MWaFclZB2XUVJhvrmUvjVs,26315
33
34
  mGST/compatibility.py,sha256=00DsPnNfOtrQcDTvxBDs-0aMhmuXmOIIxl_Ohy-Emkg,8920
34
35
  mGST/low_level_jit.py,sha256=uE1D3v01FbPpsbP92C4220OQalzOfxgL1Ku89BNkxLY,27377
35
36
  mGST/optimization.py,sha256=YHwkzIkYvsZOPjclR-BCQWh24jeqjuXp0BB0WX5Lwow,10559
36
37
  mGST/qiskit_interface.py,sha256=ajx6Zn5FnrX_T7tMP8xnBLyG4c2ddFRm0Fu2_3r1t30,10118
37
38
  mGST/reporting/figure_gen.py,sha256=6Xd8vwfy09hLY1YbJY6TRevuMsQSU4MsWqemly3ZO0I,12970
38
39
  mGST/reporting/reporting.py,sha256=B8NWfpZrrSmyH7lwZxd0EbZMYLsAGK1YsHRB4D5qXH4,26002
39
- iqm_benchmarks-2.25.dist-info/LICENSE,sha256=2Ncb40-hqkTil78RPv3-YiJfKaJ8te9USJgliKqIdSY,11558
40
- iqm_benchmarks-2.25.dist-info/METADATA,sha256=ietRHvwVJDYDtSCZjRtPSLjPjLvq0-4jU7TFZiC9Aa0,10533
41
- iqm_benchmarks-2.25.dist-info/WHEEL,sha256=beeZ86-EfXScwlR_HKu4SllMC9wUEj_8Z_4FJ3egI2w,91
42
- iqm_benchmarks-2.25.dist-info/top_level.txt,sha256=3G23Z-1LGf-IOzTCUl6QwWqiQ3USz25Zt90Ihq192to,9
43
- iqm_benchmarks-2.25.dist-info/RECORD,,
40
+ iqm_benchmarks-2.27.dist-info/METADATA,sha256=Kk7NahsiPhEhEGtiR8CWkDNuUZCtysZTwu1QBRHlK2U,10589
41
+ iqm_benchmarks-2.27.dist-info/WHEEL,sha256=L0N565qmK-3nM2eBoMNFszYJ_MTx03_tQ0CQu1bHLYo,91
42
+ iqm_benchmarks-2.27.dist-info/top_level.txt,sha256=3G23Z-1LGf-IOzTCUl6QwWqiQ3USz25Zt90Ihq192to,9
43
+ iqm_benchmarks-2.27.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (76.1.0)
2
+ Generator: setuptools (78.0.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
mGST/algorithm.py CHANGED
@@ -727,7 +727,7 @@ def run_mGST(
727
727
  qcvv_logger.info(f"Convergence criterion satisfied")
728
728
  else:
729
729
  qcvv_logger.info(
730
- f"Convergence criterion not satisfied,inspect results and consider increasing max_iter or using new initializations.",
730
+ f"Convergence criterion not satisfied, inspect results and consider increasing max_iter or using new initializations.",
731
731
  )
732
732
  qcvv_logger.info(
733
733
  f"Final objective {Decimal(res_list[-1]):.2e} in time {(time.time() - t0):.2f}s",