From 2db991b1aaf167ff1816dee38811e23483de97a6 Mon Sep 17 00:00:00 2001 From: Mudit Pandey Date: Tue, 8 Oct 2024 16:04:08 -0400 Subject: [PATCH 1/3] Misc Tensor deprecation fixes --- .../data/attributes/operator/operator.py | 3 +- pennylane/qaoa/mixers.py | 7 +++- pennylane/tape/tape.py | 5 +-- .../data/attributes/operator/test_operator.py | 39 +++++++++++++++---- 4 files changed, 42 insertions(+), 12 deletions(-) diff --git a/pennylane/data/attributes/operator/operator.py b/pennylane/data/attributes/operator/operator.py index 5301654ab9d..9929c839d9f 100644 --- a/pennylane/data/attributes/operator/operator.py +++ b/pennylane/data/attributes/operator/operator.py @@ -262,7 +262,8 @@ def _hdf5_to_ops(self, bind: HDF5Group) -> list[Operator]: op_cls = self._supported_ops_dict()[op_class_name] if op_cls is Tensor: - ops.append(Tensor(*self._hdf5_to_ops(bind[op_key]))) + prod_op = qml.ops.Prod if qml.operation.active_new_opmath() else Tensor + ops.append(prod_op(*self._hdf5_to_ops(bind[op_key]))) elif op_cls in (qml.ops.Hamiltonian, qml.ops.LinearCombination): ops.append( qml.Hamiltonian( diff --git a/pennylane/qaoa/mixers.py b/pennylane/qaoa/mixers.py index 0e96c0da991..6c39bc17c9a 100644 --- a/pennylane/qaoa/mixers.py +++ b/pennylane/qaoa/mixers.py @@ -231,7 +231,12 @@ def bit_flip_mixer(graph: Union[nx.Graph, rx.PyGraph], b: int): ] n_coeffs = [[1, sign] for n in neighbours] - final_terms = [qml.operation.Tensor(*list(m)).prune() for m in itertools.product(*n_terms)] + prod_op = ( + (lambda ops: qml.prod(*ops).simplify()) + if qml.operation.active_new_opmath() + else (lambda ops: qml.operation.Tensor(*ops).prune) + ) + final_terms = [prod_op(list(m)) for m in itertools.product(*n_terms)] final_coeffs = [ (0.5**degree) * functools.reduce(lambda x, y: x * y, list(m), 1) for m in itertools.product(*n_coeffs) diff --git a/pennylane/tape/tape.py b/pennylane/tape/tape.py index 20c8e3bd9c1..414b93e26d3 100644 --- a/pennylane/tape/tape.py +++ b/pennylane/tape/tape.py @@ -78,10 +78,9 @@ def _validate_computational_basis_sampling(tape): with ( QueuingManager.stop_recording() ): # stop recording operations - the constructed operator is just aux + prod_op = qml.ops.Prod if qml.operation.active_new_opmath() else qml.operation.Tensor pauliz_for_cb_obs = ( - qml.Z(all_wires) - if len(all_wires) == 1 - else qml.operation.Tensor(*[qml.Z(w) for w in all_wires]) + qml.Z(all_wires) if len(all_wires) == 1 else prod_op(*[qml.Z(w) for w in all_wires]) ) for obs in non_comp_basis_sampling_obs: diff --git a/tests/data/attributes/operator/test_operator.py b/tests/data/attributes/operator/test_operator.py index 8079b720f89..007db8930c4 100644 --- a/tests/data/attributes/operator/test_operator.py +++ b/tests/data/attributes/operator/test_operator.py @@ -74,12 +74,13 @@ tensors = [Tensor(qml.PauliX(1), qml.PauliY(2))] +@pytest.mark.usefixtures("use_legacy_and_new_opmath") @pytest.mark.parametrize("attribute_cls", [DatasetOperator, DatasetPyTree]) @pytest.mark.parametrize("obs_in", [*hermitian_ops, *pauli_ops, *identity, *hamiltonians, *tensors]) class TestDatasetOperatorObservable: """Tests serializing Observable operators using the ``compare()`` method.""" - def test_value_init(self, attribute_cls, obs_in): + def test_value_init(self, attribute_cls, obs_in, recwarn): """Test that a DatasetOperator can be value-initialized from an observable, and that the deserialized operator is equivalent.""" @@ -92,10 +93,22 @@ def test_value_init(self, attribute_cls, obs_in): assert dset_op.info["py_type"] == get_type_str(type(obs_in)) obs_out = dset_op.get_value() - qml.assert_equal(obs_out, obs_in) - assert obs_in.compare(obs_out) - - def test_bind_init(self, attribute_cls, obs_in): + if ( + qml.operation.active_new_opmath() + and isinstance(obs_in, Tensor) + and attribute_cls is DatasetOperator + ): + assert isinstance(obs_out, qml.ops.Prod) + for o1, o2 in zip(obs_in.obs, obs_out.operands): + qml.assert_equal(o1, o2) + + # No Tensor deprecation warnings are raised + assert len(recwarn) == 0 + else: + qml.assert_equal(obs_out, obs_in) + assert obs_in.compare(obs_out) + + def test_bind_init(self, attribute_cls, obs_in, recwarn): """Test that DatasetOperator can be initialized from a HDF5 group that contains a operator attribute.""" if not qml.operation.active_new_opmath() and isinstance(obs_in, qml.ops.LinearCombination): @@ -109,8 +122,20 @@ def test_bind_init(self, attribute_cls, obs_in): assert dset_op.info["py_type"] == get_type_str(type(obs_in)) obs_out = dset_op.get_value() - qml.assert_equal(obs_out, obs_in) - assert obs_in.compare(obs_out) + if ( + qml.operation.active_new_opmath() + and isinstance(obs_in, Tensor) + and attribute_cls is DatasetOperator + ): + assert isinstance(obs_out, qml.ops.Prod) + for o1, o2 in zip(obs_in.obs, obs_out.operands): + qml.assert_equal(o1, o2) + + # No Tensor deprecation warnings are raised + assert len(recwarn) == 0 + else: + qml.assert_equal(obs_out, obs_in) + assert obs_in.compare(obs_out) @pytest.mark.parametrize("attribute_cls", [DatasetOperator, DatasetPyTree]) From 7f2c4182cb1d71403f72e33ca9894deff823b9ff Mon Sep 17 00:00:00 2001 From: Mudit Pandey Date: Tue, 8 Oct 2024 16:07:10 -0400 Subject: [PATCH 2/3] Update changelog --- doc/releases/changelog-dev.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/releases/changelog-dev.md b/doc/releases/changelog-dev.md index fa06a4721a6..0a97c592d2f 100644 --- a/doc/releases/changelog-dev.md +++ b/doc/releases/changelog-dev.md @@ -176,6 +176,7 @@ `qml.ops.LinearCombination`; this behaviour is not deprecated. For more information, check out the [updated operator troubleshooting page](https://docs.pennylane.ai/en/stable/news/new_opmath.html). [(#6287)](https://github.com/PennyLaneAI/pennylane/pull/6287) + [(#6365)](https://github.com/PennyLaneAI/pennylane/pull/6365) * `qml.pauli.PauliSentence.hamiltonian` and `qml.pauli.PauliWord.hamiltonian` are deprecated. Instead, please use `qml.pauli.PauliSentence.operation` and `qml.pauli.PauliWord.operation` respectively. From baf27ab8c902ea5040ab019825135a5bc7a9994f Mon Sep 17 00:00:00 2001 From: Mudit Pandey Date: Tue, 8 Oct 2024 16:59:04 -0400 Subject: [PATCH 3/3] Fix minor failure --- pennylane/qaoa/mixers.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pennylane/qaoa/mixers.py b/pennylane/qaoa/mixers.py index 6c39bc17c9a..76dffccaf29 100644 --- a/pennylane/qaoa/mixers.py +++ b/pennylane/qaoa/mixers.py @@ -229,14 +229,14 @@ def bit_flip_mixer(graph: Union[nx.Graph, rx.PyGraph], b: int): n_terms = [[qml.X(get_nvalue(i))]] + [ [qml.Identity(get_nvalue(n)), qml.Z(get_nvalue(n))] for n in neighbours ] - n_coeffs = [[1, sign] for n in neighbours] + n_coeffs = [[1, sign] for _ in neighbours] - prod_op = ( - (lambda ops: qml.prod(*ops).simplify()) + final_terms = ( + [qml.prod(*list(m)).simplify() for m in itertools.product(*n_terms)] if qml.operation.active_new_opmath() - else (lambda ops: qml.operation.Tensor(*ops).prune) + else [qml.operation.Tensor(*list(m)).prune() for m in itertools.product(*n_terms)] ) - final_terms = [prod_op(list(m)) for m in itertools.product(*n_terms)] + final_coeffs = [ (0.5**degree) * functools.reduce(lambda x, y: x * y, list(m), 1) for m in itertools.product(*n_coeffs)