Insert measurements to a pre-defined quantumTape


Is it possible to insert a measurement process in a wrapper function that executes a predefined QuantumTape? For example, instead of

circuit = qml.tape.QuantumTape(ops, measurements)

def executor(tape):
  qml.execute([tape], dev_noisy)

You do something like

circuit = qml.tape.QuantumTape(ops) # define quantum tape without measurements

def executor(tape):
  # somehow insert measurements here
  qml.execute([tape], dev_noisy)

My versions are:

Name: PennyLane
Version: 0.33.1
Summary: PennyLane is a Python quantum machine learning library by Xanadu Inc.
License: Apache License 2.0
Location: /Users/bigsad/Downloads/Algorithm-Research/Student-Hub/Indy-Ng/.venv/lib/python3.11/site-packages
Requires: appdirs, autograd, autoray, cachetools, networkx, numpy, pennylane-lightning, requests, rustworkx, scipy, semantic-version, toml, typing-extensions
Required-by: PennyLane-Lightning, PennyLane-qiskit

Platform info:           macOS-12.6-x86_64-i386-64bit
Python version:          3.11.6
Numpy version:           1.23.5
Scipy version:           1.10.1
Installed devices:
- default.gaussian (PennyLane-0.33.1)
- default.mixed (PennyLane-0.33.1)
- default.qubit (PennyLane-0.33.1)
- default.qubit.autograd (PennyLane-0.33.1)
- default.qubit.jax (PennyLane-0.33.1)
- default.qubit.legacy (PennyLane-0.33.1)
- (PennyLane-0.33.1)
- default.qubit.torch (PennyLane-0.33.1)
- default.qutrit (PennyLane-0.33.1)
- null.qubit (PennyLane-0.33.1)
- lightning.qubit (PennyLane-Lightning-0.33.1)
- qiskit.aer (PennyLane-qiskit-0.33.1)
- qiskit.basicaer (PennyLane-qiskit-0.33.1)
- qiskit.ibmq (PennyLane-qiskit-0.33.1)
- qiskit.ibmq.circuit_runner (PennyLane-qiskit-0.33.1)
- qiskit.ibmq.sampler (PennyLane-qiskit-0.33.1)
- qiskit.remote (PennyLane-qiskit-0.33.1)

Hey @jkwan314! One of our PennyLane developers will get back to you shortly about this :slight_smile:

Hi @jkwan314, thanks for stopping by the forum!

Generally speaking, qml.execute is a function that takes in a set of tapes and a device, then it returns a set of results. It requires that all information about the circuit being executed is contained on those tape objects, so your best solution is effectively what you originally had (defining the measurements on the tape). If your goal is to modify the measurements within the function, you can simply create a new tape. Here’s a full example of how you might do that:

dev_noisy = qml.device("default.qubit")

ops = [qml.PauliX(0), qml.PauliY(1)]

circuit = qml.tape.QuantumTape(ops)

def executor(tape, new_measurements):
    new_tape = qml.tape.QuantumTape(
        tape.measurements + new_measurements,
    return qml.execute([new_tape], dev_noisy)

executor(circuit, [qml.state()])

Let me know if that works!

1 Like

Thanks, that worked for my usecase!