Skip to content

Commit ad311c0

Browse files
committed
FindHDF5, FindMPI robust
1 parent 6e4c97f commit ad311c0

File tree

3 files changed

+105
-30
lines changed

3 files changed

+105
-30
lines changed

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
4.2.0
1+
4.2.1

cmake/Modules/FindHDF5.cmake

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,8 @@ if(HDF5_IS_PARALLEL)
9393
if(Fortran IN_LIST HDF5_FIND_COMPONENTS)
9494
list(APPEND mpi_comp Fortran)
9595
endif()
96-
9796
find_package(MPI COMPONENTS ${mpi_comp})
97+
9898
if(MPI_FOUND)
9999
set(HDF5_parallel_FOUND true PARENT_SCOPE)
100100
endif()
@@ -168,6 +168,8 @@ endif()
168168

169169
find_program(HDF5_Fortran_COMPILER_EXECUTABLE
170170
NAMES ${wrapper_names}
171+
PATHS ${_binpref}
172+
PATH_SUFFIXES ${_binsuf}
171173
)
172174

173175
find_library(HDF5_Fortran_LIBRARY
@@ -210,9 +212,10 @@ find_path(HDF5_Fortran_INCLUDE_DIR
210212
NAMES hdf5.mod
211213
HINTS ${pc_hdf5_INCLUDE_DIRS}
212214
PATH_SUFFIXES ${_msuf}
213-
PATHS /usr/lib64
215+
PATHS ${_binpref}
214216
DOC "HDF5 Fortran modules")
215-
# CentOS: /usr/lib64/gfortran/modules/hdf5.mod
217+
# CentOS: /usr/lib64/gfortran/modules/hdf5.mod
218+
216219
if(NOT HDF5_Fortran_INCLUDE_DIR)
217220
return()
218221
endif()
@@ -229,6 +232,8 @@ function(find_hdf5_cxx)
229232

230233
find_program(HDF5_CXX_COMPILER_EXECUTABLE
231234
NAMES h5c++ h5c++-64
235+
PATHS ${_binpref}
236+
PATH_SUFFIXES ${_binsuf}
232237
)
233238

234239
find_library(HDF5_CXX_LIBRARY
@@ -274,6 +279,8 @@ endif()
274279

275280
find_program(HDF5_C_COMPILER_EXECUTABLE
276281
NAMES ${wrapper_names}
282+
PATHS ${_binpref}
283+
PATH_SUFFIXES ${_binsuf}
277284
)
278285

279286
find_library(HDF5_C_LIBRARY
@@ -449,6 +456,9 @@ if(CMAKE_Fortran_COMPILER_ID STREQUAL GNU)
449456
list(PREPEND _msuf gfortran/modules/openmpi gfortran/modules/mpich)
450457
endif()
451458
endif()
459+
460+
set(_binpref /usr/lib64)
461+
set(_binsuf bin openmpi/bin mpich/bin)
452462
# Not immediately clear the benefits of this, as we'd have to foreach()
453463
# a priori names, kind of like we already do with find_library()
454464
# find_package(hdf5 CONFIG)
@@ -508,6 +518,14 @@ if(HDF5_FOUND)
508518
if(UNIX)
509519
target_link_libraries(HDF5::HDF5 INTERFACE m)
510520
endif()
521+
522+
if(HDF5_parallel_FOUND)
523+
if(HDF5_Fortran_FOUND)
524+
target_link_libraries(HDF5::HDF5 INTERFACE MPI::MPI_Fortran MPI::MPI_C)
525+
else()
526+
target_link_libraries(HDF5::HDF5 INTERFACE MPI::MPI_C)
527+
endif()
528+
endif()
511529
endif()
512530
endif()
513531

cmake/Modules/FindMPI.cmake

Lines changed: 83 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,8 @@ list(TRANSFORM _Lflags STRIP)
9898
set(_flags ${_Lflags})
9999

100100
# check if compiler absolute path is first element and remove
101-
if(${raw} MATCHES "^/")
102-
if(${_flags} MATCHES "^/")
101+
if("${raw}" MATCHES "^/")
102+
if("${_flags}" MATCHES "^/")
103103
list(REMOVE_AT _flags 0)
104104
endif()
105105
endif()
@@ -161,7 +161,7 @@ foreach(_p IN LISTS _vars)
161161
endforeach()
162162

163163
# check if compiler absolute path is first element and remove
164-
if(${raw} MATCHES "^/")
164+
if("${raw}" MATCHES "^/")
165165
list(REMOVE_AT _v 0)
166166
endif()
167167

@@ -181,7 +181,7 @@ function(find_c)
181181
set(MPI_C_LIBRARY)
182182

183183
if(WIN32)
184-
if(CMAKE_C_COMPILER_ID MATCHES Intel)
184+
if(CMAKE_C_COMPILER_ID MATCHES "^Intel")
185185
set(names impi)
186186
else()
187187
set(names msmpi)
@@ -196,7 +196,7 @@ if(NOT MPI_C_COMPILER)
196196
pkg_search_module(pc_mpi_c ompi-c)
197197
endif()
198198

199-
if(CMAKE_C_COMPILER_ID MATCHES Intel)
199+
if(CMAKE_C_COMPILER_ID MATCHES "^Intel")
200200
set(wrap_name mpiicc mpiicc.bat)
201201
else()
202202
set(wrap_name mpicc mpicc.openmpi mpicc.mpich)
@@ -206,8 +206,8 @@ find_program(MPI_C_COMPILER
206206
NAMES ${wrap_name}
207207
HINTS ${_hints}
208208
NAMES_PER_DIR
209-
PATHS /usr/lib64
210-
PATH_SUFFIXES bin openmpi/bin mpich/bin
209+
PATHS ${_binpref}
210+
PATH_SUFFIXES ${_binsuf}
211211
)
212212
if(MPI_C_COMPILER)
213213
get_filename_component(_wrap_hint ${MPI_C_COMPILER} DIRECTORY)
@@ -235,7 +235,7 @@ foreach(n ${names})
235235
find_library(MPI_C_${n}_LIBRARY
236236
NAMES ${n}
237237
HINTS ${lib_dirs} ${_wrap_hint} ${pc_mpi_c_LIBRARY_DIRS} ${pc_mpi_c_LIBDIR} ${_hints}
238-
PATH_SUFFIXES release openmpi/lib mpich/lib
238+
PATH_SUFFIXES ${_lsuf}
239239
)
240240
if(MPI_C_${n}_LIBRARY)
241241
list(APPEND MPI_C_LIBRARY ${MPI_C_${n}_LIBRARY})
@@ -259,6 +259,45 @@ set(CMAKE_REQUIRED_INCLUDES ${MPI_C_INCLUDE_DIR})
259259
set(CMAKE_REQUIRED_LIBRARIES ${MPI_C_LIBRARY})
260260
list(APPEND CMAKE_REQUIRED_LIBRARIES ${CMAKE_THREAD_LIBS_INIT})
261261

262+
if(NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/find_mpi/get_mpi_version.c)
263+
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/find_mpi/get_mpi_version.c
264+
[=[
265+
#include <mpi.h>
266+
#include <stdio.h>
267+
268+
int main(void) {
269+
int version, subversion;
270+
271+
int ierr = MPI_Get_version(&version, &subversion);
272+
if (ierr != 0) return 1;
273+
printf("%d.%d\n", version, subversion);
274+
275+
return 0;
276+
}
277+
]=]
278+
)
279+
endif()
280+
281+
if(NOT MPI_VERSION)
282+
message(CHECK_START "Checking MPI API level")
283+
try_run(mpi_run_code mpi_build_code
284+
${CMAKE_CURRENT_BINARY_DIR}/find_mpi/build
285+
${CMAKE_CURRENT_BINARY_DIR}/find_mpi/get_mpi_version.c
286+
CMAKE_FLAGS -DINCLUDE_DIRECTORIES=${MPI_C_INCLUDE_DIR}
287+
LINK_OPTIONS ${MPI_C_LINK_FLAGS}
288+
LINK_LIBRARIES ${MPI_C_LIBRARY}
289+
RUN_OUTPUT_VARIABLE MPI_VERSION
290+
)
291+
string(STRIP "${MPI_VERSION}" MPI_VERSION)
292+
if(mpi_build_code AND mpi_run_code EQUAL 0)
293+
message(CHECK_PASS "${MPI_VERSION}")
294+
else()
295+
message(CHECK_FAIL "MPI API not detected")
296+
return()
297+
endif()
298+
set(MPI_VERSION ${MPI_VERSION} CACHE STRING "MPI API level")
299+
endif()
300+
262301
check_c_source_compiles("
263302
#include <mpi.h>
264303
#ifndef NULL
@@ -292,7 +331,7 @@ function(find_cxx)
292331
set(MPI_CXX_LIBRARY)
293332

294333
if(WIN32)
295-
if(CMAKE_CXX_COMPILER_ID MATCHES Intel)
334+
if(CMAKE_CXX_COMPILER_ID MATCHES "^Intel")
296335
set(names impi)
297336
else()
298337
set(names msmpi)
@@ -309,7 +348,7 @@ if(NOT MPI_CXX_COMPILER)
309348
pkg_search_module(pc_mpi_cxx ompi-cxx)
310349
endif()
311350

312-
if(CMAKE_CXX_COMPILER_ID MATCHES Intel)
351+
if(CMAKE_CXX_COMPILER_ID MATCHES "^Intel")
313352
set(wrap_name mpiicpc mpiicpc.bat)
314353
else()
315354
set(wrap_name mpicxx mpicxx.openmpi mpicxx.mpich)
@@ -319,8 +358,8 @@ find_program(MPI_CXX_COMPILER
319358
NAMES ${wrap_name}
320359
HINTS ${_hints}
321360
NAMES_PER_DIR
322-
PATHS /usr/lib64
323-
PATH_SUFFIXES bin openmpi/bin mpich/bin
361+
PATHS ${_binpref}
362+
PATH_SUFFIXES ${_binsuf}
324363
)
325364
if(MPI_CXX_COMPILER)
326365
get_filename_component(_wrap_hint ${MPI_CXX_COMPILER} DIRECTORY)
@@ -348,7 +387,7 @@ foreach(n ${names})
348387
find_library(MPI_CXX_${n}_LIBRARY
349388
NAMES ${n}
350389
HINTS ${lib_dirs} ${_wrap_hint} ${pc_mpi_cxx_LIBRARY_DIRS} ${pc_mpi_cxx_LIBDIR} ${_hints}
351-
PATH_SUFFIXES release openmpi/lib mpich/lib
390+
PATH_SUFFIXES ${_lsuf}
352391
)
353392
if(MPI_CXX_${n}_LIBRARY)
354393
list(APPEND MPI_CXX_LIBRARY ${MPI_CXX_${n}_LIBRARY})
@@ -405,7 +444,7 @@ function(find_fortran)
405444
set(MPI_Fortran_LIBRARY)
406445

407446
if(WIN32)
408-
if(CMAKE_Fortran_COMPILER_ID MATCHES Intel)
447+
if(CMAKE_Fortran_COMPILER_ID MATCHES "^Intel")
409448
set(names impi)
410449
else()
411450
set(names msmpi)
@@ -423,7 +462,7 @@ if(NOT MPI_Fortran_COMPILER)
423462
pkg_search_module(pc_mpi_f ompi-fort)
424463
endif()
425464

426-
if(CMAKE_Fortran_COMPILER_ID MATCHES Intel)
465+
if(CMAKE_Fortran_COMPILER_ID MATCHES "^Intel")
427466
set(wrap_name mpiifort mpiifort.bat)
428467
else()
429468
set(wrap_name mpifort mpifc mpifort.openmpi mpifort.mpich)
@@ -433,8 +472,8 @@ find_program(MPI_Fortran_COMPILER
433472
NAMES ${wrap_name}
434473
HINTS ${_hints}
435474
NAMES_PER_DIR
436-
PATHS /usr/lib64
437-
PATH_SUFFIXES bin openmpi/bin mpich/bin
475+
PATHS ${_binpref}
476+
PATH_SUFFIXES ${_binsuf}
438477
)
439478
if(MPI_Fortran_COMPILER)
440479
get_filename_component(_wrap_hint ${MPI_Fortran_COMPILER} DIRECTORY)
@@ -462,7 +501,7 @@ foreach(n ${names})
462501
find_library(MPI_Fortran_${n}_LIBRARY
463502
NAMES ${n}
464503
HINTS ${lib_dirs} ${_wrap_hint} ${pc_mpi_f_LIBRARY_DIRS} ${pc_mpi_f_LIBDIR} ${_hints}
465-
PATH_SUFFIXES release openmpi/lib mpich/lib
504+
PATH_SUFFIXES ${_lsuf}
466505
)
467506
if(MPI_Fortran_${n}_LIBRARY)
468507
list(APPEND MPI_Fortran_LIBRARY ${MPI_Fortran_${n}_LIBRARY})
@@ -488,7 +527,7 @@ if(NOT MPI_Fortran_INCLUDE_DIR)
488527
return()
489528
endif()
490529

491-
if(WIN32 AND NOT CMAKE_Fortran_COMPILER_ID MATCHES Intel)
530+
if(WIN32 AND NOT CMAKE_Fortran_COMPILER_ID MATCHES "^Intel")
492531
find_path(MPI_Fortran_INCLUDE_EXTRA
493532
NAMES mpifptr.h
494533
HINTS ${inc_dirs} ${_wrap_hint} ${pc_mpi_f_INCLUDE_DIRS} ${_hints} ${_hints_inc}
@@ -537,28 +576,29 @@ find_package(PkgConfig)
537576
find_package(Threads)
538577

539578
# Intel MPI, which works with non-Intel compilers on Linux
540-
if((CMAKE_SYSTEM_NAME STREQUAL Linux OR CMAKE_C_COMPILER_ID MATCHES Intel) AND
579+
if((CMAKE_SYSTEM_NAME STREQUAL Linux OR CMAKE_C_COMPILER_ID MATCHES "^Intel") AND
541580
DEFINED ENV{I_MPI_ROOT})
542581
list(APPEND _hints $ENV{I_MPI_ROOT})
543582
endif()
544583

545-
if(WIN32 AND NOT CMAKE_C_COMPILER_ID MATCHES Intel)
584+
if(WIN32 AND NOT CMAKE_C_COMPILER_ID MATCHES "^Intel")
546585
list(APPEND _hints $ENV{MSMPI_LIB64})
547586
list(APPEND _hints_inc $ENV{MSMPI_INC})
548587
endif()
549588

589+
set(_lsuf release openmpi/lib mpich/lib)
590+
set(_binpref /usr/lib64)
591+
set(_binsuf bin openmpi/bin mpich/bin)
592+
550593
# must have MPIexec to be worthwhile (de facto standard is mpiexec)
551594
find_program(MPIEXEC_EXECUTABLE
552595
NAMES mpiexec mpirun orterun
553596
HINTS ${_hints} $ENV{MSMPI_BIN}
554-
PATHS /usr/lib64
555-
PATH_SUFFIXES bin openmpi/bin mpich/bin
597+
PATHS ${_binpref}
598+
PATH_SUFFIXES ${_binsuf}
556599
)
557600

558601
# like factory FindMPI, always find MPI_C
559-
if(NOT C IN_LIST MPI_FIND_COMPONENTS)
560-
list(APPEND MPI_FIND_COMPONENTS C)
561-
endif()
562602
find_c()
563603

564604
if(CXX IN_LIST MPI_FIND_COMPONENTS)
@@ -572,6 +612,7 @@ endif()
572612
include(FindPackageHandleStandardArgs)
573613
find_package_handle_standard_args(MPI
574614
REQUIRED_VARS MPIEXEC_EXECUTABLE
615+
VERSION_VAR MPI_VERSION
575616
HANDLE_COMPONENTS)
576617

577618
if(MPI_C_FOUND)
@@ -627,6 +668,22 @@ if(MPI_FOUND)
627668
set(MPIEXEC_NUMPROC_FLAG "-n" CACHE STRING "Flag used by MPI to specify the number of processes for mpiexec; the next option will be the number of processes.")
628669
cmake_host_system_information(RESULT _n QUERY NUMBER_OF_PHYSICAL_CORES)
629670
set(MPIEXEC_MAX_NUMPROCS "${_n}" CACHE STRING "Maximum number of processors available to run MPI applications.")
671+
672+
message(VERBOSE "FindMPI results:
673+
MPI_C_COMPILER: ${MPI_C_COMPILER}
674+
MPI_C_LIBRARIES: ${MPI_C_LIBRARIES}
675+
MPI_C_INCLUDE_DIRS: ${MPI_C_INCLUDE_DIRS}
676+
MPI_C_LINK_FLAGS: ${MPI_C_LINK_FLAGS}
677+
678+
MPI_Fortran_COMPILER: ${MPI_Fortran_COMPILER}
679+
MPI_Fortran_LIBRARIES: ${MPI_Fortran_LIBRARIES}
680+
MPI_Fortran_INCLUDE_DIRS: ${MPI_Fortran_INCLUDE_DIRS}
681+
MPI_Fortran_LINK_FLAGS: ${MPI_Fortran_LINK_FLAGS}
682+
683+
MPIEXEC_EXECUTABLE: ${MPIEXEC_EXECUTABLE}
684+
MPIEXEC_MAX_NUMPROCS: ${MPIEXEC_MAX_NUMPROCS}
685+
MPI_VERSION: ${MPI_VERSION}
686+
")
630687
endif()
631688

632689
mark_as_advanced(MPI_Fortran_LIBRARY MPI_Fortran_INCLUDE_DIR MPI_C_LIBRARY MPI_C_INCLUDE_DIR

0 commit comments

Comments
 (0)