From da4ce1731ed004ffbc18930f51edfebd6fa5b816 Mon Sep 17 00:00:00 2001 From: Maximilian Bergbauer Date: Thu, 14 Sep 2023 14:46:19 +0200 Subject: [PATCH] Not a base class --- include/deal.II/base/array_view.h | 392 ++++++++++++++++++------------ 1 file changed, 243 insertions(+), 149 deletions(-) diff --git a/include/deal.II/base/array_view.h b/include/deal.II/base/array_view.h index 729c64430b..684789e32e 100644 --- a/include/deal.II/base/array_view.h +++ b/include/deal.II/base/array_view.h @@ -39,142 +39,6 @@ class Table; template class LAPACKFullMatrix; -/** - * Base class of @p ArrayView which allows strided access into the view. - * This is particularly useful when you want to access only one lane of a - * VectorizedArray. - */ -template -class StridedArrayView -{ -public: - /** - * An alias that denotes the "value_type" of this container-like class, - * i.e., the type of the element it "stores" or points to. - */ - using value_type = ElementType; - - /** - * Constructor. - * - * @param[in] starting_element A pointer to the first element of the array - * this object should represent. - * @param[in] n_elements The length (in elements) of the chunk of memory - * this object should represent. - * - * @note The object that is constructed from these arguments has no - * knowledge how large the object into which it points really is. As a - * consequence, whenever you call ArrayView::operator[], the array view can - * check that the given index is within the range of the view, but it can't - * check that the view is indeed a subset of the valid range of elements of - * the underlying object that allocated that range. In other words, you need - * to ensure that the range of the view specified by the two arguments to - * this constructor is in fact a subset of the elements of the array into - * which it points. The appropriate way to do this is to use the - * make_array_view() functions. - */ - StridedArrayView(value_type *starting_element, const std::size_t n_elements); - - /** - * Return the size (in elements) of the view of memory this object - * represents. - */ - std::size_t - size() const; - - /** - * Return a bool whether the array view is empty. - */ - bool - empty() const; - - /** - * Return a pointer to the underlying array serving as element storage. - * In case the container is empty a nullptr is returned. - */ - DEAL_II_HOST_DEVICE value_type * - data() const noexcept; - - /** - * Return a reference to the $i$th element of the range represented by the - * current object. - * - * This function is marked as @p const because it does not change the - * view object. It may however return a reference to a non-@p const - * memory location depending on whether the template type of the class is @p - * const or not. - * - * This function is only allowed to be called if the underlying data is indeed - * stored in CPU memory. - */ - value_type & - operator[](const std::size_t i) const; - -protected: - /** - * A pointer to the first element of the range of locations in memory that - * this object represents. - */ - value_type *starting_element; - - /** - * The length of the array this object represents. - */ - std::size_t n_elements; -}; - - - -template -typename StridedArrayView::value_type & -StridedArrayView::operator[](const std::size_t i) const -{ - AssertIndexRange(i, this->n_elements); - - return *(this->starting_element + stride * i); -} - - - -template -DEAL_II_HOST_DEVICE typename StridedArrayView::value_type * -StridedArrayView::data() const noexcept -{ - if (this->n_elements == 0) - return nullptr; - else - return this->starting_element; -} - - - -template -bool -StridedArrayView::empty() const -{ - return this->n_elements == 0; -} - - - -template -std::size_t -StridedArrayView::size() const -{ - return this->n_elements; -} - - - -template -StridedArrayView::StridedArrayView( - value_type *starting_element, - const std::size_t n_elements) - : starting_element(starting_element) - , n_elements(n_elements) -{} - - /** * A class that represents a window of memory locations of type @p ElementType @@ -218,7 +82,7 @@ StridedArrayView::StridedArrayView( * @ingroup data */ template -class ArrayView : public StridedArrayView +class ArrayView { public: /** @@ -445,6 +309,26 @@ public: operator!=(const ArrayView, MemorySpaceType> &other_view) const; + /** + * Return the size (in elements) of the view of memory this object + * represents. + */ + std::size_t + size() const; + + /** + * Return a bool whether the array view is empty. + */ + bool + empty() const; + + /** + * Return a pointer to the underlying array serving as element storage. + * In case the container is empty a nullptr is returned. + */ + DEAL_II_HOST_DEVICE value_type * + data() const noexcept; + /** * Return an iterator pointing to the beginning of the array view. */ @@ -469,6 +353,33 @@ public: const_iterator cend() const; + /** + * Return a reference to the $i$th element of the range represented by the + * current object. + * + * This function is marked as @p const because it does not change the + * view object. It may however return a reference to a non-@p const + * memory location depending on whether the template type of the class is @p + * const or not. + * + * This function is only allowed to be called if the underlying data is indeed + * stored in CPU memory. + */ + value_type & + operator[](const std::size_t i) const; + +private: + /** + * A pointer to the first element of the range of locations in memory that + * this object represents. + */ + value_type *starting_element; + + /** + * The length of the array this object represents. + */ + std::size_t n_elements; + friend class ArrayView; }; @@ -479,7 +390,8 @@ public: template inline ArrayView::ArrayView() - : StridedArrayView(nullptr, 0) + : starting_element(nullptr) + , n_elements(0) {} @@ -488,7 +400,8 @@ template inline ArrayView::ArrayView( value_type *starting_element, const std::size_t n_elements) - : StridedArrayView(starting_element, n_elements) + : starting_element(starting_element) + , n_elements(n_elements) {} @@ -506,7 +419,8 @@ ArrayView::reinit(value_type *starting_element, template inline ArrayView::ArrayView(ElementType &element) - : StridedArrayView(&element, 1) + : starting_element(&element) + , n_elements(1) {} @@ -514,7 +428,8 @@ inline ArrayView::ArrayView(ElementType &element) template inline ArrayView::ArrayView( const ArrayView, MemorySpaceType> &view) - : StridedArrayView(view.starting_element, view.n_elements) + : starting_element(view.starting_element) + , n_elements(view.n_elements) {} @@ -601,8 +516,8 @@ inline bool ArrayView::operator==( const ArrayView &other_view) const { - return (other_view.data() == this->starting_element) && - (other_view.size() == this->n_elements); + return (other_view.data() == starting_element) && + (other_view.size() == n_elements); } @@ -613,8 +528,8 @@ ArrayView::operator==( const ArrayView, MemorySpaceType> &other_view) const { - return (other_view.data() == this->starting_element) && - (other_view.size() == this->n_elements); + return (other_view.data() == starting_element) && + (other_view.size() == n_elements); } @@ -629,6 +544,19 @@ ArrayView::operator!=( +template +inline DEAL_II_HOST_DEVICE + typename ArrayView::value_type * + ArrayView::data() const noexcept +{ + if (n_elements == 0) + return nullptr; + else + return starting_element; +} + + + template inline bool ArrayView::operator!=( @@ -640,11 +568,29 @@ ArrayView::operator!=( +template +inline std::size_t +ArrayView::size() const +{ + return n_elements; +} + + + +template +inline bool +ArrayView::empty() const +{ + return n_elements == 0; +} + + + template inline typename ArrayView::iterator ArrayView::begin() const { - return this->starting_element; + return starting_element; } @@ -653,7 +599,7 @@ template inline typename ArrayView::iterator ArrayView::end() const { - return this->starting_element + this->n_elements; + return starting_element + n_elements; } @@ -662,7 +608,7 @@ template inline typename ArrayView::const_iterator ArrayView::cbegin() const { - return this->starting_element; + return starting_element; } @@ -671,11 +617,159 @@ template inline typename ArrayView::const_iterator ArrayView::cend() const { - return this->starting_element + this->n_elements; + return starting_element + n_elements; +} + + + +template +inline typename ArrayView::value_type & +ArrayView::operator[](const std::size_t i) const +{ + AssertIndexRange(i, n_elements); + + return *(starting_element + i); +} + + + +/** + * A variation of @p ArrayView which allows strided access into the view. + * This is particularly useful when you want to access only one lane of a + * VectorizedArray. + */ +template +class StridedArrayView +{ +public: + /** + * An alias that denotes the "value_type" of this container-like class, + * i.e., the type of the element it "stores" or points to. + */ + using value_type = ElementType; + + /** + * Constructor. + * + * @param[in] starting_element A pointer to the first element of the array + * this object should represent. + * @param[in] n_elements The length (in elements) of the chunk of memory + * this object should represent. + * + * @note The object that is constructed from these arguments has no + * knowledge how large the object into which it points really is. As a + * consequence, whenever you call ArrayView::operator[], the array view can + * check that the given index is within the range of the view, but it can't + * check that the view is indeed a subset of the valid range of elements of + * the underlying object that allocated that range. In other words, you need + * to ensure that the range of the view specified by the two arguments to + * this constructor is in fact a subset of the elements of the array into + * which it points. The appropriate way to do this is to use the + * make_array_view() functions. + */ + StridedArrayView(value_type *starting_element, const std::size_t n_elements); + + /** + * Return the size (in elements) of the view of memory this object + * represents. + */ + std::size_t + size() const; + + /** + * Return a bool whether the array view is empty. + */ + bool + empty() const; + + /** + * Return a pointer to the underlying array serving as element storage. + * In case the container is empty a nullptr is returned. + */ + value_type * + data() const noexcept; + + /** + * Return a reference to the $i$th element of the range represented by the + * current object. + * + * This function is marked as @p const because it does not change the + * view object. It may however return a reference to a non-@p const + * memory location depending on whether the template type of the class is @p + * const or not. + * + * This function is only allowed to be called if the underlying data is indeed + * stored in CPU memory. + */ + value_type & + operator[](const std::size_t i) const; + +protected: + /** + * A pointer to the first element of the range of locations in memory that + * this object represents. + */ + value_type *starting_element; + + /** + * The length of the array this object represents. + */ + std::size_t n_elements; +}; + + + +template +typename StridedArrayView::value_type & +StridedArrayView::operator[](const std::size_t i) const +{ + AssertIndexRange(i, this->n_elements); + + return *(this->starting_element + stride * i); +} + + + +template +typename StridedArrayView::value_type * +StridedArrayView::data() const noexcept +{ + if (this->n_elements == 0) + return nullptr; + else + return this->starting_element; } +template +bool +StridedArrayView::empty() const +{ + return this->n_elements == 0; +} + + + +template +std::size_t +StridedArrayView::size() const +{ + return this->n_elements; +} + + + +template +StridedArrayView::StridedArrayView( + value_type *starting_element, + const std::size_t n_elements) + : starting_element(starting_element) + , n_elements(n_elements) +{} + + + #ifndef DOXYGEN namespace internal { -- 2.39.5