Project
Loading...
Searching...
No Matches
AlignedArray.h
Go to the documentation of this file.
1// Copyright 2019-2023 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
15
16#ifndef RANS_INTERNAL_CONTAINERS_ALIGNEDARRAY_H_
17#define RANS_INTERNAL_CONTAINERS_ALIGNEDARRAY_H_
18
19#include <cstring>
20#include <cassert>
21#include <cstdint>
22#include <type_traits>
23
24#include <fmt/format.h>
25#include <gsl/span>
26
29
31{
32
33template <typename array_T>
35{
36 template <typename T>
37 struct getValueType {
38 using type = std::conditional_t<std::is_const_v<T>, const typename T::value_type, typename T::value_type>;
39 };
40
41 public:
42 using difference_type = std::ptrdiff_t;
43 using value_type = gsl::span<typename getValueType<array_T>::type, array_T::nElementsPerLane()>;
46 using iterator_category = std::random_access_iterator_tag;
47
48 inline constexpr AlignedArrayIterator() noexcept = default;
49
50 inline constexpr AlignedArrayIterator(array_T* array, difference_type index) noexcept : mIndex{index} {};
51 inline constexpr AlignedArrayIterator(const AlignedArrayIterator& iter) noexcept = default;
52 inline constexpr AlignedArrayIterator(AlignedArrayIterator&& iter) noexcept = default;
53 inline constexpr AlignedArrayIterator& operator=(const AlignedArrayIterator& other) noexcept = default;
54 inline constexpr AlignedArrayIterator& operator=(AlignedArrayIterator&& other) noexcept = default;
55 inline ~AlignedArrayIterator() noexcept = default;
56
57 // pointer arithmetics
58 inline constexpr AlignedArrayIterator& operator++() noexcept
59 {
60 ++mIndex;
61 return *this;
62 };
63
64 inline constexpr AlignedArrayIterator operator++(int) noexcept
65 {
66 auto res = *this;
67 ++(*this);
68 return res;
69 };
70
71 inline constexpr AlignedArrayIterator& operator--() noexcept
72 {
73 --mIndex;
74 return *this;
75 };
76
77 inline constexpr AlignedArrayIterator operator--(int) noexcept
78 {
79 auto res = *this;
80 --(*this);
81 return res;
82 };
83
85 {
86 mIndex += i;
87 return *this;
88 };
89
90 inline constexpr AlignedArrayIterator operator+(difference_type i) const noexcept
91 {
92 auto tmp = *const_cast<AlignedArrayIterator*>(this);
93 return tmp += i;
94 }
95
97 {
98 mIndex -= i;
99 return *this;
100 };
101
102 inline constexpr AlignedArrayIterator operator-(difference_type i) const noexcept
103 {
104 auto tmp = *const_cast<AlignedArrayIterator*>(this);
105 return tmp -= i;
106 };
107
108 inline constexpr difference_type operator-(const AlignedArrayIterator& other) const noexcept
109 {
110 return this->mIter - other.mIter;
111 };
112
113 // comparison
114 inline constexpr bool operator==(const AlignedArrayIterator& other) const noexcept { return this->mIndex == other.mIndex; };
115 inline constexpr bool operator!=(const AlignedArrayIterator& other) const noexcept { return this->mIndex != other.mIndex; };
116 inline constexpr bool operator<(const AlignedArrayIterator& other) const noexcept { return this->mIndex < other->mIndex; };
117 inline constexpr bool operator>(const AlignedArrayIterator& other) const noexcept { return this->mIndex > other->mIndex; };
118 inline constexpr bool operator>=(const AlignedArrayIterator& other) const noexcept { return this->mIndex >= other->mIndex; };
119 inline constexpr bool operator<=(const AlignedArrayIterator& other) const noexcept { return this->mIndex <= other->mIndex; };
120
121 // dereference
122 inline constexpr value_type operator*() const noexcept { return (*mContainer)[mIndex]; };
123
124 inline constexpr value_type operator[](difference_type i) const noexcept { return (*mContainer)[mIndex + i]; };
125
126 private:
127 array_T* mContainer;
128 difference_type mIndex{};
129};
130
131template <typename T, SIMDWidth width_V, size_t size_V = 1>
132class alignas(getAlignment(width_V)) AlignedArray
133{
134 public:
135 using value_type = T;
140 using reverse_iterator = std::reverse_iterator<iterator>;
141 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
142
143 static inline constexpr size_t size() noexcept { return size_V; };
144 static inline constexpr size_t nElementsPerLane() noexcept { return getElementCount<value_type>(width_V); };
145 static inline constexpr size_t nElements() noexcept { return size() * nElementsPerLane(); };
146
147 inline constexpr AlignedArray() noexcept {}; // NOLINT
148
149 template <typename elem_T, std::enable_if_t<std::is_convertible_v<elem_T, value_type>, bool> = true>
150 inline constexpr AlignedArray(elem_T value) noexcept
151 {
152 for (auto& elem : mData) {
153 elem = static_cast<value_type>(value);
154 }
155 };
156
157 template <typename... Args, std::enable_if_t<(sizeof...(Args) == AlignedArray<T, width_V, size_V>::nElements()) && std::is_convertible_v<std::common_type_t<Args...>, value_type>, bool> = true>
158 inline constexpr AlignedArray(Args... args) noexcept : mData{static_cast<value_type>(args)...} {};
159
160 inline constexpr const T* data() const noexcept { return mData; };
161 inline constexpr T* data() noexcept { return const_cast<T*>(static_cast<const AlignedArray&>(*this).data()); };
162 inline constexpr const_iterator begin() const noexcept { return {this, 0}; };
163 inline constexpr const_iterator end() const noexcept { return {this, size()}; };
164 inline constexpr iterator begin() noexcept { return {this, 0}; };
165 inline constexpr iterator end() noexcept { return {this, size()}; };
166 inline constexpr const_reverse_iterator rbegin() const noexcept { return std::reverse_iterator(this->end()); };
167 inline constexpr const_reverse_iterator rend() const noexcept { return std::reverse_iterator(this->begin()); };
168 inline constexpr reverse_iterator rbegin() noexcept { return std::reverse_iterator(this->end()); };
169 inline constexpr reverse_iterator rend() noexcept { return std::reverse_iterator(this->begin()); };
170
171 inline constexpr gsl::span<T, nElementsPerLane()> operator[](size_t idx) { return gsl::span<T, nElementsPerLane()>{mData + idx * nElementsPerLane(), nElementsPerLane()}; };
172
173 inline constexpr gsl::span<const T, nElementsPerLane()> operator[](size_t idx) const { return gsl::span<const T, nElementsPerLane()>{mData + idx * nElementsPerLane(), nElementsPerLane()}; };
174
175 inline constexpr const T& operator()(size_t idx, size_t elem) const
176 {
177 return (*this)[idx][elem];
178 };
179
180 inline constexpr T& operator()(size_t idx, size_t elem) { return const_cast<T&>(static_cast<const AlignedArray&>(*this)(idx, elem)); };
181
182 inline constexpr const T& operator()(size_t idx) const
183 {
184 return *(this->data() + idx);
185 };
186
187 inline constexpr T& operator()(size_t idx) { return const_cast<T&>(static_cast<const AlignedArray&>(*this)(idx)); };
188
189 private:
190 T mData[nElements()]{};
191};
192
193template <SIMDWidth width_V, size_t size_V = 1>
195template <SIMDWidth width_V, size_t size_V = 1>
197template <SIMDWidth width_V, size_t size_V = 1>
199template <SIMDWidth width_V, size_t size_V = 1>
201template <SIMDWidth width_V, size_t size_V = 1>
203
204template <typename T>
206
207template <typename T, SIMDWidth simd_V>
208struct simdWidth<AlignedArray<T, simd_V>> : public std::integral_constant<SIMDWidth, simd_V> {
209};
210
211template <typename T>
212inline constexpr SIMDWidth simdWidth_v = simdWidth<T>::value;
213
214template <typename T>
216
217template <typename T, SIMDWidth simd_V, size_t size_V>
218struct elementCount<AlignedArray<T, simd_V, size_V>> : public std::integral_constant<size_t, size_V * getElementCount<T>(simd_V)> {
219};
220
221template <typename T>
222inline constexpr size_t elementCount_v = elementCount<T>::value;
223
224namespace alignedArrayImpl
225{
227{
228 public:
229 template <typename T, std::enable_if_t<std::is_arithmetic_v<T>, bool> = true>
230 inline std::string operator()(const T& value)
231 {
232 return fmt::format("{}", value);
233 }
234
235 inline std::string operator()(const uint8_t& value)
236 {
237 return fmt::format("{}", static_cast<uint32_t>(value));
238 }
239};
240
242{
243 public:
244 template <typename T, std::enable_if_t<std::is_arithmetic_v<T>, bool> = true>
245 inline std::string operator()(const T& value)
246 {
247 return fmt::format("{:#0x}", value);
248 }
249};
250
251} // namespace alignedArrayImpl
252
253template <typename T, SIMDWidth width_V, size_t size_V, class formater_T = alignedArrayImpl::IdentityFormatingFunctor>
254std::ostream& operator<<(std::ostream& stream, const AlignedArray<T, width_V, size_V>& array)
255{
256 stream << "[";
257 for (auto subspan : array) {
258 operator<< <const T, getElementCount<T>(width_V), formater_T>(stream, subspan);
259 stream << ", ";
260 }
261 stream << "]";
262 return stream;
263};
264
265template <typename T, SIMDWidth width_V, size_t size_V>
267{
268 std::ostringstream stream;
269 operator<< <T, width_V, size_V, alignedArrayImpl::HexFormatingFunctor>(stream, array);
270 return stream.str();
271};
272
273} // namespace o2::rans::internal::simd
274
275namespace std
276{
277template <typename T, size_t extent_V, class formatingFunctor = o2::rans::internal::simd::alignedArrayImpl::IdentityFormatingFunctor>
278std::ostream& operator<<(std::ostream& stream, const gsl::span<T, extent_V>& span)
279{
280
281 if (span.empty()) {
282 stream << "[]";
283 return stream;
284 } else {
285 formatingFunctor formater;
286
287 stream << "[";
288 for (size_t i = 0; i < span.size() - 1; ++i) {
289 stream << formater(span[i]) << ", ";
290 }
291 stream << formater(*(--span.end())) << "]";
292 return stream;
293 }
294 return stream;
295}
296} // namespace std
297
298namespace gsl
299{
300template <typename T, o2::rans::internal::simd::SIMDWidth width_V, size_t size_V>
302{
303 return gsl::span<const T, o2::rans::internal::simd::AlignedArray<T, width_V, size_V>::nElements()>(array.data(), array.nElements());
304};
305
306template <typename T, o2::rans::internal::simd::SIMDWidth width_V, size_t size_V>
308{
309 return gsl::span<T, o2::rans::internal::simd::AlignedArray<T, width_V, size_V>::nElements()>(array.data(), array.nElements());
310};
311
312} // namespace gsl
313
314#endif /* RANS_INTERNAL_CONTAINERS_ALIGNEDARRAY_H_ */
int32_t i
uint32_t res
Definition RawData.h:0
common helper classes and functions
constexpr difference_type operator-(const AlignedArrayIterator &other) const noexcept
constexpr AlignedArrayIterator(AlignedArrayIterator &&iter) noexcept=default
gsl::span< typename getValueType< array_T >::type, array_T::nElementsPerLane()> value_type
constexpr bool operator==(const AlignedArrayIterator &other) const noexcept
constexpr AlignedArrayIterator & operator=(AlignedArrayIterator &&other) noexcept=default
constexpr bool operator>=(const AlignedArrayIterator &other) const noexcept
std::random_access_iterator_tag iterator_category
constexpr AlignedArrayIterator operator+(difference_type i) const noexcept
constexpr AlignedArrayIterator operator-(difference_type i) const noexcept
constexpr bool operator<=(const AlignedArrayIterator &other) const noexcept
constexpr value_type operator[](difference_type i) const noexcept
constexpr bool operator<(const AlignedArrayIterator &other) const noexcept
constexpr AlignedArrayIterator & operator-=(difference_type i) noexcept
constexpr AlignedArrayIterator operator++(int) noexcept
constexpr AlignedArrayIterator() noexcept=default
constexpr AlignedArrayIterator & operator+=(difference_type i) noexcept
constexpr AlignedArrayIterator operator--(int) noexcept
constexpr AlignedArrayIterator & operator--() noexcept
constexpr value_type operator*() const noexcept
constexpr AlignedArrayIterator & operator=(const AlignedArrayIterator &other) noexcept=default
constexpr AlignedArrayIterator(const AlignedArrayIterator &iter) noexcept=default
constexpr bool operator>(const AlignedArrayIterator &other) const noexcept
constexpr bool operator!=(const AlignedArrayIterator &other) const noexcept
static constexpr size_t size() noexcept
std::reverse_iterator< iterator > reverse_iterator
constexpr AlignedArray(Args... args) noexcept
constexpr const_iterator end() const noexcept
constexpr gsl::span< T, nElementsPerLane()> operator[](size_t idx)
static constexpr size_t nElements() noexcept
constexpr const_reverse_iterator rbegin() const noexcept
constexpr const T & operator()(size_t idx) const
constexpr iterator end() noexcept
constexpr const_iterator begin() const noexcept
std::reverse_iterator< const_iterator > const_reverse_iterator
static constexpr size_t nElementsPerLane() noexcept
constexpr const T & operator()(size_t idx, size_t elem) const
constexpr const T * data() const noexcept
constexpr T & operator()(size_t idx)
constexpr iterator begin() noexcept
constexpr reverse_iterator rbegin() noexcept
constexpr const_reverse_iterator rend() const noexcept
constexpr T & operator()(size_t idx, size_t elem)
constexpr AlignedArray(elem_T value) noexcept
constexpr gsl::span< const T, nElementsPerLane()> operator[](size_t idx) const
constexpr reverse_iterator rend() noexcept
GLenum array
Definition glcorearb.h:4274
GLuint index
Definition glcorearb.h:781
GLsizei const GLfloat * value
Definition glcorearb.h:819
GLint GLint GLsizei GLint GLenum GLenum type
Definition glcorearb.h:275
GLuint GLuint stream
Definition glcorearb.h:1806
auto make_span(const o2::rans::internal::simd::AlignedArray< T, width_V, size_V > &array)
constexpr size_t elementCount_v
std::string asHex(const AlignedArray< T, width_V, size_V > &array)
constexpr SIMDWidth simdWidth_v
std::ostream & operator<<(std::ostream &stream, const AlignedArray< T, width_V, size_V > &array)
if constexpr(std::is_unsigned_v< source_T >)
Defining DataPointCompositeObject explicitly as copiable.
std::ostream & operator<<(std::ostream &stream, const gsl::span< T, extent_V > &span)
basic SIMD datatypes and traits
VectorOfTObjectPtrs other