Skip to content

Commit

Permalink
cherry-pick minor bugfixes from master (#4807)
Browse files Browse the repository at this point in the history
**Context:**
These three bugs were identified as good to be released in a bugfix.

**Description of the Change:**
Cherry-pick the 3 commits to master onto this branch for the 0.33.1
bugfix release

**Benefits:**
Fixed bugs pushed out!

**Possible Drawbacks:**
Extra work in a critical time.

**Related GitHub Issues:**
#4768, #4781, #4787

---------

Co-authored-by: Christina Lee <[email protected]>
Co-authored-by: lillian542 <[email protected]>
Co-authored-by: Tom Bromley <[email protected]>
Co-authored-by: Mudit Pandey <[email protected]>
  • Loading branch information
5 people authored Nov 8, 2023
1 parent bb0fa9f commit 98ea7eb
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 4 deletions.
15 changes: 15 additions & 0 deletions doc/releases/changelog-0.33.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,21 @@

<h3>Bug fixes 🐛</h3>

* `qml.defer_measurements` now correctly transforms circuits when terminal measurements include wires
used in mid-circuit measurements.
[(#4787)](https://github.com/PennyLaneAI/pennylane/pull/4787)

* Any `ScalarSymbolicOp`, like `Evolution`, now states that it has a matrix if the target
is a `Hamiltonian`.
[(#4768)](https://github.com/PennyLaneAI/pennylane/pull/4768)

* In `default.qubit`, initial states are now initialized with the simulator's wire order, not the circuit's
wire order.
[(#4781)](https://github.com/PennyLaneAI/pennylane/pull/4781)

<h3>Contributors ✍️</h3>

This release contains contributions from (in alphabetical order):

Christina Lee,
Mudit Pandey
2 changes: 1 addition & 1 deletion pennylane/devices/qubit/simulate.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ def get_final_state(circuit, debugger=None, interface=None):
if len(circuit) > 0 and isinstance(circuit[0], qml.operation.StatePrepBase):
prep = circuit[0]

state = create_initial_state(circuit.op_wires, prep, like=INTERFACE_TO_LIKE[interface])
state = create_initial_state(sorted(circuit.op_wires), prep, like=INTERFACE_TO_LIKE[interface])

# initial state is batched only if the state preparation (if it exists) is batched
is_state_batched = bool(prep and prep.batch_size is not None)
Expand Down
4 changes: 4 additions & 0 deletions pennylane/ops/op_math/symbolicop.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,10 @@ def _check_and_compute_batch_size(self, scalar):
)
return scalar_size

@property
def has_matrix(self):
return self.base.has_matrix or isinstance(self.base, qml.Hamiltonian)

@property
def hash(self):
return hash(
Expand Down
2 changes: 1 addition & 1 deletion pennylane/transforms/defer_measurements.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def _collect_mid_measure_info(tape: QuantumTape):
any_repeated_measurements = False
is_postselecting = False

for op in tape.operations:
for op in tape:
if isinstance(op, MidMeasureMP):
if op.postselect is not None:
is_postselecting = True
Expand Down
11 changes: 11 additions & 0 deletions tests/devices/default_qubit/test_default_qubit.py
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,17 @@ def circuit(p):
assert qml.math.get_interface(res) == "tensorflow"
assert qml.math.allclose(res, -1)

def test_basis_state_wire_order(self):
"""Test that the wire order is correct with a basis state if the tape wires have a non standard order."""

dev = DefaultQubit()

tape = qml.tape.QuantumScript([qml.BasisState([1], wires=1), qml.PauliZ(0)], [qml.state()])

expected = np.array([0, 1, 0, 0], dtype=np.complex128)
res = dev.execute(tape)
assert qml.math.allclose(res, expected)


class TestSampleMeasurements:
"""A copy of the `qubit.simulate` tests, but using the device"""
Expand Down
7 changes: 7 additions & 0 deletions tests/ops/op_math/test_symbolic_op.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,13 @@ class DummyOp(Operator):
op = SymbolicOp(base)
assert op.has_matrix == has_mat

def test_has_matrix_hamiltonian(self):
"""Test that it has a matrix if the base is a hamiltonian."""

H = qml.Hamiltonian([1.0], [qml.PauliX(0)])
op = TempScalar(H, 2)
assert op.has_matrix

@pytest.mark.parametrize("is_herm", (True, False))
def test_is_hermitian(self, is_herm):
"""Test that symbolic op is hermitian if the base is hermitian."""
Expand Down
23 changes: 21 additions & 2 deletions tests/transforms/test_defer_measurements.py
Original file line number Diff line number Diff line change
Expand Up @@ -1348,6 +1348,25 @@ def qnode2(x):
for actual, expected in zip(qnode2.qtape.circuit, expected_circuit)
)

def test_measurements_add_new_qubits(self):
"""Test that qubit reuse related logic is applied if a wire with mid-circuit
measurements is included in terminal measurements."""
tape = qml.tape.QuantumScript(
ops=[qml.Hadamard(0), MidMeasureMP(0)], measurements=[qml.density_matrix(wires=[0])]
)
expected = np.eye(2) / 2

tapes, _ = qml.defer_measurements(tape)

dev = qml.device("default.qubit")
res = qml.execute(tapes, dev)

assert np.allclose(res, expected)

deferred_tape = tapes[0]
assert deferred_tape.operations == [qml.Hadamard(0), qml.CNOT([0, 1])]
assert deferred_tape.measurements == [qml.density_matrix(wires=[0])]

def test_wire_is_reset(self):
"""Test that a wire is reset to the |0> state without any local phases
after measurement if reset is requested."""
Expand Down Expand Up @@ -1484,7 +1503,7 @@ def test_custom_wire_labels_allowed_without_reset():
qml.Hadamard("a")
ma = qml.measure("a", reset=False)
qml.cond(ma, qml.PauliX)("b")
qml.probs(wires="a")
qml.probs(wires="b")

tape = qml.tape.QuantumScript.from_queue(q)
tapes, _ = qml.defer_measurements(tape)
Expand All @@ -1493,7 +1512,7 @@ def test_custom_wire_labels_allowed_without_reset():
assert len(tape) == 3
assert qml.equal(tape[0], qml.Hadamard("a"))
assert qml.equal(tape[1], qml.CNOT(["a", "b"]))
assert qml.equal(tape[2], qml.probs(wires="a"))
assert qml.equal(tape[2], qml.probs(wires="b"))


def test_custom_wire_labels_fails_with_reset():
Expand Down

0 comments on commit 98ea7eb

Please sign in to comment.