Skip to content

Commit f8e4749

Browse files
authored
Base MPI.identify_implementation on helper function in MPIPreferences (#595)
* Base `MPI.identify_implementation` on helper function in `MPIPreferences` We basically moved the detection of ABI/implementation to `MPIPreferences`, and added only there the support for new ABIs/implementations, which means that `MPI.identify_implementation` is now giving incorrect results for them, and also the constants `MPI.MPI_LIBRARY` and `MPI.MPI_LIBRARY_VERSION` are now wrong. By having a new helper function in `MPIPreferences` we can have all other functions use it under the hood and keep everything in-sync. * Remove `MPI.MPIImpl`
1 parent f796943 commit f8e4749

File tree

10 files changed

+57
-150
lines changed

10 files changed

+57
-150
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,6 @@ Sockets = "6462fe0b-24de-5631-8697-dd941f90decc"
1818

1919
[compat]
2020
DocStringExtensions = "0.8"
21-
MPIPreferences = "0.1"
21+
MPIPreferences = "0.1.2"
2222
Requires = "~0.5, 1.0"
2323
julia = "1.6"

docs/src/reference/library.md

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,6 @@ MPI.MPI_LIBRARY_VERSION
99
MPI.MPI_LIBRARY_VERSION_STRING
1010
```
1111

12-
## Enums
13-
14-
```@docs
15-
MPI.MPIImpl
16-
```
17-
1812
## Functions
1913

2014
```@docs

lib/MPIPreferences/Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "MPIPreferences"
22
uuid = "3da0fdf6-3ccc-4f1b-acd9-58baa6c99267"
33
authors = []
4-
version = "0.1.1"
4+
version = "0.1.2"
55

66
[deps]
77
Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb"

lib/MPIPreferences/src/MPIPreferences.jl

Lines changed: 44 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -162,45 +162,7 @@ function use_system_binary(;
162162
return nothing
163163
end
164164

165-
166-
"""
167-
identify_abi(libmpi)
168-
169-
Identify the MPI implementation from the library version string
170-
"""
171-
function identify_abi(libmpi)
172-
# 1) query MPI_Get_version
173-
# There is no way to query at runtime what the length of the buffer should be.
174-
# https://github.com/mpi-forum/mpi-issues/issues/159
175-
# 8192 is the maximum value of MPI_MAX_LIBRARY_VERSION_STRING across known
176-
# implementations.
177-
buf = Array{UInt8}(undef, 8192)
178-
buflen = Ref{Cint}()
179-
180-
hndl = @static if Sys.isunix()
181-
# Again, work around https://github.com/open-mpi/ompi/issues/10142
182-
withenv("ZES_ENABLE_SYSMAN" => "1") do
183-
# need to open libmpi with RTLD_GLOBAL flag for Linux, before
184-
# any ccall cannot use RTLD_DEEPBIND; this leads to segfaults
185-
# at least on Ubuntu 15.10
186-
Libdl.dlopen(libmpi, Libdl.RTLD_LAZY | Libdl.RTLD_GLOBAL)
187-
end
188-
else
189-
Libdl.dlopen(libmpi)
190-
end
191-
192-
try
193-
ptr = dlsym(hndl, :MPI_Get_library_version)
194-
ccall(ptr, Cint, (Ptr{UInt8}, Ref{Cint}), buf, buflen)
195-
finally
196-
Libdl.dlclose(hndl)
197-
end
198-
199-
@assert buflen[] < 8192
200-
resize!(buf, buflen[])
201-
version_string = String(buf)
202-
203-
# 2) try to identify the MPI implementation
165+
function identify_implementation_version_abi(version_string::AbstractString)
204166
impl = "unknown"
205167
version = v"0"
206168

@@ -302,6 +264,49 @@ function identify_abi(libmpi)
302264
abi = "unknown"
303265
end
304266

267+
return (impl, version, abi)
268+
end
269+
270+
"""
271+
identify_abi(libmpi)
272+
273+
Identify the MPI implementation from the library version string
274+
"""
275+
function identify_abi(libmpi)
276+
# 1) query MPI_Get_version
277+
# There is no way to query at runtime what the length of the buffer should be.
278+
# https://github.com/mpi-forum/mpi-issues/issues/159
279+
# 8192 is the maximum value of MPI_MAX_LIBRARY_VERSION_STRING across known
280+
# implementations.
281+
buf = Array{UInt8}(undef, 8192)
282+
buflen = Ref{Cint}()
283+
284+
hndl = @static if Sys.isunix()
285+
# Again, work around https://github.com/open-mpi/ompi/issues/10142
286+
withenv("ZES_ENABLE_SYSMAN" => "1") do
287+
# need to open libmpi with RTLD_GLOBAL flag for Linux, before
288+
# any ccall cannot use RTLD_DEEPBIND; this leads to segfaults
289+
# at least on Ubuntu 15.10
290+
Libdl.dlopen(libmpi, Libdl.RTLD_LAZY | Libdl.RTLD_GLOBAL)
291+
end
292+
else
293+
Libdl.dlopen(libmpi)
294+
end
295+
296+
try
297+
ptr = dlsym(hndl, :MPI_Get_library_version)
298+
ccall(ptr, Cint, (Ptr{UInt8}, Ref{Cint}), buf, buflen)
299+
finally
300+
Libdl.dlclose(hndl)
301+
end
302+
303+
@assert buflen[] < 8192
304+
resize!(buf, buflen[])
305+
version_string = String(buf)
306+
307+
# 2) try to identify the MPI implementation
308+
impl, version, abi = identify_implementation_version_abi(version_string)
309+
305310
@info "MPI implementation" libmpi version_string impl version abi
306311

307312
return abi

src/environment.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -295,10 +295,10 @@ function has_cuda()
295295
flag = get(ENV, "JULIA_MPI_HAS_CUDA", nothing)
296296
if flag === nothing
297297
# Only Open MPI provides a function to check CUDA support
298-
@static if MPI_LIBRARY == OpenMPI
298+
@static if MPI_LIBRARY == "OpenMPI"
299299
# int MPIX_Query_cuda_support(void)
300300
return 0 != ccall((:MPIX_Query_cuda_support, libmpi), Cint, ())
301-
elseif MPI_LIBRARY == IBMSpectrumMPI
301+
elseif MPI_LIBRARY == "IBMSpectrumMPI"
302302
return true
303303
else
304304
return false

src/implementations.jl

Lines changed: 3 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -49,121 +49,29 @@ $(_doc_external("MPI_Get_library_version"))
4949
"""
5050
const MPI_LIBRARY_VERSION_STRING = Get_library_version()
5151

52-
"""
53-
MPIImpl
54-
55-
An enum corresponding to known MPI implementations
56-
57-
- `UnknownMPI`: unable to determine MPI implementation
58-
- `MPICH`: [MPICH](https://www.mpich.org/)
59-
- `OpenMPI`: [Open MPI](https://www.open-mpi.org/)
60-
- `MicrosoftMPI`: [Microsoft MPI](https://docs.microsoft.com/en-us/message-passing-interface/microsoft-mpi)
61-
- `IntelMPI`: [Intel MPI](https://software.intel.com/en-us/mpi-library)
62-
- `SpectrimMPI`: [IBM Spectrum MPI](https://www.ibm.com/us-en/marketplace/spectrum-mpi)
63-
- `MVAPICH`: [MVAPICH](http://mvapich.cse.ohio-state.edu/)
64-
- `CrayMPICH`: Part of the Cray Message Passing Toolkit (MPT)
65-
66-
# See also
67-
68-
- [`MPI_LIBRARY`](@ref)
69-
"""
70-
@enum MPIImpl begin
71-
UnknownMPI
72-
MPICH
73-
MPItrampoline
74-
OpenMPI
75-
MicrosoftMPI
76-
IntelMPI
77-
IBMSpectrumMPI
78-
MVAPICH
79-
CrayMPICH
80-
end
81-
8252
"""
8353
impl, version = identify_implementation()
8454
8555
Attempt to identify the MPI implementation based on
8656
[`MPI_LIBRARY_VERSION_STRING`](@ref). Returns a triple of values:
8757
88-
- `impl`: a value of type [`MPIImpl`](@ref)
58+
- `impl`: a `String` with the name of the MPI implementation, or `"unknown"` if it cannot be determined,
8959
- `version`: a `VersionNumber` of the library, or `nothing` if it cannot be determined.
9060
9161
This function is only intended for internal use. Users should use [`MPI_LIBRARY`](@ref),
9262
[`MPI_LIBRARY_VERSION`](@ref).
9363
"""
9464
function identify_implementation()
95-
impl = UnknownMPI
96-
version = v"0"
97-
98-
if startswith(MPI_LIBRARY_VERSION_STRING, "MPICH")
99-
impl = MPICH
100-
# "MPICH Version:\t%s\n" / "MPICH2 Version:\t%s\n"
101-
if (m = match(r"^MPICH2? Version:\t(\d+.\d+(?:.\d+)?\w*)\n", MPI_LIBRARY_VERSION_STRING)) !== nothing
102-
version = VersionNumber(m.captures[1])
103-
end
104-
105-
elseif startswith(MPI_LIBRARY_VERSION_STRING, "MPItrampoline") || startswith(MPI_LIBRARY_VERSION_STRING, "MPIwrapper")
106-
impl = MPItrampoline
107-
# "MPItrampoline %d.%d.%d," / "MPIwrapper %d.%d.%d,"
108-
if (m = match(r"^MPI(wrapper|trampoline) (\d+.\d+.\d+),", MPI_LIBRARY_VERSION_STRING)) !== nothing
109-
version = VersionNumber(m.captures[2])
110-
end
111-
112-
elseif startswith(MPI_LIBRARY_VERSION_STRING, "Open MPI")
113-
# Open MPI / Spectrum MPI
114-
impl = occursin("IBM Spectrum MPI", MPI_LIBRARY_VERSION_STRING) ? IBMSpectrumMPI : OpenMPI
115-
116-
if (m = match(r"^Open MPI v(\d+.\d+.\d+\w*)", MPI_LIBRARY_VERSION_STRING)) !== nothing
117-
version = VersionNumber(m.captures[1])
118-
end
119-
120-
elseif startswith(MPI_LIBRARY_VERSION_STRING, "Microsoft MPI")
121-
impl = MicrosoftMPI
122-
# "Microsoft MPI %u.%u.%u.%u%S"
123-
# ignore last 2 (build numbers)
124-
if (m = match(r"^Microsoft MPI (\d+.\d+)", MPI_LIBRARY_VERSION_STRING)) !== nothing
125-
version = VersionNumber(m.captures[1])
126-
end
127-
128-
elseif startswith(MPI_LIBRARY_VERSION_STRING, "Intel")
129-
impl = IntelMPI
130-
131-
# "Intel(R) MPI Library 2019 Update 4 for Linux* OS"
132-
if (m = match(r"^Intel\(R\) MPI Library (\d+)(?: Update (\d+))?", MPI_LIBRARY_VERSION_STRING)) !== nothing
133-
if m.captures[2] === nothing
134-
version = VersionNumber(m.captures[1])
135-
else
136-
version = VersionNumber(m.captures[1]*"."*m.captures[2])
137-
end
138-
end
139-
140-
elseif startswith(MPI_LIBRARY_VERSION_STRING, "MVAPICH2")
141-
impl = MVAPICH
142-
# "MVAPICH2 Version :\t%s\n")
143-
if (m = match(r"^MVAPICH2? Version\s*:\t(\S*)\n", MPI_LIBRARY_VERSION_STRING)) !== nothing
144-
version = VersionNumber(m.captures[1])
145-
end
146-
147-
elseif occursin("CRAY MPICH", MPI_LIBRARY_VERSION_STRING)
148-
impl = CrayMPICH
149-
# "MPI VERSION : CRAY MPICH version 7.7.10 (ANL base 3.2)\n"
150-
if (m = match(r"CRAY MPICH version (\d+.\d+.\d+)", MPI_LIBRARY_VERSION_STRING)) !== nothing
151-
version = VersionNumber(m.captures[1])
152-
end
153-
end
154-
65+
impl, version, abi = MPIPreferences.identify_implementation_version_abi(MPI_LIBRARY_VERSION_STRING)
15566
return impl, version
15667
end
15768

15869
const MPI_LIBRARY, MPI_LIBRARY_VERSION = identify_implementation()
15970

16071
"""
161-
MPI_LIBRARY :: MPIImpl
72+
MPI_LIBRARY :: String
16273
16374
The current MPI implementation: this is determined by
164-
165-
# See also
166-
- [`MPIImpl`](@ref)
16775
"""
16876
MPI_LIBRARY
16977

src/operators.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ end
8989

9090

9191
function Op(f, T=Any; iscommutative=false)
92-
@static if MPI_LIBRARY == MicrosoftMPI && Sys.WORD_SIZE == 32
92+
@static if MPI_LIBRARY == "MicrosoftMPI" && Sys.WORD_SIZE == 32
9393
error("User-defined reduction operators are not supported on 32-bit Windows.\nSee https://github.com/JuliaParallel/MPI.jl/issues/246 for more details.")
9494
elseif Sys.ARCH (:aarch64, :ppc64le, :powerpc64le) || startswith(lowercase(String(Sys.ARCH)), "arm")
9595
error("User-defined reduction operators are currently not supported on non-Intel architectures.\nSee https://github.com/JuliaParallel/MPI.jl/issues/404 for more details.")

test/runtests.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,9 @@ testfiles = sort(filter(istest, readdir(testdir)))
4848
elseif f == "test_error.jl"
4949
r = run(ignorestatus(cmd()))
5050
@test !success(r)
51-
elseif f == "test_errorhandler.jl" && (MPI.identify_implementation()[1] == MPI.UnknownMPI ||
52-
# Fujitsu MPI is known to not work with custom error handlers
53-
startswith(MPI.MPI_LIBRARY_VERSION_STRING, "FUJITSU MPI"))
51+
elseif f == "test_errorhandler.jl" && MPI.MPI_LIBRARY in ("unknown", "FujitsuMPI")
52+
# Fujitsu MPI is known to not work with custom error handlers. Also
53+
# unknown implementations may fail for the same reason.
5454
try
5555
run(cmd())
5656
catch e

test/test_allreduce.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ MPI.Init()
1313
comm_size = MPI.Comm_size(MPI.COMM_WORLD)
1414

1515
if ArrayType != Array ||
16-
MPI.MPI_LIBRARY == MPI.MicrosoftMPI && Sys.WORD_SIZE == 32 ||
16+
MPI.MPI_LIBRARY == "MicrosoftMPI" && Sys.WORD_SIZE == 32 ||
1717
Sys.ARCH === :powerpc64le || Sys.ARCH === :ppc64le ||
1818
Sys.ARCH === :aarch64 || startswith(string(Sys.ARCH), "arm")
1919
operators = [MPI.SUM, +]

test/test_reduce.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ end
1111
# Closures might not be supported by cfunction
1212
const can_do_closures =
1313
ArrayType === Array &&
14-
!(MPI.MPI_LIBRARY == MPI.MicrosoftMPI && Sys.WORD_SIZE == 32) &&
14+
!(MPI.MPI_LIBRARY == "MicrosoftMPI" && Sys.WORD_SIZE == 32) &&
1515
Sys.ARCH !== :powerpc64le &&
1616
Sys.ARCH !== :ppc64le &&
1717
Sys.ARCH !== :aarch64 &&

0 commit comments

Comments
 (0)