Loading [MathJax]/extensions/TeX/AMSmath.js
ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages Concepts
Array.hpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2010-2022 The ESPResSo project
3 *
4 * This file is part of ESPResSo.
5 *
6 * ESPResSo is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * ESPResSo is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#pragma once
21
22/**
23 * @file
24 *
25 * @brief Array implementation with CUDA support.
26 */
27
28#include "device_qualifier.hpp"
29#include "get.hpp"
31
32#include <boost/serialization/access.hpp>
33
34#include <cassert>
35#include <cstddef>
36#include <iterator>
37#include <ostream>
38#include <stdexcept>
39#include <utility>
40
41namespace Utils {
42namespace detail {
43
44template <typename T, std::size_t N> struct Storage {
45 T m_data[N];
46
47private:
48 friend boost::serialization::access;
49 template <typename Archive>
50 void serialize(Archive &ar, const unsigned int /* version */) {
51 ar & m_data;
52 }
53};
54
55template <typename T> struct Storage<T, 0> {};
56
57struct ArrayFormatterStream {
58 std::ostream &stream;
59 char const *separator;
60 ArrayFormatterStream(std::ostream &s, char const *sep)
61 : stream(s), separator(sep) {}
62};
63
64struct ArrayFormatter {
65 char const *separator;
66 friend ArrayFormatterStream operator<<(std::ostream &os,
67 ArrayFormatter const &fmt) {
68 return {os, fmt.separator};
69 }
70};
71
72/**
73 * @brief Alias to create prvalue C-style arrays.
74 *
75 * This type is necessary when converting arrays from one type to another type
76 * within functions marked as @c noexcept. The @c std::initializer_list<T>
77 * type doesn't include the backing array length as part of the type,
78 * and is therefore not strictly equivalent.
79 */
80template <typename T, std::size_t N> using carray_alias = T const[N];
81
82} // namespace detail
83
84template <typename T, std::size_t N> struct Array {
85 using value_type = T;
86 using size_type = std::size_t;
87 using difference_type = std::ptrdiff_t;
89 using const_reference = const value_type &;
91 using const_iterator = const value_type *;
93 using const_pointer = const value_type *;
94
95 detail::Storage<T, N> m_storage;
96
98 if (i >= N) {
99 DEVICE_THROW(std::out_of_range("Array access out of bounds."));
100 }
101 return m_storage.m_data[i];
102 }
103
105 if (i >= N) {
106 DEVICE_THROW(std::out_of_range("Array access out of bounds."));
107 }
108 return m_storage.m_data[i];
109 }
110
112 DEVICE_ASSERT(i < N);
113 return m_storage.m_data[i];
114 }
115
117 operator[](size_type i) const noexcept {
118 DEVICE_ASSERT(i < N);
119 return m_storage.m_data[i];
120 }
121
122 DEVICE_QUALIFIER constexpr reference front() { return *begin(); }
123
124 DEVICE_QUALIFIER constexpr const_reference front() const { return *cbegin(); }
125
126 DEVICE_QUALIFIER constexpr reference back() { return *(end() - 1); }
127
129 return *(cend() - 1);
130 }
131
132 DEVICE_QUALIFIER constexpr pointer data() noexcept {
133 return &m_storage.m_data[0];
134 }
135
136 DEVICE_QUALIFIER constexpr const_pointer data() const noexcept {
137 return &m_storage.m_data[0];
138 }
139
140 DEVICE_QUALIFIER constexpr iterator begin() noexcept {
141 return &m_storage.m_data[0];
142 }
143
144 DEVICE_QUALIFIER constexpr const_iterator begin() const noexcept {
145 return &m_storage.m_data[0];
146 }
147
148 DEVICE_QUALIFIER constexpr const_iterator cbegin() const noexcept {
149 return &m_storage.m_data[0];
150 }
151
152 DEVICE_QUALIFIER constexpr iterator end() noexcept {
153 return &m_storage.m_data[N];
154 }
155
156 DEVICE_QUALIFIER constexpr const_iterator end() const noexcept {
157 return &m_storage.m_data[N];
158 }
159
160 DEVICE_QUALIFIER constexpr const_iterator cend() const noexcept {
161 return &m_storage.m_data[N];
162 }
163
164 DEVICE_QUALIFIER constexpr bool empty() const noexcept { return size() == 0; }
165
166 DEVICE_QUALIFIER constexpr size_type size() const noexcept { return N; }
167
168 DEVICE_QUALIFIER constexpr size_type max_size() const noexcept { return N; }
169
170 DEVICE_QUALIFIER void fill(const value_type &value) {
171 for (size_type i = 0; i != size(); ++i) {
172 m_storage.m_data[i] = value;
173 }
174 }
175
176 DEVICE_QUALIFIER static constexpr Array<T, N>
177 broadcast(const value_type &value) {
178 Array<T, N> ret{};
179 for (size_type i = 0; i != N; ++i) {
180 ret[i] = value;
181 }
182 return ret;
183 }
184
185 static constexpr detail::ArrayFormatter formatter(char const *sep = " ") {
186 return {sep};
187 }
188
189private:
190 friend boost::serialization::access;
191 template <typename Archive>
192 void serialize(Archive &ar, const unsigned int /* version */) {
193 ar & m_storage;
194 }
195
196 static std::ostream &format(std::ostream &out, Array const &a,
197 char const *const sep) {
198 if (not a.empty())
199 out << a[0];
200
201 for (auto it = std::next(a.begin()); it != a.end(); ++it)
202 out << sep << *it;
203
204 return out;
205 }
206
207 friend std::ostream &operator<<(std::ostream &out, Array const &a) {
208 return format(out, a, ", ");
209 }
210
211 friend std::ostream &operator<<(detail::ArrayFormatterStream const &fmt,
212 Array const &a) {
213 return format(fmt.stream, a, fmt.separator);
214 }
215};
216
217template <std::size_t I, class T, std::size_t N>
218typename std::tuple_element<I, Array<T, N>>::type &
219get(Array<T, N> &a) noexcept {
220 return a[I];
221}
222
223template <std::size_t I, class T, std::size_t N>
224const typename std::tuple_element<I, Array<T, N>>::type &
225get(Array<T, N> const &a) noexcept {
226 return a[I];
227}
228
229} // namespace Utils
230
231template <std::size_t I, class T, std::size_t N>
232struct std::tuple_element<I, Utils::Array<T, N>> {
233 static_assert(I < N, "Utils::Array index must be in range");
234 using type = typename std::enable_if_t<(I < N), T>;
235};
236
237template <class T, std::size_t N>
238struct std::tuple_size<Utils::Array<T, N>>
239 : std::integral_constant<std::size_t, N> {};
240
241UTILS_ARRAY_BOOST_MPI_T(Utils::detail::Storage, N)
242UTILS_ARRAY_BOOST_BIT_S(Utils::detail::Storage, N)
243UTILS_ARRAY_BOOST_CLASS(Utils::detail::Storage, N, object_serializable)
244UTILS_ARRAY_BOOST_TRACK(Utils::detail::Storage, N, track_never)
247UTILS_ARRAY_BOOST_CLASS(Utils::Array, N, object_serializable)
#define UTILS_ARRAY_BOOST_MPI_T(Container, N)
Mark array types as MPI data types.
Definition array.hpp:50
#define UTILS_ARRAY_BOOST_BIT_S(Container, N)
Mark array types as MPI bitwise serializable.
Definition array.hpp:63
#define UTILS_ARRAY_BOOST_CLASS(Container, N, ImplementationLevel)
Redefinition of BOOST_CLASS_IMPLEMENTATION for array types.
Definition array.hpp:78
#define UTILS_ARRAY_BOOST_TRACK(Container, N, TrackingLevel)
Redefinition of BOOST_CLASS_TRACKING for array types.
Definition array.hpp:97
cudaStream_t stream[1]
CUDA streams for parallel computing on CPU and GPU.
#define DEVICE_ASSERT(A)
#define DEVICE_QUALIFIER
#define DEVICE_THROW(E)
std::tuple_element< I, Array< T, N > >::type & get(Array< T, N > &a) noexcept
Definition Array.hpp:219
void serialize(Archive &ar, std::tuple< T... > &pack, unsigned int const)
Serialize std::tuple.
DEVICE_QUALIFIER constexpr const_reference operator[](size_type i) const noexcept
Definition Array.hpp:117
DEVICE_QUALIFIER constexpr reference at(size_type i)
Definition Array.hpp:97
value_type * iterator
Definition Array.hpp:90
static constexpr detail::ArrayFormatter formatter(char const *sep=" ")
Definition Array.hpp:185
DEVICE_QUALIFIER constexpr bool empty() const noexcept
Definition Array.hpp:164
DEVICE_QUALIFIER constexpr reference back()
Definition Array.hpp:126
value_type * pointer
Definition Array.hpp:92
DEVICE_QUALIFIER constexpr pointer data() noexcept
Definition Array.hpp:132
DEVICE_QUALIFIER constexpr const_reference front() const
Definition Array.hpp:124
DEVICE_QUALIFIER constexpr const_reference at(size_type i) const
Definition Array.hpp:104
DEVICE_QUALIFIER constexpr size_type max_size() const noexcept
Definition Array.hpp:168
DEVICE_QUALIFIER constexpr iterator begin() noexcept
Definition Array.hpp:140
DEVICE_QUALIFIER constexpr const_pointer data() const noexcept
Definition Array.hpp:136
DEVICE_QUALIFIER constexpr const_iterator cbegin() const noexcept
Definition Array.hpp:148
const value_type & const_reference
Definition Array.hpp:89
detail::Storage< T, N > m_storage
Definition Array.hpp:95
DEVICE_QUALIFIER constexpr reference operator[](size_type i) noexcept
Definition Array.hpp:111
friend std::ostream & operator<<(std::ostream &out, Array const &a)
Definition Array.hpp:207
DEVICE_QUALIFIER constexpr const_iterator cend() const noexcept
Definition Array.hpp:160
static DEVICE_QUALIFIER constexpr Array< T, N > broadcast(const value_type &value)
Definition Array.hpp:177
DEVICE_QUALIFIER constexpr size_type size() const noexcept
Definition Array.hpp:166
DEVICE_QUALIFIER constexpr reference front()
Definition Array.hpp:122
const value_type * const_pointer
Definition Array.hpp:93
DEVICE_QUALIFIER constexpr const_reference back() const
Definition Array.hpp:128
friend std::ostream & operator<<(detail::ArrayFormatterStream const &fmt, Array const &a)
Definition Array.hpp:211
DEVICE_QUALIFIER constexpr iterator end() noexcept
Definition Array.hpp:152
DEVICE_QUALIFIER void fill(const value_type &value)
Definition Array.hpp:170
const value_type * const_iterator
Definition Array.hpp:91
DEVICE_QUALIFIER constexpr const_iterator begin() const noexcept
Definition Array.hpp:144
std::size_t size_type
Definition Array.hpp:86
DEVICE_QUALIFIER constexpr const_iterator end() const noexcept
Definition Array.hpp:156
value_type & reference
Definition Array.hpp:88
std::ptrdiff_t difference_type
Definition Array.hpp:87
typename std::enable_if_t<(I< N), T > type
Definition Array.hpp:234