Panzer  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Panzer_ExprEval_impl.hpp
Go to the documentation of this file.
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Panzer: A partial differential equation assembly
5 // engine for strongly coupled complex multiphysics systems
6 // Copyright (2011) Sandia Corporation
7 //
8 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact Roger P. Pawlowski (rppawlo@sandia.gov) and
39 // Eric C. Cyr (eccyr@sandia.gov)
40 // ***********************************************************************
41 // @HEADER
42 
43 #ifndef PANZER_EXPR_EVAL_IMPL_HPP
44 #define PANZER_EXPR_EVAL_IMPL_HPP
45 
46 #include <Panzer_ExprEval.hpp>
47 
48 #include <algorithm>
49 #include <cmath>
50 
51 namespace panzer
52 {
53 namespace Expr
54 {
55 
56 struct ScalarTernary {
57  template <typename T>
58  static KOKKOS_FORCEINLINE_FUNCTION
59  T apply(bool cond, T const& left, T const& right) {
60  return cond ? left : right;
61  }
62 };
63 
64 struct ScalarOr {
65  static KOKKOS_FORCEINLINE_FUNCTION
66  bool apply(bool left, bool right) {
67  return left || right;
68  }
69 };
70 
71 struct ScalarAnd {
72  static KOKKOS_FORCEINLINE_FUNCTION
73  bool apply(bool left, bool right) {
74  return left && right;
75  }
76 };
77 
78 struct ScalarGT {
79  template <typename T>
80  static KOKKOS_FORCEINLINE_FUNCTION
81  bool apply(T const& left, T const& right) {
82  return left > right;
83  }
84 };
85 
86 struct ScalarLT {
87  template <typename T>
88  static KOKKOS_FORCEINLINE_FUNCTION
89  bool apply(T const& left, T const& right) {
90  return left < right;
91  }
92 };
93 
94 struct ScalarGEQ {
95  template <typename T>
96  static KOKKOS_FORCEINLINE_FUNCTION
97  bool apply(T const& left, T const& right) {
98  return left >= right;
99  }
100 };
101 
102 struct ScalarLEQ {
103  template <typename T>
104  static KOKKOS_FORCEINLINE_FUNCTION
105  bool apply(T const& left, T const& right) {
106  return left <= right;
107  }
108 };
109 
110 struct ScalarEQ {
111  template <typename T>
112  static KOKKOS_FORCEINLINE_FUNCTION
113  bool apply(T const& left, T const& right) {
114  return left == right;
115  }
116 };
117 
118 struct ScalarAdd {
119  template <typename T>
120  static KOKKOS_FORCEINLINE_FUNCTION
121  T apply(T const& left, T const& right) {
122  return left + right;
123  }
124 };
125 
126 struct ScalarSub {
127  template <typename T>
128  static KOKKOS_FORCEINLINE_FUNCTION
129  T apply(T const& left, T const& right) {
130  return left - right;
131  }
132 };
133 
134 struct ScalarMul {
135  template <typename T>
136  static KOKKOS_FORCEINLINE_FUNCTION
137  T apply(T const& left, T const& right) {
138  return left * right;
139  }
140 };
141 
142 struct ScalarDiv {
143  template <typename T>
144  static KOKKOS_FORCEINLINE_FUNCTION
145  T apply(T const& left, T const& right) {
146  return left / right;
147  }
148 };
149 
150 struct ScalarPow {
151  template <typename T>
152  static KOKKOS_FORCEINLINE_FUNCTION
153  T apply(T const& left, T const& right) {
154  using std::pow;
155  return pow(left, right);
156  }
157 };
158 
159 struct ScalarNeg {
160  template <typename T>
161  static KOKKOS_FORCEINLINE_FUNCTION
162  T apply(T const& right) {
163  return -right;
164  }
165 };
166 
167 // TODO: replace this with .access() after next Kokkos release
168 template <typename Indexed, size_t IterationRank, size_t IndexedRank = Indexed::rank>
169 struct Indexer;
170 
171 template <typename ViewType>
172 struct Indexer<ViewType, 1, 0> {
173  template <typename Integral>
174  static KOKKOS_FORCEINLINE_FUNCTION
175  typename ViewType::reference_type index(ViewType const& x, Integral) { return x(); }
176 };
177 
178 template <typename ViewType>
179 struct Indexer<ViewType, 1, 1> {
180  template <typename Integral>
181  static KOKKOS_FORCEINLINE_FUNCTION
182  typename ViewType::reference_type index(ViewType const& x, Integral i) { return x(i); }
183 };
184 
185 template <typename ViewType>
186 struct Indexer<ViewType, 2, 0> {
187  template <typename Integral>
188  static KOKKOS_FORCEINLINE_FUNCTION
189  typename ViewType::reference_type index(ViewType const& x, Integral, Integral) { return x(); }
190 };
191 
192 template <typename ViewType>
193 struct Indexer<ViewType, 2, 1> {
194  template <typename Integral>
195  static KOKKOS_FORCEINLINE_FUNCTION
196  typename ViewType::reference_type index(ViewType const& x, Integral i, Integral) { return x(i); }
197 };
198 
199 template <typename ViewType>
200 struct Indexer<ViewType, 2, 2> {
201  template <typename Integral>
202  static KOKKOS_FORCEINLINE_FUNCTION
203  typename ViewType::reference_type index(ViewType const& x, Integral i, Integral j) { return x(i, j); }
204 };
205 
206 //TODO: just use std::max once C++14 is the Trilinos standard (which makes std::max constexpr)
207 template <typename T, typename ... TS>
208 struct MaxRank;
209 
210 template <typename T>
211 struct MaxRank<T> {
212  static constexpr size_t value = T::rank;
213 };
214 
215 template <typename T, typename ... TS>
216 struct MaxRank {
217  static constexpr size_t left_value = T::rank;
218  static constexpr size_t right_value = MaxRank<TS ...>::value;
219  static constexpr size_t value = left_value > right_value ? left_value : right_value;
220 };
221 
222 template <typename A, typename B>
223 struct ResultType {
224  static constexpr size_t a_rank = A::rank;
225  static constexpr size_t b_rank = B::rank;
226  using biggest_type = typename std::conditional<(b_rank > a_rank), B, A>::type;
229 };
230 
231 template <typename C, typename A, typename B>
233  static constexpr size_t a_rank = A::rank;
234  static constexpr size_t b_rank = B::rank;
235  static constexpr size_t c_rank = C::rank;
236  using biggest_ab_type = typename std::conditional<(b_rank > a_rank), B, A>::type;
237  using biggest_type = typename std::conditional<(c_rank > biggest_ab_type::rank), C, biggest_ab_type>::type;
240 };
241 
242 template <typename Op, typename Result, typename Left, typename Right, size_t Rank = Result::rank>
244 
245 template <typename Op, typename Result, typename Left, typename Right>
246 struct BinaryFunctor<Op, Result, Left, Right, 0> {
248  using execution_space = typename Result::execution_space;
250  Left left_;
251  Right right_;
252  KOKKOS_INLINE_FUNCTION
253  void operator()(typename execution_space::size_type) const {
254  result_() = Op::apply(left_(), right_());
255  }
256  BinaryFunctor(std::string const& name, Teuchos::any& result, Teuchos::any& left, Teuchos::any& right) {
257  left_ = Teuchos::any_cast<Left>(left);
258  right_ = Teuchos::any_cast<Right>(right);
259  result_ = NonConstResult(Kokkos::ViewAllocateWithoutInitializing(name));
260  Kokkos::parallel_for(name, Kokkos::RangePolicy<execution_space>(0, 1), *this);
261  result = Result(result_);
262  }
263 };
264 
265 template <typename Op, typename Result, typename Left, typename Right>
266 struct BinaryFunctor<Op, Result, Left, Right, 1> {
268  using execution_space = typename Result::execution_space;
270  Left left_;
271  Right right_;
272  KOKKOS_INLINE_FUNCTION
273  void operator()(typename execution_space::size_type i) const {
274  result_(i) =
275  Op::apply(
276  Indexer<Left, 1>::index(left_, i),
277  Indexer<Right, 1>::index(right_, i));
278  }
279  BinaryFunctor(std::string const& name, Teuchos::any& result, Teuchos::any& left, Teuchos::any& right) {
280  left_ = Teuchos::any_cast<Left>(left);
281  right_ = Teuchos::any_cast<Right>(right);
282  auto extent_0 = std::max(left_.extent(0), right_.extent(0));
283  result_ = NonConstResult(Kokkos::ViewAllocateWithoutInitializing(name), extent_0);
284  Kokkos::parallel_for(name, Kokkos::RangePolicy<execution_space>(0, extent_0), *this);
285  result = Result{result_};
286  }
287 };
288 
289 template <typename Op, typename Result, typename Left, typename Right>
290 struct BinaryFunctor<Op, Result, Left, Right, 2> {
292  using execution_space = typename Result::execution_space;
294  Left left_;
295  Right right_;
296  KOKKOS_INLINE_FUNCTION
297  void operator()(typename execution_space::size_type i, typename execution_space::size_type j) const {
298  result_(i, j) =
299  Op::apply(
300  Indexer<Left, 2>::index(left_, i, j),
301  Indexer<Right, 2>::index(right_, i, j));
302  }
303  BinaryFunctor(std::string const& name, Teuchos::any& result, Teuchos::any& left, Teuchos::any& right) {
304  left_ = Teuchos::any_cast<Left>(left);
305  right_ = Teuchos::any_cast<Right>(right);
306  auto extent_0 = std::max(left_.extent(0), right_.extent(0));
307  auto extent_1 = std::max(left_.extent(1), right_.extent(1));
308  result_ = NonConstResult(Kokkos::ViewAllocateWithoutInitializing(name), extent_0, extent_1);
309  using policy_type = Kokkos::MDRangePolicy<execution_space, Kokkos::Rank<2>>;
310  Kokkos::parallel_for(name, policy_type({0, 0}, {extent_0, extent_1}), *this);
311  result = Result{result_};
312  }
313 };
314 
315 template <typename Cond, typename Left, typename Right, size_t Rank = MaxRank<Cond, Left, Right>::value>
317 
318 template <typename Cond, typename Left, typename Right>
319 struct TernaryFunctor<Cond, Left, Right, 1> {
322  using execution_space = typename Result::execution_space;
324  Cond cond_;
325  Left left_;
326  Right right_;
327  KOKKOS_INLINE_FUNCTION
328  void operator()(typename execution_space::size_type i) const {
329  result_(i) =
330  Indexer<Cond, 1>::index(cond_, i) ?
331  Indexer<Left, 1>::index(left_, i) :
332  Indexer<Right, 1>::index(right_, i);
333  }
334  TernaryFunctor(std::string const& name, Teuchos::any& result, Teuchos::any& cond, Teuchos::any& left, Teuchos::any& right) {
335  cond_ = Teuchos::any_cast<Cond>(cond);
336  left_ = Teuchos::any_cast<Left>(left);
337  right_ = Teuchos::any_cast<Right>(right);
338  auto extent_0 =
339  std::max(cond_.extent(0),
340  std::max(left_.extent(0), right_.extent(0)));
341  result_ = NonConstResult(Kokkos::ViewAllocateWithoutInitializing(name), extent_0);
342  Kokkos::parallel_for(name, Kokkos::RangePolicy<execution_space>(0, extent_0), *this);
343  result = Result{result_};
344  }
345 };
346 
347 template <typename Cond, typename Left, typename Right>
348 struct TernaryFunctor<Cond, Left, Right, 2> {
351  using execution_space = typename Result::execution_space;
353  Cond cond_;
354  Left left_;
355  Right right_;
356  KOKKOS_INLINE_FUNCTION
357  void operator()(typename execution_space::size_type i, typename execution_space::size_type j) const {
358  result_(i, j) =
359  Indexer<Cond, 2>::index(cond_, i, j) ?
360  Indexer<Left, 2>::index(left_, i, j) :
361  Indexer<Right, 2>::index(right_, i, j);
362  }
363  TernaryFunctor(std::string const& name, Teuchos::any& result, Teuchos::any& cond, Teuchos::any& left, Teuchos::any& right) {
364  cond_ = Teuchos::any_cast<Cond>(cond);
365  left_ = Teuchos::any_cast<Left>(left);
366  right_ = Teuchos::any_cast<Right>(right);
367  auto extent_0 =
368  std::max(cond_.extent(0),
369  std::max(left_.extent(0), right_.extent(0)));
370  auto extent_1 =
371  std::max(cond_.extent(1),
372  std::max(left_.extent(1), right_.extent(1)));
373  result_ = NonConstResult(Kokkos::ViewAllocateWithoutInitializing(name), extent_0, extent_1);
374  using policy_type = Kokkos::MDRangePolicy<execution_space, Kokkos::Rank<2>>;
375  Kokkos::parallel_for(name, policy_type({0, 0}, {extent_0, extent_1}), *this);
376  result = Result{result_};
377  }
378 };
379 
380 template <typename DT, typename ... VP>
382  : EvalBase()
383 {
384 }
385 
386 template <typename DT, typename ... VP>
387 void Eval<DT, VP ...>::set(std::string const& name, bool value) {
388  single_bool_view_type view{Kokkos::ViewAllocateWithoutInitializing{name}};
389  auto host_view = Kokkos::create_mirror_view(view);
390  host_view() = value;
391  Kokkos::deep_copy(view, host_view);
392  symbol_map[name] = const_single_bool_view_type{view};
393 }
394 
395 template <typename DT, typename ... VP>
396 void Eval<DT, VP ...>::set(std::string const& name, scalar_type const& value) {
397  single_view_type view{Kokkos::ViewAllocateWithoutInitializing{name}};
398  auto host_view = Kokkos::create_mirror_view(view);
399  host_view() = value;
400  Kokkos::deep_copy(view, host_view);
401  symbol_map[name] = const_single_view_type{view};
402  bool a, b;
403  this->inspect_arg(symbol_map[name], a, b);
404 }
405 
406 template <typename DT, typename ... VP>
407 void Eval<DT, VP ...>::set(std::string const& name, const_view_type const& value) {
408  symbol_map[name] = value;
409 }
410 
411 template <typename DT, typename ... VP>
413  single_view_type view{Kokkos::ViewAllocateWithoutInitializing{"constant"}};
414  auto host_view = Kokkos::create_mirror_view(view);
415  host_view() = value;
416  Kokkos::deep_copy(view, host_view);
417  result = const_single_view_type{view};
418  bool a, b;
419  this->inspect_arg(result, a, b);
420 }
421 
422 template <typename DT, typename ... VP>
423 void Eval<DT, VP ...>::inspect_arg(Teuchos::any const& arg, bool& is_many, bool& is_bool) {
424  if (arg.type() == typeid(const_single_bool_view_type)) {
425  is_many = false;
426  is_bool = true;
427  } else if (arg.type() == typeid(const_single_view_type)) {
428  is_many = false;
429  is_bool = false;
430  } else if (arg.type() == typeid(const_view_type)) {
431  is_many = true;
432  is_bool = false;
433  } else if (arg.type() == typeid(const_bool_view_type)) {
434  is_many = true;
435  is_bool = true;
436  } else {
438  "value is of illegal type " << arg.typeName() << ", view type is "
439  << typeid(const_view_type).name());
440  }
441 }
442 
443 template <typename DT, typename ... VP>
445  using ManyBool = const_bool_view_type;
446  using Single = const_single_view_type;
447  TernaryFunctor<ManyBool, Single, Single>("many ? single : single", result, cond, left, right);
448 }
449 
450 template <typename DT, typename ... VP>
452  using ManyBool = const_bool_view_type;
453  using Single = const_single_view_type;
454  using Many = const_view_type;
455  TernaryFunctor<ManyBool, Single, Many>("many ? single : many", result, cond, left, right);
456 }
457 
458 template <typename DT, typename ... VP>
460  using ManyBool = const_bool_view_type;
461  using Single = const_single_view_type;
462  using Many = const_view_type;
463  TernaryFunctor<ManyBool, Many, Single>("many ? many : single", result, cond, left, right);
464 }
465 
466 template <typename DT, typename ... VP>
468  using ManyBool = const_bool_view_type;
469  using Many = const_view_type;
470  TernaryFunctor<ManyBool, Many, Many>("many ? many : many", result, cond, left, right);
471 }
472 
473 template <typename DT, typename ... VP>
475  using SingleBool = const_single_bool_view_type;
476  using Single = const_single_view_type;
477  switch (code) {
478  case BinaryOpCode::OR: BinaryFunctor<ScalarOr , SingleBool, SingleBool, SingleBool>("single||single", result, left, right); break;
480  case BinaryOpCode::LT: BinaryFunctor<ScalarLT , SingleBool, Single, Single>("single< single", result, left, right); break;
481  case BinaryOpCode::GT: BinaryFunctor<ScalarGT , SingleBool, Single, Single>("single> single", result, left, right); break;
482  case BinaryOpCode::GEQ: BinaryFunctor<ScalarGEQ, SingleBool, Single, Single>("single>=single", result, left, right); break;
483  case BinaryOpCode::LEQ: BinaryFunctor<ScalarLEQ, SingleBool, Single, Single>("single<=single", result, left, right); break;
484  case BinaryOpCode::EQ: BinaryFunctor<ScalarEQ , SingleBool, Single, Single>("single==single", result, left, right); break;
485  case BinaryOpCode::MUL: BinaryFunctor<ScalarMul, Single, Single, Single>("single* single", result, left, right); break;
486  case BinaryOpCode::DIV: BinaryFunctor<ScalarDiv, Single, Single, Single>("single/ single", result, left, right); break;
487  case BinaryOpCode::ADD: BinaryFunctor<ScalarAdd, Single, Single, Single>("single+ single", result, left, right); break;
488  case BinaryOpCode::SUB: BinaryFunctor<ScalarSub, Single, Single, Single>("single- single", result, left, right); break;
489  case BinaryOpCode::POW: BinaryFunctor<ScalarPow, Single, Single, Single>("single^ single", result, left, right); break;
490  }
491 }
492 
493 template <typename DT, typename ... VP>
495  using Single = const_single_view_type;
496  using SingleBool = const_single_bool_view_type;
497  using Many = const_view_type;
498  using ManyBool = const_bool_view_type;
499  switch (code) {
500  case BinaryOpCode::OR: BinaryFunctor<ScalarOr , ManyBool, SingleBool, ManyBool>("single||many", result, left, right); break;
501  case BinaryOpCode::AND: BinaryFunctor<ScalarAnd, ManyBool, SingleBool, ManyBool>("single&&many", result, left, right); break;
502  case BinaryOpCode::LT: BinaryFunctor<ScalarLT , ManyBool, Single, Many>("single< many", result, left, right); break;
503  case BinaryOpCode::GT: BinaryFunctor<ScalarGT , ManyBool, Single, Many>("single> many", result, left, right); break;
504  case BinaryOpCode::GEQ: BinaryFunctor<ScalarGEQ, ManyBool, Single, Many>("single>=many", result, left, right); break;
505  case BinaryOpCode::LEQ: BinaryFunctor<ScalarLEQ, ManyBool, Single, Many>("single<=many", result, left, right); break;
506  case BinaryOpCode::EQ: BinaryFunctor<ScalarEQ , ManyBool, Single, Many>("single==many", result, left, right); break;
507  case BinaryOpCode::MUL: BinaryFunctor<ScalarMul, Many, Single, Many>("single* many", result, left, right); break;
508  case BinaryOpCode::DIV: BinaryFunctor<ScalarDiv, Many, Single, Many>("single/ many", result, left, right); break;
509  case BinaryOpCode::ADD: BinaryFunctor<ScalarAdd, Many, Single, Many>("single+ many", result, left, right); break;
510  case BinaryOpCode::SUB: BinaryFunctor<ScalarSub, Many, Single, Many>("single- many", result, left, right); break;
511  case BinaryOpCode::POW: BinaryFunctor<ScalarPow, Many, Single, Many>("single^ many", result, left, right); break;
512  }
513 }
514 
515 template <typename DT, typename ... VP>
517  using Single = const_single_view_type;
518  using SingleBool = const_single_bool_view_type;
519  using Many = const_view_type;
520  using ManyBool = const_bool_view_type;
521  switch (code) {
522  case BinaryOpCode::OR: BinaryFunctor<ScalarOr , ManyBool, ManyBool, SingleBool>("many||single", result, left, right); break;
523  case BinaryOpCode::AND: BinaryFunctor<ScalarAnd, ManyBool, ManyBool, SingleBool>("many&&single", result, left, right); break;
524  case BinaryOpCode::LT: BinaryFunctor<ScalarLT , ManyBool, Many, Single>("many< single", result, left, right); break;
525  case BinaryOpCode::GT: BinaryFunctor<ScalarGT , ManyBool, Many, Single>("many> single", result, left, right); break;
526  case BinaryOpCode::GEQ: BinaryFunctor<ScalarGEQ, ManyBool, Many, Single>("many>=single", result, left, right); break;
527  case BinaryOpCode::LEQ: BinaryFunctor<ScalarLEQ, ManyBool, Many, Single>("many<=single", result, left, right); break;
528  case BinaryOpCode::EQ: BinaryFunctor<ScalarEQ , ManyBool, Many, Single>("many==single", result, left, right); break;
529  case BinaryOpCode::MUL: BinaryFunctor<ScalarMul, Many, Many, Single>("many* single", result, left, right); break;
530  case BinaryOpCode::DIV: BinaryFunctor<ScalarDiv, Many, Many, Single>("many/ single", result, left, right); break;
531  case BinaryOpCode::ADD: BinaryFunctor<ScalarAdd, Many, Many, Single>("many+ single", result, left, right); break;
532  case BinaryOpCode::SUB: BinaryFunctor<ScalarSub, Many, Many, Single>("many- single", result, left, right); break;
533  case BinaryOpCode::POW: BinaryFunctor<ScalarPow, Many, Many, Single>("many^ single", result, left, right); break;
534  }
535 }
536 
537 template <typename DT, typename ... VP>
539  using Many = const_view_type;
540  using ManyBool = const_bool_view_type;
541  switch (code) {
542  case BinaryOpCode::OR: BinaryFunctor<ScalarOr , ManyBool, ManyBool, ManyBool>("many||many", result, left, right); break;
544  case BinaryOpCode::LT: BinaryFunctor<ScalarLT , ManyBool, Many, Many>("many< many", result, left, right); break;
545  case BinaryOpCode::GT: BinaryFunctor<ScalarGT , ManyBool, Many, Many>("many> many", result, left, right); break;
546  case BinaryOpCode::GEQ: BinaryFunctor<ScalarGEQ, ManyBool, Many, Many>("many>=many", result, left, right); break;
547  case BinaryOpCode::LEQ: BinaryFunctor<ScalarLEQ, ManyBool, Many, Many>("many<=many", result, left, right); break;
548  case BinaryOpCode::EQ: BinaryFunctor<ScalarEQ , ManyBool, Many, Many>("many==many", result, left, right); break;
549  case BinaryOpCode::MUL: BinaryFunctor<ScalarMul, Many, Many, Many>("many* many", result, left, right); break;
550  case BinaryOpCode::DIV: BinaryFunctor<ScalarDiv, Many, Many, Many>("many/ many", result, left, right); break;
551  case BinaryOpCode::ADD: BinaryFunctor<ScalarAdd, Many, Many, Many>("many+ many", result, left, right); break;
552  case BinaryOpCode::SUB: BinaryFunctor<ScalarSub, Many, Many, Many>("many- many", result, left, right); break;
553  case BinaryOpCode::POW: BinaryFunctor<ScalarPow, Many, Many, Many>("many^ many", result, left, right); break;
554  }
555 }
556 
557 template <typename Op, typename Result, size_t Rank = Result::rank>
559 
560 template <typename Op, typename Result>
561 struct UnaryFunctor<Op, Result, 0> {
563  using execution_space = typename Result::execution_space;
565  Result right_;
566  KOKKOS_INLINE_FUNCTION
567  void operator()(typename execution_space::size_type i) const {
568  result_() = Op::apply(right_());
569  }
570  UnaryFunctor(std::string const& name, Teuchos::any& result, Teuchos::any& right) {
571  right_ = Teuchos::any_cast<Result>(right);
572  result_ = NonConstResult(Kokkos::ViewAllocateWithoutInitializing(name));
573  Kokkos::parallel_for(name, Kokkos::RangePolicy<execution_space>(0, 1), *this);
574  result = Result(result_);
575  }
576 };
577 
578 template <typename Op, typename Result>
579 struct UnaryFunctor<Op, Result, 1> {
581  using execution_space = typename Result::execution_space;
583  Result right_;
584  KOKKOS_INLINE_FUNCTION
585  void operator()(typename execution_space::size_type i) const {
586  result_(i) = Op::apply(right_(i));
587  }
588  UnaryFunctor(std::string const& name, Teuchos::any& result, Teuchos::any& right) {
589  right_ = Teuchos::any_cast<Result>(right);
590  auto extent_0 = right_.extent(0);
591  result_ = NonConstResult(Kokkos::ViewAllocateWithoutInitializing(name), extent_0);
592  Kokkos::parallel_for(name, Kokkos::RangePolicy<execution_space>(0, extent_0), *this);
593  result = Result(result_);
594  }
595 };
596 
597 template <typename Op, typename Result>
598 struct UnaryFunctor<Op, Result, 2> {
600  using execution_space = typename Result::execution_space;
602  Result right_;
603  KOKKOS_INLINE_FUNCTION
604  void operator()(typename execution_space::size_type i, typename execution_space::size_type j) const {
605  result_(i, j) = Op::apply(right_(i, j));
606  }
607  UnaryFunctor(std::string const& name, Teuchos::any& result, Teuchos::any& right) {
608  right_ = Teuchos::any_cast<Result>(right);
609  auto extent_0 = right_.extent(0);
610  auto extent_1 = right_.extent(1);
611  result_ = NonConstResult(Kokkos::ViewAllocateWithoutInitializing(name), extent_0, extent_1);
612  using policy_type = Kokkos::MDRangePolicy<execution_space, Kokkos::Rank<2>>;
613  Kokkos::parallel_for(name, policy_type({0, 0}, {extent_0, extent_1}), *this);
614  result = Result(result_);
615  }
616 };
617 
618 template <typename DT, typename ... VP>
621 }
622 
623 template <typename DT, typename ... VP>
626 }
627 
628 struct ScalarAbs {
629  template <typename T>
630  static KOKKOS_FORCEINLINE_FUNCTION
631  T apply(T const& right) {
632  using std::abs;
633  return abs(right);
634  }
635 };
636 
637 struct ScalarExp {
638  template <typename T>
639  static KOKKOS_FORCEINLINE_FUNCTION
640  T apply(T const& right) {
641  using std::exp;
642  return exp(right);
643  }
644 };
645 
646 struct ScalarLog {
647  template <typename T>
648  static KOKKOS_FORCEINLINE_FUNCTION
649  T apply(T const& right) {
650  using std::log;
651  return log(right);
652  }
653 };
654 
655 struct ScalarSqrt {
656  template <typename T>
657  static KOKKOS_FORCEINLINE_FUNCTION
658  T apply(T const& right) {
659  using std::sqrt;
660  return sqrt(right);
661  }
662 };
663 
664 struct ScalarSin {
665  template <typename T>
666  static KOKKOS_FORCEINLINE_FUNCTION
667  T apply(T const& right) {
668  using std::sin;
669  return sin(right);
670  }
671 };
672 
673 struct ScalarCos {
674  template <typename T>
675  static KOKKOS_FORCEINLINE_FUNCTION
676  T apply(T const& right) {
677  using std::cos;
678  return cos(right);
679  }
680 };
681 
682 struct ScalarTan {
683  template <typename T>
684  static KOKKOS_FORCEINLINE_FUNCTION
685  T apply(T const& right) {
686  using std::tan;
687  return tan(right);
688  }
689 };
690 
691 template <typename Op, typename EvalType>
693  void operator()(std::string const& name, Teuchos::any& result, std::vector<Teuchos::any>& rhs) const {
694  auto& right = rhs.at(0);
695  using single_type = typename EvalType::const_single_view_type;
696  using many_type = typename EvalType::const_view_type;
697  if (right.type() == typeid(single_type)) {
699  } else if (right.type() == typeid(many_type)) {
700  UnaryFunctor<Op, many_type>(name, result, right);
701  } else {
703  "Unexpected type " << right.typeName() << " passed to UnaryFunction \"" << name << "\"\n");
704  }
705  }
706 };
707 
708 template <typename DT, typename ... VP>
710  using eval_type = Eval<DT, VP ...>;
711  EvalBase& eval_base = eval;
719 }
720 
721 }} // end namespace panzer::Expr
722 
723 #endif // PANZER_EXPR_EVAL_IMPL_HPP
typename RebindViewType< Result, typename Result::non_const_value_type >::type NonConstResult
void many_many_binary_op(BinaryOpCode code, Teuchos::any &result, Teuchos::any &left, Teuchos::any &right) override
Base class for panzer::Expr::Eval, does everything that is independent of the Kokkos::View template p...
void make_constant(Teuchos::any &result, double const &value) override
Kokkos::View< scalar_type const, VP...> const_single_view_type
One scalar (same for all evaluation points), read-only.
Kokkos::View< typename RebindDataType< view_data_type, scalar_type const >::type, VP...> const_view_type
One scalar for each evaluation point, read-only.
void set(std::string const &name, bool value)
Assign a boolean value to a variable symbol.
static KOKKOS_FORCEINLINE_FUNCTION bool apply(T const &left, T const &right)
typename RebindViewType< biggest_type, typename biggest_type::const_value_type >::type const_type
typename RebindViewType< Result, typename Result::non_const_value_type >::type NonConstResult
static KOKKOS_FORCEINLINE_FUNCTION T apply(T const &right)
BinaryOpCode
Denotes the native binary operators in the Teuchos::MathExpr language.
UnaryFunctor(std::string const &name, Teuchos::any &result, Teuchos::any &right)
typename Result::execution_space execution_space
void single_many_ternary_op(Teuchos::any &result, Teuchos::any &cond, Teuchos::any &left, Teuchos::any &right) override
static KOKKOS_FORCEINLINE_FUNCTION T apply(T const &left, T const &right)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
typename RebindViewType< Result, typename Result::non_const_value_type >::type NonConstResult
BinaryFunctor(std::string const &name, Teuchos::any &result, Teuchos::any &left, Teuchos::any &right)
std::function< void(std::string const &name, Teuchos::any &, std::vector< Teuchos::any > &rhs)> Function
The type of user-defined functions which are callable in the math language.
static KOKKOS_FORCEINLINE_FUNCTION T apply(T const &right)
static KOKKOS_FORCEINLINE_FUNCTION T apply(T const &left, T const &right)
static KOKKOS_FORCEINLINE_FUNCTION T apply(T const &right)
typename RebindViewType< Result, typename Result::non_const_value_type >::type NonConstResult
static KOKKOS_FORCEINLINE_FUNCTION ViewType::reference_type index(ViewType const &x, Integral, Integral)
KOKKOS_INLINE_FUNCTION void operator()(typename execution_space::size_type i, typename execution_space::size_type j) const
typename std::conditional<(b_rank > a_rank), Right, Left >::type biggest_ab_type
typename TernaryResultType< Cond, Left, Right >::non_const_type NonConstResult
void single_neg_op(Teuchos::any &result, Teuchos::any &right) override
UnaryFunctor(std::string const &name, Teuchos::any &result, Teuchos::any &right)
typename Result::execution_space execution_space
KOKKOS_INLINE_FUNCTION void operator()(typename execution_space::size_type i) const
TernaryFunctor(std::string const &name, Teuchos::any &result, Teuchos::any &cond, Teuchos::any &left, Teuchos::any &right)
Kokkos::View< bool const, VP...> const_single_bool_view_type
One boolean (same for all evaluation points), read-only.
static KOKKOS_FORCEINLINE_FUNCTION bool apply(T const &left, T const &right)
static constexpr size_t b_rank
void set(std::string const &name, Function const &value)
Registers an EvalBase::Function, binding it to a name and making it callable.
Kokkos::View< typename RebindDataType< view_data_type, bool const >::type, VP...> const_bool_view_type
One boolean for each evaluation point, read-only.
Declares the panzer::Expr::Eval templated class.
PHX::MDField< ScalarT, panzer::Cell, panzer::IP > result
A field that will be used to build up the result of the integral we&#39;re performing.
static KOKKOS_FORCEINLINE_FUNCTION bool apply(T const &left, T const &right)
static KOKKOS_FORCEINLINE_FUNCTION ViewType::reference_type index(ViewType const &x, Integral i, Integral)
static KOKKOS_FORCEINLINE_FUNCTION bool apply(T const &left, T const &right)
static KOKKOS_FORCEINLINE_FUNCTION T apply(bool cond, T const &left, T const &right)
static constexpr size_t left_value
static KOKKOS_FORCEINLINE_FUNCTION T apply(T const &right)
typename std::conditional<(c_rank > biggest_ab_type::rank), Cond, biggest_ab_type >::type biggest_type
static KOKKOS_FORCEINLINE_FUNCTION T apply(T const &right)
static KOKKOS_FORCEINLINE_FUNCTION ViewType::reference_type index(ViewType const &x, Integral i, Integral j)
typename Result::execution_space execution_space
typename RebindViewType< Result, typename Result::non_const_value_type >::type NonConstResult
void single_many_binary_op(BinaryOpCode code, Teuchos::any &result, Teuchos::any &left, Teuchos::any &right) override
void operator()(std::string const &name, Teuchos::any &result, std::vector< Teuchos::any > &rhs) const
KOKKOS_INLINE_FUNCTION void operator()(typename execution_space::size_type i) const
void inspect_arg(Teuchos::any const &arg, bool &is_many, bool &is_bool) override
static KOKKOS_FORCEINLINE_FUNCTION T apply(T const &right)
typename RebindViewType< Result, typename Result::non_const_value_type >::type NonConstResult
typename original_view_type::non_const_value_type scalar_type
The scalar type.
void many_many_ternary_op(Teuchos::any &result, Teuchos::any &cond, Teuchos::any &left, Teuchos::any &right) override
static constexpr size_t a_rank
KOKKOS_INLINE_FUNCTION void operator()(typename execution_space::size_type i) const
typename TernaryResultType< Cond, Left, Right >::type Result
static KOKKOS_FORCEINLINE_FUNCTION T apply(T const &right)
static KOKKOS_FORCEINLINE_FUNCTION T apply(T const &right)
BinaryFunctor(std::string const &name, Teuchos::any &result, Teuchos::any &left, Teuchos::any &right)
static KOKKOS_FORCEINLINE_FUNCTION ViewType::reference_type index(ViewType const &x, Integral)
Builds on RebindDataType, but acts directly on a Kokkos::View type.
typename RebindViewType< biggest_type, typename biggest_type::non_const_value_type >::type type
KOKKOS_INLINE_FUNCTION void operator()(typename execution_space::size_type) const
UnaryFunctor(std::string const &name, Teuchos::any &result, Teuchos::any &right)
Interprets mathematical expressions in a string and evaluates them using Kokkos::View objects as valu...
void many_neg_op(Teuchos::any &result, Teuchos::any &right) override
static KOKKOS_FORCEINLINE_FUNCTION bool apply(bool left, bool right)
typename RebindViewType< biggest_type, typename Left::non_const_value_type >::type non_const_type
KOKKOS_INLINE_FUNCTION void operator()(typename execution_space::size_type i, typename execution_space::size_type j) const
KOKKOS_INLINE_FUNCTION void operator()(typename execution_space::size_type i) const
static constexpr size_t right_value
void many_single_ternary_op(Teuchos::any &result, Teuchos::any &cond, Teuchos::any &left, Teuchos::any &right) override
static KOKKOS_FORCEINLINE_FUNCTION ViewType::reference_type index(ViewType const &x, Integral i)
TernaryFunctor(std::string const &name, Teuchos::any &result, Teuchos::any &cond, Teuchos::any &left, Teuchos::any &right)
static constexpr size_t value
Kokkos::View< bool, VP...> single_bool_view_type
One boolean (same for all evaluation points)
static KOKKOS_FORCEINLINE_FUNCTION bool apply(T const &left, T const &right)
Kokkos::View< scalar_type, VP...> single_view_type
One scalar (same for all evaluation points)
std::string typeName() const
static KOKKOS_FORCEINLINE_FUNCTION T apply(T const &left, T const &right)
void single_single_ternary_op(Teuchos::any &result, Teuchos::any &cond, Teuchos::any &left, Teuchos::any &right) override
typename RebindViewType< biggest_type, typename Left::const_value_type >::type type
const std::type_info & type() const
static KOKKOS_FORCEINLINE_FUNCTION T apply(T const &left, T const &right)
typename std::conditional<(b_rank > a_rank), B, A >::type biggest_type
void single_single_binary_op(BinaryOpCode code, Teuchos::any &result, Teuchos::any &left, Teuchos::any &right) override
void set_cmath_functions(Eval< DT, VP...> &eval)
Add support for functions such as sqrt(), sin(), and cos()
typename TernaryResultType< Cond, Left, Right >::non_const_type NonConstResult
BinaryFunctor(std::string const &name, Teuchos::any &result, Teuchos::any &left, Teuchos::any &right)
KOKKOS_INLINE_FUNCTION void operator()(typename execution_space::size_type i, typename execution_space::size_type j) const
void many_single_binary_op(BinaryOpCode code, Teuchos::any &result, Teuchos::any &left, Teuchos::any &right) override
typename TernaryResultType< Cond, Left, Right >::type Result
static KOKKOS_FORCEINLINE_FUNCTION bool apply(bool left, bool right)
static KOKKOS_FORCEINLINE_FUNCTION T apply(T const &left, T const &right)