From 066fc348f18dc18c06c6dbca365f6e4a1da016b0 Mon Sep 17 00:00:00 2001
From: kronbichler <kronbichler@0785d39b-7218-0410-832d-ea1e28bc413d>
Date: Thu, 17 Apr 2014 09:11:05 +0000
Subject: [PATCH] Fix a few issues with vectorization that might help simserv04
 with Intel min-bundled configuration. Initial detection for AVX512 (but due
 to hardware not released yet I could not test it).

git-svn-id: https://svn.dealii.org/trunk@32786 0785d39b-7218-0410-832d-ea1e28bc413d
---
 .../cmake/checks/check_01_cpu_features.cmake  | 37 +++++++++++++++++--
 deal.II/include/deal.II/base/aligned_vector.h |  2 +-
 deal.II/include/deal.II/base/vectorization.h  |  9 +++--
 3 files changed, 40 insertions(+), 8 deletions(-)

diff --git a/deal.II/cmake/checks/check_01_cpu_features.cmake b/deal.II/cmake/checks/check_01_cpu_features.cmake
index 9639b89497..4ca7062b08 100644
--- a/deal.II/cmake/checks/check_01_cpu_features.cmake
+++ b/deal.II/cmake/checks/check_01_cpu_features.cmake
@@ -80,7 +80,6 @@ IF(DEAL_II_ALLOW_PLATFORM_INTROSPECTION)
   CHECK_CXX_SOURCE_RUNS(
     "
     #include <emmintrin.h>
-    #include <mm_malloc.h>
     int main()
     {
     __m128d a, b;
@@ -112,7 +111,6 @@ IF(DEAL_II_ALLOW_PLATFORM_INTROSPECTION)
   CHECK_CXX_SOURCE_RUNS(
     "
     #include <immintrin.h>
-    #include <mm_malloc.h>
     int main()
     {
       __m256d a, b;
@@ -139,11 +137,44 @@ IF(DEAL_II_ALLOW_PLATFORM_INTROSPECTION)
     }
     "
     DEAL_II_HAVE_AVX)
+
+  CHECK_CXX_SOURCE_RUNS(
+    "
+    #include <immintrin.h>
+    int main()
+    {
+      __m512d a, b;
+      const unsigned int vector_bytes = sizeof(__m512d);
+      const int n_vectors = vector_bytes/sizeof(double);
+      __m512d * data =
+        reinterpret_cast<__m512d*>(_mm_malloc (2*vector_bytes, vector_bytes));
+      double * ptr = reinterpret_cast<double*>(&a);
+      ptr[0] = (volatile double)(1.0);
+      for (int i=1; i<n_vectors; ++i)
+        ptr[i] = 0.0;
+      const volatile double x = 2.25;
+      b = _mm512_set_pd(x, x, x, x, x, x, x, x);
+      data[0] = _mm512_add_pd (a, b);
+      data[1] = _mm512_mul_pd (b, data[0]);
+      ptr = reinterpret_cast<double*>(&data[1]);
+      unsigned int return_value = 0;
+      if (ptr[0] != 7.3125)
+        return_value = 1;
+      for (int i=1; i<n_vectors; ++i)
+        if (ptr[i] != 5.0625)
+          return_value = 1;
+      _mm_free (data);
+      return return_value;
+    }
+    "
+    DEAL_II_HAVE_AVX512)
 ENDIF()
 
 
 IF(DEAL_II_HAVE_SSE2)
-  IF(DEAL_II_HAVE_AVX)
+  IF(DEAL_II_HAVE_AVX512)
+    SET(DEAL_II_COMPILER_VECTORIZATION_LEVEL 3)
+  ELSEIF(DEAL_II_HAVE_AVX)
     SET(DEAL_II_COMPILER_VECTORIZATION_LEVEL 2)
   ELSE()
     SET(DEAL_II_COMPILER_VECTORIZATION_LEVEL 1)
diff --git a/deal.II/include/deal.II/base/aligned_vector.h b/deal.II/include/deal.II/base/aligned_vector.h
index 0acf98798b..88576b5acb 100644
--- a/deal.II/include/deal.II/base/aligned_vector.h
+++ b/deal.II/include/deal.II/base/aligned_vector.h
@@ -29,7 +29,7 @@
 #include <cstring>
 
 #if DEAL_II_COMPILER_VECTORIZATION_LEVEL > 0
-#include <mm_malloc.h>
+#include <emmintrin.h>
 #endif
 
 
diff --git a/deal.II/include/deal.II/base/vectorization.h b/deal.II/include/deal.II/base/vectorization.h
index cdb8017464..874f267644 100644
--- a/deal.II/include/deal.II/base/vectorization.h
+++ b/deal.II/include/deal.II/base/vectorization.h
@@ -90,7 +90,7 @@ public:
   VectorizedArray &
   operator = (const double x)
   {
-    data = _mm256_set_pd(x, x, x, x, x, x, x, x);
+    data = _mm512_set_pd(x, x, x, x, x, x, x, x);
     return *this;
   }
 
@@ -201,9 +201,9 @@ private:
     // to compute the absolute value, perform bitwise andnot with -0. This
     // will leave all value and exponent bits unchanged but force the sign
     // value to +.
-    __m256d mask = _mm256_set_pd (-0., -0., -0., -0., -0., -0., -0., -0.);
+    __m256d mask = _mm512_set_pd (-0., -0., -0., -0., -0., -0., -0., -0.);
     VectorizedArray res;
-    res.data = _mm256_andnot_pd(mask, data);
+    res.data = _mm512_andnot_pd(mask, data);
     return res;
   }
 
@@ -264,7 +264,7 @@ public:
   VectorizedArray &
   operator = (const float x)
   {
-    data = _mm256_set_ps(x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x);
+    data = _mm512_set_ps(x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x);
     return *this;
   }
 
@@ -419,6 +419,7 @@ private:
 };
 
 
+
 #elif DEAL_II_COMPILER_VECTORIZATION_LEVEL == 2  && defined(__AVX__)
 
 /**
-- 
2.39.5