]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Disable SIMD vector operations for certain types 608/head
authorTimo Heister <timo.heister@gmail.com>
Thu, 26 Feb 2015 14:14:11 +0000 (09:14 -0500)
committerTimo Heister <timo.heister@gmail.com>
Sat, 28 Feb 2015 12:42:37 +0000 (07:42 -0500)
Disable long double SIMD instructions on ICC. This is to work around a
bug that generates wrong code at least up to intel 15 (see tests/lac
/vector-vector, tests/lac/intel-15-bug, and the discussion at
https://github.com/dealii/dealii/issues/598).

include/deal.II/lac/vector.templates.h

index 942f1f9cbd0e6b4d6f2644bccaf1c35cb05a0094..72a65c7e17660e440f6ae5d90179a384038408a4 100644 (file)
 
 DEAL_II_NAMESPACE_OPEN
 
+/**
+ * Helper struct to tell us if we can use SIMD instructions for the given @p
+ * Number type.
+ */
+template <typename Number>
+struct EnableOpenMPSimdFor
+{
+  static const bool value = true;
+};
+
+#ifdef __INTEL_COMPILER
+// Disable long double SIMD instructions on ICC. This is to work around a bug
+// that generates wrong code at least up to intel 15 (see
+// tests/lac/vector-vector, tests/lac/intel-15-bug, and the discussion at
+// https://github.com/dealii/dealii/issues/598).
+template <>
+struct EnableOpenMPSimdFor<long double>
+{
+  static const bool value = false;
+};
+#endif
+
 
 namespace internal
 {
@@ -159,9 +181,17 @@ namespace internal
 
     void operator() (const size_type begin, const size_type end) const
     {
-      DEAL_II_OPENMP_SIMD_PRAGMA
-      for (size_type i=begin; i<end; ++i)
-        val[i] *= factor;
+      if (EnableOpenMPSimdFor<Number>::value)
+        {
+          DEAL_II_OPENMP_SIMD_PRAGMA
+          for (size_type i=begin; i<end; ++i)
+            val[i] *= factor;
+        }
+      else
+        {
+          for (size_type i=begin; i<end; ++i)
+            val[i] *= factor;
+        }
     }
   };
 
@@ -180,9 +210,17 @@ namespace internal
 
     void operator() (const size_type begin, const size_type end) const
     {
-      DEAL_II_OPENMP_SIMD_PRAGMA
-      for (size_type i=begin; i<end; ++i)
-        val[i] += factor*v_val[i];
+      if (EnableOpenMPSimdFor<Number>::value)
+        {
+          DEAL_II_OPENMP_SIMD_PRAGMA
+          for (size_type i=begin; i<end; ++i)
+            val[i] += factor*v_val[i];
+        }
+      else
+        {
+          for (size_type i=begin; i<end; ++i)
+            val[i] += factor*v_val[i];
+        }
     }
   };
 
@@ -202,9 +240,17 @@ namespace internal
 
     void operator() (const size_type begin, const size_type end) const
     {
-      DEAL_II_OPENMP_SIMD_PRAGMA
-      for (size_type i=begin; i<end; ++i)
-        val[i] = x*val[i] + a*v_val[i];
+      if (EnableOpenMPSimdFor<Number>::value)
+        {
+          DEAL_II_OPENMP_SIMD_PRAGMA
+          for (size_type i=begin; i<end; ++i)
+            val[i] = x*val[i] + a*v_val[i];
+        }
+      else
+        {
+          for (size_type i=begin; i<end; ++i)
+            val[i] = x*val[i] + a*v_val[i];
+        }
     }
   };
 
@@ -222,9 +268,17 @@ namespace internal
 
     void operator() (const size_type begin, const size_type end) const
     {
-      DEAL_II_OPENMP_SIMD_PRAGMA
-      for (size_type i=begin; i<end; ++i)
-        val[i] -= v_val[i];
+      if (EnableOpenMPSimdFor<Number>::value)
+        {
+          DEAL_II_OPENMP_SIMD_PRAGMA
+          for (size_type i=begin; i<end; ++i)
+            val[i] -= v_val[i];
+        }
+      else
+        {
+          for (size_type i=begin; i<end; ++i)
+            val[i] -= v_val[i];
+        }
     }
   };
 
@@ -242,9 +296,17 @@ namespace internal
 
     void operator() (const size_type begin, const size_type end) const
     {
-      DEAL_II_OPENMP_SIMD_PRAGMA
-      for (size_type i=begin; i<end; ++i)
-        val[i] += factor;
+      if (EnableOpenMPSimdFor<Number>::value)
+        {
+          DEAL_II_OPENMP_SIMD_PRAGMA
+          for (size_type i=begin; i<end; ++i)
+            val[i] += factor;
+        }
+      else
+        {
+          for (size_type i=begin; i<end; ++i)
+            val[i] += factor;
+        }
     }
   };
 
@@ -262,9 +324,17 @@ namespace internal
 
     void operator() (const size_type begin, const size_type end) const
     {
-      DEAL_II_OPENMP_SIMD_PRAGMA
-      for (size_type i=begin; i<end; ++i)
-        val[i] += v_val[i];
+      if (EnableOpenMPSimdFor<Number>::value)
+        {
+          DEAL_II_OPENMP_SIMD_PRAGMA
+          for (size_type i=begin; i<end; ++i)
+            val[i] += v_val[i];
+        }
+      else
+        {
+          for (size_type i=begin; i<end; ++i)
+            val[i] += v_val[i];
+        }
     }
   };
 
@@ -285,9 +355,17 @@ namespace internal
 
     void operator() (const size_type begin, const size_type end) const
     {
-      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];
+      if (EnableOpenMPSimdFor<Number>::value)
+        {
+          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];
+        }
+      else
+        {
+          for (size_type i=begin; i<end; ++i)
+            val[i] = val[i] + a*v_val[i] + b*w_val[i];
+        }
     }
   };
 
@@ -306,9 +384,17 @@ namespace internal
 
     void operator() (const size_type begin, const size_type end) const
     {
-      DEAL_II_OPENMP_SIMD_PRAGMA
-      for (size_type i=begin; i<end; ++i)
-        val[i] = x*val[i] + v_val[i];
+      if (EnableOpenMPSimdFor<Number>::value)
+        {
+          DEAL_II_OPENMP_SIMD_PRAGMA
+          for (size_type i=begin; i<end; ++i)
+            val[i] = x*val[i] + v_val[i];
+        }
+      else
+        {
+          for (size_type i=begin; i<end; ++i)
+            val[i] = x*val[i] + v_val[i];
+        }
     }
   };
 
@@ -330,9 +416,17 @@ namespace internal
 
     void operator() (const size_type begin, const size_type end) const
     {
-      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];
+      if (EnableOpenMPSimdFor<Number>::value)
+        {
+          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];
+        }
+      else
+        {
+          for (size_type i=begin; i<end; ++i)
+            val[i] = x*val[i] + a*v_val[i] + b*w_val[i];
+        }
     }
   };
 
@@ -350,9 +444,17 @@ namespace internal
 
     void operator() (const size_type begin, const size_type end) const
     {
-      DEAL_II_OPENMP_SIMD_PRAGMA
-      for (size_type i=begin; i<end; ++i)
-        val[i] *= v_val[i];
+      if (EnableOpenMPSimdFor<Number>::value)
+        {
+          DEAL_II_OPENMP_SIMD_PRAGMA
+          for (size_type i=begin; i<end; ++i)
+            val[i] *= v_val[i];
+        }
+      else
+        {
+          for (size_type i=begin; i<end; ++i)
+            val[i] *= v_val[i];
+        }
     }
   };
 
@@ -371,9 +473,17 @@ namespace internal
 
     void operator() (const size_type begin, const size_type end) const
     {
-      DEAL_II_OPENMP_SIMD_PRAGMA
-      for (size_type i=begin; i<end; ++i)
-        val[i] = a*u_val[i];
+      if (EnableOpenMPSimdFor<Number>::value)
+        {
+          DEAL_II_OPENMP_SIMD_PRAGMA
+          for (size_type i=begin; i<end; ++i)
+            val[i] = a*u_val[i];
+        }
+      else
+        {
+          for (size_type i=begin; i<end; ++i)
+            val[i] = a*u_val[i];
+        }
     }
   };
 
@@ -394,9 +504,17 @@ namespace internal
 
     void operator() (const size_type begin, const size_type end) const
     {
-      DEAL_II_OPENMP_SIMD_PRAGMA
-      for (size_type i=begin; i<end; ++i)
-        val[i] = a*u_val[i] + b*v_val[i];
+      if (EnableOpenMPSimdFor<Number>::value)
+        {
+          DEAL_II_OPENMP_SIMD_PRAGMA
+          for (size_type i=begin; i<end; ++i)
+            val[i] = a*u_val[i] + b*v_val[i];
+        }
+      else
+        {
+          for (size_type i=begin; i<end; ++i)
+            val[i] = a*u_val[i] + b*v_val[i];
+        }
     }
   };
 
@@ -419,9 +537,17 @@ namespace internal
 
     void operator() (const size_type begin, const size_type end) const
     {
-      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];
+      if (EnableOpenMPSimdFor<Number>::value)
+        {
+          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];
+        }
+      else
+        {
+          for (size_type i=begin; i<end; ++i)
+            val[i] = a*u_val[i] + b*v_val[i] + c*w_val[i];
+        }
     }
   };
 
@@ -440,9 +566,17 @@ namespace internal
 
     void operator() (const size_type begin, const size_type end) const
     {
-      DEAL_II_OPENMP_SIMD_PRAGMA
-      for (size_type i=begin; i<end; ++i)
-        val[i] = a_val[i]/b_val[i];
+      if (EnableOpenMPSimdFor<Number>::value)
+        {
+          DEAL_II_OPENMP_SIMD_PRAGMA
+          for (size_type i=begin; i<end; ++i)
+            val[i] = a_val[i]/b_val[i];
+        }
+      else
+        {
+          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.