-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.jl
More file actions
107 lines (89 loc) · 2.62 KB
/
Copy pathmain.jl
File metadata and controls
107 lines (89 loc) · 2.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#=
OBJECTIVES
1. Define the data structure of the tableau
2. Initialize that tableau
3. Function to apply Hadamard Gate
4. Function to apply CNOT Gate
5. Initialize a zero state
6. Write a helper function to translate tableau to human readable form
7. Finally test things out and print the results
=#
using KernelAbstractions
using CUDA
include("src/tableau.jl")
include("src/utils.jl")
include("src/gates_cpu.jl")
include("src/gates_gpu.jl")
# ----- MAIN TEST -----
println("=== Bell State Circuit Test ===")
# Create 2-qubit tableau
tab = MiniTab(2)
# Initialize |00⟩
init_zero_state!(tab)
println("\nInitial state |00⟩:")
print_generators(tab)
# Apply H on qubit 1
apply_hadamard_gate!(tab, 1)
println("\nAfter H on qubit 1:")
print_generators(tab)
# Apply CNOT control=1 target=2
apply_CNOT_gate!(tab, 1, 2)
println("\nAfter CNOT(1→2):")
print_generators(tab)
println("\nExpected: g1=XX, g2=ZZ")
println("\n=== GPU Ensemble Test ===")
n_qubits = 2
n_tableaux = 10_000
nw = (n_qubits + 63) ÷ 64
# Build ensemble on CPU
xs_cpu = zeros(UInt64, nw, n_qubits, n_tableaux)
zs_cpu = zeros(UInt64, nw, n_qubits, n_tableaux)
# Initialize every tableau as |00⟩
for t in 1:n_tableaux
for i in 1:n_qubits
word = (i - 1) ÷ 64
shift = (i - 1) % 64
zs_cpu[word+1, i, t] = UInt64(1) << shift
end
end
# Apply H on qubit 1 — on CPU arrays, before GPU transfer
word_h = 0
shift_h = 0
mask_h = UInt64(1) << shift_h
for t in 1:n_tableaux
for i in 1:n_qubits
x_bit = (xs_cpu[word_h+1, i, t] >> shift_h) & UInt64(1)
z_bit = (zs_cpu[word_h+1, i, t] >> shift_h) & UInt64(1)
if x_bit != z_bit
xs_cpu[word_h+1, i, t] ⊻= mask_h
zs_cpu[word_h+1, i, t] ⊻= mask_h
end
end
end
# NOW move to GPU — everything is ready
xs_gpu = CuArray(xs_cpu)
zs_gpu = CuArray(zs_cpu)
# Launch CNOT kernel on GPU
backend = CUDABackend()
kernel = cnot_kernel!(backend, 256)
kernel(xs_gpu, zs_gpu, 1, 2, ndrange=n_tableaux)
KernelAbstractions.synchronize(backend)
# Copy one tableau back to verify
xs_check = Array(xs_gpu)
zs_check = Array(zs_gpu)
println("Verifying tableau 1 of $(n_tableaux):")
pauli = ['I', 'X', 'Z', 'Y']
for i in 1:n_qubits
gen_str = ""
for q in 1:n_qubits
word = (q-1) ÷ 64
shift = (q-1) % 64
x_bit = (xs_check[word+1, i, 1] >> shift) & UInt64(1)
z_bit = (zs_check[word+1, i, 1] >> shift) & UInt64(1)
index = Int(2 * z_bit + x_bit) + 1
gen_str *= pauli[index]
end
println("g$(i) = $(gen_str)")
end
println("Expected: g1=XX, g2=ZZ")
println("\n $(n_tableaux) Bell state circuits simulated in parallel on GPU")