diff --git a/Project.toml b/Project.toml index 7a91244..fa6d2c1 100644 --- a/Project.toml +++ b/Project.toml @@ -5,4 +5,5 @@ version = "1.0.0" [deps] CEnum = "fa961155-64e5-5f13-b03f-caf6b980ea82" HYPRE_jll = "0a602bbd-b08b-5d75-8d32-0de6eef44785" +Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" MPI = "da04e1cc-30fd-572f-bb4f-1f8673147195" diff --git a/src/HYPRE.jl b/src/HYPRE.jl index 5b7debd..f6049bc 100644 --- a/src/HYPRE.jl +++ b/src/HYPRE.jl @@ -3,6 +3,56 @@ module HYPRE module LibHYPRE 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 + + import Libdl: dlsym + + function HYPRE_PCGSetPrecond(solver, precond::Function, precond_setup::Function, precond_solver) + precond_ptr = dlsym(HYPRE_jll.libHYPRE_handle, Symbol(precond)) + precond_setup_ptr = dlsym(HYPRE_jll.libHYPRE_handle, Symbol(precond_setup)) + return HYPRE_PCGSetPrecond(solver, precond_ptr, precond_setup_ptr, precond_solver) + end + function HYPRE_GMRESSetPrecond(solver, precond::Function, precond_setup::Function, precond_solver) + precond_ptr = dlsym(HYPRE_jll.libHYPRE_handle, Symbol(precond)) + precond_setup_ptr = dlsym(HYPRE_jll.libHYPRE_handle, Symbol(precond_setup)) + return HYPRE_GMRESSetPrecond(solver, precond_ptr, precond_setup_ptr, precond_solver) + end + function HYPRE_FlexGMRESSetPrecond(solver, precond::Function, precond_setup::Function, precond_solver) + precond_ptr = dlsym(HYPRE_jll.libHYPRE_handle, Symbol(precond)) + precond_setup_ptr = dlsym(HYPRE_jll.libHYPRE_handle, Symbol(precond_setup)) + return HYPRE_FlexGMRESSetPrecond(solver, precond_ptr, precond_setup_ptr, precond_solver) + end + function HYPRE_LGMRESSetPrecond(solver, precond::Function, precond_setup::Function, precond_solver) + precond_ptr = dlsym(HYPRE_jll.libHYPRE_handle, Symbol(precond)) + precond_setup_ptr = dlsym(HYPRE_jll.libHYPRE_handle, Symbol(precond_setup)) + return HYPRE_LGMRESSetPrecond(solver, precond_ptr, precond_setup_ptr, precond_solver) + end + function HYPRE_COGMRESSetPrecond(solver, precond::Function, precond_setup::Function, precond_solver) + precond_ptr = dlsym(HYPRE_jll.libHYPRE_handle, Symbol(precond)) + precond_setup_ptr = dlsym(HYPRE_jll.libHYPRE_handle, Symbol(precond_setup)) + return HYPRE_COGMRESSetPrecond(solver, precond_ptr, precond_setup_ptr, precond_solver) + end + function HYPRE_BiCGSTABSetPrecond(solver, precond::Function, precond_setup::Function, precond_solver) + precond_ptr = dlsym(HYPRE_jll.libHYPRE_handle, Symbol(precond)) + precond_setup_ptr = dlsym(HYPRE_jll.libHYPRE_handle, Symbol(precond_setup)) + return HYPRE_BiCGSTABSetPrecond(solver, precond_ptr, precond_setup_ptr, precond_solver) + end + function HYPRE_CGNRSetPrecond(solver, precond::Function, precondT::Function, precond_setup::Function, precond_solver) + precond_ptr = dlsym(HYPRE_jll.libHYPRE_handle, Symbol(precond)) + precondT_ptr = dlsym(HYPRE_jll.libHYPRE_handle, Symbol(precondT)) + precond_setup_ptr = dlsym(HYPRE_jll.libHYPRE_handle, Symbol(precond_setup)) + return HYPRE_CGNRSetPrecond(solver, precond_ptr, precondT_ptr, precond_setup_ptr, precond_solver) + end + function HYPRE_LOBPCGSetPrecond(solver, precond::Function, precond_setup::Function, precond_solver) + precond_ptr = dlsym(HYPRE_jll.libHYPRE_handle, Symbol(precond)) + precond_setup_ptr = dlsym(HYPRE_jll.libHYPRE_handle, Symbol(precond_setup)) + return HYPRE_LOBPCGSetPrecond(solver, precond_ptr, precond_setup_ptr, precond_solver) + end + + # Export everything with HYPRE_ prefix for name in names(@__MODULE__; all=true) if startswith(string(name), "HYPRE_")