From 465d33782dc46b53b52be4b45123e1adcaaded04 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 3 May 2024 10:34:28 -0400 Subject: [PATCH] Daily rc sync to master (#5635) Automatic sync from the release candidate to master during a feature freeze. --------- Co-authored-by: Mudit Pandey Co-authored-by: Astral Cai Co-authored-by: Vincent Michaud-Rioux Co-authored-by: David Wierichs Co-authored-by: lillian542 <38584660+lillian542@users.noreply.github.com> Co-authored-by: Pietropaolo Frisoni Co-authored-by: Christina Lee Co-authored-by: GitHub Actions Bot <> --- doc/introduction/compiling_circuits.rst | 2 +- doc/introduction/inspecting_circuits.rst | 2 +- doc/releases/changelog-0.36.0.md | 8 +++++++ pennylane/devices/device_api.py | 18 +++++++++++++++ pennylane/devices/preprocess.py | 17 ++++++-------- pennylane/math/fidelity.py | 9 ++++++++ pennylane/ops/functions/dot.py | 9 +++++++- pennylane/ops/op_math/composite.py | 5 +++++ pennylane/ops/op_math/linear_combination.py | 4 ++++ pennylane/pauli/dla/lie_closure.py | 22 +++++++++++-------- pennylane/pauli/dla/structure_constants.py | 2 +- pennylane/qaoa/cycle.py | 2 +- .../test_default_qubit_preprocessing.py | 2 +- tests/devices/experimental/test_device_api.py | 13 ++++++++++- tests/devices/test_default_mixed_jax.py | 11 +++++----- tests/devices/test_default_qutrit_mixed.py | 4 ++-- tests/devices/test_preprocess.py | 11 +++++++++- tests/gradients/core/test_metric_tensor.py | 4 ++-- .../test_jax_default_qubit_2.py | 3 +-- .../test_jax_jit_qnode_default_qubit_2.py | 3 +-- .../test_jax_qnode_default_qubit_2.py | 3 +-- tests/interfaces/test_jax_jit_qnode.py | 3 +-- tests/interfaces/test_jax_qnode.py | 3 +-- .../interfaces/test_jax_qnode_shot_vector.py | 3 +-- tests/ops/functions/conftest.py | 6 +---- tests/ops/functions/test_dot.py | 19 ++++++++++++++++ tests/ops/op_math/test_linear_combination.py | 6 +++++ tests/ops/op_math/test_prod.py | 2 -- 28 files changed, 140 insertions(+), 56 deletions(-) diff --git a/doc/introduction/compiling_circuits.rst b/doc/introduction/compiling_circuits.rst index 6bcf46292f3..5215e3f7ad4 100644 --- a/doc/introduction/compiling_circuits.rst +++ b/doc/introduction/compiling_circuits.rst @@ -44,7 +44,7 @@ RX(11.336370614359172, wires=[0]) >>> qml.simplify(qml.ops.Pow(qml.RX(1, 0), 3)) RX(3.0, wires=[0]) >>> qml.simplify(qml.sum(qml.Y(3), qml.Y(3))) -2 * Y(3) +2.0 * Y(3) >>> qml.simplify(qml.RX(1, 0) @ qml.RX(1, 0)) RX(2.0, wires=[0]) >>> qml.simplify(qml.prod(qml.X(0), qml.Z(0))) diff --git a/doc/introduction/inspecting_circuits.rst b/doc/introduction/inspecting_circuits.rst index 71c8373bba8..813cfb4c6ff 100644 --- a/doc/introduction/inspecting_circuits.rst +++ b/doc/introduction/inspecting_circuits.rst @@ -210,7 +210,7 @@ or to check whether two gates causally influence each other. Internally, the :class:`~pennylane.CircuitGraph` class constructs a ``rustworkx`` graph object. >>> type(g.graph) - +rustworkx.PyDiGraph There is no edge between the ``Hadamard`` and the first ``CNOT``, but between consecutive ``CNOT`` gates: diff --git a/doc/releases/changelog-0.36.0.md b/doc/releases/changelog-0.36.0.md index 93a68f89887..de7721e0040 100644 --- a/doc/releases/changelog-0.36.0.md +++ b/doc/releases/changelog-0.36.0.md @@ -551,6 +551,10 @@

Bug fixes 🐛

+* Improves the error message for setting shots on the new device interface, or trying to access a property + that no longer exists. + [(#5616)](https://github.com/PennyLaneAI/pennylane/pull/5616) + * Fixed a bug where `qml.draw` and `qml.draw_mpl` incorrectly raised errors for circuits collecting statistics on mid-circuit measurements while using `qml.defer_measurements`. [(#5610)](https://github.com/PennyLaneAI/pennylane/pull/5610) @@ -677,6 +681,10 @@ * `qml.equal` can now be used with sums and products that contain operators on no wires like `I` and `GlobalPhase`. [(#5562)](https://github.com/PennyLaneAI/pennylane/pull/5562) +* `CompositeOp.has_diagonalizing_gates` now does a more complete check of the base operators to ensure consistency + between `op.has_diagonalzing_gates` and `op.diagonalizing_gates()` + [(#5603)](https://github.com/PennyLaneAI/pennylane/pull/5603) +

Contributors ✍️

This release contains contributions from (in alphabetical order): diff --git a/pennylane/devices/device_api.py b/pennylane/devices/device_api.py index d1f0b8d502c..b472973d369 100644 --- a/pennylane/devices/device_api.py +++ b/pennylane/devices/device_api.py @@ -176,6 +176,14 @@ def __repr__(self): details = f"({', '.join(details)}) " if details else "" return f"<{self.name} device {details}at {hex(id(self))}>" + def __getattr__(self, key): + raise AttributeError( + f"{type(self).__name__} has no attribute '{key}'." + " You may be looking for a property or method present in the legacy device interface." + f" Please consult the {type(self).__name__} documentation for an updated list of public" + " properties and methods." + ) + @property def shots(self) -> Shots: """Default shots for execution workflows containing this device. @@ -186,6 +194,16 @@ def shots(self) -> Shots: """ return self._shots + @shots.setter + def shots(self, _): + raise AttributeError( + ( + "Shots can no longer be set on a device instance. " + "You can set shots on a call to a QNode, on individual tapes, or " + "create a new device instance instead." + ) + ) + @property def wires(self) -> Wires: """The device wires. diff --git a/pennylane/devices/preprocess.py b/pennylane/devices/preprocess.py index 7690903f0c4..2c821306acf 100644 --- a/pennylane/devices/preprocess.py +++ b/pennylane/devices/preprocess.py @@ -23,7 +23,7 @@ import pennylane as qml from pennylane import DeviceError, Snapshot, transform -from pennylane.measurements import MeasurementProcess, SampleMeasurement, StateMeasurement +from pennylane.measurements import SampleMeasurement, StateMeasurement from pennylane.operation import StatePrepBase, Tensor from pennylane.typing import Result, ResultBatch from pennylane.wires import WireError @@ -230,16 +230,13 @@ def validate_adjoint_trainable_params( "Differentiating with respect to the input parameters of state-prep operations " "is not supported with the adjoint differentiation method." ) - for k in tape.trainable_params: - mp_or_op = tape[tape._par_info[k]["op_idx"]] - if isinstance(mp_or_op, MeasurementProcess): + for m in tape.measurements: + if m.obs and qml.operation.is_trainable(m.obs): warnings.warn( - "Differentiating with respect to the input parameters of " - f"{mp_or_op.obs.name} is not supported with the " - "adjoint differentiation method. Gradients are computed " - "only with regards to the trainable parameters of the circuit.\n\n Mark " - "the parameters of the measured observables as non-trainable " - "to silence this warning.", + f"Differentiating with respect to the input parameters of {m.obs.name} " + "is not supported with the adjoint differentiation method. Gradients are computed " + "only with regards to the trainable parameters of the circuit.\n\n Mark the " + "parameters of the measured observables as non-trainable to silence this warning.", UserWarning, ) return (tape,), null_postprocessing diff --git a/pennylane/math/fidelity.py b/pennylane/math/fidelity.py index d8d6643f305..b338fd14c54 100644 --- a/pennylane/math/fidelity.py +++ b/pennylane/math/fidelity.py @@ -150,6 +150,15 @@ def fidelity(state0, state1, check_state=False, c_dtype="complex128"): if qml.math.shape(state0)[-1] != qml.math.shape(state1)[-1]: raise qml.QuantumFunctionError("The two states must have the same number of wires.") + batch_size0 = qml.math.shape(state0)[0] if qml.math.ndim(state0) > 2 else None + batch_size1 = qml.math.shape(state1)[0] if qml.math.ndim(state1) > 2 else None + + if qml.math.get_interface(state0) == "jax" or qml.math.get_interface(state1) == "jax": + if batch_size0 and not batch_size1: + state1 = qml.math.broadcast_to(state1, (batch_size0, *qml.math.shape(state1))) + elif not batch_size0 and batch_size1: + state0 = qml.math.broadcast_to(state0, (batch_size1, *qml.math.shape(state0))) + # Two mixed states _register_vjp(state0, state1) fid = qml.math.compute_fidelity(state0, state1) diff --git a/pennylane/ops/functions/dot.py b/pennylane/ops/functions/dot.py index 6fe52d38760..727aa9a0927 100644 --- a/pennylane/ops/functions/dot.py +++ b/pennylane/ops/functions/dot.py @@ -39,7 +39,8 @@ def dot( Args: coeffs (Sequence[float, Callable]): sequence containing the coefficients of the linear combination - ops (Sequence[Operator]): sequence containing the operators of the linear combination + ops (Sequence[Operator, PauliWord, PauliSentence]): sequence containing the operators of the linear combination. + Can also be ``PauliWord`` or ``PauliSentence`` instances. pauli (bool, optional): If ``True``, a :class:`~.PauliSentence` operator is used to represent the linear combination. If False, a :class:`Sum` operator is returned. Defaults to ``False``. Note that when ``ops`` consists solely of ``PauliWord`` @@ -136,6 +137,12 @@ def dot( if len(coeffs) == 0 and len(ops) == 0: raise ValueError("Cannot compute the dot product of an empty sequence.") + for t in (Operator, PauliWord, PauliSentence): + if isinstance(ops, t): + raise ValueError( + f"ops must be an Iterable of {t.__name__}'s, not a {t.__name__} itself." + ) + if any(callable(c) for c in coeffs): return ParametrizedHamiltonian(coeffs, ops) diff --git a/pennylane/ops/op_math/composite.py b/pennylane/ops/op_math/composite.py index f3ba3c43cfe..400535c4bd7 100644 --- a/pennylane/ops/op_math/composite.py +++ b/pennylane/ops/op_math/composite.py @@ -233,6 +233,11 @@ def eigendecomposition(self): @property def has_diagonalizing_gates(self): if self.has_overlapping_wires: + for ops in self.overlapping_ops: + # if any of the single ops doesn't have diagonalizing gates, the overall operator doesn't either + if len(ops) == 1 and not ops[0].has_diagonalizing_gates: + return False + # the lists of ops with multiple operators can be handled if there is a matrix return self.has_matrix return all(op.has_diagonalizing_gates for op in self) diff --git a/pennylane/ops/op_math/linear_combination.py b/pennylane/ops/op_math/linear_combination.py index 7b67cc4d1dc..cde0c5cd83e 100644 --- a/pennylane/ops/op_math/linear_combination.py +++ b/pennylane/ops/op_math/linear_combination.py @@ -118,6 +118,10 @@ def __init__( _pauli_rep=None, id=None, ): + if isinstance(observables, Operator): + raise ValueError( + "observables must be an Iterable of Operator's, and not an Operator itself." + ) if qml.math.shape(coeffs)[0] != len(observables): raise ValueError( "Could not create valid LinearCombination; " diff --git a/pennylane/pauli/dla/lie_closure.py b/pennylane/pauli/dla/lie_closure.py index 336a507b834..e109c50d377 100644 --- a/pennylane/pauli/dla/lie_closure.py +++ b/pennylane/pauli/dla/lie_closure.py @@ -63,9 +63,9 @@ def lie_closure( A first round of commutators between all elements yields: >>> qml.commutator(X(0) @ X(1), Z(0)) - -2j * (X(1) @ Y(0)) + -2j * (Y(0) @ X(1)) >>> qml.commutator(X(0) @ X(1), Z(1)) - -2j * (Y(1) @ X(0)) + -2j * (X(0) @ Y(1)) A next round of commutators between all elements further yields the new operator ``Y(0) @ Y(1)``. @@ -81,9 +81,9 @@ def lie_closure( [X(1) @ X(0), Z(0), Z(1), - -1.0 * (X(1) @ Y(0)), - -1.0 * (Y(1) @ X(0)), - -1.0 * (Y(1) @ Y(0))] + -1.0 * (Y(0) @ X(1)), + -1.0 * (X(0) @ Y(1)), + -1.0 * (Y(0) @ Y(1))] Note that we normalize by removing the factors of :math:`2i`, though minus signs are left intact. @@ -305,10 +305,14 @@ def add(self, other, tol=1e-15): for ps in other: # TODO: Potential speed-up by computing the maximal linear independent set for all current basis vectors + other, essentially algorithm1 in https://arxiv.org/abs/1012.5256 - self._M, self._pw_to_idx, self._rank, self._num_pw, is_independent = ( - self._check_independence( - self._M, ps, self._pw_to_idx, self._rank, self._num_pw, tol - ) + ( + self._M, + self._pw_to_idx, + self._rank, + self._num_pw, + is_independent, + ) = self._check_independence( + self._M, ps, self._pw_to_idx, self._rank, self._num_pw, tol ) if is_independent: self._basis.append(ps) diff --git a/pennylane/pauli/dla/structure_constants.py b/pennylane/pauli/dla/structure_constants.py index c6c2b16762e..c32295f9e59 100644 --- a/pennylane/pauli/dla/structure_constants.py +++ b/pennylane/pauli/dla/structure_constants.py @@ -75,7 +75,7 @@ def structure_constants( >>> gens += [Z(i) for i in range(n)] >>> dla = qml.lie_closure(gens) >>> print(dla) - [X(1) @ X(0), Z(0), Z(1), -1.0 * (X(1) @ Y(0)), -1.0 * (Y(1) @ X(0)), -1.0 * (Y(1) @ Y(0))] + [X(0) @ X(1), Z(0), Z(1), -1.0 * (Y(0) @ X(1)), -1.0 * (X(0) @ Y(1)), -1.0 * (Y(0) @ Y(1))] The dimension of the DLA is :math:`d = 6`. Hence, the structure constants have shape ``(6, 6, 6)``. diff --git a/pennylane/qaoa/cycle.py b/pennylane/qaoa/cycle.py index ab3c854ed09..1fef9d74977 100644 --- a/pennylane/qaoa/cycle.py +++ b/pennylane/qaoa/cycle.py @@ -347,7 +347,7 @@ def loss_hamiltonian(graph: Union[nx.Graph, rx.PyGraph, rx.PyDiGraph]) -> qml.op ) >>> import rustworkx as rx - >>> g = rx.generators.directed_mesh_graph(3) + >>> g = rx.generators.directed_mesh_graph(3, [0, 1, 2]) >>> edge_weight_data = {edge: (i + 1) * 0.5 for i, edge in enumerate(sorted(g.edge_list()))} >>> for k, v in edge_weight_data.items(): g.update_edge(k[0], k[1], {"weight": v}) diff --git a/tests/devices/default_qubit/test_default_qubit_preprocessing.py b/tests/devices/default_qubit/test_default_qubit_preprocessing.py index bab71975006..ac5e80d2b95 100644 --- a/tests/devices/default_qubit/test_default_qubit_preprocessing.py +++ b/tests/devices/default_qubit/test_default_qubit_preprocessing.py @@ -833,7 +833,7 @@ def test_trainable_hermitian_warns(self): expectation value of a Hermitian operator emits a warning if the parameters to Hermitian are trainable.""" - mx = qml.matrix(qml.PauliX(0) @ qml.PauliY(2)) + mx = qml.numpy.array(qml.matrix(qml.PauliX(0) @ qml.PauliY(2))) qs = qml.tape.QuantumScript([], [qml.expval(qml.Hermitian(mx, wires=[0, 2]))]) qs.trainable_params = {0} diff --git a/tests/devices/experimental/test_device_api.py b/tests/devices/experimental/test_device_api.py index 2db5826f371..44a038ab8c9 100644 --- a/tests/devices/experimental/test_device_api.py +++ b/tests/devices/experimental/test_device_api.py @@ -71,9 +71,20 @@ def test_shots(self): shots_dev = self.MinimalDevice(shots=100) assert shots_dev.shots == qml.measurements.Shots(100) - with pytest.raises(AttributeError): + with pytest.raises( + AttributeError, match="Shots can no longer be set on a device instance." + ): self.dev.shots = 100 # pylint: disable=attribute-defined-outside-init + def test_getattr_error(self): + """Test that querying a property that doesn't exist informs about interface change.""" + + with pytest.raises( + AttributeError, + match=r"You may be looking for a property or method present in the legacy device", + ): + _ = self.dev.expand_fn + def test_tracker_set_on_initialization(self): """Test that a new tracker instance is initialized with the class.""" assert isinstance(self.dev.tracker, qml.Tracker) diff --git a/tests/devices/test_default_mixed_jax.py b/tests/devices/test_default_mixed_jax.py index 466b73915df..09869162e4f 100644 --- a/tests/devices/test_default_mixed_jax.py +++ b/tests/devices/test_default_mixed_jax.py @@ -28,7 +28,6 @@ jax = pytest.importorskip("jax") jnp = pytest.importorskip("jax.numpy") -config = pytest.importorskip("jax.config") decorators = [lambda x: x, jax.jit] @@ -222,7 +221,7 @@ class TestDtypePreserved: def test_real_dtype(self, enable_x64, r_dtype, measurement): """Test that the user-defined dtype of the device is preserved for QNodes with real-valued outputs""" - config.config.update("jax_enable_x64", enable_x64) + jax.config.update("jax_enable_x64", enable_x64) p = jnp.array(0.543) dev = qml.device("default.mixed", wires=3, r_dtype=r_dtype) @@ -243,7 +242,7 @@ def circuit(x): def test_complex_dtype(self, enable_x64, c_dtype, measurement): """Test that the user-defined dtype of the device is preserved for QNodes with complex-valued outputs""" - config.config.update("jax_enable_x64", enable_x64) + jax.config.update("jax_enable_x64", enable_x64) p = jnp.array(0.543) dev = qml.device("default.mixed", wires=3, c_dtype=c_dtype) @@ -498,7 +497,7 @@ def circuit(x): def test_state_differentiability(self, decorator, op, wire_ids, exp_fn, tol): """Test that the device state can be differentiated""" # pylint: disable=too-many-arguments - config.config.update("jax_enable_x64", True) + jax.config.update("jax_enable_x64", True) dev = qml.device("default.mixed", wires=1) @@ -684,7 +683,7 @@ def test_jax_interface_gradient(self, operation, diff_method, tol): """Tests that the gradient of an arbitrary U3 gate is correct using the JAX interface, using a variety of differentiation methods.""" if diff_method == "finite-diff": - config.config.update("jax_enable_x64", True) + jax.config.update("jax_enable_x64", True) dev = qml.device("default.mixed", wires=1) state = jnp.array(1j * np.array([1, -1]) / np.sqrt(2)) @@ -747,7 +746,7 @@ def test_ragged_differentiation(self, dev_name, diff_method, grad_on_execution, with prob and expval outputs""" if diff_method == "finite-diff": - config.config.update("jax_enable_x64", True) + jax.config.update("jax_enable_x64", True) dev = qml.device(dev_name, wires=2) x = jnp.array(0.543) diff --git a/tests/devices/test_default_qutrit_mixed.py b/tests/devices/test_default_qutrit_mixed.py index 197a97c9c88..b58cd9ddfdb 100644 --- a/tests/devices/test_default_qutrit_mixed.py +++ b/tests/devices/test_default_qutrit_mixed.py @@ -1059,9 +1059,9 @@ class TestPRNGKeySeed: def test_prng_key_as_seed(self): """Test that a jax PRNG can be passed as a seed.""" - from jax.config import config + import jax - config.update("jax_enable_x64", True) + jax.config.update("jax_enable_x64", True) from jax import random diff --git a/tests/devices/test_preprocess.py b/tests/devices/test_preprocess.py index dd677cdf8ab..0931a8d9968 100644 --- a/tests/devices/test_preprocess.py +++ b/tests/devices/test_preprocess.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. """Unit tests for preprocess in devices/qubit.""" +import warnings import pytest @@ -137,10 +138,18 @@ def test_no_sampling(): def test_validate_adjoint_trainable_params_obs_warning(): """Tests warning raised for validate_adjoint_trainable_params with trainable observables.""" - tape = qml.tape.QuantumScript([], [qml.expval(2 * qml.PauliX(0))]) + + params = qml.numpy.array(0.123) + tape = qml.tape.QuantumScript([], [qml.expval(2 * qml.RX(params, wires=0))]) with pytest.warns(UserWarning, match="Differentiating with respect to the input "): validate_adjoint_trainable_params(tape) + params_non_trainable = qml.numpy.array(0.123, requires_grad=False) + tape = qml.tape.QuantumScript([], [qml.expval(2 * qml.RX(params_non_trainable, wires=0))]) + with warnings.catch_warnings(): + warnings.simplefilter("error") # assert no warning raised + validate_adjoint_trainable_params(tape) + def test_validate_adjoint_trainable_params_state_prep_error(): """Tests error raised for validate_adjoint_trainable_params with trainable state-preps.""" diff --git a/tests/gradients/core/test_metric_tensor.py b/tests/gradients/core/test_metric_tensor.py index 3f0cd8a7796..bd234062736 100644 --- a/tests/gradients/core/test_metric_tensor.py +++ b/tests/gradients/core/test_metric_tensor.py @@ -1146,10 +1146,10 @@ def circuit(*params): @pytest.mark.parametrize("ansatz, params", zip(fubini_ansatze, fubini_params)) @pytest.mark.parametrize("interface", ["auto", "jax"]) def test_correct_output_jax(self, ansatz, params, interface): - from jax import config + import jax from jax import numpy as jnp - config.update("jax_enable_x64", True) + jax.config.update("jax_enable_x64", True) expected = autodiff_metric_tensor(ansatz, self.num_wires)(*params) dev = qml.device("default.qubit.jax", wires=self.num_wires + 1) diff --git a/tests/interfaces/default_qubit_2_integration/test_jax_default_qubit_2.py b/tests/interfaces/default_qubit_2_integration/test_jax_default_qubit_2.py index 7fae36f8308..519c0daa028 100644 --- a/tests/interfaces/default_qubit_2_integration/test_jax_default_qubit_2.py +++ b/tests/interfaces/default_qubit_2_integration/test_jax_default_qubit_2.py @@ -24,8 +24,7 @@ jax = pytest.importorskip("jax") jnp = pytest.importorskip("jax.numpy") -config = pytest.importorskip("jax.config") -config.config.update("jax_enable_x64", True) +jax.config.update("jax_enable_x64", True) pytestmark = pytest.mark.jax diff --git a/tests/interfaces/default_qubit_2_integration/test_jax_jit_qnode_default_qubit_2.py b/tests/interfaces/default_qubit_2_integration/test_jax_jit_qnode_default_qubit_2.py index 7f96df42083..cb1306d7b59 100644 --- a/tests/interfaces/default_qubit_2_integration/test_jax_jit_qnode_default_qubit_2.py +++ b/tests/interfaces/default_qubit_2_integration/test_jax_jit_qnode_default_qubit_2.py @@ -47,8 +47,7 @@ pytestmark = pytest.mark.jax jax = pytest.importorskip("jax") -config = pytest.importorskip("jax.config") -config.config.update("jax_enable_x64", True) +jax.config.update("jax_enable_x64", True) TOL_FOR_SPSA = 1.0 SEED_FOR_SPSA = 32651 diff --git a/tests/interfaces/default_qubit_2_integration/test_jax_qnode_default_qubit_2.py b/tests/interfaces/default_qubit_2_integration/test_jax_qnode_default_qubit_2.py index b99bd7a0810..46f0dc77e22 100644 --- a/tests/interfaces/default_qubit_2_integration/test_jax_qnode_default_qubit_2.py +++ b/tests/interfaces/default_qubit_2_integration/test_jax_qnode_default_qubit_2.py @@ -50,8 +50,7 @@ pytestmark = pytest.mark.jax jax = pytest.importorskip("jax") -config = pytest.importorskip("jax.config") -config.config.update("jax_enable_x64", True) +jax.config.update("jax_enable_x64", True) TOL_FOR_SPSA = 1.0 SEED_FOR_SPSA = 32651 diff --git a/tests/interfaces/test_jax_jit_qnode.py b/tests/interfaces/test_jax_jit_qnode.py index 3c0ff4658c8..2cd5c3c56dc 100644 --- a/tests/interfaces/test_jax_jit_qnode.py +++ b/tests/interfaces/test_jax_jit_qnode.py @@ -35,8 +35,7 @@ pytestmark = pytest.mark.jax jax = pytest.importorskip("jax") -config = pytest.importorskip("jax.config") -config.config.update("jax_enable_x64", True) +jax.config.update("jax_enable_x64", True) TOL_FOR_SPSA = 1.0 SEED_FOR_SPSA = 32651 diff --git a/tests/interfaces/test_jax_qnode.py b/tests/interfaces/test_jax_qnode.py index 9b3896999e2..0803ff10e79 100644 --- a/tests/interfaces/test_jax_qnode.py +++ b/tests/interfaces/test_jax_qnode.py @@ -38,8 +38,7 @@ pytestmark = pytest.mark.jax jax = pytest.importorskip("jax") -config = pytest.importorskip("jax.config") -config.config.update("jax_enable_x64", True) +jax.config.update("jax_enable_x64", True) TOL_FOR_SPSA = 1.0 SEED_FOR_SPSA = 32651 diff --git a/tests/interfaces/test_jax_qnode_shot_vector.py b/tests/interfaces/test_jax_qnode_shot_vector.py index 6645e008c31..6530d3a05e1 100644 --- a/tests/interfaces/test_jax_qnode_shot_vector.py +++ b/tests/interfaces/test_jax_qnode_shot_vector.py @@ -23,8 +23,7 @@ pytestmark = pytest.mark.jax jax = pytest.importorskip("jax") -config = pytest.importorskip("jax.config") -config.config.update("jax_enable_x64", True) +jax.config.update("jax_enable_x64", True) all_shots = [(1, 20, 100), (1, (20, 1), 100), (1, (5, 4), 100)] diff --git a/tests/ops/functions/conftest.py b/tests/ops/functions/conftest.py index 80a9c034114..315cc3e50f6 100644 --- a/tests/ops/functions/conftest.py +++ b/tests/ops/functions/conftest.py @@ -24,7 +24,6 @@ import pennylane as qml from pennylane.operation import ( Channel, - DiagGatesUndefinedError, MatrixUndefinedError, Observable, Operation, @@ -61,6 +60,7 @@ qml.ops.Evolution(qml.PauliX(0), 5.2), qml.QutritBasisState([1, 2, 0], wires=[0, 1, 2]), qml.resource.FirstQuantization(1, 2, 1), + qml.prod(qml.RX(1.1, 0), qml.RY(2.2, 0), qml.RZ(3.3, 1)), ] """Valid operator instances that could not be auto-generated.""" @@ -86,10 +86,6 @@ qml.ops.Conditional(qml.measure(1), qml.S(0)), AssertionError, # needs flattening helpers to be updated, also cannot be pickled ), - ( - qml.prod(qml.RX(1.1, 0), qml.RY(2.2, 0), qml.RZ(3.3, 1)), - DiagGatesUndefinedError, # has_diagonalizing_gates should be False - ), ( qml.Identity(0), MatrixUndefinedError, # empty decomposition, matrix differs from decomp's matrix diff --git a/tests/ops/functions/test_dot.py b/tests/ops/functions/test_dot.py index d6157bfd41b..53055442bf0 100644 --- a/tests/ops/functions/test_dot.py +++ b/tests/ops/functions/test_dot.py @@ -50,6 +50,11 @@ class TestDotSum: """Unittests for the dot function when ``pauli=False``.""" + def test_error_if_ops_operator(self): + """Test that dot raises an error if ops is an operator itself.""" + with pytest.raises(ValueError, match=r"ops must be an Iterable of Operator's"): + qml.dot([1, 1], qml.X(0) @ qml.Y(1)) + def test_dot_returns_sum(self): """Test that the dot function returns a Sum operator when ``pauli=False``.""" c = [1.0, 2.0, 3.0] @@ -280,6 +285,20 @@ def test_identities_with_pauli_sentences_pauli_false(self): class TestDotPauliSentence: """Unittest for the dot function when ``pauli=True``""" + def test_error_if_ops_PauliWord(self): + """Test that dot raises an error if ops is a PauliWord itself.""" + _pw = qml.pauli.PauliWord({0: "X", 1: "Y"}) + with pytest.raises(ValueError, match=r"ops must be an Iterable of PauliWord's"): + qml.dot([1, 2], _pw) + + def test_error_if_ops_PauliSentence(self): + """Test that dot raises an error if ops is a PauliSentence itself.""" + _pw1 = qml.pauli.PauliWord({0: "X", 1: "Y"}) + _pw2 = qml.pauli.PauliWord({2: "Z"}) + ps = 2 * _pw1 + 3 * _pw2 + with pytest.raises(ValueError, match=r"ops must be an Iterable of PauliSentence's"): + qml.dot([1, 2], ps) + def test_dot_returns_pauli_sentence(self): """Test that the dot function returns a PauliSentence class.""" ps = qml.dot(coeffs0, ops0, pauli=True) diff --git a/tests/ops/op_math/test_linear_combination.py b/tests/ops/op_math/test_linear_combination.py index e2b71772ca4..74e8ec64ced 100644 --- a/tests/ops/op_math/test_linear_combination.py +++ b/tests/ops/op_math/test_linear_combination.py @@ -564,6 +564,12 @@ def circuit2(param): class TestLinearCombination: """Test the LinearCombination class""" + def test_error_if_observables_operator(self): + """Test thatt an error is raised if an operator is provided to observables.""" + + with pytest.raises(ValueError, match=r"observables must be an Iterable of Operator's"): + qml.ops.LinearCombination([1, 1], qml.X(0) @ qml.Y(1)) + PAULI_REPS = ( ([], [], PauliSentence({})), ( diff --git a/tests/ops/op_math/test_prod.py b/tests/ops/op_math/test_prod.py index 857a25d98aa..2110490517b 100644 --- a/tests/ops/op_math/test_prod.py +++ b/tests/ops/op_math/test_prod.py @@ -115,8 +115,6 @@ def test_obs_attribute(): assert obs == (X(0), X(1), X(2)) -# currently failing due to has_diagonalizing_gates logic -@pytest.mark.xfail # TODO: fix with story 49608 def test_basic_validity(): """Run basic validity checks on a prod operator.""" op1 = qml.PauliZ(0)