]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Implement VectorizedArray for Altivec/VSX (IBM Power) in double precision.
authorMartin Kronbichler <kronbichler@lnm.mw.tum.de>
Fri, 18 May 2018 14:27:58 +0000 (16:27 +0200)
committerMartin Kronbichler <kronbichler@lnm.mw.tum.de>
Mon, 8 Oct 2018 06:30:18 +0000 (08:30 +0200)
Undefine vector, pixel, bool from altivec.h

include/deal.II/base/vectorization.h

index 084980e07722b153126275f65769ba2c7c52fa66..d6ea23541ba07947b685100e31dc7f63ad037d8a 100644 (file)
 #endif
 
 
+#ifdef __ALTIVEC__
+#include <altivec.h>
+
+// altivec.h defines vector, pixel, bool, but we do not use them, so undefine
+// them before they make trouble
+#undef vector
+#undef pixel
+#undef bool
+#endif
+
 DEAL_II_NAMESPACE_OPEN
 
 
@@ -2882,6 +2892,205 @@ vectorized_transpose_and_store(const bool                    add_into,
 #endif // if DEAL_II_COMPILER_VECTORIZATION_LEVEL > 0
 
 
+#if defined(__ALTIVEC__) && defined(__VSX__)
+
+template <>
+class VectorizedArray<double>
+{
+public:
+  /**
+   * This gives the number of vectors collected in this class.
+   */
+  static const unsigned int n_array_elements = 2;
+
+  /**
+   * This function assigns a scalar to this class.
+   */
+  DEAL_II_ALWAYS_INLINE VectorizedArray &
+  operator = (const double x)
+  {
+    data = vec_splats(x);
+    return *this;
+  }
+
+  /**
+   * Access operator. The component must be either 0 or 1.
+   */
+  DEAL_II_ALWAYS_INLINE double &
+  operator [] (const unsigned int comp)
+  {
+    AssertIndexRange (comp, 2);
+    return *(reinterpret_cast<double *>(&data)+comp);
+  }
+
+  /**
+   * Constant access operator.
+   */
+  DEAL_II_ALWAYS_INLINE const double &
+  operator [] (const unsigned int comp) const
+  {
+    AssertIndexRange (comp, 2);
+    return *(reinterpret_cast<const double *>(&data)+comp);
+  }
+
+  /**
+   * Addition.
+   */
+  DEAL_II_ALWAYS_INLINE VectorizedArray &
+  operator += (const VectorizedArray &vec)
+  {
+    data = vec_add(data,vec.data);
+    return *this;
+  }
+
+  /**
+   * Subtraction.
+   */
+  DEAL_II_ALWAYS_INLINE VectorizedArray &
+  operator -= (const VectorizedArray &vec)
+  {
+    data = vec_sub(data,vec.data);
+    return *this;
+  }
+
+  /**
+   * Multiplication.
+   */
+  DEAL_II_ALWAYS_INLINE VectorizedArray &
+  operator *= (const VectorizedArray &vec)
+  {
+    data = vec_mul(data,vec.data);
+    return *this;
+  }
+
+  /**
+   * Division.
+   */
+  DEAL_II_ALWAYS_INLINE VectorizedArray &
+  operator /= (const VectorizedArray &vec)
+  {
+    data = vec_div(data,vec.data);
+    return *this;
+  }
+
+  /**
+   * Load @p n_array_elements from memory into the calling class, starting at
+   * the given address.
+   */
+  DEAL_II_ALWAYS_INLINE void load (const double *ptr)
+  {
+    data = vec_vsx_ld (0, ptr);
+  }
+
+  /**
+   * Write the content of the calling class into memory in form of @p
+   * n_array_elements to the given address.
+   */
+  DEAL_II_ALWAYS_INLINE void store (double *ptr) const
+  {
+    vec_vsx_st (data, 0, ptr);
+  }
+
+  /** @copydoc VectorizedArray<Number>::streaming_store()
+   */
+  DEAL_II_ALWAYS_INLINE
+  void streaming_store (double *ptr) const
+  {
+    store(ptr);
+  }
+
+  /** @copydoc VectorizedArray<Number>::gather()
+   */
+  DEAL_II_ALWAYS_INLINE
+  void gather (const double       *base_ptr,
+               const unsigned int *offsets)
+  {
+    for (unsigned int i=0; i<2; ++i)
+      *(reinterpret_cast<double *>(&data)+i) = base_ptr[offsets[i]];
+  }
+
+  /** @copydoc VectorizedArray<Number>::scatter
+   */
+  DEAL_II_ALWAYS_INLINE
+  void scatter (const unsigned int *offsets,
+                double             *base_ptr) const
+  {
+    for (unsigned int i=0; i<2; ++i)
+      base_ptr[offsets[i]] = *(reinterpret_cast<const double *>(&data)+i);
+  }
+
+  /**
+   * Actual data field. Since this class represents a POD data type, it
+   * remains public.
+   */
+  __vector double data;
+
+private:
+  /**
+   * Return the square root of this field. Not for use in user code. Use
+   * sqrt(x) instead.
+   */
+  DEAL_II_ALWAYS_INLINE VectorizedArray
+  get_sqrt () const
+  {
+    VectorizedArray res;
+    res.data = vec_sqrt(data);
+    return res;
+  }
+
+  /**
+   * Return the absolute value of this field. Not for use in user code. Use
+   * abs(x) instead.
+   */
+  DEAL_II_ALWAYS_INLINE VectorizedArray
+  get_abs () const
+  {
+    VectorizedArray res;
+    res.data = vec_abs (data);
+    return res;
+  }
+
+  /**
+   * Return the component-wise maximum of this field and another one. Not for
+   * use in user code. Use max(x,y) instead.
+   */
+  DEAL_II_ALWAYS_INLINE VectorizedArray
+  get_max (const VectorizedArray &other) const
+  {
+    VectorizedArray res;
+    res.data = vec_max (data, other.data);
+    return res;
+  }
+
+  /**
+   * Return the component-wise minimum of this field and another one. Not for
+   * use in user code. Use min(x,y) instead.
+   */
+  DEAL_II_ALWAYS_INLINE VectorizedArray
+  get_min (const VectorizedArray &other) const
+  {
+    VectorizedArray res;
+    res.data = vec_min (data, other.data);
+    return res;
+  }
+
+  /**
+   * Make a few functions friends.
+   */
+  template <typename Number2> friend VectorizedArray<Number2>
+  std::sqrt (const VectorizedArray<Number2> &);
+  template <typename Number2> friend VectorizedArray<Number2>
+  std::abs  (const VectorizedArray<Number2> &);
+  template <typename Number2> friend VectorizedArray<Number2>
+  std::max  (const VectorizedArray<Number2> &, const VectorizedArray<Number2> &);
+  template <typename Number2> friend VectorizedArray<Number2>
+  std::min  (const VectorizedArray<Number2> &, const VectorizedArray<Number2> &);
+};
+
+#endif // ALTIVEC && VSX
+
+
+
 /**
  * Relational operator == for VectorizedArray
  *

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.