1 //============================================================================
2 // Copyright (c) Kitware, Inc.
3 // All rights reserved.
4 // See LICENSE.txt for details.
5 // This software is distributed WITHOUT ANY WARRANTY; without even
6 // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
7 // PURPOSE. See the above copyright notice for more information.
8 //
9 // Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
10 // Copyright 2014 UT-Battelle, LLC.
11 // Copyright 2014 Los Alamos National Security.
12 //
13 // Under the terms of Contract DE-NA0003525 with NTESS,
14 // the U.S. Government retains certain rights in this software.
15 //
16 // Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
17 // Laboratory (LANL), the U.S. Government retains certain rights in
18 // this software.
19 //============================================================================
20 #ifndef vtk_m_internal_Invocation_h
21 #define vtk_m_internal_Invocation_h
22
23 #include <vtkm/Types.h>
24
25 namespace vtkm
26 {
27 namespace internal
28 {
29
30 /// \brief Container for types when dispatching worklets.
31 ///
32 /// When a dispatcher and associated class invoke a worklet, they need to keep
33 /// track of the types of all parameters and the associated features of the
34 /// worklet. \c Invocation is a class that manages all these types.
35 ///
36 template <typename _ParameterInterface,
37 typename _ControlInterface,
38 typename _ExecutionInterface,
39 vtkm::IdComponent _InputDomainIndex,
40 typename _OutputToInputMapType = vtkm::internal::NullType,
41 typename _VisitArrayType = vtkm::internal::NullType>
42 struct Invocation
43 {
44 /// \brief The types of the parameters
45 ///
46 /// \c ParameterInterface is (expected to be) a \c FunctionInterface class
47 /// that lists the types of the parameters for the invocation.
48 ///
49 using ParameterInterface = _ParameterInterface;
50
51 /// \brief The tags of the \c ControlSignature.
52 ///
53 /// \c ControlInterface is (expected to be) a \c FunctionInterface class that
54 /// represents the \c ControlSignature of a worklet (although dispatchers
55 /// might modify the control signature to provide auxiliary information).
56 ///
57 using ControlInterface = _ControlInterface;
58
59 /// \brief The tags of the \c ExecutionSignature.
60 ///
61 /// \c ExecutionInterface is (expected to be) a \c FunctionInterface class that
62 /// represents the \c ExecutionSignature of a worklet (although dispatchers
63 /// might modify the execution signature to provide auxiliary information).
64 ///
65 using ExecutionInterface = _ExecutionInterface;
66
67 /// \brief The index of the input domain.
68 ///
69 /// When a worklet is invoked, the pool of working threads is based of some
70 /// constituent element of the input (such as the points or cells). This
71 /// index points to the parameter that defines this input domain.
72 ///
73 static constexpr vtkm::IdComponent InputDomainIndex = _InputDomainIndex;
74
75 /// \brief An array representing the output to input map.
76 ///
77 /// When a worklet is invoked, there is an optional scatter operation that
78 /// allows you to vary the number of outputs each input affects. This is
79 /// represented with a map where each output points to an input that creates
80 /// it.
81 ///
82 using OutputToInputMapType = _OutputToInputMapType;
83
84 /// \brief An array containing visit indices.
85 ///
86 /// When a worklet is invoked, there is an optinonal scatter operation that
87 /// allows you to vary the number of outputs each input affects. Thus,
88 /// multiple outputs may point to the same input. The visit index uniquely
89 /// identifies which instance each is.
90 ///
91 using VisitArrayType = _VisitArrayType;
92
93 /// \brief Default Invocation constructors that holds the given parameters
94 /// by reference.
95 VTKM_CONT
96 Invocation(const ParameterInterface& parameters,
97 OutputToInputMapType outputToInputMap = OutputToInputMapType(),
98 VisitArrayType visitArray = VisitArrayType())
ParametersInvocation99 : Parameters(parameters)
100 , OutputToInputMap(outputToInputMap)
101 , VisitArray(visitArray)
102 {
103 }
104
105 /// Defines a new \c Invocation type that is the same as this type except
106 /// with the \c Parameters replaced.
107 ///
108 template <typename NewParameterInterface>
109 struct ChangeParametersType
110 {
111 using type = Invocation<NewParameterInterface,
112 ControlInterface,
113 ExecutionInterface,
114 InputDomainIndex,
115 OutputToInputMapType,
116 VisitArrayType>;
117 };
118
119 /// Returns a new \c Invocation that is the same as this one except that the
120 /// \c Parameters are replaced with those provided.
121 ///
122 template <typename NewParameterInterface>
ChangeParametersInvocation123 VTKM_CONT typename ChangeParametersType<NewParameterInterface>::type ChangeParameters(
124 const NewParameterInterface& newParameters) const
125 {
126 return typename ChangeParametersType<NewParameterInterface>::type(
127 newParameters, this->OutputToInputMap, this->VisitArray);
128 }
129
130 /// Defines a new \c Invocation type that is the same as this type except
131 /// with the \c ControlInterface replaced.
132 ///
133 template <typename NewControlInterface>
134 struct ChangeControlInterfaceType
135 {
136 using type =
137 Invocation<ParameterInterface, NewControlInterface, ExecutionInterface, InputDomainIndex>;
138 };
139
140 /// Returns a new \c Invocation that is the same as this one except that the
141 /// \c ControlInterface type is changed to the type given.
142 ///
143 template <typename NewControlInterface>
ChangeControlInterfaceInvocation144 typename ChangeControlInterfaceType<NewControlInterface>::type ChangeControlInterface(
145 NewControlInterface) const
146 {
147 return typename ChangeControlInterfaceType<NewControlInterface>::type(
148 this->Parameters, this->OutputToInputMap, this->VisitArray);
149 }
150
151 /// Defines a new \c Invocation type that is the same as this type except
152 /// with the \c ExecutionInterface replaced.
153 ///
154 template <typename NewExecutionInterface>
155 struct ChangeExecutionInterfaceType
156 {
157 using type =
158 Invocation<ParameterInterface, NewExecutionInterface, ExecutionInterface, InputDomainIndex>;
159 };
160
161 /// Returns a new \c Invocation that is the same as this one except that the
162 /// \c ExecutionInterface type is changed to the type given.
163 ///
164 template <typename NewExecutionInterface>
ChangeExecutionInterfaceInvocation165 typename ChangeExecutionInterfaceType<NewExecutionInterface>::type ChangeExecutionInterface(
166 NewExecutionInterface) const
167 {
168 return typename ChangeExecutionInterfaceType<NewExecutionInterface>::type(
169 this->Parameters, this->OutputToInputMap, this->VisitArray);
170 }
171
172 /// Defines a new \c Invocation type that is the same as this type except
173 /// with the \c InputDomainIndex replaced.
174 ///
175 template <vtkm::IdComponent NewInputDomainIndex>
176 struct ChangeInputDomainIndexType
177 {
178 using type =
179 Invocation<ParameterInterface, ControlInterface, ExecutionInterface, NewInputDomainIndex>;
180 };
181
182 /// Returns a new \c Invocation that is the same as this one except that the
183 /// \c InputDomainIndex is changed to the static number given.
184 ///
185 template <vtkm::IdComponent NewInputDomainIndex>
186 VTKM_EXEC_CONT typename ChangeInputDomainIndexType<NewInputDomainIndex>::type
ChangeInputDomainIndexInvocation187 ChangeInputDomainIndex() const
188 {
189 return typename ChangeInputDomainIndexType<NewInputDomainIndex>::type(
190 this->Parameters, this->OutputToInputMap, this->VisitArray);
191 }
192
193 /// Defines a new \c Invocation type that is the same as this type except
194 /// with the \c OutputToInputMapType replaced.
195 ///
196 template <typename NewOutputToInputMapType>
197 struct ChangeOutputToInputMapType
198 {
199 using type = Invocation<ParameterInterface,
200 ControlInterface,
201 ExecutionInterface,
202 InputDomainIndex,
203 NewOutputToInputMapType,
204 VisitArrayType>;
205 };
206
207 /// Returns a new \c Invocation that is the same as this one except that the
208 /// \c OutputToInputMap is replaced with that provided.
209 ///
210 template <typename NewOutputToInputMapType>
211 VTKM_CONT typename ChangeOutputToInputMapType<NewOutputToInputMapType>::type
ChangeOutputToInputMapInvocation212 ChangeOutputToInputMap(NewOutputToInputMapType newOutputToInputMap) const
213 {
214 return typename ChangeOutputToInputMapType<NewOutputToInputMapType>::type(
215 this->Parameters, newOutputToInputMap, this->VisitArray);
216 }
217
218 /// Defines a new \c Invocation type that is the same as this type except
219 /// with the \c VisitArrayType replaced.
220 ///
221 template <typename NewVisitArrayType>
222 struct ChangeVisitArrayType
223 {
224 using type = Invocation<ParameterInterface,
225 ControlInterface,
226 ExecutionInterface,
227 InputDomainIndex,
228 OutputToInputMapType,
229 NewVisitArrayType>;
230 };
231
232 /// Returns a new \c Invocation that is the same as this one except that the
233 /// \c VisitArray is replaced with that provided.
234 ///
235 template <typename NewVisitArrayType>
ChangeVisitArrayInvocation236 VTKM_CONT typename ChangeVisitArrayType<NewVisitArrayType>::type ChangeVisitArray(
237 NewVisitArrayType newVisitArray) const
238 {
239 return typename ChangeVisitArrayType<NewVisitArrayType>::type(
240 this->Parameters, this->OutputToInputMap, newVisitArray);
241 }
242
243 /// A convenience alias for the input domain type.
244 ///
245 using InputDomainType =
246 typename ParameterInterface::template ParameterType<InputDomainIndex>::type;
247
248 /// A convenience alias for the control signature tag of the input domain.
249 ///
250 using InputDomainTag = typename ControlInterface::template ParameterType<InputDomainIndex>::type;
251
252 /// A convenience method to get the input domain object.
253 ///
254 VTKM_SUPPRESS_EXEC_WARNINGS
255 VTKM_EXEC_CONT
GetInputDomainInvocation256 const InputDomainType& GetInputDomain() const
257 {
258 return this->Parameters.template GetParameter<InputDomainIndex>();
259 }
260
261 /// The state of an \c Invocation object holds the parameters of the
262 /// invocation. As well as the output to input map and the visit array.
263 ///
264 /// This is held by by value so that when we transfer the invocation object
265 /// over to CUDA it gets properly copied to the device. While we want to
266 /// hold by reference to reduce the number of copies, it is not possible
267 /// currently.
268 ParameterInterface Parameters;
269 OutputToInputMapType OutputToInputMap;
270 VisitArrayType VisitArray;
271
272 private:
273 // Do not allow assignment of one Invocation to another. It is too expensive.
274 void operator=(const Invocation<ParameterInterface,
275 ControlInterface,
276 ExecutionInterface,
277 InputDomainIndex,
278 OutputToInputMapType,
279 VisitArrayType>&) = delete;
280 };
281
282 /// Convenience function for creating an Invocation object.
283 ///
284 template <vtkm::IdComponent InputDomainIndex,
285 typename ControlInterface,
286 typename ExecutionInterface,
287 typename ParameterInterface,
288 typename OutputToInputMapType,
289 typename VisitArrayType>
290 VTKM_CONT vtkm::internal::Invocation<ParameterInterface,
291 ControlInterface,
292 ExecutionInterface,
293 InputDomainIndex,
294 OutputToInputMapType,
295 VisitArrayType>
make_Invocation(const ParameterInterface & params,ControlInterface,ExecutionInterface,OutputToInputMapType outputToInputMap,VisitArrayType visitArray)296 make_Invocation(const ParameterInterface& params,
297 ControlInterface,
298 ExecutionInterface,
299 OutputToInputMapType outputToInputMap,
300 VisitArrayType visitArray)
301 {
302 return vtkm::internal::Invocation<ParameterInterface,
303 ControlInterface,
304 ExecutionInterface,
305 InputDomainIndex,
306 OutputToInputMapType,
307 VisitArrayType>(params, outputToInputMap, visitArray);
308 }
309 template <vtkm::IdComponent InputDomainIndex,
310 typename ControlInterface,
311 typename ExecutionInterface,
312 typename ParameterInterface>
313 VTKM_CONT vtkm::internal::
314 Invocation<ParameterInterface, ControlInterface, ExecutionInterface, InputDomainIndex>
315 make_Invocation(const ParameterInterface& params,
316 ControlInterface = ControlInterface(),
317 ExecutionInterface = ExecutionInterface())
318 {
319 return vtkm::internal::make_Invocation<InputDomainIndex>(params,
320 ControlInterface(),
321 ExecutionInterface(),
322 vtkm::internal::NullType(),
323 vtkm::internal::NullType());
324 }
325 }
326 } // namespace vtkm::internal
327
328 #endif //vtk_m_internal_Invocation_h
329