# DEAL_II_HAVE_SSE2 *)
# DEAL_II_HAVE_AVX *)
# DEAL_II_HAVE_AVX512 *)
+# DEAL_II_HAVE_OPENMP_SIMD *)
# DEAL_II_COMPILER_VECTORIZATION_LEVEL
#
# *)
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
"${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>
"
DEAL_II_HAVE_SSE2)
-
CHECK_CXX_SOURCE_RUNS(
"
#include <immintrin.h>
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()
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:
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
#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: *
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;
}
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];
}
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];
}
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];
}
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;
}
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];
}
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];
}
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];
}
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];
}
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];
}
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];
}
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];
}
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];
}
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];
}