Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sundials ERROR: UndefVarError: LS not defined #431

Closed
briochemc opened this issue Nov 2, 2023 · 7 comments · Fixed by #439
Closed

Sundials ERROR: UndefVarError: LS not defined #431

briochemc opened this issue Nov 2, 2023 · 7 comments · Fixed by #439

Comments

@briochemc
Copy link
Contributor

Just tested solve(prob, KINSOL(;linear_solver=:GMRES)) on a simple problem and it threw:

ERROR: UndefVarError: `LS` not defined
Stacktrace:
  [1] ___kinsol(f::Function, y0::Vector{Float64}; userdata::Nothing, linear_solver::Symbol, jac_upper::Int64, jac_lower::Int64)
    @ Sundials ~/.julia/packages/Sundials/vGumE/src/simple.jl:15
@avik-pal
Copy link
Member

avik-pal commented Nov 2, 2023

if linear_solver == :Dense
A = Sundials.SUNDenseMatrix(length(y0), length(y0))
LS = Sundials.SUNLinSol_Dense(y0, A)
elseif linear_solver == :Band
A = Sundials.SUNBandMatrix(length(y0), jac_upper, jac_lower)
LS = Sundials.SUNLinSol_Band(y0, A)
end
flag = @checkflag Sundials.KINDlsSetLinearSolver(kmem, LS, A) true
seems like it doesn't have a case for GMRES. @ChrisRackauckas might be able to say more on this

@avik-pal
Copy link
Member

avik-pal commented Nov 2, 2023

On a sidenote, for most of our benchmarks we beat the nonlinear solver in Sundials by quite a margin.

@briochemc
Copy link
Contributor Author

if linear_solver == :Dense
A = Sundials.SUNDenseMatrix(length(y0), length(y0))
LS = Sundials.SUNLinSol_Dense(y0, A)
elseif linear_solver == :Band
A = Sundials.SUNBandMatrix(length(y0), jac_upper, jac_lower)
LS = Sundials.SUNLinSol_Band(y0, A)
end
flag = @checkflag Sundials.KINDlsSetLinearSolver(kmem, LS, A) true
seems like it doesn't have a case for GMRES. @ChrisRackauckas might be able to say more on this

FWIW, I tried :KLU and it threw the same error.

@briochemc
Copy link
Contributor Author

On a sidenote, for most of our benchmarks we beat the nonlinear solver in Sundials by quite a margin.

Do these benchmarks include KINSOL's GMRES or KLU?

@ChrisRackauckas
Copy link
Member

They do not yet, but it's not clear why that would change anything. As a quasi-Newton algorithm it would see less optimizations in the GMRES case, so that's a worst case scenario for it. With KLU it's still a non-globalizing method. See:

https://docs.sciml.ai/SciMLBenchmarksOutput/dev/NonlinearProblem/nonlinear_solver_23_tests/

See, the point is that it doesn't have a globalizing part (line search, trust region, etc.) and makes heavy convergence assumptions in a quasi-Newton form. So it's issue isn't speed (though it's not the fastest) as much as convergence. It only successfully solves 15 of the 23 test cases, while some of the native NonlinearSolve.jl algorithms are both faster and converge on all 23. From all of the testing we've been able to do, we have not seen KINSOL as competitive at all, so it effectively only exists as a benchmarking tool and not something we'd ever recommend in practice.

@ChrisRackauckas
Copy link
Member

But yes, if someone wants this, you just need to do

elseif LinearSolver == :Diagonal
nojacobian = false
flag = CVDiag(mem)
_A = nothing
_LS = nothing
elseif LinearSolver == :GMRES
LS = SUNLinSol_SPGMR(uvec, alg.prec_side, alg.krylov_dim)
_A = nothing
_LS = Sundials.LinSolHandle(LS, Sundials.SPGMR())
elseif LinearSolver == :FGMRES
LS = SUNLinSol_SPFGMR(uvec, alg.prec_side, alg.krylov_dim)
_A = nothing
_LS = LinSolHandle(LS, SPFGMR())
elseif LinearSolver == :BCG
LS = SUNLinSol_SPBCGS(uvec, alg.prec_side, alg.krylov_dim)
_A = nothing
_LS = LinSolHandle(LS, SPBCGS())
elseif LinearSolver == :PCG
LS = SUNLinSol_PCG(uvec, alg.prec_side, alg.krylov_dim)
_A = nothing
_LS = LinSolHandle(LS, PCG())
elseif LinearSolver == :TFQMR
LS = SUNLinSol_SPTFQMR(uvec, alg.prec_side, alg.krylov_dim)
_A = nothing
_LS = LinSolHandle(LS, PTFQMR())
elseif LinearSolver == :KLU
nojacobian = false
nnz = length(SparseArrays.nonzeros(prob.f.jac_prototype))
A = SUNSparseMatrix(length(uvec), length(uvec), nnz, CSC_MAT)
LS = SUNLinSol_KLU(uvec, A)
_A = MatrixHandle(A, SparseMatrix())
_LS = LinSolHandle(LS, KLU())
end
in the KINSOL setup code
if linear_solver == :Dense
A = Sundials.SUNDenseMatrix(length(y0), length(y0))
LS = Sundials.SUNLinSol_Dense(y0, A)
elseif linear_solver == :Band
A = Sundials.SUNBandMatrix(length(y0), jac_upper, jac_lower)
LS = Sundials.SUNLinSol_Band(y0, A)
end
flag = @checkflag Sundials.KINDlsSetLinearSolver(kmem, LS, A) true
. It would be easy to do, so it would be a nice contribution for someone to make at least so we can add GMRES and KLU to the benchmarks there, though since there isn't a globalizer in its method that wouldn't effect (improve) the convergence at all just performance in large-scale scenarios.

@ChrisRackauckas ChrisRackauckas transferred this issue from SciML/NonlinearSolve.jl Nov 2, 2023
@jguterl
Copy link

jguterl commented Nov 2, 2023 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants