TiledArray  0.7.0
subt.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  * subt.h
22  * May 8, 2013
23  *
24  */
25 
26 #ifndef TILEDARRAY_TILE_OP_SUBT_H__INCLUDED
27 #define TILEDARRAY_TILE_OP_SUBT_H__INCLUDED
28 
30 #include "../tile_interface/scale.h"
31 #include "../tile_interface/permute.h"
32 #include "../tile_interface/clone.h"
33 #include <TiledArray/zero_tensor.h>
34 
35 namespace TiledArray {
36  namespace detail {
37 
39 
51  template <typename Result, typename Left, typename Right,
52  bool LeftConsumable, bool RightConsumable>
53  class Subt {
54  public:
55 
57  typedef Left left_type;
58  typedef Right right_type;
59  typedef Result result_type;
60 
62  static constexpr bool left_is_consumable =
63  LeftConsumable && std::is_same<result_type, left_type>::value;
65  static constexpr bool right_is_consumable =
66  RightConsumable && std::is_same<result_type, right_type>::value;
67 
68  private:
69 
70  // Permuting tile evaluation function
71  // These operations cannot consume the argument tile since this operation
72  // requires temporary storage space.
73 
74  static result_type eval(const left_type& first, const right_type& second,
75  const Permutation& perm)
76  {
77  using TiledArray::subt;
78  return subt(first, second, perm);
79  }
80 
81  static result_type eval(ZeroTensor, const right_type& second,
82  const Permutation& perm)
83  {
84  using TiledArray::neg;
85  return neg(second, perm);
86  }
87 
88  static result_type eval(const left_type& first, ZeroTensor,
89  const Permutation& perm)
90  {
91  using TiledArray::permute;
92  return permute(first, perm);
93  }
94 
95  // Non-permuting tile evaluation functions
96  // The compiler will select the correct functions based on the
97  // consumability of the arguments.
98 
99  template <bool LC, bool RC,
100  typename std::enable_if<!(LC || RC)>::type* = nullptr>
101  static result_type eval(const left_type& first, const right_type& second) {
102  using TiledArray::subt;
103  return subt(first, second);
104  }
105 
106  template <bool LC, bool RC,
107  typename std::enable_if<LC>::type* = nullptr>
108  static result_type eval(left_type& first, const right_type& second) {
109  using TiledArray::subt_to;
110  return subt_to(first, second);
111  }
112 
113  template <bool LC, bool RC,
114  typename std::enable_if<!LC && RC>::type* = nullptr>
115  static result_type eval(const left_type& first, right_type& second) {
116  using TiledArray::subt_to;
117  return subt_to(second, first, -1);
118  }
119 
120  template <bool LC, bool RC,
121  typename std::enable_if<!RC>::type* = nullptr>
122  static result_type eval(ZeroTensor, const right_type& second) {
123  using TiledArray::neg;
124  return neg(second);
125  }
126 
127  template <bool LC, bool RC,
128  typename std::enable_if<RC>::type* = nullptr>
129  static result_type eval(ZeroTensor, right_type& second) {
130  using TiledArray::neg_to;
131  return neg_to(second);
132  }
133 
134  template <bool LC, bool RC,
135  typename std::enable_if<!LC>::type* = nullptr>
136  static result_type eval(const left_type& first, ZeroTensor) {
138  return clone(first);
139  }
140 
141  template <bool LC, bool RC,
142  typename std::enable_if<LC>::type* = nullptr>
143  static result_type eval(left_type& first, ZeroTensor) {
144  return first;
145  }
146 
147  public:
148 
150 
160  template <typename L, typename R>
161  result_type operator()(L&& left, R&& right, const Permutation& perm) const {
162  return eval(std::forward<L>(left), std::forward<R>(right), perm);
163  }
164 
166 
175  template <typename L, typename R>
176  result_type operator()(L&& left, R&& right) const {
177  return Subt_::template eval<left_is_consumable, right_is_consumable>(
178  std::forward<L>(left), std::forward<R>(right));
179  }
180 
182 
190  template <typename R>
191  result_type consume_left(left_type& left, R&& right) const {
192  constexpr bool can_consume_left =
194  std::is_same<result_type, left_type>::value;
195  constexpr bool can_consume_right = right_is_consumable &&
196  ! (std::is_const<R>::value || can_consume_left);
197  return Subt_::template eval<can_consume_left, can_consume_right>(left,
198  std::forward<R>(right));
199  }
200 
202 
210  template <typename L>
211  result_type consume_right(L&& left, right_type& right) const {
212  constexpr bool can_consume_right =
214  std::is_same<result_type, right_type>::value;
215  constexpr bool can_consume_left = left_is_consumable &&
216  ! (std::is_const<L>::value || can_consume_right);
217  return Subt_::template eval<can_consume_left, can_consume_right>(
218  std::forward<L>(left), right);
219  }
220 
221  }; // class Subt
222 
224 
238  template <typename Result, typename Left, typename Right, typename Scalar,
239  bool LeftConsumable, bool RightConsumable>
240  class ScalSubt {
241  public:
242 
243  typedef ScalSubt<Result, Left, Right, Scalar, LeftConsumable,
244  RightConsumable> ScalSubt_;
245  typedef Left left_type;
246  typedef Right right_type;
247  typedef Scalar scalar_type;
248  typedef Result result_type;
249 
250  static constexpr bool left_is_consumable =
251  LeftConsumable && std::is_same<result_type, left_type>::value;
252  static constexpr bool right_is_consumable =
253  RightConsumable && std::is_same<result_type, right_type>::value;
254 
255  private:
256 
257  scalar_type factor_;
258 
259  // Permuting tile evaluation function
260  // These operations cannot consume the argument tile since this operation
261  // requires temporary storage space.
262 
263  result_type eval(const left_type& first, const right_type& second,
264  const Permutation& perm) const
265  {
266  using TiledArray::subt;
267  return subt(first, second, factor_, perm);
268  }
269 
270  result_type eval(ZeroTensor, const right_type& second,
271  const Permutation& perm) const
272  {
273  using TiledArray::scale;
274  return scale(second, -factor_, perm);
275  }
276 
277  result_type eval(const left_type& first, ZeroTensor,
278  const Permutation& perm) const
279  {
280  using TiledArray::scale;
281  return scale(first, factor_, perm);
282  }
283 
284  // Non-permuting tile evaluation functions
285  // The compiler will select the correct functions based on the
286  // consumability of the arguments.
287 
288  template <bool LC, bool RC,
289  typename std::enable_if<!(LC || RC)>::type* = nullptr>
290  result_type eval(const left_type& first, const right_type& second) const {
291  using TiledArray::subt;
292  return subt(first, second, factor_);
293  }
294 
295  template <bool LC, bool RC,
296  typename std::enable_if<LC>::type* = nullptr>
297  result_type eval(left_type& first, const right_type& second) const {
298  using TiledArray::subt_to;
299  return subt_to(first, second, factor_);
300  }
301 
302  template <bool LC, bool RC,
303  typename std::enable_if<!LC && RC>::type* = nullptr>
304  result_type eval(const left_type& first, right_type& second) const {
305  using TiledArray::subt_to;
306  return subt_to(second, first, -factor_);
307  }
308 
309  template <bool LC, bool RC,
310  typename std::enable_if<!RC>::type* = nullptr>
311  result_type eval(ZeroTensor, const right_type& second) const {
312  using TiledArray::scale;
313  return scale(second, -factor_);
314  }
315 
316  template <bool LC, bool RC,
317  typename std::enable_if<RC>::type* = nullptr>
318  result_type eval(ZeroTensor, right_type& second) const {
319  using TiledArray::scale_to;
320  return scale_to(second, -factor_);
321  }
322 
323  template <bool LC, bool RC,
324  typename std::enable_if<!LC>::type* = nullptr>
325  result_type eval(const left_type& first, ZeroTensor) const {
326  using TiledArray::scale;
327  return scale(first, factor_);
328  }
329 
330  template <bool LC, bool RC,
331  typename std::enable_if<LC>::type* = nullptr>
332  result_type eval(left_type& first, ZeroTensor) const {
333  using TiledArray::scale_to;
334  return scale_to(first, factor_);
335  }
336 
337  public:
338 
339  // Compiler generated functions
340  ScalSubt(const ScalSubt_&) = default;
341  ScalSubt(ScalSubt_&&) = default;
342  ~ScalSubt() = default;
343  ScalSubt_& operator=(const ScalSubt_&) = default;
344  ScalSubt_& operator=(ScalSubt_&&) = default;
345 
347 
349  explicit ScalSubt(const Scalar factor) : factor_(factor) { }
350 
352 
362  template <typename L, typename R>
364  operator()(L&& left, R&& right, const Permutation& perm) const {
365  return eval(std::forward<L>(left), std::forward<R>(right), perm);
366  }
367 
369 
378  template <typename L, typename R>
379  result_type operator()(L&& left, R&& right) const {
380  return ScalSubt_::template eval<left_is_consumable, right_is_consumable>(
381  std::forward<L>(left), std::forward<R>(right));
382  }
383 
385 
393  template <typename R>
394  result_type consume_left(left_type& left, R&& right) const {
395  constexpr bool can_consume_left =
397  std::is_same<result_type, left_type>::value;
398  constexpr bool can_consume_right = right_is_consumable &&
399  ! (std::is_const<R>::value || can_consume_left);
400  return ScalSubt_::template eval<can_consume_left, can_consume_right>(
401  left, std::forward<R>(right));
402  }
403 
405 
413  template <typename L>
414  result_type consume_right(L&& left, right_type& right) const {
415  constexpr bool can_consume_right =
417  std::is_same<result_type, right_type>::value;
418  constexpr bool can_consume_left = left_is_consumable &&
419  ! (std::is_const<L>::value || can_consume_right);
420  return ScalSubt_::template eval<can_consume_left, can_consume_right>(
421  std::forward<L>(left), right);
422  }
423 
424  }; // class ScalSubt
425 
426  } // namespace detail
427 } // namespace TiledArray
428 
429 #endif // TILEDARRAY_TILE_OP_SUBT_H__INCLUDED
Result result_type
The result tile type.
Definition: subt.h:248
static constexpr bool left_is_consumable
Definition: subt.h:250
decltype(auto) subt(const Tile< Left > &left, const Tile< Right > &right)
Subtract tile arguments.
Definition: tile.h:489
Tile subtraction operation.
Definition: subt.h:53
void permute(InputOp &&input_op, OutputOp &&output_op, Result &result, const Permutation &perm, const Arg0 &arg0, const Args &... args)
Construct a permuted tensor copy.
Definition: permute.h:122
result_type operator()(L &&left, R &&right) const
Scale-and-subtract operator.
Definition: subt.h:379
Tile< Result > & scale_to(Tile< Result > &result, const Scalar factor)
Scale to the result tile.
Definition: tile.h:725
result_type consume_left(left_type &left, R &&right) const
Subtract right to left.
Definition: subt.h:191
result_type consume_left(left_type &left, R &&right) const
Subtract right to left and scale the result.
Definition: subt.h:394
void scale(DistArray< Tile, Policy > &a, typename DistArray< Tile, Policy >::element_type scaling_factor)
Definition: utils.h:108
Scalar scalar_type
Scaling factor type.
Definition: subt.h:247
result_type consume_right(L &&left, right_type &right) const
Subtract left to right and scale the result.
Definition: subt.h:414
Place-holder object for a zero tensor.
Definition: zero_tensor.h:32
ScalSubt_ & operator=(const ScalSubt_ &)=default
static constexpr bool right_is_consumable
Definition: subt.h:252
Tile scale-subtraction operation.
Definition: subt.h:240
result_type operator()(L &&left, R &&right) const
Subtract operator.
Definition: subt.h:176
static constexpr bool right_is_consumable
Indicates whether it is possible to consume the right tile.
Definition: subt.h:65
Left left_type
Left-hand argument base type.
Definition: subt.h:57
DistArray< Tile, Policy > clone(const DistArray< Tile, Policy > &arg)
Create a deep copy of an array.
Definition: clone.h:43
ScalSubt< Result, Left, Right, Scalar, LeftConsumable, RightConsumable > ScalSubt_
This class type.
Definition: subt.h:244
static constexpr bool left_is_consumable
Indicates whether it is possible to consume the left tile.
Definition: subt.h:62
Subt< Result, Left, Right, LeftConsumable, RightConsumable > Subt_
Definition: subt.h:56
Result result_type
The result tile type.
Definition: subt.h:59
ScalSubt(const Scalar factor)
Constructor.
Definition: subt.h:349
Right right_type
Right-hand argument base type.
Definition: subt.h:58
Tile< Result > & neg_to(Tile< Result > &result)
Multiplication constant scalar to a tile.
Definition: tile.h:758
result_type operator()(L &&left, R &&right, const Permutation &perm) const
Scale-subtract-and-permute operator.
Definition: subt.h:364
Consumable tile type trait.
Definition: type_traits.h:406
Left left_type
Left-hand argument base type.
Definition: subt.h:245
decltype(auto) neg(const Tile< Arg > &arg)
Negate the tile argument.
Definition: tile.h:739
ScalSubt(const ScalSubt_ &)=default
Right right_type
Right-hand argument base type.
Definition: subt.h:246
Permutation of a sequence of objects indexed by base-0 indices.
Definition: permutation.h:119
TiledArray::Range permute(const TiledArray::Range &r, const Perm &p)
Definition: btas.h:285
Tile< Result > & subt_to(Tile< Result > &result, const Tile< Arg > &arg)
Subtract from the result tile.
Definition: tile.h:568
result_type operator()(L &&left, R &&right, const Permutation &perm) const
Subtract-and-permute operator.
Definition: subt.h:161
Create a deep copy of a tile.
Definition: clone.h:138
result_type consume_right(L &&left, right_type &right) const
Subtract left to right.
Definition: subt.h:211