final first commit

This commit is contained in:
2026-05-19 17:19:36 +08:00
commit b199e2105e
114 changed files with 6844 additions and 0 deletions

View File

@@ -0,0 +1,33 @@
NQUBITS = "3,4,5"
MAX_QUBITS = "0,1,2,3,4"
QIBO_BACKENDS = "qibojit,tensorflow,numpy"
LIBRARIES = "qibo,qiskit,cirq,qsim,tfq,qulacs,projectq,hybridq"
def pytest_addoption(parser):
parser.addoption("--nqubits", type=str, default=NQUBITS)
parser.addoption("--max-qubits", type=str, default=MAX_QUBITS)
parser.addoption("--qibo-backends", type=str, default=QIBO_BACKENDS)
parser.addoption("--libraries", type=str, default=LIBRARIES)
parser.addoption("--add", type=str, default="")
def pytest_generate_tests(metafunc):
nqubits = [int(n) for n in metafunc.config.option.nqubits.split(",")]
library_options = [f"max_qubits={n}" for n in metafunc.config.option.max_qubits.split(",")]
backends = metafunc.config.option.qibo_backends.split(",")
libraries = metafunc.config.option.libraries.split(",")
additional = metafunc.config.option.add
if additional:
libraries.extend(additional.split(","))
if "nqubits" in metafunc.fixturenames:
metafunc.parametrize("nqubits", nqubits)
if "backend" in metafunc.fixturenames:
metafunc.parametrize("backend", backends)
if "library" in metafunc.fixturenames:
metafunc.parametrize("library", libraries)
if "library_options" in metafunc.fixturenames:
metafunc.parametrize("library_options", library_options)
if "transfer" in metafunc.fixturenames:
metafunc.parametrize("transfer", [False, True])

View File

@@ -0,0 +1 @@
{"directed": false, "multigraph": false, "graph": {}, "nodes": [{"id": 6}, {"id": 18}, {"id": 7}, {"id": 20}, {"id": 26}, {"id": 27}, {"id": 12}, {"id": 19}, {"id": 3}, {"id": 13}, {"id": 14}, {"id": 25}, {"id": 5}, {"id": 9}, {"id": 11}, {"id": 17}, {"id": 0}, {"id": 23}, {"id": 10}, {"id": 21}, {"id": 2}, {"id": 8}, {"id": 15}, {"id": 4}, {"id": 1}, {"id": 16}, {"id": 24}, {"id": 22}], "links": [{"source": 6, "target": 18}, {"source": 6, "target": 3}, {"source": 6, "target": 0}, {"source": 18, "target": 14}, {"source": 18, "target": 24}, {"source": 7, "target": 20}, {"source": 7, "target": 10}, {"source": 7, "target": 1}, {"source": 20, "target": 9}, {"source": 20, "target": 21}, {"source": 26, "target": 27}, {"source": 26, "target": 2}, {"source": 26, "target": 3}, {"source": 27, "target": 23}, {"source": 27, "target": 25}, {"source": 12, "target": 19}, {"source": 12, "target": 9}, {"source": 12, "target": 11}, {"source": 19, "target": 5}, {"source": 19, "target": 10}, {"source": 3, "target": 13}, {"source": 13, "target": 4}, {"source": 13, "target": 21}, {"source": 14, "target": 25}, {"source": 14, "target": 15}, {"source": 25, "target": 17}, {"source": 5, "target": 4}, {"source": 5, "target": 24}, {"source": 9, "target": 16}, {"source": 11, "target": 17}, {"source": 11, "target": 1}, {"source": 17, "target": 15}, {"source": 0, "target": 23}, {"source": 0, "target": 1}, {"source": 23, "target": 8}, {"source": 10, "target": 21}, {"source": 2, "target": 8}, {"source": 2, "target": 22}, {"source": 8, "target": 16}, {"source": 15, "target": 22}, {"source": 4, "target": 16}, {"source": 24, "target": 22}]}

View File

@@ -0,0 +1 @@
{"directed": false, "multigraph": false, "graph": {}, "nodes": [{"id": 0}, {"id": 7}, {"id": 1}, {"id": 2}, {"id": 4}, {"id": 3}, {"id": 5}, {"id": 6}], "links": [{"source": 0, "target": 7}, {"source": 0, "target": 4}, {"source": 0, "target": 3}, {"source": 7, "target": 1}, {"source": 7, "target": 4}, {"source": 1, "target": 2}, {"source": 1, "target": 6}, {"source": 2, "target": 6}, {"source": 2, "target": 5}, {"source": 4, "target": 5}, {"source": 3, "target": 6}, {"source": 3, "target": 5}]}

View File

@@ -0,0 +1,165 @@
"""Check that execution of circuits from external simulation libraries agrees with Qibo."""
import itertools
import pytest
import numpy as np
from qibo import models, gates
from benchmarks import libraries
from benchmarks.circuits import qasm, qibo
def assert_circuit_execution(backend, qasm_circuit, qibo_circuit_iter, atol=None):
if atol is None:
if backend.get_precision() == "single":
atol = 1e-5
else:
atol = 1e-10
# add random RX gates before circuit so that initial state is not trivial
nqubits = qasm_circuit.nqubits
theta = np.random.random(nqubits)
qasm_code = qasm_circuit.to_qasm(theta=theta)
# execute circuit using backend
circuit = backend.from_qasm(qasm_code)
final_state = backend(circuit)
final_state = backend.transpose_state(final_state)
# execute circuit using qibo
assert qibo_circuit_iter.nqubits == nqubits
target_circuit = models.Circuit(nqubits)
target_circuit.add(gates.RX(i, theta=t) for i, t in enumerate(theta))
target_circuit.add(qibo_circuit_iter)
target_state = target_circuit()
# check fidelity instead of absolute states due to different definitions
# of the phase of U gates in different backends
fidelity = np.abs(np.conj(target_state).dot(np.array(final_state)))
np.testing.assert_allclose(fidelity, 1.0, atol=atol)
@pytest.mark.parametrize("nlayers", ["1", "4"])
@pytest.mark.parametrize("gate, qibo_gate",
[("h", "H"), ("x", "X"), ("y", "Y"), ("z", "Z")])
def test_one_qubit_gate(nqubits, library, nlayers, gate, qibo_gate):
qasm_circuit = qasm.OneQubitGate(nqubits, nlayers=nlayers, gate=gate)
target_circuit = qibo.OneQubitGate(nqubits, nlayers=nlayers, gate=qibo_gate)
backend = libraries.get(library)
assert_circuit_execution(backend, qasm_circuit, target_circuit)
@pytest.mark.parametrize("gate,qibo_gate,params",
[("rx", "RX", {"theta": 0.1}),
("ry", "RY", {"theta": 0.3}),
("rz", "RZ", {"theta": 0.2}),
("u1", "U1", {"theta": 0.3}),
("u2", "U2", {"phi": 0.2, "lam": 0.3}),
("u3", "U3", {"theta": 0.1, "phi": 0.2, "lam": 0.3})])
def test_one_qubit_gate_parametrized(nqubits, library, gate, qibo_gate, params):
if gate in {"u1", "u2", "u3"} and library == "tfq":
pytest.skip("Skipping {} test because it is not supported by {}."
"".format(gate, library))
order = ["theta", "phi", "lam"]
angles = ",".join(str(params.get(n)) for n in order if n in params)
qasm_circuit = qasm.OneQubitGate(nqubits, gate=gate, angles=angles)
target_circuit = qibo.OneQubitGate(nqubits, gate=qibo_gate, **params)
backend = libraries.get(library)
assert_circuit_execution(backend, qasm_circuit, target_circuit)
@pytest.mark.parametrize("nlayers", ["1", "4"])
@pytest.mark.parametrize("gate,qibo_gate",
[("cx", "CNOT"), ("swap", "SWAP"), ("cz", "CZ")])
def test_two_qubit_gate(nqubits, library, nlayers, gate, qibo_gate):
qasm_circuit = qasm.TwoQubitGate(nqubits, nlayers=nlayers, gate=gate)
target_circuit = qibo.TwoQubitGate(nqubits, nlayers=nlayers, gate=qibo_gate)
backend = libraries.get(library)
assert_circuit_execution(backend, qasm_circuit, target_circuit)
@pytest.mark.parametrize("gate,qibo_gate,params",
[("cu1", "CU1", {"theta": 0.3}),
#("cu2", "CU2", {"phi": 0.1, "lam": 0.3}), # not supported by OpenQASM
("cu3", "CU3", {"theta": 0.1, "phi": 0.2, "lam": 0.3})])
def test_two_qubit_gate_parametrized(nqubits, library, gate, qibo_gate, params):
if gate in {"cu1", "cu2", "cu3"} and library == "tfq":
pytest.skip("Skipping {} test because it is not supported by {}."
"".format(gate, library))
if gate in {"cu3"} and library == "projectq":
pytest.skip("Skipping {} test because it is not supported by {}."
"".format(gate, library))
order = ["theta", "phi", "lam"]
angles = ",".join(str(params.get(n)) for n in order if n in params)
qasm_circuit = qasm.TwoQubitGate(nqubits, gate=gate, angles=angles)
target_circuit = qibo.TwoQubitGate(nqubits, gate=qibo_gate, **params)
backend = libraries.get(library)
assert_circuit_execution(backend, qasm_circuit, target_circuit)
@pytest.mark.parametrize("swaps", ["False", "True"])
def test_qft(nqubits, library, swaps, library_options):
qasm_circuit = qasm.QFT(nqubits, swaps=swaps)
target_circuit = qibo.QFT(nqubits, swaps=swaps)
backend = libraries.get(library, library_options)
assert_circuit_execution(backend, qasm_circuit, target_circuit)
@pytest.mark.parametrize("nlayers", ["2", "5"])
def test_variational(nqubits, library, nlayers, library_options):
qasm_circuit = qasm.VariationalCircuit(nqubits, nlayers=nlayers)
target_circuit = qibo.VariationalCircuit(nqubits, nlayers=nlayers)
backend = libraries.get(library, library_options)
assert_circuit_execution(backend, qasm_circuit, target_circuit)
def test_bernstein_vazirani(nqubits, library, library_options):
qasm_circuit = qasm.BernsteinVazirani(nqubits)
target_circuit = qibo.BernsteinVazirani(nqubits)
backend = libraries.get(library, library_options)
assert_circuit_execution(backend, qasm_circuit, target_circuit)
def test_hidden_shift(nqubits, library, library_options):
shift = "".join(str(x) for x in np.random.randint(0, 2, size=(nqubits,)))
qasm_circuit = qasm.HiddenShift(nqubits, shift=shift)
target_circuit = qibo.HiddenShift(nqubits, shift=shift)
backend = libraries.get(library, library_options)
assert_circuit_execution(backend, qasm_circuit, target_circuit)
def test_qaoa_circuit(library, library_options):
if library in {"qibo", "qcgpu"}:
pytest.skip(f"{library} does not have built-in RZZ gate.")
import pathlib
folder = str(pathlib.Path(__file__).with_name("graphs") / "testgraph8.json")
qasm_circuit = qasm.QAOA(8, graph=folder)
target_circuit = qibo.QAOA(8, graph=folder)
backend = libraries.get(library, library_options)
assert_circuit_execution(backend, qasm_circuit, target_circuit)
@pytest.mark.parametrize("depth", ["2", "5", "10"])
def test_supremacy_circuit(nqubits, library, depth, library_options):
qasm_circuit = qasm.SupremacyCircuit(nqubits, depth=depth)
target_circuit = qibo.SupremacyCircuit(nqubits, depth=depth)
backend = libraries.get(library, library_options)
assert_circuit_execution(backend, qasm_circuit, target_circuit)
@pytest.mark.parametrize("simtime", ["1", "2.5"])
def test_basis_change(nqubits, library, simtime, library_options):
qasm_circuit = qasm.BasisChange(nqubits, simulation_time=simtime)
target_circuit = qibo.BasisChange(nqubits, simulation_time=simtime)
backend = libraries.get(library, library_options)
assert_circuit_execution(backend, qasm_circuit, target_circuit)
@pytest.mark.parametrize("depth", ["2", "5", "8"])
def test_quantum_volume(nqubits, library, depth, library_options):
if library == "tfq":
pytest.skip("Skipping qv test because it is not supported by {}."
"".format(library))
qasm_circuit = qasm.QuantumVolume(nqubits, depth=depth)
target_circuit = qibo.QuantumVolume(nqubits, depth=depth)
backend = libraries.get(library, library_options)
assert_circuit_execution(backend, qasm_circuit, target_circuit)

View File

@@ -0,0 +1,166 @@
import pytest
from benchmarks.scripts import circuit_benchmark, evolution_benchmark
def assert_logs(logs, nqubits, backend, nreps=1):
assert logs[-1]["nqubits"] == nqubits
assert logs[-1]["backend"] == backend
assert logs[-1]["simulation_times_mean"] >= 0
assert logs[-1]["transfer_times_mean"] >= 0
assert len(logs[-1]["simulation_times"]) == nreps
assert len(logs[-1]["transfer_times"]) == nreps
@pytest.mark.parametrize("nreps", [1, 5])
@pytest.mark.parametrize("nlayers", ["1", "4"])
@pytest.mark.parametrize("gate", ["H", "X", "Y", "Z"])
def test_one_qubit_gate_benchmark(nqubits, backend, transfer, nreps,
nlayers, gate):
logs = circuit_benchmark(nqubits, backend, circuit_name="one-qubit-gate",
nreps=nreps, transfer=transfer,
circuit_options=f"gate={gate},nlayers={nlayers}")
assert_logs(logs, nqubits, backend, nreps)
target_options = f"nqubits={nqubits}, nlayers={nlayers}, "
target_options += f"gate={gate}, params={{}}"
assert logs[-1]["circuit"] == "one-qubit-gate"
assert logs[-1]["circuit_options"] == target_options
@pytest.mark.parametrize("gate,params",
[("RX", "theta=0.1"), ("RZ", "theta=0.2"),
("U1", "theta=0.3"), ("U2", "phi=0.2,lam=0.3"),
("U3", "theta=0.1,phi=0.2,lam=0.3")])
def test_one_qubit_gate_param_benchmark(nqubits, backend, gate, params):
logs = circuit_benchmark(nqubits, backend, circuit_name="one-qubit-gate",
circuit_options=f"gate={gate},{params}")
assert_logs(logs, nqubits, backend)
target_options = f"nqubits={nqubits}, nlayers=1, gate={gate}"
paramdict = {}
for param in params.split(","):
k, v = param.split("=")
paramdict[k] = v
target_options = f"{target_options}, params={paramdict}"
assert logs[-1]["circuit"] == "one-qubit-gate"
assert logs[-1]["circuit_options"] == target_options
@pytest.mark.parametrize("nreps", [1, 5])
@pytest.mark.parametrize("nlayers", ["1", "4"])
@pytest.mark.parametrize("gate", ["CNOT", "SWAP", "CZ"])
def test_two_qubit_gate_benchmark(nqubits, backend, transfer, nreps,
nlayers, gate):
logs = circuit_benchmark(nqubits, backend, circuit_name="two-qubit-gate",
nreps=nreps, transfer=transfer,
circuit_options=f"gate={gate},nlayers={nlayers}")
assert_logs(logs, nqubits, backend, nreps)
target_options = f"nqubits={nqubits}, nlayers={nlayers}, "
target_options += f"gate={gate}, params={{}}"
assert logs[-1]["circuit"] == "two-qubit-gate"
assert logs[-1]["circuit_options"] == target_options
@pytest.mark.parametrize("gate,params",
[("CRX", "theta=0.1"), ("CRZ", "theta=0.2"),
("CU1", "theta=0.3"), ("CU2", "phi=0.2,lam=0.3"),
("CU3", "theta=0.1,phi=0.2,lam=0.3"),
("fSim", "theta=0.1,phi=0.2")])
def test_two_qubit_gate_param_benchmark(nqubits, backend, gate, params):
logs = circuit_benchmark(nqubits, backend, circuit_name="two-qubit-gate",
circuit_options=f"gate={gate},{params}")
assert_logs(logs, nqubits, backend)
target_options = f"nqubits={nqubits}, nlayers=1, gate={gate}"
paramdict = {}
for param in params.split(","):
k, v = param.split("=")
paramdict[k] = v
target_options = f"{target_options}, params={paramdict}"
assert logs[-1]["circuit"] == "two-qubit-gate"
assert logs[-1]["circuit_options"] == target_options
@pytest.mark.parametrize("nreps", [1, 5])
@pytest.mark.parametrize("swaps", [False, True])
def test_qft_benchmark(nqubits, backend, transfer, nreps, swaps):
logs = circuit_benchmark(nqubits, backend, circuit_name="qft",
nreps=nreps, transfer=transfer,
circuit_options=f"swaps={swaps}")
assert_logs(logs, nqubits, backend, nreps)
target_options = f"nqubits={nqubits}, swaps={swaps}"
assert logs[-1]["circuit"] == "qft"
assert logs[-1]["circuit_options"] == target_options
@pytest.mark.parametrize("varlayer", [False, True])
def test_variational_benchmark(nqubits, backend, varlayer):
logs = circuit_benchmark(nqubits, backend, circuit_name="variational",
circuit_options=f"varlayer={varlayer}")
assert_logs(logs, nqubits, backend)
target_options = f"nqubits={nqubits}, nlayers=1, seed=123, varlayer={varlayer}"
assert logs[-1]["circuit"] == "variational"
assert logs[-1]["circuit_options"] == target_options
def test_bernstein_vazirani_benchmark(nqubits, backend):
logs = circuit_benchmark(nqubits, backend, circuit_name="bv")
assert_logs(logs, nqubits, backend)
assert logs[-1]["circuit"] == "bv"
assert logs[-1]["circuit_options"] == f"nqubits={nqubits}"
@pytest.mark.parametrize("random", [True, False])
def test_hidden_shift_benchmark(nqubits, backend, random):
shift = "" if random else nqubits * "0"
logs = circuit_benchmark(nqubits, backend, circuit_name="hs",
circuit_options=f"shift={shift}")
assert_logs(logs, nqubits, backend)
target_options = f"nqubits={nqubits}, shift={shift}"
assert logs[-1]["circuit"] == "hs"
assert logs[-1]["circuit_options"] == target_options
def test_qaoa_benchmark(backend):
logs = circuit_benchmark(4, backend, circuit_name="qaoa")
assert_logs(logs, 4, backend)
target_options = f"nqubits=4, nparams=2, graph=, seed=123"
assert logs[-1]["circuit"] == "qaoa"
assert logs[-1]["circuit_options"] == target_options
@pytest.mark.parametrize("depth", ["2", "5", "10"])
def test_supremacy_benchmark(nqubits, backend, depth):
logs = circuit_benchmark(nqubits, backend, circuit_name="supremacy",
circuit_options=f"depth={depth}")
assert_logs(logs, nqubits, backend)
target_options = f"nqubits={nqubits}, depth={depth}, seed=123"
assert logs[-1]["circuit"] == "supremacy"
assert logs[-1]["circuit_options"] == target_options
@pytest.mark.parametrize("simtime", ["1", "2.5"])
def test_basis_change_benchmark(nqubits, backend, simtime):
logs = circuit_benchmark(nqubits, backend, circuit_name="bc",
circuit_options=f"simulation_time={simtime}")
assert_logs(logs, nqubits, backend)
target_options = f"nqubits={nqubits}, simulation_time={simtime}, seed=123"
assert logs[-1]["circuit"] == "bc"
assert logs[-1]["circuit_options"] == target_options
@pytest.mark.parametrize("depth", ["2", "5", "8"])
def test_quantum_volume_benchmark(nqubits, backend, depth):
logs = circuit_benchmark(nqubits, backend, circuit_name="qv",
circuit_options=f"depth={depth}")
assert_logs(logs, nqubits, backend)
target_options = f"nqubits={nqubits}, depth={depth}, seed=123"
assert logs[-1]["circuit"] == "qv"
assert logs[-1]["circuit_options"] == target_options
@pytest.mark.parametrize("dt", [0.01, 0.05, 0.1])
@pytest.mark.parametrize("dense", [False, True])
def test_adiabatic_evolution_benchmark(nqubits, dt, backend, dense, solver="exp"):
logs = evolution_benchmark(nqubits, dt, solver, backend, dense=dense)
assert logs[-1]["nqubits"] == nqubits
assert logs[-1]["dt"] == dt
assert logs[-1]["backend"] == backend
assert logs[-1]["dense"] == dense

View File

@@ -0,0 +1,112 @@
"""Tests for circuits defined in benchmarks/circuits/qibo.py"""
import pytest
from qibo.models import Circuit
from benchmarks.circuits import qibo
@pytest.mark.parametrize("nlayers", [1, 2, 3, 4, 5])
@pytest.mark.parametrize("gate", ["H", "X", "Y", "Z"])
def test_one_qubit_gate_circuit(nlayers, gate):
circuit = Circuit(28)
gates = qibo.OneQubitGate(28, nlayers=nlayers, gate=gate)
circuit.add(gates)
assert circuit.nqubits == 28
assert circuit.depth == nlayers
assert circuit.ngates == nlayers * 28
@pytest.mark.parametrize("nlayers", [1, 2, 3, 4, 5])
@pytest.mark.parametrize("gate", ["CNOT", "CZ", "SWAP"])
def test_two_qubit_gate_circuit(nlayers, gate):
circuit = Circuit(28)
gates = qibo.TwoQubitGate(28, nlayers=nlayers, gate=gate)
circuit.add(gates)
assert circuit.nqubits == 28
assert circuit.depth == nlayers * 2
assert circuit.ngates == nlayers * 27
@pytest.mark.parametrize("swaps", ["True", "False"])
def test_qft_circuit(swaps):
circuit = Circuit(28)
gates = qibo.QFT(28, swaps=swaps)
circuit.add(gates)
assert circuit.nqubits == 28
if swaps == "True":
assert circuit.depth == 56
assert circuit.ngates == 420
else:
assert circuit.depth == 55
assert circuit.ngates == 406
@pytest.mark.parametrize("varlayer", ["True", "False"])
def test_variational_circuit(varlayer):
circuit = Circuit(28)
gates = qibo.VariationalCircuit(28, varlayer=varlayer)
circuit.add(gates)
assert circuit.nqubits == 28
if varlayer == "True":
assert circuit.depth == 2
assert circuit.ngates == 28
else:
assert circuit.depth == 4
assert circuit.ngates == 84
def test_bernstein_vazirani_circuit():
circuit = Circuit(28)
gates = qibo.BernsteinVazirani(28)
circuit.add(gates)
assert circuit.nqubits == 28
assert circuit.depth == 30
assert circuit.ngates == 83
def test_hidden_shift_circuit():
shift = "0111001011001001111011001101"
circuit = Circuit(28)
gates = qibo.HiddenShift(28, shift=shift)
circuit.add(gates)
assert circuit.nqubits == 28
assert circuit.depth == 7
assert circuit.ngates == 144
def test_qaoa_circuit():
import pathlib
folder = str(pathlib.Path(__file__).with_name("graphs") / "testgraph28.json")
circuit = Circuit(28)
gates = qibo.QAOA(28, graph=folder)
circuit.add(gates)
assert circuit.nqubits == 28
assert circuit.ngates == 168
assert circuit.depth == 18
def test_supremacy_circuit():
circuit = Circuit(28)
gates = qibo.SupremacyCircuit(28, depth="40")
circuit.add(gates)
assert circuit.nqubits == 28
assert circuit.ngates == 880
assert circuit.depth == 42
def test_basis_change_circuit():
circuit = Circuit(28)
gates = qibo.BasisChange(28)
circuit.add(gates)
assert circuit.nqubits == 28
assert circuit.ngates == 9912
assert circuit.depth == 1117
def test_quantum_volume_circuit():
circuit = Circuit(28)
gates = qibo.QuantumVolume(28, depth=10)
circuit.add(gates)
assert circuit.nqubits == 28
assert circuit.ngates == 1540
assert circuit.depth == 70