]> https://gitweb.dealii.org/ - dealii.git/commitdiff
VectorizedArray: accept std::initializer_list 12803/head
authorPeter Munch <peterrmuench@gmail.com>
Fri, 8 Oct 2021 05:49:38 +0000 (07:49 +0200)
committerPeter Munch <peterrmuench@gmail.com>
Sun, 10 Oct 2021 16:04:16 +0000 (18:04 +0200)
doc/news/changes/minor/20211008Munch [new file with mode: 0644]
include/deal.II/base/vectorization.h
tests/base/vectorization_16.cc [new file with mode: 0644]
tests/base/vectorization_16.output [new file with mode: 0644]

diff --git a/doc/news/changes/minor/20211008Munch b/doc/news/changes/minor/20211008Munch
new file mode 100644 (file)
index 0000000..12a44ca
--- /dev/null
@@ -0,0 +1,3 @@
+New: VectorizedArray can now be constructed from an initializer list.
+<br>
+(Peter Munch, 2021/10/08)
index 35ffce444658f675ddad293e91b7f29768edc6da..1b397fec46d6e14653534ad84dff1ce858b6dd9e 100644 (file)
@@ -251,6 +251,36 @@ template <typename T, std::size_t width>
 class VectorizedArrayBase
 {
 public:
+  /**
+   * Default constructor.
+   */
+  VectorizedArrayBase() = default;
+
+  /**
+   * Construct an array with the given initializer list.
+   */
+  template <typename U>
+  VectorizedArrayBase(const std::initializer_list<U> &list)
+  {
+    auto i0 = this->begin();
+    auto i1 = list.begin();
+
+    for (; i1 != list.end(); ++i0, ++i1)
+      {
+        Assert(
+          i0 != this->end(),
+          ExcMessage(
+            "Initializer list exceeds size of this VectorizedArray object."));
+
+        *i0 = *i1;
+      }
+
+    for (; i0 != this->end(); ++i0)
+      {
+        *i0 = 0.0;
+      }
+  }
+
   /**
    * Return the number of elements in the array.
    */
@@ -413,6 +443,14 @@ public:
     this->operator=(scalar);
   }
 
+  /**
+   * Construct an array with the given initializer list.
+   */
+  template <typename U>
+  VectorizedArray(const std::initializer_list<U> &list)
+    : VectorizedArrayBase<VectorizedArray<Number, width>, 1>(list)
+  {}
+
   /**
    * This function assigns a scalar to this class.
    */
@@ -943,6 +981,14 @@ public:
     this->operator=(scalar);
   }
 
+  /**
+   * Construct an array with the given initializer list.
+   */
+  template <typename U>
+  VectorizedArray(const std::initializer_list<U> &list)
+    : VectorizedArrayBase<VectorizedArray<double, 8>, 8>(list)
+  {}
+
   /**
    * This function can be used to set all data fields to a given scalar.
    */
@@ -1492,6 +1538,14 @@ public:
     this->operator=(scalar);
   }
 
+  /**
+   * Construct an array with the given initializer list.
+   */
+  template <typename U>
+  VectorizedArray(const std::initializer_list<U> &list)
+    : VectorizedArrayBase<VectorizedArray<float, 16>, 16>(list)
+  {}
+
   /**
    * This function can be used to set all data fields to a given scalar.
    */
@@ -2137,6 +2191,14 @@ public:
     this->operator=(scalar);
   }
 
+  /**
+   * Construct an array with the given initializer list.
+   */
+  template <typename U>
+  VectorizedArray(const std::initializer_list<U> &list)
+    : VectorizedArrayBase<VectorizedArray<double, 4>, 4>(list)
+  {}
+
   /**
    * This function can be used to set all data fields to a given scalar.
    */
@@ -2645,6 +2707,14 @@ public:
     this->operator=(scalar);
   }
 
+  /**
+   * Construct an array with the given initializer list.
+   */
+  template <typename U>
+  VectorizedArray(const std::initializer_list<U> &list)
+    : VectorizedArrayBase<VectorizedArray<float, 8>, 8>(list)
+  {}
+
   /**
    * This function can be used to set all data fields to a given scalar.
    */
@@ -3187,6 +3257,14 @@ public:
     this->operator=(scalar);
   }
 
+  /**
+   * Construct an array with the given initializer list.
+   */
+  template <typename U>
+  VectorizedArray(const std::initializer_list<U> &list)
+    : VectorizedArrayBase<VectorizedArray<double, 2>, 2>(list)
+  {}
+
   /**
    * This function can be used to set all data fields to a given scalar.
    */
@@ -3629,6 +3707,14 @@ public:
     this->operator=(scalar);
   }
 
+  /**
+   * Construct an array with the given initializer list.
+   */
+  template <typename U>
+  VectorizedArray(const std::initializer_list<U> &list)
+    : VectorizedArrayBase<VectorizedArray<float, 4>, 4>(list)
+  {}
+
   DEAL_II_ALWAYS_INLINE
   VectorizedArray &
   operator=(const float x)
@@ -4101,6 +4187,14 @@ public:
     this->operator=(scalar);
   }
 
+  /**
+   * Construct an array with the given initializer list.
+   */
+  template <typename U>
+  VectorizedArray(const std::initializer_list<U> &list)
+    : VectorizedArrayBase<VectorizedArray<double, 2>, 2>(list)
+  {}
+
   /**
    * This function assigns a scalar to this class.
    */
@@ -4337,6 +4431,14 @@ public:
     this->operator=(scalar);
   }
 
+  /**
+   * Construct an array with the given initializer list.
+   */
+  template <typename U>
+  VectorizedArray(const std::initializer_list<U> &list)
+    : VectorizedArrayBase<VectorizedArray<float, 4>, 4>(list)
+  {}
+
   /**
    * This function assigns a scalar to this class.
    */
diff --git a/tests/base/vectorization_16.cc b/tests/base/vectorization_16.cc
new file mode 100644 (file)
index 0000000..563edc5
--- /dev/null
@@ -0,0 +1,93 @@
+// ---------------------------------------------------------------------
+//
+// Copyright (C) 2015 - 2020 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 constructor of VectorizedArray with the given initializer list.
+
+#include <deal.II/base/vectorization.h>
+
+#include <limits>
+
+#include "../tests.h"
+
+
+template <typename Number, int width>
+void
+do_test(const std::initializer_list<Number> &list)
+{
+  const unsigned int entries = std::distance(list.begin(), list.end());
+
+  if (entries > width)
+    return;
+
+  const VectorizedArray<Number, width> vec = list;
+
+
+  for (unsigned int i = 0; i < entries; ++i)
+    AssertDimension(vec[i], i + 1);
+
+  for (unsigned int i = entries; i < width; ++i)
+    AssertDimension(vec[i], 0);
+}
+
+template <typename Number, int width>
+void
+do_test()
+{
+  do_test<Number, width>({1});
+  do_test<Number, width>({1, 2});
+  do_test<Number, width>({1, 2, 3});
+  do_test<Number, width>({1, 2, 3, 4});
+  do_test<Number, width>({1, 2, 3, 4, 5});
+  do_test<Number, width>({1, 2, 3, 4, 5, 6});
+  do_test<Number, width>({1, 2, 3, 4, 5, 6, 7});
+  do_test<Number, width>({1, 2, 3, 4, 5, 6, 7, 8});
+  do_test<Number, width>({1, 2, 3, 4, 5, 6, 7, 8, 9});
+  do_test<Number, width>({1, 2, 3, 4, 5, 6, 7, 8, 9, 10});
+  do_test<Number, width>({1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11});
+  do_test<Number, width>({1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12});
+  do_test<Number, width>({1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13});
+  do_test<Number, width>({1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14});
+  do_test<Number, width>({1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15});
+  do_test<Number, width>(
+    {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16});
+}
+
+
+int
+main()
+{
+  initlog();
+
+#if DEAL_II_VECTORIZATION_WIDTH_IN_BITS >= 512
+  do_test<float, 16>();
+  do_test<double, 8>();
+#endif
+
+#if DEAL_II_VECTORIZATION_WIDTH_IN_BITS >= 256
+  do_test<float, 8>();
+  do_test<double, 4>();
+#endif
+
+#if DEAL_II_VECTORIZATION_WIDTH_IN_BITS >= 128
+  do_test<float, 4>();
+  do_test<double, 2>();
+#endif
+
+  do_test<float, 1>();
+  do_test<double, 1>();
+
+  deallog << "OK!" << std::endl;
+}
diff --git a/tests/base/vectorization_16.output b/tests/base/vectorization_16.output
new file mode 100644 (file)
index 0000000..5cfb783
--- /dev/null
@@ -0,0 +1,2 @@
+
+DEAL::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.