Skip to content

Commit 82e6c27

Browse files
committed
add CUDA steadystate_fourier test
1 parent e2bb0be commit 82e6c27

File tree

4 files changed

+40
-15
lines changed

4 files changed

+40
-15
lines changed

ext/QuantumToolboxCUDAExt.jl

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@ module QuantumToolboxCUDAExt
22

33
using QuantumToolbox
44
using QuantumToolbox: makeVal, getVal
5-
import QuantumToolbox: _sparse_similar, _convert_eltype_wordsize
6-
import CUDA: cu, CuArray, allowscalar
5+
import QuantumToolbox: _sparse_similar, _convert_eltype_wordsize, _safe_setindex!
6+
import CUDA: cu, CuArray, allowscalar, @allowscalar, has_cuda
77
import CUDA.CUSPARSE: CuSparseVector, CuSparseMatrixCSC, CuSparseMatrixCSR, AbstractCuSparseArray
88
import SparseArrays: SparseVector, SparseMatrixCSC, sparse
99
import CUDA.Adapt: adapt
1010

11+
export _safe_setindex!
12+
1113
allowscalar(false)
1214

1315
@doc raw"""
@@ -108,10 +110,17 @@ function QuantumToolbox._sparse_similar(A::CuSparseMatrixCSC, rows, cols, vals,
108110
cpu_sparse = sparse(rows, cols, vals, m, n)
109111
return CuSparseMatrixCSC(cpu_sparse)
110112
end
111-
112113
function QuantumToolbox._sparse_similar(A::CuSparseMatrixCSR, rows, cols, vals, m::Int64, n::Int64)
113114
cpu_sparse = sparse(rows, cols, vals, m, n)
114115
return CuSparseMatrixCSR(cpu_sparse)
115116
end
116117

118+
function _safe_setindex!(A, val, idx)
119+
if has_cuda() && isa(A, CuArray)
120+
@allowscalar A[idx] = val
121+
else
122+
A[idx] = val
123+
end
124+
end
125+
117126
end

src/steadystate.jl

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -369,8 +369,7 @@ function _steadystate_fourier(
369369
n_fourier = 2 * n_max + 1
370370
n_list = (-n_max):n_max
371371

372-
# Create arrays with proper GPU/CPU backend
373-
weight = one(T)
372+
weight = 1
374373
rows = _dense_similar(L_0_mat, Ns)
375374
cols = _dense_similar(L_0_mat, Ns)
376375
vals = _dense_similar(L_0_mat, Ns)
@@ -382,7 +381,6 @@ function _steadystate_fourier(
382381
Mn = _sparse_similar(L_0_mat, rows, cols, vals, N, N)
383382
L = L_0_mat + Mn
384383

385-
# Initialize the big matrix M with proper backend
386384
M = _sparse_similar(L_0_mat, n_fourier * N, n_fourier * N)
387385

388386
# Add superdiagonal blocks (L_m)
@@ -391,7 +389,7 @@ function _steadystate_fourier(
391389
cols_block = _dense_similar(L_0_mat, N)
392390
fill!(rows_block, i)
393391
fill!(cols_block, i+1)
394-
block = _sparse_similar(L_0_mat, rows_block, cols_block, ones(T, N), n_fourier, n_fourier)
392+
block = _sparse_similar(L_0_mat, rows_block, cols_block, ones(N), n_fourier, n_fourier)
395393
M += kron(block, L_m_mat)
396394
end
397395

@@ -401,7 +399,7 @@ function _steadystate_fourier(
401399
cols_block = _dense_similar(L_0_mat, N)
402400
fill!(rows_block, i+1)
403401
fill!(cols_block, i)
404-
block = _sparse_similar(L_0_mat, rows_block, cols_block, ones(T, N), n_fourier, n_fourier)
402+
block = _sparse_similar(L_0_mat, rows_block, cols_block, ones(N), n_fourier, n_fourier)
405403
M += kron(block, L_p_mat)
406404
end
407405

@@ -413,16 +411,14 @@ function _steadystate_fourier(
413411
cols_block = _dense_similar(L_0_mat, N)
414412
fill!(rows_block, i)
415413
fill!(cols_block, i)
416-
block = _sparse_similar(L_0_mat, rows_block, cols_block, ones(T, N), n_fourier, n_fourier)
414+
block = _sparse_similar(L_0_mat, rows_block, cols_block, ones(N), n_fourier, n_fourier)
417415
M += kron(block, block_diag)
418416
end
419417

420-
# Initialize solution vector with proper backend
421418
v0 = _dense_similar(L_0_mat, n_fourier * N)
422-
fill!(v0, zero(T))
423-
allowed_setindex!(v0, weight, n_max * N + 1)
419+
fill!(v0, 0)
420+
_safe_setindex!(v0, weight, n_max * N + 1)
424421

425-
# Prepare preconditioners if needed
426422
if !isnothing(solver.Pl)
427423
kwargs = merge((; kwargs...), (Pl = solver.Pl(M),))
428424
elseif isa(M, SparseMatrixCSC)
@@ -431,11 +427,9 @@ function _steadystate_fourier(
431427
!isnothing(solver.Pr) && (kwargs = merge((; kwargs...), (Pr = solver.Pr(M),)))
432428
kwargs = merge((abstol = tol, reltol = tol), kwargs)
433429

434-
# Solve the linear system
435430
prob = LinearProblem(M, v0)
436431
ρtot = solve(prob, solver.alg; kwargs...).u
437432

438-
# Extract results
439433
offset1 = n_max * N
440434
offset2 = (n_max + 1) * N
441435
ρ0 = reshape(ρtot[(offset1+1):offset2], Ns, Ns)

src/utilities.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ _dense_similar(A::AbstractSparseMatrix, args...) = similar(nonzeros(A), args...)
135135

136136
_sparse_similar(A::AbstractArray, args...) = sparse(args...)
137137
_sparse_similar(A::AbstractArray, m::Int, n::Int) = spzeros(eltype(A), m, n)
138+
function _safe_setindex! end
138139

139140
_Ginibre_ensemble(n::Int, rank::Int = n) = randn(ComplexF64, n, rank) / sqrt(n)
140141

test/ext-test/gpu/cuda_ext.jl

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,27 @@ end
154154
@test ρ_ss_cpu.data Array(ρ_ss_gpu_csr.data) atol = 1e-8 * length(ρ_ss_cpu)
155155
end
156156

157+
@testset "CUDA steadystate_fourier" begin
158+
N = 2
159+
ωd = 1.0
160+
n_max = 2
161+
H0 = cu(sigmaz())
162+
Hp = cu(sigmax())
163+
Hm = cu(sigmax())
164+
c_ops = [cu(sqrt(0.1) * sigmam())]
165+
ρ_list1 = steadystate_fourier(H0, Hp, Hm, ωd, c_ops; solver = SteadyStateLinearSolver(), n_max = n_max)
166+
ρ0 = steadystate_fourier(
167+
H0,
168+
Hp,
169+
Hm,
170+
ωd,
171+
c_ops;
172+
solver = SSFloquetEffectiveLiouvillian(SteadyStateDirectSolver()),
173+
n_max = n_max,
174+
)
175+
@test isapprox(ρ0, ρ_list1[1]; atol = 1e-6)
176+
end
177+
157178
@testset "CUDA ptrace" begin
158179
g = fock(2, 1)
159180
e = fock(2, 0)

0 commit comments

Comments
 (0)