Skip to content

Commit

Permalink
Provide a workaround to #422, Sampler failing when no measurements (#426
Browse files Browse the repository at this point in the history
)

* Provide a workaround to #422, Sampler failing when no measurements

* Add test for workaround to Issue #422.

* Redo previous commit after running tox.

* Fix tox error from previous build.

* Fix tox error from last build.

* Un-modify the metadata in a notebook

With this, the current PR will touch one fewer file

* Update test/cutting/test_cutting_roundtrip.py

Co-authored-by: Jim Garrison <[email protected]>

* Update test/cutting/test_cutting_roundtrip.py

Co-authored-by: Jim Garrison <[email protected]>

* black

---------

Co-authored-by: Ibrahim <[email protected]>
Co-authored-by: Ibrahim Shehzad <[email protected]>
  • Loading branch information
3 people authored Oct 10, 2023
1 parent 3e85b57 commit f596307
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 2 deletions.
11 changes: 9 additions & 2 deletions circuit_knitting/cutting/cutting_experiments.py
Original file line number Diff line number Diff line change
Expand Up @@ -276,14 +276,21 @@ def _append_measurement_circuit(
if not inplace:
qc = qc.copy()

# If the circuit has no measurements, the Sampler will fail. So, we
# measure one qubit as a temporary workaround to
# https://github.com/Qiskit-Extensions/circuit-knitting-toolbox/issues/422
pauli_indices = cog.pauli_indices
if not pauli_indices:
pauli_indices = [0]

# Append the appropriate measurements to qc
obs_creg = ClassicalRegister(len(cog.pauli_indices), name="observable_measurements")
obs_creg = ClassicalRegister(len(pauli_indices), name="observable_measurements")
qc.add_register(obs_creg)
# Implement the necessary basis rotations and measurements, as
# in BackendEstimator._measurement_circuit().
genobs_x = cog.general_observable.x
genobs_z = cog.general_observable.z
for clbit, subqubit in enumerate(cog.pauli_indices):
for clbit, subqubit in enumerate(pauli_indices):
# subqubit is the index of the qubit in the subsystem.
# actual_qubit is its index in the system of interest (if different).
actual_qubit = qubit_locations[subqubit]
Expand Down
28 changes: 28 additions & 0 deletions test/cutting/test_cutting_roundtrip.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
from qiskit.extensions import UnitaryGate
from qiskit.quantum_info import PauliList, random_unitary
from qiskit.primitives import Estimator
from qiskit_aer.primitives import Sampler

from circuit_knitting.utils.simulation import ExactSampler
from circuit_knitting.cutting import (
Expand Down Expand Up @@ -179,3 +180,30 @@ def test_cutting_exact_reconstruction(example_circuit):
logger.info("Max error: %f", np.max(np.abs(exact_expvals - simulated_expvals)))

assert np.allclose(exact_expvals, simulated_expvals, atol=1e-8)


def test_sampler_with_identity_subobservable(example_circuit):
"""This test ensures that the sampler does not throw an error if you pass it a subcircuit with no observable measurements.
Tests temporary workaround to Issue #422.
This test passes if no exceptions are raised.
"""

qc = example_circuit
observable_to_test = PauliList(
["IIZ"]
) # Without the workaround to Issue #422, this observable causes a Sampler error.
subcircuits, bases, subobservables = partition_problem(
qc, "AAB", observables=observable_to_test
)
subexperiments, coefficients = generate_cutting_experiments(
subcircuits, subobservables, num_samples=np.inf
)
samplers = {label: Sampler() for label in subexperiments.keys()}
results = {
label: sampler.run(subexperiments[label]).result()
for label, sampler in samplers.items()
}
_ = results

0 comments on commit f596307

Please sign in to comment.