Backend Interface
MonitoredQuantumCircuits.jl allows you to integrate additional backends, including simulators or quantum devices. To streamline this process, it is recommended to create a dedicated module for each backend and import the required methods and types from MonitoredQuantumCircuits.jl into the module’s namespace.
Create a Backend Type
Define a type MyBackend <: Simulator
if your backend is a simulator, or MyBackend <: QuantumComputer
if it represents a quantum device. This type primarily serves to dispatch the execute
function and does not require attributes unless necessary for your implementation.
Implement apply!
Methods
Define apply!
methods for every operation your backend supports. For instance:
Example for a Hadamard Operation (H
):
function apply!(::MyBackend, ::H, position::Integer)
# Backend-specific logic for applying a Hadamard gate
end
Example for a Parity Measurement (ZZ
):
function apply!(::MyBackend, ::ZZ, p1::Integer, p2::Integer)
# Backend-specific logic for applying a Z-basis parity measurement
end
You can add additional parameters to the apply!
method if required for specific operations.
Implement the execute!
Method
Define the execute!
method to manage execution, whether by simulation or interaction with a quantum device’s API.
function execute!(
circuit::F1, backend::MyBackend, post_processing::F2;
shots=1, kwargs...) where {F1<:Function,F2<:Function}
# Additional execution logic, if necessary
for i in 1:shots
# Additional execution logic, if necessary
circuit()
post_processing(i)
end
# Additional execution logic, if necessary
return backend
end
The execute!
function applies gates using the apply!
methods you have implemented.
Summary
Here is a complete example:
module MyBackendModule
import MonitoredQuantumCircuits: Simulator, apply!, execute!
struct MyBackend <: Simulator end
# Implement apply! methods
function apply!(::MyBackend, ::ZZ, p1::Integer, p2::Integer, p3::Integer)
# Logic for Z-basis parity measurement with p1, p2, and ancilla p3
end
# Implement execute
function execute!(
circuit::F1, ::MyBackend, post_processing::F2;
shots=1, kwargs...) where {F1<:Function,F2<:Function}
# Additional execution logic, if necessary
for i in 1:shots
# Additional execution logic, if necessary
circuit()
post_processing(i)
end
# Additional execution logic, if necessary
return backend
end