]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Refactor openmp-simd setup 126/head
authorMatthias Maier <tamiko@kyomu.43-1.org>
Tue, 2 Sep 2014 13:41:31 +0000 (15:41 +0200)
committerMatthias Maier <tamiko@kyomu.43-1.org>
Tue, 2 Sep 2014 16:26:58 +0000 (18:26 +0200)
 * 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
cmake/setup_compiler_flags_gnu.cmake
cmake/setup_compiler_flags_intel.cmake
include/deal.II/base/config.h.in
include/deal.II/lac/vector.templates.h

index 54ceed4dce65b782923e8b743261d54f8bb1e1ba..725be611a55c0a236ece36c6d345ce8843a9f68c 100644 (file)
@@ -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 <emmintrin.h>
@@ -109,7 +110,6 @@ IF(DEAL_II_ALLOW_PLATFORM_INTROSPECTION)
     "
     DEAL_II_HAVE_SSE2)
 
-
   CHECK_CXX_SOURCE_RUNS(
     "
     #include <immintrin.h>
@@ -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()
index 838e1ba0795beaed7a6e533dc00195232c900ca8..8585bd29c3d0cd2f80cda5860908ffa237268552 100644 (file)
@@ -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:
index 6961ee6eaa6e83e66447935d2e99bef9141bfacd..7f48feb73e11bcdccec9e8b289c0343462cb12b8 100644 (file)
@@ -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
index 3709ce396a7bcd47c43eac52d24ce114bbca4888..517f1dfef46702eb8fb1950cb7b237ac7cf0edbc 100644 (file)
 #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: *
index f056e6acd546a0a14968bf8d85534b404cc0968c..42e9556e40ed892e32d29bb031877392b94ea914 100644 (file)
@@ -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<end; ++i)
         val[i] *= factor;
     }
@@ -177,7 +177,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<end; ++i)
         val[i] += factor*v_val[i];
     }
@@ -199,7 +199,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<end; ++i)
         val[i] = x*val[i] + a*v_val[i];
     }
@@ -219,7 +219,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<end; ++i)
         val[i] -= v_val[i];
     }
@@ -239,7 +239,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<end; ++i)
         val[i] += factor;
     }
@@ -259,7 +259,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<end; ++i)
         val[i] += v_val[i];
     }
@@ -282,7 +282,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<end; ++i)
         val[i] = val[i] + a*v_val[i] + b*w_val[i];
     }
@@ -303,7 +303,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<end; ++i)
         val[i] = x*val[i] + v_val[i];
     }
@@ -327,7 +327,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<end; ++i)
         val[i] = x*val[i] + a*v_val[i] + b*w_val[i];
     }
@@ -347,7 +347,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<end; ++i)
         val[i] *= v_val[i];
     }
@@ -368,7 +368,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<end; ++i)
         val[i] = a*u_val[i];
     }
@@ -391,7 +391,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<end; ++i)
         val[i] = a*u_val[i] + b*v_val[i];
     }
@@ -416,7 +416,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<end; ++i)
         val[i] = a*u_val[i] + b*v_val[i] + c*w_val[i];
     }
@@ -437,7 +437,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<end; ++i)
         val[i] = a_val[i]/b_val[i];
     }

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.