TiledArray  0.7.0
array_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  * Justus Calvin
19  * Department of Chemistry, Virginia Tech
20  *
21  * array_eval.h
22  * Aug 9, 2013
23  *
24  */
25 
26 #ifndef TILEDARRAY_DIST_EVAL_ARRAY_EVAL_H__INCLUDED
27 #define TILEDARRAY_DIST_EVAL_ARRAY_EVAL_H__INCLUDED
28 
30 #include <TiledArray/block_range.h>
31 
32 namespace TiledArray {
33  namespace detail {
34 
36 
41  template <typename Tile, typename Op>
42  class LazyArrayTile {
43  public:
45  typedef Op op_type;
46  typedef typename op_type::result_type eval_type;
47  typedef Tile tile_type;
48 
49  private:
50  mutable tile_type tile_;
51  std::shared_ptr<op_type> op_;
52  bool consume_;
53 
54  template <typename T>
55  using eval_t = typename eval_trait<typename std::decay<T>::type>::type;
56 
57  public:
59  LazyArrayTile() : tile_(), op_(), consume_(false) { }
60 
62 
64  LazyArrayTile(const LazyArrayTile_& other) :
65  tile_(other.tile_), op_(other.op_), consume_(other.consume_)
66  { }
67 
69 
73  LazyArrayTile(const tile_type& tile, const std::shared_ptr<op_type>& op, const bool consume) :
74  tile_(tile), op_(op), consume_(consume)
75  { }
76 
78 
81  tile_ = other.tile_;
82  op_ = other.op_;
83  consume_ = other.consume_;
84 
85  return *this;
86  }
87 
89 
91  bool is_consumable() const { return consume_ || op_->permutation(); }
92 
94 #ifdef __clang__ // clang's operator auto behavior is severely broken
95  // (e.g. explicit operator auto() is not considered in conversions,
96  // looking it up as From::operator To does not work, etc.)
97  // so must work around
98  using conversion_result_type =
99  decltype(((!Op::is_consumable) && consume_ ? op_->consume(tile_)
100  : (*op_)(tile_)));
101  explicit operator conversion_result_type() const {
102  return ((!Op::is_consumable) && consume_ ? op_->consume(tile_)
103  : (*op_)(tile_));
104  }
105 #else
106  explicit operator auto() const {
107  return ((!Op::is_consumable) && consume_ ? op_->consume(tile_)
108  : (*op_)(tile_));
109  }
110 #endif
111 
113  const tile_type& tile() const { return tile_; }
114 
116 
118  template <typename Archive>
119  void serialize(const Archive&) {
120  TA_ASSERT(false);
121  }
122 
123  }; // LazyArrayTile
124 
125 
127 
137  template <typename Array, typename Op, typename Policy>
139  public DistEvalImpl<LazyArrayTile<typename Array::value_type, Op>, Policy>,
140  public std::enable_shared_from_this<ArrayEvalImpl<Array, Op, Policy> >
141  {
142  public:
146  typedef Array array_type;
153  typedef Op op_type;
154 
155  using std::enable_shared_from_this<ArrayEvalImpl<Array, Op, Policy> >::shared_from_this;
156 
157  private:
158  array_type array_;
159  std::shared_ptr<op_type> op_;
160  BlockRange block_range_;
161 
162  public:
163 
165 
173  ArrayEvalImpl(const array_type& array, World& world, const trange_type& trange,
174  const shape_type& shape, const std::shared_ptr<pmap_interface>& pmap,
175  const Permutation& perm, const op_type& op) :
176  DistEvalImpl_(world, trange, shape, pmap, perm),
177  array_(array), op_(std::make_shared<op_type>(op)), block_range_()
178  { }
179 
181 
191  ArrayEvalImpl(const array_type& array, World& world, const trange_type& trange,
192  const shape_type& shape, const std::shared_ptr<pmap_interface>& pmap,
193  const Permutation& perm, const op_type& op,
194  const std::vector<std::size_t>& lower_bound,
195  const std::vector<std::size_t>& upper_bound) :
196  DistEvalImpl_(world, trange, shape, pmap, perm),
197  array_(array), op_(std::make_shared<op_type>(op)),
198  block_range_(array.trange().tiles_range(), lower_bound, upper_bound)
199  { }
200 
202  virtual ~ArrayEvalImpl() { }
203 
204  virtual Future<value_type> get_tile(size_type i) const {
205 
206  // Get the array index that corresponds to the target index
208 
209  // If this object only uses a sub-block of the array, shift the tile
210  // index to the correct location.
211  if(block_range_.rank())
212  array_index = block_range_.ordinal(array_index);
213 
214  // Get the tile from array_, which may be located on a remote node.
215  Future<typename array_type::value_type> tile =
216  array_.find(array_index);
217 
218  const bool consumable_tile = ! array_.is_local(array_index);
219  // Insert the tile into this evaluator for subsequent processing
220  if(tile.probe()) {
221  // Skip the task since the tile is ready
222  Future<value_type> result;
223  result.set(make_tile(tile, consumable_tile));
224  const_cast<ArrayEvalImpl_*>(this)->notify();
225  return result;
226  } else {
227  // Spawn a task to set the tile when the input tile is ready.
228  Future<value_type> result =
229  TensorImpl_::world().taskq.add(shared_from_this(),
230  & ArrayEvalImpl_::make_tile, tile, consumable_tile,
231  madness::TaskAttributes::hipri());
232 
233  result.register_callback(const_cast<ArrayEvalImpl_*>(this));
234  return result;
235  }
236  }
237 
239 
242  virtual void discard_tile(size_type) const {
243  const_cast<ArrayEvalImpl_*>(this)->notify();
244  }
245 
246  private:
247 
248  value_type make_tile(const typename array_type::value_type& tile, const bool consume) const {
249  return value_type(tile, op_, consume);
250  }
251 
253 
256  void set_tile(const size_type i, const typename array_type::value_type& tile, const bool consume) {
257  DistEvalImpl_::set_tile(i, value_type(tile, op_, consume));
258  }
259 
261 
265  virtual int internal_eval() {
266  // Counter for the number of tasks submitted by this object
267  int task_count = 0;
268 
269  // Get a count of the number of local tiles.
270  if(TensorImpl_::shape().is_dense()) {
271  task_count = TensorImpl_::pmap()->local_size();
272  } else {
273  // Create iterator to tiles that are local for this evaluator.
274  typename array_type::pmap_interface::const_iterator it =
275  TensorImpl_::pmap()->begin();
276  const typename array_type::pmap_interface::const_iterator end =
277  TensorImpl_::pmap()->end();
278 
279  for(; it != end; ++it) {
280  if(! TensorImpl_::is_zero(*it))
281  ++task_count;
282  }
283  }
284 
285  return task_count;
286  }
287 
288  }; // class ArrayEvalImpl
289 
290  } // namespace detail
291 } // namespace TiledArray
292 
293 #endif // TILEDARRAY_DIST_EVAL_ARRAY_EVAL_H__INCLUDED
TensorImpl_::size_type size_type
Size type.
Definition: dist_eval.h:46
DistEvalImpl< LazyArrayTile< typename Array::value_type, Op >, Policy > DistEvalImpl_
The base class type.
Definition: array_eval.h:144
DistEvalImpl_::trange_type trange_type
tiled range type
Definition: array_eval.h:151
Op op_type
The operation that will modify this tile.
Definition: array_eval.h:45
DistEvalImpl_::pmap_interface pmap_interface
Process map interface type.
Definition: array_eval.h:150
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
ordinal_type ordinal(const Index &index) const
calculate the ordinal index of i
Definition: block_range.h:130
LazyArrayTile< Tile, Op > LazyArrayTile_
This class type.
Definition: array_eval.h:44
bool is_dense() const
Query the density of the tensor.
Definition: tensor_impl.h:150
DistEvalImpl_::size_type size_type
Size type.
Definition: array_eval.h:147
DistEvalImpl_::range_type range_type
Range type.
Definition: array_eval.h:148
Future< value_type > find(const Index &i) const
Find local or remote tile.
Definition: dist_array.h:324
virtual Future< value_type > get_tile(size_type i) const
Get tile at index i.
Definition: array_eval.h:204
LazyArrayTile()
Default constructor.
Definition: array_eval.h:59
DistEvalImpl_::value_type value_type
value type
Definition: array_eval.h:152
Op op_type
Tile evaluation operator type.
Definition: array_eval.h:153
Distributed evaluator implementation object.
Definition: dist_eval.h:40
Determine the object type used in the evaluation of tensor expressions.
Definition: type_traits.h:296
TensorImpl_::pmap_interface pmap_interface
process map interface type
Definition: dist_eval.h:50
DistEvalImpl_::shape_type shape_type
Shape type.
Definition: array_eval.h:149
Tensor implementation and base for other tensor implementation objects.
Definition: tensor_impl.h:39
STL namespace.
virtual ~ArrayEvalImpl()
Virtual destructor.
Definition: array_eval.h:202
void set_tile(size_type i, const value_type &value)
Set tensor value.
Definition: dist_eval.h:146
const tile_type & tile() const
return ref to input tile
Definition: array_eval.h:113
TensorImpl_::trange_type trange_type
Tiled range type for this object.
Definition: dist_eval.h:47
ArrayEvalImpl(const array_type &array, World &world, const trange_type &trange, const shape_type &shape, const std::shared_ptr< pmap_interface > &pmap, const Permutation &perm, const op_type &op)
Construct with full array range.
Definition: array_eval.h:173
unsigned int rank() const
Rank accessor.
Definition: range.h:542
LazyArrayTile_ & operator=(const LazyArrayTile_ &other)
Assignment operator.
Definition: array_eval.h:80
ArrayEvalImpl(const array_type &array, World &world, const trange_type &trange, const shape_type &shape, const std::shared_ptr< pmap_interface > &pmap, const Permutation &perm, const op_type &op, const std::vector< std::size_t > &lower_bound, const std::vector< std::size_t > &upper_bound)
Constructor with sub-block range.
Definition: array_eval.h:191
impl_type::value_type value_type
Tile type.
Definition: dist_array.h:64
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
Forward declarations.
Definition: clone.h:32
#define TA_ASSERT(a)
Definition: error.h:107
bool is_zero(const Index &i) const
Query for a zero tile.
Definition: tensor_impl.h:141
LazyArrayTile(const tile_type &tile, const std::shared_ptr< op_type > &op, const bool consume)
Construct from tile and operation.
Definition: array_eval.h:73
bool is_local(const Index &i) const
Check if the tile at index i is stored locally.
Definition: dist_array.h:702
op_type::result_type eval_type
Definition: array_eval.h:46
virtual void discard_tile(size_type) const
Discard a tile that is not needed.
Definition: array_eval.h:242
TensorImpl_::range_type range_type
Range type this tensor.
Definition: dist_eval.h:48
Tile tile_type
The input tile type.
Definition: array_eval.h:47
Array array_type
The array type.
Definition: array_eval.h:146
Permutation of a sequence of objects indexed by base-0 indices.
Definition: permutation.h:119
Range that references a subblock of another range.
Definition: block_range.h:34
ArrayEvalImpl< Array, Op, Policy > ArrayEvalImpl_
This object type.
Definition: array_eval.h:143
Distributed evaluator for TiledArray::Array objects.
Definition: array_eval.h:138
World & world() const
World accessor.
Definition: tensor_impl.h:169
LazyArrayTile(const LazyArrayTile_ &other)
Copy constructor.
Definition: array_eval.h:64
const range_type & tiles_range() const
Tiles range accessor.
Definition: tensor_impl.h:91
bool is_consumable() const
Query runtime consumable status.
Definition: array_eval.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
DistEvalImpl_::TensorImpl_ TensorImpl_
The base, base class type.
Definition: array_eval.h:145
An N-dimensional shallow copy wrapper for tile objects.
Definition: tile.h:80
void serialize(const Archive &)
Serialization (not implemented)
Definition: array_eval.h:119