-
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
345 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
# USAGE: | ||
# cmake -Dprefix=~/mpi -P build_mpich.cmake | ||
cmake_minimum_required(VERSION 3.20) | ||
|
||
execute_process(COMMAND | ||
${CMAKE_COMMAND} -Dargs=-Dmpich:BOOL=true | ||
-P ${CMAKE_CURRENT_LIST_DIR}/build_openmpi.cmake | ||
) | ||
|
||
# NOTE: to pass-through arguments, don't quote them |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
# USAGE: | ||
# cmake -Dprefix=~/mpi -P build_openmpi.cmake | ||
cmake_minimum_required(VERSION 3.20) | ||
|
||
if(prefix) | ||
list(APPEND args -DCMAKE_INSTALL_PREFIX:PATH=${prefix}) | ||
endif() | ||
|
||
if(NOT bindir) | ||
execute_process(COMMAND mktemp -d | ||
OUTPUT_VARIABLE bindir | ||
OUTPUT_STRIP_TRAILING_WHITESPACE | ||
RESULT_VARIABLE ret | ||
) | ||
if(NOT ret EQUAL 0) | ||
string(RANDOM LENGTH 6 r) | ||
set(bindir /tmp/build_${r}) | ||
endif() | ||
endif() | ||
|
||
execute_process(COMMAND ${CMAKE_COMMAND} | ||
${args} | ||
-B${bindir} | ||
-S${CMAKE_CURRENT_LIST_DIR}/mpi | ||
COMMAND_ERROR_IS_FATAL ANY | ||
) | ||
|
||
message(STATUS "MPI build in ${bindir}") | ||
|
||
|
||
execute_process(COMMAND ${CMAKE_COMMAND} --build ${bindir} | ||
COMMAND_ERROR_IS_FATAL ANY | ||
) | ||
|
||
message(STATUS "MPI install complete.") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
cmake_minimum_required(VERSION 3.21...3.28) | ||
|
||
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR) | ||
message(FATAL_ERROR "Use out of source build like | ||
cmake -Bbuild") | ||
endif() | ||
|
||
project(BuildMPI LANGUAGES C CXX Fortran) | ||
|
||
include(CheckIncludeFile) | ||
include(ExternalProject) | ||
|
||
option(mpich "Build MPICH instead of OpenMPI") | ||
|
||
option(CMAKE_TLS_VERIFY "Verify TLS certs" on) | ||
|
||
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../cmake) | ||
|
||
file(GENERATE OUTPUT .gitignore CONTENT "*") | ||
|
||
# --- check for updated external projects when "false" | ||
set_property(DIRECTORY PROPERTY EP_UPDATE_DISCONNECTED true) | ||
|
||
|
||
find_package(Autotools REQUIRED) | ||
|
||
# --- determine number of cores for parallel build | ||
# MPI builds spawn too many threads with bare "make -j" giving build crashes like | ||
# libtool: fork: Resource temporarily unavailable | ||
# clang: error: unable to execute command: posix_spawn failed: Resource temporarily unavailable | ||
if(DEFINED ENV{CMAKE_BUILD_PARALLEL_LEVEL}) | ||
set(Ncpu $ENV{CMAKE_BUILD_PARALLEL_LEVEL}) | ||
else() | ||
cmake_host_system_information(RESULT Ncpu QUERY NUMBER_OF_PHYSICAL_CORES) | ||
endif() | ||
|
||
set(mpi_flags --prefix=${CMAKE_INSTALL_PREFIX}) | ||
|
||
# to avoid ABI problems and confusing build or runtime errors, mandate that C and C++ are same compiler vendor | ||
if(NOT CMAKE_C_COMPILER_ID STREQUAL CMAKE_CXX_COMPILER_ID) | ||
message(FATAL_ERROR "C compiler ${CMAKE_C_COMPILER_ID} and C++ compiler ${CMAKE_CXX_COMPILER_ID} must be the same to avoid ABI build/runtime errors. | ||
Set environment variables CC and CXX to the same compiler by prepending the command line: | ||
CC=gcc-13 CXX=g++-13") | ||
endiF() | ||
|
||
# help OpenMPI/MPICH by hinting compilers, particularly on MacOS | ||
# assume whatever the C compiler is, the C++ and Fortran compilers are the same vendor | ||
if(CMAKE_C_COMPILER_ID MATCHES "GNU|$Intel") | ||
# OpenMPI / MPICH needs full path to oneAPI compilers | ||
list(APPEND mpi_flags CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER} FC=${CMAKE_Fortran_COMPILER}) | ||
elseif(CMAKE_C_COMPILER_ID MATCHES "Clang$") | ||
# until Flang is ready, use Gfortran | ||
list(APPEND mpi_flags CC=clang CXX=clang++ FC=gfortran) | ||
endif() | ||
|
||
# OpenMPI/MPICH have trouble finding -lm on MacOS especially | ||
find_library(math NAMES m REQUIRED) | ||
cmake_path(GET math PARENT_PATH math_LIBDIR) | ||
|
||
set(mpi_ldflags "LDFLAGS=${CMAKE_LIBRARY_PATH_FLAG}${math_LIBDIR}") | ||
|
||
# --- read JSON with URLs for each library | ||
file(READ ${CMAKE_CURRENT_SOURCE_DIR}/../versions.json json_meta) | ||
|
||
if(mpich) | ||
check_include_file("ISO_Fortran_binding.h" HAVE_ISO_FORTRAN_BINDING_H) | ||
if(NOT HAVE_ISO_FORTRAN_BINDING_H) | ||
message(FATAL_ERROR "ISO_Fortran_binding.h not found with ${CMAKE_C_COMPILER_ID} ${CMAKE_C_COMPILER_VERSION} ${CMAKE_C_COMPILER} | ||
We suggest GCC compiler. Specify GCC by prepending \"CC=gcc-13\" or similar to your command. | ||
Setting \"CC=gcc\" on macOS defaults to Clang, which will fail. MPICH requires ISO_Fortran_binding.h") | ||
endif() | ||
|
||
string(JSON mpi_url GET ${json_meta} "mpich") | ||
|
||
list(APPEND mpi_flags --with-device=ch3) | ||
# MPICH 4.2.0 etc. fails to build without this option | ||
else() | ||
string(JSON mpi_url GET ${json_meta} "openmpi") | ||
|
||
# this --with-hwloc breaks OpenMPI 4.1 and 5.0 at least | ||
# list(APPEND mpi_flags --with-hwloc=internal) | ||
# internal HWLOC avoids error in MPI: | ||
# ibopen-pal.a(topology-linux.o): multiple definition of `hwloc_linux_component' | ||
#--with-hwloc-libdir=${CMAKE_INSTALL_PREFIX}/lib | ||
|
||
list(APPEND mpi_flags --disable-sphinx) | ||
# avoids errors with docs build that aren't used anyway | ||
|
||
find_package(ZLIB) | ||
if(ZLIB_FOUND) | ||
cmake_path(GET ZLIB_LIBRARIES PARENT_PATH ZLIB_LIBDIR) | ||
list(APPEND mpi_flags --with-zlib-libdir=${ZLIB_LIBDIR}) | ||
endif() | ||
endif() | ||
|
||
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) | ||
file(REAL_PATH "~" home EXPAND_TILDE) | ||
cmake_path(GET mpi_url STEM n) | ||
set_property(CACHE CMAKE_INSTALL_PREFIX PROPERTY VALUE "${home}/${n}") | ||
endif() | ||
|
||
|
||
# Downloading URL instead of Git avoids very long "autogen" step | ||
ExternalProject_Add(MPI | ||
URL ${mpi_url} | ||
CONFIGURE_COMMAND <SOURCE_DIR>/configure ${mpi_flags} ${mpi_ldflags} | ||
BUILD_COMMAND ${MAKE_EXECUTABLE} -j${Ncpu} | ||
INSTALL_COMMAND ${MAKE_EXECUTABLE} install | ||
TEST_COMMAND "" | ||
USES_TERMINAL_DOWNLOAD true | ||
USES_TERMINAL_UPDATE true | ||
USES_TERMINAL_CONFIGURE true | ||
USES_TERMINAL_BUILD true | ||
USES_TERMINAL_INSTALL true | ||
USES_TERMINAL_TEST true | ||
CONFIGURE_HANDLED_BY_BUILD ON | ||
) | ||
|
||
|
||
if(mpich) | ||
message(STATUS "MPICH: ${mpi_url} => ${CMAKE_INSTALL_PREFIX}") | ||
else() | ||
message(STATUS "OpenMPI: ${mpi_url} => ${CMAKE_INSTALL_PREFIX}") | ||
endif() | ||
message(STATUS "MPI flags: ${mpi_flags}") | ||
message(STATUS "MPI LDFLAGS: ${mpi_ldflags}") | ||
|
||
|
||
# --- check that MPI-3 Fortran is working | ||
ExternalProject_add(MPItest | ||
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/test | ||
CMAKE_ARGS -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -DMPI_ROOT:PATH=${CMAKE_INSTALL_PREFIX} | ||
INSTALL_COMMAND "" | ||
CONFIGURE_HANDLED_BY_BUILD on | ||
DEPENDS MPI | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
# Build MPI | ||
|
||
This mini-project is to build MPI-3 library OpenMPI for those systems not having MPI for the desired compiler. | ||
|
||
```sh | ||
cmake -Bbuild --install-prefix $HOME/my_mpi | ||
|
||
cmake --build build | ||
``` | ||
|
||
## MPICH | ||
|
||
```sh | ||
cmake -Dmpich=yes | ||
``` | ||
|
||
builds MPICH instead of the default OpenMPI. | ||
|
||
Note that MPICH does [not yet work with Clang](https://releases.llvm.org/11.0.0/tools/flang/docs/RuntimeDescriptor.html#interoperability-requirements) | ||
This is particularly relevant for macOS, where Clang is the default compiler. | ||
|
||
A successful MPICH configure step ends like: | ||
|
||
``` | ||
config.status: executing gen_binding_f90 commands | ||
[ /scripts/mpi/build/MPI-prefix/src/MPI/maint/gen_binding_f90.py -f-logical-size=4 -ignore-tkr=gcc ] | ||
--> [src/binding/fortran/use_mpi/mpi_base.f90] | ||
--> [src/binding/fortran/use_mpi/mpi_constants.f90] | ||
--> [src/binding/fortran/use_mpi/mpi_sizeofs.f90] | ||
config.status: executing gen_binding_f08 commands | ||
[ /scripts/mpi/build/MPI-prefix/src/MPI/maint/gen_binding_f08.py -fint-size=4 -aint-size=8 -count-size=8 -cint-size=4 ] | ||
--> [src/binding/fortran/use_mpi_f08/wrappers_c/f08_cdesc.c] | ||
--> [src/binding/fortran/use_mpi_f08/wrappers_c/cdesc_proto.h] | ||
--> [src/binding/fortran/use_mpi_f08/wrappers_f/f08ts.f90] | ||
--> [src/binding/fortran/use_mpi_f08/wrappers_f/pf08ts.f90] | ||
--> [src/binding/fortran/use_mpi_f08/mpi_c_interface_cdesc.f90] | ||
--> [src/binding/fortran/use_mpi_f08/mpi_c_interface_nobuf.f90] | ||
--> [src/binding/fortran/use_mpi_f08/mpi_f08.f90] | ||
--> [src/binding/fortran/use_mpi_f08/pmpi_f08.f90] | ||
--> [src/binding/fortran/use_mpi_f08/mpi_f08_types.f90] | ||
***************************************************** | ||
*** | ||
*** device configuration: ch3:nemesis | ||
*** nemesis networks: tcp | ||
*** | ||
***************************************************** | ||
Configuration completed. | ||
``` | ||
|
||
and the internal MPICH header confdef.h must have `#define HAVE_F08_BINDING 1` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
cmake_minimum_required(VERSION 3.20) | ||
|
||
project(MPItest LANGUAGES C Fortran) | ||
|
||
enable_testing() | ||
|
||
include(CheckSourceCompiles) | ||
|
||
if(NOT DEFINED MPI_ROOT AND DEFINED ENV{MPI_ROOT}) | ||
set(MPI_ROOT $ENV{MPI_ROOT}) | ||
endif() | ||
if(MPI_ROOT) | ||
message(STATUS "Using MPI_ROOT=${MPI_ROOT}") | ||
else() | ||
message(STATUS "MPI_ROOT not set, using default MPI search paths") | ||
endif() | ||
|
||
set(MPI_DETERMINE_LIBRARY_VERSION true) | ||
|
||
find_package(MPI COMPONENTS C Fortran REQUIRED) | ||
|
||
message(STATUS "${MPI_Fortran_LIBRARY_VERSION_STRING}") | ||
message(STATUS "MPI libs: ${MPI_Fortran_LIBRARIES}") | ||
message(STATUS "MPI include: ${MPI_Fortran_INCLUDE_DIRS}") | ||
message(STATUS "MPI compile flags: ${MPI_Fortran_COMPILER_FLAGS}") | ||
message(STATUS "MPI link flags: ${MPI_Fortran_LINK_FLAGS}") | ||
|
||
if(MPI_Fortran_HAVE_F08_MODULE) | ||
return() | ||
endif() | ||
|
||
set(CMAKE_REQUIRED_LIBRARIES MPI::MPI_Fortran) | ||
|
||
# sometimes factory FindMPI.cmake doesn't define this | ||
message(CHECK_START "Checking for Fortran MPI-3 binding") | ||
check_source_compiles(Fortran | ||
[=[ | ||
program test | ||
use mpi_f08, only : mpi_comm_rank, mpi_real, mpi_comm_world, mpi_init, mpi_finalize | ||
implicit none | ||
call mpi_init | ||
call mpi_finalize | ||
end program | ||
]=] | ||
MPI_Fortran_HAVE_F08_MODULE | ||
) | ||
|
||
if(MPI_Fortran_HAVE_F08_MODULE) | ||
message(CHECK_PASS "yes") | ||
else() | ||
message(CHECK_FAIL "no") | ||
message(WARNING "MPI-3 Fortran module mpi_f08 not found, builds may fail.") | ||
endif() | ||
|
||
add_executable(test_mpi3 mpi3.f90) | ||
target_link_libraries(test_mpi3 PRIVATE MPI::MPI_Fortran) | ||
|
||
add_test(NAME test_mpi3 COMMAND test_mpi3) | ||
|
||
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.29) | ||
set_property(TARGET test_mpi3 PROPERTY TEST_LAUNCHER ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS}) | ||
else() | ||
set_property(TARGET test_mpi3 PROPERTY CROSSCOMPILING_EMULATOR ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS}) | ||
endif() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
program hw_mpi | ||
!! Each process prints out a "Hello, world!" message with a process ID | ||
!! Original Author: John Burkardt | ||
!! Modified: Michael Hirsch, Ph.D. | ||
|
||
use mpi_f08, only : mpi_init, mpi_comm_size, mpi_comm_world, mpi_wtime, mpi_comm_rank, mpi_finalize | ||
use, intrinsic:: iso_fortran_env, only: dp=>real64, compiler_version | ||
|
||
implicit none | ||
|
||
integer :: id, Nproc | ||
real(dp) :: wtime | ||
|
||
!> Initialize MPI. | ||
call MPI_Init() | ||
|
||
!> Get the number of processes. | ||
call MPI_Comm_size(MPI_COMM_WORLD, Nproc) | ||
|
||
!> Get the individual process ID. | ||
call MPI_Comm_rank(MPI_COMM_WORLD, id) | ||
|
||
!> Print a message. | ||
if (id == 0) then | ||
print *,compiler_version() | ||
wtime = MPI_Wtime() | ||
print *, 'number of processes: ', Nproc | ||
end if | ||
|
||
print *, 'Process ', id | ||
|
||
if (id == 0) then | ||
wtime = MPI_Wtime() - wtime | ||
print *, 'Elapsed wall clock time = ', wtime, ' seconds.' | ||
end if | ||
|
||
!> Shut down MPI. | ||
call MPI_Finalize() | ||
|
||
end program |
Oops, something went wrong.