From c63728feecec6e767e89cec67cda6278013763c9 Mon Sep 17 00:00:00 2001 From: Jim Garrison Date: Wed, 17 Jul 2024 15:45:01 -0400 Subject: [PATCH 1/3] Migrate to `EstimatorV2` in tests Partially addresses #506. --- test/cutting/test_cutting_roundtrip.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/test/cutting/test_cutting_roundtrip.py b/test/cutting/test_cutting_roundtrip.py index d1f5b638d..79e2a1a21 100644 --- a/test/cutting/test_cutting_roundtrip.py +++ b/test/cutting/test_cutting_roundtrip.py @@ -41,10 +41,10 @@ DCXGate, ) from qiskit.quantum_info import PauliList, random_unitary -from qiskit.primitives import Estimator +from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager from qiskit_ibm_runtime import SamplerV2 from qiskit_aer import AerSimulator -from qiskit_aer.primitives import Sampler +from qiskit_aer.primitives import Sampler, EstimatorV2 from circuit_knitting.utils.simulation import ExactSampler from circuit_knitting.cutting import ( @@ -138,13 +138,14 @@ def test_cutting_exact_reconstruction(example_circuit): """Test gate-cut circuit vs original circuit on statevector simulator""" qc = example_circuit - observables = PauliList(["III", "IIY", "XII", "XYZ", "iZZZ", "-XZI"]) + observables = PauliList(["III", "IIY", "XII", "XYZ", "ZZZ", "-XZI"]) phases = np.array([(-1j) ** obs.phase for obs in observables]) observables_nophase = PauliList(["III", "IIY", "XII", "XYZ", "ZZZ", "XZI"]) - estimator = Estimator() + estimator = EstimatorV2() + pm = generate_preset_pass_manager(optimization_level=1, basis_gates=["u", "cz"]) exact_expvals = ( - estimator.run([qc] * len(observables), list(observables)).result().values + estimator.run([(pm.run(qc), list(observables))]).result()[0].data.evs ) subcircuits, bases, subobservables = partition_problem( qc, "AAB", observables=observables_nophase @@ -216,9 +217,9 @@ def test_sampler_with_identity_subobservable(sampler, is_exact_sampler): if is_exact_sampler: # Determine exact expectation values - estimator = Estimator() + estimator = EstimatorV2() exact_expvals = ( - estimator.run([qc] * len(observables), list(observables)).result().values + estimator.run([(qc, list(observables))]).result()[0].data.evs ) logger.info( From 9e00b70d88c90454286a71052832f00e0c853052 Mon Sep 17 00:00:00 2001 From: Jim Garrison Date: Wed, 17 Jul 2024 17:19:20 -0400 Subject: [PATCH 2/3] black --- test/cutting/test_cutting_roundtrip.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/cutting/test_cutting_roundtrip.py b/test/cutting/test_cutting_roundtrip.py index 79e2a1a21..e01029273 100644 --- a/test/cutting/test_cutting_roundtrip.py +++ b/test/cutting/test_cutting_roundtrip.py @@ -218,9 +218,7 @@ def test_sampler_with_identity_subobservable(sampler, is_exact_sampler): if is_exact_sampler: # Determine exact expectation values estimator = EstimatorV2() - exact_expvals = ( - estimator.run([(qc, list(observables))]).result()[0].data.evs - ) + exact_expvals = estimator.run([(qc, list(observables))]).result()[0].data.evs logger.info( "Max error: %f", np.max(np.abs(exact_expvals - reconstructed_expvals)) From e8dd3405dfcc2b742b72e87dec08f71cecb30e1f Mon Sep 17 00:00:00 2001 From: Jim Garrison Date: Thu, 18 Jul 2024 13:07:37 -0400 Subject: [PATCH 3/3] Replace `observables` with `observables_nophase` The previous code passed `observables_nophase` to the cutting code, so it wasn't even testing the phases through the workflow. The correct way to handle such observables with nontrivial phase is to use the utility introduced in #587. --- test/cutting/test_cutting_roundtrip.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/test/cutting/test_cutting_roundtrip.py b/test/cutting/test_cutting_roundtrip.py index e01029273..43999c199 100644 --- a/test/cutting/test_cutting_roundtrip.py +++ b/test/cutting/test_cutting_roundtrip.py @@ -138,9 +138,7 @@ def test_cutting_exact_reconstruction(example_circuit): """Test gate-cut circuit vs original circuit on statevector simulator""" qc = example_circuit - observables = PauliList(["III", "IIY", "XII", "XYZ", "ZZZ", "-XZI"]) - phases = np.array([(-1j) ** obs.phase for obs in observables]) - observables_nophase = PauliList(["III", "IIY", "XII", "XYZ", "ZZZ", "XZI"]) + observables = PauliList(["III", "IIY", "XII", "XYZ", "ZZZ", "XZI"]) estimator = EstimatorV2() pm = generate_preset_pass_manager(optimization_level=1, basis_gates=["u", "cz"]) @@ -148,7 +146,7 @@ def test_cutting_exact_reconstruction(example_circuit): estimator.run([(pm.run(qc), list(observables))]).result()[0].data.evs ) subcircuits, bases, subobservables = partition_problem( - qc, "AAB", observables=observables_nophase + qc, "AAB", observables=observables ) subexperiments, coefficients = generate_cutting_experiments( subcircuits, subobservables, num_samples=np.inf @@ -167,7 +165,6 @@ def test_cutting_exact_reconstruction(example_circuit): reconstructed_expvals = reconstruct_expectation_values( results, coefficients, subobservables ) - reconstructed_expvals *= phases logger.info("Max error: %f", np.max(np.abs(exact_expvals - reconstructed_expvals)))