Skip to content

Commit 2efe7c3

Browse files
authored
feature: Add Reset, Barrier, Delay, and bump deps (#104)
* feature: Add Reset, Barrier, Delay, and bump deps * fix: Doc ref * fix: doctests * fix: More coverage * fix: even more tests for coverage
1 parent 81486d8 commit 2efe7c3

12 files changed

+197
-15
lines changed

.github/workflows/CI.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -170,5 +170,5 @@ jobs:
170170
run: |
171171
using Documenter: DocMeta, doctest
172172
using Braket
173-
DocMeta.setdocmeta!(Braket, :DocTestSetup, :(using Braket); recursive=true)
173+
DocMeta.setdocmeta!(Braket, :DocTestSetup, :(using Braket, Braket.Dates); recursive=true)
174174
doctest(Braket)

Project.toml

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "Braket"
22
uuid = "19504a0f-b47d-4348-9127-acc6cc69ef67"
33
authors = ["Katharine Hyatt <hyatkath@amazon.com>"]
4-
version = "0.9.4"
4+
version = "0.9.5"
55

66
[deps]
77
AWS = "fbe9abb3-538b-5e4e-ba9e-bc94f4f92ebc"
@@ -33,7 +33,7 @@ Tar = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e"
3333
UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"
3434

3535
[compat]
36-
AWS = "=1.91.0"
36+
AWS = "=1.92.0"
3737
AWSS3 = "=0.11.2"
3838
Aqua = "=0.8"
3939
AxisArrays = "=0.4.7"
@@ -50,20 +50,20 @@ Downloads = "1"
5050
Graphs = "=1.11.2"
5151
HTTP = "=1.10.8"
5252
InteractiveUtils = "1.6"
53-
JLD2 = "=0.4.51"
53+
JLD2 = "=0.5.4"
5454
JSON3 = "=1.14.0"
5555
LinearAlgebra = "1.6"
5656
Logging = "1.6"
5757
Markdown = "=0.7.5"
58-
Mocking = "=0.7.9"
58+
Mocking = "=0.8.1"
5959
NamedTupleTools = "=0.14.3"
6060
OrderedCollections = "=1.6.3"
6161
Pkg = "1.6"
6262
Random = "1.6"
6363
SparseArrays = "1.6"
6464
StaticArrays = "=1.9.7"
6565
Statistics = "1.6"
66-
StructTypes = "=1.10.0"
66+
StructTypes = "=1.11.0"
6767
Tar = "1.9.3"
6868
Test = "1.6"
6969
UUIDs = "1.6"

PyBraket/Project.toml

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "PyBraket"
22
uuid = "e85266a6-1825-490b-a80e-9b9469c53660"
33
authors = ["Katharine Hyatt <hyatkath@amazon.com>"]
4-
version = "0.9.4"
4+
version = "0.9.5"
55

66
[deps]
77
Braket = "19504a0f-b47d-4348-9127-acc6cc69ef67"
@@ -14,13 +14,13 @@ StructTypes = "856f2bd8-1eba-4b0a-8007-ebc267875bd4"
1414

1515
[compat]
1616
Aqua = "=0.8"
17-
Braket = "=0.9.4"
17+
Braket = "=0.9.5"
1818
CondaPkg = "=0.2.23"
1919
DataStructures = "=0.18.20"
2020
LinearAlgebra = "1.6"
2121
PythonCall = "=0.9.22"
2222
Statistics = "1"
23-
StructTypes = "=1.10.0"
23+
StructTypes = "=1.11.0"
2424
Test = "1.6"
2525
julia = "1.6"
2626

docs/make.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
push!(LOAD_PATH,"../src/")
22

3-
using Documenter, Braket
3+
using Documenter, Braket, Braket.Dates
44

55
makedocs(sitename="Braket.jl")
66

docs/src/circuits.md

+6
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,12 @@ qubits
4444
qubit_count
4545
measure
4646
Measure
47+
barrier
48+
Barrier
49+
reset(::Circuit, ::Any)
50+
Reset
51+
delay
52+
Delay
4753
```
4854

4955
## Output to IR

src/Braket.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export provider_name, properties, type
88
export apply_gate_noise!, apply
99
export logs, log_metric, metrics, @hybrid_job
1010
export depth, qubit_count, qubits, ir, IRType, OpenQASMSerializationProperties
11-
export OpenQasmProgram, Measure, measure
11+
export OpenQasmProgram, Measure, Reset, Barrier, Delay, measure, reset, barrier, delay
1212
export simulate
1313
export QueueDepthInfo, QueueType, Normal, Priority, queue_depth, queue_position
1414

src/circuit.jl

+65
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,71 @@ function measure(c::Circuit, target_qubits)
354354
return _add_measure!(c, target_qubits)
355355
end
356356

357+
"""
358+
reset(c::Circuit, target_qubits) -> Circuit
359+
360+
Add a [`Reset`](@ref) operator to `c`, performing an active reset to the `|0>` state on the targeted qubits.
361+
A `Reset` operation can be applied after a [`Measure`](@ref) to re-initialize the qubit and allow it to be reused
362+
after mid-circuit measurement.
363+
364+
# Examples
365+
```jldoctest
366+
julia> circ = Circuit([(H, 0), (CNot, 0, 1)]);
367+
368+
julia> circ = reset(circ, 0);
369+
370+
julia> circ.instructions
371+
3-element Vector{Braket.Instruction}:
372+
Braket.Instruction{H}(H(), QubitSet(0))
373+
Braket.Instruction{CNot}(CNot(), QubitSet(0, 1))
374+
Braket.Instruction{Reset}(Reset(), QubitSet(0))
375+
```
376+
"""
377+
Base.reset(c::Circuit, target_qubits) = (foreach(t->add_instruction!(c, Instruction(Reset(), t)), target_qubits); return c)
378+
379+
"""
380+
delay(c::Circuit, duration::Dates.Period, target_qubits) -> Circuit
381+
382+
Add a [`Delay`](@ref) operator to `c`, which forces all targeted qubits to wait for `duration`
383+
before any new operations may be applied to any of them.
384+
385+
# Examples
386+
```jldoctest
387+
julia> circ = Circuit([(H, 0), (CNot, 0, 1)]);
388+
389+
julia> circ = delay(circ, Nanosecond(10), [0, 1]);
390+
391+
julia> circ.instructions
392+
3-element Vector{Braket.Instruction}:
393+
Braket.Instruction{H}(H(), QubitSet(0))
394+
Braket.Instruction{CNot}(CNot(), QubitSet(0, 1))
395+
Braket.Instruction{Delay}(Delay(Nanosecond(10)), QubitSet(0, 1))
396+
```
397+
"""
398+
delay(c::Circuit, duration::Dates.Period, target_qubits) = (add_instruction!(c, Instruction(Delay(duration), target_qubits)); return c)
399+
# TODO enforce this in `Moments` as well
400+
401+
"""
402+
barrier(c::Circuit, target_qubits) -> Circuit
403+
404+
Add a [`Barrier`](@ref) operator to `c`, which forces all targeted qubits to reach the barrier before any new
405+
operations may be applied to any of them.
406+
407+
# Examples
408+
```jldoctest
409+
julia> circ = Circuit([(H, 0), (CNot, 0, 1)]);
410+
411+
julia> circ = barrier(circ, [0, 1]);
412+
413+
julia> circ.instructions
414+
3-element Vector{Braket.Instruction}:
415+
Braket.Instruction{H}(H(), QubitSet(0))
416+
Braket.Instruction{CNot}(CNot(), QubitSet(0, 1))
417+
Braket.Instruction{Barrier}(Barrier(), QubitSet(0, 1))
418+
```
419+
"""
420+
barrier(c::Circuit, target_qubits) = (add_instruction!(c, Instruction(Barrier(), target_qubits)); return c)
421+
357422
function openqasm_header(c::Circuit, sps::SerializationProperties=OpenQASMSerializationProperties())
358423
ir_instructions = ["OPENQASM 3.0;"]
359424
for p in sort(string.(c.parameters))

src/operators.jl

+52-4
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,7 @@ struct PauliEigenvalues{N}
3030
end
3131
PauliEigenvalues(::Val{N}, coeff::Float64=1.0) where {N} = PauliEigenvalues{N}(coeff)
3232
Base.length(p::PauliEigenvalues{N}) where {N} = 2^N
33-
function Base.iterate(p::PauliEigenvalues{N}, ix::Int=1) where {N}
34-
return ix <= length(p) ? (p[ix], ix+1) : nothing
35-
end
33+
Base.iterate(p::PauliEigenvalues{N}, ix::Int=1) where {N} = ix <= length(p) ? (p[ix], ix+1) : nothing
3634

3735
Base.getindex(p::PauliEigenvalues{1}, i::Int)::Float64 = getindex((p.coeff, -p.coeff), i)
3836
function Base.getindex(p::PauliEigenvalues{N}, i::Int)::Float64 where N
@@ -71,8 +69,9 @@ end
7169
Measure() = Measure(-1)
7270
Parametrizable(m::Measure) = NonParametrized()
7371
chars(::Type{Measure}) = ("M",)
74-
chars(m::Measure) = ("M",)
72+
chars(::Measure) = chars(Measure)
7573
qubit_count(::Type{Measure}) = 1
74+
qubit_count(::Measure) = qubit_count(Measure)
7675
ir(m::Measure, target::QubitSet, ::Val{:JAQCD}; kwargs...) = error("measure instructions are not supported with JAQCD.")
7776
function ir(m::Measure, target::QubitSet, ::Val{:OpenQASM}; serialization_properties=OpenQASMSerializationProperties())
7877
instructions = Vector{String}(undef, length(target))
@@ -83,3 +82,52 @@ function ir(m::Measure, target::QubitSet, ::Val{:OpenQASM}; serialization_proper
8382
end
8483
return join(instructions, "\n")
8584
end
85+
86+
"""
87+
Reset() <: QuantumOperator
88+
89+
Represents an active reset operation on targeted qubit.
90+
"""
91+
struct Reset <: QuantumOperator end
92+
Parametrizable(m::Reset) = NonParametrized()
93+
chars(::Type{Reset}) = ("Reset",)
94+
chars(::Reset) = chars(Reset)
95+
label(::Reset) = "reset"
96+
qubit_count(::Type{Reset}) = 1
97+
qubit_count(r::Reset) = qubit_count(Reset)
98+
99+
"""
100+
Barrier() <: QuantumOperator
101+
102+
Represents a barrier operation on targeted qubit.
103+
"""
104+
struct Barrier <: QuantumOperator end
105+
Parametrizable(b::Barrier) = NonParametrized()
106+
chars(::Type{Barrier}) = ("Barrier",)
107+
chars(r::Barrier) = chars(Barrier)
108+
label(::Barrier) = "barrier"
109+
qubit_count(::Type{Barrier}) = 1
110+
qubit_count(b::Barrier) = qubit_count(Barrier)
111+
112+
"""
113+
Delay(duration::Period) <: QuantumOperator
114+
115+
Represents a delay operation for `duration` on targeted qubit.
116+
"""
117+
struct Delay <: QuantumOperator
118+
duration::Dates.Period
119+
end
120+
Parametrizable(m::Delay) = NonParametrized()
121+
chars(d::Delay) = ("Delay($(label(d.duration)))",)
122+
label(d::Delay) = "delay[$(label(d.duration))]"
123+
qubit_count(::Type{Delay}) = 1
124+
qubit_count(d::Delay) = qubit_count(Delay)
125+
Base.:(==)(d1::Delay, d2::Delay) = d1.duration == d2.duration
126+
label(d::Microsecond) = "$(d.value)ms"
127+
label(d::Nanosecond) = "$(d.value)ns"
128+
label(d::Second) = "$(d.value)s"
129+
130+
ir(ix::Union{Reset, Barrier, Delay}, target::QubitSet, ::Val{:JAQCD}; kwargs...) = error("$(label(ix)) instructions are not supported with JAQCD.")
131+
function ir(ix::Union{Reset, Barrier, Delay}, target::QubitSet, v::Val{:OpenQASM}; serialization_properties=OpenQASMSerializationProperties())
132+
return join(("$(label(ix)) $(format_qubits(qubit, serialization_properties));" for qubit in target), "\n")
133+
end

test/circuit_timing.jl

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
using Braket, Braket.Dates, Test
2+
using Braket: Instruction, VIRTUAL, PHYSICAL, OpenQASMSerializationProperties
3+
4+
@testset "Barrier, reset, and delay operators" begin
5+
@test Barrier() isa Braket.QuantumOperator
6+
@test Reset() isa Braket.QuantumOperator
7+
@test Braket.Parametrizable(Reset()) == Braket.NonParametrized()
8+
@test Braket.Parametrizable(Barrier()) == Braket.NonParametrized()
9+
@test Braket.Parametrizable(Delay(Microsecond(200))) == Braket.NonParametrized()
10+
@test qubit_count(Reset()) == 1
11+
@test qubit_count(Barrier()) == 1
12+
circ = Circuit([(H, 0), (CNot, 0, 1)])
13+
circ = barrier(circ, 0)
14+
@test circ.instructions == [Instruction{H}(H(), QubitSet(0)), Instruction{CNot}(CNot(), QubitSet(0, 1)), Instruction{Barrier}(Barrier(), QubitSet(0))]
15+
circ = Circuit([(H, 0), (CNot, 0, 1)])
16+
circ = reset(circ, 0)
17+
@test circ.instructions == [Instruction{H}(H(), QubitSet(0)), Instruction{CNot}(CNot(), QubitSet(0, 1)), Instruction{Reset}(Reset(), QubitSet(0))]
18+
circ = Circuit([(H, 0), (CNot, 0, 1)])
19+
circ = delay(circ, Nanosecond(10), 0)
20+
@test circ.instructions == [Instruction{H}(H(), QubitSet(0)), Instruction{CNot}(CNot(), QubitSet(0, 1)), Instruction{Delay}(Delay(Nanosecond(10)), QubitSet(0))]
21+
@test qubit_count(Delay(Microsecond(200))) == 1
22+
@test Delay(Microsecond(200)) isa Braket.QuantumOperator
23+
@testset "Equality" for t in (Barrier, Reset)
24+
t1 = t()
25+
t2 = t()
26+
non_t = Measure()
27+
@test t1 == t2
28+
@test t1 != non_t
29+
end
30+
@test Delay(Nanosecond(10)) != Delay(Microsecond(10))
31+
@test Delay(Nanosecond(10_000)) == Delay(Microsecond(10))
32+
@test Braket.chars(Barrier()) == ("Barrier",)
33+
@test Braket.chars(Reset()) == ("Reset",)
34+
@test Braket.chars(Delay(Nanosecond(4))) == ("Delay(4ns)",)
35+
@test Braket.chars(Delay(Microsecond(4))) == ("Delay(4ms)",)
36+
@testset "To IR" for (t, str) in ((Barrier(), "barrier"),
37+
(Reset(), "reset"),
38+
(Delay(Second(1)), "delay[1s]"),
39+
)
40+
@testset "Invalid ir_type $ir_type" for (ir_type, message) in ((:JAQCD, "$str instructions are not supported with JAQCD."),
41+
)
42+
@test_throws ErrorException(message) ir(t, QubitSet([0]), Val(ir_type))
43+
end
44+
@testset "OpenQASM, target $target, serialization properties $sps" for (target, sps, expected_ir) in (
45+
([0], OpenQASMSerializationProperties(qubit_reference_type=VIRTUAL), "$str q[0];"),
46+
([4], OpenQASMSerializationProperties(qubit_reference_type=PHYSICAL), "$str \$4;"),
47+
)
48+
49+
50+
@test ir(Instruction(t, target), Val(:OpenQASM); serialization_properties=sps) == expected_ir
51+
end
52+
end
53+
end

test/measure.jl

+5
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ using Braket: Instruction, VIRTUAL, PHYSICAL, OpenQASMSerializationProperties
33

44
@testset "Measure operator" begin
55
@test Measure() isa Braket.QuantumOperator
6+
@test Braket.Parametrizable(Measure()) == Braket.NonParametrized()
7+
@test qubit_count(Measure()) == 1
68
@testset "Equality" begin
79
measure1 = Measure()
810
measure2 = Measure()
@@ -11,6 +13,9 @@ using Braket: Instruction, VIRTUAL, PHYSICAL, OpenQASMSerializationProperties
1113
@test measure1 != non_measure
1214
end
1315
@test Braket.chars(Measure()) == ("M",)
16+
circ = Circuit([(H, 0), (CNot, 0, 1)])
17+
circ = measure(circ, 0)
18+
@test circ.instructions == [Instruction{H}(H(), QubitSet(0)), Instruction{CNot}(CNot(), QubitSet(0, 1)), Instruction{Measure}(Measure(0), QubitSet(0))]
1419

1520
@testset "To IR" begin
1621
@testset "Invalid ir_type $ir_type" for (ir_type, message) in ((:JAQCD, "measure instructions are not supported with JAQCD."),

test/observables.jl

+4
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,12 @@ using LinearAlgebra: eigvals
66
Braket.IRType[] = :JAQCD
77
@testset "pauli eigenvalues" begin
88
z = [1.0 0.0; 0.0 -1.0]
9+
@test PauliEigenvalues(Val(1))[1] == 1.0
10+
@test PauliEigenvalues(Val(1))[2] == -1.0
11+
@test collect(PauliEigenvalues(Val(1))) == [1.0, -1.0]
912
for n in 2:6
1013
pe = PauliEigenvalues(Val(n))
14+
@test length(pe) == 2^n
1115
mat = kron(ntuple(i->diag(z), n)...)
1216
for ix in 1:2^n
1317
@test pe[ix] == mat[ix]

test/runtests.jl

+1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ for group in groups
5151
include("device.jl")
5252
include("circuits.jl")
5353
include("measure.jl")
54+
include("circuit_timing.jl")
5455
include("free_parameter.jl")
5556
include("gates.jl")
5657
include("observables.jl")

0 commit comments

Comments
 (0)