unary_wrapper.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  * binary_interface.h
22  * Oct 6, 2013
23  *
24  */
25 
26 #ifndef TILEDARRAY_TILE_OP_UNARY_WRAPPER_H__INCLUDED
27 #define TILEDARRAY_TILE_OP_UNARY_WRAPPER_H__INCLUDED
28 
29 #include <TiledArray/permutation.h>
31 #include <TiledArray/zero_tensor.h>
32 
33 namespace TiledArray {
34 namespace detail {
35 
37 
82 template <typename Op>
83 class UnaryWrapper {
84  public:
86  typedef typename Op::argument_type argument_type;
87  typedef typename Op::result_type result_type;
88 
90  static constexpr bool is_consumable = Op::is_consumable;
91 
92  template <typename T>
93  static constexpr bool is_lazy_tile_v = is_lazy_tile<std::decay_t<T>>::value;
94 
95  template <typename T>
96  static constexpr bool is_array_tile_v = is_array_tile<std::decay_t<T>>::value;
97 
98  template <typename T>
99  static constexpr bool is_nonarray_lazy_tile_v =
100  is_lazy_tile_v<T> && !is_array_tile_v<T>;
101 
102  template <typename T>
103  using eval_t = typename eval_trait<std::decay_t<T>>::type;
104 
105  private:
106  Op op_;
107  BipartitePermutation perm_;
108 
109  public:
110  // Compiler generated functions
111  UnaryWrapper(const UnaryWrapper_&) = default;
113  ~UnaryWrapper() = default;
116 
117  UnaryWrapper(const Op& op, const BipartitePermutation& perm)
118  : op_(op), perm_(perm) {}
119 
120  UnaryWrapper(const Op& op) : op_(op), perm_() {}
121 
123 
125  const BipartitePermutation& permutation() const { return perm_; }
126 
128 
132  auto operator()(argument_type& arg) const {
133  return (perm_ ? op_(arg, perm_) : op_(arg));
134  }
135 
137 
141  auto operator()(const argument_type& arg) const {
142  return (perm_ ? op_(arg, perm_) : op_(arg));
143  }
144 
146 
153  template <typename A, std::enable_if_t<is_nonarray_lazy_tile_v<A>>* = nullptr>
154  auto operator()(A&& arg) const {
155  return (perm_ ? meta::invoke(op_, invoke_cast(std::forward<A>(arg)), perm_)
156  : meta::invoke(op_, invoke_cast(std::forward<A>(arg))));
157  }
158 
160 
166  template <typename A, std::enable_if_t<is_array_tile_v<A>>* = nullptr>
167  auto operator()(A&& arg) const {
168  auto cast_arg = invoke_cast(std::forward<A>(arg));
169  // TODO replace with generic lambda, replace cast_arg with
170  // std::move(cast_arg)
171  // NB using this generic lambda breaks TaskFn ...
172  // need to make TaskFn variadic and accepting callables, but this is
173  // a lot of MP
174  //
175  // auto op_consume = [this](auto&& arg) {
176  // return op_.consume(std::forward<decltype(arg)>(arg));
177  // };
178  auto op_consume = [this](eval_t<A>& arg) { return op_.consume(arg); };
179  return (perm_ ? meta::invoke(op_, std::move(cast_arg), perm_)
180  : (arg.is_consumable()
181  ? meta::invoke(op_consume, cast_arg)
182  : meta::invoke(op_, std::move(cast_arg))));
183  }
184 
186  template <typename A, std::enable_if_t<is_lazy_tile_v<A>>* = nullptr>
187  auto consume(A&& arg) const {
188  auto cast_arg = invoke_cast(std::forward<A>(arg));
189  // TODO replace with generic lambda, replace cast_arg with
190  // std::move(cast_arg)
191  // NB using this generic lambda breaks TaskFn ...
192  // need to make TaskFn variadic and accepting callables, but this is
193  // a lot of MP
194  //
195  // auto op_consume = [this](auto&& arg) {
196  // return op_.consume(std::forward<decltype(arg)>(arg));
197  // };
198  auto op_consume = [this](eval_t<A>& arg) { return op_.consume(arg); };
199  return (perm_ ? meta::invoke(op_, std::move(cast_arg), perm_)
200  : meta::invoke(op_consume, cast_arg));
201  }
202 
203  template <typename A, std::enable_if_t<!is_lazy_tile_v<A>>* = nullptr>
204  result_type consume(A&& arg) const {
205  static_assert(std::is_same<std::decay_t<A>, argument_type>::value,
206  "UnaryWrapper::consume(A&&): invalid argument type A");
207  return (perm_ ? op_(std::forward<A>(arg), perm_)
208  : op_.consume(std::forward<A>(arg)));
209  }
210 
211 }; // class UnaryWrapper
212 
213 } // namespace detail
214 } // namespace TiledArray
215 
216 #endif // TILEDARRAY_TILE_OP_UNARY_WRAPPER_H__INCLUDED
UnaryWrapper(const Op &op, const BipartitePermutation &perm)
::blas::Op Op
Definition: blas.h:46
const BipartitePermutation & permutation() const
Permutation accessor.
auto invoke_cast(Arg &&arg)
Definition: cast.h:176
typename eval_trait< std::decay_t< T > >::type eval_t
auto operator()(argument_type &arg) const
Apply operator to arg and possibly permute the result.
UnaryWrapper< Op > UnaryWrapper_
Definition: unary_wrapper.h:85
UnaryWrapper(const UnaryWrapper_ &)=default
static constexpr bool is_consumable
Boolean value that indicates the argument can always be consumed.
Definition: unary_wrapper.h:90
Op::argument_type argument_type
Argument type.
Definition: unary_wrapper.h:86
UnaryWrapper_ & operator=(const UnaryWrapper_ &)=default
static constexpr bool is_lazy_tile_v
Definition: unary_wrapper.h:93
auto invoke(Function &&fn, Args &&... args) -> typename std::enable_if< !or_reduce< false, madness::is_future< std::decay_t< Args >>::value... >::value, decltype(fn(args...))>::type
Definition: meta.h:52
static constexpr bool is_nonarray_lazy_tile_v
Definition: unary_wrapper.h:99
auto operator()(const argument_type &arg) const
Apply operator to arg and possibly permute the result.
Unary tile operation wrapper.
Definition: unary_wrapper.h:83
auto operator()(A &&arg) const
Evaluate a lazy tile.
result_type consume(A &&arg) const
UnaryWrapper_ & operator=(UnaryWrapper_ &&)=default
Detect tiles used by ArrayEvalImpl.
Definition: type_traits.h:670
auto consume(A &&arg) const
Consume a lazy tile.
static constexpr bool is_array_tile_v
Definition: unary_wrapper.h:96
Determine the object type used in the evaluation of tensor expressions.
Definition: type_traits.h:580
UnaryWrapper(UnaryWrapper_ &&)=default
Permutation of a bipartite set.
Definition: permutation.h:610
Detect lazy evaluation tiles.
Definition: type_traits.h:591
Op::result_type result_type
The result tile type.
Definition: unary_wrapper.h:87