-
Notifications
You must be signed in to change notification settings - Fork 586
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WIP] Add mitigation support using mitiq backend #1783
Conversation
Hello. You may have forgotten to update the changelog!
|
Codecov Report
@@ Coverage Diff @@
## master #1783 +/- ##
==========================================
- Coverage 98.90% 98.56% -0.34%
==========================================
Files 206 207 +1
Lines 15403 15497 +94
==========================================
+ Hits 15234 15275 +41
- Misses 169 222 +53
Continue to review full report at Codecov.
|
def new_executor(updated_tape): | ||
with QuantumTape() as updated_tape_with_measurements: | ||
for op in updated_tape.operations: | ||
op.queue() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
op.queue() | |
qml.apply(op) |
this will be safer than calling queue
:)
def new_executor(updated_tape): | ||
with QuantumTape() as updated_tape_with_measurements: | ||
for op in updated_tape.operations: | ||
op.queue() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
op.queue() | |
qml.apply(op) |
this will be safer than calling queue
:)
return new_tape | ||
|
||
|
||
def add_noise_to_tape(tape, noisy_op: Operation, noisy_op_args, position: str = "all"): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@trbromley you could also
-
Decorate this with
@qml.single_tape_transform
, to help remove some of the boiler plate (it allows you to remove thewith QuantumTape() as noisy_tape:
context manager) -
Also provide a
@qml.qfunc_transform
version of this function, that allows it to work on qfuncs
add_noise_to_qfunc = qml.qfunc_transform(add_noise_to_tape)
@add_noise_to_qfunc(qml.AmplitudeDamping, 0.2, position="all")
def circuit():
qml.RX(0.9, wires=0)
qml.RY(0.4, wires=1)
qml.CNOT(wires=[0, 1])
qml.RZ(0.5, wires=0)
qml.RX(0.6, wires=1)
return qml.expval(qml.PauliZ(0))
Although I don't know if this is something you would want in your workflow or not :)
def execute(circuit, **kwargs): | ||
noisy_circuit = add_noise_to_tape(circuit, noisy_op, noisy_op_args, position) | ||
return original_execute(noisy_circuit, **kwargs) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm curious if you got this to work via the expand_fn
approach?
dev = deepcopy(dev)
original_expand_fn = dev.expand_fn
def expand_fn(self, circuit, **kwargs):
circuit = original_expand_fn(circuit, **kwargs)
return add_noise_to_tape(circuit, noisy_op, noisy_op_args, position)
dev.expand_fn = types.MethodType(expand_fn, dev)
return dev
>>> tape.execute(dev) | ||
[0.97578304] | ||
""" | ||
dev = deepcopy(dev) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I worry that not all devices might be deepcopyable? Might not be an issue though
def execute(circuit, **kwargs): | ||
noisy_circuit = add_noise_to_tape(circuit, noisy_op, noisy_op_args, position) | ||
return original_execute(noisy_circuit, **kwargs) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm curious if you got this to work via the expand_fn
approach?
dev = deepcopy(dev)
original_expand_fn = dev.expand_fn
def expand_fn(self, circuit, **kwargs):
circuit = original_expand_fn(circuit, **kwargs)
return add_noise_to_tape(circuit, noisy_op, noisy_op_args, position)
dev.expand_fn = types.MethodType(expand_fn, dev)
return dev
Closing because superseded by #1813 |
Context:
The mitiq library recently merged-in support for input PennyLane tapes. This PR explores how this functionality can be wrapped to support a standard PennyLane workflow.
Description of the Change:
Adds a new
mitigate
module (+ making visible in documentation and an incomplete set of tests). The module contains:add_noise_to_tape()
andadd_noise_to_device()
transforms that allow for quick prototyping of noisy circuits without running on hardware (this could live in thetransforms
module)mitiq_interface()
function for wrapping standard functionality from themitiq
library (e.g.execute_with_zne
), allowing these functions to accept general PL tapes as input circuits and PL devices as executors.mitigate_device()
device transform that adds mitigation automatically to the device usingmitiq
as a backend.Example UI:
Here are some examples of how a user may interact with the
mitigate
module.Using mitigate_device
Using mitiq_interface
Benefits:
Mitigation is available within PennyLane, including for gradients.
Possible Drawbacks:
mitigate_device()
transform uses the mitiqexecute_with_*
function as a black box. We allowexecute_with_*
to handle the transformation of the circuit into multiple circuits (e.g. gate folding) and the composition of the execution results into a mitigated value (e.g. extrapolation). This allows us to be agnostic toward the mitigation method.Related PR:
supersedes #1183