From 2996abd8a9f869dfaa9b1eb44568a3867e220371 Mon Sep 17 00:00:00 2001 From: Matthias Maier Date: Tue, 2 Sep 2014 15:41:31 +0200 Subject: [PATCH] Refactor openmp-simd setup * The check for support of -(f)openmp-simd is now done in checks/check_01_cpu_features.cmake and guarded by DEAL_II_ALLOW_PLATFORM_INTROSPECTION The guard is important in order to allow for platform independent compilations (as required by Linux distributions) Furthermore, this allows for manual override via DEAL_II_HAVE_OPENMP_SIMD. * The pragma statement is refactored into a macro defined in config.h.in. With this, no -Wno-unknown-pragmas workarounds are necessary and picky compilers that choke on "#pragma" are happy. --- cmake/checks/check_01_cpu_features.cmake | 51 ++++++++++++++++++------ cmake/setup_compiler_flags_gnu.cmake | 8 ---- cmake/setup_compiler_flags_intel.cmake | 10 ----- include/deal.II/base/config.h.in | 8 +++- include/deal.II/lac/vector.templates.h | 28 ++++++------- 5 files changed, 60 insertions(+), 45 deletions(-) diff --git a/cmake/checks/check_01_cpu_features.cmake b/cmake/checks/check_01_cpu_features.cmake index 54ceed4dce..725be611a5 100644 --- a/cmake/checks/check_01_cpu_features.cmake +++ b/cmake/checks/check_01_cpu_features.cmake @@ -28,6 +28,7 @@ # DEAL_II_HAVE_SSE2 *) # DEAL_II_HAVE_AVX *) # DEAL_II_HAVE_AVX512 *) +# DEAL_II_HAVE_OPENMP_SIMD *) # DEAL_II_COMPILER_VECTORIZATION_LEVEL # # *) @@ -54,6 +55,17 @@ ELSE() ENDIF() +# +# Check whether the compiler allows for vectorization and that +# vectorization actually works on the given CPU. For this test, we use +# compiler intrinsics similar to what is used in the deal.II library and +# check whether the arithmetic operations are correctly performed on +# examples where all numbers are exactly represented as floating point +# numbers. +# +# - Matthias Maier, rewritten 2012 +# + IF(DEAL_II_ALLOW_PLATFORM_INTROSPECTION) # # Take care that the following tests are rerun if CMAKE_REQUIRED_FLAGS @@ -68,17 +80,6 @@ IF(DEAL_II_ALLOW_PLATFORM_INTROSPECTION) "${CMAKE_REQUIRED_FLAGS}" CACHE INTERNAL "" FORCE ) - - # - # Check whether the compiler allows for vectorization and that - # vectorization actually works on the given CPU. For this test, we use - # compiler intrinsics similar to what is used in the deal.II library and - # check whether the arithmetic operations are correctly performed on - # examples where all numbers are exactly represented as floating point - # numbers. - # - # - Matthias Maier, rewritten 2012 - # CHECK_CXX_SOURCE_RUNS( " #include @@ -109,7 +110,6 @@ IF(DEAL_II_ALLOW_PLATFORM_INTROSPECTION) " DEAL_II_HAVE_SSE2) - CHECK_CXX_SOURCE_RUNS( " #include @@ -181,3 +181,30 @@ ELSEIF(DEAL_II_HAVE_SSE2) ELSE() SET(DEAL_II_COMPILER_VECTORIZATION_LEVEL 0) ENDIF() + + +# +# OpenMP 4.0 can be used for vectorization (supported by gcc-4.9.1 and +# later). Only the vectorization instructions +# are allowed, the threading must done through TBB. +# + +IF(DEAL_II_ALLOW_PLATFORM_INTROSPECTION) + IF(CMAKE_CXX_COMPILER_ID MATCHES "Intel") + CHECK_CXX_COMPILER_FLAG("-openmp-simd" DEAL_II_HAVE_OPENMP_SIMD) + ELSE() + CHECK_CXX_COMPILER_FLAG("-fopenmp-simd" DEAL_II_HAVE_OPENMP_SIMD) + ENDIF() +ENDIF() + +IF(DEAL_II_HAVE_OPENMP_SIMD) + IF(CMAKE_CXX_COMPILER_ID MATCHES "Intel") + ADD_FLAGS(DEAL_II_CXX_FLAGS "-openmp-simd") + ADD_FLAGS(DEAL_II_LINKER_FLAGS "-openmp") + ELSE() + ADD_FLAGS(DEAL_II_CXX_FLAGS "-fopenmp-simd") + ENDIF() + SET(DEAL_II_OPENMP_SIMD_PRAGMA "_Pragma(\"omp simd\")") +ELSE() + SET(DEAL_II_OPENMP_SIMD_PRAGMA " ") +ENDIF() diff --git a/cmake/setup_compiler_flags_gnu.cmake b/cmake/setup_compiler_flags_gnu.cmake index 838e1ba079..8585bd29c3 100644 --- a/cmake/setup_compiler_flags_gnu.cmake +++ b/cmake/setup_compiler_flags_gnu.cmake @@ -85,14 +85,6 @@ ENABLE_IF_SUPPORTED(DEAL_II_CXX_FLAGS "-Wno-long-long") ENABLE_IF_SUPPORTED(DEAL_II_CXX_FLAGS "-Wno-deprecated") ENABLE_IF_SUPPORTED(DEAL_II_CXX_FLAGS "-Wno-deprecated-declarations") -# -# OpenMP 4.0 can be used for vectorization. Only the vectorization instructions -# are allowed, the threading must done through TBB. Disable unknown-pragmas -# warning, if OpenMP 4.0 is not supported. -# -ENABLE_IF_SUPPORTED(DEAL_II_CXX_FLAGS "-fopenmp-simd") -ENABLE_IF_SUPPORTED(DEAL_II_CXX_FLAGS "-Wno-unknown-pragmas") - IF(CMAKE_CXX_COMPILER_ID MATCHES "Clang") # # Silence Clang warnings about unused parameters: diff --git a/cmake/setup_compiler_flags_intel.cmake b/cmake/setup_compiler_flags_intel.cmake index 6961ee6eaa..7f48feb73e 100644 --- a/cmake/setup_compiler_flags_intel.cmake +++ b/cmake/setup_compiler_flags_intel.cmake @@ -138,16 +138,6 @@ ENABLE_IF_SUPPORTED(DEAL_II_CXX_FLAGS "-wd185") ENABLE_IF_SUPPORTED(DEAL_II_CXX_FLAGS "-wd280") -# -# OpenMP 4.0 can be used for vectorization. Only the vectorization instructions -# are allowed, the threading must done through TBB. Disable unknown-pragmas -# warning, if OpenMP 4.0 is not supported. -# -ENABLE_IF_SUPPORTED(DEAL_II_CXX_FLAGS "-openmp-simd") -ENABLE_IF_SUPPORTED(DEAL_II_CXX_FLAGS "-Wno-unknown-pragmas") - - - IF(DEAL_II_STATIC_EXECUTABLE) # # To produce a static executable, we have to statically link intel's diff --git a/include/deal.II/base/config.h.in b/include/deal.II/base/config.h.in index 3709ce396a..517f1dfef4 100644 --- a/include/deal.II/base/config.h.in +++ b/include/deal.II/base/config.h.in @@ -99,10 +99,16 @@ #cmakedefine DEAL_II_WORDS_BIGENDIAN /** Equal to 0 in the generic case, equal to 1 if CPU compiled for supports - * SSE2, equal to 2 if CPU compiled for supports AVX + * SSE2, equal to 2 if CPU compiled for supports AVX, equal to 3 if AVX512 + * support is available */ #define DEAL_II_COMPILER_VECTORIZATION_LEVEL @DEAL_II_COMPILER_VECTORIZATION_LEVEL@ +/** If openmp simd support is available this string contains the + * corresponding pragma directive + */ +#define DEAL_II_OPENMP_SIMD_PRAGMA @DEAL_II_OPENMP_SIMD_PRAGMA@ + /*************************************** * Configured in check_1_cxx_features: * diff --git a/include/deal.II/lac/vector.templates.h b/include/deal.II/lac/vector.templates.h index f056e6acd5..42e9556e40 100644 --- a/include/deal.II/lac/vector.templates.h +++ b/include/deal.II/lac/vector.templates.h @@ -156,7 +156,7 @@ namespace internal void operator() (const size_type begin, const size_type end) const { - #pragma omp simd + DEAL_II_OPENMP_SIMD_PRAGMA for (size_type i=begin; i