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 (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 return {m_chunk_borders[chunk], m_chunk_borders[chunk + 1]};
66 };
67
69 std::pair<index_type, index_type> border() const { return {m_chunk_borders.front(), m_chunk_borders.back()}; }
70
72 size_t size() const { return m_chunk_borders.size() ? m_chunk_borders.size() - 1 : 0; };
73
74 const std::vector<index_type> &chunk_borders() const { return m_chunk_borders; }
75
77 bool compatible(const Distribution<Ind> &other) const {
78 return size() == other.size() &&
79 std::inner_product(begin(m_chunk_borders), end(m_chunk_borders), begin(other.m_chunk_borders), true,
80 std::logical_and<>(), std::equal_to<>());
81 }
82
83protected:
88 std::vector<index_type> m_chunk_borders;
89};
90
98template <typename Ind>
100 assert(n_chunks > 0);
101 auto chunk_borders = std::vector<Ind>{0};
102 chunk_borders.reserve(n_chunks + 1);
103 auto block = dimension / n_chunks;
104 auto n_extra = dimension % n_chunks;
105 std::fill_n(std::back_inserter(chunk_borders), n_extra, block + 1);
106 std::fill_n(std::back_inserter(chunk_borders), n_chunks - n_extra, block);
107 std::partial_sum(begin(chunk_borders), end(chunk_borders), begin(chunk_borders));
108 return {chunk_borders};
109}
110
111} // namespace molpro::linalg::array::util
112
113#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:74
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:69
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:72
bool compatible(const Distribution< Ind > &other) const
Checks that other distribution is the same.
Definition: Distribution.h:77
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:88
auto begin(Span< T > &x)
Definition: Span.h:84
auto end(Span< T > &x)
Definition: Span.h:94
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:99