TiledArray  0.7.0
binary_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_BINARY_EVAL_H__INCLUDED
21 #define TILEDARRAY_DIST_EVAL_BINARY_EVAL_H__INCLUDED
22 
24 #include <TiledArray/zero_tensor.h>
25 
26 namespace TiledArray {
27  namespace detail {
28 
30 
37  template <typename Left, typename Right, typename Op, typename Policy>
39  public DistEvalImpl<typename Op::result_type, Policy>,
40  public std::enable_shared_from_this<BinaryEvalImpl<Left, Right, Op, Policy> >
41  {
42  public:
46  typedef Left left_type;
47  typedef Right right_type;
55  typedef Op op_type;
56 
57  using std::enable_shared_from_this<BinaryEvalImpl_>::shared_from_this;
58 
59  private:
60 
61  left_type left_;
62  right_type right_;
63  op_type op_;
64 
65  public:
66 
68 
77  BinaryEvalImpl(const left_type& left, const right_type& right,
78  World& world, const trange_type& trange, const shape_type& shape,
79  const std::shared_ptr<pmap_interface>& pmap, const Permutation& perm,
80  const op_type& op) :
82  left_(left), right_(right), op_(op)
83  {
84  TA_ASSERT(left.trange() == right.trange());
85  }
86 
87  virtual ~BinaryEvalImpl() { }
88 
90 
95  virtual Future<value_type> get_tile(size_type i) const {
98 
99 
100  const size_type source_index = DistEvalImpl_::perm_index_to_source(i);
101  const ProcessID source = left_.owner(source_index); // Left and right
102  // should have the same owner
103 
104  const madness::DistributedID key(DistEvalImpl_::id(), i);
105  return TensorImpl_::world().gop.template recv<value_type>(source, key);
106  }
107 
109 
113  virtual void discard_tile(size_type i) const { get_tile(i); }
114 
115  private:
116 
118 
122  template <typename L, typename R>
123  void eval_tile(const size_type i, L left, R right) {
124  DistEvalImpl_::set_tile(i, op_(left, right));
125  }
126 
128 
134  virtual int internal_eval() {
135 
136  // Evaluate child tensors
137  left_.eval();
138  right_.eval();
139 
140  // Task function argument types
141  typedef typename std::conditional<op_type::left_is_consumable,
142  typename left_type::value_type,
143  const typename left_type::value_type>::type &
144  left_argument_type;
145  typedef typename std::conditional<op_type::right_is_consumable,
146  typename right_type::value_type,
147  const typename right_type::value_type>::type &
148  right_argument_type;
149 
150  size_type task_count = 0ul;
151 
152  // Construct local iterator
153  TA_ASSERT(left_.pmap() == right_.pmap());
154  std::shared_ptr<BinaryEvalImpl_> self = shared_from_this();
155  typename pmap_interface::const_iterator it = left_.pmap()->begin();
156  const typename pmap_interface::const_iterator end = left_.pmap()->end();
157 
158  if(left_.is_dense() && right_.is_dense() && TensorImpl_::is_dense()) {
159  // Evaluate tiles where both arguments and the result are dense
160  for(; it != end; ++it) {
161  // Get tile indices
162  const size_type source_index = *it;
163  const size_type target_index = DistEvalImpl_::perm_index_to_target(source_index);
164 
165  // Schedule tile evaluation task
166  TensorImpl_::world().taskq.add(self,
167  & BinaryEvalImpl_::template eval_tile<left_argument_type, right_argument_type>,
168  target_index, left_.get(source_index), right_.get(source_index));
169 
170  ++task_count;
171  }
172  } else {
173  // Evaluate tiles where the result or one of the arguments is sparse
174  for(; it != end; ++it) {
175  // Get tile indices
176  const size_type index = *it;
177  const size_type target_index = DistEvalImpl_::perm_index_to_target(index);
178 
179  if(! TensorImpl_::is_zero(target_index)) {
180  // Schedule tile evaluation task
181  if(left_.is_zero(index)) {
182  TensorImpl_::world().taskq.add(self,
183  & BinaryEvalImpl_::template eval_tile<const ZeroTensor, right_argument_type>,
184  target_index, ZeroTensor(), right_.get(index));
185  } else if(right_.is_zero(index)) {
186  TensorImpl_::world().taskq.add(self,
187  & BinaryEvalImpl_::template eval_tile<left_argument_type, const ZeroTensor>,
188  target_index, left_.get(index), ZeroTensor());
189  } else {
190  TensorImpl_::world().taskq.add(self,
191  & BinaryEvalImpl_::template eval_tile<left_argument_type, right_argument_type>,
192  target_index, left_.get(index), right_.get(index));
193  }
194 
195  ++task_count;
196  } else {
197  // Cleanup unused tiles
198  if(! left_.is_zero(index))
199  left_.discard(index);
200  if(! right_.is_zero(index))
201  right_.discard(index);
202  }
203  }
204  }
205 
206  // Wait for child tensors to be evaluated, and process tasks while waiting.
207  left_.wait();
208  right_.wait();
209 
210  return task_count;
211  }
212 
213  }; // class BinaryEvalImpl
214 
215  } // namespace detail
216 } // namespace TiledArray
217 
218 #endif // TILEDARRAY_DIST_EVAL_BINARY_EVAL_H__INCLUDED
DistEvalImpl_::size_type size_type
Size type.
Definition: binary_eval.h:48
TensorImpl_::size_type size_type
Size type.
Definition: dist_eval.h:46
DistEvalImpl_::shape_type shape_type
Shape type.
Definition: binary_eval.h:50
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
bool is_dense() const
Query the density of the tensor.
Definition: tensor_impl.h:150
Distributed evaluator implementation object.
Definition: dist_eval.h:40
BinaryEvalImpl(const left_type &left, const right_type &right, 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 a binary evaluator.
Definition: binary_eval.h:77
TensorImpl_::pmap_interface pmap_interface
process map interface type
Definition: dist_eval.h:50
Tensor implementation and base for other tensor implementation objects.
Definition: tensor_impl.h:39
DistEvalImpl_::TensorImpl_ TensorImpl_
The base, base class type.
Definition: binary_eval.h:45
void set_tile(size_type i, const value_type &value)
Set tensor value.
Definition: dist_eval.h:146
TensorImpl_::trange_type trange_type
Tiled range type for this object.
Definition: dist_eval.h:47
Right right_type
The right-hand argument type.
Definition: binary_eval.h:47
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
BinaryEvalImpl< Left, Right, Op, Policy > BinaryEvalImpl_
This object type.
Definition: binary_eval.h:43
TensorImpl_::shape_type shape_type
Shape type.
Definition: dist_eval.h:49
bool is_local(const Index &i) const
Query for a locally owned tile.
Definition: tensor_impl.h:128
Op op_type
Tile evaluation operator type.
Definition: binary_eval.h:55
#define TA_ASSERT(a)
Definition: error.h:107
const madness::uniqueidT & id() const
Unique object id accessor.
Definition: dist_eval.h:125
bool is_zero(const Index &i) const
Query for a zero tile.
Definition: tensor_impl.h:141
Left left_type
The left-hand argument type.
Definition: binary_eval.h:46
TensorImpl_::range_type range_type
Range type this tensor.
Definition: dist_eval.h:48
DistEvalImpl_::range_type range_type
Range type.
Definition: binary_eval.h:49
eval_trait< value_type >::type eval_type
Tile evaluation type.
Definition: dist_eval.h:52
Permutation of a sequence of objects indexed by base-0 indices.
Definition: permutation.h:119
DistEvalImpl_::pmap_interface pmap_interface
Process map interface type.
Definition: binary_eval.h:51
Binary, distributed tensor evaluator.
Definition: binary_eval.h:38
DistEvalImpl< typename Op::result_type, Policy > DistEvalImpl_
The base class type.
Definition: binary_eval.h:44
World & world() const
World accessor.
Definition: tensor_impl.h:169
DistEvalImpl_::eval_type eval_type
Tile evaluation type.
Definition: binary_eval.h:54
virtual void discard_tile(size_type i) const
Discard a tile that is not needed.
Definition: binary_eval.h:113
DistEvalImpl_::value_type value_type
Tile type.
Definition: binary_eval.h:53
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_::trange_type trange_type
Tiled range type.
Definition: binary_eval.h:52
An N-dimensional shallow copy wrapper for tile objects.
Definition: tile.h:80
virtual Future< value_type > get_tile(size_type i) const
Get tile at index i.
Definition: binary_eval.h:95