Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/support qiskit1.2 #67

Merged
merged 7 commits into from
Sep 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ classifiers = [
]

dependencies = [
"qiskit~=1.0.0",
"qiskit~=1.2.0",
]

# This command, 'pip install {package-name}[test]',
Expand Down
5 changes: 3 additions & 2 deletions qdd/qdd_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,13 +162,14 @@ class QddBackend(BackendV1):
"cu3",
"crx",
"cry",
"crz" # rotation + 1 control
"crz", # rotation + 1 control
# "mcu1", "mcu2", "mcu3","mcu","mcp","mcphase", "mcrx", "mcry", "mcrz", "mcr", # rotation + multi controls
"rxx",
"ryy",
"rzz",
"rzx",
# "unitary",
"reset",
]
),
"gates": [],
Expand Down Expand Up @@ -695,7 +696,7 @@ def _evaluate_circuit(
for i, qargs, cargs in circ.data:
skip = False
if i.condition is not None:
classical , val = i.condition
classical, val = i.condition
if isinstance(classical, Clbit):
if val_cbit[self.get_cID(classical)] != str(int(val)):
skip = True
Expand Down
15 changes: 9 additions & 6 deletions test/python/helpers/circuit_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,19 @@ def get_simple_circuit(num_qubits: int) -> QuantumCircuit:
return circ


def run_simple_circuit(num_qubits: int, shots: int) -> JobV1:
def run_simple_circuit(num_qubits: int, shots: int, skip_transpile=False) -> JobV1:
"""Executes a simple circuit that contains no stochastic operations and returns a 'counts' result."""

circ = get_simple_circuit(num_qubits)
backend = QddProvider().get_backend()
job = backend.run(
transpile(circuits=circ, backend=backend, seed_transpiler=50),
shots=shots,
seed_simulator=80,
)
if skip_transpile:
job = backend.run(circ, shots=shots, seed_simulator=80)
else:
job = backend.run(
transpile(circuits=circ, backend=backend, seed_transpiler=50),
shots=shots,
seed_simulator=80,
)
return job


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ def test_transpiler_log(caplog):
log_circ.h(1)
log_circ.x(1)
log_circ.cx(0, 1)
log_circ.dcx(0, 1)
log_circ.measure([0, 1], [0, 1])

backend = QddProvider().get_backend()
Expand Down
2 changes: 0 additions & 2 deletions test/python/qiskit_tutorials/algorithms/test_iqpe.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@
from qdd import QddProvider
from qdd.qdd_sampler import Sampler

from qiskit.primitives import Sampler as QiskitSampler


def x_measurement(qc, qubit, cbit):
"""Measure 'qubit' in the X-basis, and store the result in 'cbit'"""
Expand Down
20 changes: 14 additions & 6 deletions test/python/qiskit_tutorials/algorithms/test_vqe.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import numpy as np
import pytest
from qiskit.circuit.library import EfficientSU2
from qiskit.primitives import Estimator as QiskitEstimator
from qiskit.primitives import StatevectorEstimator as QiskitEstimator
from qiskit.quantum_info import SparsePauliOp
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
from scipy.optimize import minimize
Expand All @@ -13,7 +13,7 @@
from qdd.qdd_estimator import Estimator as QddEstimator


def test_sampler():
def test_vqe():
backend = QddProvider().get_backend()
estimator_qdd = QddEstimator(run_options={"shots": None}, approximation=True)

Expand All @@ -26,26 +26,34 @@ def test_sampler():
ansatz = EfficientSU2(hamiltonian.num_qubits)
num_params = ansatz.num_parameters


pm = generate_preset_pass_manager(backend=backend, optimization_level=3)

ansatz_isa = pm.run(ansatz)

def cost_func(params, ansatz, hamiltonian, estimator):
def cost_func_qdd(params, ansatz, hamiltonian, estimator):
result = estimator.run(ansatz, hamiltonian, params).result()
energy = result.values[0]

return energy

x0 = 2 * np.pi * np.random.random(num_params)
result_qdd = minimize(
cost_func, x0, args=(ansatz_isa, hamiltonian, estimator_qdd), method="cobyla"
cost_func_qdd,
x0,
args=(ansatz_isa, hamiltonian, estimator_qdd),
method="cobyla",
)
energy_qdd = result_qdd.fun

def cost_func_qiskit(params, ansatz, hamiltonian, estimator):
result = estimator.run(pubs=[(ansatz, hamiltonian, params)]).result()
energy = result[0].data.evs

return energy

x0 = 2 * np.pi * np.random.random(num_params)
result_qiskit = minimize(
cost_func,
cost_func_qiskit,
x0,
args=(ansatz_isa, hamiltonian, estimator_qiskit),
method="cobyla",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@
from qiskit.quantum_info import Kraus, Operator, SuperOp
from qiskit_aer import Aer
from qiskit_aer.noise import NoiseModel, QuantumError, pauli_error
from qiskit_ibm_runtime.fake_provider import FakeVigo
from qiskit_ibm_runtime.fake_provider import FakeVigoV2

from qdd import QddBackend, QddProvider


def test_noise_simulation():
device_backend = FakeVigo()
device_backend = FakeVigoV2()
with pytest.raises(Exception):
QddBackend.from_backend(device_backend)

Expand Down Expand Up @@ -59,7 +59,8 @@ def test_gates_with_labels():
cx_circ.measure_all()

qdd_backend = QddProvider().get_backend()
circ = transpile(cx_circ, backend=qdd_backend, seed_transpiler=50)
basis_gates = qdd_backend.configuration().basis_gates
circ = transpile(cx_circ, basis_gates=basis_gates, seed_transpiler=50)
qdd_counts = qdd_backend.run(circ, seed_simulator=80).result().get_counts()

aer_backend = Aer.get_backend("aer_simulator")
Expand Down
12 changes: 5 additions & 7 deletions test/python/qiskit_tutorials/operators/test_operator_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from qiskit.circuit import Parameter, QuantumCircuit
from qiskit.circuit.library import PauliEvolutionGate
from qiskit.quantum_info import SparsePauliOp
from qiskit.primitives import Estimator as QiskitEstimator
from qiskit.primitives import StatevectorEstimator as QiskitEstimator
from qiskit.synthesis import SuzukiTrotter

from qdd.qdd_estimator import Estimator
Expand Down Expand Up @@ -55,15 +55,13 @@ def test_circuit_sampler():
circuits=evo_circ, observables=h2_measurement, parameter_values=time
)
.result()
.values
.values[0]
)
print(f"with QDD Estimator : {qdd_value}")
qiskit_value = (
estimator_qiskit.run(
circuits=evo_circ, observables=h2_measurement, parameter_values=time
)
.result()
.values
estimator_qiskit.run(pubs=[(evo_circ, h2_measurement, time)])
.result()[0]
.data.evs
)
print(f"with Qiskit Estimator : {qiskit_value}")
assert qiskit_value == pytest.approx(qdd_value, abs=0.02)
7 changes: 4 additions & 3 deletions test/python/test_basics.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def test_num_qubits_2():

def test_num_qubits_max_plus_1():
max_qubits = QddBackend._DEFAULT_CONFIG["n_qubits"]
job = run_simple_circuit(num_qubits=max_qubits + 1, shots=20)
job = run_simple_circuit(num_qubits=max_qubits + 1, shots=20, skip_transpile=True)
assert_job_failed(job)


Expand Down Expand Up @@ -133,9 +133,10 @@ def test_sv():
transpile(circuits=circ_h, backend=qdd_backend, seed_transpiler=50),
seed_simulator=80,
)
global_phase = qdd_job_h.result().results[0].header.global_phase
sv = qdd_job_h.result().get_statevector()
assert cmath.isclose(sv[0], 1 / math.sqrt(2))
assert cmath.isclose(sv[1], 1 / math.sqrt(2))
assert cmath.isclose(sv[0] * cmath.exp(1j * global_phase), 1 / math.sqrt(2))
assert cmath.isclose(sv[1] * cmath.exp(1j * global_phase), 1 / math.sqrt(2))


def test_get_counts():
Expand Down
32 changes: 18 additions & 14 deletions test/python/test_estimator.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# https://docs.quantum.ibm.com/api/qiskit/qiskit.primitives.BaseEstimatorV1
from math import sqrt
import pytest
from qiskit.primitives import Estimator as QiskitEstimator
from qiskit.primitives import StatevectorEstimator as QiskitEstimator
from qiskit.circuit.library import RealAmplitudes
from qiskit.quantum_info import SparsePauliOp
from qdd.qdd_estimator import Estimator
Expand Down Expand Up @@ -32,20 +32,22 @@ def test_estimator():
job = estimator_exact.run([psi1], [H1], [theta1])
job_result_exact = job.result()
print(f"The qdd-job without sampling finished with result {job_result_exact}")
job = estimator_qiskit.run([psi1], [H1], [theta1])
job_result_qiskit = job.result()
job = estimator_qiskit.run(pubs=[(psi1, H1, theta1)])
job_result_qiskit = job.result()[0]
print(f"The qiskit-job finished with result {job_result_qiskit}")
var = job_result.metadata[0]["variance"]
std = sqrt(var / 4096)
assert job_result.values == pytest.approx(
job_result_qiskit.values, rel=0.2, abs=std * 6
assert job_result.values[0] == pytest.approx(
job_result_qiskit.data.evs, rel=0.2, abs=std * 6
)
var = job_result_approx.metadata[0]["variance"]
std = sqrt(var / 4096)
assert job_result_approx.values == pytest.approx(
job_result_qiskit.values, rel=0.2, abs=std * 6
assert job_result_approx.values[0] == pytest.approx(
job_result_qiskit.data.evs, rel=0.2, abs=std * 6
)
assert job_result_exact.values[0] == pytest.approx(
job_result_qiskit.data.evs, rel=1e-6
)
assert job_result_exact.values == pytest.approx(job_result_qiskit.values, rel=1e-6)


def test_estimator2():
Expand Down Expand Up @@ -84,22 +86,24 @@ def test_estimator2():
)
job_result_exact = job2.result()
print(f"The qdd-job without sampling finished with result {job_result_exact}")
job2 = estimator_qiskit.run(
[psi1, psi2, psi1], [H1, H2, H3], [theta1, theta2, theta3]
)
pubs = [(psi1, H1, theta1), (psi2, H2, theta2), (psi1, H3, theta3)]
job2 = estimator_qiskit.run(pubs=pubs)
job_result_qiskit = job2.result()
print(f"The qiskit-job finished with result {job_result_qiskit}")

vars = [job_result.metadata[i]["variance"] for i in range(3)]
stds = [sqrt(var / 4096) for var in vars]
for i in range(3):
assert job_result.values[i] == pytest.approx(
job_result_qiskit.values[i], rel=0.2, abs=stds[i] * 6
job_result_qiskit[i].data.evs, rel=0.2, abs=stds[i] * 6
)
vars = [job_result_approx.metadata[i]["variance"] for i in range(3)]
stds = [sqrt(var / 4096) for var in vars]
for i in range(3):
assert job_result_approx.values[i] == pytest.approx(
job_result_qiskit.values[i], rel=0.2, abs=stds[i] * 6
job_result_qiskit[i].data.evs, rel=0.2, abs=stds[i] * 6
)
for i in range(3):
assert job_result_exact.values[i] == pytest.approx(
job_result_qiskit[i].data.evs, rel=1e-6
)
assert job_result_exact.values == pytest.approx(job_result_qiskit.values, rel=1e-6)
Loading