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.
- iqm/benchmarks/compressive_gst/compressive_gst.py +24 -21
- iqm/benchmarks/compressive_gst/gst_analysis.py +31 -22
- iqm/benchmarks/entanglement/ghz.py +10 -10
- iqm/benchmarks/optimization/qscore.py +7 -6
- iqm/benchmarks/quantum_volume/clops.py +1 -1
- iqm/benchmarks/randomized_benchmarking/clifford_1q.pkl +0 -0
- iqm/benchmarks/randomized_benchmarking/clifford_2q.pkl +0 -0
- iqm/benchmarks/randomized_benchmarking/clifford_rb/clifford_rb.py +9 -4
- iqm/benchmarks/randomized_benchmarking/interleaved_rb/interleaved_rb.py +6 -6
- iqm/benchmarks/randomized_benchmarking/mirror_rb/mirror_rb.py +4 -4
- iqm/benchmarks/randomized_benchmarking/randomized_benchmarking_common.py +12 -12
- iqm/benchmarks/utils.py +56 -61
- {iqm_benchmarks-2.25.dist-info → iqm_benchmarks-2.27.dist-info}/METADATA +7 -5
- {iqm_benchmarks-2.25.dist-info → iqm_benchmarks-2.27.dist-info}/RECORD +18 -18
- {iqm_benchmarks-2.25.dist-info → iqm_benchmarks-2.27.dist-info}/WHEEL +1 -1
- mGST/algorithm.py +1 -1
- {iqm_benchmarks-2.25.dist-info → iqm_benchmarks-2.27.dist-info/licenses}/LICENSE +0 -0
- {iqm_benchmarks-2.25.dist-info → iqm_benchmarks-2.27.dist-info}/top_level.txt +0 -0
|
@@ -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
|
-
|
|
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(
|
|
167
|
+
circ_parallel = QuantumCircuit(len(backend_qubits), len(set(all_qubits)))
|
|
165
168
|
clbits = np.arange(self.num_qubits)
|
|
166
|
-
for qubit_layout in
|
|
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=
|
|
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. "
|
|
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. "
|
|
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", "
|
|
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 = ["
|
|
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
|
-
"
|
|
491
|
-
"
|
|
492
|
-
"
|
|
493
|
-
"
|
|
494
|
-
"
|
|
495
|
-
"
|
|
496
|
-
"
|
|
497
|
-
"
|
|
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 = ["
|
|
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 + ":" + "
|
|
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"
|
|
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"
|
|
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"
|
|
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"
|
|
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"
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
f"
|
|
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"
|
|
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"
|
|
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
|
-
"
|
|
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
|
-
"
|
|
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"
|
|
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"
|
|
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"
|
|
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
|
-
"
|
|
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
|
-
"
|
|
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
|
-
"
|
|
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}
|
|
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
|
-
|
|
824
|
-
|
|
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=
|
|
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
|
-
|
|
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,
|
|
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
|
-
|
|
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(
|
|
626
|
+
graph = get_edges(self.backend.coupling_map, qubit_layout, edges_cal, fidelities_cal)
|
|
629
627
|
else:
|
|
630
|
-
graph = get_edges(
|
|
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(
|
|
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(
|
|
485
|
+
identifier=BenchmarkObservationIdentifier(qubit_indices),
|
|
485
486
|
),
|
|
486
487
|
BenchmarkObservation(
|
|
487
488
|
name="is_succesful",
|
|
488
489
|
value=str(success),
|
|
489
|
-
identifier=BenchmarkObservationIdentifier(
|
|
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(
|
|
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.
|
|
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
|
|
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.
|
|
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(
|
|
Binary file
|
|
Binary file
|
|
@@ -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
|
-
"
|
|
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
|
-
{
|
|
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
|
-
"
|
|
144
|
-
"
|
|
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
|
-
"
|
|
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
|
-
"
|
|
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
|
-
"
|
|
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}_{
|
|
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
|
-
"
|
|
220
|
-
"
|
|
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.
|
|
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
|
-
"
|
|
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
|
-
"
|
|
535
|
-
"
|
|
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]["
|
|
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]["
|
|
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]["
|
|
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]["
|
|
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]["
|
|
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]["
|
|
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]["
|
|
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]["
|
|
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]["
|
|
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]["
|
|
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]["
|
|
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]["
|
|
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
|
|
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.
|
|
312
|
-
if
|
|
311
|
+
if "move" in backend.architecture.gates:
|
|
312
|
+
if backend.num_qubits in qubits:
|
|
313
313
|
raise ValueError(
|
|
314
|
-
"Label
|
|
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
|
-
|
|
317
|
-
transpiled = reduce_to_active_qubits(transpiled,
|
|
318
|
-
transpiled = aux_qc.compose(
|
|
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{'
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
|
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(
|
|
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.
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
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
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
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
|
-
|
|
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
|
|
669
|
-
pos = {
|
|
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
|
|
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=
|
|
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]
|
|
725
|
-
qb2 = int(item["locus"][1][2:]) if item["locus"][1]
|
|
726
|
-
|
|
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 = {
|
|
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
|
-
|
|
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=
|
|
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.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: iqm-benchmarks
|
|
3
|
-
Version: 2.
|
|
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.
|
|
19
|
+
Requires-Dist: rustworkx>=0.16.0
|
|
20
20
|
Requires-Dist: numpy<2.0,>=1.25.2
|
|
21
|
-
Requires-Dist: qiskit<2.0,>=1.
|
|
22
|
-
Requires-Dist: qiskit-iqm<
|
|
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=
|
|
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=
|
|
10
|
-
iqm/benchmarks/compressive_gst/gst_analysis.py,sha256=
|
|
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=
|
|
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=
|
|
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=
|
|
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=
|
|
20
|
-
iqm/benchmarks/randomized_benchmarking/clifford_2q.pkl,sha256=
|
|
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=
|
|
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=
|
|
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=
|
|
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=
|
|
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=
|
|
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.
|
|
40
|
-
iqm_benchmarks-2.
|
|
41
|
-
iqm_benchmarks-2.
|
|
42
|
-
iqm_benchmarks-2.
|
|
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,,
|
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",
|
|
File without changes
|
|
File without changes
|