From fd14853f1f8cdf81d922fbc15602281a91a16844 Mon Sep 17 00:00:00 2001 From: Peter Munch Date: Fri, 8 Oct 2021 07:49:38 +0200 Subject: [PATCH] VectorizedArray: accept std::initializer_list --- doc/news/changes/minor/20211008Munch | 3 + include/deal.II/base/vectorization.h | 102 +++++++++++++++++++++++++++ tests/base/vectorization_16.cc | 93 ++++++++++++++++++++++++ tests/base/vectorization_16.output | 2 + 4 files changed, 200 insertions(+) create mode 100644 doc/news/changes/minor/20211008Munch create mode 100644 tests/base/vectorization_16.cc create mode 100644 tests/base/vectorization_16.output diff --git a/doc/news/changes/minor/20211008Munch b/doc/news/changes/minor/20211008Munch new file mode 100644 index 0000000000..12a44ca076 --- /dev/null +++ b/doc/news/changes/minor/20211008Munch @@ -0,0 +1,3 @@ +New: VectorizedArray can now be constructed from an initializer list. +
+(Peter Munch, 2021/10/08) diff --git a/include/deal.II/base/vectorization.h b/include/deal.II/base/vectorization.h index 35ffce4446..1b397fec46 100644 --- a/include/deal.II/base/vectorization.h +++ b/include/deal.II/base/vectorization.h @@ -251,6 +251,36 @@ template class VectorizedArrayBase { public: + /** + * Default constructor. + */ + VectorizedArrayBase() = default; + + /** + * Construct an array with the given initializer list. + */ + template + VectorizedArrayBase(const std::initializer_list &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 + VectorizedArray(const std::initializer_list &list) + : VectorizedArrayBase, 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 + VectorizedArray(const std::initializer_list &list) + : VectorizedArrayBase, 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 + VectorizedArray(const std::initializer_list &list) + : VectorizedArrayBase, 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 + VectorizedArray(const std::initializer_list &list) + : VectorizedArrayBase, 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 + VectorizedArray(const std::initializer_list &list) + : VectorizedArrayBase, 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 + VectorizedArray(const std::initializer_list &list) + : VectorizedArrayBase, 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 + VectorizedArray(const std::initializer_list &list) + : VectorizedArrayBase, 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 + VectorizedArray(const std::initializer_list &list) + : VectorizedArrayBase, 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 + VectorizedArray(const std::initializer_list &list) + : VectorizedArrayBase, 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 index 0000000000..563edc5ef4 --- /dev/null +++ b/tests/base/vectorization_16.cc @@ -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 + +#include + +#include "../tests.h" + + +template +void +do_test(const std::initializer_list &list) +{ + const unsigned int entries = std::distance(list.begin(), list.end()); + + if (entries > width) + return; + + const VectorizedArray 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 +void +do_test() +{ + do_test({1}); + do_test({1, 2}); + do_test({1, 2, 3}); + do_test({1, 2, 3, 4}); + do_test({1, 2, 3, 4, 5}); + do_test({1, 2, 3, 4, 5, 6}); + do_test({1, 2, 3, 4, 5, 6, 7}); + do_test({1, 2, 3, 4, 5, 6, 7, 8}); + do_test({1, 2, 3, 4, 5, 6, 7, 8, 9}); + do_test({1, 2, 3, 4, 5, 6, 7, 8, 9, 10}); + do_test({1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}); + do_test({1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}); + do_test({1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}); + do_test({1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}); + do_test({1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}); + do_test( + {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(); + do_test(); +#endif + +#if DEAL_II_VECTORIZATION_WIDTH_IN_BITS >= 256 + do_test(); + do_test(); +#endif + +#if DEAL_II_VECTORIZATION_WIDTH_IN_BITS >= 128 + do_test(); + do_test(); +#endif + + do_test(); + do_test(); + + deallog << "OK!" << std::endl; +} diff --git a/tests/base/vectorization_16.output b/tests/base/vectorization_16.output new file mode 100644 index 0000000000..5cfb783b8f --- /dev/null +++ b/tests/base/vectorization_16.output @@ -0,0 +1,2 @@ + +DEAL::OK! -- 2.39.5