MADNESS 0.10.1
range.h
Go to the documentation of this file.
1/*
2 This file is part of MADNESS.
3
4 Copyright (C) 2007,2010 Oak Ridge National Laboratory
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
20 For more information please contact:
21
22 Robert J. Harrison
23 Oak Ridge National Laboratory
24 One Bethel Valley Road
25 P.O. Box 2008, MS-6367
26
27 email: harrisonrj@ornl.gov
28 tel: 865-241-3937
29 fax: 865-572-0680
30*/
31
32#ifndef MADNESS_WORLD_RANGE_H__INCLUDED
33#define MADNESS_WORLD_RANGE_H__INCLUDED
34
35#include <type_traits>
36#include <iterator>
37#ifdef HAVE_INTEL_TBB
38# include <tbb/partitioner.h>
39#endif
40
41/**
42 \file range.h
43 \brief Implement the \c Range class for parallel iteration.
44 \ingroup parallel_runtime
45*/
46
47namespace madness {
48
49 /// \addtogroup parallel_runtime
50 /// @{
51
52 /// Dummy class, a la Intel TBB, used to distinguish splitting constructor.
53#ifdef HAVE_INTEL_TBB
54 typedef tbb::split Split;
55#else
56 class Split {};
57#endif // HAVE_INTEL_TBB
58
59 /// \brief Range, vaguely a la Intel TBB, to encapsulate a random-access,
60 /// STL-like start and end iterator with chunksize.
61
62 /// \tparam iteratorT The iterator type.
63 template <typename iteratorT>
64 class Range {
65 long n; ///< Number of items to iterator over. \todo Could this be replaced by size_t?
66 iteratorT start; ///< First item for iteration.
67 iteratorT finish; ///< Last item for iteration (first past the end, conventionally).
68 int chunksize; ///< Number of items to give to each thread/process.
69
70 public:
71 using iterator = iteratorT; ///< Alias for the iterator type.
72
73 /// Makes the range [start, finish).
74
75 /// The motivated reader should look at the Intel TBB range,
76 /// partitioner, split, concepts, etc.
77 /// \param[in] start The first item to iterate over.
78 /// \param[in] finish The last item for iteration (one past the end).
79 /// \param[in] chunk The number of items to give to each thread/process.
80 Range(const iterator& start, const iterator& finish, int chunk=1)
82 , start(start)
83 , finish(finish)
84 , chunksize(chunk)
85 {
86 if (chunksize < 1) chunksize = 1;
87 }
88
89 /// Copy constructor. Cost is O(1).
90
91 /// \todo Can we make this `= default`?
92 /// \param[in] r The \c Range to copy.
93 Range(const Range& r)
94 : n(r.n)
95 , start(r.start)
96 , finish(r.finish)
98 {}
99
100 /// Splits range between new and old (r) objects. Cost is O(1).
101
102 /// \param[in] left The range to be split.
103 Range(Range& left, const Split& /*split*/)
104 : n(0)
105 , start(left.finish)
106 , finish(left.finish)
107 , chunksize(left.chunksize)
108 {
109 if (left.n > chunksize) {
110 int nleft = (left.n+1)/2;
111
112 start = left.start;
113 advance(start,nleft);
114 finish = left.finish;
115 n = left.n - nleft;
116
117 left.finish = start;
118 left.n = nleft;
119 }
120 }
121
122 /// Returns the number of items in the range (cost is O(1)).
123
124 /// \return The number of items in the range.
125 size_t size() const { return n; }
126
127 /// Returns true if `size == 0`.
128
129 /// \return True if `size == 0`.
130 bool empty() const { return n==0; }
131
132 /// Access the beginning.
133
134 /// \return Iterator to the first element.
135 const iterator& begin() const { return start; }
136
137 /// Access the end.
138
139 /// \return Iterator to the last element (one past the end).
140 const iterator& end() const { return finish; }
141
142 /// \brief Return true if this iteration range can be divided; that is,
143 /// there are more items than the chunk size.
144
145 /// \return True if this range can be divided.
146 bool is_divisible() const { return n > chunksize; }
147
148 /// Access the chunk size.
149
150 /// \todo Should this return `long`, or `size_t`?
151 /// \return The chunk size.
152 unsigned int get_chunksize() const { return chunksize; }
153
154 private:
155 /// Advance by \c n elements in the range.
156
157 /// This version is for cases where the "iterator type" is integral.
158 /// \tparam integralT The integral iterator type.
159 /// \tparam distanceT The distance type.
160 /// \param[in,out] i The integral iterator.
161 /// \param[in] n The number of elements to advance.
162 template<typename integralT, typename distanceT>
163 inline static typename std::enable_if<std::is_integral<integralT>::value, void>::type
164 advance(integralT& i, distanceT n) { i += n; }
165
166 /// Advance by \c n elements in the range.
167
168 /// This version is for cases where the "iterator type" is not integral.
169 /// \tparam iterT The non-integral iterator type.
170 /// \tparam distanceT The distance type.
171 /// \param[in,out] it The iterator.
172 /// \param[in] n The number of elements to advance.
173 template<typename iterT, typename distanceT>
174 inline static typename std::enable_if<!std::is_integral<iterT>::value, void>::type
175 advance(iterT& it, distanceT n) { std::advance(it, n); }
176
177 /// Calculate the distance between two iterators.
178
179 /// This version is for cases where the "iterator type" is integral.
180 /// \tparam integralT The integral iterator type.
181 /// \param[in] first One iterator.
182 /// \param[in] last The other iterator.
183 /// \return The distance between the first and last iterators.
184 template<class integralT>
185 inline static typename std::enable_if<std::is_integral<integralT>::value, integralT>::type
186 distance(integralT first, integralT last) { return last - first; }
187
188 /// Calculate the distance between two iterators.
189
190 /// This version is for cases where the "iterator type" is not integral.
191 /// \tparam iterT The non-integral iterator type.
192 /// \param[in] first One iterator.
193 /// \param[in] last The other iterator.
194 /// \return The distance between the first and last iterators.
195 template<class iterT>
196 inline static auto
197 distance(iterT first, iterT last,
198 typename std::enable_if<!std::is_integral<iterT>::value>::type* = nullptr)
199 -> decltype(std::distance(first, last))
200 { return std::distance(first, last); }
201 };
202
203 /// @}
204
205} // namespace madness
206
207#endif // MADNESS_WORLD_RANGE_H__INCLUDED
Range, vaguely a la Intel TBB, to encapsulate a random-access, STL-like start and end iterator with c...
Definition range.h:64
Range(Range &left, const Split &)
Splits range between new and old (r) objects. Cost is O(1).
Definition range.h:103
static std::enable_if< std::is_integral< integralT >::value, integralT >::type distance(integralT first, integralT last)
Calculate the distance between two iterators.
Definition range.h:186
unsigned int get_chunksize() const
Access the chunk size.
Definition range.h:152
bool is_divisible() const
Return true if this iteration range can be divided; that is, there are more items than the chunk size...
Definition range.h:146
static auto distance(iterT first, iterT last, typename std::enable_if<!std::is_integral< iterT >::value >::type *=nullptr) -> decltype(std::distance(first, last))
Calculate the distance between two iterators.
Definition range.h:197
long n
Number of items to iterator over.
Definition range.h:65
const iterator & end() const
Access the end.
Definition range.h:140
iteratorT iterator
Alias for the iterator type.
Definition range.h:71
static std::enable_if<!std::is_integral< iterT >::value, void >::type advance(iterT &it, distanceT n)
Advance by n elements in the range.
Definition range.h:175
bool empty() const
Returns true if size == 0.
Definition range.h:130
int chunksize
Number of items to give to each thread/process.
Definition range.h:68
Range(const iterator &start, const iterator &finish, int chunk=1)
Makes the range [start, finish).
Definition range.h:80
static std::enable_if< std::is_integral< integralT >::value, void >::type advance(integralT &i, distanceT n)
Advance by n elements in the range.
Definition range.h:164
iteratorT finish
Last item for iteration (first past the end, conventionally).
Definition range.h:67
const iterator & begin() const
Access the beginning.
Definition range.h:135
iteratorT start
First item for iteration.
Definition range.h:66
size_t size() const
Returns the number of items in the range (cost is O(1)).
Definition range.h:125
Range(const Range &r)
Copy constructor. Cost is O(1).
Definition range.h:93
tbb::split Split
Dummy class, a la Intel TBB, used to distinguish splitting constructor.
Definition range.h:54
Namespace for all elements and tools of MADNESS.
Definition DFParameters.h:10
std::string type(const PairType &n)
Definition PNOParameters.h:18
void advance(madness::Hash_private::HashIterator< hashT > &it, const distT &dist)
Definition worldhashmap.h:610
int distance(const madness::Hash_private::HashIterator< hashT > &it, const madness::Hash_private::HashIterator< hashT > &jt)
Definition worldhashmap.h:616