Skip to content

Commit 9b3efc3

Browse files
authored
Merge branch 'main' into liouvillian2
2 parents 58409f6 + d33e88f commit 9b3efc3

File tree

7 files changed

+59
-11
lines changed

7 files changed

+59
-11
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased](https://github.com/qutip/QuantumToolbox.jl/tree/main)
99

10+
- Change default solver detection in `eigensolve` when using `sigma` keyword argument (shift-inverse algorithm). If the operator is a `SparseMatrixCSC`, the default solver is `UMFPACKFactorization`, otherwise it is automatically chosen by LinearSolve.jl, depending on the type of the operator. ([#580])
1011
- Generalize the definition of `liouvillian`. It no longer expects the Hamiltonian to be Hermitian. ([#581])
1112

1213
## [v0.38.1]
@@ -359,4 +360,5 @@ Release date: 2024-11-13
359360
[#575]: https://github.com/qutip/QuantumToolbox.jl/issues/575
360361
[#576]: https://github.com/qutip/QuantumToolbox.jl/issues/576
361362
[#579]: https://github.com/qutip/QuantumToolbox.jl/issues/579
363+
[#580]: https://github.com/qutip/QuantumToolbox.jl/issues/580
362364
[#581]: https://github.com/qutip/QuantumToolbox.jl/issues/581

src/QuantumToolbox.jl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import SciMLBase:
1515
remake,
1616
u_modified!,
1717
NullParameters,
18+
LinearProblem,
1819
ODEFunction,
1920
SDEFunction,
2021
ODEProblem,
@@ -46,7 +47,8 @@ import SciMLOperators:
4647
IdentityOperator,
4748
update_coefficients!,
4849
concretize
49-
import LinearSolve: LinearProblem, SciMLLinearSolveAlgorithm, KrylovJL_MINRES, KrylovJL_GMRES
50+
import LinearSolve:
51+
SciMLLinearSolveAlgorithm, KrylovJL_MINRES, KrylovJL_GMRES, UMFPACKFactorization, OperatorAssumptions
5052
import DiffEqBase: get_tstops
5153
import DiffEqCallbacks: PeriodicCallback, FunctionCallingCallback, FunctionCallingAffect, TerminateSteadyState
5254
import OrdinaryDiffEqCore: OrdinaryDiffEqAlgorithm

src/qobj/eigsolve.jl

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -352,10 +352,9 @@ function eigsolve(
352352
kwargs...,
353353
)
354354
T = eltype(A)
355-
isH = ishermitian(A)
356-
v0 === nothing && (v0 = normalize!(rand(T, size(A, 1))))
355+
isnothing(v0) && (v0 = normalize!(rand(T, size(A, 1))))
357356

358-
if sigma === nothing
357+
if isnothing(sigma)
359358
res = _eigsolve(
360359
A,
361360
v0,
@@ -371,17 +370,24 @@ function eigsolve(
371370
vals = res.values
372371
else
373372
Aₛ = A - sigma * I
374-
solver === nothing && (solver = isH ? KrylovJL_MINRES() : KrylovJL_GMRES())
375373

376374
kwargs2 = (; kwargs...)
377-
condition = !haskey(kwargs2, :Pl) && typeof(A) <: SparseMatrixCSC
378-
condition && (kwargs2 = merge(kwargs2, (Pl = ilu(Aₛ, τ = 0.01),)))
379375

380376
!haskey(kwargs2, :abstol) && (kwargs2 = merge(kwargs2, (abstol = tol * 1e-6,)))
381377
!haskey(kwargs2, :reltol) && (kwargs2 = merge(kwargs2, (reltol = tol * 1e-6,)))
378+
!haskey(kwargs2, :assumptions) && (kwargs2 = merge(kwargs2, (assumptions = OperatorAssumptions(true),)))
382379

383-
prob = LinearProblem(Aₛ, v0)
384-
linsolve = init(prob, solver; kwargs2...)
380+
prob = LinearProblem{true}(Aₛ, v0)
381+
382+
linsolve = if isnothing(solver)
383+
if typeof(A) <: SparseMatrixCSC && isprimitivetype(T)
384+
init(prob, UMFPACKFactorization(); kwargs2...)
385+
else
386+
init(prob; kwargs2...)
387+
end
388+
else
389+
init(prob, solver; kwargs2...)
390+
end
385391

386392
Amap = EigsolveInverseMap(T, size(A), linsolve)
387393

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
[deps]
22
GenericSchur = "c145ed77-6b09-5dd9-b285-bf645a82121e"
33
QuantumToolbox = "6c2fb7c5-b903-41d2-bc5e-5a7c320b9fab"
4+
Sparspak = "e56a9233-b9d6-4f03-8d0f-1825330902ac"

test/ext-test/gpu/Project.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
[deps]
22
CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba"
3+
CUDSS = "45b445bb-4962-46a0-9369-b4df9d0f772e"
4+
LinearSolve = "7ed4a6bd-45f5-4d41-b270-4a48e9bafcae"
35
QuantumToolbox = "6c2fb7c5-b903-41d2-bc5e-5a7c320b9fab"
46

57
[compat]
6-
CUDA = "5"
8+
CUDA = "5"

test/ext-test/gpu/cuda_ext.jl

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,3 +264,35 @@ end
264264
@inferred ptrace(ψ, 2)
265265
end
266266
end
267+
268+
@testset "CUDA eigsolve" begin
269+
N = 30
270+
Δ = 0.5
271+
U = 0.1
272+
κ = 0.1
273+
F = 0.5
274+
275+
a = destroy(N)
276+
H = Δ * a' * a + U / 2 * a' * a' * a * a + F * (a + a')
277+
278+
c_ops = [sqrt(κ) * a]
279+
280+
L = liouvillian(H, c_ops)
281+
L_gpu = CuSparseMatrixCSR(L)
282+
283+
vals_cpu, vecs_cpu = eigenstates(L; sparse = true, sigma = 0.01, eigvals = 4, krylovdim = 30)
284+
vals_gpu, vecs_gpu = eigenstates(
285+
L_gpu;
286+
sparse = true,
287+
sigma = 0.01,
288+
eigvals = 4,
289+
krylovdim = 30,
290+
solver = LUFactorization(),
291+
v0 = CUDA.rand(ComplexF64, size(L_gpu, 1)),
292+
)
293+
294+
@test vals_cpu vals_gpu atol = 1e-8
295+
@test all(zip(vecs_cpu, vecs_gpu)) do (v_cpu, v_gpu)
296+
return isapprox(abs(dot(v_cpu.data, Array(v_gpu.data))), 1; atol = 1e-8)
297+
end
298+
end

test/runtests.jl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,8 @@ if (GROUP == "CUDA_Ext")
7474
import StaticArraysCore: SVector
7575
using CUDA
7676
using CUDA.CUSPARSE
77-
# CUDA.allowscalar(false) # This is already set in the extension script
77+
using CUDSS
78+
using LinearSolve
7879

7980
QuantumToolbox.about()
8081
CUDA.versioninfo()
@@ -88,7 +89,9 @@ if (GROUP == "Arbitrary-Precision")
8889
Pkg.update()
8990

9091
using QuantumToolbox
92+
using LinearAlgebra
9193
using SparseArrays
94+
using Sparspak
9295
using GenericSchur
9396

9497
QuantumToolbox.about()

0 commit comments

Comments
 (0)