diff --git a/pennylane/operation.py b/pennylane/operation.py index 7fab8083d86..b2073f7a025 100644 --- a/pennylane/operation.py +++ b/pennylane/operation.py @@ -1461,7 +1461,7 @@ def generator(self): # pylint: disable=no-self-use 0.5 * Y(0) + Z(0) @ X(1) The generator may also be provided in the form of a dense or sparse Hamiltonian - (using :class:`.Hermitian` and :class:`.SparseHamiltonian` respectively). + (using :class:`.Hamiltonian` and :class:`.SparseHamiltonian` respectively). The default value to return is ``None``, indicating that the operation has no defined generator. diff --git a/pennylane/ops/functions/assert_valid.py b/pennylane/ops/functions/assert_valid.py index 09a0821cb35..7c74512b5ba 100644 --- a/pennylane/ops/functions/assert_valid.py +++ b/pennylane/ops/functions/assert_valid.py @@ -187,6 +187,25 @@ def _check_eigendecomposition(op): assert qml.math.allclose(decomp_mat, original_mat), failure_comment +def _check_generator(op): + """Checks that if an operator's has_generator property is True, it has a generator.""" + + if op.has_generator: + gen = op.generator() + assert isinstance(gen, qml.operation.Operator) + new_op = qml.exp(gen, 1j * op.data[0]) + assert qml.math.allclose( + qml.matrix(op, wire_order=op.wires), qml.matrix(new_op, wire_order=op.wires) + ) + else: + failure_comment = ( + "If has_generator is False, the matrix method must raise a ``GeneratorUndefinedError``." + ) + _assert_error_raised( + op.generator, qml.operation.GeneratorUndefinedError, failure_comment=failure_comment + )() + + def _check_copy(op): """Check that copies and deep copies give identical objects.""" copied_op = copy.copy(op) @@ -276,6 +295,39 @@ def _check_bind_new_parameters(op): assert qml.math.allclose(d1, d2), failure_comment +def _check_differentiation(op): + """Checks that the operator can be executed and differentiated correctly.""" + + if op.num_params == 0: + return + + data, struct = qml.pytrees.flatten(op) + + def circuit(*args): + qml.apply(qml.pytrees.unflatten(args, struct)) + return qml.probs(wires=op.wires) + + qnode_ref = qml.QNode(circuit, qml.device("default.qubit"), diff_method="backprop") + qnode_ps = qml.QNode(circuit, qml.device("default.qubit"), diff_method="parameter-shift") + + params = [x if isinstance(x, int) else qml.numpy.array(x) for x in data] + + ps = qml.jacobian(qnode_ps)(*params) + expected_bp = qml.jacobian(qnode_ref)(*params) + + error_msg = ( + "Parameter-shift does not produce the same Jacobian as with backpropagation. " + "This might be a bug, or it might be expected due to the mathematical nature " + "of backpropagation, in which case, this test can be skipped for this operator." + ) + + if isinstance(ps, tuple): + for actual, expected in zip(ps, expected_bp): + assert qml.math.allclose(actual, expected), error_msg + else: + assert qml.math.allclose(ps, expected_bp), error_msg + + def _check_wires(op, skip_wire_mapping): """Check that wires are a ``Wires`` class and can be mapped.""" assert isinstance(op.wires, qml.wires.Wires), "wires must be a wires instance" @@ -288,7 +340,12 @@ def _check_wires(op, skip_wire_mapping): assert mapped_op.wires == new_wires, "wires must be mappable with map_wires" -def assert_valid(op: qml.operation.Operator, skip_pickle=False, skip_wire_mapping=False) -> None: +def assert_valid( + op: qml.operation.Operator, + skip_pickle=False, + skip_wire_mapping=False, + skip_differentiation=False, +) -> None: """Runs basic validation checks on an :class:`~.operation.Operator` to make sure it has been correctly defined. @@ -298,6 +355,8 @@ def assert_valid(op: qml.operation.Operator, skip_pickle=False, skip_wire_mappin Keyword Args: skip_pickle=False : If ``True``, pickling tests are not run. Set to ``True`` when testing a locally defined operator, as pickle cannot handle local objects + skip_differentiation: If ``True``, differentiation tests are not run. Set to `True` when + the operator is parametrized but not differentiable. **Examples:** @@ -352,4 +411,7 @@ def __init__(self, wires): _check_matrix_matches_decomp(op) _check_sparse_matrix(op) _check_eigendecomposition(op) + _check_generator(op) + if not skip_differentiation: + _check_differentiation(op) _check_capture(op) diff --git a/pennylane/ops/op_math/evolution.py b/pennylane/ops/op_math/evolution.py index 6a01f17f2fc..298e27e5c38 100644 --- a/pennylane/ops/op_math/evolution.py +++ b/pennylane/ops/op_math/evolution.py @@ -147,7 +147,7 @@ def generator(self): f"The operator coefficient {self.coeff} is not imaginary; the expected format is exp(-ixG)." f"The generator is not defined." ) - return self.base + return -1 * self.base def __copy__(self): copied = super().__copy__() diff --git a/pennylane/ops/op_math/exp.py b/pennylane/ops/op_math/exp.py index a6a037c7e6c..106f387b1e2 100644 --- a/pennylane/ops/op_math/exp.py +++ b/pennylane/ops/op_math/exp.py @@ -181,7 +181,6 @@ def __init__(self, base, coeff=1, num_steps=None, id=None): super().__init__(base, scalar=coeff, id=id) self.grad_recipe = [None] self.num_steps = num_steps - self.hyperparameters["num_steps"] = num_steps def __repr__(self): diff --git a/pennylane/ops/op_math/prod.py b/pennylane/ops/op_math/prod.py index 46ab54a531d..29770c40c87 100644 --- a/pennylane/ops/op_math/prod.py +++ b/pennylane/ops/op_math/prod.py @@ -231,6 +231,7 @@ def circuit(weights): _op_symbol = "@" _math_op = math.prod + grad_method = None @property def is_hermitian(self): @@ -359,7 +360,7 @@ def arithmetic_depth(self) -> int: def _build_pauli_rep(self): """PauliSentence representation of the Product of operations.""" if all(operand_pauli_reps := [op.pauli_rep for op in self.operands]): - return reduce(lambda a, b: a @ b, operand_pauli_reps) + return reduce(lambda a, b: a @ b, operand_pauli_reps) if operand_pauli_reps else None return None def _simplify_factors(self, factors: tuple[Operator]) -> tuple[complex, Operator]: diff --git a/pennylane/templates/subroutines/prepselprep.py b/pennylane/templates/subroutines/prepselprep.py index c9796427615..d9aa0b11a5c 100644 --- a/pennylane/templates/subroutines/prepselprep.py +++ b/pennylane/templates/subroutines/prepselprep.py @@ -24,6 +24,7 @@ def _get_new_terms(lcu): """Compute a new sum of unitaries with positive coefficients""" coeffs, ops = lcu.terms() + coeffs = qml.math.stack(coeffs) angles = qml.math.angle(coeffs) new_ops = [] diff --git a/tests/ops/functions/conftest.py b/tests/ops/functions/conftest.py index 43316f0ccf0..ff01b23f40f 100644 --- a/tests/ops/functions/conftest.py +++ b/tests/ops/functions/conftest.py @@ -35,43 +35,55 @@ from pennylane.ops.op_math.pow import PowObs, PowOperation, PowOpObs _INSTANCES_TO_TEST = [ - qml.sum(qml.PauliX(0), qml.PauliZ(0)), - qml.sum(qml.X(0), qml.X(0), qml.Z(0), qml.Z(0)), - qml.BasisState([1], wires=[0]), - qml.ControlledQubitUnitary(np.eye(2), control_wires=1, wires=0), - qml.QubitChannel([np.array([[1, 0], [0, 0.8]]), np.array([[0, 0.6], [0, 0]])], wires=0), - qml.MultiControlledX(wires=[0, 1]), - qml.Projector([1], 0), # the state-vector version is already tested - qml.SpecialUnitary([1, 1, 1], 0), - qml.IntegerComparator(1, wires=[0, 1]), - qml.PauliRot(1.1, "X", wires=[0]), - qml.StatePrep([0, 1], 0), - qml.PCPhase(0.27, dim=2, wires=[0, 1]), - qml.BlockEncode([[0.1, 0.2], [0.3, 0.4]], wires=[0, 1]), - qml.adjoint(qml.PauliX(0)), - qml.adjoint(qml.RX(1.1, 0)), - Tensor(qml.PauliX(0), qml.PauliX(1)), - qml.ops.LinearCombination([1.1, 2.2], [qml.PauliX(0), qml.PauliZ(0)]), - qml.s_prod(1.1, qml.RX(1.1, 0)), - qml.prod(qml.PauliX(0), qml.PauliY(1), qml.PauliZ(0)), - qml.ctrl(qml.RX(1.1, 0), 1), - qml.exp(qml.PauliX(0), 1.1), - qml.pow(qml.IsingXX(1.1, [0, 1]), 2.5), - 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)), - qml.Snapshot(measurement=qml.expval(qml.Z(0)), tag="hi"), - qml.Snapshot(tag="tag"), + (qml.sum(qml.PauliX(0), qml.PauliZ(0)), {}), + (qml.sum(qml.X(0), qml.X(0), qml.Z(0), qml.Z(0)), {}), + (qml.BasisState([1], wires=[0]), {"skip_differentiation": True}), + ( + qml.ControlledQubitUnitary(np.eye(2), control_wires=1, wires=0), + {"skip_differentiation": True}, + ), + ( + qml.QubitChannel([np.array([[1, 0], [0, 0.8]]), np.array([[0, 0.6], [0, 0]])], wires=0), + {"skip_differentiation": True}, + ), + (qml.MultiControlledX(wires=[0, 1]), {}), + (qml.Projector([1], 0), {"skip_differentiation": True}), + (qml.Projector([1, 0], 0), {"skip_differentiation": True}), + (qml.DiagonalQubitUnitary([1, 1, 1, 1], wires=[0, 1]), {"skip_differentiation": True}), + (qml.QubitUnitary(np.eye(2), wires=[0]), {"skip_differentiation": True}), + (qml.SpecialUnitary([1, 1, 1], 0), {"skip_differentiation": True}), + (qml.IntegerComparator(1, wires=[0, 1]), {"skip_differentiation": True}), + (qml.PauliRot(1.1, "X", wires=[0]), {}), + (qml.StatePrep([0, 1], 0), {"skip_differentiation": True}), + (qml.PCPhase(0.27, dim=2, wires=[0, 1]), {}), + (qml.BlockEncode([[0.1, 0.2], [0.3, 0.4]], wires=[0, 1]), {"skip_differentiation": True}), + (qml.adjoint(qml.PauliX(0)), {}), + (qml.adjoint(qml.RX(1.1, 0)), {}), + (Tensor(qml.PauliX(0), qml.PauliX(1)), {}), + (qml.ops.LinearCombination([1.1, 2.2], [qml.PauliX(0), qml.PauliZ(0)]), {}), + (qml.s_prod(1.1, qml.RX(1.1, 0)), {}), + (qml.prod(qml.PauliX(0), qml.PauliY(1), qml.PauliZ(0)), {}), + (qml.ctrl(qml.RX(1.1, 0), 1), {}), + (qml.exp(qml.PauliX(0), 1.1), {}), + (qml.pow(qml.IsingXX(1.1, [0, 1]), 2.5), {}), + (qml.ops.Evolution(qml.PauliX(0), 5.2), {}), + (qml.QutritBasisState([1, 2, 0], wires=[0, 1, 2]), {"skip_differentiation": True}), + (qml.resource.FirstQuantization(1, 2, 1), {}), + (qml.prod(qml.RX(1.1, 0), qml.RY(2.2, 0), qml.RZ(3.3, 1)), {}), + (qml.Snapshot(measurement=qml.expval(qml.Z(0)), tag="hi"), {}), + (qml.Snapshot(tag="tag"), {}), ] """Valid operator instances that could not be auto-generated.""" with warnings.catch_warnings(): warnings.filterwarnings("ignore", "qml.ops.Hamiltonian uses", qml.PennyLaneDeprecationWarning) _INSTANCES_TO_TEST.append( - qml.operation.convert_to_legacy_H( - qml.Hamiltonian([1.1, 2.2], [qml.PauliX(0), qml.PauliZ(0)]) - ), + ( + qml.operation.convert_to_legacy_H( + qml.Hamiltonian([1.1, 2.2], [qml.PauliX(0), qml.PauliZ(0)]) + ), + {}, + ) ) @@ -130,6 +142,7 @@ Operation, Observable, Channel, + qml.ops.Projector, qml.ops.SymbolicOp, qml.ops.ScalarSymbolicOp, qml.ops.Pow, @@ -164,7 +177,7 @@ def get_all_classes(c): _CLASSES_TO_TEST = ( set(get_all_classes(Operator)) - {i[1] for i in getmembers(qml.templates) if isclass(i[1]) and issubclass(i[1], Operator)} - - {type(op) for op in _INSTANCES_TO_TEST} + - {type(op) for (op, _) in _INSTANCES_TO_TEST} - {type(op) for (op, _) in _INSTANCES_TO_FAIL} ) """All operators, except those tested manually, abstract/meta classes, and templates.""" @@ -176,7 +189,7 @@ def class_to_validate(request): @pytest.fixture(params=_INSTANCES_TO_TEST) -def valid_instance(request): +def valid_instance_and_kwargs(request): yield request.param diff --git a/tests/ops/functions/test_assert_valid.py b/tests/ops/functions/test_assert_valid.py index 5c347487d9d..70cea786063 100644 --- a/tests/ops/functions/test_assert_valid.py +++ b/tests/ops/functions/test_assert_valid.py @@ -24,6 +24,7 @@ import pennylane as qml from pennylane.operation import Operator from pennylane.ops.functions import assert_valid +from pennylane.ops.functions.assert_valid import _check_capture class TestDecompositionErrors: @@ -303,6 +304,28 @@ def _unflatten(cls, data, _): assert_valid(op, skip_pickle=True) +@pytest.mark.jax +def test_bad_capture(): + """Tests that the correct error is raised when something goes wrong with program capture.""" + + class MyBadOp(qml.operation.Operator): + + def _flatten(self): + return (self.hyperparameters["target_op"], self.data[0]), () + + @classmethod + def _unflatten(cls, data, metadata): + return cls(*data) + + def __init__(self, target_op, val): + super().__init__(val, wires=target_op.wires) + self.hyperparameters["target_op"] = target_op + + op = MyBadOp(qml.X(0), 2) + with pytest.raises(ValueError, match=r"The capture of the operation into jaxpr failed"): + _check_capture(op) + + def test_data_is_tuple(): """Check that the data property is a tuple.""" @@ -376,13 +399,14 @@ def test_generated_list_of_ops(class_to_validate, str_wires): @pytest.mark.jax -def test_explicit_list_of_ops(valid_instance): +def test_explicit_list_of_ops(valid_instance_and_kwargs): """Test the validity of operators that could not be auto-generated.""" + valid_instance, kwargs = valid_instance_and_kwargs if valid_instance.name == "Hamiltonian": with qml.operation.disable_new_opmath_cm(warn=False): - assert_valid(valid_instance) + assert_valid(valid_instance, **kwargs) else: - assert_valid(valid_instance) + assert_valid(valid_instance, **kwargs) @pytest.mark.jax diff --git a/tests/ops/op_math/test_evolution.py b/tests/ops/op_math/test_evolution.py index 4cb61166573..49179c9b7bc 100644 --- a/tests/ops/op_math/test_evolution.py +++ b/tests/ops/op_math/test_evolution.py @@ -69,7 +69,7 @@ def test_has_generator_false(self): def test_generator(self): U = Evolution(qml.PauliX(0), 3) - assert U.base == U.generator() + assert U.generator() == -1 * U.base @pytest.mark.usefixtures("legacy_opmath_only") def test_num_params_for_parametric_base_legacy_opmath(self): @@ -206,7 +206,7 @@ def test_generator_not_observable_class(self, base): """Test that qml.generator will return generator if it is_hermitian, but is not a subclass of Observable""" op = Evolution(base, 1) gen, c = qml.generator(op) - qml.assert_equal(gen if c == 1 else qml.s_prod(c, gen), base) + qml.assert_equal(gen if c == 1 else qml.s_prod(c, gen), -1 * base) def test_generator_error_if_not_hermitian(self): """Tests that an error is raised if the generator is not hermitian.""" diff --git a/tests/ops/qubit/test_observables.py b/tests/ops/qubit/test_observables.py index 66b4d7dbfa0..754ce93c1ca 100644 --- a/tests/ops/qubit/test_observables.py +++ b/tests/ops/qubit/test_observables.py @@ -539,7 +539,7 @@ def test_basisstate_projector(self): second_projector = qml.Projector(basis_state, wires) qml.assert_equal(second_projector, basis_state_projector) - qml.ops.functions.assert_valid(basis_state_projector) + qml.ops.functions.assert_valid(basis_state_projector, skip_differentiation=True) def test_statevector_projector(self): """Test that we obtain a _StateVectorProjector when input is a state vector.""" diff --git a/tests/templates/test_embeddings/test_amplitude.py b/tests/templates/test_embeddings/test_amplitude.py index 8df96c97045..ec25c437cf1 100644 --- a/tests/templates/test_embeddings/test_amplitude.py +++ b/tests/templates/test_embeddings/test_amplitude.py @@ -50,7 +50,7 @@ def test_standard_validity(): op = qml.AmplitudeEmbedding(features=FEATURES[0], wires=range(2)) - qml.ops.functions.assert_valid(op) + qml.ops.functions.assert_valid(op, skip_differentiation=True) class TestDecomposition: diff --git a/tests/templates/test_embeddings/test_angle.py b/tests/templates/test_embeddings/test_angle.py index 93cfdaccc0b..29b47b56044 100644 --- a/tests/templates/test_embeddings/test_angle.py +++ b/tests/templates/test_embeddings/test_angle.py @@ -23,7 +23,7 @@ def test_standard_validity(): """Check the operation using the assert_valid function.""" - op = qml.AngleEmbedding(features=[1, 2, 3], wires=range(3), rotation="Z") + op = qml.AngleEmbedding(features=[1.0, 2.0, 3.0], wires=range(3), rotation="Z") qml.ops.functions.assert_valid(op) diff --git a/tests/templates/test_embeddings/test_basis.py b/tests/templates/test_embeddings/test_basis.py index 3b8b93b79e6..a7ab50f48c1 100644 --- a/tests/templates/test_embeddings/test_basis.py +++ b/tests/templates/test_embeddings/test_basis.py @@ -25,7 +25,7 @@ def test_standard_validity(): """Check the operation using the assert_valid function.""" wires = qml.wires.Wires((0, 1, 2)) op = qml.BasisEmbedding(features=np.array([1, 1, 1]), wires=wires) - qml.ops.functions.assert_valid(op) + qml.ops.functions.assert_valid(op, skip_differentiation=True) # pylint: disable=protected-access diff --git a/tests/templates/test_embeddings/test_displacement_emb.py b/tests/templates/test_embeddings/test_displacement_emb.py index 9c9769ab469..a65bdf85be9 100644 --- a/tests/templates/test_embeddings/test_displacement_emb.py +++ b/tests/templates/test_embeddings/test_displacement_emb.py @@ -25,9 +25,9 @@ def test_standard_validity(): """Check the operation using the assert_valid function.""" - feature_vector = [1, 2, 3] + feature_vector = [1.0, 2.0, 3.0] op = qml.DisplacementEmbedding(features=feature_vector, wires=range(3), method="phase", c=0.5) - qml.ops.functions.assert_valid(op) + qml.ops.functions.assert_valid(op, skip_differentiation=True) # Skip because it's CV op. def test_flatten_unflatten_methods(): diff --git a/tests/templates/test_embeddings/test_iqp_emb.py b/tests/templates/test_embeddings/test_iqp_emb.py index 274e9e3e7a5..2fd260dcc14 100644 --- a/tests/templates/test_embeddings/test_iqp_emb.py +++ b/tests/templates/test_embeddings/test_iqp_emb.py @@ -23,7 +23,7 @@ def test_standard_validity(): """Check the operation using the assert_valid function.""" - features = (0, 1, 2) + features = (0.0, 1.0, 2.0) op = qml.IQPEmbedding(features, wires=(0, 1, 2)) qml.ops.functions.assert_valid(op) diff --git a/tests/templates/test_embeddings/test_squeezing_emb.py b/tests/templates/test_embeddings/test_squeezing_emb.py index 198905e6614..af2e5b244f3 100644 --- a/tests/templates/test_embeddings/test_squeezing_emb.py +++ b/tests/templates/test_embeddings/test_squeezing_emb.py @@ -25,9 +25,9 @@ def test_standard_validity(): """Check the operation using the assert_valid function.""" - feature_vector = [1, 2, 3] + feature_vector = [1.0, 2.0, 3.0] op = qml.SqueezingEmbedding(features=feature_vector, wires=range(3), method="phase", c=0.5) - qml.ops.functions.assert_valid(op) + qml.ops.functions.assert_valid(op, skip_differentiation=True) # Skip because it's CV op. def test_flatten_unflatten_methods(): diff --git a/tests/templates/test_state_preparations/test_basis_state_prep.py b/tests/templates/test_state_preparations/test_basis_state_prep.py index 441af8e007d..1056760f326 100644 --- a/tests/templates/test_state_preparations/test_basis_state_prep.py +++ b/tests/templates/test_state_preparations/test_basis_state_prep.py @@ -34,7 +34,7 @@ def test_standard_validity(): op = qml.BasisStatePreparation(basis_state, wires) - qml.ops.functions.assert_valid(op) + qml.ops.functions.assert_valid(op, skip_differentiation=True) def test_BasisStatePreparation_is_deprecated(): diff --git a/tests/templates/test_state_preparations/test_qutrit_basis_state_prep.py b/tests/templates/test_state_preparations/test_qutrit_basis_state_prep.py index 98755079512..47702382890 100644 --- a/tests/templates/test_state_preparations/test_qutrit_basis_state_prep.py +++ b/tests/templates/test_state_preparations/test_qutrit_basis_state_prep.py @@ -29,7 +29,7 @@ def test_standard_validity(): wires = [1, 2, 6, 8] op = qml.QutritBasisStatePreparation(basis_state, wires) - qml.ops.functions.assert_valid(op) + qml.ops.functions.assert_valid(op, skip_differentiation=True) class TestDecomposition: diff --git a/tests/templates/test_subroutines/test_all_singles_doubles.py b/tests/templates/test_subroutines/test_all_singles_doubles.py index f7844dcb807..e42d9193df6 100644 --- a/tests/templates/test_subroutines/test_all_singles_doubles.py +++ b/tests/templates/test_subroutines/test_all_singles_doubles.py @@ -26,7 +26,7 @@ def test_standard_validity(): """Run standard tests of operation validity.""" op = qml.AllSinglesDoubles( - [1, 2], + [1.0, 2.0], wires=range(4), hf_state=np.array([1, 1, 0, 0]), singles=[[0, 1]], diff --git a/tests/templates/test_subroutines/test_commuting_evolution.py b/tests/templates/test_subroutines/test_commuting_evolution.py index 629bdadcab5..c07bb5c3918 100644 --- a/tests/templates/test_subroutines/test_commuting_evolution.py +++ b/tests/templates/test_subroutines/test_commuting_evolution.py @@ -22,6 +22,7 @@ from pennylane import numpy as np +@pytest.mark.xfail(reason="https://github.com/PennyLaneAI/pennylane/issues/6340") def test_standard_validity(): """Run standard tests of operation validity.""" H = 2.0 * qml.PauliX(0) @ qml.PauliY(1) + 3.0 * qml.PauliY(0) @ qml.PauliZ(1) diff --git a/tests/templates/test_subroutines/test_hilbert_schmidt.py b/tests/templates/test_subroutines/test_hilbert_schmidt.py index 42b6338b82e..741989d69aa 100644 --- a/tests/templates/test_subroutines/test_hilbert_schmidt.py +++ b/tests/templates/test_subroutines/test_hilbert_schmidt.py @@ -31,7 +31,7 @@ def test_flatten_unflatten_standard_checks(op_type): v_wires = qml.wires.Wires((0, 1)) op = op_type([0.1], v_function=global_v_circuit, v_wires=v_wires, u_tape=u_tape) - qml.ops.functions.assert_valid(op, skip_wire_mapping=True) + qml.ops.functions.assert_valid(op, skip_wire_mapping=True, skip_differentiation=True) data, metadata = op._flatten() diff --git a/tests/templates/test_subroutines/test_prepselprep.py b/tests/templates/test_subroutines/test_prepselprep.py index 7e3b7966c28..b6fdbf00bb3 100644 --- a/tests/templates/test_subroutines/test_prepselprep.py +++ b/tests/templates/test_subroutines/test_prepselprep.py @@ -23,6 +23,7 @@ import pennylane as qml +@pytest.mark.xfail(reason="PrepSelPrep does not work with parameter-shift (GitHub issue #6331)") @pytest.mark.parametrize( ("lcu", "control"), [ diff --git a/tests/templates/test_subroutines/test_qdrift.py b/tests/templates/test_subroutines/test_qdrift.py index 83ef2e55ccb..2f0f25b9eb8 100644 --- a/tests/templates/test_subroutines/test_qdrift.py +++ b/tests/templates/test_subroutines/test_qdrift.py @@ -65,7 +65,7 @@ def test_init_correctly(self, coeffs, ops, time, n, seed): # pylint: disable=to if seed is not None: # For seed = None, decomposition and compute_decomposition do not match because # compute_decomposition is stochastic - qml.ops.functions.assert_valid(op) + qml.ops.functions.assert_valid(op, skip_differentiation=True) assert op.wires == h.wires assert op.parameters == [*h.data, time] diff --git a/tests/templates/test_subroutines/test_qmc.py b/tests/templates/test_subroutines/test_qmc.py index 9a5b18f3c7c..7a612f12835 100644 --- a/tests/templates/test_subroutines/test_qmc.py +++ b/tests/templates/test_subroutines/test_qmc.py @@ -264,7 +264,7 @@ def test_standard_validity(self): target_wires, estimation_wires = Wires(range(3)), Wires(range(3, 5)) op = QuantumMonteCarlo(p, self.func, target_wires, estimation_wires) - qml.ops.functions.assert_valid(op) + qml.ops.functions.assert_valid(op, skip_differentiation=True) def test_non_flat(self): """Test if a ValueError is raised when a non-flat array is input""" diff --git a/tests/templates/test_subroutines/test_qubitization.py b/tests/templates/test_subroutines/test_qubitization.py index 50c23080400..7649a0a7daa 100644 --- a/tests/templates/test_subroutines/test_qubitization.py +++ b/tests/templates/test_subroutines/test_qubitization.py @@ -65,6 +65,7 @@ def circuit(theta): assert np.allclose(np.sort(estimated_eigenvalues), qml.eigvals(hamiltonian), atol=0.1) +@pytest.mark.xfail(reason="PrepSelPrep does not work with parameter-shift (GitHub issue #6331)") def test_standard_validity(): """Check the operation using the assert_valid function.""" H = qml.dot([0.1, -0.3, -0.3], [qml.X(0), qml.Z(1), qml.Y(0) @ qml.Z(2)]) diff --git a/tests/templates/test_subroutines/test_trotter.py b/tests/templates/test_subroutines/test_trotter.py index 6ac6e2bd65f..ce9cd3f1760 100644 --- a/tests/templates/test_subroutines/test_trotter.py +++ b/tests/templates/test_subroutines/test_trotter.py @@ -29,14 +29,14 @@ from pennylane.templates.subroutines.trotter import _recursive_expression, _scalar test_hamiltonians = ( - qml.dot([1, 1, 1], [qml.PauliX(0), qml.PauliY(0), qml.PauliZ(1)]), + qml.dot([1.0, 1.0, 1.0], [qml.PauliX(0), qml.PauliY(0), qml.PauliZ(1)]), qml.dot( [1.23, -0.45], [qml.s_prod(0.1, qml.PauliX(0)), qml.prod(qml.PauliX(0), qml.PauliZ(1))] ), # op arith qml.dot( [1, -0.5, 0.5], [qml.Identity(wires=[0, 1]), qml.PauliZ(0), qml.PauliZ(0)] ), # H = Identity - qml.dot([2, 2, 2], [qml.PauliX(0), qml.PauliY(0), qml.PauliZ(1)]), + qml.dot([2.0, 2.0, 2.0], [qml.PauliX(0), qml.PauliY(0), qml.PauliZ(1)]), ) p_4 = (4 - 4 ** (1 / 3)) ** -1 @@ -447,6 +447,7 @@ def test_copy(self, hamiltonian, time, n, order): assert op.hyperparameters == new_op.hyperparameters assert op is not new_op + @pytest.mark.xfail(reason="https://github.com/PennyLaneAI/pennylane/issues/6333", strict=False) @pytest.mark.parametrize("hamiltonian", test_hamiltonians) def test_standard_validity(self, hamiltonian): """Test standard validity criteria using assert_valid."""