ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
Loading...
Searching...
No Matches
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#ifndef SRC_UTILS_INCLUDE_UTILS_ARRAY_HPP
20#define SRC_UTILS_INCLUDE_UTILS_ARRAY_HPP
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
40namespace Utils {
41namespace detail {
42
43template <typename T, std::size_t N> struct Storage {
44 T m_data[N];
45
46private:
47 friend boost::serialization::access;
48 template <typename Archive>
49 void serialize(Archive &ar, const unsigned int /* version */) {
50 ar & m_data;
51 }
52};
53
54template <typename T> struct Storage<T, 0> {};
55
56struct ArrayFormatterStream {
57 std::ostream &stream;
58 char const *separator;
59 ArrayFormatterStream(std::ostream &s, char const *sep)
60 : stream(s), separator(sep) {}
61};
62
63struct ArrayFormatter {
64 char const *separator;
65 friend ArrayFormatterStream operator<<(std::ostream &os,
66 ArrayFormatter const &fmt) {
67 return {os, fmt.separator};
68 }
69};
70
71} // namespace detail
72
73template <typename T, std::size_t N> struct Array {
74 using value_type = T;
75 using size_type = std::size_t;
76 using difference_type = std::ptrdiff_t;
78 using const_reference = const value_type &;
80 using const_iterator = const value_type *;
82 using const_pointer = const value_type *;
83
84 detail::Storage<T, N> m_storage;
85
87 if (i >= N) {
88 DEVICE_THROW(std::out_of_range("Array access out of bounds."));
89 }
90 return m_storage.m_data[i];
91 }
92
94 if (i >= N) {
95 DEVICE_THROW(std::out_of_range("Array access out of bounds."));
96 }
97 return m_storage.m_data[i];
98 }
99
101 DEVICE_ASSERT(i < N);
102 return m_storage.m_data[i];
103 }
104
106 DEVICE_ASSERT(i < N);
107 return m_storage.m_data[i];
108 }
109
110 DEVICE_QUALIFIER constexpr reference front() { return *begin(); }
111
112 DEVICE_QUALIFIER constexpr const_reference front() const { return *cbegin(); }
113
114 DEVICE_QUALIFIER constexpr reference back() { return *(end() - 1); }
115
117 return *(cend() - 1);
118 }
119
120 DEVICE_QUALIFIER constexpr pointer data() noexcept {
121 return &m_storage.m_data[0];
122 }
123
124 DEVICE_QUALIFIER constexpr const_pointer data() const noexcept {
125 return &m_storage.m_data[0];
126 }
127
128 DEVICE_QUALIFIER constexpr iterator begin() noexcept {
129 return &m_storage.m_data[0];
130 }
131
132 DEVICE_QUALIFIER constexpr const_iterator begin() const noexcept {
133 return &m_storage.m_data[0];
134 }
135
136 DEVICE_QUALIFIER constexpr const_iterator cbegin() const noexcept {
137 return &m_storage.m_data[0];
138 }
139
140 DEVICE_QUALIFIER constexpr iterator end() noexcept {
141 return &m_storage.m_data[N];
142 }
143
144 DEVICE_QUALIFIER constexpr const_iterator end() const noexcept {
145 return &m_storage.m_data[N];
146 }
147
148 DEVICE_QUALIFIER constexpr const_iterator cend() const noexcept {
149 return &m_storage.m_data[N];
150 }
151
152 DEVICE_QUALIFIER constexpr bool empty() const noexcept { return size() == 0; }
153
154 DEVICE_QUALIFIER constexpr size_type size() const noexcept { return N; }
155
156 DEVICE_QUALIFIER constexpr size_type max_size() const noexcept { return N; }
157
158 DEVICE_QUALIFIER void fill(const value_type &value) {
159 for (size_type i = 0; i != size(); ++i) {
160 m_storage.m_data[i] = value;
161 }
162 }
163
164 DEVICE_QUALIFIER static constexpr Array<T, N>
165 broadcast(const value_type &value) {
166 Array<T, N> ret{};
167 for (size_type i = 0; i != N; ++i) {
168 ret[i] = value;
169 }
170 return ret;
171 }
172
173 static constexpr detail::ArrayFormatter formatter(char const *sep = " ") {
174 return {sep};
175 }
176
177private:
178 friend boost::serialization::access;
179 template <typename Archive>
180 void serialize(Archive &ar, const unsigned int /* version */) {
181 ar & m_storage;
182 }
183
184 static std::ostream &format(std::ostream &out, Array const &a,
185 char const *const sep) {
186 if (not a.empty())
187 out << a[0];
188
189 for (auto it = std::next(a.begin()); it != a.end(); ++it)
190 out << sep << *it;
191
192 return out;
193 }
194
195 friend std::ostream &operator<<(std::ostream &out, Array const &a) {
196 return format(out, a, ", ");
197 }
198
199 friend std::ostream &operator<<(detail::ArrayFormatterStream const &fmt,
200 Array const &a) {
201 return format(fmt.stream, a, fmt.separator);
202 }
203};
204
205template <std::size_t I, class T, std::size_t N>
206struct tuple_element<I, Array<T, N>> {
207 using type = T;
208};
209
210template <class T, std::size_t N>
211struct tuple_size<Array<T, N>> : std::integral_constant<std::size_t, N> {};
212
213template <std::size_t I, class T, std::size_t N>
214auto get(Array<T, N> const &a) -> std::enable_if_t<(I < N), const T &> {
215 return a[I];
216}
217
218} // namespace Utils
219
220UTILS_ARRAY_BOOST_MPI_T(Utils::detail::Storage, N)
221UTILS_ARRAY_BOOST_BIT_S(Utils::detail::Storage, N)
222UTILS_ARRAY_BOOST_CLASS(Utils::detail::Storage, N, object_serializable)
223UTILS_ARRAY_BOOST_TRACK(Utils::detail::Storage, N, track_never)
226UTILS_ARRAY_BOOST_CLASS(Utils::Array, N, object_serializable)
228
229#endif
#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)
auto get(Array< T, N > const &a) -> std::enable_if_t<(I< N), const T & >
Definition Array.hpp:214
void serialize(Archive &ar, std::tuple< T... > &pack, unsigned int const)
Serialize std::tuple.
DEVICE_QUALIFIER constexpr reference at(size_type i)
Definition Array.hpp:86
value_type * iterator
Definition Array.hpp:79
static constexpr detail::ArrayFormatter formatter(char const *sep=" ")
Definition Array.hpp:173
DEVICE_QUALIFIER constexpr bool empty() const noexcept
Definition Array.hpp:152
DEVICE_QUALIFIER constexpr reference back()
Definition Array.hpp:114
value_type * pointer
Definition Array.hpp:81
DEVICE_QUALIFIER constexpr pointer data() noexcept
Definition Array.hpp:120
DEVICE_QUALIFIER constexpr const_reference front() const
Definition Array.hpp:112
DEVICE_QUALIFIER constexpr const_reference at(size_type i) const
Definition Array.hpp:93
DEVICE_QUALIFIER constexpr size_type max_size() const noexcept
Definition Array.hpp:156
DEVICE_QUALIFIER constexpr iterator begin() noexcept
Definition Array.hpp:128
DEVICE_QUALIFIER constexpr const_pointer data() const noexcept
Definition Array.hpp:124
DEVICE_QUALIFIER constexpr const_iterator cbegin() const noexcept
Definition Array.hpp:136
const value_type & const_reference
Definition Array.hpp:78
detail::Storage< T, N > m_storage
Definition Array.hpp:84
friend std::ostream & operator<<(std::ostream &out, Array const &a)
Definition Array.hpp:195
DEVICE_QUALIFIER constexpr const_iterator cend() const noexcept
Definition Array.hpp:148
static DEVICE_QUALIFIER constexpr Array< T, N > broadcast(const value_type &value)
Definition Array.hpp:165
DEVICE_QUALIFIER constexpr size_type size() const noexcept
Definition Array.hpp:154
DEVICE_QUALIFIER constexpr reference front()
Definition Array.hpp:110
const value_type * const_pointer
Definition Array.hpp:82
DEVICE_QUALIFIER constexpr const_reference back() const
Definition Array.hpp:116
DEVICE_QUALIFIER constexpr reference operator[](size_type i)
Definition Array.hpp:100
friend std::ostream & operator<<(detail::ArrayFormatterStream const &fmt, Array const &a)
Definition Array.hpp:199
DEVICE_QUALIFIER constexpr iterator end() noexcept
Definition Array.hpp:140
DEVICE_QUALIFIER void fill(const value_type &value)
Definition Array.hpp:158
const value_type * const_iterator
Definition Array.hpp:80
DEVICE_QUALIFIER constexpr const_iterator begin() const noexcept
Definition Array.hpp:132
DEVICE_QUALIFIER constexpr const_reference operator[](size_type i) const
Definition Array.hpp:105
std::size_t size_type
Definition Array.hpp:75
DEVICE_QUALIFIER constexpr const_iterator end() const noexcept
Definition Array.hpp:144
value_type & reference
Definition Array.hpp:77
std::ptrdiff_t difference_type
Definition Array.hpp:76