Viskores  1.0
serial/internal/TaskTiling.h
Go to the documentation of this file.
1 //============================================================================
2 // The contents of this file are covered by the Viskores license. See
3 // LICENSE.txt for details.
4 //
5 // By contributing to this file, all contributors agree to the Developer
6 // Certificate of Origin Version 1.1 (DCO 1.1) as stated in DCO.txt.
7 //============================================================================
8 
9 //============================================================================
10 // Copyright (c) Kitware, Inc.
11 // All rights reserved.
12 // See LICENSE.txt for details.
13 //
14 // This software is distributed WITHOUT ANY WARRANTY; without even
15 // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
16 // PURPOSE. See the above copyright notice for more information.
17 //============================================================================
18 
19 #ifndef viskores_exec_serial_internal_TaskTiling_h
20 #define viskores_exec_serial_internal_TaskTiling_h
21 
22 #include <viskores/exec/TaskBase.h>
23 
24 //Todo: rename this header to TaskInvokeWorkletDetail.h
26 
27 namespace viskores
28 {
29 namespace exec
30 {
31 namespace serial
32 {
33 namespace internal
34 {
35 
36 template <typename WType>
37 VISKORES_NEVER_EXPORT void TaskTilingSetErrorBuffer(
38  void* w,
39  const viskores::exec::internal::ErrorMessageBuffer& buffer)
40 {
41  using WorkletType = typename std::remove_cv<WType>::type;
42  WorkletType* const worklet = static_cast<WorkletType*>(w);
43  worklet->SetErrorMessageBuffer(buffer);
44 }
45 
46 template <typename WType, typename IType>
47 VISKORES_NEVER_EXPORT void TaskTiling1DExecute(void* w,
48  void* const v,
49  viskores::Id start,
50  viskores::Id end)
51 {
52  using WorkletType = typename std::remove_cv<WType>::type;
53  using InvocationType = typename std::remove_cv<IType>::type;
54 
55  WorkletType const* const worklet = static_cast<WorkletType*>(w);
56  InvocationType const* const invocation = static_cast<InvocationType*>(v);
57 
58  for (viskores::Id index = start; index < end; ++index)
59  {
60  //Todo: rename this function to DoTaskInvokeWorklet
61  viskores::exec::internal::detail::DoWorkletInvokeFunctor(
62  *worklet,
63  *invocation,
64  worklet->GetThreadIndices(index,
65  invocation->OutputToInputMap,
66  invocation->VisitArray,
67  invocation->ThreadToOutputMap,
68  invocation->GetInputDomain()));
69  }
70 }
71 
72 template <typename FType>
73 VISKORES_NEVER_EXPORT void FunctorTiling1DExecute(void* f,
74  void* const,
75  viskores::Id start,
76  viskores::Id end)
77 {
78  using FunctorType = typename std::remove_cv<FType>::type;
79  FunctorType const* const functor = static_cast<FunctorType*>(f);
80 
81  for (viskores::Id index = start; index < end; ++index)
82  {
83  functor->operator()(index);
84  }
85 }
86 
87 template <typename WType, typename IType>
88 VISKORES_NEVER_EXPORT void TaskTiling3DExecute(void* w,
89  void* const v,
90  const viskores::Id3& maxSize,
91  viskores::Id istart,
92  viskores::Id iend,
93  viskores::Id j,
94  viskores::Id k)
95 {
96  using WorkletType = typename std::remove_cv<WType>::type;
97  using InvocationType = typename std::remove_cv<IType>::type;
98 
99  WorkletType const* const worklet = static_cast<WorkletType*>(w);
100  InvocationType const* const invocation = static_cast<InvocationType*>(v);
101 
102  viskores::Id3 index(istart, j, k);
103  auto threadIndex1D = index[0] + maxSize[0] * (index[1] + maxSize[1] * index[2]);
104  for (viskores::Id i = istart; i < iend; ++i, ++threadIndex1D)
105  {
106  index[0] = i;
107  //Todo: rename this function to DoTaskInvokeWorklet
108  viskores::exec::internal::detail::DoWorkletInvokeFunctor(
109  *worklet,
110  *invocation,
111  worklet->GetThreadIndices(threadIndex1D,
112  index,
113  invocation->OutputToInputMap,
114  invocation->VisitArray,
115  invocation->ThreadToOutputMap,
116  invocation->GetInputDomain()));
117  }
118 }
119 
120 template <typename FType>
121 VISKORES_NEVER_EXPORT void FunctorTiling3DExecute(void* f,
122  void* const,
123  const viskores::Id3& viskoresNotUsed(maxSize),
124  viskores::Id istart,
125  viskores::Id iend,
126  viskores::Id j,
127  viskores::Id k)
128 {
129  using FunctorType = typename std::remove_cv<FType>::type;
130  FunctorType const* const functor = static_cast<FunctorType*>(f);
131 
132  viskores::Id3 index(istart, j, k);
133  for (viskores::Id i = istart; i < iend; ++i)
134  {
135  index[0] = i;
136  functor->operator()(index);
137  }
138 }
139 
140 // TaskTiling1D represents an execution pattern for a worklet
141 // that is best expressed in terms of single dimension iteration space. TaskTiling1D
142 // also states that for best performance a linear consecutive range of values
143 // should be given to the worklet for optimal performance.
144 //
145 // Note: The worklet and invocation must have a lifetime that is at least
146 // as long as the Task
147 class VISKORES_NEVER_EXPORT TaskTiling1D : public viskores::exec::TaskBase
148 {
149 public:
150  TaskTiling1D()
151  : Worklet(nullptr)
152  , Invocation(nullptr)
153  {
154  }
155 
159  template <typename FunctorType>
160  TaskTiling1D(FunctorType& functor)
161  : Worklet(nullptr)
162  , Invocation(nullptr)
163  , ExecuteFunction(nullptr)
164  , SetErrorBufferFunction(nullptr)
165  {
166  //Setup the execute and set error buffer function pointers
167  this->ExecuteFunction = &FunctorTiling1DExecute<FunctorType>;
168  this->SetErrorBufferFunction = &TaskTilingSetErrorBuffer<FunctorType>;
169 
170  //Bind the Worklet to void*
171  this->Worklet = (void*)&functor;
172  }
173 
176  template <typename WorkletType, typename InvocationType>
177  TaskTiling1D(WorkletType& worklet, InvocationType& invocation)
178  : Worklet(nullptr)
179  , Invocation(nullptr)
180  , ExecuteFunction(nullptr)
181  , SetErrorBufferFunction(nullptr)
182  {
183  //Setup the execute and set error buffer function pointers
184  this->ExecuteFunction = &TaskTiling1DExecute<WorkletType, InvocationType>;
185  this->SetErrorBufferFunction = &TaskTilingSetErrorBuffer<WorkletType>;
186 
187  //Bind the Worklet and Invocation to void*
188  this->Worklet = (void*)&worklet;
189  this->Invocation = (void*)&invocation;
190  }
191 
195  TaskTiling1D(TaskTiling1D& task)
196  : Worklet(task.Worklet)
197  , Invocation(task.Invocation)
198  , ExecuteFunction(task.ExecuteFunction)
199  , SetErrorBufferFunction(task.SetErrorBufferFunction)
200  {
201  }
202 
203  TaskTiling1D(TaskTiling1D&& task) = default;
204 
205  void SetErrorMessageBuffer(const viskores::exec::internal::ErrorMessageBuffer& buffer)
206  {
207  this->SetErrorBufferFunction(this->Worklet, buffer);
208  }
209 
210  void operator()(viskores::Id start, viskores::Id end) const
211  {
212  this->ExecuteFunction(this->Worklet, this->Invocation, start, end);
213  }
214 
215 protected:
216  void* Worklet;
217  void* Invocation;
218 
219  using ExecuteSignature = void (*)(void*, void* const, viskores::Id, viskores::Id);
220  ExecuteSignature ExecuteFunction;
221 
222  using SetErrorBufferSignature = void (*)(void*,
223  const viskores::exec::internal::ErrorMessageBuffer&);
224  SetErrorBufferSignature SetErrorBufferFunction;
225 };
226 
227 // TaskTiling3D represents an execution pattern for a worklet
228 // that is best expressed in terms of an 3 dimensional iteration space. TaskTiling3D
229 // also states that for best performance a linear consecutive range of values
230 // in the X dimension should be given to the worklet for optimal performance.
231 //
232 // Note: The worklet and invocation must have a lifetime that is at least
233 // as long as the Task
234 class VISKORES_NEVER_EXPORT TaskTiling3D : public viskores::exec::TaskBase
235 {
236 public:
237  TaskTiling3D()
238  : Worklet(nullptr)
239  , Invocation(nullptr)
240  {
241  }
242 
246  template <typename FunctorType>
247  TaskTiling3D(FunctorType& functor)
248  : Worklet(nullptr)
249  , Invocation(nullptr)
250  , ExecuteFunction(nullptr)
251  , SetErrorBufferFunction(nullptr)
252  {
253  //Setup the execute and set error buffer function pointers
254  this->ExecuteFunction = &FunctorTiling3DExecute<FunctorType>;
255  this->SetErrorBufferFunction = &TaskTilingSetErrorBuffer<FunctorType>;
256 
257  //Bind the Worklet to void*
258  this->Worklet = (void*)&functor;
259  }
260 
261  template <typename WorkletType, typename InvocationType>
262  TaskTiling3D(WorkletType& worklet, InvocationType& invocation)
263  : Worklet(nullptr)
264  , Invocation(nullptr)
265  , ExecuteFunction(nullptr)
266  , SetErrorBufferFunction(nullptr)
267  {
268  // Setup the execute and set error buffer function pointers
269  this->ExecuteFunction = &TaskTiling3DExecute<WorkletType, InvocationType>;
270  this->SetErrorBufferFunction = &TaskTilingSetErrorBuffer<WorkletType>;
271 
272  // At this point we bind the Worklet and Invocation to void*
273  this->Worklet = (void*)&worklet;
274  this->Invocation = (void*)&invocation;
275  }
276 
280  TaskTiling3D(TaskTiling3D& task)
281  : Worklet(task.Worklet)
282  , Invocation(task.Invocation)
283  , ExecuteFunction(task.ExecuteFunction)
284  , SetErrorBufferFunction(task.SetErrorBufferFunction)
285  {
286  }
287 
288  TaskTiling3D(TaskTiling3D&& task) = default;
289 
290  void SetErrorMessageBuffer(const viskores::exec::internal::ErrorMessageBuffer& buffer)
291  {
292  this->SetErrorBufferFunction(this->Worklet, buffer);
293  }
294 
295  void operator()(const viskores::Id3& maxSize,
296  viskores::Id istart,
297  viskores::Id iend,
298  viskores::Id j,
299  viskores::Id k) const
300  {
301  this->ExecuteFunction(this->Worklet, this->Invocation, maxSize, istart, iend, j, k);
302  }
303 
304 protected:
305  void* Worklet;
306  void* Invocation;
307 
308  using ExecuteSignature = void (*)(void*,
309  void* const,
310  const viskores::Id3&,
311  viskores::Id,
312  viskores::Id,
313  viskores::Id,
314  viskores::Id);
315  ExecuteSignature ExecuteFunction;
316 
317  using SetErrorBufferSignature = void (*)(void*,
318  const viskores::exec::internal::ErrorMessageBuffer&);
319  SetErrorBufferSignature SetErrorBufferFunction;
320 };
321 }
322 }
323 }
324 } // viskores::exec::serial::internal
325 
326 #endif //viskores_exec_serial_internal_TaskTiling_h
WorkletInvokeFunctorDetail.h
viskoresNotUsed
#define viskoresNotUsed(parameter_name)
Simple macro to identify a parameter as unused.
Definition: ExportMacros.h:136
viskores::Id
viskores::Int64 Id
Base type to use to index arrays.
Definition: Types.h:235
viskores
Groups connected points that have the same field value.
Definition: Atomic.h:27
TaskBase.h
viskores::Vec< viskores::Id, 3 >
viskores::exec::TaskBase
Base class for all classes that are used to marshal data from the invocation parameters to the user w...
Definition: TaskBase.h:34