VisionCpp  0.0.1
local_output.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 local_output.hpp
21 /// \brief This file contains the different specialisations of the LocalOutput
22 
23 #ifndef VISIONCPP_INCLUDE_FRAMEWORK_EXPR_CONVERTOR_LOCAL_OUTPUT_HPP_
24 #define VISIONCPP_INCLUDE_FRAMEWORK_EXPR_CONVERTOR_LOCAL_OUTPUT_HPP_
25 
26 namespace visioncpp {
27 namespace internal {
28 /// \brief OutputAccessor struct is used to generate an accessor when the node
29 /// is not root. When the node is root no local accessor will be created.
30 /// Therefore we eliminate the extra local memory for root node.
31 template <size_t IsRoot, size_t LeafType, size_t LC, size_t LR,
32  typename OutType>
34  static auto getTuple(cl::sycl::handler &cgh)
35  -> decltype(tools::tuple::make_tuple()) {
36  return tools::tuple::make_tuple();
37  }
38 };
39 /// \brief specialisation of OutputAccessor when a node is not a root node.
40 /// Here we create on output memory for the node.
41 template <size_t LeafType, size_t LC, size_t LR, typename OutType>
42 struct OutputAccessor<false, LeafType, LC, LR, OutType> {
43  using Accessor = cl::sycl::accessor<OutType, MemDimension<LeafType>::Dim,
44  cl::sycl::access::mode::read_write,
45  cl::sycl::access::target::local>;
46  static tools::tuple::Tuple<Accessor> getTuple(cl::sycl::handler &cgh) {
47  /// In get range the column is changed with row in order to set x as
48  /// column and y as row
49  return Accessor(get_range<MemDimension<LeafType>::Dim>(LR, LC), cgh);
50  }
51 };
52 
53 /// \brief LocalOutput accessor. The local output does nothing when the
54 /// operation type is point operation. If it is called when the whole expression
55 /// tree is point op or global op no local memory will be created. When the
56 /// combination of point op and NeighbourOP is used we consider the expression
57 /// tree as a NeighbourOP expression tree and generate a set of local memory.
58 /// template parameters:
59 /// \tparam PointOp: determines whether or not the overall expression tree is
60 /// pointOp
61 /// \tparam IsRoot: determines whether or not a node is a root node.
62 /// \tparam LC: determines the column size of the local memory
63 /// \tparam LR: determines the row size of the local memory
64 /// \tparam Expr: determines the type of the expression
65 template <bool PointOp, size_t IsRoot, size_t LC, size_t LR, typename Expr>
66 struct LocalOutput {
67  static constexpr size_t Out_LC = LC;
68  static constexpr size_t Out_LR = LR;
69  /// \brief getTuple function is used to create and wrap local memory into a
70  /// tuple
71  /// \param cgh : sycl command group handler.
72  static inline decltype(tools::tuple::make_tuple()) getTuple(
73  cl::sycl::handler &cgh) {
74  return tools::tuple::make_tuple();
75  }
76 };
77 
78 /// \brief specialisation of the LocalOutput for leaf node when the vision
79 /// memory is a const variable. We separate this from the specialisation of the
80 /// leaf node for LocalOutput because we don't need to create the local memory for
81 /// the Constant variable.
82 template <size_t IsRoot, bool in, size_t LC, size_t LR, size_t Width,
83  size_t Height, size_t element_category, size_t LVL, typename Sclr>
84 struct LocalOutput<
85  false, IsRoot, LC, LR,
86  LeafNode<VisionMemory<in, element_category, memory_type::Const, Sclr, Width,
87  Height, Sclr, 1, scope::Global, LVL>,
88  LVL>> {
89  static constexpr size_t Out_LC = LC;
90  static constexpr size_t Out_LR = LR;
91  static decltype(tools::tuple::make_tuple()) getTuple(cl::sycl::handler &cgh) {
92  return tools::tuple::make_tuple();
93  }
94 };
95 
96 /// \brief specialisation of the LocalOutput for leaf node when the vision
97 /// memory is a constant buffer. We separate this from the specialisation of the
98 /// leaf node for LocalOutput because we don't need to create the local memory for
99 /// an input data on a Constant buffer.
100 template <size_t IsRoot, bool in, size_t LC, size_t LR, size_t element_category,
101  size_t Memory_Type, typename Scalar, size_t Width, size_t Height,
102  typename ElementTp, size_t Elements, size_t LVL>
103 struct LocalOutput<
104  false, IsRoot, LC, LR,
105  LeafNode<VisionMemory<in, element_category, Memory_Type, Scalar, Width,
106  Height, ElementTp, Elements, scope::Constant, LVL>,
107  LVL>> {
108  static constexpr size_t Out_LC = LC;
109  static constexpr size_t Out_LR = LR;
110  static decltype(tools::tuple::make_tuple()) getTuple(cl::sycl::handler &cgh) {
111  return tools::tuple::make_tuple();
112  }
113 };
114 
115 /// \brief LocalOutput specialisation for leaf node it creates the local
116 /// accessor that contains the data of the leaf node from global memory. This
117 /// local memory then will be used by other non-terminal node as an input value.
118 template <size_t IsRoot, size_t LC, size_t LR, size_t LVL, typename RHS>
119 struct LocalOutput<false, IsRoot, LC, LR, LeafNode<RHS, LVL>> {
120  static constexpr size_t Out_LC = LC;
121  static constexpr size_t Out_LR = LR;
122  using Accessor = cl::sycl::accessor<typename RHS::ElementType, RHS::Dim,
123  cl::sycl::access::mode::read_write,
124  cl::sycl::access::target::local>;
125  static tools::tuple::Tuple<Accessor> getTuple(cl::sycl::handler &cgh) {
126  return Accessor(get_range<RHS::Dim>(LR, LC), cgh);
127  }
128 };
129 
130 /// \brief LocalOutput specialisation for unary operation(RUnOP) it creates the
131 /// local accessor to store the output of unary operation which is going to be
132 /// used as an output for its parent.
133 template <size_t IsRoot, size_t LC, size_t LR, typename OP, typename RHSExpr,
134  size_t Cols, size_t Rows, size_t LeafType, size_t LVL>
135 struct LocalOutput<false, IsRoot, LC, LR,
136  RUnOP<OP, RHSExpr, Cols, Rows, LeafType, LVL>> {
137  static constexpr size_t Out_LC =
139  static constexpr size_t Out_LR =
141  static auto getTuple(cl::sycl::handler &cgh) -> decltype(tools::tuple::append(
143  OutputAccessor<IsRoot, LeafType, Out_LC, Out_LR,
144  typename OP::OutType>::getTuple(cgh))) {
145  auto OutTuple = OutputAccessor<IsRoot, LeafType, Out_LC, Out_LR,
146  typename OP::OutType>::getTuple(cgh);
148  return tools::tuple::append(RHSTuple, OutTuple);
149  }
150 };
151 
152 /// \brief LocalOutput specialisation for binary operation(RBiOP) it creates the
153 /// local accessor to store the output of binary operation which is going to be
154 /// used as an output for its parent.
155 template <size_t IsRoot, size_t LC, size_t LR, typename OP, typename LHSExpr,
156  typename RHSExpr, size_t Cols, size_t Rows, size_t LeafType,
157  size_t LVL>
158 struct LocalOutput<false, IsRoot, LC, LR,
159  RBiOP<OP, LHSExpr, RHSExpr, Cols, Rows, LeafType, LVL>> {
160  static constexpr size_t lhs =
163  static constexpr size_t rhs =
166  static constexpr bool res = lhs < rhs;
168 
169  static constexpr size_t Out_LC =
171  static constexpr size_t Out_LR =
173 
174  static auto getTuple(cl::sycl::handler &cgh) -> decltype(tools::tuple::append(
178  OutputAccessor<IsRoot, LeafType, Out_LC, Out_LR,
179  typename OP::OutType>::getTuple(cgh))) {
180  auto OutTuple = OutputAccessor<IsRoot, LeafType, Out_LC, Out_LR,
181  typename OP::OutType>::getTuple(cgh);
184  return tools::tuple::append(tools::tuple::append(LHSTuple, RHSTuple),
185  OutTuple);
186  }
187 };
188 /// \brief LocalOutput specialisation for binary neighbour operation(StnFilt).
189 /// It creates the local accessor to store the output of neighbour operation
190 /// which is going to be used as an output for its parent.
191 template <size_t IsRoot, size_t LC, size_t LR, typename OP, size_t Halo_T,
192  size_t Halo_L, size_t Halo_B, size_t Halo_R, typename LHSExpr,
193  typename RHSExpr, size_t Cols, size_t Rows, size_t LeafType,
194  size_t LVL>
195 struct LocalOutput<false, IsRoot, LC, LR,
196  StnFilt<OP, Halo_T, Halo_L, Halo_B, Halo_R, LHSExpr, RHSExpr,
197  Cols, Rows, LeafType, LVL>> {
198  static constexpr size_t Halo_COL = Halo_L + Halo_R;
199  static constexpr size_t Halo_ROW = Halo_T + Halo_B;
200  static constexpr size_t Out_LC =
202  Halo_COL;
203  static constexpr size_t Out_LR =
205  Halo_ROW;
206 
207  static auto getTuple(cl::sycl::handler &cgh) -> decltype(tools::tuple::append(
209  LocalOutput<false, false, LC + Halo_COL, LR + Halo_ROW,
210  LHSExpr>::getTuple(cgh),
212  OutputAccessor<IsRoot, LeafType, Out_LC, Out_LR,
213  typename OP::OutType>::getTuple(cgh))) {
214  auto OutTuple = OutputAccessor<IsRoot, LeafType, Out_LC, Out_LR,
215  typename OP::OutType>::getTuple(cgh);
216  auto LHSTuple = LocalOutput<false, false, LC + Halo_COL, LR + Halo_ROW,
217  LHSExpr>::getTuple(cgh);
218 
220 
221  return tools::tuple::append(tools::tuple::append(LHSTuple, RHSTuple),
222  OutTuple);
223  }
224 };
225 
226 /// \brief LocalOutput specialisation for unary neighbour operation(StnNoFilt).
227 /// It creates the local accessor to store the output of neighbour operation
228 /// which is going to be used as an output for its parent.
229 template <size_t IsRoot, size_t LC, size_t LR, typename OP, size_t Halo_T,
230  size_t Halo_L, size_t Halo_B, size_t Halo_R, typename RHSExpr,
231  size_t Cols, size_t Rows, size_t LeafType, size_t LVL>
232 struct LocalOutput<false, IsRoot, LC, LR,
233  StnNoFilt<OP, Halo_T, Halo_L, Halo_B, Halo_R, RHSExpr, Cols,
234  Rows, LeafType, LVL>> {
235  static constexpr size_t Halo_COL = Halo_L + Halo_R;
236  static constexpr size_t Halo_ROW = Halo_T + Halo_B;
237  static constexpr size_t Out_LC =
239  Halo_COL;
240  static constexpr size_t Out_LR =
242  Halo_ROW;
243 
244  static auto getTuple(cl::sycl::handler &cgh) -> decltype(tools::tuple::append(
245  LocalOutput<false, false, LC + Halo_COL, LR + Halo_ROW,
246  RHSExpr>::getTuple(cgh),
247  OutputAccessor<IsRoot, LeafType, Out_LC, Out_LR,
248  typename OP::OutType>::getTuple(cgh))) {
249  auto OutTuple = OutputAccessor<IsRoot, LeafType, Out_LC, Out_LR,
250  typename OP::OutType>::getTuple(cgh);
251  auto RHSTuple = LocalOutput<false, false, LC + Halo_COL, LR + Halo_ROW,
252  RHSExpr>::getTuple(cgh);
253 
254  return tools::tuple::append(RHSTuple, OutTuple);
255  }
256 };
257 
258 /// \brief LocalOutput specialisation for reduction neighbour operation(RDCN).
259 /// It creates the local accessor to store the output of the operation
260 /// which is going to be used as an output for its parent.
261 template <size_t IsRoot, size_t LC, size_t LR, typename OP, typename RHSExpr,
262  size_t Cols, size_t Rows, size_t LeafType, size_t LVL>
263 struct LocalOutput<false, IsRoot, LC, LR,
264  RDCN<OP, RHSExpr, Cols, Rows, LeafType, LVL>> {
265  // Here we don't use x and y thread because it has already been calculated
266  // through Out_LC and Out_LR. When we come here it means that local sampler is
267  // used not the global one
268  static constexpr size_t LC_Ratio = RHSExpr::Type::Cols / Cols;
269  static constexpr size_t LR_Ratio = RHSExpr::Type::Rows / Rows;
270  static constexpr size_t Out_LC =
272  static constexpr size_t Out_LR =
274  static auto getTuple(cl::sycl::handler &cgh) -> decltype(tools::tuple::append(
276  OutputAccessor<IsRoot, LeafType, Out_LC, Out_LR,
277  typename OP::OutType>::getTuple(cgh))) {
278  auto OutTuple = OutputAccessor<IsRoot, LeafType, Out_LC, Out_LR,
279  typename OP::OutType>::getTuple(cgh);
281  return tools::tuple::append(RHSTuple, OutTuple);
282  }
283 };
284 
285 /// \brief LocalOutput specialisation for point operation(ParallelCopy).
286 /// It creates the local accessor to store the output of the operation
287 /// which is going to be used as an output for its parent.
288 template <size_t IsRoot, size_t LC, size_t LR, typename LHSExpr,
289  typename RHSExpr, size_t Cols, size_t Rows, size_t OffsetColIn,
290  size_t OffsetRowIn, size_t OffsetColOut, size_t OffsetRowOut,
291  size_t LeafType, size_t LVL>
292 struct LocalOutput<
293  false, IsRoot, LC, LR,
294  ParallelCopy<LHSExpr, RHSExpr, Cols, Rows, OffsetColIn, OffsetRowIn,
295  OffsetColOut, OffsetRowOut, LeafType, LVL>> {
296  static auto getTuple(cl::sycl::handler &cgh)
299  }
300 };
301 
302 /// \brief LocalOutput specialisation for point operation(Assign).
303 /// It creates the local accessor to store the output of the operation
304 /// which is going to be used as an output for its parent.
305 template <size_t IsRoot, size_t LC, size_t LR, typename LHSExpr,
306  typename RHSExpr, size_t Cols, size_t Rows, size_t LeafType,
307  size_t LVL>
308 struct LocalOutput<false, IsRoot, LC, LR,
309  Assign<LHSExpr, RHSExpr, Cols, Rows, LeafType, LVL>> {
310  static auto getTuple(cl::sycl::handler &cgh)
313  }
314 };
315 
316 /// \brief create_local_accessors is a deduction function for creating local
317 /// accessor.
318 /// parameters:
319 /// \param cgh: sycl command group handler
320 /// \return Tuple
321 
322 template <size_t LC, size_t LR, typename Expr>
323 inline auto create_local_accessors(cl::sycl::handler &cgh)
324  -> decltype(LocalOutput<Expr::Operation_type != ops_category::NeighbourOP,
325  true, LC, LR, Expr>::getTuple(cgh)) {
326  return LocalOutput<Expr::Operation_type != ops_category::NeighbourOP, true,
327  LC, LR, Expr>::getTuple(cgh);
328 }
329 } // internal
330 } // visioncpp
331 #endif // VISIONCPP_INCLUDE_FRAMEWORK_EXPR_CONVERTOR_LOCAL_OUTPUT_HPP_
Tuple< Args..., T > append(Tuple< Args... > t, T a)
append
Definition: tuple.hpp:235
Tuple< Args... > make_tuple(Args... args)
make_tuple
Definition: tuple.hpp:153
cl::sycl::range< Dim > get_range(size_t r, size_t c)
function get_range
Definition: memory.hpp:120
auto create_local_accessors(cl::sycl::handler &cgh) -> decltype(LocalOutput< Expr::Operation_type !=ops_category::NeighbourOP, true, LC, LR, Expr >::getTuple(cgh))
create_local_accessors is a deduction function for creating local accessor.
static constexpr size_t Const
static constexpr ScopeType Constant
static constexpr ScopeType Global
VisionCpp namespace.
Definition: sycl/device.hpp:24
The definition is in Assign file.
Definition: assign.hpp:44
the definition is in LeafNode.
Definition: leaf_node.hpp:38
static auto getTuple(cl::sycl::handler &cgh) -> decltype(LocalOutput< false, IsRoot, LC, LR, RHSExpr >::getTuple(cgh))
cl::sycl::accessor< typename RHS::ElementType, RHS::Dim, cl::sycl::access::mode::read_write, cl::sycl::access::target::local > Accessor
static tools::tuple::Tuple< Accessor > getTuple(cl::sycl::handler &cgh)
static auto getTuple(cl::sycl::handler &cgh) -> decltype(tools::tuple::append(tools::tuple::append(LocalOutput< false, false, LC, LR, LHSExpr >::getTuple(cgh), LocalOutput< false, false, LC, LR, RHSExpr >::getTuple(cgh)), OutputAccessor< IsRoot, LeafType, Out_LC, Out_LR, typename OP::OutType >::getTuple(cgh)))
static auto getTuple(cl::sycl::handler &cgh) -> decltype(tools::tuple::append(LocalOutput< false, false, LC, LR, RHSExpr >::getTuple(cgh), OutputAccessor< IsRoot, LeafType, Out_LC, Out_LR, typename OP::OutType >::getTuple(cgh)))
static auto getTuple(cl::sycl::handler &cgh) -> decltype(tools::tuple::append(LocalOutput< false, false, LC, LR, RHSExpr >::getTuple(cgh), OutputAccessor< IsRoot, LeafType, Out_LC, Out_LR, typename OP::OutType >::getTuple(cgh)))
static auto getTuple(cl::sycl::handler &cgh) -> decltype(tools::tuple::append(tools::tuple::append(LocalOutput< false, false, LC+Halo_COL, LR+Halo_ROW, LHSExpr >::getTuple(cgh), LocalOutput< false, false, LC, LR, RHSExpr >::getTuple(cgh)), OutputAccessor< IsRoot, LeafType, Out_LC, Out_LR, typename OP::OutType >::getTuple(cgh)))
static auto getTuple(cl::sycl::handler &cgh) -> decltype(tools::tuple::append(LocalOutput< false, false, LC+Halo_COL, LR+Halo_ROW, RHSExpr >::getTuple(cgh), OutputAccessor< IsRoot, LeafType, Out_LC, Out_LR, typename OP::OutType >::getTuple(cgh)))
LocalOutput:Local output is used for neighbour operation in order to create a local memory for the ou...
static constexpr size_t Out_LC
static decltype(tools::tuple::make_tuple()) getTuple(cl::sycl::handler &cgh)
getTuple function is used to create and wrap local memory into a tuple
static constexpr size_t Out_LR
this is used to determine the dimension of the memory based on the memory type template parameters:
Definition: memory.hpp:294
static tools::tuple::Tuple< Accessor > getTuple(cl::sycl::handler &cgh)
cl::sycl::accessor< OutType, MemDimension< LeafType >::Dim, cl::sycl::access::mode::read_write, cl::sycl::access::target::local > Accessor
OutputAccessor struct is used to generate an accessor when the node is not root.
static auto getTuple(cl::sycl::handler &cgh) -> decltype(tools::tuple::make_tuple())
The definition is in ParallelCopy file.
The definition is in RBiOP file.
The definition is in RDCN file.
Definition: reduction.hpp:42
The definition is in RUnOP file.
The definition is in StnFilt file.
The definition is in StnNoFilt file.
Definition of VisionMemory.
Definition: mem_vision.hpp:53
The tuple is a fixed-size collection of heterogeneous values.
Definition: tuple.hpp:48