TiledArray  0.7.0
tiled_range1.h
Go to the documentation of this file.
1 /*
2  * This file is a part of TiledArray.
3  * Copyright (C) 2013 Virginia Tech
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  *
18  */
19 
20 #ifndef TILEDARRAY_TILED_RANGE1_H__INCLUDED
21 #define TILEDARRAY_TILED_RANGE1_H__INCLUDED
22 
23 #include <TiledArray/error.h>
24 #include <TiledArray/type_traits.h>
25 #include <vector>
26 #include <initializer_list>
27 
28 namespace TiledArray {
29 
35  class TiledRange1 {
36  private:
37  struct Enabler { };
38  public:
39  typedef std::size_t size_type;
40  typedef std::pair<size_type, size_type> range_type;
41  typedef std::vector<range_type>::const_iterator const_iterator;
42 
45  range_(0,0), elements_range_(0,0),
46  tiles_ranges_(1, range_type(0,0)), elem2tile_(1, 0)
47  {
48  init_map_();
49  }
50 
53  template <typename RandIter,
54  typename std::enable_if<detail::is_random_iterator<RandIter>::value>::type* = nullptr>
55  TiledRange1(RandIter first, RandIter last) :
56  range_(), elements_range_(), tiles_ranges_(), elem2tile_()
57  {
58  init_tiles_(first, last, 0);
59  init_map_();
60  }
61 
63  TiledRange1(const TiledRange1& rng) :
64  range_(rng.range_), elements_range_(rng.elements_range_),
65  tiles_ranges_(rng.tiles_ranges_), elem2tile_(rng.elem2tile_)
66  { }
67 
69 
75  template<typename... _sizes>
76  explicit TiledRange1(const size_type& t0, const _sizes&... t_rest)
77  {
78  const size_type n = sizeof...(_sizes) + 1;
79  size_type tile_boundaries[n] = {t0, static_cast<size_type>(t_rest)...};
80  init_tiles_(tile_boundaries, tile_boundaries+n, 0);
81  init_map_();
82  }
83 
85 
90  explicit TiledRange1(const std::initializer_list<size_type>& list)
91  {
92  init_tiles_(list.begin(), list.end(), 0);
93  init_map_();
94  }
95 
98  TiledRange1(rng).swap(*this);
99  return *this;
100  }
101 
103  const_iterator begin() const { return tiles_ranges_.begin(); }
104 
106  const_iterator end() const { return tiles_ranges_.end(); }
107 
109  const_iterator find(const size_type& e) const{
110  if(! includes(elements_range_, e))
111  return tiles_ranges_.end();
112  const_iterator result = tiles_ranges_.begin();
113  result += element_to_tile(e);
114  return result;
115  }
116 
118  DEPRECATED const range_type& tiles() const { return range_; }
119 
121 
123  const range_type& tiles_range() const { return range_; }
124 
126  const range_type& elements() const { return elements_range_; }
127 
129 
131  const range_type& elements_range() const { return elements_range_; }
132 
134  size_type tile_extent() const { return range_.second - range_.first; }
135 
137  size_type extent() const { return elements_range_.second - elements_range_.first; }
138 
140 
144  const range_type& tile(const size_type i) const {
145  TA_ASSERT(includes(range_, i));
146  return tiles_ranges_[i - range_.first];
147  }
148 
149  const size_type& element_to_tile(const size_type& i) const {
150  TA_ASSERT( includes(elements_range_, i) );
151  return elem2tile_[i - elements_range_.first];
152  }
153 
154  DEPRECATED const size_type& element2tile(const size_type& i) const {
155  return element_to_tile(i);
156  }
157 
158  void swap(TiledRange1& other) { // no throw
159  std::swap(range_, other.range_);
160  std::swap(elements_range_, other.elements_range_);
161  std::swap(tiles_ranges_, other.tiles_ranges_);
162  std::swap(elem2tile_, other.elem2tile_);
163  }
164 
165  private:
166 
167  static bool includes(const range_type& r, size_type i) { return (i >= r.first) && (i < r.second); }
168 
170  template <typename RandIter>
171  static void valid_(RandIter first, RandIter last) {
172  // Verify at least 2 elements are present if the vector is not empty.
173  TA_USER_ASSERT((std::distance(first, last) >= 2),
174  "TiledRange1 construction failed: You need at least 2 elements in the tile boundary list.");
175  // Verify the requirement that a0 < a1 < a2 < ...
176  for (; first != (last - 1); ++first)
177  TA_USER_ASSERT(*first < *(first + 1),
178  "TiledRange1 construction failed: Invalid tile boundary, tile boundary i must be greater than tile boundary i+1 for all i. ");
179  }
180 
182  template <typename RandIter>
183  void init_tiles_(RandIter first, RandIter last, size_type start_tile_index) {
184 #ifndef NDEBUG
185  valid_(first, last);
186 #endif // NDEBUG
187  range_.first = start_tile_index;
188  range_.second = start_tile_index + last - first - 1;
189  elements_range_.first = *first;
190  elements_range_.second = *(last - 1);
191  for (; first != (last - 1); ++first)
192  tiles_ranges_.emplace_back(*first, *(first + 1));
193  }
194 
196  void init_map_() {
197  // check for 0 size range.
198  if((elements_range_.second - elements_range_.first) == 0)
199  return;
200 
201  // initialize elem2tile map
202  elem2tile_.resize(elements_range_.second - elements_range_.first);
203  const size_type end = range_.second - range_.first;
204  for(size_type t = 0; t < end; ++t)
205  for(size_type e = tiles_ranges_[t].first; e < tiles_ranges_[t].second; ++e)
206  elem2tile_[e - elements_range_.first] = t + range_.first;
207  }
208 
209  friend std::ostream& operator <<(std::ostream&, const TiledRange1&);
210 
211  // TiledRange1 data
212  range_type range_;
213  range_type elements_range_;
214  std::vector<range_type> tiles_ranges_;
215  std::vector<size_type> elem2tile_;
216 
217  }; // class TiledRange1
218 
220  inline void swap(TiledRange1& r0, TiledRange1& r1) { // no throw
221  r0.swap(r1);
222  }
223 
225  inline bool operator ==(const TiledRange1& r1, const TiledRange1& r2) {
226  return std::equal(r1.begin(), r1.end(), r2.begin()) &&
227  (r1.tiles_range() == r2.tiles_range()) && (r1.elements_range() == r2.elements_range());
228  }
229 
231  inline bool operator !=(const TiledRange1& r1, const TiledRange1& r2){
232  return ! operator ==(r1, r2);
233  }
234 
236  inline std::ostream& operator <<(std::ostream& out, const TiledRange1& rng) {
237  out << "( tiles = [ " << rng.tiles_range().first << ", " << rng.tiles_range().second
238  << " ), elements = [ " << rng.elements_range().first << ", " << rng.elements_range().second << " ) )";
239  return out;
240  }
241 
242 } // namespace TiledArray
243 
244 #endif // TILEDARRAY_TILED_RANGE1_H__INCLUDED
DEPRECATED const range_type & tiles() const
Definition: tiled_range1.h:118
constexpr bool operator==(const DenseShape &a, const DenseShape &b)
Definition: dense_shape.h:178
std::vector< range_type >::const_iterator const_iterator
Definition: tiled_range1.h:41
TiledRange1(const std::initializer_list< size_type > &list)
Construct a 1D tiled range.
Definition: tiled_range1.h:90
void swap(Range &r0, Range &r1)
Exchange the values of the give two ranges.
Definition: range.h:1048
#define DEPRECATED
Definition: error.h:148
TiledRange1(const size_type &t0, const _sizes &... t_rest)
Construct a 1D tiled range.
Definition: tiled_range1.h:76
const range_type & elements() const
Definition: tiled_range1.h:126
void swap(TiledRange1 &r0, TiledRange1 &r1)
Exchange the data of the two given ranges.
Definition: tiled_range1.h:220
const range_type & tiles_range() const
Tile range accessor.
Definition: tiled_range1.h:123
size_type extent() const
Elements range extent accessor.
Definition: tiled_range1.h:137
const range_type & elements_range() const
Elements range accessor.
Definition: tiled_range1.h:131
const_iterator find(const size_type &e) const
Return tile iterator associated with ordinal_index.
Definition: tiled_range1.h:109
constexpr bool operator!=(const DenseShape &a, const DenseShape &b)
Definition: dense_shape.h:179
TiledRange1(RandIter first, RandIter last)
Definition: tiled_range1.h:55
const range_type & tile(const size_type i) const
Tile range accessor.
Definition: tiled_range1.h:144
DEPRECATED const size_type & element2tile(const size_type &i) const
Definition: tiled_range1.h:154
std::pair< size_type, size_type > range_type
Definition: tiled_range1.h:40
const size_type & element_to_tile(const size_type &i) const
Definition: tiled_range1.h:149
void swap(TiledRange1 &other)
Definition: tiled_range1.h:158
#define TA_ASSERT(a)
Definition: error.h:107
TiledRange1()
Default constructor, range of 0 tiles and elements.
Definition: tiled_range1.h:44
std::ostream & operator<<(std::ostream &os, const DistArray< Tile, Policy > &a)
Add the tensor to an output stream.
Definition: dist_array.h:853
TiledRange1 & operator=(const TiledRange1 &rng)
Assignment operator.
Definition: tiled_range1.h:97
const_iterator begin() const
Returns an iterator to the first tile in the range.
Definition: tiled_range1.h:103
friend std::ostream & operator<<(std::ostream &, const TiledRange1 &)
TiledRange1 ostream operator.
Definition: tiled_range1.h:236
#define TA_USER_ASSERT(a, m)
Definition: error.h:123
size_type tile_extent() const
Tile range extent accessor.
Definition: tiled_range1.h:134
TiledRange1(const TiledRange1 &rng)
Copy constructor.
Definition: tiled_range1.h:63
const_iterator end() const
Returns an iterator to the end of the range.
Definition: tiled_range1.h:106