def adjoint(self): """Create a tape that is the adjoint of this one. Adjointed tapes are the conjugated and transposed version of the original tapes. Adjointed ops are equivalent to the inverted operation for unitary gates. Returns: ~.QuantumTape: the adjointed tape """ new_tape = self.copy(copy_operations=True) qml.transforms.invisible(new_tape.inv)() # the current implementation of the adjoint # transform requires that the returned inverted object # is automatically queued. QuantumTape._lock.acquire() try: QueuingContext.append(new_tape) except Exception as _: QuantumTape._lock.release() raise QuantumTape._lock.release() return new_tape
def __enter__(self): QuantumTape._lock.acquire() try: if self.do_queue: QueuingContext.append(self) return super().__enter__() except Exception as _: QuantumTape._lock.release() raise
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
def _process_queue(self): super()._process_queue() for obj, info in self._queue.items(): QueuingContext.append(obj, **info) # remove the operation recorder from the queuing # context QueuingContext.remove(self) new_tape = self.expand(depth=5, stop_at=lambda obj: not isinstance(obj, QuantumTape)) self.ops = new_tape.operations self.obs = new_tape.observables
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 mock_queuing_context(monkeypatch): """A mock instance of the abstract QueuingContext class.""" with monkeypatch.context() as m: m.setattr(QueuingContext, "__abstractmethods__", frozenset()) m.setattr( QueuingContext, "_append", lambda self, operator: self.queue.append(operator), ) m.setattr( QueuingContext, "_remove", lambda self, operator: self.queue.remove(operator), ) context = QueuingContext() context.queue = [] yield context
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 adjoint(self): """Create a tape that is the adjoint of this one. Adjointed tapes are the conjugated and transposed version of the original tapes. Adjointed ops are equivalent to the inverted operation for unitary gates. Returns: ~.QuantumTape: the adjointed tape """ new_tape = self.copy(copy_operations=True) with qml.tape.stop_recording(): new_tape.inv() # the current implementation of the adjoint # transform requires that the returned inverted object # is automatically queued. with QuantumTape._lock: QueuingContext.append(new_tape) return new_tape
def get_active_tape(): """Returns the currently recording tape. If no tape is currently recording, ``None`` is returned. **Example** >>> with qml.tape.QuantumTape(): ... qml.RX(0.2, wires="a") ... tape = qml.tape.get_active_tape() ... qml.RY(0.1, wires="b") >>> print(tape) <QuantumTape: wires=['a', 'b'], params=2> >>> print(qml.tape.get_active_tape()) None """ return QueuingContext.active_context()
def three_mock_queuing_contexts(monkeypatch): """A list of three mock instances of the abstract QueuingContext class.""" with monkeypatch.context() as m: m.setattr(QueuingContext, "__abstractmethods__", frozenset()) m.setattr( QueuingContext, "_append", lambda self, operator: self.queue.append(operator), ) m.setattr( QueuingContext, "_remove", lambda self, operator: self.queue.remove(operator), ) contexts = [QueuingContext() for _ in range(3)] for context in contexts: context.queue = [] yield contexts
def stop_recording(self): """Context manager to temporarily stop recording operations onto the tape. This is useful is scratch space is needed. **Example** >>> with qml.tape.QuantumTape() as tape: ... qml.RX(0, wires=0) ... with tape.stop_recording(): ... qml.RY(1.0, wires=1) ... qml.RZ(2, wires=1) >>> tape.operations [RX(0, wires=[0]), RZ(2, wires=[1])] """ if QueuingContext.active_context() is not self: raise QueuingError("Cannot stop recording requested tape " "as it is not currently recording.") active_contexts = QueuingContext._active_contexts QueuingContext._active_contexts = deque() yield QueuingContext._active_contexts = active_contexts
def test_remove_no_context(self): """Test that remove does not fail when no context is present.""" QueuingContext.remove(qml.PauliZ(0))
def test_append_no_context(self): """Test that append does not fail when no context is present.""" QueuingContext.append(qml.PauliZ(0))