Julia Interface¶
The Julia interface is an in-tree package under interfaces/julia. It supports
source-tree and install-prefix use today and can be registered from this monorepo
subdirectory later; a separate Julia-package repository is not required. Julia 1.9
or newer is required. The package and module name follow Julia convention: use
using HypreDrive.
Build¶
Enable the interface with CMake:
cmake -S . -B build-julia \
-DHYPREDRV_ENABLE_JULIA=ON \
-DHYPREDRV_ENABLE_TESTING=ON
cmake --build build-julia --target julia-test --parallel
To validate that an installed HYPREDRV tree exports a usable Julia bridge target:
cmake --build build-julia --target julia-install-consumer-test --parallel
The CMake build creates a small libHYPREDRV_Julia bridge library. The bridge keeps
Julia away from HYPRE ABI details such as HYPRE_BigInt width and real precision.
Because Julia loads this bridge with Libdl, it is always built as a shared library.
External static HYPRE archives must therefore be compiled with -fPIC. Auto-fetched
HYPRE builds are configured with position-independent code when the Julia interface is
enabled.
The bridge is installed under lib/julia so language-specific shared libraries do
not pollute the top-level library directory. Its install RPATH includes both that
directory and the parent lib directory so it can find libHYPREDRV from the
same prefix without LD_LIBRARY_PATH.
CMake prints the Julia executable it found. If Julia is not found, the julia-test
target fails with a clear message when run.
Use from Julia¶
Develop the in-tree package:
import Pkg
Pkg.develop(path="interfaces/julia")
From outside the repository root, Julia’s subdirectory package support can install the package sources directly:
import Pkg
Pkg.add(Pkg.PackageSpec(url="https://github.com/hypre-space/hypredrive.git",
subdir="interfaces/julia"))
This installs the Julia sources only. Until a binary artifact/JLL is published, users still need a compatible HYPREDRV build or install prefix.
Point the package at the CMake-built bridge library:
export HYPREDRV_LIBRARY=$PWD/build-julia/interfaces/julia/lib/libHYPREDRV_Julia.so
On macOS, use the .dylib extension instead of .so.
After installing hypredrive, HYPREDRV_DIR may be set instead:
export HYPREDRV_DIR=/path/to/hypredrive/install
For the Julia package, HYPREDRV_DIR means the HYPREDRV install prefix, not the
CMake package directory containing HYPREDRVConfig.cmake. The Julia package
searches lib/julia, lib, lib64/julia, and lib64 under that prefix.
If neither environment variable is set, it falls back to the Julia artifact named
hypredrive_mpi_trampoline in Artifacts.toml, then the source-tree build
search, and finally Libdl.find_library. The artifact contains the HYPREDRV
Julia bridge built against MPItrampoline; MPItrampoline itself comes from
MPItrampoline_jll.
Example¶
using HypreDrive
using SparseArrays
n = 64
A = spdiagm(-1 => fill(-1.0, n - 1), 0 => fill(2.0, n), 1 => fill(-1.0, n - 1))
b = ones(n)
x, info = hypredrive_solve(A, b)
println(info.iterations)
Options can be constructed as Julia keyword arguments instead of hand-written YAML:
opts = hypredrive_options(
solver=:pcg,
preconditioner=:amg,
pcg=(max_iter=200, relative_tol=1.0e-10),
amg=(print_level=0,),
)
x, info = hypredrive_solve(A, b; options=opts)
The generic aliases solve, solve_mpi, initialize, and shutdown remain
available for qualified calls such as HypreDrive.solve(...), but they are
intentionally not exported.
MPI¶
The package also supports MPI execution through hypredrive_solve_mpi:
mpiexec -n 2 julia --project=interfaces/julia interfaces/julia/test/mpi.jl
hypredrive_solve_mpi(A, b) creates the HYPREDRV driver on MPI_COMM_WORLD,
partitions the rows of the global Julia sparse matrix across ranks, and returns each
rank’s local solution segment. This convenience API is useful for correctness tests and
integration work.
The explicit MPI helper names hypredrive_mpi_world_rank,
hypredrive_mpi_world_size, and hypredrive_mpi_world_sum operate on
MPI_COMM_WORLD. The older qualified aliases remain available but are not exported.
Pkg.test() runs the serial package tests only. The MPI test is wired through
CMake/CTest because it requires mpiexec.
Standalone Laplacian example¶
The standalone example follows the C Laplacian driver’s command-line shape and assembles only the local CSR slab on each rank:
mpiexec -n 2 julia --project=interfaces/julia \
interfaces/julia/examples/laplacian.jl \
-n 12 12 12 -P 2 1 1 -s 7 -ns 2
Use -i options.yml to provide a hypredrive YAML solver configuration. Without
-i, the example uses quiet PCG+AMG defaults. The -P topology controls the 3D
block partition used to assemble local matrix rows.
Scope¶
The interface supports serial solves via MPI_COMM_SELF and MPI solves via
MPI_COMM_WORLD. It supports standard double-precision, real-valued HYPRE builds.
Complex, single-precision, and long-double HYPRE builds are rejected at runtime with a
clear error. The package uses process-global MPI state; do not mix multiple independent
MPI owners inside one Julia process.
The package can be registered in Julia’s General registry from interfaces/julia.
Registry releases should use normal Julia semver such as 0.2.0, not development
version strings. The fallback distribution model is source/install-prefix based:
users build HYPREDRV from this checkout or install HYPREDRV separately and set
HYPREDRV_DIR or HYPREDRV_LIBRARY.
Binary releases can be distributed from this monorepo through Julia artifacts without
moving the package to a separate repository. The first artifact policy is
MPItrampoline: Linux x86_64 glibc release tarballs are hosted on GitHub Releases and bound into
interfaces/julia/Artifacts.toml under the artifact name
hypredrive_mpi_trampoline. Release maintainers should run the Julia
Artifacts workflow manually on the release branch with update_artifacts_toml
enabled and release_tag set to the future tag name, then create the tag from
the resulting commit. The tag workflow verifies that Artifacts.toml already
contains URLs for that tag before publishing release assets. The release recipe
lives in the Julia interface’s binary tooling. Local BinaryBuilder runs require a working container runner;
if Docker cleanup fails at a sudo chown step, use the GitHub Julia
Artifacts workflow or run on a machine with passwordless sudo/unprivileged
container support. macOS, Linux aarch64, musl, Windows, OpenMPI, and custom-MPI
artifacts are not shipped until explicit additional artifact flavors are added;
those users should continue to use source/install-prefix mode.
MPItrampoline_jll is a normal dependency, not a weak dependency, so artifact
preloading works in a clean Julia environment without extension activation.