Skip to content

Commit 2de28b3

Browse files
authored
change: Add translation and tests for Braket circuit timing ops (#57)
1 parent 9319fcd commit 2de28b3

File tree

8 files changed

+49
-54
lines changed

8 files changed

+49
-54
lines changed

.github/workflows/CI.yml

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ jobs:
2626
version:
2727
- '1.9'
2828
- '1.10'
29+
- '1.11'
2930
- 'nightly'
3031
os:
3132
- ubuntu-latest

Project.toml

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "BraketSimulator"
22
uuid = "76d27892-9a0b-406c-98e4-7c178e9b3dff"
33
authors = ["Katharine Hyatt <hyatkath@amazon.com> and contributors"]
4-
version = "0.0.5"
4+
version = "0.0.6"
55

66
[deps]
77
AbstractTrees = "1520ce14-60c1-5f80-bbc7-55ef81b5835c"
@@ -30,7 +30,7 @@ BraketSimulatorBraketExt = "Braket"
3030
AbstractTrees = "=0.4.5"
3131
Aqua = "=0.8"
3232
Automa = "=1.0.4"
33-
Braket = "=0.9.4"
33+
Braket = "0.9.5"
3434
Combinatorics = "=1.0.2"
3535
DataStructures = "=0.18.20"
3636
Dates = "1.6"
@@ -45,7 +45,7 @@ PythonCall = "=0.9.23"
4545
Random = "1.6"
4646
StaticArrays = "1.9"
4747
StatsBase = "0.34"
48-
StructTypes = "=1.10.0"
48+
StructTypes = "=1.11.0"
4949
Test = "1.6"
5050
UUIDs = "1.6"
5151
julia = "1.9"

ext/BraketSimulatorBraketExt/BraketSimulatorBraketExt.jl

+9-3
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@ function Base.convert(::Type{Braket.GateModelTaskResult}, r::BraketSimulator.Gat
3030
addl_meta)
3131
end
3232

33-
Braket.qubit_count(o::O) where {O<:BraketSimulator.Operator} = BraketSimulator.qubit_count(o)
34-
Braket.qubit_count(o::O) where {O<:BraketSimulator.Observables.Observable} = BraketSimulator.qubit_count(o)
35-
Braket.qubit_count(::Type{O}) where {O<:BraketSimulator.Operator} = BraketSimulator.qubit_count(O)
33+
Braket.qubit_count(o::O) where {O<:BraketSimulator.Operator} = BraketSimulator.qubit_count(o)
34+
Braket.qubit_count(o::O) where {O<:BraketSimulator.Observables.Observable} = BraketSimulator.qubit_count(o)
35+
Braket.qubit_count(::Type{O}) where {O<:BraketSimulator.Operator} = BraketSimulator.qubit_count(O)
3636

3737
for (braket_sim, simulator_sym) in ((:(Braket.X), :(BraketSimulator.X)),
3838
(:(Braket.Y), :(BraketSimulator.Y)),
@@ -106,6 +106,12 @@ Base.convert(::Type{Braket.AbstractProgramResult}, rt::BraketSimulator.IR.Amplit
106106
Base.convert(::Type{BraketSimulator.AbstractProgramResult}, rt::Braket.IR.Amplitude) = BraketSimulator.IR.Amplitude(rt.states, rt.type)
107107
Base.convert(::Type{BraketSimulator.Operator}, m::Braket.Measure) = BraketSimulator.Measure(m.index)
108108
Base.convert(::Type{Braket.Operator}, m::BraketSimulator.Measure) = Braket.Measure(m.index)
109+
Base.convert(::Type{BraketSimulator.Operator}, ::Braket.Reset) = BraketSimulator.Reset()
110+
Base.convert(::Type{Braket.Operator}, ::BraketSimulator.Reset) = Braket.Reset()
111+
Base.convert(::Type{BraketSimulator.Operator}, ::Braket.Barrier) = BraketSimulator.Barrier()
112+
Base.convert(::Type{Braket.Operator}, ::BraketSimulator.Barrier) = Braket.Barrier()
113+
Base.convert(::Type{BraketSimulator.Operator}, d::Braket.Delay) = BraketSimulator.Delay(d.duration)
114+
Base.convert(::Type{Braket.Operator}, d::BraketSimulator.Delay) = Braket.Delay(d.duration)
109115

110116
Base.convert(::Type{BraketSimulator.Operator}, g::Braket.MS) = BraketSimulator.MS(ntuple(i->convert(Union{FreeParameter, Real}, g.angle[i]), 3))
111117
Base.convert(::Type{Braket.Operator}, g::BraketSimulator.MS) = Braket.MS(ntuple(i->convert(Union{Braket.FreeParameter, Real}, g.angle[i]), 3))

src/BraketSimulator.jl

+6-3
Original file line numberDiff line numberDiff line change
@@ -220,9 +220,12 @@ function _prepare_program(circuit_ir::Program, inputs::Dict{String, <:Any}, shot
220220
operations::Vector{Instruction} = circuit_ir.instructions
221221
symbol_inputs = Dict(Symbol(k) => v for (k, v) in inputs)
222222
operations = [bind_value!(operation, symbol_inputs) for operation in operations]
223-
qc = qubit_count(circuit_ir)
224-
bound_program = Program(circuit_ir.braketSchemaHeader, operations, circuit_ir.results, circuit_ir.basis_rotation_instructions)
225-
return bound_program, qc
223+
bound_program = Program(circuit_ir.braketSchemaHeader,
224+
operations,
225+
circuit_ir.results,
226+
circuit_ir.basis_rotation_instructions,
227+
)
228+
return bound_program, qubit_count(circuit_ir)
226229
end
227230
"""
228231
_combine_operations(program, shots::Int) -> Program

src/operators.jl

+23-42
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ Subtypes include [`Gate`](@ref), [`Noise`](@ref), [`Observable`](@ref BraketSimu
66
"""
77
abstract type Operator end
88

9+
abstract type Parametrizable end
10+
struct Parametrized end
11+
struct NonParametrized end
12+
913
"""
1014
QuantumOperator < Operator
1115
@@ -15,28 +19,20 @@ Subtypes include [`Gate`](@ref) and [`Noise`](@ref).
1519
abstract type QuantumOperator <: Operator end
1620
StructTypes.StructType(::Type{QuantumOperator}) = StructTypes.AbstractType()
1721
StructTypes.subtypes(::Type{QuantumOperator}) = (h=H, i=I, x=X, y=Y, z=Z, s=S, si=Si, t=T, ti=Ti, v=V, vi=Vi, cnot=CNot, swap=Swap, iswap=ISwap, cv=CV, cy=CY, cz=CZ, ecr=ECR, ccnot=CCNot, cswap=CSwap, unitary=Unitary, rx=Rx, ry=Ry, rz=Rz, phaseshift=PhaseShift, pswap=PSwap, xy=XY, cphaseshift=CPhaseShift, cphaseshift00=CPhaseShift00, cphaseshift01=CPhaseShift01, cphaseshift10=CPhaseShift10, xx=XX, yy=YY, zz=ZZ, gpi=GPi, gpi2=GPi2, ms=MS, prx=PRx, u=U, gphase=GPhase, kraus=Kraus, bit_flip=BitFlip, phase_flip=PhaseFlip, pauli_channel=PauliChannel, amplitude_damping=AmplitudeDamping, phase_damping=PhaseDamping, depolarizing=Depolarizing, two_qubit_dephasing=TwoQubitDephasing, two_qubit_depolarizing=TwoQubitDepolarizing, generalized_amplitude_damping=GeneralizedAmplitudeDamping, multi_qubit_pauli_channel=MultiQubitPauliChannel, measure=Measure, reset=Reset, barrier=Barrier, delay=Delay)
18-
19-
20-
abstract type Parametrizable end
21-
struct Parametrized end
22-
struct NonParametrized end
22+
parameters(::QuantumOperator) = FreeParameter[]
2323

2424
struct PauliEigenvalues{N}
2525
coeff::Float64
2626
PauliEigenvalues{N}(coeff::Float64=1.0) where {N} = new(coeff)
2727
end
2828
PauliEigenvalues(::Val{N}, coeff::Float64=1.0) where {N} = PauliEigenvalues{N}(coeff)
29-
Base.length(p::PauliEigenvalues{N}) where {N} = 2^N
30-
function Base.iterate(p::PauliEigenvalues{N}, ix::Int=1) where {N}
31-
return ix <= length(p) ? (p[ix], ix+1) : nothing
32-
end
33-
29+
Base.length(::PauliEigenvalues{N}) where {N} = 2^N
30+
Base.iterate(p::PauliEigenvalues{N}, ix::Int=1) where {N} = ix <= length(p) ? (p[ix], ix+1) : nothing
3431
Base.getindex(p::PauliEigenvalues{1}, i::Int)::Float64 = getindex((p.coeff, -p.coeff), i)
3532
function Base.getindex(p::PauliEigenvalues{N}, i::Int)::Float64 where N
3633
i_block = div(i-1, 2)
3734
split = div(2^(N-1)-1, 2)
3835
if N < 5
39-
total_evs = 2^N
4036
is_front = !isodd(mod(i-1, 2))
4137
ev = is_front ? p.coeff : -p.coeff
4238
mi = mod(i_block, 2)
@@ -57,8 +53,6 @@ function Base.getindex(p::PauliEigenvalues{N}, i::Int)::Float64 where N
5753
end
5854
Base.getindex(p::PauliEigenvalues{N}, ix::Vector{Int}) where {N} = [p[i] for i in ix]
5955

60-
parameters(o::QuantumOperator) = FreeParameter[]
61-
6256
"""
6357
Measure(index) <: QuantumOperator
6458
@@ -68,54 +62,41 @@ struct Measure <: QuantumOperator
6862
index::Int
6963
end
7064
Measure() = Measure(-1)
71-
Parametrizable(m::Measure) = NonParametrized()
72-
qubit_count(::Type{Measure}) = 1
73-
qubit_count(m::Measure) = qubit_count(Measure)
7465
StructTypes.constructfrom(::Type{Measure}, nt) = Measure()
7566

7667
"""
77-
Reset(index) <: QuantumOperator
68+
Reset() <: QuantumOperator
7869
79-
Represents an active reset operation on targeted qubit, stored in the classical register at `index`.
70+
Represents an active reset operation on targeted qubit.
8071
For now, this is a no-op.
8172
"""
82-
struct Reset <: QuantumOperator
83-
index::Int
84-
end
85-
Reset() = Reset(-1)
86-
Parametrizable(m::Reset) = NonParametrized()
87-
qubit_count(::Type{Reset}) = 1
88-
qubit_count(m::Reset) = qubit_count(Reset)
73+
struct Reset <: QuantumOperator end
8974
StructTypes.constructfrom(::Type{Reset}, nt) = Reset()
9075

9176
"""
92-
Barrier(index) <: QuantumOperator
77+
Barrier() <: QuantumOperator
9378
94-
Represents a barrier operation on targeted qubit, stored in the classical register at `index`.
79+
Represents a barrier operation on targeted qubit.
9580
For now, this is a no-op.
9681
"""
97-
struct Barrier <: QuantumOperator
98-
index::Int
99-
end
100-
Barrier() = Barrier(-1)
101-
Parametrizable(m::Barrier) = NonParametrized()
102-
qubit_count(::Type{Barrier}) = 1
103-
qubit_count(m::Barrier) = qubit_count(Barrier)
82+
struct Barrier <: QuantumOperator end
10483
StructTypes.constructfrom(::Type{Barrier}, nt) = Barrier()
10584

10685
"""
107-
Delay(index, duration::Time) <: QuantumOperator
86+
Delay(duration::Time) <: QuantumOperator
10887
109-
Represents a delay operation for `duration` on targeted qubit,
110-
stored in the classical register at `index`.
88+
Represents a delay operation for `duration` on targeted qubit.
11189
For now, this is a no-op.
11290
"""
11391
struct Delay <: QuantumOperator
114-
index::Int
11592
duration::Dates.Period
11693
end
117-
Delay(duration::Dates.Period) = Delay(-1, duration)
118-
Parametrizable(m::Delay) = NonParametrized()
119-
qubit_count(::Type{Delay}) = 1
120-
qubit_count(m::Delay) = qubit_count(Delay)
12194
StructTypes.constructfrom(::Type{Delay}, nt) = Delay(only(nt.arguments))
95+
96+
for T in (:Barrier, :Reset, :Delay, :Measure)
97+
@eval begin
98+
qubit_count(::Type{$T}) = 1
99+
qubit_count(o::$T) = qubit_count($T)
100+
Parametrizable(::$T) = NonParametrized()
101+
end
102+
end

test/test_braket_integration.jl

+3
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ end
2929

3030
@testset "Type conversions" begin
3131
@test convert(Braket.Operator, convert(BraketSimulator.Operator, Braket.Measure(2))) == Braket.Measure(2)
32+
@test convert(Braket.Operator, convert(BraketSimulator.Operator, Braket.Reset())) == Braket.Reset()
33+
@test convert(Braket.Operator, convert(BraketSimulator.Operator, Braket.Barrier())) == Braket.Barrier()
34+
@test convert(Braket.Operator, convert(BraketSimulator.Operator, Braket.Delay(Braket.Nanosecond(2)))) == Braket.Delay(Braket.Nanosecond(2))
3235
angle1 = 0.2
3336
angle2 = 0.1
3437
angle3 = π

test/test_operators.jl

+3-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ using BraketSimulator, BraketSimulator.Dates, Test
66
BraketSimulator.Barrier(),
77
BraketSimulator.Delay(Microsecond(200))
88
)
9-
@test BraketSimulator.qubit_count(op) == 1
10-
@test BraketSimulator.parameters(op) == BraketSimulator.FreeParameter[]
9+
@test BraketSimulator.qubit_count(op) == 1
10+
@test BraketSimulator.qubit_count(typeof(op)) == 1
11+
@test BraketSimulator.parameters(op) == BraketSimulator.FreeParameter[]
1112
end
1213
end

test/test_python_ext.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ using Test, JSON3, PythonCall, BraketSimulator
9898
@test result.resultTypes[1].type.type == "expectation"
9999
@test result.resultTypes[1].type.targets == [0]
100100
@test result.resultTypes[1].type.observable == ["z"]
101-
@test result.resultTypes[1].value == 0.0
101+
@test abs(result.resultTypes[1].value) 0.0 atol=eps(result.resultTypes[1].value)
102102

103103
simple_bell_qasm = """
104104
h \$0;

0 commit comments

Comments
 (0)