pmap.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  * Justus Calvin
19  * Department of Chemistry, Virginia Tech
20  *
21  * pmap.h
22  * April 24, 2012
23  *
24  */
25 
26 #ifndef TILEDARRAY_PMAP_H__INCLUDED
27 #define TILEDARRAY_PMAP_H__INCLUDED
28 
29 #include <TiledArray/error.h>
31 
32 #include <madness/config.h>
33 
34 TILEDARRAY_PRAGMA_GCC(diagnostic push)
35 TILEDARRAY_PRAGMA_GCC(diagnostic ignored "-Wparentheses")
36 
37 #include <boost/iterator/iterator_facade.hpp>
38 
39 TILEDARRAY_PRAGMA_GCC(diagnostic pop)
40 
41 namespace TiledArray {
42 
44 
55 class Pmap {
56  public:
57  typedef std::size_t size_type;
58 
59  protected:
60  const size_type rank_;
61  const size_type procs_;
62  const size_type size_;
63  std::vector<size_type>
66 
69  private:
70  Pmap(const Pmap&) = delete;
71  Pmap& operator=(const Pmap&) = delete;
72 
73  public:
75 
78  Pmap(World& world, const size_type size)
79  : rank_(world.rank()),
80  procs_(world.size()),
81  size_(size),
82  local_(),
83  local_size_(0) {}
84 
85  virtual ~Pmap() {}
86 
88 
91  virtual size_type owner(const size_type tile) const = 0;
92 
94 
97  virtual bool is_local(const size_type tile) const = 0;
98 
100 
102  size_type size() const { return size_; }
103 
105 
107  size_type rank() const { return rank_; }
108 
110 
112  size_type procs() const { return procs_; }
113 
115 
118  virtual bool known_local_size() const { return true; }
119 
121 
125  if (size_ > 0) TA_ASSERT(known_local_size() == true);
126  return local_size_;
127  }
128 
130 
133  bool empty() const {
134  if (size_ > 0) TA_ASSERT(known_local_size() == true);
135  return local_size_ == 0;
136  }
137 
139 
141  virtual bool is_replicated() const { return false; }
142 
145 
146  private:
147  virtual void advance(size_type& value, bool increment) const {
148  if (increment)
149  ++value;
150  else
151  --value;
152  }
153 
154  public:
159  class Iterator
160  : public boost::iterator_facade<Iterator, const size_type,
161  boost::bidirectional_traversal_tag> {
162  public:
171  Iterator(const Pmap& pmap, size_type begin_idx, size_type end_idx,
172  size_type idx, bool checking, bool use_pmap_advance = false)
173  : pmap_(&pmap),
174  use_it_(false),
175  idx_(idx),
176  begin_idx_(begin_idx),
177  end_idx_(end_idx),
178  checking_(checking),
179  use_pmap_advance_(use_pmap_advance) {
180  if (idx_ != end_idx) { // unless this is end
181  if (checking_ &&
182  idx_ == begin_idx_) { // create valid begin iterator if needed
183  while (idx_ < end_idx_ && !pmap_->is_local(idx_)) {
184  ++idx_;
185  }
186  } else // else assert that this is a valid iterator
187  TA_ASSERT(pmap_->is_local(idx_));
188  }
189  }
193  Iterator(const Pmap& pmap, std::vector<size_type>::const_iterator it)
194  : use_it_(true), it_(it) {
195  TA_ASSERT(it_ == pmap.local_.end() || pmap.is_local(*it_));
196  }
197 
198  private:
200  const Pmap* pmap_ = nullptr;
201 
202  bool use_it_;
203 
204  // have iterator
205  std::vector<size_type>::const_iterator it_;
206 
208  size_type idx_ = 0;
209  size_type begin_idx_ = 0;
210  size_type end_idx_ = 0;
211  bool checking_ = true;
212  bool use_pmap_advance_ = false;
213 
216  void increment() {
217  if (use_it_) {
218  TA_ASSERT(it_ != pmap_->local_.end());
219  ++it_;
220  } else {
221  if (idx_ == end_idx_) return;
222  if (!use_pmap_advance_) {
223  ++idx_;
224  if (checking_) {
225  while (idx_ < end_idx_ && !pmap_->is_local(idx_)) {
226  ++idx_;
227  }
228  }
229  } else {
230  pmap_->advance(idx_, true);
231  }
232  if (idx_ > end_idx_) // normalize if past end
233  idx_ = end_idx_;
234  TA_ASSERT(idx_ == end_idx_ || pmap_->is_local(idx_));
235  }
236  }
240  void decrement() {
241  if (use_it_) {
242  TA_ASSERT(it_ !=
243  pmap_->local_
244  .begin()); // no good will happen if we decrement begin
245  TA_ASSERT(it_ != pmap_->local_.end()); // don't decrement the end since
246  // it's an invalid iterator
247  --it_;
248  } else {
249  TA_ASSERT(idx_ != begin_idx_);
250  TA_ASSERT(idx_ != end_idx_);
251  if (!use_pmap_advance_) {
252  --idx_;
253  if (checking_) {
254  while (idx_ > begin_idx_ && !pmap_->is_local(idx_)) {
255  --idx_;
256  }
257  }
258  } else {
259  pmap_->advance(idx_, false);
260  }
261  if (idx_ < begin_idx_) // normalize if past begin
262  idx_ = begin_idx_;
263  TA_ASSERT(idx_ == begin_idx_ || pmap_->is_local(idx_));
264  }
265  }
266 
271  bool equal(Iterator const& other) const {
272  TA_ASSERT(this->pmap_ == other.pmap_ && this->use_it_ == other.use_it_);
273  return use_it_ ? this->it_ == other.it_ : this->idx_ == other.idx_;
274  }
275 
278  const size_type& dereference() const { return use_it_ ? *it_ : idx_; }
279  };
280  friend class Iterator;
281 
283 
285 
287  virtual const_iterator begin() const {
288  return !local_.empty() ? Iterator(*this, local_.begin())
289  : Iterator(*this, 0, size_, 0, true);
290  }
291 
293 
295  virtual const_iterator end() const {
296  return !local_.empty() ? Iterator(*this, local_.end())
297  : Iterator(*this, 0, size_, size_, true);
298  }
299 
301 
303  const const_iterator cbegin() const { return begin(); }
304 
306 
308  const const_iterator cend() const { return end(); }
309 
311 
312 }; // class Pmap
313 
314 } // namespace TiledArray
315 
316 #endif // TILEDARRAY_PMAP_H__INCLUDED
Iterator const_iterator
Iterator type.
Definition: pmap.h:282
const const_iterator cbegin() const
Begin local element iterator.
Definition: pmap.h:303
Pmap(World &world, const size_type size)
Process map constructor.
Definition: pmap.h:78
friend class boost::iterator_core_access
Definition: pmap.h:199
virtual const_iterator begin() const
Begin local element iterator.
Definition: pmap.h:287
virtual size_type owner(const size_type tile) const =0
Maps tile to the processor that owns it.
const const_iterator cend() const
End local element iterator.
Definition: pmap.h:308
size_type rank() const
Process rank accessor.
Definition: pmap.h:107
virtual const_iterator end() const
End local element iterator.
Definition: pmap.h:295
#define TA_ASSERT(EXPR,...)
Definition: error.h:39
const size_type procs_
The number of processes.
Definition: pmap.h:61
virtual ~Pmap()
Definition: pmap.h:85
Pmap iterator type.
Definition: pmap.h:161
size_type local_size_
Definition: pmap.h:65
Iterator(const Pmap &pmap, std::vector< size_type >::const_iterator it)
Creates an iterator over pmap.local_.
Definition: pmap.h:193
virtual bool is_replicated() const
Replicated array status.
Definition: pmap.h:141
std::vector< size_type > local_
A list of local tiles (may be empty, if not needed)
Definition: pmap.h:64
size_type size() const
Size accessor.
Definition: pmap.h:102
virtual bool known_local_size() const
Queries whether local size is known.
Definition: pmap.h:118
size_type local_size() const
Local size accessor.
Definition: pmap.h:124
const size_type rank_
The rank of this process.
Definition: pmap.h:60
virtual bool is_local(const size_type tile) const =0
Check that the tile is owned by this process.
std::size_t size_type
Size type.
Definition: pmap.h:57
friend class Iterator
Iterator type.
Definition: pmap.h:280
Iterator(const Pmap &pmap, size_type begin_idx, size_type end_idx, size_type idx, bool checking, bool use_pmap_advance=false)
Creates an iterator of an integer range [begin_idx,end_idx)
Definition: pmap.h:171
Process map.
Definition: pmap.h:55
const size_type size_
The number of tiles mapped among all processes.
Definition: pmap.h:62
Pmap::size_type size_type
Key type.
size_type procs() const
Process count accessor.
Definition: pmap.h:112
bool empty() const
Check if there are any local elements.
Definition: pmap.h:133