Local Simulators
Local simulators allow you to classically simulate your Circuit
or OpenQasmProgram
on local hardware, rather than sending it to the cloud for on-demand execution. Local simulators can run task batches in parallel using multithreading. Gate-based simulators are provided in the BraketSimulator.jl
package.
Developers wishing to implement their own LocalSimulator
should extend the simulate
function. New simulator backends must be subtypes of the AbstractLocalSimulator
type. Additionally, new simulators should "register" themselves in Braket._simulator_devices
in their parent module's __init__
function so that they can be referred to by name, like so:
module NewLocalSimulator
using Braket
struct NewSimulator <: Braket.AbstractLocalSimulator
# implementation of a new local simulator backend
# with name "new_simulator"
end
function Braket.simulate()
# simulation implementation here
end
function __init__()
Braket._simulator_devices[]["new_simulator"] = NewLocalSimulator()
end
end
Then users can use the new simulator like so:
using NewLocalSimulator, Braket
dev = LocalSimulator("new_simulator")
simulate(dev, task_specification, args...; kwargs...)
Braket._simulator_devices
— Constant_simulator_devices
A Ref{Dict}
which records the id
s of registered LocalSimulator
backends so that they can be retrieved by this id
. A new simulator backend should register itself in _simulator_devices
in its module's __init__
function.
Braket.LocalQuantumTask
— TypeLocalQuantumTask(id::String, result::Union{GateModelQuantumTaskResult, AnalogHamiltonianSimulationQuantumTaskResult})
A quantum task which has been run locally using a LocalSimulator
. The state
of a LocalQuantumTask
is always "COMPLETED"
as the task object is only created once the loca simulation has finished.
Braket.LocalQuantumTaskBatch
— TypeLocalQuantumTaskBatch(ids::Vector{String}, results::Vector{GateModelQuantumTaskResult})
A batch of quantum tasks which has been run locally using a LocalSimulator
.
Braket.LocalSimulator
— TypeLocalSimulator(backend::Union{String, AbstractBraketSimulator})
A quantum simulator which runs locally rather than sending the circuit(s) to the cloud to be executed on-demand. A LocalSimulator
must be created with a backend – either a handle, in the form of a String
, which uniquely identifies a simulator backend registered in _simulator_devices
, or an already instantiated simulator object.
LocalSimulator
s should implement their own method for simulate
if needed. They can process single tasks or task batches.
Braket.simulate
— Functionsimulate(d::LocalSimulator, task_spec::Union{Circuit, AbstractProgram}, args...; shots::Int=0, inputs::Dict{String, Float64} = Dict{String, Float64}(), kwargs...)
Simulate the execution of task_spec
using the backend of `LocalSimulator d
. args
are additional arguments to be provided to the backend. inputs
is used to set the value of any FreeParameter
in task_spec
and will override the existing inputs
field of an OpenQasmProgram
. Other kwargs
will be passed to the backend simulator. Returns a LocalQuantumTask
.
simulate(d::LocalSimulator, task_specs::Vector{T}, args...; kwargs...) where {T}
Simulate the execution of a batch of tasks specified by task_specs
using the backend of `LocalSimulator d
. args
are additional arguments to be provided to the backend.
kwargs
used by the LocalSimulator
are:
shots::Int
- the number of shots to run for all tasks intask_specs
. Default is0
.max_parallel::Int
- the maximum number of simulations to execute simultaneously. Default is32
.inputs::Union{Vector{Dict{String, Float64}}, Dict{String, Float64}}
- used to set the value of anyFreeParameter
in each task specification. It must either be aDict
or a single-elementVector
(in which case the same parameter values are used for all elements oftask_specs
or of the same length astask_specs
(in which case thei
-th specification is paired with thei
-th input dictionary). Default is an empty dictionary.
Other kwargs
are passed through to the backend simulator. Returns a LocalQuantumTaskBatch
.
Because Julia uses dynamic threading and Task
s can migrate between threads, each simulation is a Task
which itself can spawn many more Task
s, as the internal implementation of LocalSimulator
's backend may use threading where appropriate. On systems with many CPU cores, spawning too many Task
s may overwhelm the Julia scheduler and degrade performance. "Too many" depends on the particulars of your hardware, so on many-core systems you may need to tune this value for best performance.