iqm-benchmarks 1.3__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 +31 -0
- iqm/benchmarks/benchmark.py +109 -0
- iqm/benchmarks/benchmark_definition.py +264 -0
- iqm/benchmarks/benchmark_experiment.py +163 -0
- iqm/benchmarks/compressive_gst/__init__.py +20 -0
- iqm/benchmarks/compressive_gst/compressive_gst.py +1029 -0
- iqm/benchmarks/entanglement/__init__.py +18 -0
- iqm/benchmarks/entanglement/ghz.py +802 -0
- iqm/benchmarks/logging_config.py +29 -0
- iqm/benchmarks/optimization/__init__.py +18 -0
- iqm/benchmarks/optimization/qscore.py +719 -0
- iqm/benchmarks/quantum_volume/__init__.py +21 -0
- iqm/benchmarks/quantum_volume/clops.py +726 -0
- iqm/benchmarks/quantum_volume/quantum_volume.py +854 -0
- iqm/benchmarks/randomized_benchmarking/__init__.py +18 -0
- iqm/benchmarks/randomized_benchmarking/clifford_1q.pkl +0 -0
- iqm/benchmarks/randomized_benchmarking/clifford_2q.pkl +0 -0
- iqm/benchmarks/randomized_benchmarking/clifford_rb/__init__.py +19 -0
- iqm/benchmarks/randomized_benchmarking/clifford_rb/clifford_rb.py +386 -0
- iqm/benchmarks/randomized_benchmarking/interleaved_rb/__init__.py +19 -0
- iqm/benchmarks/randomized_benchmarking/interleaved_rb/interleaved_rb.py +555 -0
- iqm/benchmarks/randomized_benchmarking/mirror_rb/__init__.py +19 -0
- iqm/benchmarks/randomized_benchmarking/mirror_rb/mirror_rb.py +810 -0
- iqm/benchmarks/randomized_benchmarking/multi_lmfit.py +86 -0
- iqm/benchmarks/randomized_benchmarking/randomized_benchmarking_common.py +892 -0
- iqm/benchmarks/readout_mitigation.py +290 -0
- iqm/benchmarks/utils.py +521 -0
- iqm_benchmarks-1.3.dist-info/LICENSE +205 -0
- iqm_benchmarks-1.3.dist-info/METADATA +190 -0
- iqm_benchmarks-1.3.dist-info/RECORD +42 -0
- iqm_benchmarks-1.3.dist-info/WHEEL +5 -0
- iqm_benchmarks-1.3.dist-info/top_level.txt +2 -0
- mGST/LICENSE +21 -0
- mGST/README.md +54 -0
- mGST/additional_fns.py +962 -0
- mGST/algorithm.py +733 -0
- mGST/compatibility.py +238 -0
- mGST/low_level_jit.py +694 -0
- mGST/optimization.py +349 -0
- mGST/qiskit_interface.py +282 -0
- mGST/reporting/figure_gen.py +334 -0
- mGST/reporting/reporting.py +710 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Copyright 2024 IQM Benchmarks developers
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
"""
|
|
15
|
+
Randomized Benchmarking reflects the fidelity of a gate or operation on a number of qubits
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
from . import randomized_benchmarking_common
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Copyright 2024 IQM Benchmarks developers
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
"""
|
|
16
|
+
Clifford RB reflects the fidelity of Clifford gates
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
from . import clifford_rb
|
|
@@ -0,0 +1,386 @@
|
|
|
1
|
+
# Copyright 2024 IQM Benchmarks developers
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
"""
|
|
16
|
+
'Standard' Clifford Randomized Benchmarking.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
from time import strftime
|
|
20
|
+
from typing import Any, Dict, List, Sequence, Type
|
|
21
|
+
|
|
22
|
+
import numpy as np
|
|
23
|
+
from qiskit import QuantumCircuit
|
|
24
|
+
import xarray as xr
|
|
25
|
+
|
|
26
|
+
from iqm.benchmarks import AnalysisResult, Benchmark, RunResult
|
|
27
|
+
from iqm.benchmarks.benchmark import BenchmarkConfigurationBase
|
|
28
|
+
from iqm.benchmarks.benchmark_definition import add_counts_to_dataset
|
|
29
|
+
from iqm.benchmarks.logging_config import qcvv_logger
|
|
30
|
+
from iqm.benchmarks.randomized_benchmarking.randomized_benchmarking_common import (
|
|
31
|
+
exponential_rb,
|
|
32
|
+
fit_decay_lmfit,
|
|
33
|
+
generate_all_rb_circuits,
|
|
34
|
+
generate_fixed_depth_parallel_rb_circuits,
|
|
35
|
+
get_survival_probabilities,
|
|
36
|
+
import_native_gate_cliffords,
|
|
37
|
+
lmfit_minimizer,
|
|
38
|
+
plot_rb_decay,
|
|
39
|
+
submit_parallel_rb_job,
|
|
40
|
+
submit_sequential_rb_jobs,
|
|
41
|
+
survival_probabilities_parallel,
|
|
42
|
+
validate_rb_qubits,
|
|
43
|
+
)
|
|
44
|
+
from iqm.benchmarks.utils import retrieve_all_counts, retrieve_all_job_metadata, timeit, xrvariable_to_counts
|
|
45
|
+
from iqm.qiskit_iqm.iqm_backend import IQMBackendBase
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def clifford_rb_analysis(run: RunResult) -> AnalysisResult:
|
|
49
|
+
"""Analysis function for a Clifford RB experiment
|
|
50
|
+
|
|
51
|
+
Args:
|
|
52
|
+
run (RunResult): A Clifford RB experiment run for which analysis result is created
|
|
53
|
+
Returns:
|
|
54
|
+
AnalysisResult corresponding to Clifford RB
|
|
55
|
+
"""
|
|
56
|
+
dataset = run.dataset
|
|
57
|
+
observations = {}
|
|
58
|
+
plots = {}
|
|
59
|
+
|
|
60
|
+
is_parallel_execution = dataset.attrs["parallel_execution"]
|
|
61
|
+
qubits_array = dataset.attrs["qubits_array"]
|
|
62
|
+
num_circuit_samples = dataset.attrs["num_circuit_samples"]
|
|
63
|
+
sequence_lengths = dataset.attrs["sequence_lengths"]
|
|
64
|
+
|
|
65
|
+
all_noisy_counts: Dict[str, Dict[int, List[Dict[str, int]]]] = {}
|
|
66
|
+
fidelities: Dict[str, Dict[int, List[float]]] = {str(q): {} for q in qubits_array}
|
|
67
|
+
|
|
68
|
+
if is_parallel_execution:
|
|
69
|
+
qcvv_logger.info(f"Post-processing parallel RB for qubits {qubits_array}")
|
|
70
|
+
all_noisy_counts[str(qubits_array)] = {}
|
|
71
|
+
for depth in sequence_lengths:
|
|
72
|
+
identifier = f"qubits_{str(qubits_array)}_depth_{str(depth)}"
|
|
73
|
+
all_noisy_counts[str(qubits_array)][depth] = xrvariable_to_counts(dataset, identifier, num_circuit_samples)
|
|
74
|
+
|
|
75
|
+
qcvv_logger.info(f"Depth {depth}")
|
|
76
|
+
|
|
77
|
+
# Retrieve the marginalized survival probabilities
|
|
78
|
+
all_survival_probabilities = survival_probabilities_parallel(
|
|
79
|
+
qubits_array, all_noisy_counts[str(qubits_array)][depth]
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
# The marginalized survival probabilities will be arranged by qubit layouts
|
|
83
|
+
for qubits_str in all_survival_probabilities.keys():
|
|
84
|
+
fidelities[qubits_str][depth] = all_survival_probabilities[qubits_str]
|
|
85
|
+
# Remaining analysis is the same regardless of whether execution was in parallel or sequential
|
|
86
|
+
else: # sequential
|
|
87
|
+
qcvv_logger.info(f"Post-processing sequential RB for qubits {qubits_array}")
|
|
88
|
+
|
|
89
|
+
for q in qubits_array:
|
|
90
|
+
all_noisy_counts[str(q)] = {}
|
|
91
|
+
num_qubits = len(q)
|
|
92
|
+
fidelities[str(q)] = {}
|
|
93
|
+
for depth in sequence_lengths:
|
|
94
|
+
identifier = f"qubits_{str(q)}_depth_{str(depth)}"
|
|
95
|
+
all_noisy_counts[str(q)][depth] = xrvariable_to_counts(dataset, identifier, num_circuit_samples)
|
|
96
|
+
|
|
97
|
+
qcvv_logger.info(f"Qubits {q} and depth {depth}")
|
|
98
|
+
fidelities[str(q)][depth] = get_survival_probabilities(num_qubits, all_noisy_counts[str(q)][depth])
|
|
99
|
+
# Remaining analysis is the same regardless of whether execution was in parallel or sequential
|
|
100
|
+
|
|
101
|
+
# All remaining (fitting & plotting) is done per qubit layout
|
|
102
|
+
for qubits_idx, qubits in enumerate(qubits_array):
|
|
103
|
+
# Fit decays
|
|
104
|
+
list_of_fidelities = list(fidelities[str(qubits)].values())
|
|
105
|
+
fit_data, fit_parameters = fit_decay_lmfit(exponential_rb, qubits, list_of_fidelities, "clifford")
|
|
106
|
+
rb_fit_results = lmfit_minimizer(fit_parameters, fit_data, sequence_lengths, exponential_rb)
|
|
107
|
+
|
|
108
|
+
average_fidelities = {d: np.mean(fidelities[str(qubits)][d]) for d in sequence_lengths}
|
|
109
|
+
stddevs_from_mean = {
|
|
110
|
+
d: np.std(fidelities[str(qubits)][d]) / np.sqrt(num_circuit_samples) for d in sequence_lengths
|
|
111
|
+
}
|
|
112
|
+
popt = {
|
|
113
|
+
"amplitude": rb_fit_results.params["amplitude_1"],
|
|
114
|
+
"offset": rb_fit_results.params["offset_1"],
|
|
115
|
+
"decay_rate": rb_fit_results.params["p_rb"],
|
|
116
|
+
}
|
|
117
|
+
fidelity = rb_fit_results.params["fidelity_per_clifford"]
|
|
118
|
+
|
|
119
|
+
processed_results = {
|
|
120
|
+
"avg_gate_fidelity": {"value": fidelity.value, "uncertainty": fidelity.stderr},
|
|
121
|
+
"decay_rate": {"value": popt["decay_rate"].value, "uncertainty": popt["decay_rate"].stderr},
|
|
122
|
+
"fit_amplitude": {"value": popt["amplitude"].value, "uncertainty": popt["amplitude"].stderr},
|
|
123
|
+
"fit_offset": {"value": popt["offset"].value, "uncertainty": popt["offset"].stderr},
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
dataset.attrs[qubits_idx].update(
|
|
127
|
+
{
|
|
128
|
+
"fidelities": fidelities[str(qubits)],
|
|
129
|
+
"avg_fidelities_nominal_values": average_fidelities,
|
|
130
|
+
"avg_fidelities_stderr": stddevs_from_mean,
|
|
131
|
+
"fitting_method": str(rb_fit_results.method),
|
|
132
|
+
"num_function_evals": int(rb_fit_results.nfev),
|
|
133
|
+
"data_points": int(rb_fit_results.ndata),
|
|
134
|
+
"num_variables": int(rb_fit_results.nvarys),
|
|
135
|
+
"chi_square": float(rb_fit_results.chisqr),
|
|
136
|
+
"reduced_chi_square": float(rb_fit_results.redchi),
|
|
137
|
+
"Akaike_info_crit": float(rb_fit_results.aic),
|
|
138
|
+
"Bayesian_info_crit": float(rb_fit_results.bic),
|
|
139
|
+
}
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
observations.update({qubits_idx: processed_results})
|
|
143
|
+
|
|
144
|
+
# Generate individual decay plots
|
|
145
|
+
fig_name, fig = plot_rb_decay("clifford", [qubits], dataset, observations)
|
|
146
|
+
plots[fig_name] = fig
|
|
147
|
+
|
|
148
|
+
return AnalysisResult(dataset=dataset, observations=observations, plots=plots)
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
class CliffordRandomizedBenchmarking(Benchmark):
|
|
152
|
+
"""Clifford RB estimates the average gate fidelity of the n-qubit Clifford group"""
|
|
153
|
+
|
|
154
|
+
analysis_function = staticmethod(clifford_rb_analysis)
|
|
155
|
+
|
|
156
|
+
name: str = "clifford_rb"
|
|
157
|
+
|
|
158
|
+
def __init__(self, backend_arg: IQMBackendBase | str, configuration: "CliffordRBConfiguration"):
|
|
159
|
+
"""Construct the CliffordRandomizedBenchmark class
|
|
160
|
+
|
|
161
|
+
Args:
|
|
162
|
+
backend_arg (IQMBackendBase | str): the backend to execute Clifford RB on
|
|
163
|
+
configuration (CliffordRBConfiguration): The Clifford RB configuration
|
|
164
|
+
"""
|
|
165
|
+
super().__init__(backend_arg, configuration)
|
|
166
|
+
|
|
167
|
+
# EXPERIMENT
|
|
168
|
+
self.backend_configuration_name = backend_arg if isinstance(backend_arg, str) else backend_arg.name
|
|
169
|
+
|
|
170
|
+
self.qubits_array = configuration.qubits_array
|
|
171
|
+
self.sequence_lengths = configuration.sequence_lengths
|
|
172
|
+
self.num_circuit_samples = configuration.num_circuit_samples
|
|
173
|
+
|
|
174
|
+
self.parallel_execution = configuration.parallel_execution
|
|
175
|
+
|
|
176
|
+
self.session_timestamp = strftime("%Y%m%d-%H%M%S")
|
|
177
|
+
self.execution_timestamp = ""
|
|
178
|
+
|
|
179
|
+
def add_all_meta_to_dataset(self, dataset: xr.Dataset):
|
|
180
|
+
"""Adds all configuration metadata and circuits to the dataset variable
|
|
181
|
+
Args:
|
|
182
|
+
dataset (xr.Dataset): The xarray dataset
|
|
183
|
+
"""
|
|
184
|
+
dataset.attrs["session_timestamp"] = self.session_timestamp
|
|
185
|
+
dataset.attrs["execution_timestamp"] = self.execution_timestamp
|
|
186
|
+
dataset.attrs["backend_configuration_name"] = self.backend_configuration_name
|
|
187
|
+
dataset.attrs["backend_name"] = self.backend.name
|
|
188
|
+
|
|
189
|
+
for key, value in self.configuration:
|
|
190
|
+
if key == "benchmark": # Avoid saving the class object
|
|
191
|
+
dataset.attrs[key] = value.name
|
|
192
|
+
else:
|
|
193
|
+
dataset.attrs[key] = value
|
|
194
|
+
# Defined outside configuration - if any
|
|
195
|
+
|
|
196
|
+
@timeit
|
|
197
|
+
def add_all_circuits_to_dataset(self, dataset: xr.Dataset):
|
|
198
|
+
"""Adds all generated circuits during execution to the dataset variable
|
|
199
|
+
|
|
200
|
+
Args:
|
|
201
|
+
dataset (xr.Dataset): The xarray dataset
|
|
202
|
+
|
|
203
|
+
Returns:
|
|
204
|
+
|
|
205
|
+
"""
|
|
206
|
+
qcvv_logger.info(f"Adding all circuits to the dataset")
|
|
207
|
+
dataset.attrs["untranspiled_circuits"] = self.untranspiled_circuits
|
|
208
|
+
dataset.attrs["transpiled_circuits"] = self.transpiled_circuits
|
|
209
|
+
|
|
210
|
+
# pylint: disable=too-many-statements
|
|
211
|
+
def execute(self, backend: IQMBackendBase) -> xr.Dataset:
|
|
212
|
+
"""Executes the benchmark"""
|
|
213
|
+
|
|
214
|
+
self.execution_timestamp = strftime("%Y%m%d-%H%M%S")
|
|
215
|
+
validate_rb_qubits(self.qubits_array, backend)
|
|
216
|
+
|
|
217
|
+
dataset = xr.Dataset()
|
|
218
|
+
self.add_all_meta_to_dataset(dataset)
|
|
219
|
+
|
|
220
|
+
clifford_1q_dict, clifford_2q_dict = import_native_gate_cliffords()
|
|
221
|
+
|
|
222
|
+
# Submit jobs for all qubit layouts
|
|
223
|
+
all_rb_jobs: List[Dict[str, Any]] = []
|
|
224
|
+
time_circuit_generation: Dict[str, float] = {}
|
|
225
|
+
|
|
226
|
+
# Initialize the variable to contain the circuits for each layout
|
|
227
|
+
self.untranspiled_circuits: Dict[str, Dict[int, List[QuantumCircuit]]] = {}
|
|
228
|
+
self.transpiled_circuits: Dict[str, Dict[int, List[QuantumCircuit]]] = {}
|
|
229
|
+
|
|
230
|
+
# Auxiliary dict from str(qubits) to indices
|
|
231
|
+
qubit_idx: Dict[str, Any] = {}
|
|
232
|
+
|
|
233
|
+
if self.parallel_execution:
|
|
234
|
+
# Take the whole qubits_array and do RB in parallel on each qubits_array element
|
|
235
|
+
parallel_untranspiled_rb_circuits = {}
|
|
236
|
+
parallel_transpiled_rb_circuits = {}
|
|
237
|
+
qcvv_logger.info(
|
|
238
|
+
f"Executing parallel RB on qubits {self.qubits_array}."
|
|
239
|
+
f" Will generate and submit all {self.num_circuit_samples} Clifford RB circuits"
|
|
240
|
+
f" for each depth {self.sequence_lengths}"
|
|
241
|
+
)
|
|
242
|
+
|
|
243
|
+
time_circuit_generation[str(self.qubits_array)] = 0
|
|
244
|
+
# Generate and submit all circuits
|
|
245
|
+
for seq_length in self.sequence_lengths:
|
|
246
|
+
qcvv_logger.info(f"Sequence length {seq_length}")
|
|
247
|
+
(
|
|
248
|
+
(parallel_untranspiled_rb_circuits[seq_length], parallel_transpiled_rb_circuits[seq_length]),
|
|
249
|
+
elapsed_time,
|
|
250
|
+
) = generate_fixed_depth_parallel_rb_circuits(
|
|
251
|
+
self.qubits_array,
|
|
252
|
+
clifford_1q_dict,
|
|
253
|
+
clifford_2q_dict,
|
|
254
|
+
seq_length,
|
|
255
|
+
self.num_circuit_samples,
|
|
256
|
+
backend,
|
|
257
|
+
)
|
|
258
|
+
time_circuit_generation[str(self.qubits_array)] += elapsed_time
|
|
259
|
+
|
|
260
|
+
# Submit all
|
|
261
|
+
flat_qubits_array = [x for y in self.qubits_array for x in y]
|
|
262
|
+
sorted_transpiled_qc_list = {tuple(flat_qubits_array): parallel_transpiled_rb_circuits[seq_length]}
|
|
263
|
+
all_rb_jobs.append(
|
|
264
|
+
submit_parallel_rb_job(
|
|
265
|
+
backend,
|
|
266
|
+
self.qubits_array,
|
|
267
|
+
seq_length,
|
|
268
|
+
sorted_transpiled_qc_list,
|
|
269
|
+
self.shots,
|
|
270
|
+
self.calset_id,
|
|
271
|
+
self.max_gates_per_batch,
|
|
272
|
+
)
|
|
273
|
+
)
|
|
274
|
+
qcvv_logger.info(f"Job for sequence length {seq_length} submitted successfully!")
|
|
275
|
+
|
|
276
|
+
self.untranspiled_circuits[str(self.qubits_array)] = {
|
|
277
|
+
m: parallel_untranspiled_rb_circuits[m] for m in self.sequence_lengths
|
|
278
|
+
}
|
|
279
|
+
self.transpiled_circuits[str(self.qubits_array)] = {
|
|
280
|
+
m: parallel_transpiled_rb_circuits[m] for m in self.sequence_lengths
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
qubit_idx = {str(self.qubits_array): "parallel_all"}
|
|
284
|
+
dataset.attrs["parallel_all"] = {"qubits": self.qubits_array}
|
|
285
|
+
dataset.attrs.update({q_idx: {"qubits": q} for q_idx, q in enumerate(self.qubits_array)})
|
|
286
|
+
else:
|
|
287
|
+
rb_untranspiled_circuits: Dict[str, Dict[int, List[QuantumCircuit]]] = {}
|
|
288
|
+
rb_transpiled_circuits: Dict[str, Dict[int, List[QuantumCircuit]]] = {}
|
|
289
|
+
for qubits_idx, qubits in enumerate(self.qubits_array):
|
|
290
|
+
qubit_idx[str(qubits)] = qubits_idx
|
|
291
|
+
qcvv_logger.info(
|
|
292
|
+
f"Executing sequential Clifford RB on qubits {qubits}."
|
|
293
|
+
f" Will generate and submit all {self.num_circuit_samples} Clifford RB circuits"
|
|
294
|
+
f" for each depth {self.sequence_lengths}"
|
|
295
|
+
)
|
|
296
|
+
|
|
297
|
+
num_qubits = len(qubits)
|
|
298
|
+
rb_untranspiled_circuits[str(qubits)] = {}
|
|
299
|
+
rb_transpiled_circuits[str(qubits)] = {}
|
|
300
|
+
|
|
301
|
+
if num_qubits == 1:
|
|
302
|
+
clifford_dict = clifford_1q_dict
|
|
303
|
+
else:
|
|
304
|
+
clifford_dict = clifford_2q_dict
|
|
305
|
+
|
|
306
|
+
(rb_untranspiled_circuits[str(qubits)], rb_transpiled_circuits[str(qubits)]), time_circuit_generation[
|
|
307
|
+
str(qubits)
|
|
308
|
+
] = generate_all_rb_circuits(
|
|
309
|
+
qubits,
|
|
310
|
+
self.sequence_lengths,
|
|
311
|
+
clifford_dict,
|
|
312
|
+
self.num_circuit_samples,
|
|
313
|
+
backend,
|
|
314
|
+
interleaved_gate=None,
|
|
315
|
+
)
|
|
316
|
+
|
|
317
|
+
# Submit
|
|
318
|
+
all_rb_jobs.extend(
|
|
319
|
+
submit_sequential_rb_jobs(
|
|
320
|
+
qubits,
|
|
321
|
+
rb_transpiled_circuits[str(qubits)],
|
|
322
|
+
self.shots,
|
|
323
|
+
self.backend,
|
|
324
|
+
self.calset_id,
|
|
325
|
+
max_gates_per_batch=self.max_gates_per_batch,
|
|
326
|
+
)
|
|
327
|
+
)
|
|
328
|
+
qcvv_logger.info(
|
|
329
|
+
f"All jobs for qubits {qubits} and sequence lengths {self.sequence_lengths} submitted successfully!"
|
|
330
|
+
)
|
|
331
|
+
|
|
332
|
+
self.untranspiled_circuits[str(qubits)] = rb_untranspiled_circuits[str(qubits)]
|
|
333
|
+
self.transpiled_circuits[str(qubits)] = rb_transpiled_circuits[str(qubits)]
|
|
334
|
+
|
|
335
|
+
dataset.attrs[qubits_idx] = {"qubits": qubits}
|
|
336
|
+
|
|
337
|
+
# Retrieve counts of jobs for all qubit layouts
|
|
338
|
+
all_job_metadata = {}
|
|
339
|
+
for job_dict in all_rb_jobs:
|
|
340
|
+
qubits = job_dict["qubits"]
|
|
341
|
+
depth = job_dict["depth"]
|
|
342
|
+
# Retrieve counts
|
|
343
|
+
identifier = f"qubits_{str(qubits)}_depth_{str(depth)}"
|
|
344
|
+
execution_results, time_retrieve = retrieve_all_counts(job_dict["jobs"], identifier)
|
|
345
|
+
# Retrieve all job meta data
|
|
346
|
+
all_job_metadata = retrieve_all_job_metadata(job_dict["jobs"])
|
|
347
|
+
# Export all to dataset
|
|
348
|
+
dataset.attrs[qubit_idx[str(qubits)]].update(
|
|
349
|
+
{
|
|
350
|
+
f"depth_{str(depth)}": {
|
|
351
|
+
"time_circuit_generation": time_circuit_generation[str(qubits)],
|
|
352
|
+
"time_submit": job_dict["time_submit"],
|
|
353
|
+
"time_retrieve": time_retrieve,
|
|
354
|
+
"all_job_metadata": all_job_metadata,
|
|
355
|
+
},
|
|
356
|
+
}
|
|
357
|
+
)
|
|
358
|
+
|
|
359
|
+
qcvv_logger.info(f"Adding counts of qubits {qubits} and depth {depth} run to the dataset")
|
|
360
|
+
dataset, _ = add_counts_to_dataset(execution_results, identifier, dataset)
|
|
361
|
+
|
|
362
|
+
self.add_all_circuits_to_dataset(dataset)
|
|
363
|
+
|
|
364
|
+
qcvv_logger.info(f"RB experiment concluded !")
|
|
365
|
+
|
|
366
|
+
return dataset
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
class CliffordRBConfiguration(BenchmarkConfigurationBase):
|
|
370
|
+
"""Clifford RB configuration.
|
|
371
|
+
|
|
372
|
+
Attributes:
|
|
373
|
+
benchmark (Type[Benchmark]): CliffordRandomizedBenchmarking
|
|
374
|
+
qubits_array (Sequence[Sequence[int]]): The array of qubits on which to execute the benchmark.
|
|
375
|
+
sequence_lengths (Sequence[int]): The length of Cliffords sequences with which to execute benchmark.
|
|
376
|
+
num_circuit_samples (int): The number of Cliffords circuits per sequence length.
|
|
377
|
+
shots (int): The number of measurement shots per circuit.
|
|
378
|
+
parallel_execution(bool): Whether the benchmark is executed on all qubits in parallel or not.
|
|
379
|
+
* Default is False.
|
|
380
|
+
"""
|
|
381
|
+
|
|
382
|
+
benchmark: Type[Benchmark] = CliffordRandomizedBenchmarking
|
|
383
|
+
qubits_array: Sequence[Sequence[int]]
|
|
384
|
+
sequence_lengths: Sequence[int]
|
|
385
|
+
num_circuit_samples: int
|
|
386
|
+
parallel_execution: bool = False
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Copyright 2024 IQM Benchmarks developers
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
"""
|
|
16
|
+
Interleaved RB reflects the fidelity of a given gate
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
from . import interleaved_rb
|