Distributed Ranges
Loading...
Searching...
No Matches
segmented.hpp
1// SPDX-FileCopyrightText: Intel Corporation
2//
3// SPDX-License-Identifier: BSD-3-Clause
4
5#pragma once
6
7#include <dr/detail/remote_subrange.hpp>
8
9namespace dr::mp {
10
11template <typename BaseIter, typename SegTplIter, typename SegTplSentinel>
13public:
14 using iterator_category = std::forward_iterator_tag;
15 using difference_type = rng::iter_difference_t<SegTplIter>;
17
19 segmented_view_iterator(BaseIter base_begin, SegTplIter tpl_begin,
20 SegTplSentinel tpl_end)
21 : base_cur_(base_begin), tpl_cur_(tpl_begin), tpl_end_(tpl_end) {}
22
23 auto operator==(segmented_view_iterator other) const {
24 return tpl_cur_ == other.tpl_cur_;
25 }
26 auto &operator++() {
27 base_cur_ += rng::size(*tpl_cur_);
28 tpl_cur_++;
29 return *this;
30 }
31 auto operator++(int) {
32 auto iter(*this);
33 base_cur_ += rng::size(*tpl_cur_);
34 tpl_cur_++;
35 return iter;
36 }
37 auto operator*() const {
38 return dr::remote_subrange(base_cur_, base_cur_ + rng::size(*tpl_cur_),
39 dr::ranges::rank(*tpl_cur_));
40 }
41
42private:
43 BaseIter base_cur_;
44 SegTplIter tpl_cur_;
45 SegTplSentinel tpl_end_;
46};
47
48//
49// Some distributed algorithms need an iota_view as an operand. An
50// iota_view does not depend on external data and can be segmented as
51// needed. The segmented_view creates segments for a range using the
52// segments of another range. It can be used to create segments for an
53// iota_view, using the segments of a distributed_range.
54//
55// It should be usable if you have a range that is local and
56// replicated across all processes, but that is not tested.
57//
58template <rng::random_access_range R, rng::common_range SegTpl>
59class segmented_view : public rng::view_interface<segmented_view<R, SegTpl>> {
60public:
61 template <typename V1, typename V2>
62 segmented_view(V1 &&r, V2 &&tpl)
63 : base_(rng::views::all(std::forward<V1>(r))),
64 segments_tpl_(rng::views::all(std::forward<V2>(tpl))) {}
65
66 auto begin() const {
67 return segmented_view_iterator(rng::begin(base_), rng::begin(segments_tpl_),
68 rng::end(segments_tpl_));
69 }
70 auto end() const {
71 return segmented_view_iterator(rng::begin(base_), rng::end(segments_tpl_),
72 rng::end(segments_tpl_));
73 }
74
75 auto size() const { return rng::size(segments_tpl_); }
76
77private:
78 rng::views::all_t<R> base_;
79 rng::views::all_t<SegTpl> segments_tpl_;
80};
81
82template <typename R, typename Seg>
83segmented_view(R &&r, Seg &&seg)
84 -> segmented_view<rng::views::all_t<R>, rng::views::all_t<Seg>>;
85
86namespace views {
87
89template <typename R, typename Seg> auto segmented(R &&r, Seg &&seg) {
90 return segmented_view(std::forward<R>(r), std::forward<Seg>(seg));
91}
92
93} // namespace views
94
95} // namespace dr::mp
Definition: segmented.hpp:12
Definition: segmented.hpp:59
Definition: remote_subrange.hpp:15