diff --git a/CMakeLists.txt b/CMakeLists.txt index fad0058ba..1b2c05ef3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,6 +42,7 @@ include(ReplaceIdefixSource) include(AddIdefixSource) include(SetIdefixProperty) include(SetRequiredBuildSettingsForGCC8) +include(CheckHdf5ParallelSupport) #Idefix requires Cuda Lambdas (experimental) if(Kokkos_ENABLE_CUDA) @@ -113,12 +114,25 @@ if(Idefix_HDF5) PUBLIC src/output/xdmf.cpp PUBLIC src/output/xdmf.hpp ) - find_package(HDF5 REQUIRED) - target_link_libraries(idefix "${HDF5_LIBRARIES}") + # Prefer imported targets (matches older working behavior), then fall back. + find_package(HDF5 QUIET COMPONENTS C) + if(NOT HDF5_FOUND) + find_package(HDF5 REQUIRED MODULE COMPONENTS C) + endif() + + set(_idefix_hdf5_link_items "${HDF5_LIBRARIES}") + if(TARGET hdf5::hdf5) + set(_idefix_hdf5_link_items hdf5::hdf5) + elseif(TARGET HDF5::HDF5) + set(_idefix_hdf5_link_items HDF5::HDF5) + endif() + + target_link_libraries(idefix ${_idefix_hdf5_link_items}) message(STATUS "Found HDF5 include directories: ${HDF5_INCLUDE_DIRS}") target_include_directories(idefix PUBLIC "${HDF5_INCLUDE_DIRS}") if(Idefix_MPI) - if(NOT HDF5_IS_PARALLEL) + CheckHdf5ParallelSupport("${_idefix_hdf5_link_items}") + if(NOT IDEFIX_HDF5_IS_PARALLEL) message(FATAL_ERROR "Parallel HDF5 required for Idefix_MPI but the found HDF5 library does not support it") endif() endif() diff --git a/cmake/CheckHdf5ParallelSupport.cmake b/cmake/CheckHdf5ParallelSupport.cmake new file mode 100644 index 000000000..aae651a17 --- /dev/null +++ b/cmake/CheckHdf5ParallelSupport.cmake @@ -0,0 +1,50 @@ +include(CheckCSourceCompiles) + +# Check whether the HDF5 library found by find_package(HDF5) supports parallel +# (MPI-IO) access, and store the result in IDEFIX_HDF5_IS_PARALLEL in the +# caller's scope. +# +# Usage: CheckHdf5ParallelSupport() +# where is the list of HDF5 targets/libraries to link against. +# +# Some CMake/HDF5 combinations do not reliably set HDF5_IS_PARALLEL (e.g. when +# HDF5 is found via its CMake config package rather than the FindHDF5 module). +# Combine metadata checks with a compile+link probe for the MPI-IO symbols to +# reliably detect parallel HDF5. +function(CheckHdf5ParallelSupport hdf5_link_items) + set(_idefix_hdf5_is_parallel FALSE) + if(HDF5_IS_PARALLEL OR HDF5_C_IS_PARALLEL) + set(_idefix_hdf5_is_parallel TRUE) + endif() + + if(NOT _idefix_hdf5_is_parallel AND DEFINED HDF5_C_COMPILER_EXECUTABLE) + execute_process( + COMMAND "${HDF5_C_COMPILER_EXECUTABLE}" -showconfig + OUTPUT_VARIABLE _idefix_hdf5_showconfig + ERROR_QUIET + ) + if(_idefix_hdf5_showconfig MATCHES "Parallel HDF5:[ \t]*yes") + set(_idefix_hdf5_is_parallel TRUE) + endif() + endif() + + set(CMAKE_REQUIRED_INCLUDES ${HDF5_INCLUDE_DIRS} ${MPI_C_INCLUDE_DIRS}) + set(CMAKE_REQUIRED_LIBRARIES ${hdf5_link_items} MPI::MPI_C) + check_c_source_compiles( + "#include + #include + int main(void) { + hid_t plist = H5Pcreate(H5P_FILE_ACCESS); + H5Pset_fapl_mpio(plist, MPI_COMM_WORLD, MPI_INFO_NULL); + H5Pclose(plist); + return 0; + }" + IDEFIX_HDF5_HAS_MPI_IO + ) + + if(IDEFIX_HDF5_HAS_MPI_IO) + set(_idefix_hdf5_is_parallel TRUE) + endif() + + set(IDEFIX_HDF5_IS_PARALLEL ${_idefix_hdf5_is_parallel} PARENT_SCOPE) +endfunction() diff --git a/src/fluid/showConfig.hpp b/src/fluid/showConfig.hpp index f3a144304..0f8b64ed9 100644 --- a/src/fluid/showConfig.hpp +++ b/src/fluid/showConfig.hpp @@ -60,7 +60,7 @@ void Fluid::ShowConfig() { << ": Ohmic resistivity ENABLED with user-defined resistivity function." << std::endl; if(!ohmicDiffusivityFunc) { - IDEFIX_ERROR("No user-defined Ihmic resistivity function has been enrolled."); + IDEFIX_ERROR("No user-defined Ohmic resistivity function has been enrolled."); } } else { IDEFIX_ERROR("Unknown Ohmic resistivity mode"); diff --git a/src/output/xdmf.cpp b/src/output/xdmf.cpp index 4e7ff6843..f08819003 100644 --- a/src/output/xdmf.cpp +++ b/src/output/xdmf.cpp @@ -295,7 +295,7 @@ int Xdmf::Write() { #if DIMENSIONS == 1 [[maybe_unused]] int tot_dim = 1; #elif DIMENSIONS == 2 - int tot_dim = 2; + [[maybe_unused]] int tot_dim = 2; #elif DIMENSIONS == 3 [[maybe_unused]] int tot_dim = 3; #endif