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

[Testing] Reduce testing time of measurement protocols #638

Merged
merged 9 commits into from
Jan 6, 2025
65 changes: 16 additions & 49 deletions tests/qadence/test_measurements/test_shadows.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,14 +124,12 @@ def test_estimations_comparison_exact(
(QuantumCircuit(2, blocks), values2, DiffMode.GPSR),
],
)
@pytest.mark.parametrize("observable", [Z(0) ^ 2, X(1)])
def test_estimations_comparison_tomo_forward_pass(
circuit: QuantumCircuit,
values: dict,
diff_mode: DiffMode,
observable: AbstractBlock,
def test_estimations_shadow_forward_pass(
circuit: QuantumCircuit, values: dict, diff_mode: DiffMode
) -> None:
pyq_backend = backend_factory(BackendName.PYQTORCH, diff_mode=diff_mode)
# combine observables to avoid repeating measurements
observable = [Z(0) ^ 2, X(1)]
(conv_circ, conv_obs, embed, params) = pyq_backend.convert(circuit, observable)
pyq_exp_exact = pyq_backend.expectation(conv_circ, conv_obs, embed(params, values))
model = QuantumModel(
Expand All @@ -140,18 +138,11 @@ def test_estimations_comparison_tomo_forward_pass(
backend=BackendName.PYQTORCH,
diff_mode=DiffMode.GPSR,
)
options = {"n_shots": 100000}
estimated_exp_tomo = model.expectation(
values=values,
measurement=Measurements(protocol=Measurements.TOMOGRAPHY, options=options),
)
new_options = {"accuracy": 0.1, "confidence": 0.1}
options = {"accuracy": 0.1, "confidence": 0.1}
estimated_exp_shadow = model.expectation(
values=values,
measurement=Measurements(protocol=Measurements.SHADOW, options=new_options),
) # N = 54400.
assert torch.allclose(estimated_exp_tomo, pyq_exp_exact, atol=1.0e-2)
assert torch.allclose(estimated_exp_shadow, pyq_exp_exact, atol=0.1)
measurement=Measurements(protocol=Measurements.SHADOW, options=options),
)
assert torch.allclose(estimated_exp_shadow, pyq_exp_exact, atol=0.1)


Expand All @@ -161,17 +152,19 @@ def test_chemistry_hamiltonian_1() -> None:

circuit = load("./tests/test_files/chem_circ.json")
assert isinstance(circuit, QuantumCircuit)
hamiltonian = load("./tests/test_files/chem_ham.json")
assert isinstance(hamiltonian, AbstractBlock)
# combine observables to avoid repeating measurements
hamiltonians = [load("./tests/test_files/chem_ham.json"), ising_hamiltonian(circuit.n_qubits)]
for hamiltonian in hamiltonians:
assert isinstance(hamiltonian, AbstractBlock)
# Restrict shadow size for faster tests.
kwargs = {"accuracy": 0.1, "confidence": 0.1, "shadow_size": 1000}
param_values = {"theta_0": torch.tensor([1.0])}

model = QuantumModel(
circuit=circuit,
observable=hamiltonian,
observable=hamiltonians, # type: ignore[arg-type]
backend=BackendName.PYQTORCH,
diff_mode=DiffMode.GPSR,
diff_mode=DiffMode.AD,
)
chMoussa marked this conversation as resolved.
Show resolved Hide resolved
exact = model.expectation(values=param_values)
estim = model.expectation(
Expand All @@ -181,32 +174,6 @@ def test_chemistry_hamiltonian_1() -> None:
assert torch.allclose(estim, exact, atol=0.3)


@pytest.mark.flaky(max_runs=5)
def test_chemistry_hamiltonian_2() -> None:
from qadence import load

circuit = load("./tests/test_files/chem_circ.json")
assert isinstance(circuit, QuantumCircuit)
hamiltonian = ising_hamiltonian(2)
assert isinstance(hamiltonian, AbstractBlock)
# Restrict shadow size for faster tests.
kwargs = {"accuracy": 0.1, "confidence": 0.1, "shadow_size": 1000}
param_values = {"theta_0": torch.tensor([1.0])}

model = QuantumModel(
circuit=circuit,
observable=hamiltonian,
backend=BackendName.PYQTORCH,
diff_mode=DiffMode.GPSR,
)
exact = model.expectation(values=param_values)
estim = model.expectation(
values=param_values,
measurement=Measurements(protocol=Measurements.SHADOW, options=kwargs),
)
assert torch.allclose(estim, exact, atol=0.2)


def open_chem_obs() -> AbstractBlock:
directory = os.getcwd()
with open(os.path.join(directory, "tests/test_files/h4.json"), "r") as js:
Expand All @@ -215,18 +182,18 @@ def open_chem_obs() -> AbstractBlock:


@pytest.mark.flaky(max_runs=5)
def test_chemistry_hamiltonian_3() -> None:
def test_chemistry_hamiltonian_2() -> None:
circuit = QuantumCircuit(4, kron(Z(0), H(1), Z(2), X(3)))
hamiltonian = open_chem_obs()
param_values: dict = dict()

kwargs = {"accuracy": 0.1, "confidence": 0.1, "shadow_size": 5000}
kwargs = {"accuracy": 0.1, "confidence": 0.1, "shadow_size": 1000}

model = QuantumModel(
circuit=circuit,
observable=hamiltonian,
backend=BackendName.PYQTORCH,
diff_mode=DiffMode.GPSR,
diff_mode=DiffMode.AD,
)
exact = model.expectation(values=param_values)
estim = model.expectation(
Expand Down
32 changes: 17 additions & 15 deletions tests/qadence/test_measurements/test_tomography.py
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@ def test_basic_tomography_for_parametric_circuit_forward_pass(
"observable, acceptance",
[
(total_magnetization(4), MIDDLE_ACCEPTANCE),
(zz_hamiltonian(4), MIDDLE_ACCEPTANCE),
chMoussa marked this conversation as resolved.
Show resolved Hide resolved
# (zz_hamiltonian(4), MIDDLE_ACCEPTANCE), # skiping zz as it is very heavy
# (ising_hamiltonian(4), MIDDLE_ACCEPTANCE),
(
add(
Expand All @@ -482,7 +482,6 @@ def test_forward_and_backward_passes_with_qnn(observable: AbstractBlock, accepta
batch_size = 5
kwargs = {"n_shots": 1000000}

# fm = fourier_feature_map(n_qubits)
fm = feature_map(n_qubits, fm_type=BasisSet.CHEBYSHEV)
ansatz = hea(n_qubits, depth=2)
circuit = QuantumCircuit(n_qubits, fm, ansatz)
Expand Down Expand Up @@ -571,12 +570,13 @@ def test_partial_derivatives_with_qnn(observable: AbstractBlock, acceptance: flo
ones_like(dexpval_tomo_phi),
create_graph=True,
)[0]
d2expval_tomo_phi2theta = autograd.grad(
d2expval_tomo_phi2,
list(params.values()),
ones_like(d2expval_tomo_phi2),
create_graph=True,
)[0]
##### this derivative is very long, disabling for CI
# d2expval_tomo_phi2theta = autograd.grad(
# d2expval_tomo_phi2,
# list(params.values()),
# ones_like(d2expval_tomo_phi2),
# create_graph=True,
# )[0]
expectation_exact = model_with_psr.expectation(values=values)
dexpval_exact_phi = autograd.grad(
expectation_exact,
Expand All @@ -590,6 +590,7 @@ def test_partial_derivatives_with_qnn(observable: AbstractBlock, acceptance: flo
ones_like(expectation_exact),
create_graph=True,
)[0]

dexpval_exact_phitheta = autograd.grad(
dexpval_exact_phi,
list(params.values()),
Expand All @@ -602,18 +603,19 @@ def test_partial_derivatives_with_qnn(observable: AbstractBlock, acceptance: flo
ones_like(dexpval_exact_phi),
create_graph=True,
)[0]
d2expval_exact_phi2theta = autograd.grad(
d2expval_exact_phi2,
list(params.values()),
ones_like(d2expval_exact_phi2),
create_graph=True,
)[0]
##### this derivative is very long, disabling for CI
# d2expval_exact_phi2theta = autograd.grad(
# d2expval_exact_phi2,
# list(params.values()),
# ones_like(d2expval_exact_phi2),
# create_graph=True,
# )[0]
assert allclose(expectation_tomo, expectation_exact, atol=acceptance)
assert allclose(dexpval_tomo_phi, dexpval_exact_phi, atol=acceptance)
assert allclose(dexpval_tomo_theta, dexpval_exact_theta, atol=acceptance)
assert allclose(dexpval_tomo_phitheta, dexpval_exact_phitheta, atol=acceptance)
assert allclose(d2expval_tomo_phi2, d2expval_exact_phi2, atol=HIGH_ACCEPTANCE)
assert allclose(d2expval_tomo_phi2theta, d2expval_exact_phi2theta, atol=HIGH_ACCEPTANCE)
# assert allclose(d2expval_tomo_phi2theta, d2expval_exact_phi2theta, atol=HIGH_ACCEPTANCE)


@pytest.mark.skip(
Expand Down
Loading