]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Introduce VectorizedArrayBase and VectorizedArrayIterator 8900/head
authorPeter Munch <peterrmuench@gmail.com>
Fri, 11 Oct 2019 17:39:25 +0000 (19:39 +0200)
committerPeter Munch <peterrmuench@gmail.com>
Sat, 12 Oct 2019 14:18:22 +0000 (16:18 +0200)
doc/news/changes/minor/20191008MartinKronbichler [deleted file]
doc/news/changes/minor/20191012MartinKronbichlerPeterMunchDanielArndt [new file with mode: 0644]
include/deal.II/base/vectorization.h
tests/base/vectorization_iterator_01.cc [new file with mode: 0644]
tests/base/vectorization_iterator_01.output [new file with mode: 0644]

diff --git a/doc/news/changes/minor/20191008MartinKronbichler b/doc/news/changes/minor/20191008MartinKronbichler
deleted file mode 100644 (file)
index 3225e94..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-New: The class VectorizedArray now provides a member function
-VectorizedArray::size() to return the number of array elements, in analogy to
-the STL containers.
-<br>
-(Martin Kronbichler, 2019/10/08)
diff --git a/doc/news/changes/minor/20191012MartinKronbichlerPeterMunchDanielArndt b/doc/news/changes/minor/20191012MartinKronbichlerPeterMunchDanielArndt
new file mode 100644 (file)
index 0000000..dbcaa43
--- /dev/null
@@ -0,0 +1,6 @@
+New: The class VectorizedArray now provides STL-like member functions:
+VectorizedArray::size() returns the number of array elements and
+VectorizedArray:begin() as well as VectorizedArray::end() provide iterators
+enabling range-based iterations.
+<br>
+(Martin Kronbichler, Peter Munch, Daniel Arndt, 2019/10/12)
index 5dc022dfb11a5e0bbc6a5efa8ce736aee914c17c..48d3f6fa1765a89405e4bbf767c127871bcda04c 100644 (file)
@@ -84,6 +84,149 @@ struct EnableIfScalar<VectorizedArray<Number, width>>
 
 
 
+/**
+ * An iterator for VectorizedArray.
+ *
+ * @author Peter Munch, 2019
+ */
+template <typename T>
+class VectorizedArrayIterator
+{
+public:
+  /**
+   * Constructor.
+   *
+   * @param data The actual VectorizedArray.
+   * @param lane A pointer to the current lane.
+   */
+  VectorizedArrayIterator(T &data, unsigned int lane)
+    : data(data)
+    , lane(lane)
+  {}
+
+  /**
+   * Compare for inequality.
+   */
+  bool
+  operator!=(const VectorizedArrayIterator<T> &other) const
+  {
+    return this->lane != other.lane;
+  }
+
+  /**
+   * Dereferencing operator (const version): returns the value of the current
+   * lane.
+   */
+  const typename T::value_type &operator*() const
+  {
+    return data[lane];
+  }
+
+
+  /**
+   * Dereferencing operator (non-@p const version): returns the value of the
+   * current lane.
+   */
+  template <typename U = T>
+  typename std::enable_if<!std::is_same<U, const U>::value,
+                          typename T::value_type>::type &
+  operator*()
+  {
+    return data[lane];
+  }
+
+  /**
+   * Prefix <tt>++</tt> operator: <tt>++iterator</tt>. This operator advances
+   * the iterator to the next lane and returns a reference to
+   * <tt>*this</tt>.
+   */
+  VectorizedArrayIterator<T> &
+  operator++()
+  {
+    lane++;
+    return *this;
+  }
+
+private:
+  /**
+   * Reference to the actual VectorizedArray.
+   */
+  T &data;
+
+  /**
+   * Pointer to the current lane.
+   */
+  unsigned int lane;
+};
+
+
+
+/**
+ * A base class for the VectorizedArray specialization, containing common
+ * functionalities.
+ *
+ * @tparam Type of the actual vectorized array. We are using CRTP to prevent
+ * the usage of the virtual keyword.
+ *
+ * @author Peter Munch, 2019
+ */
+template <typename T>
+class VectorizedArrayBase
+{
+public:
+  /**
+   * Return the number of elements in the array stored in the variable
+   * n_array_elements of VectorizedArray.
+   */
+  static constexpr unsigned int
+  size()
+  {
+    return T::n_array_elements;
+  }
+
+  /**
+   * @return An iterator pointing to the beginning of the underlying data.
+   */
+  VectorizedArrayIterator<T>
+  begin()
+  {
+    return VectorizedArrayIterator<T>(static_cast<T &>(*this), 0);
+  }
+
+  /**
+   * @return An iterator pointing to the end of the underlying data.
+   */
+  VectorizedArrayIterator<T>
+  end()
+  {
+    return VectorizedArrayIterator<T>(static_cast<T &>(*this),
+                                      T::n_array_elements);
+  }
+
+  /**
+   * @return An iterator pointing to the beginning of the underlying data (const
+   * version).
+   */
+  VectorizedArrayIterator<const T>
+  begin() const
+  {
+    return VectorizedArrayIterator<const T>(static_cast<const T &>(*this), 0);
+  }
+
+  /**
+   * @return An iterator pointing to the end of the underlying data (const
+   * version).
+   */
+  VectorizedArrayIterator<const T>
+  end() const
+  {
+    return VectorizedArrayIterator<const T>(static_cast<const T &>(*this),
+                                            T::n_array_elements);
+  }
+};
+
+
+
 /**
  * This generic class defines a unified interface to a vectorized data type.
  * For general template arguments, this class simply corresponds to the
@@ -171,6 +314,7 @@ struct EnableIfScalar<VectorizedArray<Number, width>>
  */
 template <typename Number, int width>
 class VectorizedArray
+  : public VectorizedArrayBase<VectorizedArray<Number, width>>
 {
 public:
   /**
@@ -216,16 +360,6 @@ public:
     return *this;
   }
 
-  /**
-   * Return the number of elements in the array stored in the variable
-   * n_array_elements.
-   */
-  static constexpr unsigned int
-  size()
-  {
-    return n_array_elements;
-  }
-
   /**
    * Access operator (only valid with component 0 in the base class without
    * specialization).
@@ -657,6 +791,7 @@ vectorized_transpose_and_store(const bool                            add_into,
  */
 template <>
 class VectorizedArray<double, 8>
+  : public VectorizedArrayBase<VectorizedArray<double, 8>>
 {
 public:
   /**
@@ -694,16 +829,6 @@ public:
     return *this;
   }
 
-  /**
-   * Return the number of elements in the array stored in the variable
-   * n_array_elements.
-   */
-  static constexpr unsigned int
-  size()
-  {
-    return n_array_elements;
-  }
-
   /**
    * Access operator.
    */
@@ -1100,6 +1225,7 @@ vectorized_transpose_and_store(const bool                        add_into,
  */
 template <>
 class VectorizedArray<float, 16>
+  : public VectorizedArrayBase<VectorizedArray<float, 16>>
 {
 public:
   /**
@@ -1137,16 +1263,6 @@ public:
     return *this;
   }
 
-  /**
-   * Return the number of elements in the array stored in the variable
-   * n_array_elements.
-   */
-  static constexpr unsigned int
-  size()
-  {
-    return n_array_elements;
-  }
-
   /**
    * Access operator.
    */
@@ -1594,6 +1710,7 @@ vectorized_transpose_and_store(const bool                        add_into,
  */
 template <>
 class VectorizedArray<double, 4>
+  : public VectorizedArrayBase<VectorizedArray<double, 4>>
 {
 public:
   /**
@@ -1631,16 +1748,6 @@ public:
     return *this;
   }
 
-  /**
-   * Return the number of elements in the array stored in the variable
-   * n_array_elements.
-   */
-  static constexpr unsigned int
-  size()
-  {
-    return n_array_elements;
-  }
-
   /**
    * Access operator.
    */
@@ -2006,6 +2113,7 @@ vectorized_transpose_and_store(const bool                        add_into,
  */
 template <>
 class VectorizedArray<float, 8>
+  : public VectorizedArrayBase<VectorizedArray<float, 8>>
 {
 public:
   /**
@@ -2043,16 +2151,6 @@ public:
     return *this;
   }
 
-  /**
-   * Return the number of elements in the array stored in the variable
-   * n_array_elements.
-   */
-  static constexpr unsigned int
-  size()
-  {
-    return n_array_elements;
-  }
-
   /**
    * Access operator.
    */
@@ -2439,6 +2537,7 @@ vectorized_transpose_and_store(const bool                       add_into,
  */
 template <>
 class VectorizedArray<double, 2>
+  : public VectorizedArrayBase<VectorizedArray<double, 2>>
 {
 public:
   /**
@@ -2465,16 +2564,6 @@ public:
     this->operator=(scalar);
   }
 
-  /**
-   * Return the number of elements in the array stored in the variable
-   * n_array_elements.
-   */
-  static constexpr unsigned int
-  size()
-  {
-    return n_array_elements;
-  }
-
   /**
    * This function can be used to set all data fields to a given scalar.
    */
@@ -2810,6 +2899,7 @@ vectorized_transpose_and_store(const bool                        add_into,
  */
 template <>
 class VectorizedArray<float, 4>
+  : public VectorizedArrayBase<VectorizedArray<float, 4>>
 {
 public:
   /**
@@ -2848,16 +2938,6 @@ public:
     return *this;
   }
 
-  /**
-   * Return the number of elements in the array stored in the variable
-   * n_array_elements.
-   */
-  static constexpr unsigned int
-  size()
-  {
-    return n_array_elements;
-  }
-
   /**
    * Access operator.
    */
@@ -3202,6 +3282,7 @@ vectorized_transpose_and_store(const bool                       add_into,
 
 template <>
 class VectorizedArray<double, 2>
+  : public VectorizedArrayBase<VectorizedArray<double, 2>>
 {
 public:
   /**
@@ -3239,16 +3320,6 @@ public:
     return *this;
   }
 
-  /**
-   * Return the number of elements in the array stored in the variable
-   * n_array_elements.
-   */
-  static constexpr unsigned int
-  size()
-  {
-    return n_array_elements;
-  }
-
   /**
    * Access operator. The component must be either 0 or 1.
    */
@@ -3444,6 +3515,7 @@ private:
 
 template <>
 class VectorizedArray<float, 4>
+  : public VectorizedArrayBase<VectorizedArray<float, 4>>
 {
 public:
   /**
@@ -3481,16 +3553,6 @@ public:
     return *this;
   }
 
-  /**
-   * Return the number of elements in the array stored in the variable
-   * n_array_elements.
-   */
-  static constexpr unsigned int
-  size()
-  {
-    return n_array_elements;
-  }
-
   /**
    * Access operator. The component must be between 0 and 3.
    */
diff --git a/tests/base/vectorization_iterator_01.cc b/tests/base/vectorization_iterator_01.cc
new file mode 100644 (file)
index 0000000..da85b47
--- /dev/null
@@ -0,0 +1,74 @@
+// ---------------------------------------------------------------------
+//
+// Copyright (C) 2019 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE.md at
+// the top level directory of deal.II.
+//
+// ---------------------------------------------------------------------
+
+
+// test for arithmetic operations on VectorizedArray
+
+#include <deal.II/base/vectorization.h>
+
+#include "../tests.h"
+
+
+template <typename Number>
+void
+test_const(const VectorizedArray<Number> &vector)
+{
+  unsigned int counter = 0;
+  for (const auto v : vector)
+    {
+      AssertThrow(v == vector[counter++], ExcInternalError());
+    }
+}
+
+template <typename Number>
+void
+test_nonconst(VectorizedArray<Number> &vector)
+{
+  unsigned int counter = 0;
+  for (auto v : vector)
+    {
+      AssertThrow(v == vector[counter++], ExcInternalError());
+    }
+}
+
+template <typename Number>
+void
+test()
+{
+  VectorizedArray<Number> vector;
+
+  for (unsigned int v = 0; v < VectorizedArray<Number>::size(); v++)
+    vector[v] = v;
+
+  test_const(vector);
+  test_nonconst(vector);
+}
+
+
+int
+main()
+{
+  initlog();
+
+  deallog.push("float");
+  test<float>();
+  deallog << "OK" << std::endl;
+  deallog.pop();
+
+  deallog.push("double");
+  test<double>();
+  deallog << "OK" << std::endl;
+  deallog.pop();
+}
diff --git a/tests/base/vectorization_iterator_01.output b/tests/base/vectorization_iterator_01.output
new file mode 100644 (file)
index 0000000..76f093e
--- /dev/null
@@ -0,0 +1,3 @@
+
+DEAL:float::OK
+DEAL:double::OK

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.