Skip to content

Commit 035e85c

Browse files
authored
change: Add tests for complicated observables for OQ3, shots > 0 (#39)
* change: Add tests for complicated observables for OQ3, shots > 0 * fix: Don't run memory heavy tests on Ubuntu runners
1 parent 89be354 commit 035e85c

33 files changed

+3078
-861
lines changed

.github/workflows/CI.yml

+2
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ jobs:
4747
Pkg.Registry.update()
4848
- uses: julia-actions/julia-buildpkg@v1
4949
- uses: julia-actions/julia-runtest@v1
50+
env: # ubuntu-latest has too little memory
51+
BRAKET_SIM_LARGE_TESTS: ${{ matrix.os != 'ubuntu-latest'}}
5052
- uses: julia-actions/julia-processcoverage@v1
5153
- uses: codecov/codecov-action@v3
5254
with:

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@
33
*.jl.mem
44
lcov.info
55
*.profraw
6+
*.json
67
/Manifest.toml
78
/docs/Manifest.toml
89
/docs/build/
910
/.coverage
1011
.DS_Store
11-
*/.DS_Store
12+
*/.DS_Store

benchmark/gate_kernels.jl

+328
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,328 @@
1+
using BraketSimulator, PythonCall, BenchmarkTools
2+
3+
max_qubits(::Val{:noise}) = 5
4+
max_qubits(::Val{:pure}) = 10
5+
6+
gate_operations = pyimport("braket.default_simulator.gate_operations")
7+
noise_operations = pyimport("braket.default_simulator.noise_operations")
8+
local_sv = pyimport("braket.default_simulator.state_vector_simulation")
9+
local_dm = pyimport("braket.default_simulator.density_matrix_simulation")
10+
qml = pyimport("pennylane")
11+
np = pyimport("numpy")
12+
pnp = pyimport("pennylane.numpy")
13+
suite = BenchmarkGroup()
14+
suite["gates"] = BenchmarkGroup()
15+
suite["noise"] = BenchmarkGroup()
16+
for gate in [
17+
"H",
18+
"X",
19+
"Y",
20+
"Z",
21+
"V",
22+
"Vi",
23+
"T",
24+
"Ti",
25+
"S",
26+
"Si",
27+
"Rx",
28+
"Ry",
29+
"Rz",
30+
"GPi",
31+
"GPi2",
32+
"MS",
33+
"PhaseShift",
34+
"CNot",
35+
"CY",
36+
"CZ",
37+
"CV",
38+
"XX",
39+
"XY",
40+
"YY",
41+
"ZZ",
42+
"ECR",
43+
"Swap",
44+
"ISwap",
45+
"PSwap",
46+
"CCNot",
47+
"CSwap",
48+
"CPhaseShift",
49+
"CPhaseShift00",
50+
"CPhaseShift01",
51+
"CPhaseShift10",
52+
]
53+
suite["gates"][gate] = BenchmarkGroup()
54+
end
55+
for noise in [
56+
"BitFlip",
57+
"PhaseFlip",
58+
"Depolarizing",
59+
"PauliChannel",
60+
"AmplitudeDamping",
61+
"GeneralizedAmplitudeDamping",
62+
"PhaseDamping",
63+
"TwoQubitDepolarizing",
64+
"TwoQubitPauliChannel",
65+
"TwoQubitDephasing",
66+
"Kraus",
67+
]
68+
suite["noise"][noise] = BenchmarkGroup()
69+
end
70+
for n_qubits = 4:2:max_qubits(Val(:pure))
71+
n_amps = 2^n_qubits
72+
angle = π / 3.5
73+
angle2 = π / 5.2
74+
angle3 = π / 0.6
75+
for q in 0:0#n_qubits-1
76+
for (gate_str, gate, py_gate) in zip(
77+
["H", "X", "Y", "Z", "V", "Vi", "T", "Ti", "S", "Si"],
78+
[BraketSimulator.H(),
79+
BraketSimulator.X(),
80+
BraketSimulator.Y(),
81+
BraketSimulator.Z(),
82+
BraketSimulator.V(),
83+
BraketSimulator.Vi(),
84+
BraketSimulator.T(),
85+
BraketSimulator.Ti(),
86+
BraketSimulator.S(),
87+
BraketSimulator.Si(),
88+
],
89+
[
90+
[gate_operations.Hadamard([q])],
91+
[gate_operations.PauliX([q])],
92+
[gate_operations.PauliY([q])],
93+
[gate_operations.PauliZ([q])],
94+
[gate_operations.V([q])],
95+
[gate_operations.Vi([q])],
96+
[gate_operations.T([q])],
97+
[gate_operations.Ti([q])],
98+
[gate_operations.S([q])],
99+
[gate_operations.Si([q])],
100+
],
101+
)
102+
suite["gates"][gate_str][(string(n_qubits), string(q), "Julia")] =
103+
@benchmarkable BraketSimulator.apply_gate!($gate, sv, $q) setup =
104+
(sv = zeros(ComplexF64, $n_amps))
105+
suite["gates"][gate_str][(string(n_qubits), string(q), "BraketSV")] =
106+
@benchmarkable py_sv.evolve($py_gate) setup =
107+
(py_sv = local_sv.StateVectorSimulation($n_qubits, 0, 1))
108+
end
109+
for (gate_str, gate, py_gate) in zip(
110+
["Rx", "Ry", "Rz", "PhaseShift", "GPi", "GPi2"],
111+
[BraketSimulator.Rx(angle),
112+
BraketSimulator.Ry(angle),
113+
BraketSimulator.Rz(angle),
114+
BraketSimulator.PhaseShift(angle),
115+
BraketSimulator.GPi(angle),
116+
BraketSimulator.GPi2(angle),
117+
],
118+
[
119+
gate_operations.RotX([q], angle),
120+
gate_operations.RotY([q], angle),
121+
gate_operations.RotZ([q], angle),
122+
gate_operations.PhaseShift([q], angle),
123+
gate_operations.GPi([q], angle),
124+
gate_operations.GPi2([q], angle),
125+
],
126+
)
127+
suite["gates"][gate_str][(string(n_qubits), string(q), "Julia")] =
128+
@benchmarkable BraketSimulator.apply_gate!($gate, sv, $q) setup =
129+
(sv = zeros(ComplexF64, $n_amps))
130+
suite["gates"][gate_str][(string(n_qubits), string(q), "BraketSV")] =
131+
@benchmarkable py_sv.evolve([$py_gate]) setup =
132+
(py_sv = local_sv.StateVectorSimulation($n_qubits, 0, 1))
133+
end
134+
# do just one pair rather than setdiff(0:n_qubits-1, q)
135+
# to avoid redundancies (benchmark results shouldn't depend
136+
# on input qubits)
137+
for q2 in [mod(q+1, n_qubits)]
138+
for (gate_str, gate, py_gate) in zip(
139+
[
140+
"XX",
141+
"XY",
142+
"YY",
143+
"ZZ",
144+
"CPhaseShift",
145+
"CPhaseShift00",
146+
"CPhaseShift10",
147+
"CPhaseShift01",
148+
"PSwap",
149+
"MS",
150+
],
151+
[
152+
BraketSimulator.XX(angle),
153+
BraketSimulator.XY(angle),
154+
BraketSimulator.YY(angle),
155+
BraketSimulator.ZZ(angle),
156+
BraketSimulator.CPhaseShift(angle),
157+
BraketSimulator.CPhaseShift00(angle),
158+
BraketSimulator.CPhaseShift10(angle),
159+
BraketSimulator.CPhaseShift01(angle),
160+
BraketSimulator.PSwap(angle),
161+
BraketSimulator.MS(angle, angle2, angle3),
162+
],
163+
[
164+
gate_operations.XX([q, q2], angle),
165+
gate_operations.XY([q, q2], angle),
166+
gate_operations.YY([q, q2], angle),
167+
gate_operations.ZZ([q, q2], angle),
168+
gate_operations.CPhaseShift([q, q2], angle),
169+
gate_operations.CPhaseShift00([q, q2], angle),
170+
gate_operations.CPhaseShift10([q, q2], angle),
171+
gate_operations.CPhaseShift01([q, q2], angle),
172+
gate_operations.PSwap([q, q2], angle),
173+
gate_operations.MS([q, q2], angle, angle2, angle3),
174+
],
175+
)
176+
suite["gates"][gate_str][(string(n_qubits), string(q), string(q2), "Julia")] =
177+
@benchmarkable BraketSimulator.apply_gate!($gate, sv, $q, $q2) setup =
178+
(sv = zeros(ComplexF64, $n_amps))
179+
suite["gates"][gate_str][(string(n_qubits), string(q), string(q2), "BraketSV")] =
180+
@benchmarkable py_sv.evolve([$py_gate]) setup =
181+
(py_sv = local_sv.StateVectorSimulation($n_qubits, 0, 1))
182+
end
183+
for (gate_str, gate, py_gate) in zip(
184+
["CNot", "CY", "CZ", "CV", "Swap", "ISwap", "ECR"],
185+
[BraketSimulator.CNot(),
186+
BraketSimulator.CY(),
187+
BraketSimulator.CZ(),
188+
BraketSimulator.CV(),
189+
BraketSimulator.Swap(),
190+
BraketSimulator.ISwap(),
191+
BraketSimulator.ECR(),
192+
],
193+
[
194+
gate_operations.CX([q, q2]),
195+
gate_operations.CY([q, q2]),
196+
gate_operations.CZ([q, q2]),
197+
gate_operations.CV([q, q2]),
198+
gate_operations.Swap([q, q2]),
199+
gate_operations.ISwap([q, q2]),
200+
gate_operations.ECR([q, q2]),
201+
],
202+
)
203+
suite["gates"][gate_str][(string(n_qubits), string(q), string(q2), "Julia")] =
204+
@benchmarkable BraketSimulator.apply_gate!($gate, sv, $q, $q2) setup =
205+
(sv = zeros(ComplexF64, $n_amps))
206+
suite["gates"][gate_str][(string(n_qubits), string(q), string(q2), "BraketSV")] =
207+
@benchmarkable py_sv.evolve([$py_gate]) setup =
208+
(py_sv = local_sv.StateVectorSimulation($n_qubits, 0, 1))
209+
end
210+
# do just one pair rather than setdiff(0:n_qubits - 1, q, q2)
211+
# to avoid redundancies (benchmark results shouldn't depend
212+
# on input qubits)
213+
for q3 in [mod(q+2, n_qubits)]
214+
for (gate_str, gate, py_gate) in zip(
215+
["CCNot", "CSwap"],
216+
[BraketSimulator.CCNot(), BraketSimulator.CSwap()],
217+
[gate_operations.CCNot([q, q2, 2]), gate_operations.CSwap([q, q2, 2])],
218+
)
219+
suite["gates"][gate_str][(
220+
string(n_qubits),
221+
string(q),
222+
string(q2),
223+
string(q3),
224+
"Julia",
225+
)] = @benchmarkable BraketSimulator.apply_gate!($gate, sv, $q, $q2, $q3) setup =
226+
(sv = zeros(ComplexF64, $n_amps))
227+
suite["gates"][gate_str][(
228+
string(n_qubits),
229+
string(q),
230+
string(q2),
231+
string(q3),
232+
"BraketSV",
233+
)] = @benchmarkable py_sv.evolve([$py_gate]) setup =
234+
(py_sv = local_sv.StateVectorSimulation($n_qubits, 0, 1))
235+
end
236+
end
237+
end
238+
end
239+
end
240+
241+
for n_qubits = 2:2:max_qubits(Val(:noise))
242+
n_amps = 2^n_qubits
243+
prob = 0.1
244+
gamma = 0.2
245+
# do just qubit rather than 0:n_qubits - 1
246+
# to avoid redundancies
247+
for q in 0:0
248+
for (noise_str, noise, py_noise) in zip(
249+
["BitFlip", "PhaseFlip", "Depolarizing", "AmplitudeDamping", "PhaseDamping"],
250+
[
251+
BraketSimulator.BitFlip(prob),
252+
BraketSimulator.PhaseFlip(prob),
253+
BraketSimulator.Depolarizing(prob),
254+
BraketSimulator.AmplitudeDamping(prob),
255+
BraketSimulator.PhaseDamping(prob),
256+
],
257+
[
258+
noise_operations.BitFlip([q], prob),
259+
noise_operations.PhaseFlip([q], prob),
260+
noise_operations.Depolarizing([q], prob),
261+
noise_operations.AmplitudeDamping([q], prob),
262+
noise_operations.PhaseDamping([q], prob),
263+
],
264+
)
265+
suite["noise"][noise_str][(string(n_qubits), string(q), "Julia")] =
266+
@benchmarkable BraketSimulator.apply_noise!($noise, dm, $q) setup =
267+
(dm = zeros(ComplexF64, $n_amps, $n_amps))
268+
suite["noise"][noise_str][(string(n_qubits), string(q), "BraketSV")] =
269+
@benchmarkable py_sv.evolve([$py_noise]) setup =
270+
(py_sv = local_dm.DensityMatrixSimulation($n_qubits, 0))
271+
end
272+
# do just one pair rather than setdiff(0:n_qubits - 1, q, q2)
273+
# to avoid redundancies (benchmark results shouldn't depend
274+
# on input qubits)
275+
for q2 in [mod(q+1, n_qubits)]
276+
for (noise_str, noise, py_noise) in zip(
277+
["TwoQubitDepolarizing", "TwoQubitDephasing"],
278+
[BraketSimulator.TwoQubitDepolarizing(prob),
279+
BraketSimulator.TwoQubitDephasing(prob),
280+
],
281+
[
282+
noise_operations.TwoQubitDepolarizing([q, q2], prob),
283+
noise_operations.TwoQubitDephasing([q, q2], prob),
284+
],
285+
)
286+
suite["noise"][noise_str][(string(n_qubits), string(q), string(q2), "Julia")] =
287+
@benchmarkable BraketSimulator.apply_noise!($noise, dm, $q, $q2) setup =
288+
(dm = zeros(ComplexF64, $n_amps, $n_amps))
289+
suite["noise"][noise_str][(string(n_qubits), string(q), string(q2), "BraketSV")] =
290+
@benchmarkable py_sv.evolve([$py_noise]) setup =
291+
(py_sv = local_dm.DensityMatrixSimulation($n_qubits, 0))
292+
end
293+
end
294+
suite["noise"]["GeneralizedAmplitudeDamping"][(string(n_qubits), string(q), "Julia")] =
295+
@benchmarkable BraketSimulator.apply_noise!(
296+
BraketSimulator.GeneralizedAmplitudeDamping($prob, $gamma),
297+
dm,
298+
$q,
299+
) setup = (dm = zeros(ComplexF64, $n_amps, $n_amps))
300+
suite["noise"]["GeneralizedAmplitudeDamping"][(string(n_qubits), string(q), "BraketSV")] =
301+
@benchmarkable py_sv.evolve([
302+
noise_operations.GeneralizedAmplitudeDamping([$q], $prob, $gamma),
303+
]) setup = (py_sv = local_dm.DensityMatrixSimulation($n_qubits, 0))
304+
suite["noise"]["PauliChannel"][(string(n_qubits), string(q), "Julia")] =
305+
@benchmarkable BraketSimulator.apply_noise!(
306+
PauliChannel($prob, $gamma, 0.0),
307+
dm,
308+
$q,
309+
) setup = (dm = zeros(ComplexF64, $n_amps, $n_amps))
310+
suite["noise"]["PauliChannel"][(string(n_qubits), string(q), "BraketSV")] =
311+
@benchmarkable py_sv.evolve([
312+
noise_operations.PauliChannel(
313+
targets = [$q],
314+
probX = $prob,
315+
probY = $gamma,
316+
probZ = 0.0,
317+
),
318+
]) setup = (py_sv = local_dm.DensityMatrixSimulation($n_qubits, 0))
319+
end
320+
end
321+
# this is expensive! only do it if we're sure we need to regen parameters
322+
if !isfile("small_gate_kernel_params.json")
323+
tune!(suite; verbose=true)
324+
BenchmarkTools.save("small_gate_kernel_params.json", params(suite))
325+
end
326+
loadparams!(suite, BenchmarkTools.load("small_gate_kernel_params.json")[1], :evals, :samples);
327+
results = run(suite; verbose = true)
328+
BenchmarkTools.save("small_gate_kernel_results.json", results)

0 commit comments

Comments
 (0)