def test_remove_not_in_queue(self): """Test that remove fails when the object to be removed is not in the queue.""" with AnnotatedQueue() as q1: op1 = qml.PauliZ(0) op2 = qml.PauliZ(1) q1.append(op1) q1.append(op2) with AnnotatedQueue() as q2: q2.append(op1) with pytest.raises(KeyError): q2.remove(op2)
def test_append_annotating_object(self): """Test appending an object that writes annotations when queuing itself""" class AnnotatingTensor(qml.operation.Tensor): """Dummy tensor class that queues itself on initialization to an annotating queue.""" def __init__(self, *args): super().__init__(*args) self.queue() def queue(self): QueuingContext.append(self, owns=tuple(self.obs)) for o in self.obs: try: QueuingContext.update_info(o, owner=self) except AttributeError: pass return self with AnnotatedQueue() as q: A = qml.PauliZ(0) B = qml.PauliY(1) tensor_op = AnnotatingTensor(A, B) assert q.queue == [A, B, tensor_op] assert q._get_info(A) == {"owner": tensor_op} assert q._get_info(B) == {"owner": tensor_op} assert q._get_info(tensor_op) == {"owns": (A, B)}
def test_get_info_none(self): """Test that get_info returns None if there is no active queuing context""" A = qml.RZ(0.5, wires=1) with AnnotatedQueue() as q: q.append(A, inv=True) assert QueuingContext.get_info(A) is None
def test_get_info(self): """Test that get_info correctly returns an annotation""" A = qml.RZ(0.5, wires=1) with AnnotatedQueue() as q: q.append(A, inv=True) assert q._get_info(A) == {"inv": True}
def test_annotating_probs(self, wires): with AnnotatedQueue() as q: probs(wires) assert len(q.queue) == 1 meas_proc = q.queue[0] assert isinstance(meas_proc, MeasurementProcess) assert meas_proc.return_type == Probability
def test_append_tensor_ops_overloaded(self): """Test that Tensor ops created using `@` are successfully added to the queue, as well as the `Tensor` object.""" with AnnotatedQueue() as q: A = qml.PauliZ(0) B = qml.PauliY(1) tensor_op = A @ B assert q.queue == [A, B, tensor_op] assert tensor_op.obs == [A, B]
def test_append_tensor_ops(self): """Test that ops which are used as inputs to `Tensor` are successfully added to the queue, as well as the `Tensor` object.""" with AnnotatedQueue() as q: A = qml.PauliZ(0) B = qml.PauliY(1) tensor_op = qml.operation.Tensor(A, B) assert q.queue == [A, B, tensor_op] assert tensor_op.obs == [A, B]
def test_update_error(self): """Test that an exception is raised if get_info is called for a non-existent object""" with AnnotatedQueue() as q: A = qml.PauliZ(0) B = qml.PauliY(1) with pytest.raises(QueuingError, match="not in the queue"): q._update_info(B, inv=True)
def test_append_qubit_gates(self): """Test that gates are successfully appended to the queue.""" with AnnotatedQueue() as q: ops = [ qml.RX(0.5, wires=0), qml.RY(-10.1, wires=1), qml.CNOT(wires=[0, 1]), qml.PhaseShift(-1.1, wires=18), qml.T(wires=99), ] assert q.queue == ops
def test_update_info(self): """Test that update_info correctly updates an annotation""" A = qml.RZ(0.5, wires=1) with AnnotatedQueue() as q: q.append(A, inv=True) assert QueuingContext.get_info(A) == {"inv": True} assert q._get_info(A) == {"inv": True} q._update_info(A, inv=False, owner=None) assert q._get_info(A) == {"inv": False, "owner": None}
def test_append_annotating_object(self): """Test appending an object that writes annotations when queuing itself""" with AnnotatedQueue() as q: A = qml.PauliZ(0) B = qml.PauliY(1) tensor_op = qml.operation.Tensor(A, B) assert q.queue == [A, B, tensor_op] assert q._get_info(A) == {"owner": tensor_op} assert q._get_info(B) == {"owner": tensor_op} assert q._get_info(tensor_op) == {"owns": (A, B)}
def test_append_qubit_observables(self): """Test that ops that are also observables are successfully appended to the queue.""" with AnnotatedQueue() as q: # wire repetition is deliberate, Queue contains no checks/logic # for circuits ops = [ qml.Hadamard(wires=0), qml.PauliX(wires=1), qml.PauliY(wires=1), qml.Hermitian(np.ones([2, 2]), wires=7), ] assert q.queue == ops
def test_annotating_obs_return_type(self, stat_func, return_type, op): """Test that the return_type related info is updated for a measurement""" with AnnotatedQueue() as q: A = op(0) stat_func(A) assert q.queue[:-1] == [A] meas_proc = q.queue[-1] assert isinstance(meas_proc, MeasurementProcess) assert meas_proc.return_type == return_type assert q._get_info(A) == {"owner": meas_proc} assert q._get_info(meas_proc) == {"owns": (A)}
def test_annotating_tensor_return_type(self, op1, op2, stat_func, return_type): """Test that the return_type related info is updated for a measurement when called for an Tensor observable""" with AnnotatedQueue() as q: A = op1(0) B = op2(1) tensor_op = A @ B stat_func(tensor_op) assert q.queue[:-1] == [A, B, tensor_op] meas_proc = q.queue[-1] assert isinstance(meas_proc, MeasurementProcess) assert meas_proc.return_type == return_type assert q._get_info(A) == {"owner": tensor_op} assert q._get_info(B) == {"owner": tensor_op} assert q._get_info(tensor_op) == {"owns": (A, B), "owner": meas_proc}
def test_annotating_tensor_hermitian(self, stat_func, return_type): """Test that the return_type related info is updated for a measurement when called for an Hermitian observable""" mx = np.array([[1, 0], [0, 1]]) with AnnotatedQueue() as q: Herm = qml.Hermitian(mx, wires=[1]) stat_func(Herm) assert q.queue[:-1] == [Herm] meas_proc = q.queue[-1] assert isinstance(meas_proc, MeasurementProcess) assert meas_proc.return_type == return_type assert q._get_info(Herm) == {"owner": meas_proc} assert q._get_info(meas_proc) == {"owns": (Herm)}
def test_queueing_tensor_observable(self, op1, op2, stat_func, return_type): """Test that if the constituent components of a tensor operation are not found in the queue for annotation, that they are queued first and then annotated.""" A = op1(0) B = op2(1) with AnnotatedQueue() as q: tensor_op = A @ B stat_func(tensor_op) assert q.queue[:-1] == [A, B, tensor_op] meas_proc = q.queue[-1] assert isinstance(meas_proc, MeasurementProcess) assert meas_proc.return_type == return_type assert q._get_info(A) == {"owner": tensor_op} assert q._get_info(B) == {"owner": tensor_op} assert q._get_info(tensor_op) == {"owns": (A, B), "owner": meas_proc}