mirror of https://github.com/fredrikekre/HYPRE.jl
Julia interface to hypre linear solvers (https://github.com/hypre-space/hypre)
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
97 lines
3.7 KiB
97 lines
3.7 KiB
module LibHYPRE |
|
|
|
using Libdl: dlsym |
|
|
|
# Clang.jl auto-generated bindings |
|
include("../lib/LibHYPRE.jl") |
|
|
|
# Add manual methods for some ::Function signatures where the library wants function |
|
# pointers. Instead of creating function pointers to the Julia wrappers we can just look |
|
# up the pointer in the library and pass that. |
|
# TODO: Maybe this can be done automatically as post-process pass in Clang.jl |
|
|
|
macro setprecond(fn) |
|
for idx in 3:4 |
|
fn.args[idx] = Expr(:(::), fn.args[idx], :Function) |
|
end |
|
block = quote |
|
precond_ptr = dlsym(HYPRE_jll.libHYPRE_handle, Symbol(precond)) |
|
precond_setup_ptr = dlsym(HYPRE_jll.libHYPRE_handle, Symbol(precond_setup)) |
|
return $(fn.args[1])(solver, precond_ptr, precond_setup_ptr, precond_solver) |
|
end |
|
r = Expr(:function, fn, block) |
|
return r |
|
end |
|
|
|
@setprecond HYPRE_BiCGSTABSetPrecond(solver, precond, precond_setup, precond_solver) |
|
# @setprecond HYPRE_CGNRSetPrecond(solver, precond, precondT, precond_setup, precond_solver) |
|
@setprecond HYPRE_COGMRESSetPrecond(solver, precond, precond_setup, precond_solver) |
|
@setprecond HYPRE_FlexGMRESSetPrecond(solver, precond, precond_setup, precond_solver) |
|
@setprecond HYPRE_GMRESSetPrecond(solver, precond, precond_setup, precond_solver) |
|
@setprecond HYPRE_LGMRESSetPrecond(solver, precond, precond_setup, precond_solver) |
|
@setprecond HYPRE_LOBPCGSetPrecond(solver, precond, precond_setup, precond_solver) |
|
@setprecond HYPRE_PCGSetPrecond(solver, precond, precond_setup, precond_solver) |
|
@setprecond HYPRE_ParCSRBiCGSTABSetPrecond(solver, precond, precond_setup, precond_solver) |
|
# @setprecond HYPRE_ParCSRCGNRSetPrecond(solver, precond, precondT, precond_setup, precond_solver) |
|
@setprecond HYPRE_ParCSRCOGMRESSetPrecond(solver, precond, precond_setup, precond_solver) |
|
@setprecond HYPRE_ParCSRFlexGMRESSetPrecond(solver, precond, precond_setup, precond_solver) |
|
@setprecond HYPRE_ParCSRGMRESSetPrecond(solver, precond, precond_setup, precond_solver) |
|
@setprecond HYPRE_ParCSRHybridSetPrecond(solver, precond, precond_setup, precond_solver) |
|
@setprecond HYPRE_ParCSRLGMRESSetPrecond(solver, precond, precond_setup, precond_solver) |
|
@setprecond HYPRE_ParCSRPCGSetPrecond(solver, precond, precond_setup, precond_solver) |
|
|
|
|
|
struct HYPREError <: Exception |
|
fn::Symbol |
|
ierr::HYPRE_Int |
|
end |
|
|
|
# See HYPRE_DescribeError(HYPRE_Int ierr, char *msg) |
|
function Base.showerror(io::IO, h::HYPREError) |
|
print(io, "LibHYPRE.$(h.fn) returned error code $(h.ierr):") |
|
if (h.ierr & HYPRE_ERROR_GENERIC) != 0 |
|
print(io, " [Generic error]") |
|
end |
|
if (h.ierr & HYPRE_ERROR_MEMORY) != 0 |
|
print(io, " [Memory error]") |
|
end |
|
if (h.ierr & HYPRE_ERROR_ARG) != 0 |
|
arg = h.ierr >> 3 & 31 # See HYPRE_GetErrorArg() |
|
print(io, " [Error in argument $arg]") |
|
end |
|
if (h.ierr & HYPRE_ERROR_CONV) != 0 |
|
print(io, " [Method did not converge]") |
|
end |
|
return nothing |
|
end |
|
|
|
# Macro for checking LibHYPRE return codes |
|
macro check(arg) |
|
Meta.isexpr(arg, :call) || throw(ArgumentError("wrong usage of @check")) |
|
return quote |
|
r = $(esc(arg)) |
|
if r != 0 |
|
# Since we throw here we can clear the errors (I think?) |
|
HYPRE_ClearAllErrors() |
|
throw(HYPREError($(QuoteNode(arg.args[1])), r)) |
|
end |
|
r |
|
end |
|
end |
|
|
|
# Export everything with HYPRE_ prefix |
|
for name in names(@__MODULE__; all=true) |
|
if startswith(string(name), "HYPRE_") |
|
@eval export $name |
|
end |
|
end |
|
|
|
function __init__() |
|
major_ref = Ref{HYPRE_Int}(-1) |
|
minor_ref = Ref{HYPRE_Int}(-1) |
|
patch_ref = Ref{HYPRE_Int}(-1) |
|
@check HYPRE_VersionNumber(major_ref, minor_ref, patch_ref, C_NULL) |
|
global VERSION = VersionNumber(major_ref[], minor_ref[], patch_ref[]) |
|
end |
|
|
|
end
|
|
|