Internals

These functions are for internal use for preparing IRs for simulation and validating properties to make sure all instructions and results are supported.

BraketSimulator._combine_operationsFunction
_combine_operations(program, shots::Int) -> Program

Combine explicit instructions and basis rotation instructions (if necessary). Validate that all operations are performed on qubits within qubit_count.

source
BraketSimulator._prepare_programFunction
_prepare_program(circuit_ir::OpenQasmProgram, inputs::Dict{String, <:Any}, shots::Int) -> (Program, Int)

Parse the OpenQASM3 source, apply any inputs provided for the simulation, and compute basis rotation instructions if running with non-zero shots. Return the Program after parsing and the qubit count of the circuit.

source
_prepare_program(circuit_ir::Program, inputs::Dict{String, <:Any}, shots::Int) -> (Program, Int)

Apply any inputs provided for the simulation. Return the Program (with bound parameters) and the qubit count of the circuit.

source
BraketSimulator._get_measured_qubitsFunction
_get_measured_qubits(program, qubit_count::Int) -> Vector{Int}

Get the qubits measured by the program. If Measure instructions are present in the program's instruction list, their targets are used to form the list of measured qubits. If not, all qubits from 0 to qubit_count-1 are measured.

source
BraketSimulator._compute_resultsFunction
_compute_results(::, simulator, program::Program, n_qubits::Int, shots::Int) -> Vector{ResultTypeValue}

Compute the results once simulator has finished applying all the instructions. The results depend on the IR type if shots>0:

  • For JAQCD IR (Program), the results array is empty because the Braket SDK computes the results from the IR directly.
  • For OpenQASM IR (OpenQasmProgram), the results array is empty only if no results are present in the parsed IR. Otherwise, the results array is populated with the parsed result types (to help the Braket SDK compute them from the sampled measurements) and a placeholder zero value.
source
BraketSimulator.flip_bitFunction
flip_bit(amp_index::Integer, bit::Integer)

Flip the bit-th bit of amp_index, so that 0 becomes 1 and 1 becomes 0. The first valid value of bit is zero.

Examples

julia> amp_index = 10
10

julia> digits(amp_index, base=2, pad=6)
6-element Vector{Int64}:
 0
 1
 0
 1
 0
 0

julia> amp_index = BraketSimulator.flip_bit(amp_index, 1)
8

julia> digits(amp_index, base=2, pad=6)
6-element Vector{Int64}:
 0
 0
 0
 1
 0
 0
source
BraketSimulator.flip_bitsFunction
flip_bits(amp_index::Integer, to_flip)

Flip the bit-th bit of amp_index for every bit in to_flip, so that 0 becomes 1 and 1 becomes 0. The first valid value of bit is zero.

Examples

julia> amp_index = 10
10

julia> digits(amp_index, base=2, pad=6)
6-element Vector{Int64}:
 0
 1
 0
 1
 0
 0

julia> amp_index = BraketSimulator.flip_bits(amp_index, (1, 3, 2))
4

julia> digits(amp_index, base=2, pad=6)
6-element Vector{Int64}:
 0
 0
 1
 0
 0
 0
source
BraketSimulator.pad_bitFunction
pad_bit(amp_index::Integer, bit::Integer)

Insert a 0 at location bit of amp_index (in its bits representation). The first valid value of bit is zero.

Examples

julia> amp_index = 10
10

julia> digits(amp_index, base=2, pad=6)
6-element Vector{Int64}:
 0
 1
 0
 1
 0
 0

julia> amp_index = BraketSimulator.pad_bit(amp_index, 2);

julia> digits(amp_index, base=2, pad=7)
7-element Vector{Int64}:
 0
 1
 0
 0
 1
 0
 0
source
BraketSimulator.pad_bitsFunction
pad_bits(amp_index::Integer, to_pad)

Insert a 0 in amp_index at each location bit in the collection to_pad. The first valid value of any bit is zero.

Examples

julia> amp_index = 10
10

julia> digits(amp_index, base=2, pad=6)
6-element Vector{Int64}:
 0
 1
 0
 1
 0
 0

julia> amp_index = BraketSimulator.pad_bits(amp_index, (2, 4));

julia> digits(amp_index, base=2, pad=8)
8-element Vector{Int64}:
 0
 1
 0
 0
 0
 1
 0
 0
Note

The indices in pad_bits aren't adjusted based on previous indices – this can be seen in the above example, where the bit at index 4 is different before and after inserting a bit at index 2.

source
BraketSimulator.endian_qubitsFunction
endian_qubits(n_qubits::Int, qubit::Int)

Rotate the qubit index qubit to match what Braket expects with the correct endianness. This has to be done because Braket and Julia have different endianness.

Note

The first valid value for qubit is zero, since qubits are zero-indexed.

Examples

julia> qubit = 2
2

julia> n_qubits = 5
5

julia> BraketSimulator.endian_qubits(n_qubits, qubit)
2

julia> qubit = 3
3

julia> BraketSimulator.endian_qubits(n_qubits, qubit)
1
source
endian_qubits(n_qubits::Int, qubits::Int...)

Rotate each qubit index in qubits to match what Braket expects with the correct endianness. This has to be done because Braket and Julia have different endianness.

Note

The first valid value for any element of qubits is zero, since qubits are zero-indexed.

source
BraketSimulator.get_amps_and_qubitsFunction
get_amps_and_qubits(state_vec::AbstractStateVector, qubits::Int...)

Get the total number of amplitudes of state_vec (its length) and use this to apply endian_qubits to qubits. This is a convenience function to automate several common operations.

Note

The first valid value for any element of qubits is zero, since qubits are zero-indexed.

source