RAJA
RAJA provides a collection of platform portability abstractions for C++ HPC applications.
TensorDivide.hpp
Go to the documentation of this file.
1 
11 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
12 // Copyright (c) Lawrence Livermore National Security, LLC and other
13 // RAJA Project Developers. See top-level LICENSE and COPYRIGHT
14 // files for dates and other details. No copyright assignment is required
15 // to contribute to RAJA.
16 //
17 // SPDX-License-Identifier: (BSD-3-Clause)
18 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
19 
20 #ifndef RAJA_pattern_tensor_ET_TensorDivide_HPP
21 #define RAJA_pattern_tensor_ET_TensorDivide_HPP
22 
23 #include "RAJA/config.hpp"
24 
25 #include "RAJA/util/macros.hpp"
26 
28 
29 namespace RAJA
30 {
31 namespace internal
32 {
33 namespace expt
34 {
35 
36 
37 namespace ET
38 {
39 
40 template<typename LEFT_OPERAND_TYPE,
41  typename RIGHT_OPERAND_TYPE,
42  class ENABLE = void>
44 
48 template<typename LEFT_OPERAND_TYPE, typename RIGHT_OPERAND_TYPE>
50  LEFT_OPERAND_TYPE,
51  RIGHT_OPERAND_TYPE,
52  typename std::enable_if<LEFT_OPERAND_TYPE::s_num_dims == 0 &&
53  RIGHT_OPERAND_TYPE::s_num_dims == 1>::type>
54 {
55 
56  using result_type = typename RIGHT_OPERAND_TYPE::result_type;
57  static constexpr camp::idx_t s_num_dims = RIGHT_OPERAND_TYPE::s_num_dims;
58 
59  RAJA_INLINE
60 
62  static int getDimSize(int dim,
63  LEFT_OPERAND_TYPE const&,
64  RIGHT_OPERAND_TYPE const& right)
65  {
66  return right.getDimSize(dim);
67  }
68 
72  template<typename TILE_TYPE>
73  RAJA_INLINE RAJA_HOST_DEVICE static result_type divide(
74  TILE_TYPE const& tile,
75  LEFT_OPERAND_TYPE const& left,
76  RIGHT_OPERAND_TYPE const& right)
77  {
78  result_type numerator(left.eval(tile));
79 
80  if (tile.s_tensor_size == TENSOR_FULL)
81  {
82  return numerator.divide(right.eval(tile));
83  }
84 
85  return numerator.divide_n(right.eval(tile), tile.m_size[0]);
86  }
87 };
88 
92 template<typename LEFT_OPERAND_TYPE, typename RIGHT_OPERAND_TYPE>
94  LEFT_OPERAND_TYPE,
95  RIGHT_OPERAND_TYPE,
96  typename std::enable_if<LEFT_OPERAND_TYPE::s_num_dims == 1 &&
97  RIGHT_OPERAND_TYPE::s_num_dims == 0>::type>
98 {
99  using result_type = typename LEFT_OPERAND_TYPE::result_type;
100  static constexpr camp::idx_t s_num_dims = LEFT_OPERAND_TYPE::s_num_dims;
101 
102 
103  RAJA_INLINE
104 
106  static int getDimSize(int dim,
107  LEFT_OPERAND_TYPE const& left,
108  RIGHT_OPERAND_TYPE const&)
109  {
110  return left.getDimSize(dim);
111  }
112 
116  template<typename TILE_TYPE>
117  RAJA_INLINE RAJA_HOST_DEVICE static result_type divide(
118  TILE_TYPE const& tile,
119  LEFT_OPERAND_TYPE const& left,
120  RIGHT_OPERAND_TYPE const& right)
121  {
122  result_type denominator(right.eval(tile));
123 
124  if (tile.s_tensor_size == TENSOR_FULL)
125  {
126  return left.eval(tile).divide(denominator);
127  }
128  else
129  {
130  return left.eval(tile).divide_n(denominator, tile.m_size[0]);
131  }
132  }
133 };
134 
138 template<typename LEFT_OPERAND_TYPE, typename RIGHT_OPERAND_TYPE>
140  LEFT_OPERAND_TYPE,
141  RIGHT_OPERAND_TYPE,
142  typename std::enable_if<LEFT_OPERAND_TYPE::s_num_dims == 1 &&
143  RIGHT_OPERAND_TYPE::s_num_dims == 1>::type>
144 {
145  using result_type = typename LEFT_OPERAND_TYPE::result_type;
146  static constexpr camp::idx_t s_num_dims = LEFT_OPERAND_TYPE::s_num_dims;
147 
148 
149  RAJA_INLINE
150 
152  static int getDimSize(int dim,
153  LEFT_OPERAND_TYPE const& left,
154  RIGHT_OPERAND_TYPE const&)
155  {
156  return left.getDimSize(dim);
157  }
158 
162  template<typename TILE_TYPE>
163  RAJA_INLINE RAJA_HOST_DEVICE static result_type divide(
164  TILE_TYPE const& tile,
165  LEFT_OPERAND_TYPE const& left,
166  RIGHT_OPERAND_TYPE const& right)
167  {
168  if (tile.s_tensor_size == TENSOR_FULL)
169  {
170  return left.eval(tile).divide(right.eval(tile));
171  }
172  else
173  {
174  return left.eval(tile).divide_n(right.eval(tile), tile.m_size[0]);
175  }
176  }
177 };
178 
182 template<typename LEFT_OPERAND_TYPE, typename RIGHT_OPERAND_TYPE>
184  LEFT_OPERAND_TYPE,
185  RIGHT_OPERAND_TYPE,
186  typename std::enable_if<LEFT_OPERAND_TYPE::s_num_dims == 0 &&
187  RIGHT_OPERAND_TYPE::s_num_dims == 2>::type>
188 {
189 
190  using result_type = typename RIGHT_OPERAND_TYPE::result_type;
191  static constexpr camp::idx_t s_num_dims = RIGHT_OPERAND_TYPE::s_num_dims;
192 
193  RAJA_INLINE
194 
196  static int getDimSize(int dim,
197  LEFT_OPERAND_TYPE const&,
198  RIGHT_OPERAND_TYPE const& right)
199  {
200  return right.getDimSize(dim);
201  }
202 
206  template<typename TILE_TYPE>
207  RAJA_INLINE RAJA_HOST_DEVICE static result_type divide(
208  TILE_TYPE const& tile,
209  LEFT_OPERAND_TYPE const& left,
210  RIGHT_OPERAND_TYPE const& right)
211  {
212  result_type numerator(left.eval(tile));
213 
214  if (tile.s_tensor_size == TENSOR_FULL)
215  {
216  return numerator.divide(right.eval(tile));
217  }
218 
219  return numerator.divide_nm(right.eval(tile), tile.m_size[0],
220  tile.m_size[1]);
221  }
222 };
223 
227 template<typename LEFT_OPERAND_TYPE, typename RIGHT_OPERAND_TYPE>
229  LEFT_OPERAND_TYPE,
230  RIGHT_OPERAND_TYPE,
231  typename std::enable_if<LEFT_OPERAND_TYPE::s_num_dims == 2 &&
232  RIGHT_OPERAND_TYPE::s_num_dims == 0>::type>
233 {
234  using result_type = typename LEFT_OPERAND_TYPE::result_type;
235  static constexpr camp::idx_t s_num_dims = LEFT_OPERAND_TYPE::s_num_dims;
236 
237 
238  RAJA_INLINE
239 
241  static int getDimSize(int dim,
242  LEFT_OPERAND_TYPE const& left,
243  RIGHT_OPERAND_TYPE const&)
244  {
245  return left.getDimSize(dim);
246  }
247 
252  template<typename TILE_TYPE>
253  RAJA_INLINE RAJA_HOST_DEVICE static result_type divide(
254  TILE_TYPE const& tile,
255  LEFT_OPERAND_TYPE const& left,
256  RIGHT_OPERAND_TYPE const& right)
257  {
258  result_type denominator(right.eval(tile));
259 
260  if (tile.s_tensor_size == TENSOR_FULL)
261  {
262  return left.eval(tile).divide(denominator);
263  }
264  else
265  {
266  return left.eval(tile).divide_nm(denominator, tile.m_size[0],
267  tile.m_size[1]);
268  }
269  }
270 };
271 
275 template<typename LEFT_OPERAND_TYPE, typename RIGHT_OPERAND_TYPE>
277  LEFT_OPERAND_TYPE,
278  RIGHT_OPERAND_TYPE,
279  typename std::enable_if<LEFT_OPERAND_TYPE::s_num_dims == 2 &&
280  RIGHT_OPERAND_TYPE::s_num_dims == 2>::type>
281 {
282  using result_type = typename LEFT_OPERAND_TYPE::result_type;
283  static constexpr camp::idx_t s_num_dims = LEFT_OPERAND_TYPE::s_num_dims;
284 
285 
286  RAJA_INLINE
287 
289  static int getDimSize(int dim,
290  LEFT_OPERAND_TYPE const& left,
291  RIGHT_OPERAND_TYPE const&)
292  {
293  return left.getDimSize(dim);
294  }
295 
299  template<typename TILE_TYPE>
300  RAJA_INLINE RAJA_HOST_DEVICE static result_type divide(
301  TILE_TYPE const& tile,
302  LEFT_OPERAND_TYPE const& left,
303  RIGHT_OPERAND_TYPE const& right)
304  {
305  if (tile.s_tensor_size == TENSOR_FULL)
306  {
307  return left.eval(tile).divide(right.eval(tile));
308  }
309  else
310  {
311  return left.eval(tile).divide_nm(right.eval(tile), tile.m_size[0],
312  tile.m_size[1]);
313  }
314  }
315 };
316 
317 template<typename LEFT_OPERAND_TYPE, typename RIGHT_OPERAND_TYPE>
319  TensorDivide<LEFT_OPERAND_TYPE, RIGHT_OPERAND_TYPE>>
320 {
321 public:
323  using left_operand_type = LEFT_OPERAND_TYPE;
324  using right_operand_type = RIGHT_OPERAND_TYPE;
325  using element_type = typename LEFT_OPERAND_TYPE::element_type;
326  using index_type = typename LEFT_OPERAND_TYPE::index_type;
327 
329  using result_type = typename divide_op::result_type;
330  static constexpr camp::idx_t s_num_dims = divide_op::s_num_dims;
331 
332 
333 private:
334  left_operand_type m_left_operand;
335  right_operand_type m_right_operand;
336 
337 public:
338  RAJA_INLINE
339 
341  TensorDivide(left_operand_type const& left_operand,
342  right_operand_type const& right_operand)
343  : m_left_operand {left_operand},
344  m_right_operand {right_operand}
345  {}
346 
347  RAJA_INLINE
348 
350  constexpr index_type getDimSize(index_type dim) const
351  {
352  return divide_op::getDimSize(dim, m_left_operand, m_right_operand);
353  }
354 
355  template<typename TILE_TYPE>
356  RAJA_INLINE RAJA_HOST_DEVICE result_type eval(TILE_TYPE const& tile) const
357  {
358  return divide_op::divide(tile, m_left_operand, m_right_operand);
359  }
360 
364  RAJA_INLINE
365 
367  constexpr left_operand_type const& getLeftOperand() const
368  {
369  return m_left_operand;
370  }
371 
375  RAJA_INLINE
376 
378  constexpr right_operand_type const& getRightOperand() const
379  {
380  return m_right_operand;
381  }
382 
383  RAJA_INLINE
384 
386  void print_ast() const
387  {
388  printf("Divide(");
389  m_left_operand.print_ast();
390  printf(", ");
391  m_right_operand.print_ast();
392  printf(")");
393  }
394 };
395 
396 /*
397  * Overload for: arithmetic / tensorexpression
398 
399  */
400 template<
401  typename LHS,
402  typename RHS,
403  typename std::enable_if<std::is_arithmetic<LHS>::value, bool>::type = true,
404  typename std::enable_if<
405  std::is_base_of<TensorExpressionConcreteBase, RHS>::value,
406  bool>::type = true>
407 RAJA_INLINE RAJA_HOST_DEVICE auto operator/(LHS const& left_operand,
408  RHS const& right_operand)
410 {
412  NormalizeOperandHelper<LHS>::normalize(left_operand), right_operand);
413 }
414 
415 } // namespace ET
416 
417 } // namespace expt
418 } // namespace internal
419 
420 } // namespace RAJA
421 
422 
423 #endif
RAJA header file defining SIMD/SIMT register operations.
Definition: TensorDivide.hpp:320
typename LEFT_OPERAND_TYPE::index_type index_type
Definition: TensorDivide.hpp:326
RIGHT_OPERAND_TYPE right_operand_type
Definition: TensorDivide.hpp:324
static constexpr camp::idx_t s_num_dims
Definition: TensorDivide.hpp:330
RAJA_INLINE constexpr RAJA_HOST_DEVICE left_operand_type const & getLeftOperand() const
Definition: TensorDivide.hpp:367
RAJA_INLINE RAJA_HOST_DEVICE void print_ast() const
Definition: TensorDivide.hpp:386
LEFT_OPERAND_TYPE left_operand_type
Definition: TensorDivide.hpp:323
typename divide_op::result_type result_type
Definition: TensorDivide.hpp:329
RAJA_INLINE constexpr RAJA_HOST_DEVICE right_operand_type const & getRightOperand() const
Definition: TensorDivide.hpp:378
RAJA_INLINE RAJA_HOST_DEVICE TensorDivide(left_operand_type const &left_operand, right_operand_type const &right_operand)
Definition: TensorDivide.hpp:341
RAJA_INLINE constexpr RAJA_HOST_DEVICE index_type getDimSize(index_type dim) const
Definition: TensorDivide.hpp:350
RAJA_INLINE RAJA_HOST_DEVICE result_type eval(TILE_TYPE const &tile) const
Definition: TensorDivide.hpp:356
typename LEFT_OPERAND_TYPE::element_type element_type
Definition: TensorDivide.hpp:325
Definition: ExpressionTemplateBase.hpp:72
Header file for common RAJA internal macro definitions.
#define RAJA_HOST_DEVICE
Definition: macros.hpp:65
#define RAJA_SUPPRESS_HD_WARN
Definition: macros.hpp:68
RAJA_INLINE RAJA_HOST_DEVICE auto operator/(LHS const &left_operand, RHS const &right_operand) -> TensorDivide< typename NormalizeOperandHelper< LHS >::return_type, RHS >
Definition: TensorDivide.hpp:407
@ TENSOR_FULL
Definition: TensorRef.hpp:236
Definition: AlignedRangeIndexSetBuilders.cpp:35
RAJA_HOST_DEVICE RAJA_INLINE void tile(CONTEXT const &ctx, TILE_T tile_size, SEGMENT const &segment, BODY const &body)
Definition: launch_core.hpp:589
Definition: ListSegment.hpp:416
RAJA_SUPPRESS_HD_WARN RAJA_INLINE static RAJA_HOST_DEVICE result_type divide(TILE_TYPE const &tile, LEFT_OPERAND_TYPE const &left, RIGHT_OPERAND_TYPE const &right)
Definition: TensorDivide.hpp:253
RAJA_INLINE static RAJA_HOST_DEVICE int getDimSize(int dim, LEFT_OPERAND_TYPE const &left, RIGHT_OPERAND_TYPE const &)
Definition: TensorDivide.hpp:241
RAJA_INLINE static RAJA_HOST_DEVICE int getDimSize(int dim, LEFT_OPERAND_TYPE const &, RIGHT_OPERAND_TYPE const &right)
Definition: TensorDivide.hpp:196
RAJA_INLINE static RAJA_HOST_DEVICE result_type divide(TILE_TYPE const &tile, LEFT_OPERAND_TYPE const &left, RIGHT_OPERAND_TYPE const &right)
Definition: TensorDivide.hpp:207
RAJA_INLINE static RAJA_HOST_DEVICE result_type divide(TILE_TYPE const &tile, LEFT_OPERAND_TYPE const &left, RIGHT_OPERAND_TYPE const &right)
Definition: TensorDivide.hpp:117
RAJA_INLINE static RAJA_HOST_DEVICE int getDimSize(int dim, LEFT_OPERAND_TYPE const &left, RIGHT_OPERAND_TYPE const &)
Definition: TensorDivide.hpp:106
RAJA_INLINE static RAJA_HOST_DEVICE result_type divide(TILE_TYPE const &tile, LEFT_OPERAND_TYPE const &left, RIGHT_OPERAND_TYPE const &right)
Definition: TensorDivide.hpp:73
RAJA_INLINE static RAJA_HOST_DEVICE int getDimSize(int dim, LEFT_OPERAND_TYPE const &, RIGHT_OPERAND_TYPE const &right)
Definition: TensorDivide.hpp:62
RAJA_INLINE static RAJA_HOST_DEVICE result_type divide(TILE_TYPE const &tile, LEFT_OPERAND_TYPE const &left, RIGHT_OPERAND_TYPE const &right)
Definition: TensorDivide.hpp:163
RAJA_INLINE static RAJA_HOST_DEVICE int getDimSize(int dim, LEFT_OPERAND_TYPE const &left, RIGHT_OPERAND_TYPE const &)
Definition: TensorDivide.hpp:152
RAJA_INLINE static RAJA_HOST_DEVICE result_type divide(TILE_TYPE const &tile, LEFT_OPERAND_TYPE const &left, RIGHT_OPERAND_TYPE const &right)
Definition: TensorDivide.hpp:300
RAJA_INLINE static RAJA_HOST_DEVICE int getDimSize(int dim, LEFT_OPERAND_TYPE const &left, RIGHT_OPERAND_TYPE const &)
Definition: TensorDivide.hpp:289
Definition: TensorDivide.hpp:43
Definition: normalizeOperand.hpp:44