RAJA
RAJA provides a collection of platform portability abstractions for C++ HPC applications.
zip.hpp
Go to the documentation of this file.
1 
11 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
12 // Copyright (c) Lawrence Livermore National Security, LLC and other
13 // RAJA Project Developers. See top-level LICENSE and COPYRIGHT
14 // files for dates and other details. No copyright assignment is required
15 // to contribute to RAJA.
16 //
17 // SPDX-License-Identifier: (BSD-3-Clause)
18 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
19 
20 
21 #ifndef RAJA_util_zip_HPP
22 #define RAJA_util_zip_HPP
23 
24 #include "RAJA/config.hpp"
25 
26 #include <iostream>
27 #include <type_traits>
28 
31 #include "RAJA/util/concepts.hpp"
32 #include "RAJA/util/zip_tuple.hpp"
33 #include "RAJA/util/Span.hpp"
34 
35 namespace RAJA
36 {
37 
42 template<typename... Iters>
44 {
45  static_assert(
46  concepts::all_of<type_traits::is_random_access_iterator<Iters>...>::value,
47  "ZipIterator can only contain random access iterators");
48  static_assert(sizeof...(Iters) > 1,
49  "ZipIterator must contain one or more iterators");
50 
51  using value_type =
53  using difference_type = std::ptrdiff_t;
54  using pointer = void;
56  using creference =
58  using iterator_category = std::random_access_iterator_tag;
59 
60  RAJA_HOST_DEVICE RAJA_INLINE constexpr ZipIterator() : m_iterators() {}
61 
62  template<typename... Args,
63  typename = concepts::enable_if<
64  type_traits::convertible_to<Args&&, Iters>...>>
65  RAJA_HOST_DEVICE RAJA_INLINE constexpr ZipIterator(Args&&... args)
66  : m_iterators(std::forward<Args>(args)...)
67  {}
68 
69  RAJA_HOST_DEVICE RAJA_INLINE constexpr ZipIterator(const ZipIterator& rhs)
70  : m_iterators(rhs.m_iterators)
71  {}
72 
73  RAJA_HOST_DEVICE RAJA_INLINE constexpr ZipIterator(ZipIterator&& rhs)
74  : m_iterators(std::move(rhs.m_iterators))
75  {}
76 
77  RAJA_HOST_DEVICE RAJA_INLINE constexpr ZipIterator& operator=(
78  const ZipIterator& rhs)
79  {
80  m_iterators = rhs.m_iterators;
81  return *this;
82  }
83 
84  RAJA_HOST_DEVICE RAJA_INLINE constexpr ZipIterator& operator=(
85  ZipIterator&& rhs)
86  {
87  m_iterators = std::move(rhs.m_iterators);
88  return *this;
89  }
90 
91  RAJA_HOST_DEVICE RAJA_INLINE constexpr difference_type get_stride() const
92  {
93  return 1;
94  }
95 
96  RAJA_HOST_DEVICE RAJA_INLINE constexpr bool operator==(
97  const ZipIterator& rhs) const
98  {
99  return RAJA::get<0>(m_iterators) == RAJA::get<0>(rhs.m_iterators);
100  }
101 
102  RAJA_HOST_DEVICE RAJA_INLINE constexpr bool operator!=(
103  const ZipIterator& rhs) const
104  {
105  return RAJA::get<0>(m_iterators) != RAJA::get<0>(rhs.m_iterators);
106  }
107 
108  RAJA_HOST_DEVICE RAJA_INLINE constexpr bool operator>(
109  const ZipIterator& rhs) const
110  {
111  return RAJA::get<0>(m_iterators) > RAJA::get<0>(rhs.m_iterators);
112  }
113 
114  RAJA_HOST_DEVICE RAJA_INLINE constexpr bool operator<(
115  const ZipIterator& rhs) const
116  {
117  return RAJA::get<0>(m_iterators) < RAJA::get<0>(rhs.m_iterators);
118  }
119 
120  RAJA_HOST_DEVICE RAJA_INLINE constexpr bool operator>=(
121  const ZipIterator& rhs) const
122  {
123  return RAJA::get<0>(m_iterators) >= RAJA::get<0>(rhs.m_iterators);
124  }
125 
126  RAJA_HOST_DEVICE RAJA_INLINE constexpr bool operator<=(
127  const ZipIterator& rhs) const
128  {
129  return RAJA::get<0>(m_iterators) <= RAJA::get<0>(rhs.m_iterators);
130  }
131 
132  RAJA_HOST_DEVICE RAJA_INLINE constexpr ZipIterator& operator++()
133  {
134  detail::zip_for_each(m_iterators, detail::PreInc {});
135  return *this;
136  }
137 
138  RAJA_HOST_DEVICE RAJA_INLINE constexpr ZipIterator& operator--()
139  {
140  detail::zip_for_each(m_iterators, detail::PreDec {});
141  return *this;
142  }
143 
144  RAJA_HOST_DEVICE RAJA_INLINE constexpr ZipIterator operator++(int)
145  {
146  ZipIterator tmp(*this);
147  ++(*this);
148  return tmp;
149  }
150 
151  RAJA_HOST_DEVICE RAJA_INLINE constexpr ZipIterator operator--(int)
152  {
153  ZipIterator tmp(*this);
154  --(*this);
155  return tmp;
156  }
157 
158  RAJA_HOST_DEVICE RAJA_INLINE constexpr ZipIterator& operator+=(
159  const difference_type& rhs)
160  {
162  return *this;
163  }
164 
165  RAJA_HOST_DEVICE RAJA_INLINE constexpr ZipIterator& operator-=(
166  const difference_type& rhs)
167  {
169  return *this;
170  }
171 
173  const ZipIterator& rhs) const
174  {
175  return RAJA::get<0>(m_iterators) - RAJA::get<0>(rhs.m_iterators);
176  }
177 
178  RAJA_HOST_DEVICE RAJA_INLINE constexpr ZipIterator operator+(
179  const difference_type& rhs) const
180  {
181  ZipIterator tmp(*this);
182  tmp += rhs;
183  return tmp;
184  }
185 
186  RAJA_HOST_DEVICE RAJA_INLINE constexpr ZipIterator operator-(
187  const difference_type& rhs) const
188  {
189  ZipIterator tmp(*this);
190  tmp -= rhs;
191  return tmp;
192  }
193 
194  RAJA_HOST_DEVICE RAJA_INLINE constexpr friend ZipIterator operator+(
195  difference_type lhs,
196  const ZipIterator& rhs)
197  {
198  ZipIterator tmp(rhs);
199  tmp += lhs;
200  return tmp;
201  }
202 
203  RAJA_HOST_DEVICE RAJA_INLINE constexpr reference operator*() const
204  {
205  return deref_helper(camp::make_idx_seq_t<sizeof...(Iters)> {});
206  }
207 
208  // TODO:: figure out what to do with this
209  // RAJA_HOST_DEVICE RAJA_INLINE constexpr reference operator->() const
210  // {
211  // return *(*this);
212  // }
213  RAJA_HOST_DEVICE RAJA_INLINE constexpr reference operator[](
214  difference_type rhs) const
215  {
216  return *((*this) + rhs);
217  }
218 
219  RAJA_HOST_DEVICE RAJA_INLINE constexpr friend void safe_iter_swap(
220  ZipIterator lhs,
221  ZipIterator rhs)
222  {
223  detail::zip_for_each(lhs.m_iterators, rhs.m_iterators, detail::IterSwap {});
224  }
225 
226 private:
227  zip_val<camp::decay<Iters>...> m_iterators;
228 
229  template<camp::idx_t... Is>
230  RAJA_HOST_DEVICE RAJA_INLINE constexpr reference deref_helper(
231  camp::idx_seq<Is...>) const
232  {
233  return reference(*RAJA::get<Is>(m_iterators)...);
234  }
235 };
236 
241 template<typename... Args>
242 RAJA_HOST_DEVICE RAJA_INLINE constexpr auto zip(Args&&... args)
244 {
245  return {std::forward<Args>(args)...};
246 }
247 
252 template<typename... Args>
253 RAJA_HOST_DEVICE RAJA_INLINE constexpr auto zip_span(Args&&... args)
255  typename ZipIterator<
256  detail::ContainerIter<camp::decay<Args>>...>::difference_type>
257 {
258  using std::begin;
259  using std::end;
262  camp::decay<Args>>...>::difference_type>(
263  zip(begin(std::forward<Args>(args))...),
264  zip(end(std::forward<Args>(args))...));
265 }
266 
271 template<typename T, typename Compare>
273 {
274  RAJA_HOST_DEVICE RAJA_INLINE constexpr CompareFirst(Compare comp_)
275  : comp(comp_)
276  {}
277 
278  RAJA_HOST_DEVICE RAJA_INLINE constexpr bool operator()(T const& lhs,
279  T const& rhs) const
280  {
281  return comp(RAJA::get<0>(lhs), RAJA::get<0>(rhs));
282  }
283 
284 private:
285  Compare comp;
286 };
287 
292 template<typename T, typename Compare>
293 RAJA_HOST_DEVICE RAJA_INLINE constexpr auto compare_first(Compare comp)
295 {
296  return {comp};
297 }
298 
299 } // end namespace RAJA
300 
301 #endif
Header file for RAJA span constructs.
Header file for RAJA algorithm definitions.
Header file with aliases to camp types.
Header file for RAJA concept definitions.
#define RAJA_HOST_DEVICE
Definition: macros.hpp:65
camp::iterator_from< Container > ContainerIter
Definition: algorithm.hpp:47
Args args
Definition: WorkRunner.hpp:212
RAJA_HOST_DEVICE constexpr RAJA_INLINE void zip_for_each(Tuple &&t, F &&f)
Call f on each member of t (f(t)...).
Definition: zip_tuple.hpp:216
Definition: AlignedRangeIndexSetBuilders.cpp:35
RAJA_HOST_DEVICE constexpr RAJA_INLINE auto compare_first(Compare comp) -> CompareFirst< T, Compare >
Make a comparator to compare first member of tuple like objects of type T.
Definition: zip.hpp:293
RAJA_HOST_DEVICE constexpr RAJA_INLINE auto zip_span(Args &&... args) -> Span< ZipIterator< detail::ContainerIter< camp::decay< Args >>... >, typename ZipIterator< detail::ContainerIter< camp::decay< Args >>... >::difference_type >
Zip multiple containers together to iterate them simultaneously with ZipIterator objects.
Definition: zip.hpp:253
RAJA_HOST_DEVICE constexpr RAJA_INLINE auto zip(Args &&... args) -> ZipIterator< camp::decay< Args >... >
Zip multiple iterators together to iterate them simultaneously with a single ZipIterator object.
Definition: zip.hpp:242
Definition: ListSegment.hpp:416
Comparator object that compares the first member of tuple like objects.
Definition: zip.hpp:273
RAJA_HOST_DEVICE constexpr RAJA_INLINE bool operator()(T const &lhs, T const &rhs) const
Definition: zip.hpp:278
RAJA_HOST_DEVICE constexpr RAJA_INLINE CompareFirst(Compare comp_)
Definition: zip.hpp:274
A view to a sequence of objects.
Definition: Span.hpp:62
ZipIterator class for simultaneously iterating over multiple iterators. This is not a standards compl...
Definition: zip.hpp:44
RAJA_HOST_DEVICE constexpr RAJA_INLINE ZipIterator & operator=(ZipIterator &&rhs)
Definition: zip.hpp:84
std::random_access_iterator_tag iterator_category
Definition: zip.hpp:58
RAJA_HOST_DEVICE constexpr RAJA_INLINE reference operator*() const
Definition: zip.hpp:203
RAJA_HOST_DEVICE constexpr RAJA_INLINE ZipIterator & operator+=(const difference_type &rhs)
Definition: zip.hpp:158
std::ptrdiff_t difference_type
Definition: zip.hpp:53
RAJA_HOST_DEVICE constexpr RAJA_INLINE ZipIterator operator-(const difference_type &rhs) const
Definition: zip.hpp:186
RAJA_HOST_DEVICE constexpr RAJA_INLINE bool operator>=(const ZipIterator &rhs) const
Definition: zip.hpp:120
RAJA_HOST_DEVICE constexpr RAJA_INLINE friend void safe_iter_swap(ZipIterator lhs, ZipIterator rhs)
Definition: zip.hpp:219
RAJA_HOST_DEVICE constexpr RAJA_INLINE ZipIterator(ZipIterator &&rhs)
Definition: zip.hpp:73
RAJA_HOST_DEVICE constexpr RAJA_INLINE ZipIterator()
Definition: zip.hpp:60
RAJA_HOST_DEVICE constexpr RAJA_INLINE ZipIterator operator++(int)
Definition: zip.hpp:144
zip_ref< typename std::iterator_traits< Iters >::reference... > reference
Definition: zip.hpp:55
RAJA_HOST_DEVICE constexpr RAJA_INLINE bool operator!=(const ZipIterator &rhs) const
Definition: zip.hpp:102
RAJA_HOST_DEVICE constexpr RAJA_INLINE bool operator<(const ZipIterator &rhs) const
Definition: zip.hpp:114
RAJA_HOST_DEVICE constexpr RAJA_INLINE ZipIterator & operator++()
Definition: zip.hpp:132
RAJA_HOST_DEVICE constexpr RAJA_INLINE bool operator<=(const ZipIterator &rhs) const
Definition: zip.hpp:126
RAJA_HOST_DEVICE constexpr RAJA_INLINE ZipIterator & operator-=(const difference_type &rhs)
Definition: zip.hpp:165
RAJA_HOST_DEVICE constexpr RAJA_INLINE ZipIterator & operator=(const ZipIterator &rhs)
Definition: zip.hpp:77
RAJA_HOST_DEVICE constexpr RAJA_INLINE friend ZipIterator operator+(difference_type lhs, const ZipIterator &rhs)
Definition: zip.hpp:194
RAJA_HOST_DEVICE constexpr RAJA_INLINE ZipIterator(Args &&... args)
Definition: zip.hpp:65
RAJA_HOST_DEVICE constexpr RAJA_INLINE ZipIterator(const ZipIterator &rhs)
Definition: zip.hpp:69
RAJA_HOST_DEVICE constexpr RAJA_INLINE ZipIterator operator--(int)
Definition: zip.hpp:151
RAJA_HOST_DEVICE constexpr RAJA_INLINE ZipIterator & operator--()
Definition: zip.hpp:138
RAJA_HOST_DEVICE constexpr RAJA_INLINE difference_type get_stride() const
Definition: zip.hpp:91
RAJA_HOST_DEVICE constexpr RAJA_INLINE reference operator[](difference_type rhs) const
Definition: zip.hpp:213
RAJA_HOST_DEVICE constexpr RAJA_INLINE bool operator==(const ZipIterator &rhs) const
Definition: zip.hpp:96
RAJA_HOST_DEVICE constexpr RAJA_INLINE difference_type operator-(const ZipIterator &rhs) const
Definition: zip.hpp:172
void pointer
Definition: zip.hpp:54
RAJA_HOST_DEVICE constexpr RAJA_INLINE bool operator>(const ZipIterator &rhs) const
Definition: zip.hpp:108
RAJA_HOST_DEVICE constexpr RAJA_INLINE ZipIterator operator+(const difference_type &rhs) const
Definition: zip.hpp:178
Definition: zip_tuple.hpp:176
Definition: zip_tuple.hpp:143
Definition: zip_tuple.hpp:130
Definition: zip_tuple.hpp:119
Definition: zip_tuple.hpp:109
Tuple used by ZipIterator for storing multiple references and values. Acts like a reference to its me...
Definition: zip_tuple.hpp:247
Header file for multi-iterator Zip Views.