TiledArray  0.7.0
dist_eval.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_DIST_EVAL_DIST_EVAL_BASE_H__INCLUDED
21 #define TILEDARRAY_DIST_EVAL_DIST_EVAL_BASE_H__INCLUDED
22 
23 #include <TiledArray/tensor_impl.h>
24 #include <TiledArray/permutation.h>
25 #include <TiledArray/perm_index.h>
26 #include <TiledArray/type_traits.h>
27 
28 namespace TiledArray {
29  namespace detail {
30 
32 
39  template <typename Tile, typename Policy>
40  class DistEvalImpl : public TensorImpl<Policy>, public madness::CallbackInterface {
41  public:
45 
46  typedef typename TensorImpl_::size_type size_type;
51  typedef Tile value_type;
53 
54  private:
55  madness::uniqueidT id_;
56  PermIndex source_to_target_;
57  PermIndex target_to_source_;
58 
59  // The following variables are used to track the total number of tasks run
60  // on the local node, task_count_, and the number of tiles set on this
61  // node, set_counter_. They are used to track the progress of work done by
62  // this node, which allows us to wait for the completion of these tasks
63  // without waiting for all tasks.
64 
65  volatile int task_count_;
66  madness::AtomicInt set_counter_;
67 
68  protected:
69 
70 
72 
76  TA_ASSERT(index < TensorImpl_::trange().tiles_range().volume());
77  return (source_to_target_ ? source_to_target_(index) : index);
78  }
79 
81 
85  TA_ASSERT(index < TensorImpl_::trange().tiles_range().volume());
86  return (target_to_source_ ? target_to_source_(index) : index);
87  }
88 
89  public:
91 
100  const shape_type& shape, const std::shared_ptr<pmap_interface>& pmap,
101  const Permutation& perm) :
103  id_(world.unique_obj_id()),
104  source_to_target_(),
105  target_to_source_(),
106  task_count_(-1),
107  set_counter_()
108  {
109  set_counter_ = 0;
110 
111  if(perm) {
112  Permutation inv_perm(-perm);
113  range_type source_range = inv_perm * trange.tiles_range();
114  source_to_target_ = PermIndex(source_range, perm);
115  target_to_source_ = PermIndex(trange.tiles_range(), inv_perm);
116  }
117  }
118 
119  virtual ~DistEvalImpl() { }
120 
121 
123 
125  const madness::uniqueidT& id() const { return id_; }
126 
128 
131  virtual Future<value_type> get_tile(size_type i) const = 0;
132 
134 
138  virtual void discard_tile(size_type i) const = 0;
139 
141 
146  void set_tile(size_type i, const value_type& value) {
147  // Store value
148  madness::DistributedID id(id_, i);
149  TensorImpl_::world().gop.send(TensorImpl_::owner(i), id, value);
150 
151  // Record the assignment of a tile
153  }
154 
156 
161  void set_tile(size_type i, Future<value_type> f) {
162  // Store value
163  madness::DistributedID id(id_, i);
164  TensorImpl_::world().gop.send(TensorImpl_::owner(i), id, f);
165 
166  // Record the assignment of a tile
167  f.register_callback(this);
168  }
169 
171  virtual void notify() { set_counter_++; }
172 
174  void wait() const {
175  const int task_count = task_count_;
176  if(task_count > 0) {
177  auto report_and_abort = [&,this](const char* type, const char* what = nullptr) {
178  std::stringstream ss;
179  ss << "!! ERROR TiledArray: Aborting due to " << type << " exception.\n"
180  << (what != nullptr ? "!! ERROR TiledArray: " : "")
181  << (what != nullptr ? what : "")
182  << (what != nullptr ? "\n" : "")
183  << "!! ERROR TiledArray: rank=" << TensorImpl_::world().rank()
184  << " id=" << id_ << " " << set_counter_ << " of " << task_count << " tiles set" << std::endl;
185  std::cerr << ss.str().c_str();
186  abort();
187  };
188  try {
189  TensorImpl_::world().await([this,task_count] ()
190  { return this->set_counter_ == task_count; });
191  } catch(TiledArray::Exception& e) {
192  report_and_abort("TiledArray", e.what());
193  } catch(madness::MadnessException& e) {
194  report_and_abort("MADNESS", e.what());
195  } catch(SafeMPI::Exception& e) {
196  report_and_abort("SafeMPI", e.what());
197  } catch(std::exception& e) {
198  report_and_abort("std", e.what());
199  } catch(...) {
200  report_and_abort("", nullptr);
201  }
202  }
203  }
204 
205  private:
206 
208 
214  virtual int internal_eval() = 0;
215 
216  public:
217 
219 
224  void eval() {
225  TA_ASSERT(task_count_ == -1);
226  task_count_ = this->internal_eval();
227  TA_ASSERT(task_count_ >= 0);
228  }
229 
230  }; // class DistEvalImpl
231 
232 
234 
240  template <typename Tile, typename Policy>
241  class DistEval {
242  public:
245  typedef typename impl_type::size_type size_type;
251  typedef typename impl_type::eval_type eval_type;
252  typedef Future<value_type> future;
253 
254  private:
255  std::shared_ptr<impl_type> pimpl_;
256 
257  public:
259 
261  template <typename Impl>
262  DistEval(const std::shared_ptr<Impl>& pimpl) :
263  pimpl_(std::static_pointer_cast<impl_type>(pimpl))
264  {
265  TA_ASSERT(pimpl_);
266  }
267 
269 
272  DistEval(const DistEval_& other) : pimpl_(other.pimpl_) { }
273 
275 
279  DistEval_& operator=(const DistEval_& other) {
280  pimpl_ = other.pimpl_;
281  return *this;
282  }
283 
285 
288  void eval() { return pimpl_->eval(); }
289 
290 
292 
294  const range_type& range() const { return pimpl_->tiles_range(); }
295 
297 
299  size_type size() const { return pimpl_->size(); }
300 
302 
305  ProcessID owner(size_type i) const { return pimpl_->owner(i); }
306 
308 
311  bool is_local(size_type i) const { return pimpl_->is_local(i); }
312 
314 
317  bool is_zero(size_type i) const { return pimpl_->is_zero(i); }
318 
320 
322  const std::shared_ptr<pmap_interface>& pmap() const { return pimpl_->pmap(); }
323 
325 
327  bool is_dense() const { return pimpl_->is_dense(); }
328 
330 
332  const shape_type& shape() const { return pimpl_->shape(); }
333 
335 
337  const trange_type& trange() const { return pimpl_->trange(); }
338 
340 
344  future get(size_type i) const { return pimpl_->get_tile(i); }
345 
347 
351  virtual void discard(size_type i) const { pimpl_->discard_tile(i); }
352 
354 
356  World& world() const { return pimpl_->world(); }
357 
359 
361  madness::uniqueidT id() const { return pimpl_->id(); }
362 
364  void wait() const { pimpl_->wait(); }
365 
366  }; // class DistEval
367 
368  } // namespace detail
369 } // namespace TiledArray
370 
371 #endif // TILEDARRAY_DIST_EVAL_DIST_EVAL_BASE_H__INCLUDED
TensorImpl_::size_type size_type
Size type.
Definition: dist_eval.h:46
const std::shared_ptr< pmap_interface > & pmap() const
Tensor process map accessor.
Definition: dist_eval.h:322
bool is_zero(size_type i) const
Query for a zero tile.
Definition: dist_eval.h:317
void eval()
Evaluate this tensor expression object.
Definition: dist_eval.h:224
A functor that permutes ordinal indices.
Definition: perm_index.h:39
DistEvalImpl< Tile, Policy > impl_type
Implementation base class type.
Definition: dist_eval.h:244
impl_type::value_type value_type
Tile type.
Definition: dist_eval.h:250
ProcessID owner(size_type i) const
Query a tile owner.
Definition: dist_eval.h:305
const shape_type & shape() const
Tensor shape accessor.
Definition: tensor_impl.h:156
const trange_type & trange() const
Tiled range accessor.
Definition: tensor_impl.h:161
Policy::range_type range_type
Element/tile range type.
Definition: tensor_impl.h:44
World & world() const
World object accessor.
Definition: dist_eval.h:356
Policy::pmap_interface pmap_interface
Process map interface type.
Definition: tensor_impl.h:47
DistEval< Tile, Policy > DistEval_
This class type.
Definition: dist_eval.h:243
void wait() const
Wait for all tiles to be assigned.
Definition: dist_eval.h:174
virtual Future< value_type > get_tile(size_type i) const =0
Get tile at index i.
DistEval(const DistEval_ &other)
Copy constructor.
Definition: dist_eval.h:272
Distributed evaluator implementation object.
Definition: dist_eval.h:40
DistEval_ & operator=(const DistEval_ &other)
Assignment operator.
Definition: dist_eval.h:279
TiledArray::detail::TensorImpl< Policy > TensorImpl_
Tensor implementation base class.
Definition: dist_eval.h:43
TensorImpl_::pmap_interface pmap_interface
process map interface type
Definition: dist_eval.h:50
void set_tile(size_type i, Future< value_type > f)
Set tensor value with a future.
Definition: dist_eval.h:161
Tensor implementation and base for other tensor implementation objects.
Definition: tensor_impl.h:39
void eval()
Evaluate this tensor object with the given result variable list.
Definition: dist_eval.h:288
STL namespace.
void set_tile(size_type i, const value_type &value)
Set tensor value.
Definition: dist_eval.h:146
madness::uniqueidT id() const
Unique object id.
Definition: dist_eval.h:361
impl_type::trange_type trange_type
Tiled range type for this object.
Definition: dist_eval.h:246
const range_type & range() const
Tensor tile size array accessor.
Definition: dist_eval.h:294
TensorImpl_::trange_type trange_type
Tiled range type for this object.
Definition: dist_eval.h:47
Policy::trange_type trange_type
Tiled range type.
Definition: tensor_impl.h:43
size_type perm_index_to_target(size_type index) const
Permute index from a source index to a target index.
Definition: dist_eval.h:75
bool is_local(size_type i) const
Query for a locally owned tile.
Definition: dist_eval.h:311
impl_type::range_type range_type
Range type this tensor.
Definition: dist_eval.h:247
impl_type::pmap_interface pmap_interface
Process map interface type.
Definition: dist_eval.h:249
virtual const char * what() const TILEDARRAY_NO_EXCEPTION
Definition: error.h:56
Lazy tile for on-the-fly evaluation of array tiles.
Definition: array_eval.h:42
TensorImpl_::shape_type shape_type
Shape type.
Definition: dist_eval.h:49
Tensor expression object.
Definition: dist_eval.h:241
ProcessID owner(const Index &i) const
Query a tile owner.
Definition: tensor_impl.h:116
#define TA_ASSERT(a)
Definition: error.h:107
const madness::uniqueidT & id() const
Unique object id accessor.
Definition: dist_eval.h:125
size_type size() const
Tensor tile volume accessor.
Definition: dist_eval.h:299
impl_type::eval_type eval_type
Tile evaluation type.
Definition: dist_eval.h:251
const shape_type & shape() const
Tensor shape accessor.
Definition: dist_eval.h:332
Policy::size_type size_type
Size type.
Definition: tensor_impl.h:45
bool is_dense() const
Query the density of the tensor.
Definition: dist_eval.h:327
impl_type::size_type size_type
Size type.
Definition: dist_eval.h:245
TensorImpl_::range_type range_type
Range type this tensor.
Definition: dist_eval.h:48
void wait() const
Wait for all local tiles to be evaluated.
Definition: dist_eval.h:364
eval_trait< value_type >::type eval_type
Tile evaluation type.
Definition: dist_eval.h:52
virtual void discard_tile(size_type i) const =0
Discard a tile that is not needed.
Permutation of a sequence of objects indexed by base-0 indices.
Definition: permutation.h:119
DistEval(const std::shared_ptr< Impl > &pimpl)
Constructor.
Definition: dist_eval.h:262
DistEvalImpl(World &world, const trange_type &trange, const shape_type &shape, const std::shared_ptr< pmap_interface > &pmap, const Permutation &perm)
Constructor.
Definition: dist_eval.h:99
const trange_type & trange() const
Tiled range accessor.
Definition: dist_eval.h:337
World & world() const
World accessor.
Definition: tensor_impl.h:169
virtual void discard(size_type i) const
Discard a tile that is not needed.
Definition: dist_eval.h:351
impl_type::shape_type shape_type
Tensor shape type.
Definition: dist_eval.h:248
const range_type & tiles_range() const
Tiles range accessor.
Definition: tensor_impl.h:91
size_type perm_index_to_source(size_type index) const
Permute index from a target index to a source index.
Definition: dist_eval.h:84
const std::shared_ptr< pmap_interface > & pmap() const
Tensor process map accessor.
Definition: tensor_impl.h:85
Future< value_type > future
Future of tile type.
Definition: dist_eval.h:252
An N-dimensional shallow copy wrapper for tile objects.
Definition: tile.h:80
virtual void notify()
Tile set notification.
Definition: dist_eval.h:171
DistEvalImpl< Tile, Policy > DistEvalImpl_
This object type.
Definition: dist_eval.h:42
Policy::shape_type shape_type
Tensor shape type.
Definition: tensor_impl.h:46