Tatooine
chunked_multidim_array.h
Go to the documentation of this file.
1#ifndef TATOOINE_CHUNKED_MULTIDIM_ARRAY_H
2#define TATOOINE_CHUNKED_MULTIDIM_ARRAY_H
3//==============================================================================
5#include <tatooine/concepts.h>
8#include <tatooine/math.h>
10#include <tatooine/utility.h>
11
12#include <array>
13#include <boost/range/algorithm.hpp>
14#include <cassert>
15#include <cmath>
16#include <iostream>
17#include <memory>
18#include <numeric>
19#include <random>
20#include <utility>
21#include <vector>
22//==============================================================================
23namespace tatooine {
24//==============================================================================
25template <typename T, typename GlobalIndexOrder = x_fastest,
26 typename LocalIndexOrder = GlobalIndexOrder>
28 //============================================================================
29 using value_type = T;
33 using chunk_ptr_t = std::unique_ptr<chunk_t>;
34 using chunk_ptr_field_t = std::vector<chunk_ptr_t>;
35 using global_index_order_t = GlobalIndexOrder;
36 using local_index_order_t = LocalIndexOrder;
37 //----------------------------------------------------------------------------
43 //----------------------------------------------------------------------------
44 private:
45 std::vector<std::size_t> m_internal_chunk_size;
47
48 protected:
50 //============================================================================
51 public:
53 : parent_type{other},
56 m_chunks(other.m_chunks.size()) {
57 copy_chunks(other);
58 }
59 //----------------------------------------------------------------------------
60 template <range SizeRange, range ChunkSizeRange>
61 requires(is_integral<typename std::decay_t<SizeRange>::value_type>) &&
62 (is_integral<typename std::decay_t<ChunkSizeRange>::value_type>)
64 ChunkSizeRange&& chunk_size) {
65 resize(std::forward<SizeRange>(size),
66 std::forward<ChunkSizeRange>(chunk_size));
67 }
68 //----------------------------------------------------------------------------
69 template <range Range>
70 chunked_multidim_array(Range&& data, std::vector<std::size_t> const& size,
71 std::vector<std::size_t> const& chunk_size) {
73 std::size_t i = 0;
74 for (auto const& d : data) {
75 (*this)[i++] = d;
76 }
77 }
78 //----------------------------------------------------------------------------
79 template <can_read<this_type> Reader>
80 chunked_multidim_array(Reader&& reader,
81 std::vector<std::size_t> const& chunk_size) {
83 reader.read(*this);
84 }
85 //==============================================================================
86 template <range SizeRange>
87 auto resize(SizeRange&& size) -> void requires(
88 is_integral<typename std::decay_t<SizeRange>::value_type>) {
89 // apply full size
91
92 // transform to chunk size and apply
93 auto size_it = begin(size);
94 auto chunk_size_it = begin(m_internal_chunk_size);
95 for (; size_it < end(size); ++size_it, ++chunk_size_it) {
96 *size_it = static_cast<tatooine::value_type<std::decay_t<SizeRange>>>(gcem::ceil(
97 static_cast<double>(*size_it) / static_cast<double>(*chunk_size_it)));
98 }
99 m_chunk_structure.resize(size);
100 m_chunks.resize(m_chunk_structure.num_components());
101 }
102 //----------------------------------------------------------------------------
103 template <range SizeRange, range ChunkSizeRange>
104 auto resize(SizeRange&& size, ChunkSizeRange&& chunk_size)
107 m_internal_chunk_size.resize(chunk_size.size());
108 std::ranges::copy(chunk_size, begin(m_internal_chunk_size));
109 auto i = std::size_t{};
110 for (auto& s : m_internal_chunk_size) {
111 s = std::min(s, static_cast<std::size_t>(size[i++]));
112 }
113 resize(std::forward<SizeRange>(size));
114 }
115 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
116 auto resize(integral auto const... sizes) -> void {
117 return resize(std::vector{static_cast<std::size_t>(sizes)...});
118 }
119 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
120 template <typename Tensor, integral Int, std::size_t N>
121 auto resize(base_tensor<Tensor, Int, N> const& v) -> void {
122 assert(N == num_dimensions());
123 std::vector<std::size_t> s(num_dimensions());
124 for (std::size_t i = 0; i < N; ++i) {
125 s[i] = v(i);
126 }
127 return resize(s);
128 }
129 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
130 template <integral Int, std::size_t N>
131 auto resize(std::array<Int, N> const& v) {
132 assert(N == num_dimensions());
133 return resize(std::vector<std::size_t>(begin(v), end(v)));
134 }
135 //----------------------------------------------------------------------------
136 private:
137 template <std::size_t... Seq>
139 std::size_t plain_chunk_index, std::index_sequence<Seq...>,
140 integral auto const... is) const {
141 assert(m_chunks[plain_chunk_index] != nullptr);
142 assert(sizeof...(is) == m_chunks[plain_chunk_index]->num_dimensions());
143 return m_chunks[plain_chunk_index]->plain_index(
144 (static_cast<std::size_t>(is) % m_internal_chunk_size[Seq])...);
145 }
146 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
147 public:
149 std::size_t plain_chunk_index, integral auto const... is) const {
150 assert(m_chunks[plain_chunk_index] != nullptr);
151 assert(sizeof...(is) == m_chunks[plain_chunk_index]->num_dimensions());
153 plain_chunk_index, std::make_index_sequence<sizeof...(is)>{}, is...);
154 }
155 //----------------------------------------------------------------------------
156 private:
157 template <std::size_t... Seq>
159 std::index_sequence<Seq...> /*seq*/, integral auto const... is) const {
160 assert(sizeof...(is) == num_dimensions());
161 return m_chunk_structure.plain_index(
162 (static_cast<std::size_t>(is) / m_internal_chunk_size[Seq])...);
163 }
164 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
165 public:
166 auto plain_chunk_index_from_global_indices(integral auto const... is) const {
167 assert(sizeof...(is) == num_dimensions());
169 std::make_index_sequence<sizeof...(is)>{}, is...);
170 }
171 //----------------------------------------------------------------------------
172 private:
173 template <std::size_t... Seq>
175 std::index_sequence<Seq...>, integral auto const... is) const {
176 return std::array{static_cast<std::size_t>(is % m_internal_chunk_size[Seq])...};
177 }
178 //----------------------------------------------------------------------------
179 public:
181 integral auto const... is) const {
183 std::make_index_sequence<sizeof...(is)>{}, is...);
184 }
185 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
186 template <integral Int>
187 auto internal_chunk_indices_from_global_indices(std::vector<Int> is) const {
188 assert(is.size() == num_dimensions());
189 for (std::size_t i = 0; i < num_dimensions(); ++i) {
190 is[i] %= m_internal_chunk_size[i];
191 }
192 return is;
193 }
194 //----------------------------------------------------------------------------
195 private:
196 template <std::size_t... Seq>
197 auto chunk_indices_from_global_indices(std::index_sequence<Seq...>,
198 integral auto const... is) const {
199 return std::vector{
200 (static_cast<std::size_t>(is) / m_internal_chunk_size[Seq])...};
201 }
202 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
203 public:
204 auto chunk_indices_from_global_indices(integral auto const... is) const {
205 assert(sizeof...(is) == num_dimensions());
207 std::make_index_sequence<sizeof...(is)>{}, is...);
208 }
209 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
210 template <integral Int>
211 auto chunk_indices_from_global_indices(std::vector<Int> is) const {
212 assert(is.size() == num_dimensions());
213 for (std::size_t i = 0; i < num_dimensions(); ++i) {
214 is[i] /= m_internal_chunk_size[i];
215 }
216 return is;
217 }
218 //----------------------------------------------------------------------------
219 template <integral Int>
220 auto global_indices_from_chunk_indices(std::vector<Int> is) const {
221 assert(is.size() == num_dimensions());
222 for (std::size_t i = 0; i < num_dimensions(); ++i) {
223 is[i] *= m_internal_chunk_size[i];
224 }
225 return is;
226 }
227 //----------------------------------------------------------------------------
229 integral auto const... chunk_indices) const {
230 assert(sizeof...(chunk_indices) == num_dimensions());
231 return m_chunk_structure.plain_index(chunk_indices...);
232 }
233 //----------------------------------------------------------------------------
234 template <integral Int>
236 std::vector<Int> const& chunk_indices) const {
237 assert(chunk_indices.size() == num_dimensions());
238 return m_chunk_structure.plain_index(chunk_indices);
239 }
240 //----------------------------------------------------------------------------
241 auto chunk_at(integral auto const chunk_index0,
242 integral auto const... chunk_indices) const -> auto const& {
243 if constexpr (sizeof...(chunk_indices) == 0) {
244 return m_chunks[chunk_index0];
245 } else {
246 assert(sizeof...(chunk_indices) + 1 == num_dimensions());
248 chunk_indices...)];
249 }
250 }
251 //----------------------------------------------------------------------------
252 auto chunk_at_is_null(integral auto const chunk_index0,
253 integral auto const... chunk_indices) const {
254 if constexpr (sizeof...(chunk_indices) == 0) {
255 return m_chunks[chunk_index0] == nullptr;
256 } else {
257 assert(sizeof...(chunk_indices) + 1 == num_dimensions());
259 chunk_index0, chunk_indices...)] == nullptr;
260 }
261 }
262 //----------------------------------------------------------------------------
263 auto create_all_chunks() const -> void {
264 for (std::size_t i = 0; i < num_chunks(); ++i) {
266 }
267 }
268 //----------------------------------------------------------------------------
269 auto create_chunk_at(std::size_t const plain_chunk_index,
270 std::vector<std::size_t> const& multi_indices) const
271 -> auto const& {
272 assert(multi_indices.size() == num_dimensions());
273 std::vector<std::size_t> chunk_size = m_internal_chunk_size;
274 for (std::size_t i = 0; i < num_dimensions(); ++i) {
275 if (multi_indices[i] == m_chunk_structure.size(i) - 1) {
276 chunk_size[i] = this->size(i) % chunk_size[i];
277 if (chunk_size[i] == 0) {
279 }
280 }
281 }
282 m_chunks[plain_chunk_index] = std::make_unique<chunk_t>(chunk_size);
283 return m_chunks[plain_chunk_index];
284 }
285 //----------------------------------------------------------------------------
286 auto create_chunk_at(std::size_t const plain_chunk_index) const -> auto const& {
287 assert(plain_chunk_index < num_chunks());
288 return create_chunk_at(plain_chunk_index,
289 m_chunk_structure.multi_index(plain_chunk_index));
290 }
291 //----------------------------------------------------------------------------
292 auto create_chunk_at(integral auto const chunk_index0,
293 integral auto const chunk_index1,
294 integral auto const... chunk_indices) const
295 -> auto const& {
296 assert(sizeof...(chunk_indices) + 2 == num_dimensions());
297 return create_chunk_at(
298 plain_chunk_index_from_chunk_indices(chunk_index0, chunk_index1,
299 chunk_indices...),
300 std::vector<std::size_t>{chunk_index0, chunk_index1, chunk_indices...});
301 }
302 //----------------------------------------------------------------------------
303 auto destroy_chunk_at(integral auto const chunk_index0,
304 integral auto const... chunk_indices) const {
305 if constexpr (sizeof...(chunk_indices) == 0) {
306 m_chunks[chunk_index0].reset();
307 } else {
308 assert(sizeof...(chunk_indices) + 1 == num_dimensions());
309 m_chunks[plain_chunk_index_from_chunk_indices(chunk_indices...)].reset();
310 }
311 }
312 //----------------------------------------------------------------------------
313 auto copy_chunks(chunked_multidim_array const& other) -> void {
314 auto chunk_it = begin(m_chunks);
315 for (auto const& chunk : other.m_chunks) {
316 if (chunk) {
317 *(chunk_it++) = std::make_unique<chunk_t>(*chunk);
318 }
319 }
320 }
321 //----------------------------------------------------------------------------
322 auto clear() {
323 for (auto& chunk : m_chunks) {
324 if (chunk != nullptr) {
325 chunk.reset();
326 }
327 }
328 }
329 //----------------------------------------------------------------------------
330 auto num_chunks() const { return m_chunks.size(); }
331 //----------------------------------------------------------------------------
332 auto chunk_size() const { return m_chunk_structure.size(); }
333 auto chunk_size(std::size_t i) const { return m_chunk_structure.size(i); }
334 //----------------------------------------------------------------------------
336 auto internal_chunk_size(std::size_t const i) const {
337 return m_internal_chunk_size[i];
338 }
339 //----------------------------------------------------------------------------
340 auto operator[](std::size_t plain_index) -> T& {
341 assert(plain_index < num_components());
342 return at(multi_index(plain_index));
343 }
344 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
345 auto operator[](std::size_t plain_index) const -> T const& {
346 assert(plain_index < num_components());
347 return at(multi_index(plain_index));
348 }
349 //----------------------------------------------------------------------------
350 auto at(integral auto const... is) -> T& {
351 assert(sizeof...(is) == num_dimensions());
352 assert(in_range(is...));
353 std::size_t const plain_index = plain_chunk_index_from_global_indices(is...);
356 }
357 std::size_t const plain_internal_index =
359 return (*m_chunks[plain_index])[plain_internal_index];
360 }
361 //----------------------------------------------------------------------------
362 auto at(integral auto const... is) const -> T const& {
363 assert(sizeof...(is) == num_dimensions());
364 assert(in_range(is...));
365 std::size_t const plain_index = plain_chunk_index_from_global_indices(is...);
367 static constexpr T t{};
368 return t;
369 }
370 std::size_t const plain_internal_index =
372 return (*m_chunks[plain_index])[plain_internal_index];
373 }
374 //----------------------------------------------------------------------------
375 template <typename Tensor, std::size_t N, integral S>
376 auto at(base_tensor<Tensor, S, N> const& is) -> T& {
377 return invoke_unpacked(
378 [this](auto const... is) -> decltype(auto) { return at(is...); },
379 unpack(is));
380 }
381 //----------------------------------------------------------------------------
382 template <integral S, std::size_t N>
383 auto at(std::array<S, N> const& is) -> T& {
384 return invoke_unpacked(
385 [this](auto const... is) -> decltype(auto) { return at(is...); },
386 unpack(is));
387 }
388 //----------------------------------------------------------------------------
389 template <integral S>
390 auto at(std::vector<S> const& is) -> T& {
391 assert(num_dimensions() == is.size());
392 assert(in_range(is));
393 std::size_t const plain_chunk_index =
395 if (!m_chunks[plain_chunk_index]) {
396 create_chunk_at(plain_chunk_index);
397 }
398 return m_chunks[plain_chunk_index]->at(
400 }
401 //----------------------------------------------------------------------------
402 template <integral S>
403 auto at(std::vector<S> const& is) const -> T const& {
404 assert(num_dimensions() == is.size());
405 assert(in_range(is));
406 auto global_is = is;
407 for (std::size_t i = 0; i < num_dimensions(); ++i) {
408 global_is[i] /= is[i];
409 }
410 std::size_t const plain_chunk_index = m_chunk_structure.plain_index(global_is);
411 if (!m_chunks[plain_chunk_index]) {
412 static const T t{};
413 return t;
414 }
415 auto local_is = is;
416 for (std::size_t i = 0; i < num_dimensions(); ++i) {
417 local_is[i] %= is[i];
418 }
419 return m_chunks[plain_chunk_index]->at(local_is);
420 }
421 //----------------------------------------------------------------------------
422 auto operator()(integral auto const... is) -> T& {
423 assert(sizeof...(is) == num_dimensions());
424 return at(is...);
425 }
426 //----------------------------------------------------------------------------
427 auto operator()(integral auto const... is) const -> T const& {
428 assert(sizeof...(is) == num_dimensions());
429 return at(is...);
430 }
431 //----------------------------------------------------------------------------
432 template <typename Tensor, std::size_t N, integral S>
433 auto operator()(base_tensor<Tensor, S, N> const& is) -> T& {
434 return at(is);
435 }
436 //----------------------------------------------------------------------------
437 template <integral S, std::size_t N>
438 auto operator()(std::array<S, N> const& is) -> T& {
439 return at(is);
440 }
441 //----------------------------------------------------------------------------
442 template <integral S, std::size_t N>
443 auto operator()(std::array<S, N> const& is) const -> T const& {
444 return at(is);
445 }
446 //----------------------------------------------------------------------------
447 template <integral S, std::size_t N>
448 auto at(std::array<S, N> const& is) const -> T const& {
449 return invoke_unpacked(
450 [this](auto const... is) -> decltype(auto) { return at(is...); },
451 unpack(is));
452 }
454 // auto unchunk() const {
455 // std::vector<T> data(num_components());
456 // for (std::size_t i = 0; i < num_components(); ++i) { data[i] = (*this)[i]; }
457 // return data;
458 //}
460 //
461 // auto unchunk_plain() const requires is_arithmetic<T>{
462 // using real_type = typename T::real_type;
463 // constexpr auto n = T::num_components();
464 // std::vector<real_type> data;
465 // data.reserve(num_components() * n);
466 // for (std::size_t i = 0; i < num_components(); ++i) {
467 // for (std::size_t j = 0; j < n; ++j) { data.push_back((*this)[i][j]); }
468 // }
469 // return data;
470 //}
471 //----------------------------------------------------------------------------
472 template <typename RandomEngine = std::mt19937_64>
473 requires is_arithmetic<T> auto randu(
474 T min = 0, T max = 1,
475 RandomEngine&& random_engine = RandomEngine{std::random_device{}()})
476 -> void {
477 for (auto& chunk : m_chunks) {
478 if (!chunk) {
479 chunk = std::make_unique<chunk_t>();
480 }
481 chunk->randu(min, max, std::forward<RandomEngine>(random_engine));
482 }
483 }
484
485 auto min_value() const requires is_arithmetic<T> {
486 T min = std::numeric_limits<T>::max();
487 for (auto const& chunk : m_chunks) {
488 if (chunk) {
489 min = std::min(min, *chunk->min_element());
490 }
491 }
492 return min;
493 }
494
495 auto max_value() const requires is_arithmetic<T> {
496 T max = -std::numeric_limits<T>::max();
497 for (auto const& chunk : m_chunks) {
498 if (chunk) {
499 max = std::max(max, *chunk->max_element());
500 }
501 }
502 return max;
503 }
504
505 auto minmax_value() const requires is_arithmetic<T> {
506 std::pair minmax{std::numeric_limits<T>::max(),
507 -std::numeric_limits<T>::max()};
508 auto& [min, max] = minmax;
509 for (auto const& chunk : m_chunks) {
510 if (chunk) {
511 auto [chunkmin, chunkmax] = chunk->minmax_element();
512 if (!std::isinf(*chunkmin) && !std::isnan(*chunkmin)) {
513 min = std::min(min, *chunkmin);
514 }
515 if (!std::isinf(*chunkmax) && !std::isnan(*chunkmax)) {
516 max = std::max(max, *chunkmax);
517 }
518 }
519 }
520 return minmax;
521 }
522
523 auto normalize() -> void requires is_arithmetic<T> {
524 auto [min, max] = minmax_value();
525 auto normalizer = 1.0 / (max - min);
526
527 for (auto const& chunk : m_chunks) {
528 if (chunk) {
529 for (auto& val : *chunk) {
530 val = (val - min) * normalizer;
531 }
532 }
533 }
534 }
535 //----------------------------------------------------------------------------
538 template <typename Iteration>
539 auto iterate_over_indices(Iteration&& iteration) const {
540 auto outer_ranges =
541 std::vector<std::pair<std::size_t, std::size_t>>(num_dimensions());
542 auto inner_ranges =
543 std::vector<std::pair<std::size_t, std::size_t>>(num_dimensions());
544
545 for (std::size_t i = 0; i < num_dimensions(); ++i) {
546 outer_ranges[i] = {0, m_chunk_structure.size(i)};
547 }
548
549 // outer loop iterates over chunks
550 for_loop(
551 [&](std::vector<std::size_t> const& outer_indices) {
552 for (std::size_t i = 0; i < num_dimensions(); ++i) {
554 if (outer_indices[i] == m_chunk_structure.size(i) - 1) {
555 chunk_size = this->size(i) % chunk_size;
556 if (chunk_size == 0) {
558 }
559 }
560 inner_ranges[i] = {0, chunk_size};
561 }
562 // inner loop iterates indices of current chunk
563 for_loop(
564 [&](std::vector<std::size_t> const& inner_indices) {
565 auto global_indices =
566 std::vector<std::size_t>(num_dimensions());
567
568 for (std::size_t i = 0; i < num_dimensions(); ++i) {
569 global_indices[i] =
570 outer_indices[i] * m_internal_chunk_size[i] +
571 inner_indices[i];
572 }
573 iteration(global_indices);
574 },
575 inner_ranges);
576 },
577 outer_ranges);
578 }
579};
580//==============================================================================
581} // namespace tatooine
582//==============================================================================
583#endif
Definition: dynamic_multidim_array.h:18
Definition: dynamic_multidim_size.h:16
auto constexpr plain_index(integral auto const ... indices) const
Definition: dynamic_multidim_size.h:149
auto constexpr in_range(integral auto const ... indices) const
Definition: dynamic_multidim_size.h:130
auto constexpr multi_index(std::size_t const gi) const
Definition: dynamic_multidim_size.h:161
auto num_dimensions() const
Definition: dynamic_multidim_size.h:105
auto resize(integral auto const ... size) -> void
Definition: dynamic_multidim_size.h:116
auto num_components() const
Definition: dynamic_multidim_size.h:111
Definition: netcdf.h:348
Definition: concepts.h:21
Definition: algorithm.h:6
auto begin(Range &&range)
Definition: iterator_facade.h:318
typename value_type_impl< T >::type value_type
Definition: type_traits.h:280
auto end(Range &&range)
Definition: iterator_facade.h:322
static constexpr auto is_integral
Definition: type_traits.h:83
static constexpr auto is_arithmetic
Definition: type_traits.h:80
constexpr auto max(A &&a, B &&b)
Definition: math.h:20
constexpr auto min(A &&a, B &&b)
Definition: math.h:15
constexpr decltype(auto) invoke_unpacked(F &&f)
All arguments are bound -> just call f.
Definition: invoke_unpacked.h:15
constexpr auto for_loop(Iteration &&iteration, execution_policy::sequential_t, Ranges(&&... ranges)[2]) -> void
Use this function for creating a sequential nested loop.
Definition: for_loop.h:336
Definition: base_tensor.h:23
Definition: chunked_multidim_array.h:27
auto internal_chunk_indices_from_global_indices(integral auto const ... is) const
Definition: chunked_multidim_array.h:180
LocalIndexOrder local_index_order_t
Definition: chunked_multidim_array.h:36
auto resize(SizeRange &&size, ChunkSizeRange &&chunk_size)
Definition: chunked_multidim_array.h:104
auto global_indices_from_chunk_indices(std::vector< Int > is) const
Definition: chunked_multidim_array.h:220
auto internal_chunk_size() const
Definition: chunked_multidim_array.h:335
auto at(std::vector< S > const &is) const -> T const &
Definition: chunked_multidim_array.h:403
auto constexpr in_range(integral auto const ... indices) const
Definition: dynamic_multidim_size.h:130
auto internal_chunk_size(std::size_t const i) const
Definition: chunked_multidim_array.h:336
chunk_ptr_field_t m_chunks
Definition: chunked_multidim_array.h:49
chunked_multidim_array(Range &&data, std::vector< std::size_t > const &size, std::vector< std::size_t > const &chunk_size)
Definition: chunked_multidim_array.h:70
auto resize(base_tensor< Tensor, Int, N > const &v) -> void
Definition: chunked_multidim_array.h:121
auto plain_chunk_index_from_chunk_indices(integral auto const ... chunk_indices) const
Definition: chunked_multidim_array.h:228
auto resize(integral auto const ... sizes) -> void
Definition: chunked_multidim_array.h:116
auto chunk_indices_from_global_indices(std::index_sequence< Seq... >, integral auto const ... is) const
Definition: chunked_multidim_array.h:197
auto internal_chunk_indices_from_global_indices(std::index_sequence< Seq... >, integral auto const ... is) const
Definition: chunked_multidim_array.h:174
auto operator()(integral auto const ... is) const -> T const &
Definition: chunked_multidim_array.h:427
auto chunk_at(integral auto const chunk_index0, integral auto const ... chunk_indices) const -> auto const &
Definition: chunked_multidim_array.h:241
auto chunk_size() const
Definition: chunked_multidim_array.h:332
auto plain_chunk_index_from_chunk_indices(std::vector< Int > const &chunk_indices) const
Definition: chunked_multidim_array.h:235
auto at(std::array< S, N > const &is) -> T &
Definition: chunked_multidim_array.h:383
auto create_chunk_at(std::size_t const plain_chunk_index, std::vector< std::size_t > const &multi_indices) const -> auto const &
Definition: chunked_multidim_array.h:269
auto max_value() const
Definition: chunked_multidim_array.h:495
auto operator[](std::size_t plain_index) const -> T const &
Definition: chunked_multidim_array.h:345
auto create_all_chunks() const -> void
Definition: chunked_multidim_array.h:263
auto at(integral auto const ... is) -> T &
Definition: chunked_multidim_array.h:350
auto chunk_size(std::size_t i) const
Definition: chunked_multidim_array.h:333
auto plain_internal_chunk_index_from_global_indices(std::size_t plain_chunk_index, std::index_sequence< Seq... >, integral auto const ... is) const
Definition: chunked_multidim_array.h:138
auto randu(T min=0, T max=1, RandomEngine &&random_engine=RandomEngine{std::random_device{}()}) -> void
Definition: chunked_multidim_array.h:473
auto chunk_at_is_null(integral auto const chunk_index0, integral auto const ... chunk_indices) const
Definition: chunked_multidim_array.h:252
auto constexpr multi_index(std::size_t const gi) const
Definition: dynamic_multidim_size.h:161
auto create_chunk_at(integral auto const chunk_index0, integral auto const chunk_index1, integral auto const ... chunk_indices) const -> auto const &
Definition: chunked_multidim_array.h:292
std::vector< std::size_t > m_internal_chunk_size
Definition: chunked_multidim_array.h:45
auto min_value() const
Definition: chunked_multidim_array.h:485
auto plain_chunk_index_from_global_indices(integral auto const ... is) const
Definition: chunked_multidim_array.h:166
auto at(std::vector< S > const &is) -> T &
Definition: chunked_multidim_array.h:390
auto normalize() -> void
Definition: chunked_multidim_array.h:523
T value_type
Definition: chunked_multidim_array.h:29
auto size() const -> auto const &
Definition: dynamic_multidim_size.h:107
GlobalIndexOrder global_index_order_t
Definition: chunked_multidim_array.h:35
auto num_chunks() const
Definition: chunked_multidim_array.h:330
auto clear()
Definition: chunked_multidim_array.h:322
auto num_dimensions() const
Definition: dynamic_multidim_size.h:105
chunked_multidim_array(chunked_multidim_array const &other)
Definition: chunked_multidim_array.h:52
auto operator()(base_tensor< Tensor, S, N > const &is) -> T &
Definition: chunked_multidim_array.h:433
std::vector< chunk_ptr_t > chunk_ptr_field_t
Definition: chunked_multidim_array.h:34
dynamic_multidim_size< LocalIndexOrder > m_chunk_structure
Definition: chunked_multidim_array.h:46
auto copy_chunks(chunked_multidim_array const &other) -> void
Definition: chunked_multidim_array.h:313
auto operator()(std::array< S, N > const &is) -> T &
Definition: chunked_multidim_array.h:438
auto operator()(std::array< S, N > const &is) const -> T const &
Definition: chunked_multidim_array.h:443
auto internal_chunk_indices_from_global_indices(std::vector< Int > is) const
Definition: chunked_multidim_array.h:187
auto chunk_indices_from_global_indices(std::vector< Int > is) const
Definition: chunked_multidim_array.h:211
auto iterate_over_indices(Iteration &&iteration) const
Definition: chunked_multidim_array.h:539
auto operator[](std::size_t plain_index) -> T &
Definition: chunked_multidim_array.h:340
auto destroy_chunk_at(integral auto const chunk_index0, integral auto const ... chunk_indices) const
Definition: chunked_multidim_array.h:303
auto minmax_value() const
Definition: chunked_multidim_array.h:505
auto plain_internal_chunk_index_from_global_indices(std::size_t plain_chunk_index, integral auto const ... is) const
Definition: chunked_multidim_array.h:148
auto num_components() const
Definition: dynamic_multidim_size.h:111
auto resize(SizeRange &&size) -> void requires(is_integral< typename std::decay_t< SizeRange >::value_type >)
Definition: chunked_multidim_array.h:87
auto chunk_indices_from_global_indices(integral auto const ... is) const
Definition: chunked_multidim_array.h:204
chunked_multidim_array(SizeRange &&size, ChunkSizeRange &&chunk_size)
Definition: chunked_multidim_array.h:63
auto operator()(integral auto const ... is) -> T &
Definition: chunked_multidim_array.h:422
auto resize(std::array< Int, N > const &v)
Definition: chunked_multidim_array.h:131
auto plain_chunk_index_from_global_indices(std::index_sequence< Seq... >, integral auto const ... is) const
Definition: chunked_multidim_array.h:158
chunked_multidim_array(Reader &&reader, std::vector< std::size_t > const &chunk_size)
Definition: chunked_multidim_array.h:80
auto create_chunk_at(std::size_t const plain_chunk_index) const -> auto const &
Definition: chunked_multidim_array.h:286
std::unique_ptr< chunk_t > chunk_ptr_t
Definition: chunked_multidim_array.h:33
auto at(std::array< S, N > const &is) const -> T const &
Definition: chunked_multidim_array.h:448
auto at(integral auto const ... is) const -> T const &
Definition: chunked_multidim_array.h:362
auto at(base_tensor< Tensor, S, N > const &is) -> T &
Definition: chunked_multidim_array.h:376
Definition: invoke_unpacked.h:11