Skip to content

Commit

Permalink
Interface Block-GMRES from Krylov.jl
Browse files Browse the repository at this point in the history
  • Loading branch information
amontoison committed Oct 28, 2024
1 parent afc7a12 commit 0920aec
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 36 deletions.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ IterativeSolvers = "0.9.3"
JET = "0.8.28, 0.9"
KLU = "0.6"
KernelAbstractions = "0.9.27"
Krylov = "0.9"
Krylov = "0.9.8"
KrylovKit = "0.8"
KrylovPreconditioners = "0.3"
LazyArrays = "1.8, 2"
Expand Down
23 changes: 20 additions & 3 deletions src/iterative_wrappers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,17 @@ function KrylovJL_GMRES(args...; kwargs...)
KrylovJL(args...; KrylovAlg = Krylov.gmres!, kwargs...)
end

"""
```julia
KrylovJL_BLOCK_GMRES(args...; gmres_restart = 0, window = 0, kwargs...)
```
A generic BLOCK-GMRES implementation for square non-Hermitian linear systems with multiple right-hand sides
"""
function KrylovJL_BLOCK_GMRES(args...; kwargs...)
KrylovJL(args...; KrylovAlg = Krylov.block_gmres!, kwargs...)
end

"""
```julia
KrylovJL_BICGSTAB(args...; kwargs...)
Expand Down Expand Up @@ -143,8 +154,10 @@ function get_KrylovJL_solver(KrylovAlg)
Krylov.CrmrSolver
elseif (KrylovAlg === Krylov.cg!)
Krylov.CgSolver
elseif (KrylovAlg === Krylov.cg_lanczos!)
elseif (KrylovAlg === Krylov.cg_lanczos_shift!)
Krylov.CgLanczosShiftSolver
elseif (KrylovAlg === Krylov.cgls_lanczos_shift!)
Krylov.CglsLanczosShiftSolver
elseif (KrylovAlg === Krylov.cgls!)
Krylov.CglsSolver
elseif (KrylovAlg === Krylov.cg_lanczos!)
Expand All @@ -163,6 +176,8 @@ function get_KrylovJL_solver(KrylovAlg)
Krylov.GpmrSolver
elseif (KrylovAlg === Krylov.fom!)
Krylov.FomSolver
elseif (KrylovAlg === Krylov.block_gmres!)
Krylov.BlockGmresSolver
else
error("Invalid Krylov method detected")
end
Expand All @@ -181,7 +196,8 @@ function init_cacheval(alg::KrylovJL, A, b, u, Pl, Pr, maxiters::Int, abstol, re
alg.KrylovAlg === Krylov.gmres! ||
alg.KrylovAlg === Krylov.fgmres! ||
alg.KrylovAlg === Krylov.gpmr! ||
alg.KrylovAlg === Krylov.fom!)
alg.KrylovAlg === Krylov.fom! ||
alg.KrylovAlg === Krylov.block_gmres!)
if A isa SparseMatrixCSC
KS(SparseMatrixCSC(0, 0, [1], Int[], eltype(A)[]), eltype(b)[], 1)
elseif A isa Matrix
Expand All @@ -206,7 +222,8 @@ function init_cacheval(alg::KrylovJL, A, b, u, Pl, Pr, maxiters::Int, abstol, re
alg.KrylovAlg === Krylov.gmres! ||
alg.KrylovAlg === Krylov.fgmres! ||
alg.KrylovAlg === Krylov.gpmr! ||
alg.KrylovAlg === Krylov.fom!)
alg.KrylovAlg === Krylov.fom! ||
alg.KrylovAlg === Krylov.block_gmres!)
KS(A, b, memory)
elseif (alg.KrylovAlg === Krylov.minres! ||
alg.KrylovAlg === Krylov.symmlq! ||
Expand Down
33 changes: 1 addition & 32 deletions src/simplegmres.jl
Original file line number Diff line number Diff line change
Expand Up @@ -88,38 +88,7 @@ function update_cacheval!(cache::LinearCache, cacheval::SimpleGMRESCache, name::
return cacheval
end

"""
(c, s, ρ) = _sym_givens(a, b)
Numerically stable symmetric Givens reflection.
Given `a` and `b` reals, return `(c, s, ρ)` such that
[ c s ] [ a ] = [ ρ ]
[ s -c ] [ b ] = [ 0 ].
"""
function _sym_givens(a::T, b::T) where {T <: AbstractFloat}
# This has taken from Krylov.jl
if b == 0
c = ifelse(a == 0, one(T), sign(a)) # In Julia, sign(0) = 0.
s = zero(T)
ρ = abs(a)
elseif a == 0
c = zero(T)
s = sign(b)
ρ = abs(b)
elseif abs(b) > abs(a)
t = a / b
s = sign(b) / sqrt(one(T) + t * t)
c = s * t
ρ = b / s # Computationally better than ρ = a / c since |c| ≤ |s|.
else
t = b / a
c = sign(a) / sqrt(one(T) + t * t)
s = c * t
ρ = a / c # Computationally better than ρ = b / s since |s| ≤ |c|
end
return (c, s, ρ)
end
_sym_givens(a::T, b::T) where {T <: AbstractFloat} = Krylov.sym_givens(a, b)

function _sym_givens!(c, s, R, nr::Int, inner_iter::Int, bsize::Int, Hbis)
if __is_extension_loaded(Val(:KernelAbstractions))
Expand Down

0 comments on commit 0920aec

Please sign in to comment.