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/config.h>
24 #include <TiledArray/perm_index.h>
25 #include <TiledArray/permutation.h>
26 #include <TiledArray/tensor_impl.h>
27 #include <TiledArray/type_traits.h>
28 #ifdef TILEDARRAY_HAS_CUDA
31 #endif
32 
33 namespace TiledArray {
34 namespace detail {
35 
37 
44 template <typename Tile, typename Policy>
45 class DistEvalImpl : public TensorImpl<Policy>,
46  public madness::CallbackInterface {
47  public:
51 
53  typedef typename TensorImpl_::trange_type
55  typedef
58  typedef typename TensorImpl_::pmap_interface
60  typedef Tile value_type;
61  typedef typename eval_trait<value_type>::type
63 
64  private:
65  madness::uniqueidT id_;
66  PermIndex source_to_target_;
67  PermIndex target_to_source_;
69 
71  // The following variables are used to track the total number of tasks run
72  // on the local node, task_count_, and the number of tiles set on this
73  // node, set_counter_. They are used to track the progress of work done by
74  // this node, which allows us to wait for the completion of these tasks
75  // without waiting for all tasks.
76 
77  volatile int task_count_;
78  madness::AtomicInt set_counter_;
79 
80  protected:
82 
87  return (source_to_target_ ? source_to_target_(index) : index);
88  }
89 
91 
96  return (target_to_source_ ? target_to_source_(index) : index);
97  }
98 
99  public:
101 
110  const std::shared_ptr<pmap_interface>& pmap,
111  const Permutation& perm)
113  id_(world.unique_obj_id()),
114  source_to_target_(),
115  target_to_source_(),
116  task_count_(-1),
117  set_counter_() {
118  set_counter_ = 0;
119 
120  if (perm) {
121  Permutation inv_perm(-perm);
122  range_type source_range = inv_perm * trange.tiles_range();
123  source_to_target_ = PermIndex(source_range, perm);
124  target_to_source_ = PermIndex(trange.tiles_range(), inv_perm);
125  }
126  }
127 
128  virtual ~DistEvalImpl() {}
129 
131 
133  const madness::uniqueidT& id() const { return id_; }
134 
136 
140 
142 
146  virtual void discard_tile(ordinal_type i) const = 0;
147 
149 
154  void set_tile(ordinal_type i, const value_type& value) {
155  // Store value
156  madness::DistributedID id(id_, i);
157  TensorImpl_::world().gop.send(TensorImpl_::owner(i), id, value);
158 
159  // Record the assignment of a tile
161  }
162 
164 
170  // Store value
171  madness::DistributedID id(id_, i);
172  TensorImpl_::world().gop.send(TensorImpl_::owner(i), id, f);
173 
174  // Record the assignment of a tile
175  f.register_callback(this);
176  }
177 
179  virtual void notify() { set_counter_++; }
180 
182  void wait() const {
183  const int task_count = task_count_;
184  if (task_count > 0) {
185  auto report_and_abort = [&, this](const char* type,
186  const char* what = nullptr) {
187  std::stringstream ss;
188  ss << "!! ERROR TiledArray: Aborting due to " << type << " exception.\n"
189  << (what != nullptr ? "!! ERROR TiledArray: " : "")
190  << (what != nullptr ? what : "") << (what != nullptr ? "\n" : "")
191  << "!! ERROR TiledArray: rank=" << TensorImpl_::world().rank()
192  << " id=" << id_ << " " << set_counter_ << " of " << task_count
193  << " tiles set" << std::endl;
194  std::cerr << ss.str().c_str();
195  abort();
196  };
197  try {
198  TensorImpl_::world().await(
199  [this, task_count]() { return this->set_counter_ == task_count; });
200  } catch (TiledArray::Exception& e) {
201  report_and_abort("TiledArray", e.what());
202  } catch (madness::MadnessException& e) {
203  report_and_abort("MADNESS", e.what());
204  } catch (SafeMPI::Exception& e) {
205  report_and_abort("SafeMPI", e.what());
206  } catch (std::exception& e) {
207  report_and_abort("std", e.what());
208  } catch (...) {
209  report_and_abort("", nullptr);
210  }
211  }
212  }
213 
214  private:
216 
222  virtual int internal_eval() = 0;
223 
224  public:
226 
231  void eval() {
232  TA_ASSERT(task_count_ == -1);
233  task_count_ = this->internal_eval();
234  TA_ASSERT(task_count_ >= 0);
235  }
236 
237 }; // class DistEvalImpl
238 
240 
246 template <typename Tile, typename Policy>
247 class DistEval {
248  public:
253  typedef typename impl_type::trange_type
255  typedef
258  typedef typename impl_type::pmap_interface
261  typedef typename impl_type::eval_type eval_type;
263 
264  private:
265  std::shared_ptr<impl_type> pimpl_;
266 
267  public:
269 
271  template <typename Impl>
272  DistEval(const std::shared_ptr<Impl>& pimpl)
273  : pimpl_(std::static_pointer_cast<impl_type>(pimpl)) {
274  TA_ASSERT(pimpl_);
275  }
276 
278 
281  DistEval(const DistEval_& other) : pimpl_(other.pimpl_) {}
282 
284 
288  DistEval_& operator=(const DistEval_& other) {
289  pimpl_ = other.pimpl_;
290  return *this;
291  }
292 
294 
299  void eval() { pimpl_->eval(); }
300 
302 
304  const range_type& range() const { return pimpl_->tiles_range(); }
305 
307 
309  ordinal_type size() const { return pimpl_->size(); }
310 
312 
315  ProcessID owner(ordinal_type i) const { return pimpl_->owner(i); }
316 
318 
321  bool is_local(ordinal_type i) const { return pimpl_->is_local(i); }
322 
324 
327  bool is_zero(ordinal_type i) const { return pimpl_->is_zero(i); }
328 
330 
332  const std::shared_ptr<pmap_interface>& pmap() const { return pimpl_->pmap(); }
333 
335 
337  bool is_dense() const { return pimpl_->is_dense(); }
338 
340 
342  const shape_type& shape() const { return pimpl_->shape(); }
343 
345 
347  const trange_type& trange() const { return pimpl_->trange(); }
348 
350 
354  future get(ordinal_type i) const { return pimpl_->get_tile(i); }
355 
357 
361  virtual void discard(ordinal_type i) const { pimpl_->discard_tile(i); }
362 
364 
366  World& world() const { return pimpl_->world(); }
367 
369 
371  madness::uniqueidT id() const { return pimpl_->id(); }
372 
374  void wait() const { pimpl_->wait(); }
375 
376 }; // class DistEval
377 
378 } // namespace detail
379 } // namespace TiledArray
380 
381 #endif // TILEDARRAY_DIST_EVAL_DIST_EVAL_BASE_H__INCLUDED
impl_type::ordinal_type ordinal_type
Ordinal type.
Definition: dist_eval.h:252
World & world() const
World accessor.
Definition: tensor_impl.h:175
const trange_type & trange() const
Tiled range accessor.
Definition: dist_eval.h:347
const shape_type & shape() const
Tensor shape accessor.
Definition: dist_eval.h:342
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:109
ordinal_type size() const
Tensor tile volume accessor.
Definition: tensor_impl.h:101
DistEvalImpl< Tile, Policy > DistEvalImpl_
This object type.
Definition: dist_eval.h:48
future get(ordinal_type i) const
Tile move.
Definition: dist_eval.h:354
Permutation of a sequence of objects indexed by base-0 indices.
Definition: permutation.h:130
bool is_zero(const Index &i) const
Query for a zero tile.
Definition: tensor_impl.h:147
ordinal_type perm_index_to_target(ordinal_type index) const
Permute index from a source index to a target index.
Definition: dist_eval.h:85
bool is_dense() const
Query the density of the tensor.
Definition: tensor_impl.h:156
DistEvalImpl< Tile, Policy > impl_type
Implementation base class type.
Definition: dist_eval.h:251
void set_tile(ordinal_type i, Future< value_type > f)
Set tensor value with a future.
Definition: dist_eval.h:169
void set_tile(ordinal_type i, const value_type &value)
Set tensor value.
Definition: dist_eval.h:154
madness::uniqueidT id() const
Unique object id.
Definition: dist_eval.h:371
const range_type & tiles_range() const
Tiles range accessor.
Definition: tensor_impl.h:95
void wait() const
Wait for all tiles to be assigned.
Definition: dist_eval.h:182
bool is_zero(ordinal_type i) const
Query for a zero tile.
Definition: dist_eval.h:327
Lazy tile for on-the-fly evaluation of array tiles.
Definition: array_eval.h:42
eval_trait< value_type >::type eval_type
Tile evaluation type.
Definition: dist_eval.h:62
DistEval(const std::shared_ptr< Impl > &pimpl)
Constructor.
Definition: dist_eval.h:272
const std::shared_ptr< pmap_interface > & pmap() const
Tensor process map accessor.
Definition: tensor_impl.h:89
virtual Future< value_type > get_tile(ordinal_type i) const =0
Get tile at index i.
impl_type::trange_type trange_type
Tiled range type for this object.
Definition: dist_eval.h:254
Distributed evaluator implementation object.
Definition: dist_eval.h:46
ProcessID owner(ordinal_type i) const
Query a tile owner.
Definition: dist_eval.h:315
World & world() const
World object accessor.
Definition: dist_eval.h:366
Tensor implementation and base for other tensor implementation objects.
Definition: tensor_impl.h:39
DistEval< Tile, Policy > DistEval_
This class type.
Definition: dist_eval.h:249
#define TA_ASSERT(EXPR,...)
Definition: error.h:39
ProcessID owner(const Index &i) const
Query a tile owner.
Definition: tensor_impl.h:122
Policy::ordinal_type ordinal_type
Ordinal type.
Definition: tensor_impl.h:46
ordinal_type perm_index_to_source(ordinal_type index) const
Permute index from a target index to a source index.
Definition: dist_eval.h:94
TiledArray::detail::TensorImpl< Policy > TensorImpl_
Tensor implementation base class.
Definition: dist_eval.h:49
TensorImpl_::ordinal_type ordinal_type
Ordinal type.
Definition: dist_eval.h:52
A functor that permutes ordinal indices.
Definition: perm_index.h:38
Policy::shape_type shape_type
Tensor shape type.
Definition: tensor_impl.h:47
const std::shared_ptr< pmap_interface > & pmap() const
Tensor process map accessor.
Definition: dist_eval.h:332
Future< value_type > future
Future of tile type.
Definition: dist_eval.h:262
virtual void discard(ordinal_type i) const
Discard a tile that is not needed.
Definition: dist_eval.h:361
impl_type::pmap_interface pmap_interface
Process map interface type.
Definition: dist_eval.h:259
void eval()
Evaluate this tensor expression object.
Definition: dist_eval.h:231
TensorImpl_::range_type range_type
Range type this tensor.
Definition: dist_eval.h:56
impl_type::range_type range_type
Range type this tensor.
Definition: dist_eval.h:256
TensorImpl_::shape_type shape_type
Shape type.
Definition: dist_eval.h:57
virtual void notify()
Tile set notification.
Definition: dist_eval.h:179
ordinal_type size() const
Tensor tile volume accessor.
Definition: dist_eval.h:309
Policy::range_type range_type
Element/tile range type.
Definition: tensor_impl.h:44
void eval()
Evaluate this object.
Definition: dist_eval.h:299
Policy::trange_type trange_type
Tiled range type.
Definition: tensor_impl.h:43
impl_type::shape_type shape_type
Tensor shape type.
Definition: dist_eval.h:257
size_t volume(const DistArray< Tile, Policy > &a)
Definition: dist_array.h:1622
impl_type::eval_type eval_type
Tile evaluation type.
Definition: dist_eval.h:261
bool is_local(ordinal_type i) const
Query for a locally owned tile.
Definition: dist_eval.h:321
impl_type::value_type value_type
Tile type.
Definition: dist_eval.h:260
Policy::pmap_interface pmap_interface
Process map interface type.
Definition: tensor_impl.h:49
TensorImpl_::pmap_interface pmap_interface
process map interface type
Definition: dist_eval.h:59
void wait() const
Wait for all local tiles to be evaluated.
Definition: dist_eval.h:374
const range_type & range() const
Tensor tile size array accessor.
Definition: dist_eval.h:304
bool is_dense() const
Query the density of the tensor.
Definition: dist_eval.h:337
Determine the object type used in the evaluation of tensor expressions.
Definition: type_traits.h:580
const trange_type & trange() const
Tiled range accessor.
Definition: tensor_impl.h:167
const shape_type & shape() const
Tensor shape accessor.
Definition: tensor_impl.h:162
DistEval(const DistEval_ &other)
Copy constructor.
Definition: dist_eval.h:281
const madness::uniqueidT & id() const
Unique object id accessor.
Definition: dist_eval.h:133
Tensor expression object.
Definition: dist_eval.h:247
TensorImpl_::trange_type trange_type
Tiled range type for this object.
Definition: dist_eval.h:54
An N-dimensional shallow copy wrapper for tile objects.
Definition: tile.h:82
bool is_local(const Index &i) const
Query for a locally owned tile.
Definition: tensor_impl.h:134
virtual void discard_tile(ordinal_type i) const =0
Discard a tile that is not needed.
DistEval_ & operator=(const DistEval_ &other)
Assignment operator.
Definition: dist_eval.h:288