From 1258c287f4b98e3d40e8e08a7cb6355b84853759 Mon Sep 17 00:00:00 2001 From: glesur Date: Mon, 24 Aug 2026 12:30:07 +0200 Subject: [PATCH 1/8] follow cines proposition to fix Kokkos5 performances on AMD Mi250 --- src/loop.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/loop.hpp b/src/loop.hpp index 42192fa84..319ad8553 100644 --- a/src/loop.hpp +++ b/src/loop.hpp @@ -85,7 +85,7 @@ inline void idefix_for(const std::string & NAME, idfx::pushRegion("idefix_for("+NAME+")"); #endif const int NI = IE - IB; - Kokkos::parallel_for(NAME, NI, + Kokkos::parallel_for(NAME, Kokkos::RangePolicy>(0, NI), KOKKOS_LAMBDA (const int& IDX) { int i = IDX; i += IB; @@ -112,7 +112,7 @@ inline void idefix_for(const std::string & NAME, const int NJ = JE - JB; const int NI = IE - IB; const int NJNI = NJ * NI; - Kokkos::parallel_for(NAME, NJNI, + Kokkos::parallel_for(NAME, Kokkos::RangePolicy>(0, NJNI), KOKKOS_LAMBDA (const int& IDX) { int j = IDX / NI; int i = IDX - j*NI; @@ -172,7 +172,7 @@ inline void idefix_for(const std::string & NAME, const int NI = IE - IB; const int NKNJNI = NK*NJ*NI; const int NJNI = NJ * NI; - Kokkos::parallel_for(NAME,NKNJNI, + Kokkos::parallel_for(NAME,Kokkos::RangePolicy>(0, NKNJNI), KOKKOS_LAMBDA (const int& IDX) { int k = IDX / NJNI; int j = (IDX - k*NJNI) / NI; @@ -259,7 +259,7 @@ inline void idefix_for(const std::string & NAME, const int NNNKNJNI = NN*NK*NJ*NI; const int NKNJNI = NK*NJ*NI; const int NJNI = NJ * NI; - Kokkos::parallel_for(NAME,NNNKNJNI, + Kokkos::parallel_for(NAME,Kokkos::RangePolicy>(0, NNNKNJNI), KOKKOS_LAMBDA (const int& IDX) { int n = IDX / NKNJNI; int k = (IDX - n*NKNJNI) / NJNI; From 525ab76c816bf33d8599823bd44ec1852265e9e5 Mon Sep 17 00:00:00 2001 From: Geoffroy Lesur Date: Tue, 25 Aug 2026 11:00:49 +0200 Subject: [PATCH 2/8] use Cmake config file to pass CMake variables to Idefix. Add compiler infos to idefix. --- CMakeLists.txt | 22 ++++++++++++++++------ src/compiler_info.h.in | 17 +++++++++++++++++ src/dataBlock/dumpToFile.cpp | 3 ++- src/input.cpp | 11 ++++++++--- src/output/dump.cpp | 3 ++- src/output/vtk.cpp | 3 ++- src/output/xdmf.cpp | 3 ++- src/version.h.in | 19 +++++++++++++++++++ 8 files changed, 68 insertions(+), 13 deletions(-) create mode 100644 src/compiler_info.h.in create mode 100644 src/version.h.in diff --git a/CMakeLists.txt b/CMakeLists.txt index 1b2c05ef3..23b110707 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -183,14 +183,15 @@ if(Idefix_EVOLVE_VECTOR_POTENTIAL) endif() #update version.hpp if possible git_describe(GIT_SHA1) -set(Idefix_VERSION ${Idefix_VERSION_MAJOR}.${Idefix_VERSION_MINOR}.${Idefix_VERSION_PATCH}-${GIT_SHA1}) -file(WRITE ${CMAKE_SOURCE_DIR}/src/version.hpp "#define IDEFIX_GIT_COMMIT \"${GIT_SHA1}\"\n") -file(APPEND ${CMAKE_SOURCE_DIR}/src/version.hpp "#define IDEFIX_VERSION_MAJOR \"${Idefix_VERSION_MAJOR}\"\n") -file(APPEND ${CMAKE_SOURCE_DIR}/src/version.hpp "#define IDEFIX_VERSION_MINOR \"${Idefix_VERSION_MINOR}\"\n") -file(APPEND ${CMAKE_SOURCE_DIR}/src/version.hpp "#define IDEFIX_VERSION_PATCH \"${Idefix_VERSION_PATCH}\"\n") -file(APPEND ${CMAKE_SOURCE_DIR}/src/version.hpp "#define IDEFIX_VERSION \"${Idefix_VERSION}\"\n") +set(Idefix_VERSION ${Idefix_VERSION_MAJOR}.${Idefix_VERSION_MINOR}.${Idefix_VERSION_PATCH}-${GIT_SHA1}) +configure_file( + ${CMAKE_SOURCE_DIR}/src/version.h.in + ${CMAKE_BINARY_DIR}/build/generated/version.h + @ONLY +) + if(NOT ${Idefix_DEFS} STREQUAL "definitions.hpp") add_compile_definitions("DEFINITIONS_FILE=\"${Idefix_DEFS}\"") endif() @@ -269,6 +270,15 @@ target_include_directories(idefix PUBLIC target_link_libraries(idefix Kokkos::kokkos) +# Generate header with compiler information (name, flags, path) +configure_file( + ${CMAKE_SOURCE_DIR}/src/compiler_info.h.in + ${CMAKE_BINARY_DIR}/build/generated/compiler_info.h + @ONLY +) +# Make sure the generated header is on the include path +target_include_directories(idefix PRIVATE ${CMAKE_BINARY_DIR}/build/generated) + message(STATUS "Idefix final configuration") if(Idefix_EVOLVE_VECTOR_POTENTIAL) message(STATUS " MHD: ${Idefix_MHD} (Vector potential)") diff --git a/src/compiler_info.h.in b/src/compiler_info.h.in new file mode 100644 index 000000000..140eafd79 --- /dev/null +++ b/src/compiler_info.h.in @@ -0,0 +1,17 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// Copyright(C) Geoffroy R. J. Lesur +// and other code contributors +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + +#ifndef COMPILER_INFO_H +#define COMPILER_INFO_H + +namespace CompilerInfo { + inline constexpr const char* name = "@CMAKE_CXX_COMPILER_ID@"; + inline constexpr const char* version = "@CMAKE_CXX_COMPILER_VERSION@"; + inline constexpr const char* path = "@CMAKE_CXX_COMPILER@"; +} + +#endif diff --git a/src/dataBlock/dumpToFile.cpp b/src/dataBlock/dumpToFile.cpp index f20dde838..690447b24 100644 --- a/src/dataBlock/dumpToFile.cpp +++ b/src/dataBlock/dumpToFile.cpp @@ -11,6 +11,7 @@ #include "dataBlock.hpp" #include "version.hpp" #include "fluid.hpp" +#include "version.h" #define NAMESIZE 16 #define HEADERSIZE 128 @@ -78,7 +79,7 @@ void DataBlock::DumpToFile(std::string filebase) { // Write Header char header[HEADERSIZE]; - std::snprintf(header, HEADERSIZE, "Idefix %s Debug DataBlock", IDEFIX_VERSION); + std::snprintf(header, HEADERSIZE, "Idefix %s Debug DataBlock", VersionInfo::version); fwrite (header, sizeof(char), HEADERSIZE, fileHdl); // Write Vc diff --git a/src/input.cpp b/src/input.cpp index 336414953..c397e3f26 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -20,6 +20,8 @@ #include "input.hpp" #include "version.hpp" #include "profiler.hpp" +#include "version.h" +#include "compiler_info.h" // Flag will be set if a signal has been received bool Input::abortRequested = false; @@ -415,7 +417,10 @@ void Input::PrintOptions() { } void Input::PrintVersion() { - idfx::cout << " Idefix version " << IDEFIX_VERSION << std::endl; - idfx::cout << " Built against Kokkos " << KOKKOS_VERSION << std::endl; - idfx::cout << " Compiled on " << __DATE__ << " at " << __TIME__ << std::endl; + idfx::cout << "Idefix version " << VersionInfo::version << std::endl; + idfx::cout << "Built against Kokkos " << KOKKOS_VERSION << std::endl; + idfx::cout << "Compiled on " << __DATE__ << " at " << __TIME__ << std::endl; + idfx::cout << "Compiler name: " << CompilerInfo::name << std::endl; + idfx::cout << "Compiler version: " << CompilerInfo::version << std::endl; + idfx::cout << "Compiler path: " << CompilerInfo::path << std::endl; } diff --git a/src/output/dump.cpp b/src/output/dump.cpp index 96a40b548..f521746b2 100644 --- a/src/output/dump.cpp +++ b/src/output/dump.cpp @@ -25,6 +25,7 @@ #include "gridHost.hpp" #include "output.hpp" #include "fluid.hpp" +#include "version.h" // Max size of array name #define NAMESIZE 16 @@ -880,7 +881,7 @@ int Dump::Write(Output& output) { char header[HEADERSIZE]; std::snprintf(header, HEADERSIZE, "Idefix %s Dump Data %s endian", - IDEFIX_VERSION, endian.c_str()); + VersionInfo::version, endian.c_str()); WriteString(fileHdl, header, HEADERSIZE); for(int dir = 0; dir < 3 ; dir++) { diff --git a/src/output/vtk.cpp b/src/output/vtk.cpp index 98e4c2577..eafeab847 100644 --- a/src/output/vtk.cpp +++ b/src/output/vtk.cpp @@ -26,6 +26,7 @@ #include "gridHost.hpp" #include "output.hpp" #include "fluid.hpp" +#include "version.h" #define VTK_RECTILINEAR_GRID 14 #define VTK_STRUCTURED_GRID 35 @@ -385,7 +386,7 @@ void Vtk::WriteHeader(IdfxFileHandler fvtk, real time) { 2. Header ------------------------------------------- */ - ssheader << "Idefix " << IDEFIX_VERSION << " VTK Data" << std::endl; + ssheader << "Idefix " << VersionInfo::version << " VTK Data" << std::endl; /* ------------------------------------------ 3. File format diff --git a/src/output/xdmf.cpp b/src/output/xdmf.cpp index f08819003..fc16353f8 100644 --- a/src/output/xdmf.cpp +++ b/src/output/xdmf.cpp @@ -26,6 +26,7 @@ #include "dataBlockHost.hpp" #include "gridHost.hpp" #include "output.hpp" +#include "version.h" // Whether or not we write the time in the XDMF file #define WRITE_TIME @@ -526,7 +527,7 @@ void Xdmf::WriteHeader( dimstr = 1; - ssheader << "Idefix " << IDEFIX_VERSION << " XDMF Data"; + ssheader << "Idefix " << VersionInfo::version << " XDMF Data"; strspace = H5Screate_simple(1, &dimstr, NULL); string_type = H5Tcopy(H5T_C_S1); H5Tset_size(string_type, strlen( ssheader.str().c_str() )); diff --git a/src/version.h.in b/src/version.h.in new file mode 100644 index 000000000..5561658aa --- /dev/null +++ b/src/version.h.in @@ -0,0 +1,19 @@ +// *********************************************************************************** +// Idefix MHD astrophysical code +// Copyright(C) Geoffroy R. J. Lesur +// and other code contributors +// Licensed under CeCILL 2.1 License, see COPYING for more information +// *********************************************************************************** + +#ifndef VERSION_H +#define VERSION_H + +namespace VersionInfo { + inline constexpr const char* gitCommit = "@GIT_SHA1@"; + inline constexpr const char* versionMajor = "@Idefix_VERSION_MAJOR@"; + inline constexpr const char* versionMinor = "@Idefix_VERSION_MINOR@"; + inline constexpr const char* versionPatch = "@Idefix_VERSION_PATCH@"; + inline constexpr const char* version = "@Idefix_VERSION@"; +} + +#endif From b32c7b44a04dce8a54aeb052a80df507d0f279a2 Mon Sep 17 00:00:00 2001 From: Geoffroy Lesur Date: Tue, 25 Aug 2026 11:29:58 +0200 Subject: [PATCH 3/8] clean up old references to version.hpp --- CMakeLists.txt | 5 ++--- src/dataBlock/dumpToFile.cpp | 1 - src/input.cpp | 1 - src/output/dump.cpp | 1 - src/output/vtk.cpp | 1 - src/output/xdmf.cpp | 1 - 6 files changed, 2 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 23b110707..08825827c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -181,10 +181,9 @@ endif() if(Idefix_EVOLVE_VECTOR_POTENTIAL) add_compile_definitions("EVOLVE_VECTOR_POTENTIAL") endif() -#update version.hpp if possible -git_describe(GIT_SHA1) - +# determine idefix version from git +git_describe(GIT_SHA1) set(Idefix_VERSION ${Idefix_VERSION_MAJOR}.${Idefix_VERSION_MINOR}.${Idefix_VERSION_PATCH}-${GIT_SHA1}) configure_file( ${CMAKE_SOURCE_DIR}/src/version.h.in diff --git a/src/dataBlock/dumpToFile.cpp b/src/dataBlock/dumpToFile.cpp index 690447b24..305b417a7 100644 --- a/src/dataBlock/dumpToFile.cpp +++ b/src/dataBlock/dumpToFile.cpp @@ -9,7 +9,6 @@ #include #include "../idefix.hpp" #include "dataBlock.hpp" -#include "version.hpp" #include "fluid.hpp" #include "version.h" diff --git a/src/input.cpp b/src/input.cpp index c397e3f26..6be052f66 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -18,7 +18,6 @@ #include "idefix.hpp" #include "input.hpp" -#include "version.hpp" #include "profiler.hpp" #include "version.h" #include "compiler_info.h" diff --git a/src/output/dump.cpp b/src/output/dump.cpp index f521746b2..d20eec265 100644 --- a/src/output/dump.cpp +++ b/src/output/dump.cpp @@ -20,7 +20,6 @@ #include #include #include "dump.hpp" -#include "version.hpp" #include "dataBlockHost.hpp" #include "gridHost.hpp" #include "output.hpp" diff --git a/src/output/vtk.cpp b/src/output/vtk.cpp index eafeab847..fb04e03de 100644 --- a/src/output/vtk.cpp +++ b/src/output/vtk.cpp @@ -20,7 +20,6 @@ #else error "Missing the header." #endif -#include "version.hpp" #include "idefix.hpp" #include "dataBlock.hpp" #include "gridHost.hpp" diff --git a/src/output/xdmf.cpp b/src/output/xdmf.cpp index fc16353f8..7d559a6d6 100644 --- a/src/output/xdmf.cpp +++ b/src/output/xdmf.cpp @@ -21,7 +21,6 @@ #endif #include "xdmf.hpp" -#include "version.hpp" #include "idefix.hpp" #include "dataBlockHost.hpp" #include "gridHost.hpp" From 7ea6fa747e11e8767ae119150b4faede1730e99f Mon Sep 17 00:00:00 2001 From: Geoffroy Lesur Date: Tue, 25 Aug 2026 14:18:00 +0200 Subject: [PATCH 4/8] compiler-dependent fma suppression directly from cmake using -DIdefix_SUPPRESS_FMA --- CMakeLists.txt | 10 ++++ cmake/SuppressFMA.cmake | 104 ++++++++++++++++++++++++++++++++++++++++ pytools/idfx_test.py | 8 ++-- 3 files changed, 117 insertions(+), 5 deletions(-) create mode 100644 cmake/SuppressFMA.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 08825827c..56115620c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,6 +16,7 @@ option(Idefix_DEBUG "Enable Idefix debug features (makes the code very slow)" OF option(Idefix_RUNTIME_CHECKS "Enable runtime sanity checks" OFF) option(Idefix_WERROR "Treat compiler warnings as errors" OFF) option(Idefix_PYTHON "Enable python bindings (requires pybind11)" OFF) +option(Idefix_SUPPRESS_FMA "Disable FMA (fused multiply-add) contraction/codegen. Useful for code validation accross architectures." OFF) set(Idefix_PROBLEM_DIR "${CMAKE_BINARY_DIR}" CACHE STRING "Problem directory to build for.") set(Idefix_CXX_FLAGS "" CACHE STRING "Additional compiler/linker flag") set(Idefix_DEFS "definitions.hpp" CACHE FILEPATH "Problem definition header file") @@ -43,6 +44,7 @@ include(AddIdefixSource) include(SetIdefixProperty) include(SetRequiredBuildSettingsForGCC8) include(CheckHdf5ParallelSupport) +include(SuppressFMA) #Idefix requires Cuda Lambdas (experimental) if(Kokkos_ENABLE_CUDA) @@ -58,6 +60,8 @@ include_directories(${Kokkos_INCLUDE_DIRS_RET}) # Add Idefix CXX Flags add_compile_options(${Idefix_CXX_FLAGS}) + + # Add filesystem libraries for GCC8 set_required_build_settings_for_GCC8() @@ -278,6 +282,12 @@ configure_file( # Make sure the generated header is on the include path target_include_directories(idefix PRIVATE ${CMAKE_BINARY_DIR}/build/generated) +# disable FMA if needed +if(Idefix_SUPPRESS_FMA) + message(STATUS "FMA (fused multiply-add) contraction/codegen is disabled") + target_suppress_fma(idefix) +endif() + message(STATUS "Idefix final configuration") if(Idefix_EVOLVE_VECTOR_POTENTIAL) message(STATUS " MHD: ${Idefix_MHD} (Vector potential)") diff --git a/cmake/SuppressFMA.cmake b/cmake/SuppressFMA.cmake new file mode 100644 index 000000000..cdf42b925 --- /dev/null +++ b/cmake/SuppressFMA.cmake @@ -0,0 +1,104 @@ +#[[============================================================================ + SuppressFMA.cmake + + Provides an option and a function to optionally disable fused + multiply-add (FMA) code generation / contraction for a Kokkos-based CXX + target. + + Kokkos wraps the real device compiler behind nvcc_wrapper (CUDA) or + hipcc (HIP), which makes CMAKE_CXX_COMPILER_ID report the *underlying + host* compiler (e.g. "GNU" or "Clang") instead of "NVIDIA" or "Clang + as HIP". Backend detection therefore relies on the Kokkos_ENABLE_* + variables exported by KokkosConfig.cmake / set by the Kokkos build, + and only falls back to CMAKE_CXX_COMPILER_ID for the plain host + compilers (no CUDA/HIP backend active): + + - Kokkos_ENABLE_HIP ON -> AMD HIP (hipcc, clang-based) : -ffp-contract=off + - Kokkos_ENABLE_CUDA ON -> NVIDIA nvcc (via nvcc_wrapper) : --fmad=false + - otherwise, CMAKE_CXX_COMPILER_ID selects among: + GNU : gcc/g++ + Intel : classic icc/icpc + IntelLLVM : Intel oneAPI icx/icpx + Clang : LLVM clang++ + AppleClang : Xcode clang++ + NVHPC : NVIDIA HPC SDK (nvc++), e.g. for OpenMPTarget/OpenACC + + Usage (after find_package(Kokkos) so Kokkos_ENABLE_* are defined): + include(SuppressFMA.cmake) + add_library(mylib source.cpp) + target_link_libraries(mylib PUBLIC Kokkos::kokkos) + target_suppress_fma(mylib) + + FMA suppression is only actually applied if the cache option + SUPPRESS_FMA is ON (default OFF), so the function can be called + unconditionally and toggled at configure time with: + cmake -DSUPPRESS_FMA=ON .. +============================================================================]] + +include_guard(GLOBAL) + +option(SUPPRESS_FMA "Disable FMA (fused multiply-add) contraction/codegen for CXX where possible" OFF) + +# Determine the CXX FMA-suppression flags for the active Kokkos backend / +# CXX compiler. Returns the list of flags (possibly empty) via out_var. +function(_fma_suppression_flags_cxx out_var) + set(flags "") + set(id "${CMAKE_CXX_COMPILER_ID}") + + # Kokkos backend takes priority: nvcc_wrapper/hipcc hide the real + # device compiler from CMAKE_CXX_COMPILER_ID. + if(Kokkos_ENABLE_HIP) + set(flags "-ffp-contract=off") + + elseif(Kokkos_ENABLE_CUDA) + set(flags "--fmad=false") + + elseif(id STREQUAL "GNU") + set(flags "-ffp-contract=off" "-mno-fma") + + elseif(id MATCHES "^(Clang|AppleClang)$") + set(flags "-ffp-contract=off") + + elseif(id STREQUAL "Intel") + # Intel classic compiler + set(flags "-fp-model=precise" "-no-fma") + + elseif(id STREQUAL "IntelLLVM") + # Intel oneAPI compiler (clang-based) + set(flags "-ffp-contract=off" "-fp-model=strict") + + elseif(id STREQUAL "NVHPC") + # NVIDIA HPC SDK (formerly PGI), e.g. OpenMPTarget/OpenACC backend + set(flags "-Mnofma") # untested + endif() + + set(${out_var} "${flags}" PARENT_SCOPE) +endfunction() + +# target_suppress_fma() +# +# Applies compiler-specific FMA-suppression flags to 's CXX +# sources, but only when the SUPPRESS_FMA option is ON. Safe to call +# unconditionally. +function(target_suppress_fma target) + + if(NOT TARGET ${target}) + message(FATAL_ERROR "target_suppress_fma: '${target}' is not a target") + endif() + + _fma_suppression_flags_cxx(cxx_flags) + + if(cxx_flags) + foreach(flag IN LISTS cxx_flags) + target_compile_options(${target} PRIVATE + $<$:${flag}> + ) + endforeach() + else() + message(VERBOSE + "target_suppress_fma: no FMA-suppression flag known for " + "CXX compiler '${CMAKE_CXX_COMPILER_ID}' " + "(Kokkos_ENABLE_CUDA=${Kokkos_ENABLE_CUDA}, " + "Kokkos_ENABLE_HIP=${Kokkos_ENABLE_HIP}) (target ${target})") + endif() +endfunction() diff --git a/pytools/idfx_test.py b/pytools/idfx_test.py index ac72d6dde..ffbd0de33 100644 --- a/pytools/idfx_test.py +++ b/pytools/idfx_test.py @@ -225,21 +225,19 @@ def _genCmakeCommand(self, definitionFile=""): if self.cuda: comm.append("-DKokkos_ENABLE_CUDA=ON") - # disable fmad operations on Cuda to make it compatible with CPU arithmetics - comm.append("-DIdefix_CXX_FLAGS=--fmad=false") # disable Async cuda malloc for tests performed on old UCX implementations comm.append("-DKokkos_ENABLE_IMPL_CUDA_MALLOC_ASYNC=OFF") if self.intel: # disable fmad operations on Cuda to make it compatible with CPU arithmetics - comm.append("-DIdefix_CXX_FLAGS=-fp-model=strict") comm.append("-DCMAKE_CXX_COMPILER=icpx") comm.append("-DCMAKE_C_COMPILER=icx") if self.hip: comm.append("-DKokkos_ENABLE_HIP=ON") - # disable fmad operations on HIP to make it compatible with CPU arithmetics - comm.append("-DIdefix_CXX_FLAGS=-ffp-contract=off") + + # disable FMA for testing so that we have the same results on CPU and GPU (otherwise, the results are not bitwise identical) + comm.append("-DIdefix_SUPPRESS_FMA=ON") # if we use single precision if self.single: From b35ab7d948dad77d6c9caa20c977f5643c732fc4 Mon Sep 17 00:00:00 2001 From: Geoffroy Lesur Date: Tue, 25 Aug 2026 14:22:40 +0200 Subject: [PATCH 5/8] fix comment --- cmake/SuppressFMA.cmake | 6 ------ 1 file changed, 6 deletions(-) diff --git a/cmake/SuppressFMA.cmake b/cmake/SuppressFMA.cmake index cdf42b925..0dbf9e6c1 100644 --- a/cmake/SuppressFMA.cmake +++ b/cmake/SuppressFMA.cmake @@ -29,16 +29,10 @@ target_link_libraries(mylib PUBLIC Kokkos::kokkos) target_suppress_fma(mylib) - FMA suppression is only actually applied if the cache option - SUPPRESS_FMA is ON (default OFF), so the function can be called - unconditionally and toggled at configure time with: - cmake -DSUPPRESS_FMA=ON .. ============================================================================]] include_guard(GLOBAL) -option(SUPPRESS_FMA "Disable FMA (fused multiply-add) contraction/codegen for CXX where possible" OFF) - # Determine the CXX FMA-suppression flags for the active Kokkos backend / # CXX compiler. Returns the list of flags (possibly empty) via out_var. function(_fma_suppression_flags_cxx out_var) From df774284b9b54fdeefb75bc9d66f8c56c9fa9860 Mon Sep 17 00:00:00 2001 From: Geoffroy Lesur Date: Tue, 25 Aug 2026 15:52:07 +0200 Subject: [PATCH 6/8] add crayClang as an compiler to suppress fma --- cmake/SuppressFMA.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/SuppressFMA.cmake b/cmake/SuppressFMA.cmake index 0dbf9e6c1..b5ef1f182 100644 --- a/cmake/SuppressFMA.cmake +++ b/cmake/SuppressFMA.cmake @@ -50,7 +50,7 @@ function(_fma_suppression_flags_cxx out_var) elseif(id STREQUAL "GNU") set(flags "-ffp-contract=off" "-mno-fma") - elseif(id MATCHES "^(Clang|AppleClang)$") + elseif(id MATCHES "^(Clang|AppleClang|CrayClang)$") set(flags "-ffp-contract=off") elseif(id STREQUAL "Intel") From bfad781811671853a948719426ad4ea9c5d4a795 Mon Sep 17 00:00:00 2001 From: Geoffroy Lesur Date: Wed, 26 Aug 2026 09:07:12 +0200 Subject: [PATCH 7/8] fix typo Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 56115620c..ed2276839 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ option(Idefix_DEBUG "Enable Idefix debug features (makes the code very slow)" OF option(Idefix_RUNTIME_CHECKS "Enable runtime sanity checks" OFF) option(Idefix_WERROR "Treat compiler warnings as errors" OFF) option(Idefix_PYTHON "Enable python bindings (requires pybind11)" OFF) -option(Idefix_SUPPRESS_FMA "Disable FMA (fused multiply-add) contraction/codegen. Useful for code validation accross architectures." OFF) +option(Idefix_SUPPRESS_FMA "Disable FMA (fused multiply-add) contraction/codegen. Useful for code validation across architectures." OFF) set(Idefix_PROBLEM_DIR "${CMAKE_BINARY_DIR}" CACHE STRING "Problem directory to build for.") set(Idefix_CXX_FLAGS "" CACHE STRING "Additional compiler/linker flag") set(Idefix_DEFS "definitions.hpp" CACHE FILEPATH "Problem definition header file") From 6f689d8d7350389a81a1f54ccc82e1c2f66f5868 Mon Sep 17 00:00:00 2001 From: Geoffroy Lesur Date: Wed, 26 Aug 2026 09:08:11 +0200 Subject: [PATCH 8/8] no-fma valid only on non-x86 gcc Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- cmake/SuppressFMA.cmake | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/cmake/SuppressFMA.cmake b/cmake/SuppressFMA.cmake index b5ef1f182..18dc10d46 100644 --- a/cmake/SuppressFMA.cmake +++ b/cmake/SuppressFMA.cmake @@ -48,8 +48,12 @@ function(_fma_suppression_flags_cxx out_var) set(flags "--fmad=false") elseif(id STREQUAL "GNU") - set(flags "-ffp-contract=off" "-mno-fma") - + include(CheckCXXCompilerFlag) + check_cxx_compiler_flag("-mno-fma" IDEFIX_HAS_MNO_FMA) + set(flags "-ffp-contract=off") + if(IDEFIX_HAS_MNO_FMA) + list(APPEND flags "-mno-fma") + endif() elseif(id MATCHES "^(Clang|AppleClang|CrayClang)$") set(flags "-ffp-contract=off")