From 09ce68aede661dc61819332cec5cb82218fd91e7 Mon Sep 17 00:00:00 2001 From: Nils Kohl <nils.kohl@fau.de> Date: Mon, 20 Mar 2023 10:20:37 +0100 Subject: [PATCH] Half precision support for gcc. --- CMakeLists.txt | 29 +++++++++++++++++++------ apps/tools/MixedPrecision/CheckFP16.cpp | 8 +++---- src/core/DataTypes.h | 17 ++++++++------- 3 files changed, 35 insertions(+), 19 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 54b37fb1e..b6962d6dc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1256,13 +1256,28 @@ endif() ## Half precision ## ############################################################################################################################ -if ( WALBERLA_BUILD_WITH_HALF_PRECISION_SUPPORT ) - message( STATUS "Configuring with *experimental* half precision (float16) support. You better know what you are doing." ) - if ( NOT WALBERLA_OPTIMIZE_FOR_LOCALHOST ) - message( WARNING "[WALBERLA_BUILD_WITH_HALF_PRECISION_SUPPORT] " - "You are not optimizing for localhost. Linker errors could occur. Consider also enabling WALBERLA_OPTIMIZE_FOR_LOCALHOST!" ) - endif() -endif() +if (WALBERLA_BUILD_WITH_HALF_PRECISION_SUPPORT) + if (WALBERLA_CXX_COMPILER_IS_GNU OR WALBERLA_CXX_COMPILER_IS_CLANG) + message(STATUS "Configuring with *experimental* half precision (float16) support. You better know what you are doing.") + if (WALBERLA_CXX_COMPILER_IS_GNU AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 12.0.0) + message(WARNING "[WALBERLA_BUILD_WITH_HALF_PRECISION_SUPPORT] " + "Half precision support for gcc has only been tested with version >= 12. " + "You are using a previous version - it may not work correctly.") + endif () + if (WALBERLA_CXX_COMPILER_IS_CLANG AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 15.0.0) + message(WARNING "[WALBERLA_BUILD_WITH_HALF_PRECISION_SUPPORT] " + "Half precision support for clang has only been tested with version >= 15. " + "You are using a previous version - it may not work correctly.") + endif () + if (NOT WALBERLA_OPTIMIZE_FOR_LOCALHOST) + message(WARNING "[WALBERLA_BUILD_WITH_HALF_PRECISION_SUPPORT] " + "You are not optimizing for localhost. Linker errors could occur. Consider also enabling WALBERLA_OPTIMIZE_FOR_LOCALHOST!") + endif () + else () + message(FATAL_ERROR "[WALBERLA_BUILD_WITH_HALF_PRECISION_SUPPORT] " + "Half precision support is currently only available for gcc and clang.") + endif () +endif () ############################################################################################################################ # Documentation Generation diff --git a/apps/tools/MixedPrecision/CheckFP16.cpp b/apps/tools/MixedPrecision/CheckFP16.cpp index 24e29e1cf..7c84676de 100644 --- a/apps/tools/MixedPrecision/CheckFP16.cpp +++ b/apps/tools/MixedPrecision/CheckFP16.cpp @@ -77,8 +77,8 @@ int main(int argc, char** argv) WALBERLA_LOG_INFO_ON_ROOT(" Casting and output compiles.") WALBERLA_LOG_INFO_ON_ROOT(" - Basic arithmetic check: ") - float16 x = 1.2f16; - float16 y = -1.8f16; + auto x = float16(1.2); + auto y = float16(-1.8); float64 z = -0.6; float16 sum = x + y; WALBERLA_LOG_INFO_ON_ROOT(" " << (double) x << " + " << (double) y << " == " << (float64) (x + y) << "") @@ -113,11 +113,11 @@ int main(int argc, char** argv) std::vector< float64 > v64(vsize, 0.01); std::vector< float32 > v32(vsize, 0.01f); - std::vector< float16 > v16(vsize, 0.01f16); + std::vector< float16 > v16(vsize, float16(0.01)); std::vector< float64 > vv64(vsize, 0.02); std::vector< float32 > vv32(vsize, 0.02f); - std::vector< float16 > vv16(vsize, 0.02f16); + std::vector< float16 > vv16(vsize, float16(0.02)); std::vector< float64 > r64(vsize); std::vector< float32 > r32(vsize); diff --git a/src/core/DataTypes.h b/src/core/DataTypes.h index 951e1413d..bae5b7651 100644 --- a/src/core/DataTypes.h +++ b/src/core/DataTypes.h @@ -167,7 +167,6 @@ using real_t = double; using real_t = float; #endif - /// Half precision support. Experimental. Use carefully. /// /// This feature is experimental, since it strictly depends on the underlying architecture and compiler support. @@ -176,19 +175,21 @@ using real_t = float; /// Only bandwidth bound code may therefore benefit. None of this is guaranteed, and may change in the future. /// #ifdef WALBERLA_BUILD_WITH_HALF_PRECISION_SUPPORT -#ifdef WALBERLA_CXX_COMPILER_IS_CLANG +# if defined(WALBERLA_CXX_COMPILER_IS_CLANG) || defined(WALBERLA_CXX_COMPILER_IS_GNU) /// Clang version must be 15 or higher for x86 half precision support. +/// GCC version must be 12 or higher for x86 half precision support. /// Also support seems to require SSE, so ensure that respective instruction sets are enabled. /// See /// https://clang.llvm.org/docs/LanguageExtensions.html#half-precision-floating-point +/// https://gcc.gnu.org/onlinedocs/gcc/Half-Precision.html /// for more information. -using half = _Float16; -#else -static_assert( false, "Attempting to built walberla with half precision support.\n" - "However, the compiler you chose is not suited for that, or we simply have not implemented " - "support for half precision and your compiler." ) -#endif +using half = _Float16; using float16 = half; +# else +static_assert(false, "\n\n### Attempting to built walberla with half precision support.\n" + "### However, the compiler you chose is not suited for that, or we simply have not implemented " + "support for half precision and your compiler.\n"); +# endif #endif using float32 = float; using float64 = double; -- GitLab