7#include <dr/detail/mdspan_shim.hpp>
8#include <dr/detail/ranges_shim.hpp>
9#include <dr/mp/views/mdspan_view.hpp>
11namespace dr::mp::__detail {
16template <
typename BaseSegment, std::size_t Rank,
17 typename Layout = md::layout_stride>
21 using index_type = dr::__detail::dr_extents<Rank>;
24 mdsub_segment(BaseSegment segment,
const index_type &slice_starts,
25 const index_type &slice_ends)
26 : BaseSegment(segment),
27 mdspan_(local_tile(segment, slice_starts, slice_ends)),
28 root_mdspan_(segment.mdspan()) {}
30 auto mdspan()
const {
return mdspan_; }
31 auto root_mdspan()
const {
return root_mdspan_; }
34 using T = rng::range_value_t<BaseSegment>;
36 static auto local_tile(BaseSegment segment,
const index_type &slice_starts,
37 const index_type &slice_ends) {
38 index_type starts, ends;
39 index_type base_starts = segment.origin();
40 auto base_mdspan = segment.mdspan();
42 for (std::size_t i = 0; i < Rank; i++) {
45 auto base_end = base_starts[i] + base_mdspan.extent(i);
47 std::min(base_end, std::max(slice_starts[i], base_starts[i])) -
49 ends[i] = std::max(base_starts[i], std::min(slice_ends[i], base_end)) -
53 return dr::__detail::make_submdspan(base_mdspan, starts, ends);
56 md::mdspan<T, dr::__detail::md_extents<Rank>, md::layout_stride> mdspan_;
57 md::mdspan<T, dr::__detail::md_extents<Rank>, md::layout_stride> root_mdspan_;
67template <is_mdspan_view Base>
70 static auto make_segments(
auto base,
auto slice_starts,
auto slice_ends) {
71 auto make_md = [=](
auto segment) {
74 return dr::ranges::segments(base) | rng::views::transform(make_md);
77 using iterator_type = rng::iterator_t<Base>;
78 using extents_type = dr::__detail::dr_extents<Base::rank()>;
79 using difference_type = rng::iter_difference_t<iterator_type>;
81 decltype(make_segments(std::declval<Base>(), std::declval<extents_type>(),
82 std::declval<extents_type>()));
85 extents_type slice_starts_;
86 extents_type slice_ends_;
87 segments_type segments_;
91 extents_type slice_ends)
92 : base_(base), slice_starts_(std::forward<extents_type>(slice_starts)),
93 slice_ends_(std::forward<extents_type>(slice_ends)) {
94 segments_ = make_segments(base_, slice_starts_, slice_ends_);
98 auto begin()
const {
return base_.begin(); }
99 auto end()
const {
return base_.end(); }
100 auto operator[](difference_type n) {
return base_[n]; }
102 auto mdspan()
const {
103 return dr::__detail::make_submdspan(base_.mdspan(), slice_starts_,
107 auto segments()
const {
return segments_; }
111 using grid_iterator_type = rng::iterator_t<segments_type>;
113 md::mdspan<grid_iterator_type, dr::__detail::md_extents<Base::rank()>,
116 return grid_type(rng::begin(segments_), base_.grid().extents());
120template <
typename R,
typename Extents>
126namespace dr::mp::views {
131 : slice_starts_(slice_starts), slice_ends_(slice_ends) {}
133 template <rng::viewable_range R>
auto operator()(R &&r)
const {
134 return submdspan_view(std::forward<R>(r), slice_starts_, slice_ends_);
137 template <rng::viewable_range R>
139 return closure(std::forward<R>(r));
143 Extents slice_starts_;
149 template <is_mdspan_view R,
typename Extents>
150 auto operator()(R r, Extents &&slice_starts, Extents &&slice_ends)
const {
152 std::forward<Extents>(slice_ends))(
156 template <
typename Extents>
157 auto operator()(Extents &&slice_starts, Extents &&slice_ends)
const {
159 std::forward<Extents>(slice_ends));
Definition: mdspan_utils.hpp:60
Definition: submdspan_view.hpp:18
Definition: submdspan_view.hpp:128
Definition: submdspan_view.hpp:147
Definition: mdspan_view.hpp:206
Definition: submdspan_view.hpp:68