Skip to content

Commit 175a74f

Browse files
Merge pull request #506 from j-fu/pardiso-vendor
Allow to choose Pardiso vendor
2 parents 1f8eb0d + 0c0de1c commit 175a74f

File tree

5 files changed

+219
-121
lines changed

5 files changed

+219
-121
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ MPI = "0.20"
9696
Markdown = "1.10"
9797
Metal = "1"
9898
MultiFloats = "1"
99-
Pardiso = "0.5"
99+
Pardiso = "0.5.7"
100100
Pkg = "1"
101101
PrecompileTools = "1.2"
102102
Preferences = "1.4"

ext/LinearSolvePardisoExt.jl

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,26 +22,44 @@ function LinearSolve.init_cacheval(alg::PardisoJL,
2222
reltol,
2323
verbose::Bool,
2424
assumptions::LinearSolve.OperatorAssumptions)
25-
@unpack nprocs, solver_type, matrix_type, cache_analysis, iparm, dparm = alg
25+
@unpack nprocs, solver_type, matrix_type, cache_analysis, iparm, dparm, vendor = alg
2626
A = convert(AbstractMatrix, A)
2727

28+
if isnothing(vendor)
29+
if Pardiso.panua_is_available()
30+
vendor = :Panua
31+
else
32+
vendor = :MKL
33+
end
34+
end
35+
2836
transposed_iparm = 1
29-
solver = if Pardiso.PARDISO_LOADED[]
30-
solver = Pardiso.PardisoSolver()
31-
Pardiso.pardisoinit(solver)
32-
solver_type !== nothing && Pardiso.set_solver!(solver, solver_type)
37+
solver = if vendor == :MKL
38+
solver = if Pardiso.mkl_is_available()
39+
solver = Pardiso.MKLPardisoSolver()
40+
Pardiso.pardisoinit(solver)
41+
nprocs !== nothing && Pardiso.set_nprocs!(solver, nprocs)
3342

34-
solver
35-
else
36-
solver = Pardiso.MKLPardisoSolver()
37-
Pardiso.pardisoinit(solver)
38-
nprocs !== nothing && Pardiso.set_nprocs!(solver, nprocs)
43+
# for mkl 1 means conjugated and 2 means transposed.
44+
# https://www.intel.com/content/www/us/en/docs/onemkl/developer-reference-c/2024-0/pardiso-iparm-parameter.html#IPARM37
45+
transposed_iparm = 2
3946

40-
# for mkl 1 means conjugated and 2 means transposed.
41-
# https://www.intel.com/content/www/us/en/docs/onemkl/developer-reference-c/2024-0/pardiso-iparm-parameter.html#IPARM37
42-
transposed_iparm = 2
47+
solver
48+
else
49+
error("MKL Pardiso is not available. On MacOSX, possibly, try Panua Pardiso.")
50+
end
51+
elseif vendor == :Panua
52+
solver = if Pardiso.panua_is_available()
53+
solver = Pardiso.PardisoSolver()
54+
Pardiso.pardisoinit(solver)
55+
solver_type !== nothing && Pardiso.set_solver!(solver, solver_type)
4356

44-
solver
57+
solver
58+
else
59+
error("Panua Pardiso is not available.")
60+
end
61+
else
62+
error("Pardiso vendor must be either `:MKL` or `:Panua`")
4563
end
4664

4765
if matrix_type !== nothing
@@ -113,7 +131,6 @@ end
113131
function SciMLBase.solve!(cache::LinearSolve.LinearCache, alg::PardisoJL; kwargs...)
114132
@unpack A, b, u = cache
115133
A = convert(AbstractMatrix, A)
116-
117134
if cache.isfresh
118135
phase = alg.cache_analysis ? Pardiso.NUM_FACT : Pardiso.ANALYSIS_NUM_FACT
119136
Pardiso.set_phase!(cache.cacheval, phase)

src/LinearSolve.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,7 @@ export SimpleGMRES
253253
export HYPREAlgorithm
254254
export CudaOffloadFactorization
255255
export MKLPardisoFactorize, MKLPardisoIterate
256+
export PanuaPardisoFactorize, PanuaPardisoIterate
256257
export PardisoJL
257258
export MKLLUFactorization
258259
export AppleAccelerateLUFactorization

src/extension_algs.jl

Lines changed: 61 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ All values default to `nothing` and the solver internally determines the values
108108
given the input types, and these keyword arguments are only for overriding the
109109
default handling process. This should not be required by most users.
110110
"""
111-
MKLPardisoFactorize(; kwargs...) = PardisoJL(; solver_type = 0, kwargs...)
111+
MKLPardisoFactorize(; kwargs...) = PardisoJL(; vendor = :MKL, solver_type = 0, kwargs...)
112112

113113
"""
114114
```julia
@@ -136,19 +136,18 @@ All values default to `nothing` and the solver internally determines the values
136136
given the input types, and these keyword arguments are only for overriding the
137137
default handling process. This should not be required by most users.
138138
"""
139-
MKLPardisoIterate(; kwargs...) = PardisoJL(; solver_type = 1, kwargs...)
139+
MKLPardisoIterate(; kwargs...) = PardisoJL(; vendor = :MKL, solver_type = 1, kwargs...)
140140

141141
"""
142142
```julia
143-
PardisoJL(; nprocs::Union{Int, Nothing} = nothing,
144-
solver_type = nothing,
143+
PanuaPardisoFactorize(; nprocs::Union{Int, Nothing} = nothing,
145144
matrix_type = nothing,
146145
cache_analysis = false,
147146
iparm::Union{Vector{Tuple{Int, Int}}, Nothing} = nothing,
148147
dparm::Union{Vector{Tuple{Int, Int}}, Nothing} = nothing)
149148
```
150149
151-
A generic method using MKL Pardiso. Specifying `solver_type` is required.
150+
A sparse factorization method using Panua Pardiso.
152151
153152
!!! note
154153
@@ -165,20 +164,75 @@ All values default to `nothing` and the solver internally determines the values
165164
given the input types, and these keyword arguments are only for overriding the
166165
default handling process. This should not be required by most users.
167166
"""
167+
PanuaPardisoFactorize(; kwargs...) = PardisoJL(;
168+
vendor = :Panua, solver_type = 0, kwargs...)
169+
170+
"""
171+
```julia
172+
PanuaPardisoIterate(; nprocs::Union{Int, Nothing} = nothing,
173+
matrix_type = nothing,
174+
iparm::Union{Vector{Tuple{Int, Int}}, Nothing} = nothing,
175+
dparm::Union{Vector{Tuple{Int, Int}}, Nothing} = nothing)
176+
```
177+
178+
A mixed factorization+iterative method using Panua Pardiso.
179+
180+
!!! note
181+
182+
Using this solver requires adding the package Pardiso.jl, i.e. `using Pardiso`
183+
184+
## Keyword Arguments
185+
186+
For the definition of the keyword arguments, see the Pardiso.jl documentation.
187+
All values default to `nothing` and the solver internally determines the values
188+
given the input types, and these keyword arguments are only for overriding the
189+
default handling process. This should not be required by most users.
190+
"""
191+
PanuaPardisoIterate(; kwargs...) = PardisoJL(; vendor = :Panua, solver_type = 1, kwargs...)
192+
193+
"""
194+
```julia
195+
PardisoJL(; nprocs::Union{Int, Nothing} = nothing,
196+
solver_type = nothing,
197+
matrix_type = nothing,
198+
iparm::Union{Vector{Tuple{Int, Int}}, Nothing} = nothing,
199+
dparm::Union{Vector{Tuple{Int, Int}}, Nothing} = nothing,
200+
vendor::Union{Symbol, Nothing} = nothing
201+
)
202+
```
203+
204+
A generic method using Pardiso. Specifying `solver_type` is required.
205+
206+
!!! note
207+
208+
Using this solver requires adding the package Pardiso.jl, i.e. `using Pardiso`
209+
210+
## Keyword Arguments
211+
212+
The `vendor` keyword allows to choose between Panua pardiso (former pardiso-project.org; `vendor=:Panua`)
213+
and MKL Pardiso (`vendor=:MKL`). If `vendor==nothing`, Panua pardiso is preferred over MKL Pardiso.
214+
215+
For the definition of the other keyword arguments, see the Pardiso.jl documentation.
216+
All values default to `nothing` and the solver internally determines the values
217+
given the input types, and these keyword arguments are only for overriding the
218+
default handling process. This should not be required by most users.
219+
"""
168220
struct PardisoJL{T1, T2} <: LinearSolve.SciMLLinearSolveAlgorithm
169221
nprocs::Union{Int, Nothing}
170222
solver_type::T1
171223
matrix_type::T2
172224
cache_analysis::Bool
173225
iparm::Union{Vector{Tuple{Int, Int}}, Nothing}
174226
dparm::Union{Vector{Tuple{Int, Int}}, Nothing}
227+
vendor::Union{Symbol, Nothing}
175228

176229
function PardisoJL(; nprocs::Union{Int, Nothing} = nothing,
177230
solver_type = nothing,
178231
matrix_type = nothing,
179232
cache_analysis = false,
180233
iparm::Union{Vector{Tuple{Int, Int}}, Nothing} = nothing,
181-
dparm::Union{Vector{Tuple{Int, Float64}}, Nothing} = nothing)
234+
dparm::Union{Vector{Tuple{Int, Int}}, Nothing} = nothing,
235+
vendor::Union{Symbol, Nothing} = nothing)
182236
ext = Base.get_extension(@__MODULE__, :LinearSolvePardisoExt)
183237
if ext === nothing
184238
error("PardisoJL requires that Pardiso is loaded, i.e. `using Pardiso`")
@@ -188,7 +242,7 @@ struct PardisoJL{T1, T2} <: LinearSolve.SciMLLinearSolveAlgorithm
188242
@assert T1 <: Union{Int, Nothing, ext.Pardiso.Solver}
189243
@assert T2 <: Union{Int, Nothing, ext.Pardiso.MatrixType}
190244
return new{T1, T2}(
191-
nprocs, solver_type, matrix_type, cache_analysis, iparm, dparm)
245+
nprocs, solver_type, matrix_type, cache_analysis, iparm, dparm, vendor)
192246
end
193247
end
194248
end

0 commit comments

Comments
 (0)