Skip to content

Commit

Permalink
Merge pull request #415 from GEOS-ESM/feature/mathomp4/mpi-stack-bett…
Browse files Browse the repository at this point in the history
…er-v3

v3: Fix multiple MPI_STACK sets
  • Loading branch information
mathomp4 authored Dec 2, 2024
2 parents 79b174f + 3a8cca5 commit ee49277
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 50 deletions.
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Deprecated

## [3.52.0] - 2024-11-13
## [3.55.0] - 2024-12-02

### Fixed

- Fixed bad behavior in the `MPI_STACK` detection on subsequent calls to `DetermineMPIStack`

## [3.54.0] - 2024-11-13

### Fixed

Expand Down
110 changes: 61 additions & 49 deletions external_libraries/DetermineMPIStack.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -4,57 +4,69 @@ include(CMakePrintHelpers)

set(ALLOWED_MPI_STACKS "intelmpi;mvapich;mpt;mpich;openmpi")

if (MPI_STACK)
if (NOT MPI_STACK IN_LIST ALLOWED_MPI_STACKS)
message(FATAL_ERROR "MPI_STACK must be one of the following: ${ALLOWED_MPI_STACKS}")
else()
set(MPI_STACK_TYPE "User Specified")
message(WARNING "MPI_STACK is user specified. Please ensure that the specified MPI stack is compatible with the build. NOTE: MPI_STACK_VERSION is not being set.")
endif()
else ()
message(STATUS "MPI_STACK not specified. Attempting to autodetect MPI stack...")
message(DEBUG "MPI_Fortran_LIBRARY_VERSION_STRING: ${MPI_Fortran_LIBRARY_VERSION_STRING}")
# Define a helper variable to track whether the block was processed
# This let's us avoid weird warnings since MPI_STACK was defined
# in the first run
if (NOT DEFINED MPI_STACK_PROCESSED)
set(MPI_STACK_PROCESSED OFF CACHE INTERNAL "Flag to track if MPI_STACK block was processed")
endif()

string(REPLACE " " ";" MPI_Fortran_LIBRARY_VERSION_LIST ${MPI_Fortran_LIBRARY_VERSION_STRING})
message(DEBUG "MPI_Fortran_LIBRARY_VERSION_LIST: ${MPI_Fortran_LIBRARY_VERSION_LIST}")
list(GET MPI_Fortran_LIBRARY_VERSION_LIST 0 MPI_Fortran_LIBRARY_VERSION_FIRSTWORD)
message(DEBUG "MPI_Fortran_LIBRARY_VERSION_FIRSTWORD: ${MPI_Fortran_LIBRARY_VERSION_FIRSTWORD}")
if (NOT MPI_STACK_PROCESSED)
set(MPI_STACK_PROCESSED ON CACHE INTERNAL "Flag to track if MPI_STACK block was processed")
if (MPI_STACK)
if (NOT MPI_STACK IN_LIST ALLOWED_MPI_STACKS)
message(FATAL_ERROR "MPI_STACK must be one of the following: ${ALLOWED_MPI_STACKS}")
else()
set(MPI_STACK_TYPE "User Specified")
message(WARNING "MPI_STACK is user specified. Please ensure that the specified MPI stack is compatible with the build. NOTE: MPI_STACK_VERSION is not being set.")
endif()
else ()
message(STATUS "MPI_STACK not specified. Attempting to autodetect MPI stack...")
message(DEBUG "MPI_Fortran_LIBRARY_VERSION_STRING: ${MPI_Fortran_LIBRARY_VERSION_STRING}")

if(MPI_Fortran_LIBRARY_VERSION_STRING MATCHES "Intel")
set(MPI_STACK intelmpi)
list(GET MPI_Fortran_LIBRARY_VERSION_LIST 3 MPI_STACK_VERSION)
elseif(MPI_Fortran_LIBRARY_VERSION_STRING MATCHES "MVAPICH")
set(MPI_STACK mvapich)
# MVAPICH output for MPI_Fortran_LIBRARY_VERSION_STRING is complex and multi-line.
# So we need to extract the first line from that multi-line string.
string(REGEX REPLACE "\n.*" "" MPI_Fortran_LIBRARY_VERSION_STRING_FIRST_LINE ${MPI_Fortran_LIBRARY_VERSION_STRING})
# Now we need to grab the last word from the first line of the string
string(REGEX MATCH "[^ ]+$" MPI_STACK_VERSION ${MPI_Fortran_LIBRARY_VERSION_STRING_FIRST_LINE})
# Now we need to remove any colons, spaces, tabs, etc., but keep dots and letters.
string(REGEX REPLACE "[^a-zA-Z0-9.]" "" MPI_STACK_VERSION ${MPI_STACK_VERSION})
elseif(MPI_Fortran_LIBRARY_VERSION_STRING MATCHES "MPT")
set(MPI_STACK mpt)
list(GET MPI_Fortran_LIBRARY_VERSION_LIST 2 MPI_STACK_VERSION)
elseif(MPI_Fortran_LIBRARY_VERSION_STRING MATCHES "MPICH")
set(MPI_STACK mpich)
# MPICH output for MPI_Fortran_LIBRARY_VERSION_STRING is complex and multi-line.
# So we need to extract the first line from that multi-line string.
string(REGEX REPLACE "\n.*" "" MPI_Fortran_LIBRARY_VERSION_STRING_FIRST_LINE ${MPI_Fortran_LIBRARY_VERSION_STRING})
# Now we need to grab the last word from the first line of the string
string(REGEX MATCH "[^ ]+$" MPI_STACK_VERSION ${MPI_Fortran_LIBRARY_VERSION_STRING_FIRST_LINE})
# Now we need to remove any colons, spaces, tabs, etc., but keep dots and letters.
string(REGEX REPLACE "[^a-zA-Z0-9.]" "" MPI_STACK_VERSION ${MPI_STACK_VERSION})
elseif(MPI_Fortran_LIBRARY_VERSION_STRING MATCHES "Open MPI")
set(MPI_STACK openmpi)
list(GET MPI_Fortran_LIBRARY_VERSION_LIST 2 DETECTED_MPI_STACK_VERSION_STRING_WITH_COMMA)
string(REPLACE "," "" DETECTED_MPI_STACK_VERSION_STRING_WITH_V ${DETECTED_MPI_STACK_VERSION_STRING_WITH_COMMA})
string(REPLACE "v" "" MPI_STACK_VERSION ${DETECTED_MPI_STACK_VERSION_STRING_WITH_V})
else()
message (FATAL_ERROR "ERROR: MPI_STACK autodetection failed. Must specify a value for MPI_STACK with cmake ... -DMPI_STACK=<mpistack>. The acceptable values are: intelmpi, mvapich, mpt, mpich, openmpi")
string(REPLACE " " ";" MPI_Fortran_LIBRARY_VERSION_LIST ${MPI_Fortran_LIBRARY_VERSION_STRING})
message(DEBUG "MPI_Fortran_LIBRARY_VERSION_LIST: ${MPI_Fortran_LIBRARY_VERSION_LIST}")
list(GET MPI_Fortran_LIBRARY_VERSION_LIST 0 MPI_Fortran_LIBRARY_VERSION_FIRSTWORD)
message(DEBUG "MPI_Fortran_LIBRARY_VERSION_FIRSTWORD: ${MPI_Fortran_LIBRARY_VERSION_FIRSTWORD}")

if(MPI_Fortran_LIBRARY_VERSION_STRING MATCHES "Intel")
set(MPI_STACK intelmpi)
list(GET MPI_Fortran_LIBRARY_VERSION_LIST 3 MPI_STACK_VERSION)
elseif(MPI_Fortran_LIBRARY_VERSION_STRING MATCHES "MVAPICH")
set(MPI_STACK mvapich)
# MVAPICH output for MPI_Fortran_LIBRARY_VERSION_STRING is complex and multi-line.
# So we need to extract the first line from that multi-line string.
string(REGEX REPLACE "\n.*" "" MPI_Fortran_LIBRARY_VERSION_STRING_FIRST_LINE ${MPI_Fortran_LIBRARY_VERSION_STRING})
# Now we need to grab the last word from the first line of the string
string(REGEX MATCH "[^ ]+$" MPI_STACK_VERSION ${MPI_Fortran_LIBRARY_VERSION_STRING_FIRST_LINE})
# Now we need to remove any colons, spaces, tabs, etc., but keep dots and letters.
string(REGEX REPLACE "[^a-zA-Z0-9.]" "" MPI_STACK_VERSION ${MPI_STACK_VERSION})
elseif(MPI_Fortran_LIBRARY_VERSION_STRING MATCHES "MPT")
set(MPI_STACK mpt)
list(GET MPI_Fortran_LIBRARY_VERSION_LIST 2 MPI_STACK_VERSION)
elseif(MPI_Fortran_LIBRARY_VERSION_STRING MATCHES "MPICH")
set(MPI_STACK mpich)
# MPICH output for MPI_Fortran_LIBRARY_VERSION_STRING is complex and multi-line.
# So we need to extract the first line from that multi-line string.
string(REGEX REPLACE "\n.*" "" MPI_Fortran_LIBRARY_VERSION_STRING_FIRST_LINE ${MPI_Fortran_LIBRARY_VERSION_STRING})
# Now we need to grab the last word from the first line of the string
string(REGEX MATCH "[^ ]+$" MPI_STACK_VERSION ${MPI_Fortran_LIBRARY_VERSION_STRING_FIRST_LINE})
# Now we need to remove any colons, spaces, tabs, etc., but keep dots and letters.
string(REGEX REPLACE "[^a-zA-Z0-9.]" "" MPI_STACK_VERSION ${MPI_STACK_VERSION})
elseif(MPI_Fortran_LIBRARY_VERSION_STRING MATCHES "Open MPI")
set(MPI_STACK openmpi)
list(GET MPI_Fortran_LIBRARY_VERSION_LIST 2 DETECTED_MPI_STACK_VERSION_STRING_WITH_COMMA)
string(REPLACE "," "" DETECTED_MPI_STACK_VERSION_STRING_WITH_V ${DETECTED_MPI_STACK_VERSION_STRING_WITH_COMMA})
string(REPLACE "v" "" MPI_STACK_VERSION ${DETECTED_MPI_STACK_VERSION_STRING_WITH_V})
else()
message (FATAL_ERROR "ERROR: MPI_STACK autodetection failed. Must specify a value for MPI_STACK with cmake ... -DMPI_STACK=<mpistack>. The acceptable values are: intelmpi, mvapich, mpt, mpich, openmpi")
endif()
set(MPI_STACK_TYPE "Autodetected")
endif()
set(MPI_STACK_TYPE "Autodetected")
endif()

set(MPI_STACK "${MPI_STACK}" CACHE STRING "MPI_STACK Value")
set(MPI_STACK_VERSION "${MPI_STACK_VERSION}" CACHE STRING "MPI_STACK_VERSION Value")
set(MPI_STACK "${MPI_STACK}" CACHE STRING "MPI_STACK Value")
set(MPI_STACK_VERSION "${MPI_STACK_VERSION}" CACHE STRING "MPI_STACK_VERSION Value")
else ()
message(STATUS "MPI_STACK previously detected.")
endif ()
message(STATUS "Using ${MPI_STACK_TYPE} MPI_STACK: ${MPI_STACK}. Version: ${MPI_STACK_VERSION}")

0 comments on commit ee49277

Please sign in to comment.