OpenMPCD
BunchIteratorRange.hpp
Go to the documentation of this file.
1 /**
2  * @file
3  * Defines the `OpenMPCD::CUDA::BunchIteratorRange` class.
4  */
5 
6 #ifndef OPENMPCD_CUDA_BUNCHITERATORRANGE_HPP
7 #define OPENMPCD_CUDA_BUNCHITERATORRANGE_HPP
8 
10 #include <OpenMPCD/Exceptions.hpp>
12 
13 #include <thrust/functional.h>
14 #include <thrust/iterator/counting_iterator.h>
15 #include <thrust/iterator/permutation_iterator.h>
16 #include <thrust/iterator/transform_iterator.h>
17 
18 namespace OpenMPCD
19 {
20 namespace CUDA
21 {
22 
23 /**
24  * Wraps an iterator range such that it is grouped into "bunches" of a given
25  * length, with a configurable gap between bunches.
26  *
27  * As an example, assume that one has an input iterator range that represents
28  * the sequence `A_0`, `A_1`, `A_2`, ..., `A_N`.
29  * If `bunchSize` is set to `3`, `gapSize` is set to `2`, and `N = 11` (i.e. if
30  * the input sequence has `12` elements), this iterator range will iterate over
31  * the elements `A_0`, `A_1`, `A_2`, followed by `A_5`, `A_6`, `A_7` (skipping
32  * the two elements `A_3` and `A_4`), followed by `A_10` and `A_11`, and end
33  * there since the input sequence is exhausted.
34  *
35  * @tparam UnderlyingIterator
36  * The underlying iterator type.
37  */
38 template<typename UnderlyingIterator>
40 {
41 
42 public:
43  typedef
44  typename thrust::iterator_difference<UnderlyingIterator>::type
46  ///< The type of the difference of two of the underlying iterators.
47 
48  /**
49  * Functor class for advancing a pointer by the given number of effective
50  * elements.
51  */
53  : public thrust::unary_function<IteratorDifference, IteratorDifference>
54  {
55  public:
56  /**
57  * The constructor.
58  *
59  * @throw OpenMPCD::InvalidArgumentException
60  * If `OPENMPCD_DEBUG` is defined, throws if
61  * `bunchSize_ == 0`.
62  *
63  * @param[in] bunchSize_ The bunch size, which must not be `0`.
64  * @param[in] gapSize_ The gap size.
65  */
68  const unsigned int bunchSize_, const unsigned int gapSize_)
69  : bunchSize(bunchSize_), gapSize(gapSize_)
70  {
72  bunchSize != 0, InvalidArgumentException);
73  }
74 
75  /**
76  * Calculates how many times the underlying iterator has to be
77  * incremented to achieve `i` increments of the effective iterator.
78  *
79  * @param[in] i
80  * The number of times the effective iterator is to be
81  * incremented.
82  */
85  const IteratorDifference& i) const
86  {
87  OPENMPCD_DEBUG_ASSERT(i >= 0);
88 
89  unsigned int ret = 0;
90  unsigned int positionInBunch = 0;
91  for(unsigned int remaining = i; remaining != 0; --remaining)
92  {
93  ++positionInBunch;
94  ++ret;
95 
96  if(positionInBunch == bunchSize)
97  {
98  positionInBunch = 0;
99  ret += gapSize;
100  }
101  }
102 
103  return ret;
104  }
105 
106  private:
107  const unsigned int bunchSize; ///< The bunch size.
108  const unsigned int gapSize; ///< The gap size.
109  };
110 
111  typedef
112  typename thrust::counting_iterator<IteratorDifference>
114  ///< Type that is used to linearly increment a count.
115  typedef
116  typename thrust::transform_iterator<AdvancingFunctor, CountingIterator>
118  ///< Type that applies `AdvancingFunctor` to the input sequence.
119  typedef
120  typename thrust::permutation_iterator<
121  UnderlyingIterator, TransformIterator>
123  /**< Type that will be indexing into the `UnderlyingIterator` according
124  to the `TransformIterator`.*/
125 
126  typedef PermutationIterator Iterator; ///< The effective iterator type.
127 
128 public:
129  /**
130  * The constructor.
131  *
132  * @throw OpenMPCD::InvalidArgumentException
133  * If `OPENMPCD_DEBUG` is defined, throws if `bunchSize_ == 0`.
134  *
135  * @param[in] start The first iterator to iterate over.
136  * @param[in] pastTheEnd_ The first iterator that is past-the-end.
137  * @param[in] bunchSize_ The bunch size, which must not be 0.
138  * @param[in] gapSize_ The gap size.
139  */
141  const UnderlyingIterator& start, const UnderlyingIterator& pastTheEnd_,
142  const unsigned int bunchSize_, const unsigned int gapSize_)
143  : first(start), pastTheEnd(pastTheEnd_),
144  bunchSize(bunchSize_), gapSize(gapSize_)
145  {
147  bunchSize != 0, InvalidArgumentException);
148  }
149 
150 public:
151  /**
152  * Returns the first iterator in the effective range.
153  */
154  Iterator begin() const
155  {
156  return Iterator(
157  first,
159  CountingIterator(0),
160  AdvancingFunctor(bunchSize, gapSize)));
161  }
162 
163  /**
164  * Returns the first past-the-end iterator of the effective range.
165  */
166  Iterator end() const
167  {
168  IteratorDifference effectiveCount = 0;
169  IteratorDifference underlyingRemaining = pastTheEnd - first;
170 
171  for(;;)
172  {
173  if(underlyingRemaining <= bunchSize)
174  {
175  effectiveCount += underlyingRemaining;
176  break;
177  }
178 
179  effectiveCount += bunchSize;
180  underlyingRemaining -= bunchSize;
181 
182  if(underlyingRemaining <= gapSize)
183  break;
184 
185  underlyingRemaining -= gapSize;
186  }
187 
188  return begin() + effectiveCount;
189  }
190 
191 private:
192  UnderlyingIterator first; ///< The first iterator to iterate over.
193  UnderlyingIterator pastTheEnd; ///< The first iterator that is past-the-end.
194  const unsigned int bunchSize; ///< The bunch size.
195  const unsigned int gapSize; ///< The gap size.
196 
197 }; //class BunchIteratorRange
198 
199 
200 } //namespace CUDA
201 } //namespace OpenMPCD
202 
203 #endif //OPENMPCD_CUDA_BUNCHITERATORRANGE_HPP
OpenMPCD::CUDA::BunchIteratorRange::AdvancingFunctor::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: BunchIteratorRange.hpp:84
Exceptions.hpp
OpenMPCD::CUDA::BunchIteratorRange::IteratorDifference
thrust::iterator_difference< UnderlyingIterator >::type IteratorDifference
The type of the difference of two of the underlying iterators.
Definition: BunchIteratorRange.hpp:45
OpenMPCD::CUDA::BunchIteratorRange::AdvancingFunctor
Functor class for advancing a pointer by the given number of effective elements.
Definition: BunchIteratorRange.hpp:52
OpenMPCD::CUDA::BunchIteratorRange
Wraps an iterator range such that it is grouped into "bunches" of a given length, with a configurable...
Definition: BunchIteratorRange.hpp:39
OPENMPCD_DEBUG_ASSERT
#define OPENMPCD_DEBUG_ASSERT(assertion)
Asserts that the given expression evaluates to true, but only if OPENMPCD_DEBUG is defined.
Definition: OPENMPCD_DEBUG_ASSERT.hpp:88
OpenMPCD::CUDA::BunchIteratorRange::CountingIterator
thrust::counting_iterator< IteratorDifference > CountingIterator
Type that is used to linearly increment a count.
Definition: BunchIteratorRange.hpp:113
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::BunchIteratorRange::begin
Iterator begin() const
Returns the first iterator in the effective range.
Definition: BunchIteratorRange.hpp:154
OpenMPCD::CUDA::BunchIteratorRange::BunchIteratorRange
BunchIteratorRange(const UnderlyingIterator &start, const UnderlyingIterator &pastTheEnd_, const unsigned int bunchSize_, const unsigned int gapSize_)
The constructor.
Definition: BunchIteratorRange.hpp:140
OpenMPCD::CUDA::BunchIteratorRange::TransformIterator
thrust::transform_iterator< AdvancingFunctor, CountingIterator > TransformIterator
Type that applies AdvancingFunctor to the input sequence.
Definition: BunchIteratorRange.hpp:117
OpenMPCD::CUDA::BunchIteratorRange::AdvancingFunctor::AdvancingFunctor
OPENMPCD_CUDA_HOST_AND_DEVICE AdvancingFunctor(const unsigned int bunchSize_, const unsigned int gapSize_)
The constructor.
Definition: BunchIteratorRange.hpp:67
OpenMPCD::CUDA::BunchIteratorRange::PermutationIterator
thrust::permutation_iterator< UnderlyingIterator, TransformIterator > PermutationIterator
Type that will be indexing into the UnderlyingIterator according to the TransformIterator.
Definition: BunchIteratorRange.hpp:122
OPENMPCD_DEBUG_ASSERT.hpp
OPENMPCD_DEBUG_ASSERT_EXCEPTIONTYPE
#define OPENMPCD_DEBUG_ASSERT_EXCEPTIONTYPE(assertion, ExceptionType)
Definition: OPENMPCD_DEBUG_ASSERT.hpp:76
OpenMPCD::CUDA::BunchIteratorRange::Iterator
PermutationIterator Iterator
The effective iterator type.
Definition: BunchIteratorRange.hpp:126
Macros.hpp
OpenMPCD::CUDA::BunchIteratorRange::end
Iterator end() const
Returns the first past-the-end iterator of the effective range.
Definition: BunchIteratorRange.hpp:166
OpenMPCD::InvalidArgumentException
Invalid argument exception.
Definition: Exceptions.hpp:128