1 #ifndef VIENNACL_OCL_KERNEL_HPP_
2 #define VIENNACL_OCL_KERNEL_HPP_
3 
4 /* =========================================================================
5    Copyright (c) 2010-2016, Institute for Microelectronics,
6                             Institute for Analysis and Scientific Computing,
7                             TU Wien.
8    Portions of this software are copyright by UChicago Argonne, LLC.
9 
10                             -----------------
11                   ViennaCL - The Vienna Computing Library
12                             -----------------
13 
14    Project Head:    Karl Rupp                   rupp@iue.tuwien.ac.at
15 
16    (A list of authors and contributors can be found in the manual)
17 
18    License:         MIT (X11), see file LICENSE in the base directory
19 ============================================================================= */
20 
21 /** @file viennacl/ocl/kernel.hpp
22     @brief Representation of an OpenCL kernel in ViennaCL.
23 */
24 
25 #ifdef __APPLE__
26 #include <OpenCL/cl.h>
27 #else
28 #include <CL/cl.h>
29 #endif
30 
31 #include "viennacl/ocl/forwards.h"
32 #include "viennacl/ocl/handle.hpp"
33 #include "viennacl/ocl/program.hpp"
34 #include "viennacl/ocl/device.hpp"
35 #include "viennacl/ocl/local_mem.hpp"
36 
37 namespace viennacl
38 {
39   namespace ocl
40   {
41     /** @brief Helper class for packing four cl_uint numbers into a uint4 type for access inside an OpenCL kernel.
42       *
43       * Since the primary use is for dealing with ranges and strides, the four members are termed accordingly.
44       */
45     struct packed_cl_uint
46     {
47       /** @brief Starting value of the integer stride. */
48       cl_uint start;
49       /** @brief Increment between integers. */
50       cl_uint stride;
51       /** @brief Number of values in the stride. */
52       cl_uint size;
53       /** @brief Internal length of the buffer. Might be larger than 'size' due to padding. */
54       cl_uint internal_size;
55     };
56 
57     /** @brief Represents an OpenCL kernel within ViennaCL */
58     class kernel
59     {
60       template<typename KernelType>
61       friend void enqueue(KernelType & k, viennacl::ocl::command_queue const & queue);
62 
63     public:
64       typedef vcl_size_t            size_type;
65 
kernel()66       kernel() : handle_(), p_program_(NULL), p_context_(NULL), name_()
67       {
68         #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_KERNEL)
69         std::cout << "ViennaCL: Creating kernel object (default CTOR): " << name_ << std::endl;
70         #endif
71       }
72 
kernel(cl_kernel kernel_handle,viennacl::ocl::program const & kernel_program,viennacl::ocl::context const & kernel_context,std::string const & name)73       kernel(cl_kernel kernel_handle, viennacl::ocl::program const & kernel_program, viennacl::ocl::context const & kernel_context, std::string const & name)
74         : handle_(kernel_handle, kernel_context), p_program_(&kernel_program), p_context_(&kernel_context), name_(name)
75       {
76         #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_KERNEL)
77         std::cout << "ViennaCL: Creating kernel object (full CTOR): " << name_ << std::endl;
78         #endif
79         set_work_size_defaults();
80       }
81 
kernel(kernel const & other)82       kernel(kernel const & other)
83         : handle_(other.handle_), p_program_(other.p_program_), p_context_(other.p_context_), name_(other.name_)
84       {
85         #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_KERNEL)
86         std::cout << "ViennaCL: Creating kernel object (Copy CTOR): " << name_ << std::endl;
87         #endif
88         local_work_size_[0] = other.local_work_size_[0];
89         local_work_size_[1] = other.local_work_size_[1];
90         local_work_size_[2] = other.local_work_size_[2];
91 
92         global_work_size_[0] = other.global_work_size_[0];
93         global_work_size_[1] = other.global_work_size_[1];
94         global_work_size_[2] = other.global_work_size_[2];
95       }
96 
operator =(const kernel & other)97       viennacl::ocl::kernel & operator=(const kernel & other)
98       {
99         #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_KERNEL)
100         std::cout << "ViennaCL: Assigning kernel object: " << other.name_ << std::endl;
101         #endif
102         handle_ = other.handle_;
103         p_program_ = other.p_program_;
104         p_context_ = other.p_context_;
105         name_ = other.name_;
106         local_work_size_[0] = other.local_work_size_[0];
107         local_work_size_[1] = other.local_work_size_[1];
108         local_work_size_[2] = other.local_work_size_[2];
109         global_work_size_[0] = other.global_work_size_[0];
110         global_work_size_[1] = other.global_work_size_[1];
111         global_work_size_[2] = other.global_work_size_[2];
112         return *this;
113       }
114 
115       /** @brief Sets a char argument at the provided position */
arg(unsigned int pos,cl_char val)116       void arg(unsigned int pos, cl_char val)
117       {
118         #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_KERNEL)
119         std::cout << "ViennaCL: Setting char kernel argument " << val << " at pos " << pos << " for kernel " << name_ << std::endl;
120         #endif
121         cl_int err = clSetKernelArg(handle_.get(), pos, sizeof(cl_char), (void*)&val);
122         VIENNACL_ERR_CHECK(err);
123       }
124 
125       /** @brief Sets a char argument at the provided position */
arg(unsigned int pos,cl_uchar val)126       void arg(unsigned int pos, cl_uchar val)
127       {
128         #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_KERNEL)
129         std::cout << "ViennaCL: Setting unsigned char kernel argument " << val << " at pos " << pos << " for kernel " << name_ << std::endl;
130         #endif
131         cl_int err = clSetKernelArg(handle_.get(), pos, sizeof(cl_uchar), (void*)&val);
132         VIENNACL_ERR_CHECK(err);
133       }
134 
135       /** @brief Sets a argument of type short at the provided position */
arg(unsigned int pos,cl_short val)136       void arg(unsigned int pos, cl_short val)
137       {
138         #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_KERNEL)
139         std::cout << "ViennaCL: Setting short kernel argument " << val << " at pos " << pos << " for kernel " << name_ << std::endl;
140         #endif
141         cl_int err = clSetKernelArg(handle_.get(), pos, sizeof(cl_short), (void*)&val);
142         VIENNACL_ERR_CHECK(err);
143       }
144 
145       /** @brief Sets a argument of type unsigned short at the provided position */
arg(unsigned int pos,cl_ushort val)146       void arg(unsigned int pos, cl_ushort val)
147       {
148         #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_KERNEL)
149         std::cout << "ViennaCL: Setting unsigned short kernel argument " << val << " at pos " << pos << " for kernel " << name_ << std::endl;
150         #endif
151         cl_int err = clSetKernelArg(handle_.get(), pos, sizeof(cl_ushort), (void*)&val);
152         VIENNACL_ERR_CHECK(err);
153       }
154 
155 
156       /** @brief Sets an unsigned integer argument at the provided position */
arg(unsigned int pos,cl_uint val)157       void arg(unsigned int pos, cl_uint val)
158       {
159         #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_KERNEL)
160         std::cout << "ViennaCL: Setting unsigned int kernel argument " << val << " at pos " << pos << " for kernel " << name_ << std::endl;
161         #endif
162         cl_int err = clSetKernelArg(handle_.get(), pos, sizeof(cl_uint), (void*)&val);
163         VIENNACL_ERR_CHECK(err);
164       }
165 
166       /** @brief Sets four packed unsigned integers as argument at the provided position */
arg(unsigned int pos,packed_cl_uint val)167       void arg(unsigned int pos, packed_cl_uint val)
168       {
169         #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_KERNEL)
170         std::cout << "ViennaCL: Setting packed_cl_uint kernel argument (" << val.start << ", " << val.stride << ", " << val.size << ", " << val.internal_size << ") at pos " << pos << " for kernel " << name_ << std::endl;
171         #endif
172         cl_int err = clSetKernelArg(handle_.get(), pos, sizeof(packed_cl_uint), (void*)&val);
173         VIENNACL_ERR_CHECK(err);
174       }
175 
176       /** @brief Sets a single precision floating point argument at the provided position */
arg(unsigned int pos,float val)177       void arg(unsigned int pos, float val)
178       {
179         #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_KERNEL)
180         std::cout << "ViennaCL: Setting floating point kernel argument " << val << " at pos " << pos << " for kernel " << name_ << std::endl;
181         #endif
182         cl_int err = clSetKernelArg(handle_.get(), pos, sizeof(float), (void*)&val);
183         VIENNACL_ERR_CHECK(err);
184       }
185 
186       /** @brief Sets a double precision floating point argument at the provided position */
arg(unsigned int pos,double val)187       void arg(unsigned int pos, double val)
188       {
189         #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_KERNEL)
190         std::cout << "ViennaCL: Setting double precision kernel argument " << val << " at pos " << pos << " for kernel " << name_ << std::endl;
191         #endif
192         cl_int err = clSetKernelArg(handle_.get(), pos, sizeof(double), (void*)&val);
193         VIENNACL_ERR_CHECK(err);
194       }
195 
196       /** @brief Sets an int argument at the provided position */
arg(unsigned int pos,cl_int val)197       void arg(unsigned int pos, cl_int val)
198       {
199         #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_KERNEL)
200         std::cout << "ViennaCL: Setting int precision kernel argument " << val << " at pos " << pos << " for kernel " << name_ << std::endl;
201         #endif
202         cl_int err = clSetKernelArg(handle_.get(), pos, sizeof(cl_int), (void*)&val);
203         VIENNACL_ERR_CHECK(err);
204       }
205 
206       /** @brief Sets an unsigned long argument at the provided position */
arg(unsigned int pos,cl_ulong val)207       void arg(unsigned int pos, cl_ulong val)
208       {
209         #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_KERNEL)
210         std::cout << "ViennaCL: Setting ulong precision kernel argument " << val << " at pos " << pos << " for kernel " << name_ << std::endl;
211         #endif
212         cl_int err = clSetKernelArg(handle_.get(), pos, sizeof(cl_ulong), (void*)&val);
213         VIENNACL_ERR_CHECK(err);
214       }
215 
216       /** @brief Sets an unsigned long argument at the provided position */
arg(unsigned int pos,cl_long val)217       void arg(unsigned int pos, cl_long val)
218       {
219         #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_KERNEL)
220         std::cout << "ViennaCL: Setting long precision kernel argument " << val << " at pos " << pos << " for kernel " << name_ << std::endl;
221         #endif
222         cl_int err = clSetKernelArg(handle_.get(), pos, sizeof(cl_long), (void*)&val);
223         VIENNACL_ERR_CHECK(err);
224       }
225 
226       //generic handling: call .handle() member
227       /** @brief Sets an OpenCL memory object at the provided position */
228       template<class VCL_TYPE>
arg(unsigned int pos,VCL_TYPE const & val)229       void arg(unsigned int pos, VCL_TYPE const & val)
230       {
231         assert(&val.handle().opencl_handle().context() == &handle_.context() && bool("Kernel and memory object not in the same context!"));
232 
233         cl_mem temp = val.handle().opencl_handle().get();
234         #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_KERNEL)
235         std::cout << "ViennaCL: Setting generic kernel argument " << temp << " at pos " << pos << " for kernel " << name_ << std::endl;
236         #endif
237         cl_int err = clSetKernelArg(handle_.get(), pos, sizeof(cl_mem), (void*)&temp);
238         VIENNACL_ERR_CHECK(err);
239       }
240 
241       //forward handles directly:
242       /** @brief Sets an OpenCL object at the provided position */
243       template<class CL_TYPE>
arg(unsigned int pos,viennacl::ocl::handle<CL_TYPE> const & h)244       void arg(unsigned int pos, viennacl::ocl::handle<CL_TYPE> const & h)
245       {
246         CL_TYPE temp = h.get();
247         #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_KERNEL)
248         std::cout << "ViennaCL: Setting handle kernel argument " << temp << " at pos " << pos << " for kernel " << name_ << std::endl;
249         #endif
250         cl_int err = clSetKernelArg(handle_.get(), pos, sizeof(CL_TYPE), (void*)&temp);
251         VIENNACL_ERR_CHECK(err);
252       }
253 
254 
255       //local buffer argument:
256       /** @brief Sets an OpenCL local memory object at the provided position */
arg(unsigned int pos,const local_mem & mem)257       void arg(unsigned int pos, const local_mem & mem)
258       {
259         cl_uint size = static_cast<cl_uint>(mem.size());
260         #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_KERNEL)
261         std::cout << "ViennaCL: Setting local memory kernel argument of size " << size << " bytes at pos " << pos << " for kernel " << name_ << std::endl;
262         #endif
263         cl_int err = clSetKernelArg(handle_.get(), pos, size, 0);
264         VIENNACL_ERR_CHECK(err);
265       }
266 
267 
268 
269       /** @brief Convenience function for setting one kernel parameter */
270       template<typename T0>
operator ()(T0 const & t0)271       kernel & operator()(T0 const & t0)
272       {
273          arg(0, t0);
274          return *this;
275       }
276 
277       /** @brief Convenience function for setting two kernel parameters */
278       template<typename T0, typename T1>
operator ()(T0 const & t0,T1 const & t1)279       kernel & operator()(T0 const & t0, T1 const & t1)
280       {
281          arg(0, t0); arg(1, t1);
282          return *this;
283       }
284 
285       /** @brief Convenience function for setting three kernel parameters */
286       template<typename T0, typename T1, typename T2>
operator ()(T0 const & t0,T1 const & t1,T2 const & t2)287       kernel & operator()(T0 const & t0, T1 const & t1, T2 const & t2)
288       {
289          arg(0, t0); arg(1, t1); arg(2, t2);
290          return *this;
291       }
292 
293       /** @brief Convenience function for setting four kernel parameters */
294       template<typename T0, typename T1, typename T2, typename T3>
operator ()(T0 const & t0,T1 const & t1,T2 const & t2,T3 const & t3)295       kernel & operator()(T0 const & t0, T1 const & t1, T2 const & t2, T3 const & t3)
296       {
297          arg(0, t0); arg(1, t1); arg(2, t2); arg(3, t3);
298          return *this;
299       }
300 
301       /** @brief Convenience function for setting five kernel parameters */
302       template<typename T0, typename T1, typename T2, typename T3, typename T4>
operator ()(T0 const & t0,T1 const & t1,T2 const & t2,T3 const & t3,T4 const & t4)303       kernel & operator()(T0 const & t0, T1 const & t1, T2 const & t2, T3 const & t3, T4 const & t4)
304       {
305          arg(0, t0); arg(1, t1); arg(2, t2); arg(3, t3); arg(4, t4);
306          return *this;
307       }
308 
309       /** @brief Convenience function for setting six kernel parameters */
310       template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5>
operator ()(T0 const & t0,T1 const & t1,T2 const & t2,T3 const & t3,T4 const & t4,T5 const & t5)311       kernel & operator()(T0 const & t0, T1 const & t1, T2 const & t2, T3 const & t3, T4 const & t4, T5 const & t5)
312       {
313          arg(0, t0); arg(1, t1); arg(2, t2); arg(3, t3); arg(4, t4); arg(5, t5);
314          return *this;
315       }
316 
317       /** @brief Convenience function for setting seven kernel parameters */
318       template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
operator ()(T0 const & t0,T1 const & t1,T2 const & t2,T3 const & t3,T4 const & t4,T5 const & t5,T6 const & t6)319       kernel & operator()(T0 const & t0, T1 const & t1, T2 const & t2, T3 const & t3, T4 const & t4, T5 const & t5, T6 const & t6)
320       {
321          arg(0, t0); arg(1, t1); arg(2, t2); arg(3, t3); arg(4, t4); arg(5, t5); arg(6, t6);
322          return *this;
323       }
324 
325       /** @brief Convenience function for setting eight kernel parameters */
326       template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
operator ()(T0 const & t0,T1 const & t1,T2 const & t2,T3 const & t3,T4 const & t4,T5 const & t5,T6 const & t6,T7 const & t7)327       kernel & operator()(T0 const & t0, T1 const & t1, T2 const & t2, T3 const & t3, T4 const & t4, T5 const & t5, T6 const & t6, T7 const & t7)
328       {
329          arg(0, t0); arg(1, t1); arg(2, t2); arg(3, t3); arg(4, t4); arg(5, t5); arg(6, t6); arg(7, t7);
330          return *this;
331       }
332 
333       /** @brief Convenience function for setting nine kernel parameters */
334       template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
operator ()(T0 const & t0,T1 const & t1,T2 const & t2,T3 const & t3,T4 const & t4,T5 const & t5,T6 const & t6,T7 const & t7,T8 const & t8)335       kernel & operator()(T0 const & t0, T1 const & t1, T2 const & t2, T3 const & t3, T4 const & t4, T5 const & t5, T6 const & t6, T7 const & t7, T8 const & t8)
336       {
337          arg(0, t0); arg(1, t1); arg(2, t2); arg(3, t3); arg(4, t4); arg(5, t5); arg(6, t6); arg(7, t7); arg(8, t8);
338          return *this;
339       }
340 
341       /** @brief Convenience function for setting ten kernel parameters */
342       template<typename T0, typename T1, typename T2, typename T3, typename T4,
343                 typename T5, typename T6, typename T7, typename T8, typename T9>
operator ()(T0 const & t0,T1 const & t1,T2 const & t2,T3 const & t3,T4 const & t4,T5 const & t5,T6 const & t6,T7 const & t7,T8 const & t8,T9 const & t9)344       kernel & operator()(T0 const & t0, T1 const & t1, T2 const & t2, T3 const & t3, T4 const & t4,
345                           T5 const & t5, T6 const & t6, T7 const & t7, T8 const & t8, T9 const & t9)
346       {
347          arg(0, t0); arg(1, t1); arg(2, t2); arg(3, t3); arg(4, t4); arg(5, t5); arg(6, t6); arg(7, t7); arg(8, t8); arg(9, t9);
348          return *this;
349       }
350 
351       /** @brief Convenience function for setting eleven kernel parameters */
352       template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5,
353                 typename T6, typename T7, typename T8, typename T9, typename T10>
operator ()(T0 const & t0,T1 const & t1,T2 const & t2,T3 const & t3,T4 const & t4,T5 const & t5,T6 const & t6,T7 const & t7,T8 const & t8,T9 const & t9,T10 const & t10)354       kernel & operator()(T0 const & t0, T1 const & t1, T2 const & t2, T3 const & t3, T4 const & t4, T5 const & t5,
355                           T6 const & t6, T7 const & t7, T8 const & t8, T9 const & t9, T10 const & t10)
356       {
357          arg(0, t0); arg(1, t1); arg(2, t2); arg(3, t3); arg(4, t4); arg(5, t5); arg(6, t6); arg(7, t7); arg(8, t8); arg(9, t9); arg(10, t10);
358          return *this;
359       }
360 
361       /** @brief Convenience function for setting twelve kernel parameters */
362       template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5,
363                 typename T6, typename T7, typename T8, typename T9, typename T10, typename T11>
operator ()(T0 const & t0,T1 const & t1,T2 const & t2,T3 const & t3,T4 const & t4,T5 const & t5,T6 const & t6,T7 const & t7,T8 const & t8,T9 const & t9,T10 const & t10,T11 const & t11)364       kernel & operator()(T0 const & t0, T1 const & t1, T2 const & t2, T3 const & t3, T4 const & t4, T5 const & t5,
365                           T6 const & t6, T7 const & t7, T8 const & t8, T9 const & t9, T10 const & t10, T11 const & t11)
366       {
367          arg(0, t0); arg(1, t1); arg(2, t2); arg(3, t3); arg(4, t4); arg(5, t5);
368          arg(6, t6); arg(7, t7); arg(8, t8); arg(9, t9); arg(10, t10); arg(11, t11);
369          return *this;
370       }
371 
372       /** @brief Convenience function for setting thirteen kernel parameters */
373       template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5,
374                 typename T6, typename T7, typename T8, typename T9, typename T10, typename T11, typename T12>
operator ()(T0 const & t0,T1 const & t1,T2 const & t2,T3 const & t3,T4 const & t4,T5 const & t5,T6 const & t6,T7 const & t7,T8 const & t8,T9 const & t9,T10 const & t10,T11 const & t11,T12 const & t12)375       kernel & operator()(T0 const & t0, T1 const & t1, T2 const & t2, T3 const & t3, T4 const & t4, T5 const & t5,
376                           T6 const & t6, T7 const & t7, T8 const & t8, T9 const & t9, T10 const & t10, T11 const & t11, T12 const & t12)
377       {
378          arg(0, t0); arg(1, t1); arg(2, t2); arg(3, t3); arg(4, t4); arg(5, t5);
379          arg(6, t6); arg(7, t7); arg(8, t8); arg(9, t9); arg(10, t10); arg(11, t11); arg(12, t12);
380          return *this;
381       }
382 
383       /** @brief Convenience function for setting fourteen kernel parameters */
384       template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5,
385                 typename T6, typename T7, typename T8, typename T9, typename T10, typename T11,
386                 typename T12, typename T13>
operator ()(T0 const & t0,T1 const & t1,T2 const & t2,T3 const & t3,T4 const & t4,T5 const & t5,T6 const & t6,T7 const & t7,T8 const & t8,T9 const & t9,T10 const & t10,T11 const & t11,T12 const & t12,T13 const & t13)387       kernel & operator()(T0 const & t0, T1 const & t1, T2 const & t2, T3 const & t3, T4 const & t4, T5 const & t5,
388                           T6 const & t6, T7 const & t7, T8 const & t8, T9 const & t9, T10 const & t10, T11 const & t11,
389                           T12 const & t12, T13 const & t13)
390       {
391          arg(0, t0); arg(1, t1); arg(2, t2); arg(3, t3); arg(4, t4); arg(5, t5);
392          arg(6, t6); arg(7, t7); arg(8, t8); arg(9, t9); arg(10, t10); arg(11, t11);
393          arg(12, t12); arg(13, t13);
394          return *this;
395       }
396 
397       /** @brief Convenience function for setting fifteen kernel parameters */
398       template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5,
399                 typename T6, typename T7, typename T8, typename T9, typename T10, typename T11,
400                 typename T12, typename T13, typename T14>
operator ()(T0 const & t0,T1 const & t1,T2 const & t2,T3 const & t3,T4 const & t4,T5 const & t5,T6 const & t6,T7 const & t7,T8 const & t8,T9 const & t9,T10 const & t10,T11 const & t11,T12 const & t12,T13 const & t13,T14 const & t14)401       kernel & operator()(T0 const & t0, T1 const & t1, T2 const & t2, T3 const & t3, T4 const & t4, T5 const & t5,
402                           T6 const & t6, T7 const & t7, T8 const & t8, T9 const & t9, T10 const & t10, T11 const & t11,
403                           T12 const & t12, T13 const & t13, T14 const & t14)
404       {
405          arg(0, t0); arg(1, t1); arg(2, t2); arg(3, t3); arg(4, t4); arg(5, t5);
406          arg(6, t6); arg(7, t7); arg(8, t8); arg(9, t9); arg(10, t10); arg(11, t11);
407          arg(12, t12); arg(13, t13); arg(14, t14);
408          return *this;
409       }
410 
411       /** @brief Convenience function for setting sixteen kernel parameters */
412       template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5,
413                 typename T6, typename T7, typename T8, typename T9, typename T10, typename T11,
414                 typename T12, typename T13, typename T14, typename T15>
operator ()(T0 const & t0,T1 const & t1,T2 const & t2,T3 const & t3,T4 const & t4,T5 const & t5,T6 const & t6,T7 const & t7,T8 const & t8,T9 const & t9,T10 const & t10,T11 const & t11,T12 const & t12,T13 const & t13,T14 const & t14,T15 const & t15)415       kernel & operator()(T0 const & t0, T1 const & t1, T2 const & t2, T3 const & t3, T4 const & t4, T5 const & t5,
416                           T6 const & t6, T7 const & t7, T8 const & t8, T9 const & t9, T10 const & t10, T11 const & t11,
417                           T12 const & t12, T13 const & t13, T14 const & t14, T15 const & t15)
418       {
419          arg(0, t0); arg(1, t1); arg(2, t2); arg(3, t3); arg(4, t4); arg(5, t5);
420          arg(6, t6); arg(7, t7); arg(8, t8); arg(9, t9); arg(10, t10); arg(11, t11);
421          arg(12, t12); arg(13, t13); arg(14, t14); arg(15, t15);
422          return *this;
423       }
424 
425       /** @brief Convenience function for setting seventeen kernel parameters */
426       template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5,
427                 typename T6, typename T7, typename T8, typename T9, typename T10, typename T11,
428                 typename T12, typename T13, typename T14, typename T15, typename T16>
operator ()(T0 const & t0,T1 const & t1,T2 const & t2,T3 const & t3,T4 const & t4,T5 const & t5,T6 const & t6,T7 const & t7,T8 const & t8,T9 const & t9,T10 const & t10,T11 const & t11,T12 const & t12,T13 const & t13,T14 const & t14,T15 const & t15,T16 const & t16)429       kernel & operator()(T0 const & t0, T1 const & t1, T2 const & t2, T3 const & t3, T4 const & t4, T5 const & t5,
430                           T6 const & t6, T7 const & t7, T8 const & t8, T9 const & t9, T10 const & t10, T11 const & t11,
431                           T12 const & t12, T13 const & t13, T14 const & t14, T15 const & t15, T16 const & t16)
432       {
433          arg(0, t0); arg(1, t1); arg(2, t2); arg(3, t3); arg(4, t4); arg(5, t5);
434          arg(6, t6); arg(7, t7); arg(8, t8); arg(9, t9); arg(10, t10); arg(11, t11);
435          arg(12, t12); arg(13, t13); arg(14, t14); arg(15, t15); arg(16, t16);
436          return *this;
437       }
438 
439       /** @brief Convenience function for setting eighteen kernel parameters */
440       template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5,
441                 typename T6, typename T7, typename T8, typename T9, typename T10, typename T11,
442                 typename T12, typename T13, typename T14, typename T15, typename T16, typename T17>
operator ()(T0 const & t0,T1 const & t1,T2 const & t2,T3 const & t3,T4 const & t4,T5 const & t5,T6 const & t6,T7 const & t7,T8 const & t8,T9 const & t9,T10 const & t10,T11 const & t11,T12 const & t12,T13 const & t13,T14 const & t14,T15 const & t15,T16 const & t16,T17 const & t17)443       kernel & operator()(T0 const & t0, T1 const & t1, T2 const & t2, T3 const & t3, T4 const & t4, T5 const & t5,
444                           T6 const & t6, T7 const & t7, T8 const & t8, T9 const & t9, T10 const & t10, T11 const & t11,
445                           T12 const & t12, T13 const & t13, T14 const & t14, T15 const & t15, T16 const & t16, T17 const & t17)
446       {
447          arg(0, t0); arg(1, t1); arg(2, t2); arg(3, t3); arg(4, t4); arg(5, t5);
448          arg(6, t6); arg(7, t7); arg(8, t8); arg(9, t9); arg(10, t10); arg(11, t11);
449          arg(12, t12); arg(13, t13); arg(14, t14); arg(15, t15); arg(16, t16); arg(17, t17);
450          return *this;
451       }
452 
453       /** @brief Convenience function for setting nineteen kernel parameters */
454       template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5,
455                 typename T6, typename T7, typename T8, typename T9, typename T10, typename T11,
456                 typename T12, typename T13, typename T14, typename T15, typename T16, typename T17,
457                 typename T18>
operator ()(T0 const & t0,T1 const & t1,T2 const & t2,T3 const & t3,T4 const & t4,T5 const & t5,T6 const & t6,T7 const & t7,T8 const & t8,T9 const & t9,T10 const & t10,T11 const & t11,T12 const & t12,T13 const & t13,T14 const & t14,T15 const & t15,T16 const & t16,T17 const & t17,T18 const & t18)458       kernel & operator()(T0 const & t0, T1 const & t1, T2 const & t2, T3 const & t3, T4 const & t4, T5 const & t5,
459                           T6 const & t6, T7 const & t7, T8 const & t8, T9 const & t9, T10 const & t10, T11 const & t11,
460                           T12 const & t12, T13 const & t13, T14 const & t14, T15 const & t15, T16 const & t16, T17 const & t17,
461                           T18 const & t18
462                          )
463       {
464          arg(0, t0); arg(1, t1); arg(2, t2); arg(3, t3); arg(4, t4); arg(5, t5);
465          arg(6, t6); arg(7, t7); arg(8, t8); arg(9, t9); arg(10, t10); arg(11, t11);
466          arg(12, t12); arg(13, t13); arg(14, t14); arg(15, t15); arg(16, t16); arg(17, t17);
467          arg(18, t18);
468          return *this;
469       }
470 
471       /** @brief Convenience function for setting twenty kernel parameters */
472       template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5,
473                 typename T6, typename T7, typename T8, typename T9, typename T10, typename T11,
474                 typename T12, typename T13, typename T14, typename T15, typename T16, typename T17,
475                 typename T18, typename T19>
operator ()(T0 const & t0,T1 const & t1,T2 const & t2,T3 const & t3,T4 const & t4,T5 const & t5,T6 const & t6,T7 const & t7,T8 const & t8,T9 const & t9,T10 const & t10,T11 const & t11,T12 const & t12,T13 const & t13,T14 const & t14,T15 const & t15,T16 const & t16,T17 const & t17,T18 const & t18,T19 const & t19)476       kernel & operator()(T0 const & t0, T1 const & t1, T2 const & t2, T3 const & t3, T4 const & t4, T5 const & t5,
477                           T6 const & t6, T7 const & t7, T8 const & t8, T9 const & t9, T10 const & t10, T11 const & t11,
478                           T12 const & t12, T13 const & t13, T14 const & t14, T15 const & t15, T16 const & t16, T17 const & t17,
479                           T18 const & t18, T19 const & t19
480                          )
481       {
482          arg(0, t0); arg(1, t1); arg(2, t2); arg(3, t3); arg(4, t4); arg(5, t5);
483          arg(6, t6); arg(7, t7); arg(8, t8); arg(9, t9); arg(10, t10); arg(11, t11);
484          arg(12, t12); arg(13, t13); arg(14, t14); arg(15, t15); arg(16, t16); arg(17, t17);
485          arg(18, t18); arg(19, t19);
486          return *this;
487       }
488 
489       /** @brief Convenience function for setting twentyone kernel parameters */
490       template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5,
491                 typename T6, typename T7, typename T8, typename T9, typename T10, typename T11,
492                 typename T12, typename T13, typename T14, typename T15, typename T16, typename T17,
493                 typename T18, typename T19, typename T20>
operator ()(T0 const & t0,T1 const & t1,T2 const & t2,T3 const & t3,T4 const & t4,T5 const & t5,T6 const & t6,T7 const & t7,T8 const & t8,T9 const & t9,T10 const & t10,T11 const & t11,T12 const & t12,T13 const & t13,T14 const & t14,T15 const & t15,T16 const & t16,T17 const & t17,T18 const & t18,T19 const & t19,T20 const & t20)494       kernel & operator()(T0 const & t0, T1 const & t1, T2 const & t2, T3 const & t3, T4 const & t4, T5 const & t5,
495                           T6 const & t6, T7 const & t7, T8 const & t8, T9 const & t9, T10 const & t10, T11 const & t11,
496                           T12 const & t12, T13 const & t13, T14 const & t14, T15 const & t15, T16 const & t16, T17 const & t17,
497                           T18 const & t18, T19 const & t19, T20 const & t20
498                          )
499       {
500          arg(0, t0); arg(1, t1); arg(2, t2); arg(3, t3); arg(4, t4); arg(5, t5);
501          arg(6, t6); arg(7, t7); arg(8, t8); arg(9, t9); arg(10, t10); arg(11, t11);
502          arg(12, t12); arg(13, t13); arg(14, t14); arg(15, t15); arg(16, t16); arg(17, t17);
503          arg(18, t18); arg(19, t19); arg(20, t20);
504          return *this;
505       }
506 
507       /** @brief Convenience function for setting twentytwo kernel parameters */
508       template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5,
509                 typename T6, typename T7, typename T8, typename T9, typename T10, typename T11,
510                 typename T12, typename T13, typename T14, typename T15, typename T16, typename T17,
511                 typename T18, typename T19, typename T20, typename T21>
operator ()(T0 const & t0,T1 const & t1,T2 const & t2,T3 const & t3,T4 const & t4,T5 const & t5,T6 const & t6,T7 const & t7,T8 const & t8,T9 const & t9,T10 const & t10,T11 const & t11,T12 const & t12,T13 const & t13,T14 const & t14,T15 const & t15,T16 const & t16,T17 const & t17,T18 const & t18,T19 const & t19,T20 const & t20,T21 const & t21)512       kernel & operator()(T0 const & t0, T1 const & t1, T2 const & t2, T3 const & t3, T4 const & t4, T5 const & t5,
513                           T6 const & t6, T7 const & t7, T8 const & t8, T9 const & t9, T10 const & t10, T11 const & t11,
514                           T12 const & t12, T13 const & t13, T14 const & t14, T15 const & t15, T16 const & t16, T17 const & t17,
515                           T18 const & t18, T19 const & t19, T20 const & t20, T21 const & t21
516                          )
517       {
518          arg(0, t0); arg(1, t1); arg(2, t2); arg(3, t3); arg(4, t4); arg(5, t5);
519          arg(6, t6); arg(7, t7); arg(8, t8); arg(9, t9); arg(10, t10); arg(11, t11);
520          arg(12, t12); arg(13, t13); arg(14, t14); arg(15, t15); arg(16, t16); arg(17, t17);
521          arg(18, t18); arg(19, t19); arg(20, t20); arg(21, t21);
522          return *this;
523       }
524 
525       /** @brief Convenience function for setting 23 kernel parameters */
526       template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5,
527                 typename T6, typename T7, typename T8, typename T9, typename T10, typename T11,
528                 typename T12, typename T13, typename T14, typename T15, typename T16, typename T17,
529                 typename T18, typename T19, typename T20, typename T21, typename T22>
operator ()(T0 const & t0,T1 const & t1,T2 const & t2,T3 const & t3,T4 const & t4,T5 const & t5,T6 const & t6,T7 const & t7,T8 const & t8,T9 const & t9,T10 const & t10,T11 const & t11,T12 const & t12,T13 const & t13,T14 const & t14,T15 const & t15,T16 const & t16,T17 const & t17,T18 const & t18,T19 const & t19,T20 const & t20,T21 const & t21,T22 const & t22)530       kernel & operator()(T0 const & t0, T1 const & t1, T2 const & t2, T3 const & t3, T4 const & t4, T5 const & t5,
531                           T6 const & t6, T7 const & t7, T8 const & t8, T9 const & t9, T10 const & t10, T11 const & t11,
532                           T12 const & t12, T13 const & t13, T14 const & t14, T15 const & t15, T16 const & t16, T17 const & t17,
533                           T18 const & t18, T19 const & t19, T20 const & t20, T21 const & t21, T22 const & t22
534                          )
535       {
536          arg(0, t0); arg(1, t1); arg(2, t2); arg(3, t3); arg(4, t4); arg(5, t5);
537          arg(6, t6); arg(7, t7); arg(8, t8); arg(9, t9); arg(10, t10); arg(11, t11);
538          arg(12, t12); arg(13, t13); arg(14, t14); arg(15, t15); arg(16, t16); arg(17, t17);
539          arg(18, t18); arg(19, t19); arg(20, t20); arg(21, t21);  arg(22, t22);
540          return *this;
541       }
542 
543       /** @brief Convenience function for setting 24 kernel parameters */
544       template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5,
545                 typename T6, typename T7, typename T8, typename T9, typename T10, typename T11,
546                 typename T12, typename T13, typename T14, typename T15, typename T16, typename T17,
547                 typename T18, typename T19, typename T20, typename T21, typename T22, typename T23>
operator ()(T0 const & t0,T1 const & t1,T2 const & t2,T3 const & t3,T4 const & t4,T5 const & t5,T6 const & t6,T7 const & t7,T8 const & t8,T9 const & t9,T10 const & t10,T11 const & t11,T12 const & t12,T13 const & t13,T14 const & t14,T15 const & t15,T16 const & t16,T17 const & t17,T18 const & t18,T19 const & t19,T20 const & t20,T21 const & t21,T22 const & t22,T23 const & t23)548       kernel & operator()(T0 const & t0, T1 const & t1, T2 const & t2, T3 const & t3, T4 const & t4, T5 const & t5,
549                           T6 const & t6, T7 const & t7, T8 const & t8, T9 const & t9, T10 const & t10, T11 const & t11,
550                           T12 const & t12, T13 const & t13, T14 const & t14, T15 const & t15, T16 const & t16, T17 const & t17,
551                           T18 const & t18, T19 const & t19, T20 const & t20, T21 const & t21, T22 const & t22, T23 const & t23
552                          )
553       {
554          arg(0, t0); arg(1, t1); arg(2, t2); arg(3, t3); arg(4, t4); arg(5, t5);
555          arg(6, t6); arg(7, t7); arg(8, t8); arg(9, t9); arg(10, t10); arg(11, t11);
556          arg(12, t12); arg(13, t13); arg(14, t14); arg(15, t15); arg(16, t16); arg(17, t17);
557          arg(18, t18); arg(19, t19); arg(20, t20); arg(21, t21); arg(22, t22); arg(23, t23);
558          return *this;
559       }
560 
561       /** @brief Convenience function for setting 25 kernel parameters */
562       template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5,
563                 typename T6, typename T7, typename T8, typename T9, typename T10, typename T11,
564                 typename T12, typename T13, typename T14, typename T15, typename T16, typename T17,
565                 typename T18, typename T19, typename T20, typename T21, typename T22, typename T23,
566                 typename T24>
operator ()(T0 const & t0,T1 const & t1,T2 const & t2,T3 const & t3,T4 const & t4,T5 const & t5,T6 const & t6,T7 const & t7,T8 const & t8,T9 const & t9,T10 const & t10,T11 const & t11,T12 const & t12,T13 const & t13,T14 const & t14,T15 const & t15,T16 const & t16,T17 const & t17,T18 const & t18,T19 const & t19,T20 const & t20,T21 const & t21,T22 const & t22,T23 const & t23,T24 const & t24)567       kernel & operator()(T0 const & t0, T1 const & t1, T2 const & t2, T3 const & t3, T4 const & t4, T5 const & t5,
568                           T6 const & t6, T7 const & t7, T8 const & t8, T9 const & t9, T10 const & t10, T11 const & t11,
569                           T12 const & t12, T13 const & t13, T14 const & t14, T15 const & t15, T16 const & t16, T17 const & t17,
570                           T18 const & t18, T19 const & t19, T20 const & t20, T21 const & t21, T22 const & t22, T23 const & t23,
571                           T24 const & t24
572                          )
573       {
574          arg(0, t0); arg(1, t1); arg(2, t2); arg(3, t3); arg(4, t4); arg(5, t5);
575          arg(6, t6); arg(7, t7); arg(8, t8); arg(9, t9); arg(10, t10); arg(11, t11);
576          arg(12, t12); arg(13, t13); arg(14, t14); arg(15, t15); arg(16, t16); arg(17, t17);
577          arg(18, t18); arg(19, t19); arg(20, t20); arg(21, t21); arg(22, t22); arg(23, t23);
578          arg(24, t24);
579          return *this;
580       }
581 
582       /** @brief Convenience function for setting 26 kernel parameters */
583       template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5,
584                 typename T6, typename T7, typename T8, typename T9, typename T10, typename T11,
585                 typename T12, typename T13, typename T14, typename T15, typename T16, typename T17,
586                 typename T18, typename T19, typename T20, typename T21, typename T22, typename T23,
587                 typename T24, typename T25>
operator ()(T0 const & t0,T1 const & t1,T2 const & t2,T3 const & t3,T4 const & t4,T5 const & t5,T6 const & t6,T7 const & t7,T8 const & t8,T9 const & t9,T10 const & t10,T11 const & t11,T12 const & t12,T13 const & t13,T14 const & t14,T15 const & t15,T16 const & t16,T17 const & t17,T18 const & t18,T19 const & t19,T20 const & t20,T21 const & t21,T22 const & t22,T23 const & t23,T24 const & t24,T25 const & t25)588       kernel & operator()(T0 const & t0, T1 const & t1, T2 const & t2, T3 const & t3, T4 const & t4, T5 const & t5,
589                           T6 const & t6, T7 const & t7, T8 const & t8, T9 const & t9, T10 const & t10, T11 const & t11,
590                           T12 const & t12, T13 const & t13, T14 const & t14, T15 const & t15, T16 const & t16, T17 const & t17,
591                           T18 const & t18, T19 const & t19, T20 const & t20, T21 const & t21, T22 const & t22, T23 const & t23,
592                           T24 const & t24, T25 const & t25
593                          )
594       {
595          arg(0, t0); arg(1, t1); arg(2, t2); arg(3, t3); arg(4, t4); arg(5, t5);
596          arg(6, t6); arg(7, t7); arg(8, t8); arg(9, t9); arg(10, t10); arg(11, t11);
597          arg(12, t12); arg(13, t13); arg(14, t14); arg(15, t15); arg(16, t16); arg(17, t17);
598          arg(18, t18); arg(19, t19); arg(20, t20); arg(21, t21); arg(22, t22); arg(23, t23);
599          arg(24, t24); arg(25, t25);
600          return *this;
601       }
602 
603       /** @brief Convenience function for setting 27 kernel parameters */
604       template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5,
605                 typename T6, typename T7, typename T8, typename T9, typename T10, typename T11,
606                 typename T12, typename T13, typename T14, typename T15, typename T16, typename T17,
607                 typename T18, typename T19, typename T20, typename T21, typename T22, typename T23,
608                 typename T24, typename T25, typename T26>
operator ()(T0 const & t0,T1 const & t1,T2 const & t2,T3 const & t3,T4 const & t4,T5 const & t5,T6 const & t6,T7 const & t7,T8 const & t8,T9 const & t9,T10 const & t10,T11 const & t11,T12 const & t12,T13 const & t13,T14 const & t14,T15 const & t15,T16 const & t16,T17 const & t17,T18 const & t18,T19 const & t19,T20 const & t20,T21 const & t21,T22 const & t22,T23 const & t23,T24 const & t24,T25 const & t25,T26 const & t26)609       kernel & operator()(T0 const & t0, T1 const & t1, T2 const & t2, T3 const & t3, T4 const & t4, T5 const & t5,
610                           T6 const & t6, T7 const & t7, T8 const & t8, T9 const & t9, T10 const & t10, T11 const & t11,
611                           T12 const & t12, T13 const & t13, T14 const & t14, T15 const & t15, T16 const & t16, T17 const & t17,
612                           T18 const & t18, T19 const & t19, T20 const & t20, T21 const & t21, T22 const & t22, T23 const & t23,
613                           T24 const & t24, T25 const & t25, T26 const & t26
614                          )
615       {
616          arg(0, t0); arg(1, t1); arg(2, t2); arg(3, t3); arg(4, t4); arg(5, t5);
617          arg(6, t6); arg(7, t7); arg(8, t8); arg(9, t9); arg(10, t10); arg(11, t11);
618          arg(12, t12); arg(13, t13); arg(14, t14); arg(15, t15); arg(16, t16); arg(17, t17);
619          arg(18, t18); arg(19, t19); arg(20, t20); arg(21, t21); arg(22, t22); arg(23, t23);
620          arg(24, t24); arg(25, t25); arg(26, t26);
621          return *this;
622       }
623 
624       /** @brief Convenience function for setting 28 kernel parameters */
625       template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5,
626                 typename T6, typename T7, typename T8, typename T9, typename T10, typename T11,
627                 typename T12, typename T13, typename T14, typename T15, typename T16, typename T17,
628                 typename T18, typename T19, typename T20, typename T21, typename T22, typename T23,
629                 typename T24, typename T25, typename T26, typename T27>
operator ()(T0 const & t0,T1 const & t1,T2 const & t2,T3 const & t3,T4 const & t4,T5 const & t5,T6 const & t6,T7 const & t7,T8 const & t8,T9 const & t9,T10 const & t10,T11 const & t11,T12 const & t12,T13 const & t13,T14 const & t14,T15 const & t15,T16 const & t16,T17 const & t17,T18 const & t18,T19 const & t19,T20 const & t20,T21 const & t21,T22 const & t22,T23 const & t23,T24 const & t24,T25 const & t25,T26 const & t26,T27 const & t27)630       kernel & operator()(T0 const & t0, T1 const & t1, T2 const & t2, T3 const & t3, T4 const & t4, T5 const & t5,
631                           T6 const & t6, T7 const & t7, T8 const & t8, T9 const & t9, T10 const & t10, T11 const & t11,
632                           T12 const & t12, T13 const & t13, T14 const & t14, T15 const & t15, T16 const & t16, T17 const & t17,
633                           T18 const & t18, T19 const & t19, T20 const & t20, T21 const & t21, T22 const & t22, T23 const & t23,
634                           T24 const & t24, T25 const & t25, T26 const & t26, T27 const & t27
635                          )
636       {
637          arg(0, t0); arg(1, t1); arg(2, t2); arg(3, t3); arg(4, t4); arg(5, t5);
638          arg(6, t6); arg(7, t7); arg(8, t8); arg(9, t9); arg(10, t10); arg(11, t11);
639          arg(12, t12); arg(13, t13); arg(14, t14); arg(15, t15); arg(16, t16); arg(17, t17);
640          arg(18, t18); arg(19, t19); arg(20, t20); arg(21, t21); arg(22, t22); arg(23, t23);
641          arg(24, t24); arg(25, t25); arg(26, t26); arg(27, t27);
642          return *this;
643       }
644 
645       /** @brief Convenience function for setting 29 kernel parameters */
646       template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5,
647                 typename T6, typename T7, typename T8, typename T9, typename T10, typename T11,
648                 typename T12, typename T13, typename T14, typename T15, typename T16, typename T17,
649                 typename T18, typename T19, typename T20, typename T21, typename T22, typename T23,
650                 typename T24, typename T25, typename T26, typename T27, typename T28>
operator ()(T0 const & t0,T1 const & t1,T2 const & t2,T3 const & t3,T4 const & t4,T5 const & t5,T6 const & t6,T7 const & t7,T8 const & t8,T9 const & t9,T10 const & t10,T11 const & t11,T12 const & t12,T13 const & t13,T14 const & t14,T15 const & t15,T16 const & t16,T17 const & t17,T18 const & t18,T19 const & t19,T20 const & t20,T21 const & t21,T22 const & t22,T23 const & t23,T24 const & t24,T25 const & t25,T26 const & t26,T27 const & t27,T28 const & t28)651       kernel & operator()(T0 const & t0, T1 const & t1, T2 const & t2, T3 const & t3, T4 const & t4, T5 const & t5,
652                           T6 const & t6, T7 const & t7, T8 const & t8, T9 const & t9, T10 const & t10, T11 const & t11,
653                           T12 const & t12, T13 const & t13, T14 const & t14, T15 const & t15, T16 const & t16, T17 const & t17,
654                           T18 const & t18, T19 const & t19, T20 const & t20, T21 const & t21, T22 const & t22, T23 const & t23,
655                           T24 const & t24, T25 const & t25, T26 const & t26, T27 const & t27, T28 const & t28
656                          )
657       {
658          arg(0, t0); arg(1, t1); arg(2, t2); arg(3, t3); arg(4, t4); arg(5, t5);
659          arg(6, t6); arg(7, t7); arg(8, t8); arg(9, t9); arg(10, t10); arg(11, t11);
660          arg(12, t12); arg(13, t13); arg(14, t14); arg(15, t15); arg(16, t16); arg(17, t17);
661          arg(18, t18); arg(19, t19); arg(20, t20); arg(21, t21); arg(22, t22); arg(23, t23);
662          arg(24, t24); arg(25, t25); arg(26, t26); arg(27, t27); arg(28, t28);
663          return *this;
664       }
665 
666       /** @brief Convenience function for setting 30 kernel parameters */
667       template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5,
668                 typename T6, typename T7, typename T8, typename T9, typename T10, typename T11,
669                 typename T12, typename T13, typename T14, typename T15, typename T16, typename T17,
670                 typename T18, typename T19, typename T20, typename T21, typename T22, typename T23,
671                 typename T24, typename T25, typename T26, typename T27, typename T28, typename T29>
operator ()(T0 const & t0,T1 const & t1,T2 const & t2,T3 const & t3,T4 const & t4,T5 const & t5,T6 const & t6,T7 const & t7,T8 const & t8,T9 const & t9,T10 const & t10,T11 const & t11,T12 const & t12,T13 const & t13,T14 const & t14,T15 const & t15,T16 const & t16,T17 const & t17,T18 const & t18,T19 const & t19,T20 const & t20,T21 const & t21,T22 const & t22,T23 const & t23,T24 const & t24,T25 const & t25,T26 const & t26,T27 const & t27,T28 const & t28,T29 const & t29)672       kernel & operator()(T0 const & t0, T1 const & t1, T2 const & t2, T3 const & t3, T4 const & t4, T5 const & t5,
673                           T6 const & t6, T7 const & t7, T8 const & t8, T9 const & t9, T10 const & t10, T11 const & t11,
674                           T12 const & t12, T13 const & t13, T14 const & t14, T15 const & t15, T16 const & t16, T17 const & t17,
675                           T18 const & t18, T19 const & t19, T20 const & t20, T21 const & t21, T22 const & t22, T23 const & t23,
676                           T24 const & t24, T25 const & t25, T26 const & t26, T27 const & t27, T28 const & t28, T29 const & t29
677                          )
678       {
679          arg(0, t0); arg(1, t1); arg(2, t2); arg(3, t3); arg(4, t4); arg(5, t5);
680          arg(6, t6); arg(7, t7); arg(8, t8); arg(9, t9); arg(10, t10); arg(11, t11);
681          arg(12, t12); arg(13, t13); arg(14, t14); arg(15, t15); arg(16, t16); arg(17, t17);
682          arg(18, t18); arg(19, t19); arg(20, t20); arg(21, t21); arg(22, t22); arg(23, t23);
683          arg(24, t24); arg(25, t25); arg(26, t26); arg(27, t27); arg(28, t28); arg(29, t29);
684          return *this;
685       }
686 
687       /** @brief Convenience function for setting 31 kernel parameters */
688       template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5,
689                 typename T6, typename T7, typename T8, typename T9, typename T10, typename T11,
690                 typename T12, typename T13, typename T14, typename T15, typename T16, typename T17,
691                 typename T18, typename T19, typename T20, typename T21, typename T22, typename T23,
692                 typename T24, typename T25, typename T26, typename T27, typename T28, typename T29,
693                 typename T30>
operator ()(T0 const & t0,T1 const & t1,T2 const & t2,T3 const & t3,T4 const & t4,T5 const & t5,T6 const & t6,T7 const & t7,T8 const & t8,T9 const & t9,T10 const & t10,T11 const & t11,T12 const & t12,T13 const & t13,T14 const & t14,T15 const & t15,T16 const & t16,T17 const & t17,T18 const & t18,T19 const & t19,T20 const & t20,T21 const & t21,T22 const & t22,T23 const & t23,T24 const & t24,T25 const & t25,T26 const & t26,T27 const & t27,T28 const & t28,T29 const & t29,T30 const & t30)694       kernel & operator()(T0 const & t0, T1 const & t1, T2 const & t2, T3 const & t3, T4 const & t4, T5 const & t5,
695                           T6 const & t6, T7 const & t7, T8 const & t8, T9 const & t9, T10 const & t10, T11 const & t11,
696                           T12 const & t12, T13 const & t13, T14 const & t14, T15 const & t15, T16 const & t16, T17 const & t17,
697                           T18 const & t18, T19 const & t19, T20 const & t20, T21 const & t21, T22 const & t22, T23 const & t23,
698                           T24 const & t24, T25 const & t25, T26 const & t26, T27 const & t27, T28 const & t28, T29 const & t29,
699                           T30 const & t30
700                          )
701       {
702          arg(0, t0); arg(1, t1); arg(2, t2); arg(3, t3); arg(4, t4); arg(5, t5);
703          arg(6, t6); arg(7, t7); arg(8, t8); arg(9, t9); arg(10, t10); arg(11, t11);
704          arg(12, t12); arg(13, t13); arg(14, t14); arg(15, t15); arg(16, t16); arg(17, t17);
705          arg(18, t18); arg(19, t19); arg(20, t20); arg(21, t21); arg(22, t22); arg(23, t23);
706          arg(24, t24); arg(25, t25); arg(26, t26); arg(27, t27); arg(28, t28); arg(29, t29);
707          arg(30, t30);
708          return *this;
709       }
710 
711       /** @brief Convenience function for setting 32 kernel parameters */
712       template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5,
713                 typename T6, typename T7, typename T8, typename T9, typename T10, typename T11,
714                 typename T12, typename T13, typename T14, typename T15, typename T16, typename T17,
715                 typename T18, typename T19, typename T20, typename T21, typename T22, typename T23,
716                 typename T24, typename T25, typename T26, typename T27, typename T28, typename T29,
717                 typename T30, typename T31>
operator ()(T0 const & t0,T1 const & t1,T2 const & t2,T3 const & t3,T4 const & t4,T5 const & t5,T6 const & t6,T7 const & t7,T8 const & t8,T9 const & t9,T10 const & t10,T11 const & t11,T12 const & t12,T13 const & t13,T14 const & t14,T15 const & t15,T16 const & t16,T17 const & t17,T18 const & t18,T19 const & t19,T20 const & t20,T21 const & t21,T22 const & t22,T23 const & t23,T24 const & t24,T25 const & t25,T26 const & t26,T27 const & t27,T28 const & t28,T29 const & t29,T30 const & t30,T31 const & t31)718       kernel & operator()(T0 const & t0, T1 const & t1, T2 const & t2, T3 const & t3, T4 const & t4, T5 const & t5,
719                           T6 const & t6, T7 const & t7, T8 const & t8, T9 const & t9, T10 const & t10, T11 const & t11,
720                           T12 const & t12, T13 const & t13, T14 const & t14, T15 const & t15, T16 const & t16, T17 const & t17,
721                           T18 const & t18, T19 const & t19, T20 const & t20, T21 const & t21, T22 const & t22, T23 const & t23,
722                           T24 const & t24, T25 const & t25, T26 const & t26, T27 const & t27, T28 const & t28, T29 const & t29,
723                           T30 const & t30, T31 const & t31
724                          )
725       {
726          arg(0, t0); arg(1, t1); arg(2, t2); arg(3, t3); arg(4, t4); arg(5, t5);
727          arg(6, t6); arg(7, t7); arg(8, t8); arg(9, t9); arg(10, t10); arg(11, t11);
728          arg(12, t12); arg(13, t13); arg(14, t14); arg(15, t15); arg(16, t16); arg(17, t17);
729          arg(18, t18); arg(19, t19); arg(20, t20); arg(21, t21); arg(22, t22); arg(23, t23);
730          arg(24, t24); arg(25, t25); arg(26, t26); arg(27, t27); arg(28, t28); arg(29, t29);
731          arg(30, t30); arg(31, t31);
732          return *this;
733       }
734 
735 
736 
737 
738       /** @brief Returns the local work size at the respective dimension
739       *
740       * @param index   Dimension index (currently either 0 or 1)
741       */
local_work_size(int index=0) const742       size_type local_work_size(int index = 0) const
743       {
744         assert(index < 3 && bool("Work size index out of bounds"));
745         return local_work_size_[index];
746       }
747       /** @brief Returns the global work size at the respective dimension
748       *
749       * @param index   Dimension index (currently either 0 or 1)
750       */
global_work_size(int index=0) const751       size_type global_work_size(int index = 0) const
752       {
753         assert(index < 3 && bool("Work size index out of bounds"));
754         return global_work_size_[index];
755       }
756 
757       /** @brief Sets the local work size at the respective dimension
758       *
759       * @param index   Dimension index (currently either 0 or 1)
760       * @param s       The new local work size
761       */
local_work_size(int index,size_type s)762       void local_work_size(int index, size_type s)
763       {
764         #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_KERNEL)
765         std::cout << "ViennaCL: Setting local work size to " << s << " at index " << index << " for kernel " << name_ << std::endl;
766         #endif
767         assert(index < 3 && bool("Work size index out of bounds"));
768         local_work_size_[index] = s;
769       }
770       /** @brief Sets the global work size at the respective dimension
771       *
772       * @param index   Dimension index (currently either 0 or 1)
773       * @param s       The new global work size
774       */
global_work_size(int index,size_type s)775       void global_work_size(int index, size_type s)
776       {
777         #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_KERNEL)
778         std::cout << "ViennaCL: Setting global work size to " << s << " at index " << index << " for kernel " << name_ << std::endl;
779         #endif
780         assert(index < 3 && bool("Work size index out of bounds"));
781         global_work_size_[index] = s;
782       }
783 
name() const784       std::string const & name() const { return name_; }
785 
handle() const786       viennacl::ocl::handle<cl_kernel> const & handle() const { return handle_; }
787 
context() const788       viennacl::ocl::context const & context() const { return *p_context_; }
789 
790     private:
791 
792       inline void set_work_size_defaults();    //see context.hpp for implementation
793 
794       viennacl::ocl::handle<cl_kernel> handle_;
795       viennacl::ocl::program const * p_program_;
796       viennacl::ocl::context const * p_context_;
797       std::string name_;
798       size_type local_work_size_[3];
799       size_type global_work_size_[3];
800     };
801 
802   } //namespace ocl
803 } //namespace viennacl
804 
805 #endif
806