Skip to content

Commit ece9b75

Browse files
Merge pull request #986 from ytdHuang/fix/cuda-cusolver
Support `CUDA v6`/`CUDSS v0.7` and use `cuSOLVER` as dependency instead of `CUDA`
2 parents 9ce30d4 + 9f47e68 commit ece9b75

8 files changed

Lines changed: 66 additions & 63 deletions

File tree

Project.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e"
3131
AlgebraicMultigrid = "2169fc97-5a83-5252-b627-83903c6c433c"
3232
BandedMatrices = "aae01518-5342-5314-be14-df237901396f"
3333
BlockDiagonals = "0a1fb500-61f7-11e9-3c65-f5ef3456f9f0"
34-
CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba"
34+
cuSOLVER = "887afef0-6a32-4de5-add4-7827692ba8fc"
3535
CUDSS = "45b445bb-4962-46a0-9369-b4df9d0f772e"
3636
CUSOLVERRF = "a8cc9031-bad2-4722-94f5-40deabb4245c"
3737
ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
@@ -66,7 +66,7 @@ LinearSolveAlgebraicMultigridExt = "AlgebraicMultigrid"
6666
LinearSolveBLISExt = ["blis_jll", "LAPACK_jll"]
6767
LinearSolveBandedMatricesExt = "BandedMatrices"
6868
LinearSolveBlockDiagonalsExt = "BlockDiagonals"
69-
LinearSolveCUDAExt = "CUDA"
69+
LinearSolveCUDAExt = ["cuSOLVER"]
7070
LinearSolveCUDSSExt = "CUDSS"
7171
LinearSolveCUSOLVERRFExt = ["CUSOLVERRF", "SparseArrays"]
7272
LinearSolveChainRulesCoreExt = "ChainRulesCore"
@@ -100,8 +100,8 @@ Aqua = "0.8"
100100
ArrayInterface = "7.19"
101101
BandedMatrices = "1.8"
102102
BlockDiagonals = "0.2"
103-
CUDA = "5.5, 6"
104-
CUDSS = "0.6.3, 0.7"
103+
cuSOLVER = "6"
104+
CUDSS = "0.7"
105105
CUSOLVERRF = "0.2.6"
106106
ChainRulesCore = "1.25.1"
107107
CliqueTrees = "1.13.1"

ext/LinearSolveCUDAExt.jl

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
module LinearSolveCUDAExt
22

3-
using CUDA
3+
using cuSOLVER
4+
CUDACore = cuSOLVER.CUDACore
5+
cuSPARSE = cuSOLVER.cuSPARSE
6+
47
using LinearSolve: LinearSolve, is_cusparse, defaultalg, cudss_loaded, DefaultLinearSolver,
58
DefaultAlgorithmChoice, ALREADY_WARNED_CUDSS, LinearCache,
69
needs_concrete_A,
@@ -11,20 +14,20 @@ using LinearSolve: LinearSolve, is_cusparse, defaultalg, cudss_loaded, DefaultLi
1114
using LinearSolve.LinearAlgebra, LinearSolve.SciMLBase, LinearSolve.ArrayInterface
1215
using SciMLBase: AbstractSciMLOperator
1316

14-
LinearSolve.usecuda(x::Nothing) = CUDA.functional()
17+
LinearSolve.usecuda(x::Nothing) = CUDACore.functional()
1518

1619
function LinearSolve.is_cusparse(
1720
A::Union{
18-
CUDA.CUSPARSE.CuSparseMatrixCSR, CUDA.CUSPARSE.CuSparseMatrixCSC,
21+
cuSPARSE.CuSparseMatrixCSR, cuSPARSE.CuSparseMatrixCSC,
1922
}
2023
)
2124
return true
2225
end
23-
LinearSolve.is_cusparse_csr(::CUDA.CUSPARSE.CuSparseMatrixCSR) = true
24-
LinearSolve.is_cusparse_csc(::CUDA.CUSPARSE.CuSparseMatrixCSC) = true
26+
LinearSolve.is_cusparse_csr(::cuSPARSE.CuSparseMatrixCSR) = true
27+
LinearSolve.is_cusparse_csc(::cuSPARSE.CuSparseMatrixCSC) = true
2528

2629
function LinearSolve.defaultalg(
27-
A::CUDA.CUSPARSE.CuSparseMatrixCSR{Tv, Ti}, b,
30+
A::cuSPARSE.CuSparseMatrixCSR{Tv, Ti}, b,
2831
assump::OperatorAssumptions{Bool}
2932
) where {Tv, Ti}
3033
return if LinearSolve.cudss_loaded(A)
@@ -39,7 +42,7 @@ function LinearSolve.defaultalg(
3942
end
4043

4144
function LinearSolve.defaultalg(
42-
A::CUDA.CUSPARSE.CuSparseMatrixCSC, b,
45+
A::cuSPARSE.CuSparseMatrixCSC, b,
4346
assump::OperatorAssumptions{Bool}
4447
)
4548
if LinearSolve.cudss_loaded(A)
@@ -50,7 +53,7 @@ function LinearSolve.defaultalg(
5053
return LinearSolve.DefaultLinearSolver(LinearSolve.DefaultAlgorithmChoice.KrylovJL_GMRES)
5154
end
5255

53-
function LinearSolve.error_no_cudss_lu(A::CUDA.CUSPARSE.CuSparseMatrixCSR)
56+
function LinearSolve.error_no_cudss_lu(A::cuSPARSE.CuSparseMatrixCSR)
5457
if !LinearSolve.cudss_loaded(A)
5558
error("CUDSS.jl is required for LU Factorizations on CuSparseMatrixCSR. Please load this library.")
5659
end
@@ -63,12 +66,12 @@ function SciMLBase.solve!(
6366
)
6467
if cache.isfresh
6568
cacheval = LinearSolve.@get_cacheval(cache, :CudaOffloadLUFactorization)
66-
fact = lu(CUDA.CuArray(cache.A))
69+
fact = lu(CUDACore.CuArray(cache.A))
6770
cache.cacheval = fact
6871
cache.isfresh = false
6972
end
7073
fact = LinearSolve.@get_cacheval(cache, :CudaOffloadLUFactorization)
71-
y = Array(ldiv!(CUDA.CuArray(cache.u), fact, CUDA.CuArray(cache.b)))
74+
y = Array(ldiv!(CUDACore.CuArray(cache.u), fact, CUDACore.CuArray(cache.b)))
7275
cache.u .= y
7376
return SciMLBase.build_linear_solution(alg, y, nothing, cache)
7477
end
@@ -79,28 +82,28 @@ function LinearSolve.init_cacheval(
7982
assumptions::OperatorAssumptions
8083
)
8184
# Check if CUDA is functional before creating CUDA arrays
82-
if !CUDA.functional()
85+
if !CUDACore.functional()
8386
return nothing
8487
end
8588

8689
T = eltype(A)
8790
noUnitT = typeof(zero(T))
8891
luT = LinearAlgebra.lutype(noUnitT)
89-
ipiv = CuVector{Int32}(undef, 0)
92+
ipiv = CUDACore.CuVector{Int32}(undef, 0)
9093
info = zero(LinearAlgebra.BlasInt)
91-
return LU{luT}(CuMatrix{Float64}(undef, 0, 0), ipiv, info)
94+
return LU{luT}(CUDACore.CuMatrix{Float64}(undef, 0, 0), ipiv, info)
9295
end
9396

9497
function SciMLBase.solve!(
9598
cache::LinearSolve.LinearCache, alg::CudaOffloadQRFactorization;
9699
kwargs...
97100
)
98101
if cache.isfresh
99-
fact = qr(CUDA.CuArray(cache.A))
102+
fact = qr(CUDACore.CuArray(cache.A))
100103
cache.cacheval = fact
101104
cache.isfresh = false
102105
end
103-
y = Array(ldiv!(CUDA.CuArray(cache.u), cache.cacheval, CUDA.CuArray(cache.b)))
106+
y = Array(ldiv!(CUDACore.CuArray(cache.u), cache.cacheval, CUDACore.CuArray(cache.b)))
104107
cache.u .= y
105108
return SciMLBase.build_linear_solution(alg, y, nothing, cache)
106109
end
@@ -111,11 +114,11 @@ function LinearSolve.init_cacheval(
111114
assumptions::OperatorAssumptions
112115
)
113116
# Check if CUDA is functional before creating CUDA arrays
114-
if !CUDA.functional()
117+
if !CUDACore.functional()
115118
return nothing
116119
end
117120

118-
return qr(CUDA.CuArray(A))
121+
return qr(CUDACore.CuArray(A))
119122
end
120123

121124
# Keep the deprecated CudaOffloadFactorization working by forwarding to QR
@@ -124,11 +127,11 @@ function SciMLBase.solve!(
124127
kwargs...
125128
)
126129
if cache.isfresh
127-
fact = qr(CUDA.CuArray(cache.A))
130+
fact = qr(CUDACore.CuArray(cache.A))
128131
cache.cacheval = fact
129132
cache.isfresh = false
130133
end
131-
y = Array(ldiv!(CUDA.CuArray(cache.u), cache.cacheval, CUDA.CuArray(cache.b)))
134+
y = Array(ldiv!(CUDACore.CuArray(cache.u), cache.cacheval, CUDACore.CuArray(cache.b)))
132135
cache.u .= y
133136
return SciMLBase.build_linear_solution(alg, y, nothing, cache)
134137
end
@@ -138,19 +141,19 @@ function LinearSolve.init_cacheval(
138141
maxiters::Int, abstol, reltol, verbose::Union{LinearVerbosity, Bool},
139142
assumptions::OperatorAssumptions
140143
)
141-
return qr(CUDA.CuArray(A))
144+
return qr(CUDACore.CuArray(A))
142145
end
143146

144147
for AlgType in (SparspakFactorization, LinearSolve.QRFactorization)
145148
@eval function LinearSolve.init_cacheval(
146-
::$AlgType, A::CUDA.CUSPARSE.CuSparseMatrixCSR, b, u,
149+
::$AlgType, A::cuSPARSE.CuSparseMatrixCSR, b, u,
147150
Pl, Pr, maxiters::Int, abstol, reltol,
148151
verbose::Union{LinearVerbosity, Bool}, assumptions::OperatorAssumptions
149152
)
150153
return nothing
151154
end
152155
@eval function LinearSolve.init_cacheval(
153-
::$AlgType, A::CUDA.CUSPARSE.CuSparseMatrixCSC, b, u,
156+
::$AlgType, A::cuSPARSE.CuSparseMatrixCSC, b, u,
154157
Pl, Pr, maxiters::Int, abstol, reltol,
155158
verbose::Union{LinearVerbosity, Bool}, assumptions::OperatorAssumptions
156159
)
@@ -159,14 +162,14 @@ for AlgType in (SparspakFactorization, LinearSolve.QRFactorization)
159162
end
160163

161164
function LinearSolve.init_cacheval(
162-
::KLUFactorization, A::CUDA.CUSPARSE.CuSparseMatrixCSR, b, u,
165+
::KLUFactorization, A::cuSPARSE.CuSparseMatrixCSR, b, u,
163166
Pl, Pr, maxiters::Int, abstol, reltol, verbose::Union{LinearVerbosity, Bool}, assumptions::OperatorAssumptions
164167
)
165168
return nothing
166169
end
167170

168171
function LinearSolve.init_cacheval(
169-
::UMFPACKFactorization, A::CUDA.CUSPARSE.CuSparseMatrixCSR, b, u,
172+
::UMFPACKFactorization, A::cuSPARSE.CuSparseMatrixCSR, b, u,
170173
Pl, Pr, maxiters::Int, abstol, reltol, verbose::Union{LinearVerbosity, Bool}, assumptions::OperatorAssumptions
171174
)
172175
return nothing

ext/LinearSolveCUDSSExt.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@ module LinearSolveCUDSSExt
33
using LinearSolve: LinearSolve, cudss_loaded
44
using CUDSS
55

6-
LinearSolve.cudss_loaded(A::CUDSS.CUDA.CUSPARSE.CuSparseMatrixCSR) = true
6+
LinearSolve.cudss_loaded(A::CUDSS.cuSPARSE.CuSparseMatrixCSR) = true
77

88
end

lib/LinearSolveAutotune/Project.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ LinearSolve = {path = "../.."}
1010
Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
1111
BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf"
1212
CPUSummary = "2a0fbf3d-bb9c-48f3-b0a9-814d99fd7ab9"
13-
CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba"
13+
cuSOLVER = "887afef0-6a32-4de5-add4-7827692ba8fc"
1414
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
1515
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
1616
FastLapackInterface = "29a986be-02c6-4525-aec4-84b980013641"
@@ -38,7 +38,7 @@ gh_cli_jll = "5d31d589-30fb-542f-b82d-10325e863e38"
3838
Base64 = "1"
3939
BenchmarkTools = "1"
4040
CPUSummary = "0.2"
41-
CUDA = "5"
41+
cuSOLVER = "6"
4242
DataFrames = "1"
4343
Dates = "1"
4444
FastLapackInterface = "2"

lib/LinearSolveAutotune/src/LinearSolveAutotune.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ using CPUSummary
3535
using RecursiveFactorization
3636
using blis_jll
3737
using LAPACK_jll
38-
using CUDA
38+
using cuSOLVER
3939
using Metal
4040
using FastLapackInterface
4141

lib/LinearSolveAutotune/src/gpu_detection.jl

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,18 @@ function is_cuda_available()
2020
if haskey(ENV, "CUDA_VISIBLE_DEVICES") ||
2121
(Sys.islinux() && isfile("/proc/driver/nvidia/version")) ||
2222
(Sys.iswindows() && success(`where nvidia-smi`))
23-
@warn "CUDA hardware may be available but CUDA.jl extension is not loaded. Consider adding `using CUDA` to enable GPU algorithms."
23+
@warn "CUDA hardware may be available but CUDA.jl extension is not loaded. Consider adding `using cuSOLVER` or `using CUDA` to enable GPU algorithms."
2424
end
2525
catch
2626
# Silently continue if detection fails
2727
end
2828
return false
2929
end
3030

31-
# Check if we have CUDA.jl loaded
31+
# Check if we have cuSOLVER.jl loaded
3232
try
33-
CUDA = Base.get_extension(LinearSolve, :LinearSolveCUDAExt).CUDA
34-
return CUDA.functional()
33+
cuSOLVER = Base.get_extension(LinearSolve, :LinearSolveCUDAExt).cuSOLVER
34+
return cuSOLVER.functional()
3535
catch
3636
return false
3737
end
@@ -86,38 +86,38 @@ function get_cuda_gpu_info()
8686
end
8787

8888
try
89-
# Get CUDA module from the extension
90-
CUDA = ext.CUDA
89+
# Get CUDACore module from the extension
90+
CUDACore = ext.CUDACore
9191

92-
# Check if CUDA is functional
93-
if !CUDA.functional()
92+
# Check if CUDACore is functional
93+
if !CUDACore.functional()
9494
return gpu_info
9595
end
9696

9797
# Get device information
98-
devices = collect(CUDA.devices())
98+
devices = collect(CUDACore.devices())
9999
num_devices = length(devices)
100100

101101
if num_devices > 0
102102
gpu_info["gpu_count"] = num_devices
103103

104104
# Get information from the first GPU
105105
first_device = devices[1]
106-
gpu_info["gpu_type"] = CUDA.name(first_device)
106+
gpu_info["gpu_type"] = CUDACore.name(first_device)
107107

108108
# Convert memory from bytes to GB
109-
total_mem_bytes = CUDA.totalmem(first_device)
109+
total_mem_bytes = CUDACore.totalmem(first_device)
110110
gpu_info["gpu_memory_gb"] = round(total_mem_bytes / (1024^3), digits = 2)
111111

112112
# Get compute capability
113-
capability = CUDA.capability(first_device)
113+
capability = CUDACore.capability(first_device)
114114
gpu_info["gpu_capability"] = "$(capability.major).$(capability.minor)"
115115

116116
# If multiple GPUs, list all types
117117
if num_devices > 1
118118
gpu_types = String[]
119119
for dev in devices
120-
push!(gpu_types, CUDA.name(dev))
120+
push!(gpu_types, CUDACore.name(dev))
121121
end
122122
gpu_info["gpu_types"] = unique(gpu_types)
123123
end
@@ -302,7 +302,7 @@ function get_package_versions()
302302
"LinearSolve",
303303
"LinearSolveAutotune",
304304
"RecursiveFactorization",
305-
"CUDA",
305+
"cuSOLVER",
306306
"Metal",
307307
"MKL_jll",
308308
"BLISBLAS",
@@ -626,9 +626,9 @@ function get_detailed_system_info()
626626
system_data["cuda_loaded"] = false
627627
system_data["metal_loaded"] = false
628628
try
629-
# Check if CUDA algorithms are actually available
629+
# Check if cuSOLVER (CUDA algorithms) are actually available
630630
if system_data["cuda_available"]
631-
system_data["cuda_loaded"] = isdefined(Main, :CUDA) || haskey(Base.loaded_modules, Base.PkgId(Base.UUID("052768ef-5323-5732-b1bb-66c8b64840ba"), "CUDA"))
631+
system_data["cuda_loaded"] = isdefined(Main, :cuSOLVER) || haskey(Base.loaded_modules, Base.PkgId(Base.UUID("887afef0-6a32-4de5-add4-7827692ba8fc"), "cuSOLVER"))
632632
end
633633
if system_data["metal_available"]
634634
system_data["metal_loaded"] = isdefined(Main, :Metal) || haskey(Base.loaded_modules, Base.PkgId(Base.UUID("dde4c033-4e86-420c-a63e-0dd931031962"), "Metal"))

test/gpu/Project.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
[deps]
22
BlockDiagonals = "0a1fb500-61f7-11e9-3c65-f5ef3456f9f0"
3-
CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba"
3+
CUDACore = "bd0ed864-bdfe-4181-a5ed-ce625a5fdea2"
4+
cuSPARSE = "b26da814-b3bc-49ef-b0ee-c816305aa060"
45
CUDSS = "45b445bb-4962-46a0-9369-b4df9d0f772e"
5-
CUSOLVERRF = "a8cc9031-bad2-4722-94f5-40deabb4245c"
6+
cuSOLVER = "887afef0-6a32-4de5-add4-7827692ba8fc"
67
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
78
LinearSolve = "7ed4a6bd-45f5-4d41-b270-4a48e9bafcae"
89
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
910
StableRNGs = "860ef19b-820b-49d6-a774-d7a799459cd3"
1011
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
11-

0 commit comments

Comments
 (0)