iqm-benchmarks 2.50__tar.gz → 2.52__tar.gz
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.
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/CHANGELOG.rst +8 -0
- {iqm_benchmarks-2.50/src/iqm_benchmarks.egg-info → iqm_benchmarks-2.52}/PKG-INFO +1 -1
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/src/iqm/benchmarks/entanglement/ghz.py +129 -21
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/src/iqm/benchmarks/optimization/qscore.py +247 -44
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52/src/iqm_benchmarks.egg-info}/PKG-INFO +1 -1
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/tests/test_qscore.py +5 -4
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/.github/workflows/main.yml +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/.github/workflows/publish.yml +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/.github/workflows/tag_and_release.yml +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/.gitignore +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/LICENSE +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/MANIFEST.in +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/README.md +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/benchmark_runner.py +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/docbuild +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/docs/API.rst +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/docs/Makefile +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/docs/_static/images/favicon.ico +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/docs/_static/images/logo.png +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/docs/_templates/autosummary-class-template.rst +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/docs/_templates/autosummary-module-template.rst +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/docs/changelog.rst +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/docs/conf.py +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/docs/development/development.rst +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/docs/development/generate_2qubit_cliffords.ipynb +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/docs/development/how_to_make_your_own_benchmark.ipynb +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/docs/devices/devices.rst +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/docs/devices/spark.ipynb +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/docs/devices/star.ipynb +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/docs/examples/example_clifford_rb.ipynb +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/docs/examples/example_clops.ipynb +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/docs/examples/example_coherence.ipynb +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/docs/examples/example_eplg.ipynb +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/docs/examples/example_experiment_all.ipynb +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/docs/examples/example_ghz.ipynb +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/docs/examples/example_graphstate.ipynb +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/docs/examples/example_gst.ipynb +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/docs/examples/example_interleaved_rb.ipynb +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/docs/examples/example_mirror_rb.ipynb +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/docs/examples/example_qscore.ipynb +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/docs/examples/example_quantum_volume.ipynb +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/docs/examples/examples.rst +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/docs/index.rst +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/docs/license.rst +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/docs/readme.md +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/format +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/pyproject.toml +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/requirements.txt +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/scheduled_experiments/adonis/__init__.py +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/scheduled_experiments/adonis/weekly.py +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/setup.cfg +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/src/iqm/benchmarks/__init__.py +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/src/iqm/benchmarks/benchmark.py +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/src/iqm/benchmarks/benchmark_definition.py +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/src/iqm/benchmarks/circuit_containers.py +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/src/iqm/benchmarks/coherence/__init__.py +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/src/iqm/benchmarks/coherence/coherence.py +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/src/iqm/benchmarks/compressive_gst/__init__.py +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/src/iqm/benchmarks/compressive_gst/compressive_gst.py +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/src/iqm/benchmarks/compressive_gst/gst_analysis.py +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/src/iqm/benchmarks/entanglement/__init__.py +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/src/iqm/benchmarks/entanglement/graph_states.py +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/src/iqm/benchmarks/logging_config.py +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/src/iqm/benchmarks/optimization/__init__.py +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/src/iqm/benchmarks/quantum_volume/__init__.py +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/src/iqm/benchmarks/quantum_volume/clops.py +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/src/iqm/benchmarks/quantum_volume/quantum_volume.py +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/src/iqm/benchmarks/randomized_benchmarking/__init__.py +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/src/iqm/benchmarks/randomized_benchmarking/clifford_1q.pkl +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/src/iqm/benchmarks/randomized_benchmarking/clifford_2q.pkl +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/src/iqm/benchmarks/randomized_benchmarking/clifford_rb/__init__.py +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/src/iqm/benchmarks/randomized_benchmarking/clifford_rb/clifford_rb.py +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/src/iqm/benchmarks/randomized_benchmarking/direct_rb/__init__.py +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/src/iqm/benchmarks/randomized_benchmarking/direct_rb/direct_rb.py +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/src/iqm/benchmarks/randomized_benchmarking/eplg/__init__.py +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/src/iqm/benchmarks/randomized_benchmarking/eplg/eplg.py +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/src/iqm/benchmarks/randomized_benchmarking/interleaved_rb/__init__.py +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/src/iqm/benchmarks/randomized_benchmarking/interleaved_rb/interleaved_rb.py +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/src/iqm/benchmarks/randomized_benchmarking/mirror_rb/__init__.py +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/src/iqm/benchmarks/randomized_benchmarking/mirror_rb/mirror_rb.py +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/src/iqm/benchmarks/randomized_benchmarking/multi_lmfit.py +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/src/iqm/benchmarks/randomized_benchmarking/randomized_benchmarking_common.py +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/src/iqm/benchmarks/readout_mitigation.py +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/src/iqm/benchmarks/utils.py +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/src/iqm/benchmarks/utils_plots.py +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/src/iqm/benchmarks/utils_shadows.py +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/src/iqm_benchmarks.egg-info/SOURCES.txt +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/src/iqm_benchmarks.egg-info/dependency_links.txt +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/src/iqm_benchmarks.egg-info/requires.txt +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/src/iqm_benchmarks.egg-info/top_level.txt +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/src/mGST/LICENSE +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/src/mGST/README.md +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/src/mGST/additional_fns.py +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/src/mGST/algorithm.py +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/src/mGST/compatibility.py +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/src/mGST/low_level_jit.py +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/src/mGST/optimization.py +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/src/mGST/qiskit_interface.py +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/src/mGST/reporting/figure_gen.py +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/src/mGST/reporting/reporting.py +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/tag-from-pipeline.sh +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/test +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/tests/test_coherence.py +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/tests/test_ghz.py +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/tests/test_graph_states.py +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/tests/test_gst.py +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/tests/test_qv.py +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/tests/test_rb.py +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/tests/unit/test_backend_transpilation.py +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/tests/unit/test_benchmark_circuit.py +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/tests/unit/test_submit_execute.py +0 -0
- {iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/update-requirements.py +0 -0
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
Changelog
|
|
3
3
|
=========
|
|
4
4
|
|
|
5
|
+
Version 2.52
|
|
6
|
+
============
|
|
7
|
+
* Circuit transpilation improvements for GHZ benchmark implemented.
|
|
8
|
+
|
|
9
|
+
Version 2.51
|
|
10
|
+
============
|
|
11
|
+
* Circuit transpilation improvements for Q-score implemented.
|
|
12
|
+
|
|
5
13
|
Version 2.50
|
|
6
14
|
============
|
|
7
15
|
* Update iqm-client and iqm-station-control-client dependency versions as part of IQM OS 4.3 release.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: iqm-benchmarks
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.52
|
|
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
|
|
@@ -25,7 +25,7 @@ import matplotlib.pyplot as plt
|
|
|
25
25
|
import networkx
|
|
26
26
|
from networkx import Graph, all_pairs_shortest_path, is_connected, minimum_spanning_tree
|
|
27
27
|
import numpy as np
|
|
28
|
-
from qiskit import QuantumRegister
|
|
28
|
+
from qiskit import ClassicalRegister, QuantumRegister
|
|
29
29
|
from qiskit.quantum_info import random_clifford
|
|
30
30
|
from qiskit.transpiler import CouplingMap
|
|
31
31
|
from qiskit_aer import Aer
|
|
@@ -55,6 +55,7 @@ from iqm.benchmarks.utils import (
|
|
|
55
55
|
xrvariable_to_counts,
|
|
56
56
|
)
|
|
57
57
|
from iqm.qiskit_iqm import IQMCircuit as QuantumCircuit
|
|
58
|
+
from iqm.qiskit_iqm import transpile_to_IQM
|
|
58
59
|
from iqm.qiskit_iqm.iqm_backend import IQMBackendBase
|
|
59
60
|
|
|
60
61
|
|
|
@@ -304,6 +305,74 @@ def generate_ghz_log_cruz(num_qubits: int) -> QuantumCircuit:
|
|
|
304
305
|
return qc
|
|
305
306
|
|
|
306
307
|
|
|
308
|
+
## can introduce another fucntion to time order here CZ and pick the best MOVE qubit.
|
|
309
|
+
|
|
310
|
+
|
|
311
|
+
def generate_ghz_star_optimal(
|
|
312
|
+
qubit_layout: List[int], cal_url: str, backend: IQMBackendBase, inv: bool = False
|
|
313
|
+
) -> QuantumCircuit:
|
|
314
|
+
"""
|
|
315
|
+
Generates the circuit for creating a GHZ state by maximizing the number of CZ gates between a pair of MOVE gates.
|
|
316
|
+
|
|
317
|
+
Args:
|
|
318
|
+
qubit_layout: List[int]
|
|
319
|
+
The layout of qubits for the GHZ state.
|
|
320
|
+
cal_url: str
|
|
321
|
+
The calibration URL for extracting fidelities.
|
|
322
|
+
backend: IQMBackendBase
|
|
323
|
+
The backend to be used for the quantum circuit.
|
|
324
|
+
inv: bool
|
|
325
|
+
Whether to generate the inverse circuit.
|
|
326
|
+
|
|
327
|
+
Returns:
|
|
328
|
+
QuantumCircuit: A quantum circuit generating a GHZ state on a given number of qubits.
|
|
329
|
+
"""
|
|
330
|
+
num_qubits = len(qubit_layout)
|
|
331
|
+
|
|
332
|
+
# Initialize quantum and classical registers
|
|
333
|
+
comp_r = QuantumRegister(1, "comp_r") # Computational resonator
|
|
334
|
+
q = QuantumRegister(backend.num_qubits, "q") # Qubits
|
|
335
|
+
c = ClassicalRegister(num_qubits, "c")
|
|
336
|
+
qc = QuantumCircuit(comp_r, q, c, name="GHZ_star_optimal")
|
|
337
|
+
|
|
338
|
+
cal_data = extract_fidelities(cal_url, all_metrics=True)
|
|
339
|
+
# Determine the best move qubit
|
|
340
|
+
move_dict = {q + 1: cal_data[1][q] for q in qubit_layout} ## +1 to match qubit indexing in cal data
|
|
341
|
+
best_move = max(move_dict, key=move_dict.get)
|
|
342
|
+
|
|
343
|
+
T2 = cal_data[-1]["t2_echo_time"]
|
|
344
|
+
t2_dict = {qubit + 1: T2[qubit + 1] for qubit in qubit_layout} ## +1 to match qubit indexing in cal data
|
|
345
|
+
cz_order = dict(sorted(t2_dict.items(), key=lambda item: item[1], reverse=True))
|
|
346
|
+
qubits_to_measure = list(cz_order.keys())
|
|
347
|
+
cz_order.pop(best_move)
|
|
348
|
+
|
|
349
|
+
# Construct the quantum circuit
|
|
350
|
+
qc.h(best_move)
|
|
351
|
+
qc.move(best_move, 0)
|
|
352
|
+
for qubit in cz_order.keys():
|
|
353
|
+
qc.cx(0, qubit)
|
|
354
|
+
qc.barrier()
|
|
355
|
+
qc.move(best_move, 0)
|
|
356
|
+
qc.barrier()
|
|
357
|
+
qc.measure(sorted(qubits_to_measure), list(range(num_qubits)))
|
|
358
|
+
|
|
359
|
+
if inv:
|
|
360
|
+
comp_r = QuantumRegister(1, "comp_r") # Computational resonator
|
|
361
|
+
q = QuantumRegister(backend.num_qubits, "q") # Qubits
|
|
362
|
+
c = ClassicalRegister(num_qubits, "c")
|
|
363
|
+
qc = QuantumCircuit(comp_r, q, c, name="GHZ_star_optimal_inv")
|
|
364
|
+
|
|
365
|
+
qc.move(best_move, 0)
|
|
366
|
+
for qubit in reversed(cz_order.keys()):
|
|
367
|
+
qc.cx(0, qubit)
|
|
368
|
+
qc.barrier()
|
|
369
|
+
qc.move(best_move, 0)
|
|
370
|
+
qc.h(best_move)
|
|
371
|
+
qc.barrier()
|
|
372
|
+
|
|
373
|
+
return qc
|
|
374
|
+
|
|
375
|
+
|
|
307
376
|
def generate_ghz_star(num_qubits: int) -> QuantumCircuit:
|
|
308
377
|
"""
|
|
309
378
|
Generates the circuit for creating a GHZ state by maximizing the number of CZ gates between a pair of MOVE gates.
|
|
@@ -648,7 +717,20 @@ class GHZBenchmark(Benchmark):
|
|
|
648
717
|
optimize_sqg=self.optimize_sqg,
|
|
649
718
|
)
|
|
650
719
|
final_ghz = ghz_native_transpiled
|
|
651
|
-
|
|
720
|
+
elif routine == "star_optimal":
|
|
721
|
+
if self.cal_url is None:
|
|
722
|
+
raise ValueError("Calibration URL must be provided for 'star_optimal' routine.")
|
|
723
|
+
ghz = generate_ghz_star_optimal(qubit_layout, self.cal_url, self.backend)
|
|
724
|
+
circuit_group.add_circuit(ghz)
|
|
725
|
+
ghz_native_transpiled = transpile_to_IQM(
|
|
726
|
+
ghz,
|
|
727
|
+
self.backend,
|
|
728
|
+
existing_moves_handling=True,
|
|
729
|
+
perform_move_routing=False,
|
|
730
|
+
optimize_single_qubits=self.optimize_sqg,
|
|
731
|
+
optimization_level=self.qiskit_optim_level,
|
|
732
|
+
)
|
|
733
|
+
final_ghz = [ghz_native_transpiled]
|
|
652
734
|
else:
|
|
653
735
|
ghz_log = [generate_ghz_log_cruz(qubit_count), generate_ghz_log_mooney(qubit_count)]
|
|
654
736
|
ghz_native_transpiled, _ = perform_backend_transpilation(
|
|
@@ -691,27 +773,54 @@ class GHZBenchmark(Benchmark):
|
|
|
691
773
|
|
|
692
774
|
qc = qc_list[0].copy()
|
|
693
775
|
qc.remove_final_measurements()
|
|
694
|
-
qc_inv = qc.inverse()
|
|
695
776
|
phases = [np.pi * i / (qubit_count + 1) for i in range(2 * qubit_count + 2)]
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
qc_phase.
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
777
|
+
if self.state_generation_routine == "star_optimal":
|
|
778
|
+
qc_inv = generate_ghz_star_optimal(qubit_layout, self.cal_url, self.backend, inv=True)
|
|
779
|
+
for phase in phases:
|
|
780
|
+
qc_phase = qc.copy()
|
|
781
|
+
qc_phase.barrier()
|
|
782
|
+
for _, qubit in enumerate(qubit_layout):
|
|
783
|
+
qc_phase.p(phase, qubit + 1)
|
|
784
|
+
qc_phase.barrier()
|
|
785
|
+
qc_phase.compose(qc_inv, inplace=True)
|
|
786
|
+
qc_phase.measure([q + 1 for q in qubit_layout], list(range(qubit_count)))
|
|
787
|
+
qc_list.append(qc_phase)
|
|
788
|
+
else:
|
|
789
|
+
qc_inv = qc.inverse()
|
|
790
|
+
for phase in phases:
|
|
791
|
+
qc_phase = qc.copy()
|
|
792
|
+
qc_phase.barrier()
|
|
793
|
+
for qubit, _ in enumerate(qubit_layout):
|
|
794
|
+
qc_phase.p(phase, qubit)
|
|
795
|
+
qc_phase.barrier()
|
|
796
|
+
qc_phase.compose(qc_inv, inplace=True)
|
|
797
|
+
qc_phase.measure_active()
|
|
798
|
+
qc_list.append(qc_phase)
|
|
705
799
|
|
|
706
800
|
fixed_coupling_map = set_coupling_map(qubit_layout, self.backend, "fixed")
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
801
|
+
|
|
802
|
+
if self.state_generation_routine == "star_optimal":
|
|
803
|
+
qc_list_transpiled = [
|
|
804
|
+
transpile_to_IQM(
|
|
805
|
+
ghz,
|
|
806
|
+
self.backend,
|
|
807
|
+
existing_moves_handling=True,
|
|
808
|
+
perform_move_routing=False,
|
|
809
|
+
optimize_single_qubits=self.optimize_sqg,
|
|
810
|
+
optimization_level=self.qiskit_optim_level,
|
|
811
|
+
)
|
|
812
|
+
for ghz in qc_list
|
|
813
|
+
]
|
|
814
|
+
|
|
815
|
+
else:
|
|
816
|
+
qc_list_transpiled, _ = perform_backend_transpilation(
|
|
817
|
+
qc_list,
|
|
818
|
+
self.backend,
|
|
819
|
+
qubit_layout,
|
|
820
|
+
fixed_coupling_map,
|
|
821
|
+
qiskit_optim_level=self.qiskit_optim_level,
|
|
822
|
+
optimize_sqg=self.optimize_sqg,
|
|
823
|
+
)
|
|
715
824
|
circuit_group = CircuitGroup(name=idx, circuits=qc_list)
|
|
716
825
|
self.circuits["untranspiled_circuits"].circuit_groups.append(circuit_group)
|
|
717
826
|
return qc_list_transpiled
|
|
@@ -791,7 +900,6 @@ class GHZBenchmark(Benchmark):
|
|
|
791
900
|
transpiled_ghz_group: CircuitGroup = self.generate_native_ghz(
|
|
792
901
|
qubit_layout, qubit_count, self.state_generation_routine
|
|
793
902
|
)
|
|
794
|
-
|
|
795
903
|
match self.fidelity_routine:
|
|
796
904
|
case "randomized_measurements":
|
|
797
905
|
all_circuits_list, _ = self.append_rms(cast(int, self.num_RMs), qubit_layout)
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
# pylint: disable=too-many-lines
|
|
1
2
|
"""
|
|
2
|
-
Qscore
|
|
3
|
+
This module contains functions and classes for the Qscore benchmarking process.
|
|
3
4
|
"""
|
|
4
5
|
|
|
5
6
|
import itertools
|
|
@@ -12,7 +13,8 @@ import matplotlib.pyplot as plt
|
|
|
12
13
|
from networkx import Graph
|
|
13
14
|
import networkx as nx
|
|
14
15
|
import numpy as np
|
|
15
|
-
from qiskit import QuantumCircuit
|
|
16
|
+
from qiskit import ClassicalRegister, QuantumCircuit, QuantumRegister
|
|
17
|
+
from qiskit.circuit.library import RZZGate
|
|
16
18
|
from scipy.optimize import basinhopping, minimize
|
|
17
19
|
import xarray as xr
|
|
18
20
|
|
|
@@ -34,6 +36,8 @@ from iqm.benchmarks.utils import ( # execute_with_dd,
|
|
|
34
36
|
submit_execute,
|
|
35
37
|
xrvariable_to_counts,
|
|
36
38
|
)
|
|
39
|
+
from iqm.iqm_client.transpile import ExistingMoveHandlingOptions
|
|
40
|
+
from iqm.qiskit_iqm import IQMCircuit, transpile_to_IQM
|
|
37
41
|
from iqm.qiskit_iqm.iqm_backend import IQMBackendBase
|
|
38
42
|
|
|
39
43
|
|
|
@@ -195,7 +199,7 @@ def get_optimal_angles(num_layers: int) -> List[float]:
|
|
|
195
199
|
# "The fixed angle conjecture for QAOA on regular MaxCut graphs."
|
|
196
200
|
# arXiv preprint arXiv:2107.00677 (2021).
|
|
197
201
|
|
|
198
|
-
OPTIMAL_INITIAL_ANGLES = {
|
|
202
|
+
OPTIMAL_INITIAL_ANGLES = { # pylint: disable=undefined-variable
|
|
199
203
|
"1": [-0.616, 0.393 / 2],
|
|
200
204
|
"2": [-0.488, 0.898 / 2, 0.555 / 2, 0.293 / 2],
|
|
201
205
|
"3": [-0.422, 0.798 / 2, 0.937 / 2, 0.609 / 2, 0.459 / 2, 0.235 / 2],
|
|
@@ -323,6 +327,76 @@ def get_optimal_angles(num_layers: int) -> List[float]:
|
|
|
323
327
|
return OPTIMAL_INITIAL_ANGLES[str(num_layers)]
|
|
324
328
|
|
|
325
329
|
|
|
330
|
+
def group_rzz_gates(circuit: QuantumCircuit):
|
|
331
|
+
"""
|
|
332
|
+
Extract and group commuting RZZ gates so that gates sharing a qubit
|
|
333
|
+
are placed next to each other.
|
|
334
|
+
|
|
335
|
+
Args:
|
|
336
|
+
circuit: QuantumCircuit containing RZZ gates.
|
|
337
|
+
|
|
338
|
+
Returns:
|
|
339
|
+
grouped_rzz: list of tuples (instr, [q0_idx, q1_idx])
|
|
340
|
+
in reordered grouping.
|
|
341
|
+
"""
|
|
342
|
+
# Collect RZZ gates as (gate_pos, instr, [q0, q1])
|
|
343
|
+
rzz_entries = []
|
|
344
|
+
for pos, (instr, qargs, _) in enumerate(circuit.data):
|
|
345
|
+
if isinstance(instr, RZZGate) or getattr(instr, "name", "") == "rzz":
|
|
346
|
+
qidxs = [circuit.find_bit(q).index for q in qargs]
|
|
347
|
+
rzz_entries.append((pos, instr, qidxs))
|
|
348
|
+
|
|
349
|
+
if not rzz_entries:
|
|
350
|
+
return []
|
|
351
|
+
|
|
352
|
+
# Build bipartite graph: gate nodes <-> qubit nodes
|
|
353
|
+
B = nx.Graph()
|
|
354
|
+
for gate_pos, instr, qidxs in rzz_entries:
|
|
355
|
+
gnode = f"g{gate_pos}"
|
|
356
|
+
B.add_node(gnode, kind="gate", instr=instr, qidxs=qidxs)
|
|
357
|
+
for q in qidxs:
|
|
358
|
+
qnode = f"q{q}"
|
|
359
|
+
B.add_node(qnode, kind="qubit", qidx=q)
|
|
360
|
+
B.add_edge(gnode, qnode)
|
|
361
|
+
|
|
362
|
+
grouped_rzz = []
|
|
363
|
+
|
|
364
|
+
# Repeatedly pick the hub qubit with the most RZZs
|
|
365
|
+
while True:
|
|
366
|
+
qubit_nodes = [n for n, d in B.nodes(data=True) if d["kind"] == "qubit"]
|
|
367
|
+
if not qubit_nodes:
|
|
368
|
+
break
|
|
369
|
+
|
|
370
|
+
# Pick hub: max degree, tie-break by smallest index
|
|
371
|
+
hub = max(qubit_nodes, key=lambda q: (B.degree(q), -int(q[1:])))
|
|
372
|
+
hub_idx = int(hub[1:])
|
|
373
|
+
|
|
374
|
+
# Gates connected to hub
|
|
375
|
+
connected_gates = [nbr for nbr in B.neighbors(hub) if nbr.startswith("g")]
|
|
376
|
+
if not connected_gates:
|
|
377
|
+
B.remove_node(hub)
|
|
378
|
+
continue
|
|
379
|
+
|
|
380
|
+
# Sort gates: prioritize partner qubits with higher degree
|
|
381
|
+
def sort_key(g):
|
|
382
|
+
qidxs = B.nodes[g]["qidxs"]
|
|
383
|
+
other = [q for q in qidxs if q != hub_idx][0]
|
|
384
|
+
return (-B.degree(f"q{other}"), other)
|
|
385
|
+
|
|
386
|
+
connected_gates.sort(key=sort_key)
|
|
387
|
+
|
|
388
|
+
# Append in chosen order
|
|
389
|
+
for g in connected_gates:
|
|
390
|
+
data = B.nodes[g]
|
|
391
|
+
grouped_rzz.append((data["qidxs"]))
|
|
392
|
+
B.remove_node(g)
|
|
393
|
+
|
|
394
|
+
# Remove hub itself
|
|
395
|
+
B.remove_node(hub)
|
|
396
|
+
|
|
397
|
+
return grouped_rzz
|
|
398
|
+
|
|
399
|
+
|
|
326
400
|
def plot_approximation_ratios(
|
|
327
401
|
nodes: list[int],
|
|
328
402
|
beta_ratio: list[float],
|
|
@@ -369,7 +443,7 @@ def plot_approximation_ratios(
|
|
|
369
443
|
ax.set_ylabel(r"Q-score ratio $\beta(n)$")
|
|
370
444
|
ax.set_xlabel("Number of nodes $(n)$")
|
|
371
445
|
plt.xticks(range(min(nodes), max(nodes) + 1))
|
|
372
|
-
plt.legend(loc="
|
|
446
|
+
plt.legend(loc="upper right")
|
|
373
447
|
plt.grid(True)
|
|
374
448
|
|
|
375
449
|
if use_virtual_node and use_classically_optimized_angles:
|
|
@@ -600,6 +674,7 @@ class QScoreBenchmark(Benchmark):
|
|
|
600
674
|
self.session_timestamp = strftime("%Y%m%d-%H%M%S")
|
|
601
675
|
self.execution_timestamp = ""
|
|
602
676
|
self.seed = configuration.seed
|
|
677
|
+
self.num_trials = configuration.num_trials
|
|
603
678
|
|
|
604
679
|
self.graph_physical: Graph
|
|
605
680
|
self.virtual_nodes: List[Tuple[int, int]]
|
|
@@ -622,10 +697,107 @@ class QScoreBenchmark(Benchmark):
|
|
|
622
697
|
list(x) for x in cast(Sequence[Sequence[int]], configuration.custom_qubits_array)
|
|
623
698
|
]
|
|
624
699
|
|
|
700
|
+
def greedy_vertex_cover_with_mapping(self, G: nx.Graph):
|
|
701
|
+
"""
|
|
702
|
+
Approximate a minimum vertex cover for a given graph, providing a mapping of nodes to the edges they cover.
|
|
703
|
+
|
|
704
|
+
Args:
|
|
705
|
+
G (nx.Graph): The input graph for which the vertex cover is to be computed.
|
|
706
|
+
|
|
707
|
+
Returns:
|
|
708
|
+
dict: A dictionary where keys are nodes and values are lists of edges that each node covers.
|
|
709
|
+
"""
|
|
710
|
+
|
|
711
|
+
G = G.copy()
|
|
712
|
+
cover_map = {}
|
|
713
|
+
|
|
714
|
+
while G.number_of_edges() > 0:
|
|
715
|
+
# Pick node with max degree
|
|
716
|
+
node = max(G.degree, key=lambda x: x[1])[0]
|
|
717
|
+
|
|
718
|
+
# Collect neighbors (unique)
|
|
719
|
+
neighbors = list(G.neighbors(node))
|
|
720
|
+
cover_map[node] = neighbors
|
|
721
|
+
|
|
722
|
+
# Remove node (and incident edges)
|
|
723
|
+
G.remove_node(node)
|
|
724
|
+
|
|
725
|
+
return cover_map
|
|
726
|
+
|
|
727
|
+
def generate_maxcut_ansatz_star( # pylint: disable=too-many-branches
|
|
728
|
+
self,
|
|
729
|
+
graph,
|
|
730
|
+
theta,
|
|
731
|
+
):
|
|
732
|
+
"""Generate an ansatz circuit for QAOA MaxCut, with measurements at the end.
|
|
733
|
+
|
|
734
|
+
Args:
|
|
735
|
+
graph (networkx graph): the MaxCut problem graph
|
|
736
|
+
theta (list[float]): the variational parameters for QAOA, first gammas then betas
|
|
737
|
+
|
|
738
|
+
Returns:
|
|
739
|
+
QuantumCircuit: the QAOA ansatz quantum circuit.
|
|
740
|
+
"""
|
|
741
|
+
|
|
742
|
+
gamma = theta[: self.num_qaoa_layers]
|
|
743
|
+
beta = theta[self.num_qaoa_layers :]
|
|
744
|
+
|
|
745
|
+
if self.graph_physical.number_of_nodes() != graph.number_of_nodes():
|
|
746
|
+
num_qubits = self.graph_physical.number_of_nodes()
|
|
747
|
+
# re-label the nodes to be between 0 and _num_qubits
|
|
748
|
+
self.node_to_qubit = {node: qubit for qubit, node in enumerate(list(self.graph_physical.nodes))}
|
|
749
|
+
self.qubit_to_node = dict(enumerate(list(self.graph_physical.nodes)))
|
|
750
|
+
else:
|
|
751
|
+
num_qubits = graph.number_of_nodes()
|
|
752
|
+
self.node_to_qubit = {node: node for node in list(self.graph_physical.nodes)} # no relabeling
|
|
753
|
+
self.qubit_to_node = self.node_to_qubit
|
|
754
|
+
|
|
755
|
+
covermap = self.greedy_vertex_cover_with_mapping(self.graph_physical)
|
|
756
|
+
new_covermap = {}
|
|
757
|
+
for key, value in covermap.items():
|
|
758
|
+
new_covermap[self.node_to_qubit[key]] = [self.node_to_qubit[i] for i in value]
|
|
759
|
+
covermap = new_covermap
|
|
760
|
+
|
|
761
|
+
compr = QuantumRegister(1, "compr")
|
|
762
|
+
q = QuantumRegister(num_qubits, "q")
|
|
763
|
+
c = ClassicalRegister(num_qubits, "c")
|
|
764
|
+
qaoa_qc = IQMCircuit(compr, q, c) # num_qb+1,num_qb)
|
|
765
|
+
# in case the graph is trivial: return empty circuit
|
|
766
|
+
if num_qubits == 0:
|
|
767
|
+
return QuantumCircuit(1)
|
|
768
|
+
for i in range(1, num_qubits + 1):
|
|
769
|
+
qaoa_qc.h(i)
|
|
770
|
+
for layer in range(self.num_qaoa_layers):
|
|
771
|
+
for move_qubit, edge_qubits in covermap.items():
|
|
772
|
+
qaoa_qc.move(move_qubit + 1, 0)
|
|
773
|
+
for edge_qubit in edge_qubits:
|
|
774
|
+
qaoa_qc.rzz(2 * gamma[layer], 0, edge_qubit + 1)
|
|
775
|
+
qaoa_qc.move(move_qubit + 1, 0)
|
|
776
|
+
|
|
777
|
+
# include edges of the virtual node as rz terms
|
|
778
|
+
for vn in self.virtual_nodes:
|
|
779
|
+
for edge in graph.edges(vn[0]):
|
|
780
|
+
# exclude edges between virtual nodes
|
|
781
|
+
edges_between_virtual_nodes = list(itertools.combinations([i[0] for i in self.virtual_nodes], 2))
|
|
782
|
+
if set(edge) not in list(map(set, edges_between_virtual_nodes)):
|
|
783
|
+
# The value of the fixed node defines the sign of the rz gate
|
|
784
|
+
sign = 1.0
|
|
785
|
+
if vn[1] == 1:
|
|
786
|
+
sign = -1.0
|
|
787
|
+
qaoa_qc.rz(sign * 2.0 * gamma[layer], self.node_to_qubit[edge[1]] + 1)
|
|
788
|
+
|
|
789
|
+
for i in range(1, num_qubits + 1):
|
|
790
|
+
qaoa_qc.rx(2 * beta[layer], i)
|
|
791
|
+
qaoa_qc.barrier()
|
|
792
|
+
qaoa_qc.measure(q, c)
|
|
793
|
+
|
|
794
|
+
return qaoa_qc
|
|
795
|
+
|
|
625
796
|
def generate_maxcut_ansatz( # pylint: disable=too-many-branches
|
|
626
797
|
self,
|
|
627
798
|
graph: Graph,
|
|
628
799
|
theta: list[float],
|
|
800
|
+
rzz_list=None,
|
|
629
801
|
) -> QuantumCircuit:
|
|
630
802
|
"""Generate an ansatz circuit for QAOA MaxCut, with measurements at the end.
|
|
631
803
|
|
|
@@ -656,10 +828,14 @@ class QScoreBenchmark(Benchmark):
|
|
|
656
828
|
for i in range(0, num_qubits):
|
|
657
829
|
qaoa_qc.h(i)
|
|
658
830
|
for layer in range(self.num_qaoa_layers):
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
831
|
+
if rzz_list is not None and layer == 0:
|
|
832
|
+
for rzzs in rzz_list:
|
|
833
|
+
qaoa_qc.rzz(2 * gamma[layer], rzzs[0], rzzs[1])
|
|
834
|
+
else:
|
|
835
|
+
for edge in self.graph_physical.edges():
|
|
836
|
+
i = self.node_to_qubit[edge[0]]
|
|
837
|
+
j = self.node_to_qubit[edge[1]]
|
|
838
|
+
qaoa_qc.rzz(2 * gamma[layer], i, j)
|
|
663
839
|
|
|
664
840
|
# include edges of the virtual node as rz terms
|
|
665
841
|
for vn in self.virtual_nodes:
|
|
@@ -792,6 +968,33 @@ class QScoreBenchmark(Benchmark):
|
|
|
792
968
|
no_edge_instances = []
|
|
793
969
|
qc_all = [] # all circuits, including those with no edges
|
|
794
970
|
start_seed = seed
|
|
971
|
+
|
|
972
|
+
# Choose the qubit layout
|
|
973
|
+
if self.choose_qubits_routine.lower() == "naive":
|
|
974
|
+
qubit_set = self.choose_qubits_naive(updated_num_nodes)
|
|
975
|
+
elif self.choose_qubits_routine.lower() == "custom" or self.choose_qubits_routine.lower() == "mapomatic":
|
|
976
|
+
qubit_set = self.choose_qubits_custom(updated_num_nodes)
|
|
977
|
+
else:
|
|
978
|
+
raise ValueError('choose_qubits_routine must either be "naive" or "custom".')
|
|
979
|
+
qubit_set_list.append(qubit_set)
|
|
980
|
+
|
|
981
|
+
qcvv_logger.setLevel(logging.WARNING)
|
|
982
|
+
if self.choose_qubits_routine == "naive":
|
|
983
|
+
active_qubit_set = None
|
|
984
|
+
effective_coupling_map = self.backend.coupling_map
|
|
985
|
+
else:
|
|
986
|
+
active_qubit_set = qubit_set
|
|
987
|
+
effective_coupling_map = self.backend.coupling_map.reduce(active_qubit_set)
|
|
988
|
+
|
|
989
|
+
transpilation_params = {
|
|
990
|
+
"backend": self.backend,
|
|
991
|
+
"qubits": active_qubit_set,
|
|
992
|
+
"coupling_map": effective_coupling_map,
|
|
993
|
+
"qiskit_optim_level": self.qiskit_optim_level,
|
|
994
|
+
"optimize_sqg": self.optimize_sqg,
|
|
995
|
+
"routing_method": self.routing_method,
|
|
996
|
+
}
|
|
997
|
+
|
|
795
998
|
for instance in range(self.num_instances):
|
|
796
999
|
qcvv_logger.debug(f"Executing graph {instance} with {num_nodes} nodes.")
|
|
797
1000
|
graph = nx.generators.erdos_renyi_graph(num_nodes, 0.5, seed=seed)
|
|
@@ -820,17 +1023,6 @@ class QScoreBenchmark(Benchmark):
|
|
|
820
1023
|
no_edge_instances.append(instance)
|
|
821
1024
|
qcvv_logger.debug(f"Graph {instance+1}/{self.num_instances} had no edges: cut size = 0.")
|
|
822
1025
|
|
|
823
|
-
# Choose the qubit layout
|
|
824
|
-
if self.choose_qubits_routine.lower() == "naive":
|
|
825
|
-
qubit_set = self.choose_qubits_naive(updated_num_nodes)
|
|
826
|
-
elif (
|
|
827
|
-
self.choose_qubits_routine.lower() == "custom" or self.choose_qubits_routine.lower() == "mapomatic"
|
|
828
|
-
):
|
|
829
|
-
qubit_set = self.choose_qubits_custom(updated_num_nodes)
|
|
830
|
-
else:
|
|
831
|
-
raise ValueError('choose_qubits_routine must either be "naive" or "custom".')
|
|
832
|
-
qubit_set_list.append(qubit_set)
|
|
833
|
-
|
|
834
1026
|
if self.use_classically_optimized_angles:
|
|
835
1027
|
if graph.number_of_edges() != 0:
|
|
836
1028
|
theta = calculate_optimal_angles_for_QAOA_p1(graph)
|
|
@@ -841,11 +1033,26 @@ class QScoreBenchmark(Benchmark):
|
|
|
841
1033
|
|
|
842
1034
|
theta_list.append(theta)
|
|
843
1035
|
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
1036
|
+
if self.backend.has_resonators():
|
|
1037
|
+
qc_opt = self.generate_maxcut_ansatz_star(graph, theta)
|
|
1038
|
+
else:
|
|
1039
|
+
qc_list_temp = []
|
|
1040
|
+
cz_count_temp = []
|
|
1041
|
+
for _ in range(self.num_trials):
|
|
1042
|
+
perm = np.random.permutation(num_nodes)
|
|
1043
|
+
mapping = dict(zip(graph.nodes, perm))
|
|
1044
|
+
G1_permuted = nx.relabel_nodes(graph, mapping)
|
|
1045
|
+
theta = calculate_optimal_angles_for_QAOA_p1(G1_permuted)
|
|
1046
|
+
qc_perm = self.generate_maxcut_ansatz(G1_permuted, theta)
|
|
1047
|
+
transpiled_qc_temp, _ = perform_backend_transpilation([qc_perm], **transpilation_params)
|
|
1048
|
+
cz_count_temp.append(transpiled_qc_temp[0].count_ops().get("cz", 0))
|
|
1049
|
+
qc_list_temp.append(qc_perm)
|
|
1050
|
+
min_cz_index = cz_count_temp.index(min(cz_count_temp))
|
|
1051
|
+
qc_opt = qc_list_temp[min_cz_index]
|
|
1052
|
+
|
|
1053
|
+
if len(qc_opt.count_ops()) != 0:
|
|
1054
|
+
qc_list.append(qc_opt)
|
|
1055
|
+
qc_all.append(qc_opt)
|
|
849
1056
|
qubit_to_node_copy = self.qubit_to_node.copy()
|
|
850
1057
|
qubit_to_node_list.append(qubit_to_node_copy)
|
|
851
1058
|
else:
|
|
@@ -855,24 +1062,20 @@ class QScoreBenchmark(Benchmark):
|
|
|
855
1062
|
seed += 1
|
|
856
1063
|
qcvv_logger.debug(f"Solved the MaxCut on graph {instance+1}/{self.num_instances}.")
|
|
857
1064
|
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
1065
|
+
if self.backend.has_resonators():
|
|
1066
|
+
transpiled_qc = [
|
|
1067
|
+
transpile_to_IQM(
|
|
1068
|
+
qc,
|
|
1069
|
+
self.backend,
|
|
1070
|
+
optimize_single_qubits=self.optimize_sqg,
|
|
1071
|
+
existing_moves_handling=ExistingMoveHandlingOptions.KEEP,
|
|
1072
|
+
perform_move_routing=False,
|
|
1073
|
+
optimization_level=self.qiskit_optim_level,
|
|
1074
|
+
)
|
|
1075
|
+
for qc in qc_list
|
|
1076
|
+
]
|
|
862
1077
|
else:
|
|
863
|
-
|
|
864
|
-
effective_coupling_map = self.backend.coupling_map.reduce(active_qubit_set)
|
|
865
|
-
|
|
866
|
-
transpilation_params = {
|
|
867
|
-
"backend": self.backend,
|
|
868
|
-
"qubits": active_qubit_set,
|
|
869
|
-
"coupling_map": effective_coupling_map,
|
|
870
|
-
"qiskit_optim_level": self.qiskit_optim_level,
|
|
871
|
-
"optimize_sqg": self.optimize_sqg,
|
|
872
|
-
"routing_method": self.routing_method,
|
|
873
|
-
}
|
|
874
|
-
|
|
875
|
-
transpiled_qc, _ = perform_backend_transpilation(qc_list, **transpilation_params)
|
|
1078
|
+
transpiled_qc, _ = perform_backend_transpilation(qc_list, **transpilation_params)
|
|
876
1079
|
|
|
877
1080
|
sorted_transpiled_qc_list = {tuple(qubit_set): transpiled_qc}
|
|
878
1081
|
# Execute on the backend
|
|
@@ -892,9 +1095,7 @@ class QScoreBenchmark(Benchmark):
|
|
|
892
1095
|
num_instances_with_edges = len(instance_with_edges)
|
|
893
1096
|
if self.REM:
|
|
894
1097
|
counts_retrieved, time_retrieve = retrieve_all_counts(jobs)
|
|
895
|
-
rem_counts = apply_readout_error_mitigation(
|
|
896
|
-
backend, transpiled_qc, counts_retrieved, self.mit_shots
|
|
897
|
-
)
|
|
1098
|
+
rem_counts = apply_readout_error_mitigation(backend, transpiled_qc, counts_retrieved, self.mit_shots)
|
|
898
1099
|
execution_results.extend(
|
|
899
1100
|
rem_counts[0][instance].nearest_probability_distribution()
|
|
900
1101
|
for instance in range(num_instances_with_edges)
|
|
@@ -960,6 +1161,7 @@ class QScoreConfiguration(BenchmarkConfigurationBase):
|
|
|
960
1161
|
* Default is 3.
|
|
961
1162
|
optimize_sqg (bool): Whether Single Qubit Gate Optimization is performed upon transpilation.
|
|
962
1163
|
* Default is True.
|
|
1164
|
+
num_trials (Optional[int]): Number of trials to perform when choosing graph permutations to minimize CZ gates.
|
|
963
1165
|
seed (int): The random seed.
|
|
964
1166
|
* Default is 1.
|
|
965
1167
|
REM (bool): Use readout error mitigation.
|
|
@@ -980,6 +1182,7 @@ class QScoreConfiguration(BenchmarkConfigurationBase):
|
|
|
980
1182
|
custom_qubits_array: Optional[Sequence[Sequence[int]]] = None
|
|
981
1183
|
qiskit_optim_level: int = 3
|
|
982
1184
|
optimize_sqg: bool = True
|
|
1185
|
+
num_trials: int = 10
|
|
983
1186
|
seed: int = 1
|
|
984
1187
|
REM: bool = False
|
|
985
1188
|
mit_shots: int = 1000
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: iqm-benchmarks
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.52
|
|
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
|
|
@@ -7,7 +7,7 @@ from iqm.qiskit_iqm.fake_backends.fake_deneb import IQMFakeDeneb
|
|
|
7
7
|
|
|
8
8
|
class TestQScore:
|
|
9
9
|
backend = IQMFakeApollo()
|
|
10
|
-
custom_qubits_array = [[0, 1,
|
|
10
|
+
custom_qubits_array = [[0, 1, 2, 3], [0, 1, 2, 3, 4]]
|
|
11
11
|
|
|
12
12
|
def test_qscore(self):
|
|
13
13
|
EXAMPLE_QSCORE = QScoreConfiguration(
|
|
@@ -15,13 +15,14 @@ class TestQScore:
|
|
|
15
15
|
num_qaoa_layers=1,
|
|
16
16
|
shots=4,
|
|
17
17
|
calset_id=None, # calibration set ID, default is None
|
|
18
|
-
min_num_nodes=
|
|
18
|
+
min_num_nodes=4,
|
|
19
19
|
max_num_nodes=5,
|
|
20
20
|
use_virtual_node=True,
|
|
21
21
|
use_classically_optimized_angles=True,
|
|
22
22
|
choose_qubits_routine="custom",
|
|
23
23
|
custom_qubits_array=self.custom_qubits_array,
|
|
24
|
-
seed=
|
|
24
|
+
seed=200,
|
|
25
|
+
num_trials = 2,
|
|
25
26
|
REM=True,
|
|
26
27
|
mit_shots=10,
|
|
27
28
|
)
|
|
@@ -32,4 +33,4 @@ class TestQScore:
|
|
|
32
33
|
|
|
33
34
|
class TestQScoreDeneb(TestQScore):
|
|
34
35
|
backend = IQMFakeDeneb()
|
|
35
|
-
custom_qubits_array = [[1, 2, 3
|
|
36
|
+
custom_qubits_array = [[1, 2, 3, 4], [1, 2, 3, 4, 5]]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/docs/development/generate_2qubit_cliffords.ipynb
RENAMED
|
File without changes
|
{iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/docs/development/how_to_make_your_own_benchmark.ipynb
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/src/iqm/benchmarks/compressive_gst/compressive_gst.py
RENAMED
|
File without changes
|
{iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/src/iqm/benchmarks/compressive_gst/gst_analysis.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/src/iqm/benchmarks/quantum_volume/quantum_volume.py
RENAMED
|
File without changes
|
{iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/src/iqm/benchmarks/randomized_benchmarking/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/src/iqm/benchmarks/randomized_benchmarking/eplg/eplg.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{iqm_benchmarks-2.50 → iqm_benchmarks-2.52}/src/iqm_benchmarks.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|