Skip to content

Commit

Permalink
Disable SIMD vector operations for certain types
Browse files Browse the repository at this point in the history
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
dealii#598).
  • Loading branch information
tjhei committed Feb 28, 2015
1 parent 54453c0 commit 197f3a1
Showing 1 changed file with 176 additions and 42 deletions.
218 changes: 176 additions & 42 deletions include/deal.II/lac/vector.templates.h
Expand Up @@ -48,6 +48,28 @@

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
{
Expand Down Expand Up @@ -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;
}
}
};

Expand All @@ -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];
}
}
};

Expand All @@ -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];
}
}
};

Expand All @@ -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];
}
}
};

Expand All @@ -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;
}
}
};

Expand All @@ -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];
}
}
};

Expand All @@ -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];
}
}
};

Expand All @@ -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];
}
}
};

Expand All @@ -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];
}
}
};

Expand All @@ -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];
}
}
};

Expand All @@ -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];
}
}
};

Expand All @@ -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];
}
}
};

Expand All @@ -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];
}
}
};

Expand All @@ -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];
}
}
};

Expand Down

0 comments on commit 197f3a1

Please sign in to comment.