Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions RELEASE-NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ The project release numbers follow [Semantic Versioning](http://semver.org/spec/
- Removed `-Winline` from being added to GoogleTest for Clang/Intel as it is a noop and caused a warning on Intel.
- Toggle GoogleTest adding `-Wno-implicit-float-size-conversion` or `-Wno-sycl-implicit-float-size-conversion` based on Intel version.
- Update CUDA runtime smoketest to be compatible with CUDA 13
- Adds `BLT_ALLOW_MISSING_MPI_WRAPPER` (default `OFF`) to allow setting up MPI without providing `MPI_<lang>_COMPILER` for some enabled languages.
This supports niche cases (e.g. Fortran enabled without a compatible `MPI_Fortran_COMPILER`) while preserving the default behavior of requiring wrappers.
- Checks for missing `MPI_<lang>_COMPILER` flags for each enabled language when `ENABLE_MPI` evaluates to `ON`
and `BLT_ALLOW_MISSING_MPI_WRAPPER` evaluates to `OFF`.

### Fixed
- In non-mpi configurations, `blt_add_test` will now throw a `FATAL_ERROR` if the user provides `NUM_MPI_RANKS`
Expand Down
12 changes: 12 additions & 0 deletions cmake/BLTOptions.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,17 @@ endif()
option(ENABLE_FORTRAN "Enables Fortran compiler support" ${_fortran_already_enabled})

option(ENABLE_MPI "Enables MPI support" OFF)

# By default, we require MPI_<langl>_COMPILER to be provided for each
# enabled language when ENABLE_MPI. The following options overrides this.
cmake_dependent_option(BLT_ALLOW_MISSING_MPI_WRAPPER
"Allow MPI_<lang>_COMPILER to be missing for some enabled languages"
OFF
"ENABLE_MPI"
OFF)
mark_as_advanced(BLT_ALLOW_MISSING_MPI_WRAPPER)


option(ENABLE_OPENMP "Enables OpenMP compiler support" OFF)
option(ENABLE_CUDA "Enable CUDA support" OFF)
cmake_dependent_option(ENABLE_CLANG_CUDA "Enable Clang's native CUDA support" OFF
Expand Down Expand Up @@ -146,6 +157,7 @@ set(BLT_RUN_BENCHMARKS_TARGET_NAME "run_benchmarks" CACHE STRING "Name of the ta
# All advanced options should be marked as advanced
mark_as_advanced(
ENABLE_FIND_MPI
BLT_ALLOW_MISSING_MPI_WRAPPER
ENABLE_GTEST_DEATH_TESTS
ENABLE_WRAP_ALL_TESTS_WITH_MPIEXEC
BLT_CODE_CHECK_TARGET_NAME
Expand Down
3 changes: 3 additions & 0 deletions cmake/BLTThirdPartyConfigFlags.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ endif()
if(NOT BLT_ENABLE_FIND_MPI)
set(BLT_ENABLE_FIND_MPI @ENABLE_FIND_MPI@)
endif()
if (NOT DEFINED BLT_ALLOW_MISSING_MPI_WRAPPER)
set(BLT_ALLOW_MISSING_MPI_WRAPPER @BLT_ALLOW_MISSING_MPI_WRAPPER@)
endif()

# Always prefer the current project if they turned it on
if(ENABLE_CLANG_CUDA)
Expand Down
120 changes: 89 additions & 31 deletions cmake/thirdparty/BLTSetupMPI.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,59 @@ set(_mpi_includes )
set(_mpi_libraries )
set(_mpi_link_flags )

# Users must provide MPI_<lang>_COMPILER variables for each enabled language unless BLT_ALLOW_MISSING_MPI_WRAPPER
# Check for each variable and print a warning/error message if appropriate
get_property(_enabled_languages GLOBAL PROPERTY ENABLED_LANGUAGES)

if(BLT_ENABLE_FIND_MPI)
if (BLT_ENABLE_FIND_MPI)
message(STATUS "FindMPI Enabled (ENABLE_FIND_MPI == ON)")

set(_blt_missing_mpi_wrappers)
foreach(_lang "C" "CXX" "Fortran")
if (${_lang} IN_LIST _enabled_languages AND NOT MPI_${_lang}_COMPILER)
list(APPEND _blt_missing_mpi_wrappers "MPI_${_lang}_COMPILER")
endif()
endforeach()

if (_blt_missing_mpi_wrappers)
if (BLT_ALLOW_MISSING_MPI_WRAPPER)
message(STATUS "BLT_ALLOW_MISSING_MPI_WRAPPER == ON. Proceeding without: ${_blt_missing_mpi_wrappers}")
else()
message(FATAL_ERROR
"MPI support is enabled, but missing MPI compiler wrapper(s): ${_blt_missing_mpi_wrappers}\n"
"Provide MPI_<lang>_COMPILER for each enabled language or set BLT_ALLOW_MISSING_MPI_WRAPPER=ON to bypass this check.")
endif()
endif()
unset(_blt_missing_mpi_wrappers)
else()
message(STATUS "FindMPI Disabled (ENABLE_FIND_MPI == OFF) ")
endif()

set(_blt_enable_mpi_c FALSE)
if("C" IN_LIST _enabled_languages AND MPI_C_COMPILER)
set(_blt_enable_mpi_c TRUE)
endif()

set(_blt_enable_mpi_cxx FALSE)
if("CXX" IN_LIST _enabled_languages AND MPI_CXX_COMPILER)
set(_blt_enable_mpi_cxx TRUE)
endif()

set(_blt_enable_mpi_fortran FALSE)
if ("Fortran" IN_LIST _enabled_languages AND MPI_Fortran_COMPILER)
set(_blt_enable_mpi_fortran TRUE)
endif()

if (BLT_ENABLE_FIND_MPI)
find_package(MPI REQUIRED)
if (BLT_ALLOW_MISSING_MPI_WRAPPER)
set(_blt_mpi_components)
blt_list_append(TO _blt_mpi_components ELEMENTS C IF _blt_enable_mpi_c)
blt_list_append(TO _blt_mpi_components ELEMENTS CXX IF _blt_enable_mpi_cxx)
blt_list_append(TO _blt_mpi_components ELEMENTS Fortran IF _blt_enable_mpi_fortran)
find_package(MPI REQUIRED COMPONENTS ${_blt_mpi_components})
else()
find_package(MPI REQUIRED)
endif()

#-------------------
# Merge found MPI info and remove duplication
Expand All @@ -49,27 +92,31 @@ if (BLT_ENABLE_FIND_MPI)
#-------------------
# Compile flags
#-------------------
set(_c_flag ${MPI_C_${_mpi_compile_flags_suffix}})
if (_c_flag AND BLT_ENABLE_CUDA)
list(APPEND _mpi_compile_flags
$<$<NOT:$<COMPILE_LANGUAGE:CUDA>>:${_c_flag}>
$<$<COMPILE_LANGUAGE:CUDA>:-Xcompiler=${_c_flag}>)
else()
list(APPEND _mpi_compile_flags ${_c_flag})
endif()

set(_cxx_flag ${MPI_CXX_${_mpi_compile_flags_suffix}})
if (_cxx_flag AND NOT "${_c_flag}" STREQUAL "${_cxx_flag}")
if (BLT_ENABLE_CUDA)
if(_blt_enable_mpi_c)
set(_c_flag ${MPI_C_${_mpi_compile_flags_suffix}})
if (_c_flag AND BLT_ENABLE_CUDA)
list(APPEND _mpi_compile_flags
$<$<NOT:$<COMPILE_LANGUAGE:CUDA>>:${_cxx_flag}>
$<$<COMPILE_LANGUAGE:CUDA>:-Xcompiler=${_cxx_flag}>)
$<$<NOT:$<COMPILE_LANGUAGE:CUDA>>:${_c_flag}>
$<$<COMPILE_LANGUAGE:CUDA>:-Xcompiler=${_c_flag}>)
else()
list(APPEND _mpi_compile_flags ${_cxx_flag})
list(APPEND _mpi_compile_flags ${_c_flag})
endif()
endif()

if (BLT_ENABLE_FORTRAN)
if(_blt_enable_mpi_cxx)
set(_cxx_flag ${MPI_CXX_${_mpi_compile_flags_suffix}})
if (_cxx_flag AND NOT "${_c_flag}" STREQUAL "${_cxx_flag}")
if (BLT_ENABLE_CUDA)
list(APPEND _mpi_compile_flags
$<$<NOT:$<COMPILE_LANGUAGE:CUDA>>:${_cxx_flag}>
$<$<COMPILE_LANGUAGE:CUDA>:-Xcompiler=${_cxx_flag}>)
else()
list(APPEND _mpi_compile_flags ${_cxx_flag})
endif()
endif()
endif()

if (_blt_enable_mpi_fortran)
set(_f_flag ${MPI_Fortran_${_mpi_compile_flags_suffix}})
if (_f_flag AND NOT "${_c_flag}" STREQUAL "${_f_flag}")
list(APPEND _mpi_compile_flags ${_f_flag})
Expand All @@ -82,25 +129,31 @@ if (BLT_ENABLE_FIND_MPI)
#-------------------
# Include paths
#-------------------
list(APPEND _mpi_includes ${MPI_C_${_mpi_includes_suffix}}
${MPI_CXX_${_mpi_includes_suffix}})
if (BLT_ENABLE_FORTRAN)
set(_mpi_includes)
if(_blt_enable_mpi_c)
list(APPEND _mpi_includes ${MPI_C_${_mpi_includes_suffix}})
endif()
if(_blt_enable_mpi_cxx)
list(APPEND _mpi_includes ${MPI_CXX_${_mpi_includes_suffix}})
endif()
if(_blt_enable_mpi_fortran)
list(APPEND _mpi_includes ${MPI_Fortran_${_mpi_includes_suffix}})
endif()
blt_list_remove_duplicates(TO _mpi_includes)

#-------------------
# Link flags
#-------------------
set(_mpi_link_flags ${MPI_C_LINK_FLAGS})
if (NOT "${MPI_C_LINK_FLAGS}" STREQUAL "${MPI_CXX_LINK_FLAGS}")
if(_blt_enable_mpi_c)
set(_mpi_link_flags ${MPI_C_LINK_FLAGS})
endif()

if(_blt_enable_mpi_cxx AND NOT "${_mpi_link_flags}" STREQUAL "${MPI_CXX_LINK_FLAGS}")
list(APPEND _mpi_link_flags ${MPI_CXX_LINK_FLAGS})
endif()
if (BLT_ENABLE_FORTRAN)
if ((NOT "${MPI_C_LINK_FLAGS}" STREQUAL "${MPI_Fortran_LINK_FLAGS}") AND
(NOT "${MPI_CXX_LINK_FLAGS}" STREQUAL "${MPI_Fortran_LINK_FLAGS}"))
list(APPEND _mpi_link_flags ${MPI_Fortran_LINK_FLAGS})
endif()

if (_blt_enable_mpi_fortran AND NOT "${_mpi_link_flags}" STREQUAL "${MPI_Fortran_LINK_FLAGS}")
list(APPEND _mpi_link_flags ${MPI_Fortran_LINK_FLAGS})
endif()

# Selectively remove set of known locations of spaces
Expand All @@ -121,8 +174,13 @@ if (BLT_ENABLE_FIND_MPI)
#-------------------
# Libraries
#-------------------
set(_mpi_libraries ${MPI_C_LIBRARIES} ${MPI_CXX_LIBRARIES})
if (BLT_ENABLE_FORTRAN)
if(_blt_enable_mpi_c)
list(APPEND _mpi_libraries ${MPI_C_LIBRARIES})
endif()
if(_blt_enable_mpi_cxx)
list(APPEND _mpi_libraries ${MPI_CXX_LIBRARIES})
endif()
if(_blt_enable_mpi_fortran)
list(APPEND _mpi_libraries ${MPI_Fortran_LIBRARIES})
endif()
blt_list_remove_duplicates(TO _mpi_libraries)
Expand Down Expand Up @@ -166,7 +224,7 @@ endif()
message(STATUS "MPI Num Proc Flag: ${MPIEXEC_NUMPROC_FLAG}")
message(STATUS "MPI Command Append: ${BLT_MPI_COMMAND_APPEND}")

if (BLT_ENABLE_FORTRAN)
if (_blt_enable_mpi_fortran)
# Determine if we should use fortran mpif.h header or fortran mpi module
find_path(mpif_path
NAMES "mpif.h"
Expand Down
11 changes: 11 additions & 0 deletions docs/tutorial/common_hpc_dependencies.rst
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ Our next example, ``test_2``, builds and tests the ``calc_pi_mpi`` library,
which uses MPI to parallelize the calculation over the integration intervals.

To enable MPI, we set ``ENABLE_MPI``, ``MPI_C_COMPILER``, and ``MPI_CXX_COMPILER``
(and ``MPI_Fortran_COMPILER`` if your project enables Fortran)
in our host config file. Here is a snippet with these settings for LLNL's Lassen Cluster:

.. literalinclude:: ../../host-configs/llnl/toss_4_x86_64_ib/gcc@10.3.1.cmake
Expand Down Expand Up @@ -84,6 +85,16 @@ Test. ``test_2.cpp`` provides an example driver for MPI with GoogleTest.
* ``BLT_MPI_LIBRARIES``
* ``BLT_MPI_LINK_FLAGS``

By default (when ``ENABLE_MPI`` and ``ENABLE_FIND_MPI`` are ``ON``), BLT requires
an ``MPI_<lang>_COMPILER`` wrapper for each enabled language (e.g. ``MPI_C_COMPILER``,
``MPI_CXX_COMPILER``, and/or ``MPI_Fortran_COMPILER``). If any required wrapper is
missing, BLT will stop with a configuration error.

For cases where a language is enabled but an MPI wrapper is unavailable or
incompatible (for example, enabling Fortran without a compatible ``MPI_Fortran_COMPILER``),
set ``BLT_ALLOW_MISSING_MPI_WRAPPER=ON``. BLT will print which wrappers are missing
and will only configure MPI support for the languages that have wrappers available.

BLT also has the variable ``ENABLE_FIND_MPI`` which turns off all CMake's ``FindMPI``
logic and then uses the MPI wrapper directly when you provide them as the default
compilers.
Expand Down
85 changes: 17 additions & 68 deletions docs/tutorial/host_configs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -31,20 +31,20 @@ These files use standard CMake commands. CMake ``set()`` commands need to specif
set(CMAKE_VARIABLE_NAME {VALUE} CACHE PATH "")

Here is a snippet from a host-config file that specifies compiler details for
using specific gcc (version 10.3.1 in this case) on the LLNL Pascal cluster:
using specific gcc (version 10.3.1 in this case) on the LLNL Dane cluster:

.. literalinclude:: ../../host-configs/llnl/toss_4_x86_64_ib/gcc@10.3.1_nvcc.cmake
:start-after: _blt_pascal_compiler_config_start
:end-before: _blt_pascal_compiler_config_end
.. literalinclude:: ../../host-configs/llnl/toss_4_x86_64_ib/gcc@10.3.1.cmake
:start-after: _blt_tutorial_compiler_config_start
:end-before: _blt_tutorial_compiler_config_end
:language: cmake


Building and Testing on Pascal
Building and Testing on Matrix
------------------------------

Since compute nodes on the Pascal cluster have CPUs and GPUs, here is how you
Since compute nodes on the Matrix cluster have CPUs and GPUs, here is how you
can use the host-config file to configure a build of the ``calc_pi`` project with
MPI and CUDA enabled on Pascal:
MPI and CUDA enabled on Matrix:

.. code-block:: bash

Expand All @@ -63,52 +63,6 @@ to run the unit tests that are using MPI and CUDA:
bash-4.1$ make
bash-4.1$ make test

Running tests...
Test project blt/docs/tutorial/calc_pi/build
Start 1: test_1
1/8 Test #1: test_1 ........................... Passed 0.01 sec
Start 2: test_2
2/8 Test #2: test_2 ........................... Passed 2.79 sec
Start 3: test_3
3/8 Test #3: test_3 ........................... Passed 0.54 sec
Start 4: blt_gtest_smoke
4/8 Test #4: blt_gtest_smoke .................. Passed 0.01 sec
Start 5: blt_fruit_smoke
5/8 Test #5: blt_fruit_smoke .................. Passed 0.01 sec
Start 6: blt_mpi_smoke
6/8 Test #6: blt_mpi_smoke .................... Passed 2.82 sec
Start 7: blt_cuda_smoke
7/8 Test #7: blt_cuda_smoke ................... Passed 0.48 sec
Start 8: blt_cuda_runtime_smoke
8/8 Test #8: blt_cuda_runtime_smoke ........... Passed 0.11 sec

100% tests passed, 0 tests failed out of 8

Total Test time (real) = 6.80 sec


Building and Testing on Matrix
------------------------------

Here is how you can use the host-config file to configure a build of the
``calc_pi`` project with MPI and CUDA enabled on the LLNL's Matrix cluster:

.. code-block:: bash

# create build dir
mkdir build
cd build
# configure using host-config
cmake -C ../../host-configs/llnl/toss_4_x86_64_ib/gcc@10.3.1_nvcc.cmake ..

And here is how to build and test the code on Matrix:

.. code-block:: console

bash-4.2$ salloc 1 -A <valid group>
bash-4.2$ make
bash-4.2$ make test

Running tests...
Test project projects/blt/docs/tutorial/calc_pi/build
Start 1: test_1
Expand All @@ -128,8 +82,7 @@ And here is how to build and test the code on Matrix:

100% tests passed, 0 tests failed out of 7

Total Test time (real) = 2.47 sec

Total Test time (real) = 2.47 sec

Building and Testing on Summit
-------------------------------
Expand Down Expand Up @@ -190,7 +143,7 @@ And here is how to build and test the code on Summit:
Example Host-configs
--------------------

Basic TOSS3 (for example: Quartz) host-config that has C, C++, and Fortran Compilers along with MPI support:
Basic TOSS4 (for example: Dane) host-config that has C, C++, and Fortran Compilers along with MPI support:

.. container:: toggle

Expand All @@ -202,20 +155,16 @@ Basic TOSS3 (for example: Quartz) host-config that has C, C++, and Fortran Compi
:language: cmake
:linenos:

Here are the full example host-config files for LLNL's Pascal, Lassen,
and Quartz Clusters that uses the default compilers on the system:
.. note::
When ``ENABLE_MPI`` is ``ON`` and you are using CMake's ``FindMPI`` (the default,
``ENABLE_FIND_MPI=ON``), BLT expects an ``MPI_<lang>_COMPILER`` wrapper for each
enabled language. For example, if you enable Fortran, also set
``MPI_Fortran_COMPILER`` in your host-config.

.. container:: toggle

.. container:: label

``gcc@10.3.1 host-config``

.. literalinclude:: ../../host-configs/llnl/toss_4_x86_64_ib/gcc@10.3.1_nvcc.cmake
:language: cmake
:linenos:
If a wrapper is unavailable or incompatible for a specific language, you can set
``BLT_ALLOW_MISSING_MPI_WRAPPER=ON`` to allow configuring MPI without that wrapper.

More complicated host-config that has C, C++, MPI, and CUDA support:
Here is the full example host-config files for LLNL's Matrix Cluster that uses C, C++, MPI, and CUDA support:

.. container:: toggle

Expand Down
Loading