Skip to content

Commit 623d8f4

Browse files
authored
add version errors (#602)
1 parent 793314f commit 623d8f4

File tree

5 files changed

+58
-18
lines changed

5 files changed

+58
-18
lines changed

docs/src/reference/environment.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,10 @@ MPI.Initialized
2424
MPI.Finalize
2525
MPI.Finalized
2626
```
27+
28+
## Errors
29+
30+
```@docs
31+
MPI.MPIError
32+
MPI.FeatureLevelError
33+
```

lib/MPIPreferences/src/MPIPreferences.jl

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,8 @@ else
4141
error("Unknown binary: $binary")
4242
end
4343

44-
module System
45-
export libmpi, mpiexec
46-
using Preferences
47-
const libmpi = @load_preference("libmpi")
48-
const mpiexec_path = @load_preference("mpiexec")
49-
mpiexec(;adjust_PATH=true, adjust_LIBPATH=true) = `$mpiexec_path`
50-
mpiexec(f;adjust_PATH=true, adjust_LIBPATH=true) = f(`$mpiexec_path`)
44+
@static if binary == "system"
45+
include("system.jl")
5146
end
5247

5348
"""

lib/MPIPreferences/src/system.jl

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
module System
2+
export libmpi, mpiexec
3+
using Preferences, Libdl
4+
const libmpi = @load_preference("libmpi")
5+
const mpiexec_path = @load_preference("mpiexec")
6+
mpiexec(;adjust_PATH=true, adjust_LIBPATH=true) = `$mpiexec_path`
7+
mpiexec(f;adjust_PATH=true, adjust_LIBPATH=true) = f(`$mpiexec_path`)
8+
9+
libmpi_handle = C_NULL
10+
function __init__()
11+
global libmpi_handle = Libdl.dlopen(libmpi, Libdl.RTLD_LAZY | Libdl.RTLD_GLOBAL)
12+
end
13+
end

src/MPI.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,19 +37,19 @@ end
3737
import MPIPreferences
3838

3939
if MPIPreferences.binary == "MPICH_jll"
40-
import MPICH_jll: libmpi, mpiexec
40+
import MPICH_jll: libmpi, libmpi_handle, mpiexec
4141
const libmpiconstants = nothing
4242
elseif MPIPreferences.binary == "OpenMPI_jll"
43-
import OpenMPI_jll: libmpi, mpiexec
43+
import OpenMPI_jll: libmpi, libmpi_handle, mpiexec
4444
const libmpiconstants = nothing
4545
elseif MPIPreferences.binary == "MicrosoftMPI_jll"
46-
import MicrosoftMPI_jll: libmpi, mpiexec
46+
import MicrosoftMPI_jll: libmpi, libmpi_handle, mpiexec
4747
const libmpiconstants = nothing
4848
elseif MPIPreferences.binary == "MPItrampoline_jll"
49-
import MPItrampoline_jll: MPItrampoline_jll, libmpi, mpiexec
49+
import MPItrampoline_jll: MPItrampoline_jll, libmpi, libmpi_handle, mpiexec
5050
const libmpiconstants = MPItrampoline_jll.libload_time_mpi_constants_path
5151
elseif MPIPreferences.binary == "system"
52-
import MPIPreferences.System: libmpi, mpiexec
52+
import MPIPreferences.System: libmpi, libmpi_handle, mpiexec
5353
const libmpiconstants = nothing
5454
else
5555
error("Unknown MPI binary: $(MPIPreferences.binary)")

src/error.jl

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,43 @@
1+
"""
2+
MPIError
3+
4+
Error thrown when an MPI function returns an error code. The `code` field contains the MPI error code.
5+
"""
16
struct MPIError <: Exception
27
code::Cint
38
end
9+
function Base.show(io::IO, err::MPIError)
10+
print(io, "MPIError(", err.code, "): ", error_string(err))
11+
end
12+
13+
"""
14+
FeatureLevelError
15+
16+
Error thrown if a feature is not implemented in the current MPI backend.
17+
"""
18+
struct FeatureLevelError <: Exception
19+
function_name::Symbol
20+
min_version::VersionNumber # minimal MPI version required for this feature to be available
21+
end
22+
function Base.show(io::IO, err::FeatureLevelError)
23+
print(io, "FeatureLevelError($(err.function_name)): Minimum MPI version is $(err.min_version)")
24+
end
25+
26+
macro mpichk(expr, min_version=nothing)
27+
if !isnothing(min_version) && expr.args[2].head == :tuple
28+
fn = expr.args[2].args[1].value
29+
if isnothing(dlsym(libmpi_handle, fn; throw_error=false))
30+
return quote
31+
throw(FeatureLevelError($fn, $min_version))
32+
end
33+
end
34+
end
435

5-
macro mpichk(expr)
636
expr = macroexpand(@__MODULE__, :(@mpicall($expr)))
737
# MPI_SUCCESS is defined to be 0
838
:((errcode = $(esc(expr))) == 0 || throw(MPIError(errcode)))
939
end
1040

11-
1241
function error_string(err::MPIError)
1342
len_ref = Ref{Cint}()
1443
str_buf = Vector{UInt8}(undef, Consts.MPI_MAX_ERROR_STRING)
@@ -18,7 +47,3 @@ function error_string(err::MPIError)
1847
resize!(str_buf, len_ref[])
1948
return String(str_buf)
2049
end
21-
22-
function Base.show(io::IO, err::MPIError)
23-
print(io, "MPIError(", err.code, "): ", error_string(err))
24-
end

0 commit comments

Comments
 (0)