VisionCpp  0.0.1
eval_expr_reduction.hpp
Go to the documentation of this file.
1 // This file is part of VisionCpp, a lightweight C++ template library
2 // for computer vision and image processing.
3 //
4 // Copyright (C) 2016 Codeplay Software Limited. All Rights Reserved.
5 //
6 // Contact: visioncpp@codeplay.com
7 //
8 // Licensed under the Apache License, Version 2.0 (the "License");
9 // you may not use this file except in compliance with the License.
10 // You may obtain a copy of the License at
11 //
12 // http://www.apache.org/licenses/LICENSE-2.0
13 //
14 // Unless required by applicable law or agreed to in writing, software
15 // distributed under the License is distributed on an "AS IS" BASIS,
16 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 // See the License for the specific language governing permissions and
18 // limitations under the License.
19 
20 /// \file eval_expr_reduction.hpp
21 /// \brief This file contains the specialisation of the EvalExpr
22 /// for RDCN( reduction operation node).
23 
24 #ifndef VISIONCPP_INCLUDE_FRAMEWORK_EVALUATOR_EVAL_EXPRESSION_EVAL_EXPR_REDUCTION_HPP_
25 #define VISIONCPP_INCLUDE_FRAMEWORK_EVALUATOR_EVAL_EXPRESSION_EVAL_EXPR_REDUCTION_HPP_
26 
27 namespace visioncpp {
28 namespace internal {
29 /// \brief Partial specialisation of the EvalExpr when the expression is
30 /// an RDCN(reduction operation) expression.
31 template <typename C_OP, typename RHS, size_t Cols, size_t Rows, size_t LfType,
32  size_t LVL, typename Loc, typename... Params>
33 struct EvalExpr<RDCN<C_OP, RHS, Cols, Rows, LfType, LVL>, Loc, Params...> {
34  // no eval point
35  //-- -
36  /// \brief evaluate function when the internal::ops_category is NeighbourOP.
37  template <bool IsRoot, size_t Halo_Top, size_t Halo_Left, size_t Halo_Butt,
38  size_t Halo_Right, size_t Offset, size_t Index, size_t LC,
39  size_t LR>
40  static auto eval_neighbour(Loc &cOffset,
42  -> decltype(
44  t)) {
45  constexpr size_t OutOffset = OutputLocation<IsRoot, Offset + Index - 1>::ID;
46  constexpr bool isLocal =
47  Trait<typename tools::RemoveAll<decltype(
48  tools::tuple::get<OutOffset>(t))>::Type>::scope == scope::Local;
49  constexpr size_t LC_Ratio = RHS::CThread / Cols;
50  constexpr size_t LR_Ratio = RHS::RThread / Rows;
51  // lhs expression shared mem
52  auto nested_acc = EvalExpr<RHS, Loc, Params...>::template eval_neighbour<
53  false, Halo_Top, Halo_Left, Halo_Butt, Halo_Right,
54  Offset, Index - 1, LC, LR>(cOffset, t).get_pointer();
55 
56  if ((cOffset.l_c < (cOffset.cLRng / LC_Ratio)) &&
57  (cOffset.l_r < (cOffset.rLRng / LR_Ratio))) {
58  static constexpr size_t Neighbour_LC_Ratio =
59  LC_Ratio / (RHS::Type::Cols / Cols);
60  static constexpr size_t Neighbour_LR_Ratio =
61  LR_Ratio / (RHS::Type::Rows / Rows);
63  nested_acc, LC / Neighbour_LC_Ratio, LR / Neighbour_LR_Ratio);
64  size_t g_c = ((cOffset.g_c - cOffset.l_c) / LC_Ratio) + cOffset.l_c;
65  size_t g_r = ((cOffset.g_r - cOffset.l_r) / LR_Ratio) + cOffset.l_r;
66 
67  for (int i = 0; i < LC / LC_Ratio; i += (cOffset.cLRng / LC_Ratio)) {
68  if (get_compare<isLocal, LC / LC_Ratio, Cols>(cOffset.l_c, i, g_c)) {
69  for (size_t j = 0; j < LR / LR_Ratio;
70  j += (cOffset.rLRng / LR_Ratio)) {
71  if (get_compare<isLocal, LR / LR_Ratio, Rows>(cOffset.l_r, j,
72  g_r)) {
73  neighbour.set_offset((cOffset.l_c + i), (cOffset.l_r + j));
74  tools::tuple::get<OutOffset>(t).get_pointer()[calculate_index(
75  id_val<isLocal>(cOffset.l_c, g_c) + i,
76  id_val<isLocal>(cOffset.l_r, g_r) + j,
77  id_val<isLocal>(LC / LC_Ratio, Cols),
78  id_val<isLocal>(LR / LR_Ratio, Rows))] =
79  tools::convert<typename MemoryTrait<
80  LfType, decltype(tools::tuple::get<OutOffset>(t))>::Type>(
81  typename C_OP::OP()(neighbour));
82  }
83  }
84  }
85  }
86  }
87  // here you need to put a local barrier
88  cOffset.barrier();
89  // return the valid neighbour area for your parent
90  return tools::tuple::get<OutOffset>(t);
91  }
92  // eval global
93  template <bool IsRoot, size_t Offset, size_t Index, size_t LC, size_t LR>
94  static auto eval_global_neighbour(Loc &cOffset,
96  -> decltype(
98  t)) {
99  constexpr size_t OutOffset = OutputLocation<IsRoot, Offset + Index - 1>::ID;
100  constexpr bool isLocal =
101  Trait<typename tools::RemoveAll<decltype(
102  tools::tuple::get<OutOffset>(t))>::Type>::scope == scope::Local;
103  // lhs expression shared mem
104  auto nested_acc =
105  EvalExpr<RHS, Loc, Params...>::template eval_global_neighbour<
106  false, Offset, Index - 1, LC, LR>(cOffset, t).get_pointer();
107  // here the neighbour is the entire output
109  nested_acc, RHS::Type::Cols, RHS::Type::Rows);
110  for (int i = 0; i < LC; i += cOffset.cLRng) {
111  if (get_compare<isLocal, LC, Cols>(cOffset.l_c, i, cOffset.g_c)) {
112  for (int j = 0; j < LR; j += cOffset.rLRng) {
113  if (get_compare<isLocal, LR, Rows>(cOffset.l_r, j, cOffset.g_r)) {
114  reduction.set_offset(cOffset.g_c + i, cOffset.g_r + j);
115  tools::tuple::get<OutOffset>(t).get_pointer()[calculate_index(
116  id_val<isLocal>(cOffset.l_c, cOffset.g_c) + i,
117  id_val<isLocal>(cOffset.l_r, cOffset.g_r) + j,
118  id_val<isLocal>(LC, Cols), id_val<isLocal>(LR, Rows))] =
119  ((tools::convert<typename MemoryTrait<
120  LfType, decltype(tools::tuple::get<OutOffset>(t))>::Type>(
121  typename C_OP::OP()(reduction))));
122  }
123  }
124  }
125  }
126 
127  // here you need to put a local barrier
128  cOffset.barrier();
129  // return the valid neighbour area for your parent
130  return tools::tuple::get<OutOffset>(t);
131  }
132 };
133 } // internal
134 } // visioncpp
135 #endif // VISIONCPP_INCLUDE_FRAMEWORK_EVALUATOR_EVAL_EXPRESSION_EVAL_EXPR_REDUCTION_HPP_
EnableIf< k==0, typename ElemTypeHolder< 0, Tuple< Ts... > >::type & >::type get(Tuple< Ts... > &t)
get
Definition: tuple.hpp:99
T1 convert(T2 x)
function convert
Definition: convert.hpp:558
static size_t calculate_index(size_t c, size_t r, size_t cols, size_t rows)
function calculate_index
static constexpr ScopeType Local
VisionCpp namespace.
Definition: sycl/device.hpp:24
static auto eval_neighbour(Loc &cOffset, const tools::tuple::Tuple< Params... > &t) -> decltype(tools::tuple::get< OutputLocation< IsRoot, Offset+Index - 1 >::ID >(t))
evaluate function when the internal::ops_category is NeighbourOP.
static auto eval_global_neighbour(Loc &cOffset, const tools::tuple::Tuple< Params... > &t) -> decltype(tools::tuple::get< OutputLocation< IsRoot, Offset+Index - 1 >::ID >(t))
eval_global_neighbour function:
Definition: evaluator.hpp:195
GlobalNeighbour is used to provide local access for each element of the global memory based on the Co...
LocalNeighbour is used to provide local access for each element of the local memory based on the Coor...
This class is used to determine the ElementType of accessor template parameters.
This is used to find whether a node should use a global memory output or a local memory output is cre...
Definition: evaluator.hpp:265
The definition is in RDCN file.
Definition: reduction.hpp:42
This struct is used to trait the value type inside the accessor.
Definition: evaluator.hpp:89
These methods are used to remove all the & const and * from a type.
The tuple is a fixed-size collection of heterogeneous values.
Definition: tuple.hpp:48