iqm-benchmarks 1.12__py3-none-any.whl → 2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of iqm-benchmarks might be problematic. Click here for more details.
- iqm/benchmarks/__init__.py +1 -0
- iqm/benchmarks/benchmark_definition.py +15 -12
- iqm/benchmarks/circuit_containers.py +221 -0
- iqm/benchmarks/compressive_gst/compressive_gst.py +11 -4
- iqm/benchmarks/entanglement/ghz.py +101 -89
- iqm/benchmarks/optimization/qscore.py +1 -1
- iqm/benchmarks/quantum_volume/clops.py +13 -32
- iqm/benchmarks/quantum_volume/quantum_volume.py +18 -19
- iqm/benchmarks/randomized_benchmarking/clifford_rb/clifford_rb.py +23 -14
- iqm/benchmarks/randomized_benchmarking/interleaved_rb/interleaved_rb.py +48 -30
- iqm/benchmarks/randomized_benchmarking/mirror_rb/mirror_rb.py +14 -31
- iqm/benchmarks/randomized_benchmarking/randomized_benchmarking_common.py +2 -1
- iqm/benchmarks/readout_mitigation.py +2 -1
- iqm/benchmarks/utils.py +2 -1
- {iqm_benchmarks-1.12.dist-info → iqm_benchmarks-2.0.dist-info}/METADATA +1 -1
- {iqm_benchmarks-1.12.dist-info → iqm_benchmarks-2.0.dist-info}/RECORD +20 -19
- mGST/qiskit_interface.py +1 -1
- {iqm_benchmarks-1.12.dist-info → iqm_benchmarks-2.0.dist-info}/LICENSE +0 -0
- {iqm_benchmarks-1.12.dist-info → iqm_benchmarks-2.0.dist-info}/WHEEL +0 -0
- {iqm_benchmarks-1.12.dist-info → iqm_benchmarks-2.0.dist-info}/top_level.txt +0 -0
|
@@ -28,7 +28,7 @@ import networkx
|
|
|
28
28
|
from networkx import Graph, all_pairs_shortest_path, is_connected, minimum_spanning_tree
|
|
29
29
|
import numpy as np
|
|
30
30
|
import pycurl
|
|
31
|
-
from qiskit import
|
|
31
|
+
from qiskit import QuantumRegister, transpile
|
|
32
32
|
from qiskit.quantum_info import random_clifford
|
|
33
33
|
from qiskit.transpiler import CouplingMap
|
|
34
34
|
from qiskit_aer import Aer
|
|
@@ -44,6 +44,7 @@ from iqm.benchmarks.benchmark_definition import (
|
|
|
44
44
|
BenchmarkRunResult,
|
|
45
45
|
add_counts_to_dataset,
|
|
46
46
|
)
|
|
47
|
+
from iqm.benchmarks.circuit_containers import BenchmarkCircuit, CircuitGroup, Circuits
|
|
47
48
|
from iqm.benchmarks.logging_config import qcvv_logger
|
|
48
49
|
from iqm.benchmarks.readout_mitigation import apply_readout_error_mitigation
|
|
49
50
|
from iqm.benchmarks.utils import (
|
|
@@ -55,6 +56,7 @@ from iqm.benchmarks.utils import (
|
|
|
55
56
|
timeit,
|
|
56
57
|
xrvariable_to_counts,
|
|
57
58
|
)
|
|
59
|
+
from iqm.qiskit_iqm import IQMCircuit as QuantumCircuit
|
|
58
60
|
from iqm.qiskit_iqm.iqm_backend import IQMBackendBase
|
|
59
61
|
|
|
60
62
|
|
|
@@ -94,16 +96,13 @@ def append_rms(
|
|
|
94
96
|
rm_circ.compose(rand_clifford, qubits=[q], inplace=True)
|
|
95
97
|
|
|
96
98
|
rm_circ.measure_active()
|
|
97
|
-
# if backend is not None and backend.name != "IQMNdonisBackend" and optimize_sqg:
|
|
98
|
-
# rm_circuits.append(optimize_single_qubit_gates(rm_circ))
|
|
99
|
-
# else:
|
|
100
99
|
rm_circuits.append(transpile(rm_circ, basis_gates=backend.operation_names))
|
|
101
100
|
|
|
102
101
|
return rm_circuits
|
|
103
102
|
|
|
104
103
|
|
|
105
104
|
def fidelity_ghz_randomized_measurements(
|
|
106
|
-
dataset: xr.Dataset, qubit_layout, ideal_probabilities: List[Dict[str, int]], num_qubits: int
|
|
105
|
+
dataset: xr.Dataset, qubit_layout, ideal_probabilities: List[Dict[str, int]], num_qubits: int, circuits: Circuits
|
|
107
106
|
) -> tuple[dict[str, Any], dict[str, Any]]:
|
|
108
107
|
"""
|
|
109
108
|
Estimates GHZ state fidelity through cross-correlations of RMs.
|
|
@@ -113,7 +112,8 @@ def fidelity_ghz_randomized_measurements(
|
|
|
113
112
|
dataset (xr.Dataset):
|
|
114
113
|
qubit_layout: List[int]: The subset of system-qubits used in the protocol
|
|
115
114
|
ideal_probabilities (List[Dict[str, int]]):
|
|
116
|
-
num_qubits (int):
|
|
115
|
+
num_qubits (int): Number of qubits
|
|
116
|
+
circuits (Circuits): Instance of `Circuits` containing transpiled circuits
|
|
117
117
|
Returns:
|
|
118
118
|
values: dict[str, Any]
|
|
119
119
|
The fidelities
|
|
@@ -125,7 +125,7 @@ def fidelity_ghz_randomized_measurements(
|
|
|
125
125
|
fid_rm = []
|
|
126
126
|
|
|
127
127
|
# Loop through RMs and add each contribution
|
|
128
|
-
num_rms = len(
|
|
128
|
+
num_rms = len(circuits["transpiled_circuits"][f"{idx}_native_ghz"].circuits)
|
|
129
129
|
for u in range(num_rms):
|
|
130
130
|
# Probability estimates for noisy measurements
|
|
131
131
|
probabilities_sample = {}
|
|
@@ -168,7 +168,7 @@ def fidelity_ghz_randomized_measurements(
|
|
|
168
168
|
return values, uncertainties
|
|
169
169
|
|
|
170
170
|
|
|
171
|
-
def fidelity_ghz_coherences(dataset: xr.Dataset, qubit_layout: List[int]) -> list[Any]:
|
|
171
|
+
def fidelity_ghz_coherences(dataset: xr.Dataset, qubit_layout: List[int], circuits: Circuits) -> list[Any]:
|
|
172
172
|
"""
|
|
173
173
|
Estimates the GHZ state fidelity based on the multiple quantum coherences method based on [Mooney, 2021]
|
|
174
174
|
|
|
@@ -177,6 +177,8 @@ def fidelity_ghz_coherences(dataset: xr.Dataset, qubit_layout: List[int]) -> lis
|
|
|
177
177
|
An xarray dataset containing the measurement data
|
|
178
178
|
qubit_layout: List[int]
|
|
179
179
|
The subset of system-qubits used in the protocol
|
|
180
|
+
circuits: Circuits
|
|
181
|
+
Instance of `Circuits` containing transpiled circuits
|
|
180
182
|
|
|
181
183
|
Returns:
|
|
182
184
|
dict[str, dict[str, Any]]: The ghz fidelity or, if rem=True, fidelity and readout error mitigated fidelity
|
|
@@ -185,9 +187,9 @@ def fidelity_ghz_coherences(dataset: xr.Dataset, qubit_layout: List[int]) -> lis
|
|
|
185
187
|
num_qubits = len(qubit_layout)
|
|
186
188
|
phases = [np.pi * i / (num_qubits + 1) for i in range(2 * num_qubits + 2)]
|
|
187
189
|
idx = BenchmarkObservationIdentifier(qubit_layout).string_identifier
|
|
188
|
-
transpiled_circuits =
|
|
190
|
+
transpiled_circuits = circuits["transpiled_circuits"]
|
|
189
191
|
num_shots = dataset.attrs["shots"]
|
|
190
|
-
num_circuits = len(transpiled_circuits)
|
|
192
|
+
num_circuits = len(transpiled_circuits[f"{qubit_layout}_native_ghz"].circuits)
|
|
191
193
|
|
|
192
194
|
# Computing the phase acquired by the |11...1> component for each interval
|
|
193
195
|
complex_coefficients = np.exp(1j * num_qubits * np.array(phases))
|
|
@@ -250,45 +252,50 @@ def fidelity_analysis(run: BenchmarkRunResult) -> BenchmarkAnalysisResult:
|
|
|
250
252
|
|
|
251
253
|
observation_list: list[BenchmarkObservation] = []
|
|
252
254
|
for qubit_layout in qubit_layouts:
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
)
|
|
266
|
-
observation_list.extend(
|
|
267
|
-
[
|
|
268
|
-
BenchmarkObservation(
|
|
269
|
-
name=key,
|
|
270
|
-
identifier=BenchmarkObservationIdentifier(qubit_layout),
|
|
271
|
-
value=value,
|
|
272
|
-
uncertainty=uncertainties[key],
|
|
273
|
-
)
|
|
274
|
-
for key, value in values.items()
|
|
275
|
-
]
|
|
276
|
-
)
|
|
277
|
-
else: # default routine == "coherences":
|
|
278
|
-
fidelity = fidelity_ghz_coherences(dataset, qubit_layout)
|
|
279
|
-
observation_list.extend(
|
|
280
|
-
[
|
|
281
|
-
BenchmarkObservation(
|
|
282
|
-
name="fidelity", identifier=BenchmarkObservationIdentifier(qubit_layout), value=fidelity[0]
|
|
283
|
-
)
|
|
284
|
-
]
|
|
285
|
-
)
|
|
286
|
-
if len(fidelity) > 1:
|
|
287
|
-
observation_list.append(
|
|
288
|
-
BenchmarkObservation(
|
|
289
|
-
name="fidelity_rem", identifier=BenchmarkObservationIdentifier(qubit_layout), value=fidelity[1]
|
|
255
|
+
match routine:
|
|
256
|
+
case "randomized_measurements":
|
|
257
|
+
ideal_simulator = Aer.get_backend("statevector_simulator")
|
|
258
|
+
ideal_probabilities = []
|
|
259
|
+
idx = BenchmarkObservationIdentifier(qubit_layout).string_identifier
|
|
260
|
+
all_circuits = run.circuits["transpiled_circuits"][f"{idx}_native_ghz"].circuits
|
|
261
|
+
for qc in all_circuits:
|
|
262
|
+
qc_copy = qc.copy()
|
|
263
|
+
qc_copy.remove_final_measurements()
|
|
264
|
+
deflated_qc = reduce_to_active_qubits(qc_copy, backend_name)
|
|
265
|
+
ideal_probabilities.append(
|
|
266
|
+
dict(sorted(ideal_simulator.run(deflated_qc).result().get_counts().items()))
|
|
290
267
|
)
|
|
268
|
+
values, uncertainties = fidelity_ghz_randomized_measurements(
|
|
269
|
+
dataset, qubit_layout, ideal_probabilities, len(qubit_layout), run.circuits
|
|
291
270
|
)
|
|
271
|
+
observation_list.extend(
|
|
272
|
+
[
|
|
273
|
+
BenchmarkObservation(
|
|
274
|
+
name=key,
|
|
275
|
+
identifier=BenchmarkObservationIdentifier(qubit_layout),
|
|
276
|
+
value=value,
|
|
277
|
+
uncertainty=uncertainties[key],
|
|
278
|
+
)
|
|
279
|
+
for key, value in values.items()
|
|
280
|
+
]
|
|
281
|
+
)
|
|
282
|
+
case "coherences":
|
|
283
|
+
fidelity = fidelity_ghz_coherences(dataset, qubit_layout, run.circuits)
|
|
284
|
+
observation_list.extend(
|
|
285
|
+
[
|
|
286
|
+
BenchmarkObservation(
|
|
287
|
+
name="fidelity", identifier=BenchmarkObservationIdentifier(qubit_layout), value=fidelity[0]
|
|
288
|
+
)
|
|
289
|
+
]
|
|
290
|
+
)
|
|
291
|
+
if len(fidelity) > 1:
|
|
292
|
+
observation_list.append(
|
|
293
|
+
BenchmarkObservation(
|
|
294
|
+
name="fidelity_rem",
|
|
295
|
+
identifier=BenchmarkObservationIdentifier(qubit_layout),
|
|
296
|
+
value=fidelity[1],
|
|
297
|
+
)
|
|
298
|
+
)
|
|
292
299
|
plots = {"All layout fidelities": plot_fidelities(observation_list, qubit_layouts)}
|
|
293
300
|
return BenchmarkAnalysisResult(dataset=dataset, observations=observation_list, plots=plots)
|
|
294
301
|
|
|
@@ -304,7 +311,8 @@ def generate_ghz_linear(num_qubits: int) -> QuantumCircuit:
|
|
|
304
311
|
A quantum circuit generating a GHZ state of n qubits
|
|
305
312
|
"""
|
|
306
313
|
s = int(num_qubits / 2)
|
|
307
|
-
|
|
314
|
+
quantum_register = QuantumRegister(num_qubits)
|
|
315
|
+
qc = QuantumCircuit(quantum_register, name="GHZ_linear")
|
|
308
316
|
qc.h(s)
|
|
309
317
|
|
|
310
318
|
for m in range(s, 0, -1):
|
|
@@ -325,7 +333,8 @@ def generate_ghz_log_cruz(num_qubits: int) -> QuantumCircuit:
|
|
|
325
333
|
Returns:
|
|
326
334
|
A quantum circuit generating a GHZ state of n qubits
|
|
327
335
|
"""
|
|
328
|
-
|
|
336
|
+
quantum_register = QuantumRegister(num_qubits)
|
|
337
|
+
qc = QuantumCircuit(quantum_register, name="GHZ_log_Cruz")
|
|
329
338
|
qc.h(0)
|
|
330
339
|
|
|
331
340
|
for m in range(num_qubits):
|
|
@@ -346,7 +355,8 @@ def generate_ghz_log_mooney(num_qubits: int) -> QuantumCircuit:
|
|
|
346
355
|
Returns:
|
|
347
356
|
A quantum circuit generating a GHZ state of n qubits
|
|
348
357
|
"""
|
|
349
|
-
|
|
358
|
+
quantum_register = QuantumRegister(num_qubits)
|
|
359
|
+
qc = QuantumCircuit(quantum_register, name="GHZ_log_Mooney")
|
|
350
360
|
qc.h(0)
|
|
351
361
|
|
|
352
362
|
aux_n = int(np.ceil(np.log2(num_qubits)))
|
|
@@ -389,7 +399,8 @@ def generate_ghz_spanning_tree(
|
|
|
389
399
|
participating_qubits = set(qubit for pair in cx_map[: n_state - 1] for qubit in pair)
|
|
390
400
|
|
|
391
401
|
relabeling = {idx_old: idx_new for idx_new, idx_old in enumerate(participating_qubits)}
|
|
392
|
-
|
|
402
|
+
n_state_register = QuantumRegister(n_state)
|
|
403
|
+
qc = QuantumCircuit(n_state_register, name="ghz")
|
|
393
404
|
qc.h([relabeling[cx_map[0][0]]])
|
|
394
405
|
for _, pair in zip(np.arange(n_state - 1), cx_map):
|
|
395
406
|
relabeled_pair = [relabeling[pair[0]], relabeling[pair[1]]]
|
|
@@ -594,7 +605,6 @@ class GHZBenchmark(Benchmark):
|
|
|
594
605
|
super().__init__(backend, configuration)
|
|
595
606
|
|
|
596
607
|
self.state_generation_routine = configuration.state_generation_routine
|
|
597
|
-
# self.choose_qubits_routine = configuration.choose_qubits_routine
|
|
598
608
|
if configuration.custom_qubits_array:
|
|
599
609
|
self.custom_qubits_array = configuration.custom_qubits_array
|
|
600
610
|
else:
|
|
@@ -606,7 +616,6 @@ class GHZBenchmark(Benchmark):
|
|
|
606
616
|
if any(np.max(configuration.qubit_counts) > [len(layout) for layout in self.custom_qubits_array]):
|
|
607
617
|
raise ValueError("The maximum given qubit count is larger than the size of the smallest qubit layout.")
|
|
608
618
|
self.qubit_counts = configuration.qubit_counts
|
|
609
|
-
# self.layout_idx_mapping = {str(qubit_layout): idx for idx, qubit_layout in enumerate(self.custom_qubits_array)}
|
|
610
619
|
|
|
611
620
|
self.qiskit_optim_level = configuration.qiskit_optim_level
|
|
612
621
|
self.optimize_sqg = configuration.optimize_sqg
|
|
@@ -617,11 +626,7 @@ class GHZBenchmark(Benchmark):
|
|
|
617
626
|
self.cal_url = configuration.cal_url
|
|
618
627
|
self.timestamp = strftime("%Y%m%d-%H%M%S")
|
|
619
628
|
|
|
620
|
-
|
|
621
|
-
# def name() -> str:
|
|
622
|
-
# return "ghz"
|
|
623
|
-
|
|
624
|
-
def generate_native_ghz(self, qubit_layout: List[int], qubit_count: int, routine: str) -> QuantumCircuit:
|
|
629
|
+
def generate_native_ghz(self, qubit_layout: List[int], qubit_count: int, routine: str) -> CircuitGroup:
|
|
625
630
|
"""
|
|
626
631
|
Generate a circuit preparing a GHZ state,
|
|
627
632
|
according to a given routine and transpiled to the native gate set and topology.
|
|
@@ -638,13 +643,13 @@ class GHZBenchmark(Benchmark):
|
|
|
638
643
|
Returns:
|
|
639
644
|
QuantumCircuit implementing GHZ native state
|
|
640
645
|
"""
|
|
641
|
-
|
|
646
|
+
circuit_group = CircuitGroup(name=f"{qubit_layout}_native_ghz")
|
|
642
647
|
fixed_coupling_map = set_coupling_map(qubit_layout, self.backend, "fixed")
|
|
643
|
-
idx = BenchmarkObservationIdentifier(qubit_layout).string_identifier
|
|
644
648
|
ghz_native_transpiled: List[QuantumCircuit]
|
|
649
|
+
|
|
645
650
|
if routine == "naive":
|
|
646
|
-
ghz = generate_ghz_linear(qubit_count)
|
|
647
|
-
|
|
651
|
+
ghz: QuantumCircuit = generate_ghz_linear(qubit_count)
|
|
652
|
+
circuit_group.add_circuit(ghz)
|
|
648
653
|
ghz_native_transpiled, _ = perform_backend_transpilation(
|
|
649
654
|
[ghz],
|
|
650
655
|
self.backend,
|
|
@@ -661,7 +666,7 @@ class GHZBenchmark(Benchmark):
|
|
|
661
666
|
else:
|
|
662
667
|
graph = get_edges(self.backend.coupling_map, qubit_layout)
|
|
663
668
|
ghz, _ = generate_ghz_spanning_tree(graph, qubit_layout, qubit_count)
|
|
664
|
-
|
|
669
|
+
circuit_group.add_circuit(ghz)
|
|
665
670
|
ghz_native_transpiled, _ = perform_backend_transpilation(
|
|
666
671
|
[ghz],
|
|
667
672
|
self.backend,
|
|
@@ -685,12 +690,13 @@ class GHZBenchmark(Benchmark):
|
|
|
685
690
|
if ghz_native_transpiled[0].depth() == ghz_native_transpiled[1].depth():
|
|
686
691
|
index_min_2q = np.argmin([c.count_ops()["cz"] for c in ghz_native_transpiled])
|
|
687
692
|
final_ghz = ghz_native_transpiled[index_min_2q]
|
|
688
|
-
|
|
693
|
+
circuit_group.add_circuit(ghz_log[index_min_2q])
|
|
689
694
|
else:
|
|
690
695
|
index_min_depth = np.argmin([c.depth() for c in ghz_native_transpiled])
|
|
691
696
|
final_ghz = ghz_native_transpiled[index_min_depth]
|
|
692
|
-
|
|
693
|
-
|
|
697
|
+
circuit_group.add_circuit([ghz_log[index_min_depth]])
|
|
698
|
+
self.circuits["untranspiled_circuits"].circuit_groups.append(circuit_group)
|
|
699
|
+
return CircuitGroup(name=f"{qubit_layout}_native_ghz", circuits=[final_ghz[0]])
|
|
694
700
|
|
|
695
701
|
def generate_coherence_meas_circuits(self, qubit_layout: List[int], qubit_count: int) -> List[QuantumCircuit]:
|
|
696
702
|
"""
|
|
@@ -708,9 +714,9 @@ class GHZBenchmark(Benchmark):
|
|
|
708
714
|
"""
|
|
709
715
|
|
|
710
716
|
idx = BenchmarkObservationIdentifier(qubit_layout).string_identifier
|
|
711
|
-
|
|
712
|
-
qc_list = [qc.copy()]
|
|
717
|
+
qc_list = self.circuits["untranspiled_circuits"][f"{qubit_layout}_native_ghz"].circuits
|
|
713
718
|
|
|
719
|
+
qc = qc_list[0].copy()
|
|
714
720
|
qc.remove_final_measurements()
|
|
715
721
|
qc_inv = qc.inverse()
|
|
716
722
|
phases = [np.pi * i / (qubit_count + 1) for i in range(2 * qubit_count + 2)]
|
|
@@ -733,10 +739,11 @@ class GHZBenchmark(Benchmark):
|
|
|
733
739
|
qiskit_optim_level=self.qiskit_optim_level,
|
|
734
740
|
optimize_sqg=self.optimize_sqg,
|
|
735
741
|
)
|
|
736
|
-
|
|
742
|
+
circuit_group = CircuitGroup(name=idx, circuits=qc_list)
|
|
743
|
+
self.circuits["untranspiled_circuits"].circuit_groups.append(circuit_group)
|
|
737
744
|
return qc_list_transpiled
|
|
738
745
|
|
|
739
|
-
def generate_readout_circuit(self, qubit_layout, qubit_count):
|
|
746
|
+
def generate_readout_circuit(self, qubit_layout: List[int], qubit_count: int) -> CircuitGroup:
|
|
740
747
|
"""
|
|
741
748
|
A wrapper for the creation of different circuits to estimate the fidelity
|
|
742
749
|
|
|
@@ -752,22 +759,23 @@ class GHZBenchmark(Benchmark):
|
|
|
752
759
|
A list of transpiled quantum circuits to be measured
|
|
753
760
|
"""
|
|
754
761
|
# Generate the list of circuits
|
|
755
|
-
idx = BenchmarkObservationIdentifier(qubit_layout).string_identifier
|
|
756
|
-
self.untranspiled_circuits[idx] = {}
|
|
757
|
-
self.transpiled_circuits[idx] = {}
|
|
758
762
|
|
|
759
763
|
qcvv_logger.info(f"Now generating a {len(qubit_layout)}-qubit GHZ state on qubits {qubit_layout}")
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
all_circuits_list, _ = append_rms(transpiled_ghz, cast(int, self.num_RMs), self.backend)
|
|
764
|
-
elif self.fidelity_routine == "coherences":
|
|
765
|
-
all_circuits_list = self.generate_coherence_meas_circuits(qubit_layout, qubit_count)
|
|
766
|
-
else:
|
|
767
|
-
all_circuits_list = transpiled_ghz
|
|
764
|
+
transpiled_ghz_group: CircuitGroup = self.generate_native_ghz(
|
|
765
|
+
qubit_layout, qubit_count, self.state_generation_routine
|
|
766
|
+
)
|
|
768
767
|
|
|
769
|
-
self.
|
|
770
|
-
|
|
768
|
+
match self.fidelity_routine:
|
|
769
|
+
case "randomized_measurements":
|
|
770
|
+
all_circuits_list, _ = append_rms(
|
|
771
|
+
transpiled_ghz_group.circuits[0], cast(int, self.num_RMs), self.backend
|
|
772
|
+
)
|
|
773
|
+
transpiled_ghz_group.circuits = all_circuits_list
|
|
774
|
+
case "coherences":
|
|
775
|
+
all_circuits_list = self.generate_coherence_meas_circuits(qubit_layout, qubit_count)
|
|
776
|
+
transpiled_ghz_group.circuits = all_circuits_list
|
|
777
|
+
self.circuits["transpiled_circuits"].circuit_groups.append(transpiled_ghz_group)
|
|
778
|
+
return transpiled_ghz_group
|
|
771
779
|
|
|
772
780
|
def add_configuration_to_dataset(self, dataset: xr.Dataset): # CHECK
|
|
773
781
|
"""
|
|
@@ -785,8 +793,7 @@ class GHZBenchmark(Benchmark):
|
|
|
785
793
|
else:
|
|
786
794
|
dataset.attrs[key] = value
|
|
787
795
|
dataset.attrs[f"backend_name"] = self.backend.name
|
|
788
|
-
dataset.attrs[
|
|
789
|
-
dataset.attrs[f"transpiled_circuits"] = self.transpiled_circuits
|
|
796
|
+
dataset.attrs["fidelity_routine"] = self.fidelity_routine
|
|
790
797
|
|
|
791
798
|
def execute(self, backend) -> xr.Dataset:
|
|
792
799
|
"""
|
|
@@ -797,13 +804,17 @@ class GHZBenchmark(Benchmark):
|
|
|
797
804
|
|
|
798
805
|
# Submit all
|
|
799
806
|
all_jobs: Dict = {}
|
|
807
|
+
|
|
808
|
+
self.circuits = Circuits()
|
|
809
|
+
self.circuits.benchmark_circuits.append(BenchmarkCircuit(name="transpiled_circuits"))
|
|
810
|
+
self.circuits.benchmark_circuits.append(BenchmarkCircuit(name="untranspiled_circuits"))
|
|
800
811
|
for qubit_layout in aux_custom_qubits_array:
|
|
801
812
|
Id = BenchmarkObservationIdentifier(qubit_layout)
|
|
802
813
|
idx = Id.string_identifier
|
|
803
814
|
# for qubit_count in self.qubit_counts[idx]:
|
|
804
815
|
qubit_count = len(qubit_layout)
|
|
805
|
-
|
|
806
|
-
transpiled_circuit_dict = {tuple(qubit_layout): circuits}
|
|
816
|
+
circuit_group: CircuitGroup = self.generate_readout_circuit(qubit_layout, qubit_count)
|
|
817
|
+
transpiled_circuit_dict = {tuple(qubit_layout): circuit_group.circuits}
|
|
807
818
|
all_jobs[idx], _ = submit_execute(
|
|
808
819
|
transpiled_circuit_dict,
|
|
809
820
|
backend,
|
|
@@ -811,6 +822,7 @@ class GHZBenchmark(Benchmark):
|
|
|
811
822
|
self.calset_id,
|
|
812
823
|
max_gates_per_batch=self.max_gates_per_batch,
|
|
813
824
|
)
|
|
825
|
+
|
|
814
826
|
# Retrieve all
|
|
815
827
|
qcvv_logger.info(f"Retrieving counts and adding counts to dataset...")
|
|
816
828
|
for qubit_layout in aux_custom_qubits_array:
|
|
@@ -822,8 +834,8 @@ class GHZBenchmark(Benchmark):
|
|
|
822
834
|
dataset, _ = add_counts_to_dataset(counts, idx, dataset)
|
|
823
835
|
if self.rem:
|
|
824
836
|
qcvv_logger.info(f"Applying readout error mitigation")
|
|
825
|
-
|
|
826
|
-
rem_results, _ = apply_readout_error_mitigation(backend, circuits, counts, self.mit_shots)
|
|
837
|
+
circuit_group = self.circuits["transpiled_circuits"][f"{idx}_native_ghz"]
|
|
838
|
+
rem_results, _ = apply_readout_error_mitigation(backend, circuit_group.circuits, counts, self.mit_shots)
|
|
827
839
|
rem_results_dist = [counts_mit.nearest_probability_distribution() for counts_mit in rem_results]
|
|
828
840
|
dataset, _ = add_counts_to_dataset(rem_results_dist, f"{idx}_rem", dataset)
|
|
829
841
|
|
|
@@ -26,12 +26,12 @@ import matplotlib.pyplot as plt
|
|
|
26
26
|
from networkx import Graph
|
|
27
27
|
import networkx as nx
|
|
28
28
|
import numpy as np
|
|
29
|
-
from qiskit import QuantumCircuit
|
|
30
29
|
from scipy.optimize import basinhopping, minimize
|
|
31
30
|
|
|
32
31
|
from iqm.benchmarks.benchmark import BenchmarkBase, BenchmarkConfigurationBase
|
|
33
32
|
from iqm.benchmarks.logging_config import qcvv_logger
|
|
34
33
|
from iqm.benchmarks.utils import perform_backend_transpilation, retrieve_all_counts, submit_execute, timeit
|
|
34
|
+
from iqm.qiskit_iqm import IQMCircuit as QuantumCircuit
|
|
35
35
|
from iqm.qiskit_iqm.iqm_backend import IQMBackendBase
|
|
36
36
|
|
|
37
37
|
|
|
@@ -25,13 +25,13 @@ import matplotlib as mpl
|
|
|
25
25
|
from matplotlib.figure import Figure
|
|
26
26
|
import matplotlib.pyplot as plt
|
|
27
27
|
import numpy as np
|
|
28
|
-
from qiskit import QuantumCircuit
|
|
29
28
|
from qiskit.circuit import ParameterVector
|
|
30
29
|
import xarray as xr
|
|
31
30
|
|
|
32
31
|
from iqm.benchmarks import Benchmark
|
|
33
32
|
from iqm.benchmarks.benchmark import BenchmarkConfigurationBase
|
|
34
33
|
from iqm.benchmarks.benchmark_definition import BenchmarkAnalysisResult, BenchmarkRunResult
|
|
34
|
+
from iqm.benchmarks.circuit_containers import BenchmarkCircuit, CircuitGroup, Circuits
|
|
35
35
|
from iqm.benchmarks.logging_config import qcvv_logger
|
|
36
36
|
from iqm.benchmarks.utils import (
|
|
37
37
|
count_2q_layers,
|
|
@@ -44,6 +44,7 @@ from iqm.benchmarks.utils import (
|
|
|
44
44
|
submit_execute,
|
|
45
45
|
timeit,
|
|
46
46
|
)
|
|
47
|
+
from iqm.qiskit_iqm import IQMCircuit as QuantumCircuit
|
|
47
48
|
from iqm.qiskit_iqm.iqm_backend import IQMBackendBase
|
|
48
49
|
from iqm.qiskit_iqm.iqm_transpilation import optimize_single_qubit_gates
|
|
49
50
|
|
|
@@ -251,9 +252,10 @@ def clops_analysis(run: BenchmarkRunResult) -> BenchmarkAnalysisResult:
|
|
|
251
252
|
all_times_retrieve = dataset.attrs["all_times_retrieve"]
|
|
252
253
|
|
|
253
254
|
transpiled_qc_list = []
|
|
254
|
-
for
|
|
255
|
-
|
|
256
|
-
|
|
255
|
+
for group in run.circuits["transpiled_circuits"].circuit_groups:
|
|
256
|
+
transpiled_qc_list.extend(group.circuits)
|
|
257
|
+
# for _, value in dataset.attrs["transpiled_circuits"].items():
|
|
258
|
+
# for _, transpiled_circuit in value.items():
|
|
257
259
|
|
|
258
260
|
# CLOPS_V
|
|
259
261
|
clops_v: float = num_circuits * num_updates * num_shots * depth / clops_time
|
|
@@ -387,26 +389,6 @@ class CLOPSBenchmark(Benchmark):
|
|
|
387
389
|
dataset.attrs["u_per_layer"] = self.u_per_layer
|
|
388
390
|
dataset.attrs["num_parameters"] = self.num_parameters
|
|
389
391
|
|
|
390
|
-
def add_all_circuits_to_dataset(self, dataset: xr.Dataset):
|
|
391
|
-
"""Adds all generated circuits during execution to the dataset variable
|
|
392
|
-
|
|
393
|
-
Args:
|
|
394
|
-
dataset (xr.Dataset): The xarray dataset
|
|
395
|
-
|
|
396
|
-
Returns:
|
|
397
|
-
|
|
398
|
-
"""
|
|
399
|
-
qcvv_logger.info(f"Adding all circuits to the dataset")
|
|
400
|
-
for key, circuit in zip(
|
|
401
|
-
["transpiled_circuits", "untranspiled_circuits"], [self.transpiled_circuits, self.untranspiled_circuits]
|
|
402
|
-
):
|
|
403
|
-
dictionary = {}
|
|
404
|
-
for outer_key, outer_value in circuit.items():
|
|
405
|
-
dictionary[str(outer_key)] = {
|
|
406
|
-
str(inner_key): inner_values for inner_key, inner_values in outer_value.items()
|
|
407
|
-
}
|
|
408
|
-
dataset.attrs[key] = dictionary
|
|
409
|
-
|
|
410
392
|
def append_parameterized_unitary(
|
|
411
393
|
self,
|
|
412
394
|
qc: QuantumCircuit,
|
|
@@ -593,8 +575,6 @@ class CLOPSBenchmark(Benchmark):
|
|
|
593
575
|
Dict[str, QuantumCircuit]: a dictionary of quantum circuits with keys being str(qubit layout)
|
|
594
576
|
"""
|
|
595
577
|
# Generate the list of QV circuits
|
|
596
|
-
self.untranspiled_circuits = {}
|
|
597
|
-
self.transpiled_circuits = {}
|
|
598
578
|
|
|
599
579
|
qc_list, self.time_circuit_generate = self.generate_circuit_list()
|
|
600
580
|
|
|
@@ -622,11 +602,9 @@ class CLOPSBenchmark(Benchmark):
|
|
|
622
602
|
# Sort circuits according to their final measurement mappings
|
|
623
603
|
(sorted_transpiled_qc_list, _), self.time_sort_batches = sort_batches_by_final_layout(transpiled_qc_list)
|
|
624
604
|
|
|
625
|
-
self.untranspiled_circuits.
|
|
626
|
-
|
|
627
|
-
{
|
|
628
|
-
)
|
|
629
|
-
# self.transpiled_circuits[str(self.qubits)].update(sorted_transpiled_qc_list)
|
|
605
|
+
self.untranspiled_circuits.circuit_groups.append(CircuitGroup(name=self.qubits, circuits=qc_list))
|
|
606
|
+
for key in sorted_transpiled_qc_list.keys():
|
|
607
|
+
self.transpiled_circuits.circuit_groups.append(CircuitGroup(name=f"{self.qubits}_{key}", circuits=qc_list))
|
|
630
608
|
|
|
631
609
|
return sorted_transpiled_qc_list
|
|
632
610
|
|
|
@@ -635,6 +613,9 @@ class CLOPSBenchmark(Benchmark):
|
|
|
635
613
|
|
|
636
614
|
self.execution_timestamp = strftime("%Y-%m-%d_%H:%M:%S")
|
|
637
615
|
|
|
616
|
+
self.circuits = Circuits()
|
|
617
|
+
self.transpiled_circuits = BenchmarkCircuit(name="transpiled_circuits")
|
|
618
|
+
self.untranspiled_circuits = BenchmarkCircuit(name="untranspiled_circuits")
|
|
638
619
|
dataset = xr.Dataset()
|
|
639
620
|
self.add_all_meta_to_dataset(dataset)
|
|
640
621
|
|
|
@@ -691,7 +672,7 @@ class CLOPSBenchmark(Benchmark):
|
|
|
691
672
|
}
|
|
692
673
|
)
|
|
693
674
|
|
|
694
|
-
self.
|
|
675
|
+
self.circuits = Circuits([self.transpiled_circuits, self.untranspiled_circuits])
|
|
695
676
|
|
|
696
677
|
return dataset
|
|
697
678
|
|
|
@@ -25,14 +25,10 @@ import matplotlib.pyplot as plt
|
|
|
25
25
|
from mthree.classes import QuasiCollection
|
|
26
26
|
from mthree.utils import expval
|
|
27
27
|
import numpy as np
|
|
28
|
-
from qiskit import QuantumCircuit
|
|
29
28
|
from qiskit.circuit.library import QuantumVolume
|
|
30
29
|
from qiskit_aer import Aer
|
|
31
30
|
import xarray as xr
|
|
32
31
|
|
|
33
|
-
# import iqm.diqe.executors.dynamical_decoupling.dd_high_level as dd
|
|
34
|
-
# from iqm.diqe.executors.dynamical_decoupling.dynamical_decoupling_core import DDStrategy
|
|
35
|
-
# from iqm.diqe.mapomatic import evaluate_costs, get_calibration_fidelities, get_circuit, matching_layouts
|
|
36
32
|
from iqm.benchmarks.benchmark import BenchmarkConfigurationBase
|
|
37
33
|
from iqm.benchmarks.benchmark_definition import (
|
|
38
34
|
Benchmark,
|
|
@@ -42,6 +38,11 @@ from iqm.benchmarks.benchmark_definition import (
|
|
|
42
38
|
BenchmarkRunResult,
|
|
43
39
|
add_counts_to_dataset,
|
|
44
40
|
)
|
|
41
|
+
|
|
42
|
+
# import iqm.diqe.executors.dynamical_decoupling.dd_high_level as dd
|
|
43
|
+
# from iqm.diqe.executors.dynamical_decoupling.dynamical_decoupling_core import DDStrategy
|
|
44
|
+
# from iqm.diqe.mapomatic import evaluate_costs, get_calibration_fidelities, get_circuit, matching_layouts
|
|
45
|
+
from iqm.benchmarks.circuit_containers import BenchmarkCircuit, CircuitGroup, Circuits
|
|
45
46
|
from iqm.benchmarks.logging_config import qcvv_logger
|
|
46
47
|
from iqm.benchmarks.readout_mitigation import apply_readout_error_mitigation
|
|
47
48
|
from iqm.benchmarks.utils import ( # execute_with_dd,
|
|
@@ -55,6 +56,7 @@ from iqm.benchmarks.utils import ( # execute_with_dd,
|
|
|
55
56
|
timeit,
|
|
56
57
|
xrvariable_to_counts,
|
|
57
58
|
)
|
|
59
|
+
from iqm.qiskit_iqm import IQMCircuit as QuantumCircuit
|
|
58
60
|
from iqm.qiskit_iqm.iqm_backend import IQMBackendBase
|
|
59
61
|
|
|
60
62
|
|
|
@@ -322,13 +324,7 @@ def qv_analysis(run: BenchmarkRunResult) -> BenchmarkAnalysisResult:
|
|
|
322
324
|
# Retrieve other dataset values
|
|
323
325
|
dataset_dictionary = dataset.attrs[qubits_idx]
|
|
324
326
|
sorted_qc_list_indices = dataset_dictionary["sorted_qc_list_indices"]
|
|
325
|
-
|
|
326
|
-
transpiled_qc_list = []
|
|
327
|
-
untranspiled_circ_dataset = dataset.attrs["untranspiled_circuits"][str(qubits)]
|
|
328
|
-
qc_list = []
|
|
329
|
-
for key in transpiled_circ_dataset: # Keys (final layouts) are the same for transp/untransp
|
|
330
|
-
transpiled_qc_list.extend(transpiled_circ_dataset[key])
|
|
331
|
-
qc_list.extend(untranspiled_circ_dataset[key])
|
|
327
|
+
qc_list = run.circuits["transpiled_circuits"][str(qubits)].circuits
|
|
332
328
|
|
|
333
329
|
qv_results_type[str(qubits)] = dataset_dictionary["qv_results_type"]
|
|
334
330
|
depth[str(qubits)] = len(qubits)
|
|
@@ -738,13 +734,13 @@ class QuantumVolumeBenchmark(Benchmark):
|
|
|
738
734
|
sorted_qc_list_indices = {}
|
|
739
735
|
|
|
740
736
|
# Initialize the variable to contain the QV circuits of each layout
|
|
741
|
-
self.
|
|
742
|
-
self.
|
|
737
|
+
self.circuits = Circuits()
|
|
738
|
+
self.untranspiled_circuits = BenchmarkCircuit(name="untranspiled_circuits")
|
|
739
|
+
self.transpiled_circuits = BenchmarkCircuit(name="transpiled_circuits")
|
|
743
740
|
all_op_counts = {}
|
|
744
741
|
|
|
745
742
|
for qubits in self.custom_qubits_array: # NB: jobs will be submitted for qubit layouts in the specified order
|
|
746
|
-
|
|
747
|
-
self.transpiled_circuits[str(qubits)] = {}
|
|
743
|
+
|
|
748
744
|
num_qubits = len(qubits)
|
|
749
745
|
depth = num_qubits
|
|
750
746
|
qcvv_logger.info(f"Executing QV on qubits {qubits}")
|
|
@@ -781,8 +777,10 @@ class QuantumVolumeBenchmark(Benchmark):
|
|
|
781
777
|
else:
|
|
782
778
|
raise ValueError("physical_layout must either be \"fixed\" or \"batching\"")
|
|
783
779
|
|
|
784
|
-
self.untranspiled_circuits
|
|
785
|
-
self.transpiled_circuits
|
|
780
|
+
self.untranspiled_circuits.circuit_groups.append(CircuitGroup(name=str(qubits), circuits=qc_list))
|
|
781
|
+
self.transpiled_circuits.circuit_groups.append(
|
|
782
|
+
CircuitGroup(name=str(qubits), circuits=sorted_transpiled_qc_list[tuple(qubits)])
|
|
783
|
+
)
|
|
786
784
|
|
|
787
785
|
# Count operations
|
|
788
786
|
all_op_counts[str(qubits)] = count_native_gates(backend, transpiled_qc_list)
|
|
@@ -823,14 +821,15 @@ class QuantumVolumeBenchmark(Benchmark):
|
|
|
823
821
|
qcvv_logger.info(f"Adding counts of {qubits} run to the dataset")
|
|
824
822
|
dataset, _ = add_counts_to_dataset(execution_results, str(qubits), dataset)
|
|
825
823
|
|
|
826
|
-
self.
|
|
824
|
+
self.circuits = Circuits([self.transpiled_circuits, self.untranspiled_circuits])
|
|
827
825
|
|
|
828
826
|
if self.rem:
|
|
829
827
|
rem_quasidistros = {}
|
|
830
828
|
for qubits in self.custom_qubits_array:
|
|
831
829
|
exec_counts = xrvariable_to_counts(dataset, str(qubits), self.num_circuits)
|
|
832
830
|
rem_quasidistros[f"REM_quasidist_{str(qubits)}"] = self.get_rem_quasidistro(
|
|
833
|
-
self.transpiled_circuits[str(qubits)],
|
|
831
|
+
{tuple(qubits): self.transpiled_circuits[str(qubits)].circuits},
|
|
832
|
+
# self.transpiled_circuits[str(qubits)],
|
|
834
833
|
sorted_qc_list_indices[str(qubits)],
|
|
835
834
|
exec_counts,
|
|
836
835
|
self.mit_shots,
|