VisionCpp  0.0.1
evaluator.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 evaluator.hpp
21 /// \brief This file contains a collection of headers and forward declaration
22 /// for evaluating an expression tree.
23 
24 #ifndef VISIONCPP_INCLUDE_FRAMEWORK_EVALUATOR_EVALUATOR_HPP_
25 #define VISIONCPP_INCLUDE_FRAMEWORK_EVALUATOR_EVALUATOR_HPP_
26 
27 namespace visioncpp {
28 namespace internal {
29 /// \struct GetGlobalRange
30 /// \brief GetGlobalRange is used to check the range when the halo is applied
31 /// template parameters
32 /// \tparam Halo is the halo used around the image
33 /// \tparam DimSize is the size of the dimension we want to check
34 template <size_t Halo, size_t DimSize>
36  /// function get_global_range checks the range and pass the correct value as
37  /// an index
38  /// parameters:
39  /// \param index is the passed index to be checked and corrected if needed
40  /// \return size_t
41  static size_t inline get_global_range(size_t index) {
42  size_t val = index;
43  if (val < Halo)
44  val = 0;
45  else if (val >= DimSize)
46  val = DimSize - 1;
47  else
48  val -= Halo;
49  return val;
50  }
51 };
52 /// \brief specialisation of GetGlobalRange when the Halo is 0
53 template <size_t DimSize>
54 struct GetGlobalRange<0, DimSize> {
55  /// function get_global_range checks the range and pass the correct value as
56  /// an index
57  /// parameters:
58  /// \param index is the passed index to be checked and corrected if needed
59  /// \return size_t
60  static size_t inline get_global_range(size_t index) {
61  return ((index < DimSize) ? index : DimSize - 1);
62  }
63 };
64 /// \brief template deduction function for get_global_range
65 /// template parameters:
66 /// \tparam Halo is the halo used around the image
67 /// \tparam DimSize is the size of the dimension we want to check
68 /// function parameters:
69 /// \param index is the passed index to be checked and corrected if needed
70 /// \return size_t
71 template <size_t Halo, size_t DimSize>
72 static size_t inline get_global_range(size_t index) {
74 }
75 /// \struct Fill
76 /// \brief The Fill is used to load a rectangle neighbour area from
77 /// global memory to local memory. However, when the memory is constant or
78 /// located in device constant memory we do not create a load for them in shared
79 /// memory. LR and LC determines the valid size of local memory for the parent
80 /// of this function, the child can add its own valid size to it for its
81 /// calculation. This will happen when we have StnFilt
82 /// template parameters
83 /// \tparam Expr : the leaf node expression
84 /// \tparam Sc : the sycl target representing the location of the buffer on the
85 /// device memory
86 /// \tparam Loc the coordinate needed to be accessed
87 /// \tparam Params... tuple of accessors
88 template <typename Expr, typename Loc, typename... Params>
89 struct Fill;
90 /// \struct Trait
91 /// \brief This struct is used to trait the value type inside the accessor
92 template <typename T>
93 struct Trait;
94 /// specialisation of the Trait class when the accessor is sycl accessor
95 template <typename elementType, int dimensions,
96  cl::sycl::access::mode accessMode,
97  cl::sycl::access::target accessTarget>
98 struct Trait<
99  cl::sycl::accessor<elementType, dimensions, accessMode, accessTarget>> {
100  using Type = elementType;
101  static constexpr int Dim = dimensions;
102  static constexpr size_t scope = ConvertToVisionScope<accessTarget>::scope;
103 };
104 /// specialisation of the Trait class when the accessor is on ConstMemory
105 template <typename T>
107  using Type = T;
108  static constexpr size_t scope = scope::Global;
109 };
110 
111 /// \struct Index_Finder This struct is used to find the index required to
112 /// access the accessor inside the buffer.
113 /// template parameters
114 /// \tparam N the location of the global memory
115 /// \tparam Index the location of the local memory if exists
116 /// \tparam LeafType the type of the memory
117 /// \tparam Sc the location of the buffer on the device memory
118 template <size_t N, size_t Indx, size_t LeafType, size_t Sc>
119 struct Index_Finder {
120  static constexpr size_t Index = Indx;
121 };
122 /// specialisation of the Index_Finder when the memory_type is a constant variable
123 template <size_t N, size_t Indx, size_t Sc>
124 struct Index_Finder<N, Indx, memory_type::Const, Sc> {
125  static constexpr size_t Index = N;
126 };
127 
128 /// specialisation of the Index_Finder when the memory located on device
129 /// constant memory
130 template <size_t N, size_t Indx, size_t LeafType>
131 struct Index_Finder<N, Indx, LeafType, scope::Constant> {
132  static constexpr size_t Index = N;
133 };
134 
135 /// \brief the root of the expression tree. It is used to avoid extra creation
136 /// of the shared memory for the LHS of the root node.
137 /// The are two types of nodes that can be the root of the expression tree.
138 /// ParallelCopy and assign.
139 /// An expression tree can be evaluated in three ways, depending on the type of
140 /// operation it represents. A global operation node represents that the
141 /// operation requires to access the entire input or non-linear area of input to
142 /// calculate an element of the output; a neighbour operation node requires to
143 /// access a linear area of the input in order to calculate the output; and a
144 /// point operation node requires a corresponding elements of the input to
145 /// calculate an elements of the output. Therefore, we have tree types of
146 /// Operations. GlobalNeighbourOP, NeighbourOP, PointOP. Thus, 6 specialisation
147 /// of Evaluator template struct has been provided. In an expression tree with
148 /// the mixed types of nodes following rules will be applied. \n
149 /// 1) If an expression tree contains a combination of point and neighbour
150 /// operations nodes, the neighbour operation will be used for the evaluation of
151 /// the expression tree without splitting the expression tree into small
152 /// sub-trees. In this case only one kernel will be executed. \n
153 /// 2)If an expression tree has global operation node in the middle of the tree,
154 /// the expression tree will be split in to 3 sub-trees. One before the
155 /// global operation node; one is the global operation node; and one is the
156 /// nodes after global expression node. \n
157 /// 3) If the global operation is the root of the expression tree, the
158 /// expression will be split in to two sub-trees. \n
159 /// 4) If the child of the global operation node is a leaf node, the child will
160 /// not be split in to a sub-tree. The eval struct has been
161 /// specialised
162 /// based on the operation types of the expression tree, in order to call the
163 /// appropriate function.\n
164 /// These specialisation of Evaluator class are located in
165 /// eval_root/eval_assign.hpp and eval_root/eval_partial_assign.hpp
166 /// files.
167 /// Typical usage:
168 /// \code
169 /// \endcode
170 ///
171 /// Template parameters:
172 /// \param Offset: the starting offset of the output shared
173 /// \param memories inside the input tuple.
174 /// \param Output_Index: the required step from offset in order to
175 /// \param access the output memory of the current expression
176 /// \param LHS: the left-hand size expression
177 /// \param RHS: then right-hand size expression
178 /// \param internal::ops_category: the type of the operation
179 /// \param LC: the shared memory column size
180 /// \param LR: the shared memory row size
181 /// \param Cols: output memory column size
182 /// \param Rows: output memory row size
183 /// \param LVL: the depth of the subexpression root in the expression tree
184 /// \param LfType: the type of the output memory
185 /// \param Loc: Coordinate of accessing a particular location
186 /// \param Params: the input/output memories
187 ///
188 /// eval function parameters:
189 /// \param cOffset Coordinate of accessing a particular location.
190 /// \param t: tuple of input/output memories
191 ///
192 /// \returns void.
193 template <size_t OPT, size_t Output_Index, size_t Offset, size_t LC, size_t LR,
194  typename Expr, typename Loc, typename... Params>
195 struct Evaluator;
196 
197 /// \struct EvalExpr
198 /// \brief is used to convert the static expression tree to the runtime the
199 /// expression tree when it is not a root of an expression tree. It is used to
200 /// calculate the runtime evaluation of the specified operators for each node.
201 /// The runtime Executor expression tree can be specialised per device through
202 /// template parameters. Each primary node in an expression tree will have an
203 /// equivalent node in the evaluation expression tree. An expression tree can be
204 /// evaluated in three ways, depending on the type of
205 /// operation it represents.
206 /// A point operation node is evaluated through eval_point function; a
207 /// neighbour
208 /// operation node is evaluated by eval_neighbour; and a global operation node
209 /// is evaluated by eval_global_neighbour. The specialisation of EvalExpr
210 /// located on eval_expression folder.
211 /// Template parameters
212 /// \param Expr: the expression node required to be executed.
213 /// \param Loc: Coordinate of accessing a particular location
214 /// \param params: the input/output memories
215 /// eval_point function: \brief point operation evaluation.
216 /// \param cOffset: coordinate of accessing a particular location.
217 /// \param t: tuple of the input/output memories
218 /// \return the calculated memory element (pixel)
219 /// \n
220 /// eval_neighbour function: \brief neighbour operation evaluation.
221 /// \param IsRoot: check whether or not this node should use the global memory
222 /// as an output memory or a local memory. This is used to avoid the last local
223 /// memory between assign and the immediate RHS expression in Assign.
224 /// \param Halo_Top: pass the top side value of halo for row of the local memory
225 /// \param Halo_Left: pass the left side value of halo for column of the local
226 /// memory
227 /// \param Halo_Butt: pass the bottom side value of halo for row of the local
228 /// memory
229 /// \param Halo_Right: pass the right side value of halo for column of the local
230 /// memory
231 /// \param Offset: determines the starting location of the local output memory
232 /// in the input tuple.
233 /// \param Index: represent the distance of the local memory in the tuple for
234 /// this node from the Offset.
235 /// \param LC: determines the local memory column size.
236 /// \param LR: determines the local memory row size.
237 /// \return the reference to the output memory block calculated the value.
238 
239 /// eval_global_neighbour function: \brief global operation evaluation
240 /// \param IsRoot: check whether or not this node should use the global memory
241 /// as an output memory or a local memory. This is used to avoid the last local
242 /// memory between assign and the immediate RHS expression in Assign.
243 /// \param Offset: determines the starting location of the local output memory
244 /// in the input tuple.
245 /// \param Index: represent the distance of the local memory in the tuple for
246 /// this node from the Offset.
247 /// \param LC: determines the local memory column size.
248 /// \param LR: determines the local memory row size.
249 /// \return the reference to the output memory block calculated the value.
250 
251 template <typename Expr, typename Loc, typename... Params>
252 struct EvalExpr;
253 
254 /// \struct OutputLocation
255 /// \brief This is used to find whether a node should use a global memory
256 /// output or a local memory output is created for that node. When the node is
257 /// the immediate child of the root (Assign or Partial Assign) we do not create
258 /// the local shared memory for it and directly save the result in the global
259 /// memory. In this case we can avoid creation of unnecessary shared memory.
260 /// template parameters
261 /// \tparam IsRoot boolean value represent if the expression is the immediate
262 /// child of a root node
263 /// \tparam OutOffset: the offset for location of the local memory if it exists
264 template <bool IsRoot, size_t OutOffset>
266  static constexpr size_t ID = OutOffset;
267 };
268 /// \brief specialisation of the OutputLocation when the node is the immediate
269 /// child of the root node
270 template <size_t OutOffset>
271 struct OutputLocation<true, OutOffset> {
272  static constexpr size_t ID = 0;
273 };
274 /// \brief template deduction for Fill struct.
275 template <size_t Halo_Top, size_t Halo_Left, size_t Halo_Butt,
276  size_t Halo_Right, size_t Offset, size_t LC, size_t LR, size_t Sc,
277  typename Expr, typename Loc, typename... Params>
279  Loc &cOffset, const internal::tools::tuple::Tuple<Params...> &t);
280 
281 /// \brief deduction function for Evaluator struct.
282 template <size_t Offset, size_t LC, size_t LR, typename Expr, typename Loc,
283  typename... Params>
284 inline void eval(Loc &cOffset, const tools::tuple::Tuple<Params...> &t) {
285  /// \brief This will count N+1 where the number of memory is N. However the N+1 is
286  /// useless as it does not exist and is going to be replaced by the final output
287  /// node in the expression tree trough OutputLocation struct.
288  constexpr size_t Index = LocalMemCount<Expr::ND_Category, Expr>::Count;
289  Evaluator<Expr::Operation_type, Index, Offset, LC, LR, Expr, Loc,
290  Params...>::eval(cOffset, t);
291 }
292 } // internal
293 } // visioncpp
294 
299 #endif // VISIONCPP_INCLUDE_FRAMEWORK_EVALUATOR_EVALUATOR_HPP_
This file contains the specialisation of the Evaluator struct for assign when it is a root struct.
This file contains the specialisation of the Evaluator struct for assign when it is a root struct.
This file contains a collection of headers that required for eval_expression.
static size_t get_global_range(size_t index)
template deduction function for get_global_range template parameters:
Definition: evaluator.hpp:72
static void fill_local_neighbour(Loc &cOffset, const internal::tools::tuple::Tuple< Params... > &t)
template deduction for Fill struct.
void eval(Loc &cOffset, const tools::tuple::Tuple< Params... > &t)
deduction function for Evaluator struct.
Definition: evaluator.hpp:284
static constexpr size_t Const
static constexpr ScopeType Constant
static constexpr ScopeType Global
VisionCpp namespace.
Definition: sycl/device.hpp:24
this file contains the partial specialisation of the Fill for LeafNode
The definition can be found in ConstMemory.
Definition: mem_const.hpp:38
this struct is used to convert the sycl target to visioncpp target
Definition: memory.hpp:171
eval_global_neighbour function:
Definition: evaluator.hpp:195
the root of the expression tree.
Definition: evaluator.hpp:195
The Fill is used to load a rectangle neighbour area from global memory to local memory.
Definition: evaluator.hpp:89
static size_t get_global_range(size_t index)
function get_global_range checks the range and pass the correct value as an index parameters:
Definition: evaluator.hpp:60
GetGlobalRange is used to check the range when the halo is applied template parameters.
Definition: evaluator.hpp:35
static size_t get_global_range(size_t index)
function get_global_range checks the range and pass the correct value as an index parameters:
Definition: evaluator.hpp:41
is used to find the index required to access the accessor inside the buffer.
Definition: evaluator.hpp:119
static constexpr size_t Index
Definition: evaluator.hpp:120
is used to count the total number of local memory for the subxpression.
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
static constexpr size_t ID
Definition: evaluator.hpp:266
This struct is used to trait the value type inside the accessor.
Definition: evaluator.hpp:89
The tuple is a fixed-size collection of heterogeneous values.
Definition: tuple.hpp:48