iterative-solver 0.0
Distribution.h
1#ifndef LINEARALGEBRA_SRC_MOLPRO_LINALG_ARRAY_UTIL_DISTRIBUTION_H
2#define LINEARALGEBRA_SRC_MOLPRO_LINALG_ARRAY_UTIL_DISTRIBUTION_H
3#include <algorithm>
4#include <cassert>
5#include <numeric>
6#include <utility>
7#include <vector>
8
10
15template <typename Ind = size_t>
17public:
18 using index_type = Ind;
19
20 Distribution() = default;
21 Distribution(const Distribution<Ind> &) = default;
22 Distribution(Distribution<Ind> &&) noexcept = default;
23 Distribution<Ind> &operator=(const Distribution<Ind> &) = default;
24 Distribution<Ind> &operator=(Distribution<Ind> &&) noexcept = default;
25 ~Distribution() = default;
26
28 using std::swap;
29 swap(l.m_chunk_borders, r.m_chunk_borders);
30 }
31
36 Distribution(const std::vector<index_type> &indices) : m_chunk_borders{indices} {
37 assert("indices must be sorted" && std::is_sorted(begin(m_chunk_borders), end(m_chunk_borders)));
38 };
39
46 std::pair<int, int> cover(index_type lo, index_type hi) const {
47 assert(lo < hi);
48 return {cover(lo), cover(hi - 1)};
49 };
50
55 int cover(index_type ind) const {
56 if (m_chunk_borders.empty() || ind < border().first || ind >= border().second)
57 return size();
58 auto iter = std::upper_bound(begin(m_chunk_borders), end(m_chunk_borders), ind);
59 int chunk = iter == begin(m_chunk_borders) ? size() : distance(begin(m_chunk_borders), prev(iter));
60 return chunk;
61 };
62
64 std::pair<index_type, index_type> range(int chunk) const {
65 assert(chunk >= 0 && static_cast<size_t>(chunk) < size() && "chunk index out of range");
66 return {m_chunk_borders[chunk], m_chunk_borders[chunk + 1]};
67 };
68
70 std::pair<index_type, index_type> border() const {
71 assert(!m_chunk_borders.empty() && "border() called on default-constructed Distribution");
72 return {m_chunk_borders.front(), m_chunk_borders.back()};
73 }
74
76 size_t size() const { return m_chunk_borders.size() ? m_chunk_borders.size() - 1 : 0; };
77
78 const std::vector<index_type> &chunk_borders() const { return m_chunk_borders; }
79
81 bool compatible(const Distribution<Ind> &other) const {
82 return size() == other.size() &&
83 std::inner_product(begin(m_chunk_borders), end(m_chunk_borders), begin(other.m_chunk_borders), true,
84 std::logical_and<>(), std::equal_to<>());
85 }
86
87protected:
92 std::vector<index_type> m_chunk_borders;
93};
94
102template <typename Ind>
104 assert(n_chunks > 0);
105 auto chunk_borders = std::vector<Ind>{0};
106 chunk_borders.reserve(n_chunks + 1);
107 auto block = dimension / n_chunks;
108 auto n_extra = dimension % n_chunks;
109 std::fill_n(std::back_inserter(chunk_borders), n_extra, block + 1);
110 std::fill_n(std::back_inserter(chunk_borders), n_chunks - n_extra, block);
111 std::partial_sum(begin(chunk_borders), end(chunk_borders), begin(chunk_borders));
112 return {chunk_borders};
113}
114
115} // namespace molpro::linalg::array::util
116
117#endif // LINEARALGEBRA_SRC_MOLPRO_LINALG_ARRAY_UTIL_DISTRIBUTION_H
Specifies distribution of a contiguous array into non-overlapping chunks.
Definition: Distribution.h:16
const std::vector< index_type > & chunk_borders() const
Definition: Distribution.h:78
friend void swap(Distribution< index_type > &l, Distribution< index_type > &r)
Definition: Distribution.h:27
std::pair< index_type, index_type > border() const
Definition: Distribution.h:70
std::pair< int, int > cover(index_type lo, index_type hi) const
Maps first and last index in the array to a pair of chunks encapsulating the corresponding range.
Definition: Distribution.h:46
size_t size() const
Number of chunks in the distribution.
Definition: Distribution.h:76
bool compatible(const Distribution< Ind > &other) const
Checks that other distribution is the same.
Definition: Distribution.h:81
Ind index_type
Definition: Distribution.h:18
Distribution(Distribution< Ind > &&) noexcept=default
Distribution(const Distribution< Ind > &)=default
Distribution(const std::vector< index_type > &indices)
Construct a contiguous distribution list using vector of start indices.
Definition: Distribution.h:36
int cover(index_type ind) const
Definition: Distribution.h:55
std::pair< index_type, index_type > range(int chunk) const
Returns [fist, end) indices for section of array assigned to chunk.
Definition: Distribution.h:64
std::vector< index_type > m_chunk_borders
list of starting indices for each chunk with past the end index as last element. e....
Definition: Distribution.h:92
auto begin(Span< T > &x)
Definition: Span.h:87
auto end(Span< T > &x)
Definition: Span.h:97
Definition: ArrayHandler.h:23
Distribution< Ind > make_distribution_spread_remainder(size_t dimension, int n_chunks)
Creates a distribution with first (dimension % n_chunks) chunks larger by 1 element.
Definition: Distribution.h:103