Skip to content

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):

julia
function apply!(::MyBackend, ::H, position::Integer)
    # Backend-specific logic for applying a Hadamard gate
end

Example for a Parity Measurement (ZZ):

julia
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.

julia
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:

julia
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