From: Peter Munch Date: Fri, 11 Oct 2019 17:39:25 +0000 (+0200) Subject: Introduce VectorizedArrayBase and VectorizedArrayIterator X-Git-Tag: v9.2.0-rc1~987^2 X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2375c6efc1405774d341ecf03132dc6cd0d2c4c4;p=dealii.git Introduce VectorizedArrayBase and VectorizedArrayIterator --- diff --git a/doc/news/changes/minor/20191008MartinKronbichler b/doc/news/changes/minor/20191008MartinKronbichler deleted file mode 100644 index 3225e94246..0000000000 --- a/doc/news/changes/minor/20191008MartinKronbichler +++ /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. -
-(Martin Kronbichler, 2019/10/08) diff --git a/doc/news/changes/minor/20191012MartinKronbichlerPeterMunchDanielArndt b/doc/news/changes/minor/20191012MartinKronbichlerPeterMunchDanielArndt new file mode 100644 index 0000000000..dbcaa430bb --- /dev/null +++ b/doc/news/changes/minor/20191012MartinKronbichlerPeterMunchDanielArndt @@ -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. +
+(Martin Kronbichler, Peter Munch, Daniel Arndt, 2019/10/12) diff --git a/include/deal.II/base/vectorization.h b/include/deal.II/base/vectorization.h index 5dc022dfb1..48d3f6fa17 100644 --- a/include/deal.II/base/vectorization.h +++ b/include/deal.II/base/vectorization.h @@ -84,6 +84,149 @@ struct EnableIfScalar> +/** + * An iterator for VectorizedArray. + * + * @author Peter Munch, 2019 + */ +template +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 &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 std::enable_if::value, + typename T::value_type>::type & + operator*() + { + return data[lane]; + } + + /** + * Prefix ++ operator: ++iterator. This operator advances + * the iterator to the next lane and returns a reference to + * *this. + */ + VectorizedArrayIterator & + 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 +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 + begin() + { + return VectorizedArrayIterator(static_cast(*this), 0); + } + + /** + * @return An iterator pointing to the end of the underlying data. + */ + VectorizedArrayIterator + end() + { + return VectorizedArrayIterator(static_cast(*this), + T::n_array_elements); + } + + /** + * @return An iterator pointing to the beginning of the underlying data (const + * version). + */ + VectorizedArrayIterator + begin() const + { + return VectorizedArrayIterator(static_cast(*this), 0); + } + + /** + * @return An iterator pointing to the end of the underlying data (const + * version). + */ + VectorizedArrayIterator + end() const + { + return VectorizedArrayIterator(static_cast(*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> */ template class VectorizedArray + : public VectorizedArrayBase> { 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 + : public VectorizedArrayBase> { 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 + : public VectorizedArrayBase> { 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 + : public VectorizedArrayBase> { 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 + : public VectorizedArrayBase> { 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 + : public VectorizedArrayBase> { 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 + : public VectorizedArrayBase> { 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 + : public VectorizedArrayBase> { 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 + : public VectorizedArrayBase> { 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 index 0000000000..da85b477ff --- /dev/null +++ b/tests/base/vectorization_iterator_01.cc @@ -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 + +#include "../tests.h" + + +template +void +test_const(const VectorizedArray &vector) +{ + unsigned int counter = 0; + for (const auto v : vector) + { + AssertThrow(v == vector[counter++], ExcInternalError()); + } +} + +template +void +test_nonconst(VectorizedArray &vector) +{ + unsigned int counter = 0; + for (auto v : vector) + { + AssertThrow(v == vector[counter++], ExcInternalError()); + } +} + +template +void +test() +{ + VectorizedArray vector; + + for (unsigned int v = 0; v < VectorizedArray::size(); v++) + vector[v] = v; + + test_const(vector); + test_nonconst(vector); +} + + +int +main() +{ + initlog(); + + deallog.push("float"); + test(); + deallog << "OK" << std::endl; + deallog.pop(); + + deallog.push("double"); + test(); + 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 index 0000000000..76f093e48f --- /dev/null +++ b/tests/base/vectorization_iterator_01.output @@ -0,0 +1,3 @@ + +DEAL:float::OK +DEAL:double::OK