14 template <
typename T,
typename =
void>
15 struct needs_checkout :
public std::false_type {};
18 struct needs_checkout<T, std::enable_if_t<is_global_iterator_v<T>>>
19 :
public std::conditional_t<std::is_same_v<typename T::mode, checkout_mode::no_access_t>,
24 inline constexpr
bool needs_checkout_v = needs_checkout<T>::value;
26 inline auto checkout_global_iterators_aux(std::size_t) {
27 return std::make_tuple(std::make_tuple(), std::make_tuple());
30 template <
typename ForwardIterator,
typename... ForwardIterators>
31 inline auto checkout_global_iterators_aux(std::size_t n, ForwardIterator it, ForwardIterators... rest) {
33 if constexpr (needs_checkout_v<ForwardIterator>) {
34 auto&& [cs, it_] = it.checkout_nb(n);
35 auto&& [css, its] = checkout_global_iterators_aux(n, rest...);
37 std::tuple_cat(std::make_tuple(it_), its));
39 auto&& [css, its] = checkout_global_iterators_aux(n, rest...);
41 std::tuple_cat(std::make_tuple(it), its));
45 template <
typename... ForwardIterators>
46 inline auto checkout_global_iterators(std::size_t n, ForwardIterators... its) {
47 auto ret = checkout_global_iterators_aux(n, its...);
52 template <
typename Op,
typename... ForwardIterators>
53 inline void apply_iterators(Op op,
55 ForwardIterators... its) {
56 for (std::size_t i = 0; i < n; (++i, ..., ++its)) {
61 template <
typename Op,
typename ForwardIterator,
typename... ForwardIterators>
62 inline void for_each_aux(
const execution::sequenced_policy& policy,
64 ForwardIterator first,
66 ForwardIterators... firsts) {
67 if constexpr ((needs_checkout_v<ForwardIterator> || ... ||
68 needs_checkout_v<ForwardIterators>)) {
70 std::size_t n = std::distance(first, last);
71 std::size_t c = policy.checkout_count;
73 for (std::size_t d = 0; d < n; d += c) {
76 auto [css, its] = checkout_global_iterators(n_, first, firsts...);
77 std::apply([&](
auto&&...
args) {
78 apply_iterators(op, n_, std::forward<decltype(
args)>(
args)...);
81 ((first = std::next(first, n_)), ..., (firsts = std::next(firsts, n_)));
85 for (; first != last; (++first, ..., ++firsts)) {
86 op(*first, *firsts...);
91 template <
typename Iterator,
typename Mode>
92 inline auto convert_to_global_iterator(Iterator it, Mode
mode) {
93 if constexpr (is_global_iterator_v<Iterator>) {
94 static_assert(std::is_same_v<typename Iterator::mode, Mode> ||
95 std::is_same_v<typename Iterator::mode, checkout_mode::no_access_t>);
97 }
else if constexpr (ori::is_global_ptr_v<Iterator>) {
106 template <
typename B
idirectionalIterator1,
typename B
idirectionalIteratorD>
107 inline BidirectionalIteratorD
109 BidirectionalIterator1 first1,
110 BidirectionalIterator1 last1,
111 BidirectionalIteratorD first_d) {
112 if constexpr (ori::is_global_ptr_v<BidirectionalIterator1> ||
113 ori::is_global_ptr_v<BidirectionalIteratorD>) {
114 using value_type1 =
typename std::iterator_traits<BidirectionalIterator1>::value_type;
115 using value_type_d =
typename std::iterator_traits<BidirectionalIteratorD>::value_type;
118 internal::convert_to_global_iterator(first1 , internal::src_checkout_mode_t<value_type1>{}),
119 internal::convert_to_global_iterator(last1 , internal::src_checkout_mode_t<value_type1>{}),
120 internal::convert_to_global_iterator(first_d, internal::dest_checkout_mode_t<value_type_d>{}));
125 internal::for_each_aux(
127 [&](
auto&& r1,
auto&& d) {
134 return std::prev(first_d, std::distance(first1, last1));
138 ITYR_TEST_CASE(
"[ityr::pattern::serial_loop] move_backward") {
143 ori::global_ptr<common::move_only_t> p = ori::malloc_coll<common::move_only_t>(n);
146 internal::for_each_aux(
147 execution::sequenced_policy(128),
148 [&](common::move_only_t& mo,
long i) {
149 mo = common::move_only_t{i};
153 count_iterator<long>(0));
157 execution::sequenced_policy(128),
158 p, p + n - offset, p + n);
160 internal::for_each_aux(
161 execution::sequenced_policy(128),
162 [&](
const common::move_only_t& mo,
long i) {
171 count_iterator<long>(0));
#define ITYR_CHECK(cond)
Definition: util.hpp:48
constexpr read_write_t read_write
Read+Write checkout mode.
Definition: checkout_span.hpp:39
constexpr read_t read
Read-only checkout mode.
Definition: checkout_span.hpp:19
ITYR_CONCAT(mode_, ITYR_PROFILER_MODE) mode
Definition: profiler.hpp:257
va_list args
Definition: util.hpp:76
void fini()
Definition: ito.hpp:45
void init(MPI_Comm comm=MPI_COMM_WORLD)
Definition: ito.hpp:41
void fini()
Definition: ori.hpp:49
void init(MPI_Comm comm=MPI_COMM_WORLD)
Definition: ori.hpp:45
void free_coll(global_ptr< T > ptr)
Definition: ori.hpp:70
void checkout_complete()
Definition: ori.hpp:139
monoid< T, min_functor<>, highest< T > > min
Definition: reducer.hpp:101
Definition: allocator.hpp:16
global_reverse_iterator< global_iterator< T, Mode > > make_reverse_iterator(ori::global_ptr< T > gptr, Mode mode)
Make a reverse iterator for global memory.
Definition: global_iterator.hpp:333
BidirectionalIteratorD move_backward(const execution::sequenced_policy &policy, BidirectionalIterator1 first1, BidirectionalIterator1 last1, BidirectionalIteratorD first_d)
Definition: serial_loop.hpp:108
auto root_exec(Fn &&fn, Args &&... args)
Spawn the root thread (collective).
Definition: root_exec.hpp:47
global_iterator< T, Mode > make_global_iterator(ori::global_ptr< T > gptr, Mode)
Make a global iterator to enable/disable automatic checkout.
Definition: global_iterator.hpp:158
global_move_iterator< global_iterator< T, internal::src_checkout_mode_t< T > > > make_move_iterator(ori::global_ptr< T > gptr)
Make a global iterator for moving objects.
Definition: global_iterator.hpp:258
ForwardIteratorD move(const ExecutionPolicy &policy, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIteratorD first_d)
Move a range to another.
Definition: parallel_loop.hpp:934
Serial execution policy for iterator-based loop functions.
Definition: execution.hpp:16