OpenMPCD
StridedIteratorRange.hpp
Go to the documentation of this file.
1 /**
2  * @file
3  * Defines the `OpenMPCD::CUDA::StridedIteratorRange` class.
4  */
5 
6 #ifndef OPENMPCD_CUDA_STRIDEDITERATORRANGE_HPP
7 #define OPENMPCD_CUDA_STRIDEDITERATORRANGE_HPP
8 
10 
11 #include <boost/static_assert.hpp>
12 #include <thrust/functional.h>
13 #include <thrust/iterator/counting_iterator.h>
14 #include <thrust/iterator/permutation_iterator.h>
15 #include <thrust/iterator/transform_iterator.h>
16 
17 namespace OpenMPCD
18 {
19 namespace CUDA
20 {
21 
22 /**
23  * Wraps an iterator range such that the iteration stride is not (necessarily)
24  * `1`.
25  *
26  * This strided iterator range exposes the underlying iterator range in such a
27  * way that incrementing the exposed iterator (called "effective iterator") once
28  * is equivalent to incrementing the underlying iterator as many times as the
29  * `stride` specifies.
30  *
31  * @remark
32  * This code has been adapted from `examples/strided_range.cu` of the `thrust`
33  * library.
34  *
35  * @tparam UnderlyingIterator
36  * The underlying iterator type.
37  * @tparam stride
38  * The iterator stride. This parameter specifies how often the
39  * underlying iterator gets incremented each time this instance of
40  * `StridedIteratorRange` gets incremented.
41  * The special value `0` selects a (partially) specialized template of
42  * `StridedIteratorRange` that allows one to set the stride in the
43  * constructor.
44  */
45 template<typename UnderlyingIterator, unsigned int stride = 0>
47 {
48 
49 BOOST_STATIC_ASSERT(stride != 0);
50 
51 public:
52  typedef
53  typename thrust::iterator_difference<UnderlyingIterator>::type
55  ///< The type of the difference of two of the underlying iterators.
56 
57  /**
58  * Functor class for advancing a pointer by the given stride.
59  */
61  : public thrust::unary_function<IteratorDifference, IteratorDifference>
62  {
63  public:
64  /**
65  * Calculates how many times the underlying iterator has to be
66  * incremented to achieve `i` increments of the effective iterator.
67  *
68  * @param[in] i
69  * The number of times the effective iterator is to be
70  * incremented.
71  */
74  const IteratorDifference& i) const
75  {
76  return stride * i;
77  }
78  };
79 
80  typedef
81  typename thrust::counting_iterator<IteratorDifference>
83  ///< Type that is used to linearly increment a count.
84  typedef
85  typename thrust::transform_iterator<StrideFunctor, CountingIterator>
87  ///< Type that applies `StrideFunctor` to the input sequence.
88  typedef
89  typename thrust::permutation_iterator<
90  UnderlyingIterator, TransformIterator>
92  /**< Type that will be indexing into the `UnderlyingIterator` according
93  to the `TransformIterator`.*/
94 
95  typedef PermutationIterator Iterator; ///< The effective iterator type.
96 
97 public:
98  /**
99  * The constructor.
100  *
101  * @param[in] start The first iterator to iterate over.
102  * @param[in] pastTheEnd_ The first iterator that is past-the-end.
103  */
105  const UnderlyingIterator& start, const UnderlyingIterator& pastTheEnd_)
106  : first(start), pastTheEnd(pastTheEnd_)
107  {
108  }
109 
110 public:
111  /**
112  * Returns the first iterator in the strided range.
113  */
114  Iterator begin() const
115  {
116  return Iterator(
118  }
119 
120  /**
121  * Returns the first past-the-end iterator of the strided range.
122  */
123  Iterator end() const
124  {
125  return begin() + ((pastTheEnd - first) + (stride - 1)) / stride;
126  }
127 
128 private:
129  UnderlyingIterator first; ///< The first iterator to iterate over.
130  UnderlyingIterator pastTheEnd; ///< The first iterator that is past-the-end.
131 
132 }; //class StridedIteratorRange
133 
134 
135 /**
136  * Partial template specialization of `StridedIteratorRange` for dynamic
137  * strides.
138  */
139 template<typename UnderlyingIterator>
140 class StridedIteratorRange<UnderlyingIterator, 0>
141 {
142 
143 public:
144  typedef
145  typename thrust::iterator_difference<UnderlyingIterator>::type
147  ///< The type of the difference of two of the underlying iterators.
148 
149  /**
150  * Functor class for advancing a pointer by the given stride.
151  */
152  class StrideFunctor
153  : public thrust::unary_function<IteratorDifference, IteratorDifference>
154  {
155  public:
156  /**
157  * The constructor.
158  *
159  * @param[in] s The iterator stride.
160  */
161  StrideFunctor(const unsigned int s) : stride(s)
162  {
163  }
164 
165  /**
166  * Calculates how many times the underlying iterator has to be
167  * incremented to achieve `i` increments of the effective iterator.
168  *
169  * @param[in] i
170  * The number of times the effective iterator is to be
171  * incremented.
172  */
174  const IteratorDifference& i) const
175  {
176  return stride * i;
177  }
178 
179  private:
180  const unsigned int stride; ///< The iterator stride.
181  };
182 
183  typedef
184  typename thrust::counting_iterator<IteratorDifference>
186  ///< Type that is used to linearly increment a count.
187  typedef
188  typename thrust::transform_iterator<StrideFunctor, CountingIterator>
190  ///< Type that applies `StrideFunctor` to the input sequence.
191  typedef
192  typename thrust::permutation_iterator<
193  UnderlyingIterator, TransformIterator>
195  /**< Type that will be indexing into the `UnderlyingIterator` according
196  to the `TransformIterator`.*/
197 
198  typedef PermutationIterator Iterator; ///< The effective iterator type.
199 
200 public:
201  /**
202  * The constructor.
203  *
204  * @param[in] start The first iterator to iterate over.
205  * @param[in] pastTheEnd_ The first iterator that is past-the-end.
206  * @param[in] stride_ The iterator stride.
207  */
209  const UnderlyingIterator& start, const UnderlyingIterator& pastTheEnd_,
210  const unsigned int stride_)
211  : first(start), pastTheEnd(pastTheEnd_), stride(stride_)
212  {
213  }
214 
215 public:
216  /**
217  * Returns the first iterator in the strided range.
218  */
219  Iterator begin() const
220  {
221  return Iterator(
222  first,
223  TransformIterator(CountingIterator(0), StrideFunctor(stride)));
224  }
225 
226  /**
227  * Returns the first past-the-end iterator of the strided range.
228  */
229  Iterator end() const
230  {
231  return begin() + ((pastTheEnd - first) + (stride - 1)) / stride;
232  }
233 
234 private:
235  UnderlyingIterator first; ///< The first iterator to iterate over.
236  UnderlyingIterator pastTheEnd; ///< The first iterator that is past-the-end.
237  const unsigned int stride; ///< The iterator stride.
238 
239 }; //class StridedIteratorRange
240 
241 
242 } //namespace CUDA
243 } //namespace OpenMPCD
244 
245 #endif
OpenMPCD::CUDA::StridedIteratorRange::begin
Iterator begin() const
Returns the first iterator in the strided range.
Definition: StridedIteratorRange.hpp:114
OpenMPCD::CUDA::StridedIteratorRange::StrideFunctor
Functor class for advancing a pointer by the given stride.
Definition: StridedIteratorRange.hpp:60
OpenMPCD::CUDA::StridedIteratorRange::IteratorDifference
thrust::iterator_difference< UnderlyingIterator >::type IteratorDifference
The type of the difference of two of the underlying iterators.
Definition: StridedIteratorRange.hpp:54
OPENMPCD_CUDA_HOST_AND_DEVICE
#define OPENMPCD_CUDA_HOST_AND_DEVICE
Denotes a function to be callable both from the Host and from a CUDA Device.
Definition: Macros.hpp:15
OpenMPCD::CUDA::StridedIteratorRange< UnderlyingIterator, 0 >::end
Iterator end() const
Returns the first past-the-end iterator of the strided range.
Definition: StridedIteratorRange.hpp:229
OpenMPCD::CUDA::StridedIteratorRange< UnderlyingIterator, 0 >::begin
Iterator begin() const
Returns the first iterator in the strided range.
Definition: StridedIteratorRange.hpp:219
OpenMPCD::CUDA::StridedIteratorRange::PermutationIterator
thrust::permutation_iterator< UnderlyingIterator, TransformIterator > PermutationIterator
Type that will be indexing into the UnderlyingIterator according to the TransformIterator.
Definition: StridedIteratorRange.hpp:91
OpenMPCD::CUDA::StridedIteratorRange::Iterator
PermutationIterator Iterator
The effective iterator type.
Definition: StridedIteratorRange.hpp:95
OpenMPCD::CUDA::StridedIteratorRange< UnderlyingIterator, 0 >::Iterator
PermutationIterator Iterator
The effective iterator type.
Definition: StridedIteratorRange.hpp:198
OpenMPCD::CUDA::StridedIteratorRange::StrideFunctor::operator()
const OPENMPCD_CUDA_HOST_AND_DEVICE IteratorDifference operator()(const IteratorDifference &i) const
Calculates how many times the underlying iterator has to be incremented to achieve i increments of th...
Definition: StridedIteratorRange.hpp:73
OpenMPCD::CUDA::StridedIteratorRange< UnderlyingIterator, 0 >::TransformIterator
thrust::transform_iterator< StrideFunctor, CountingIterator > TransformIterator
Type that applies StrideFunctor to the input sequence.
Definition: StridedIteratorRange.hpp:189
OpenMPCD::CUDA::StridedIteratorRange< UnderlyingIterator, 0 >::PermutationIterator
thrust::permutation_iterator< UnderlyingIterator, TransformIterator > PermutationIterator
Type that will be indexing into the UnderlyingIterator according to the TransformIterator.
Definition: StridedIteratorRange.hpp:194
OpenMPCD::CUDA::StridedIteratorRange::TransformIterator
thrust::transform_iterator< StrideFunctor, CountingIterator > TransformIterator
Type that applies StrideFunctor to the input sequence.
Definition: StridedIteratorRange.hpp:86
OpenMPCD::CUDA::StridedIteratorRange< UnderlyingIterator, 0 >::IteratorDifference
thrust::iterator_difference< UnderlyingIterator >::type IteratorDifference
The type of the difference of two of the underlying iterators.
Definition: StridedIteratorRange.hpp:146
OpenMPCD::CUDA::StridedIteratorRange< UnderlyingIterator, 0 >::StrideFunctor::StrideFunctor
StrideFunctor(const unsigned int s)
The constructor.
Definition: StridedIteratorRange.hpp:161
Macros.hpp
OpenMPCD::CUDA::StridedIteratorRange< UnderlyingIterator, 0 >::CountingIterator
thrust::counting_iterator< IteratorDifference > CountingIterator
Type that is used to linearly increment a count.
Definition: StridedIteratorRange.hpp:185
OpenMPCD::CUDA::StridedIteratorRange
Wraps an iterator range such that the iteration stride is not (necessarily) 1.
Definition: StridedIteratorRange.hpp:46
OpenMPCD::CUDA::StridedIteratorRange< UnderlyingIterator, 0 >::StridedIteratorRange
StridedIteratorRange(const UnderlyingIterator &start, const UnderlyingIterator &pastTheEnd_, const unsigned int stride_)
The constructor.
Definition: StridedIteratorRange.hpp:208
OpenMPCD::CUDA::StridedIteratorRange< UnderlyingIterator, 0 >::StrideFunctor::operator()
const IteratorDifference operator()(const IteratorDifference &i) const
Calculates how many times the underlying iterator has to be incremented to achieve i increments of th...
Definition: StridedIteratorRange.hpp:173
OpenMPCD::CUDA::StridedIteratorRange::CountingIterator
thrust::counting_iterator< IteratorDifference > CountingIterator
Type that is used to linearly increment a count.
Definition: StridedIteratorRange.hpp:82
OpenMPCD::CUDA::StridedIteratorRange::StridedIteratorRange
StridedIteratorRange(const UnderlyingIterator &start, const UnderlyingIterator &pastTheEnd_)
The constructor.
Definition: StridedIteratorRange.hpp:104
OpenMPCD::CUDA::StridedIteratorRange::end
Iterator end() const
Returns the first past-the-end iterator of the strided range.
Definition: StridedIteratorRange.hpp:123