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