1 /*******************************************************************************
2  * Copyright (c) 2008-2010 The Khronos Group Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and/or associated documentation files (the
6  * "Materials"), to deal in the Materials without restriction, including
7  * without limitation the rights to use, copy, modify, merge, publish,
8  * distribute, sublicense, and/or sell copies of the Materials, and to
9  * permit persons to whom the Materials are furnished to do so, subject to
10  * the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included
13  * in all copies or substantial portions of the Materials.
14  *
15  * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21  * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
22  ******************************************************************************/
23 
24 /*! \file
25  *
26  *   \brief C++ bindings for OpenCL 1.0 (rev 48) and OpenCL 1.1 (rev 33)
27  *   \author Benedict R. Gaster and Laurent Morichetti
28  *
29  *   Additions and fixes from Brian Cole, March 3rd 2010.
30  *
31  *   \version 1.1
32  *   \date June 2010
33  *
34  *   Optional extension support
35  *
36  *         cl
37  *         cl_ext_device_fission
38  *				#define USE_CL_DEVICE_FISSION
39  */
40 
41 /*! \mainpage
42  * \section intro Introduction
43  * For many large applications C++ is the language of choice and so it seems
44  * reasonable to define C++ bindings for OpenCL.
45  *
46  *
47  * The interface is contained with a single C++ header file \em cl.hpp and all
48  * definitions are contained within the namespace \em cl. There is no additional
49  * requirement to include \em cl.h and to use either the C++ or original C
50  * bindings it is enough to simply include \em cl.hpp.
51  *
52  * The bindings themselves are lightweight and correspond closely to the
53  * underlying C API. Using the C++ bindings introduces no additional execution
54  * overhead.
55  *
56  * For detail documentation on the bindings see:
57  *
58  * The OpenCL C++ Wrapper API 1.1 (revision 04)
59  *  http://www.khronos.org/registry/cl/specs/opencl-cplusplus-1.1.pdf
60  *
61  * \section example Example
62  *
63  * The following example shows a general use case for the C++
64  * bindings, including support for the optional exception feature and
65  * also the supplied vector and string classes, see following sections for
66  * decriptions of these features.
67  *
68  * \code
69  * #define __CL_ENABLE_EXCEPTIONS
70  *
71  * #if defined(__APPLE__) || defined(__MACOSX)
72  * #include <OpenCL/cl.hpp>
73  * #else
74  * #include <CL/cl.hpp>
75  * #endif
76  * #include <cstdio>
77  * #include <cstdlib>
78  * #include <iostream>
79  *
80  *  const char * helloStr  = "__kernel void "
81  *                           "hello(void) "
82  *                           "{ "
83  *                           "  "
84  *                           "} ";
85  *
86  *  int
87  *  main(void)
88  *  {
89  *     cl_int err = CL_SUCCESS;
90  *     try {
91  *
92  *       std::vector<cl::Platform> platforms;
93  *       cl::Platform::get(&platforms);
94  *       if (platforms.size() == 0) {
95  *           std::cout << "Platform size 0\n";
96  *           return -1;
97  *       }
98  *
99  *       cl_context_properties properties[] =
100  *          { CL_CONTEXT_PLATFORM, (cl_context_properties)(platforms[0])(), 0};
101  *       cl::Context context(CL_DEVICE_TYPE_CPU, properties);
102  *
103  *       std::vector<cl::Device> devices = context.getInfo<CL_CONTEXT_DEVICES>();
104  *
105  *       cl::Program::Sources source(1,
106  *           std::make_pair(helloStr,strlen(helloStr)));
107  *       cl::Program program_ = cl::Program(context, source);
108  *       program_.build(devices);
109  *
110  *       cl::Kernel kernel(program_, "hello", &err);
111  *
112  *       cl::Event event;
113  *       cl::CommandQueue queue(context, devices[0], 0, &err);
114  *       queue.enqueueNDRangeKernel(
115  *           kernel,
116  *           cl::NullRange,
117  *           cl::NDRange(4,4),
118  *           cl::NullRange,
119  *           NULL,
120  *           &event);
121  *
122  *       event.wait();
123  *     }
124  *     catch (cl::Error err) {
125  *        std::cerr
126  *           << "ERROR: "
127  *           << err.what()
128  *           << "("
129  *           << err.err()
130  *           << ")"
131  *           << std::endl;
132  *     }
133  *
134  *    return EXIT_SUCCESS;
135  *  }
136  *
137  * \endcode
138  *
139  */
140 #ifndef CL_HPP_
141 #define CL_HPP_
142 
143 #ifdef _WIN32
144 #include <windows.h>
145 #include <malloc.h>
146 #if defined(USE_DX_INTEROP)
147 #include <CL/cl_d3d10.h>
148 #endif
149 #endif // _WIN32
150 
151 //
152 #if defined(USE_CL_DEVICE_FISSION)
153 #include <CL/cl_ext.h>
154 #endif
155 
156 #if defined(__APPLE__) || defined(__MACOSX)
157 #include <OpenGL/OpenGL.h>
158 #include <OpenCL/opencl.h>
159 #else
160 #include <GL/gl.h>
161 #include <CL/opencl.h>
162 #endif // !__APPLE__
163 
164 #if !defined(CL_CALLBACK)
165 #define CL_CALLBACK
166 #endif //CL_CALLBACK
167 
168 #include <utility>
169 
170 #if !defined(__NO_STD_VECTOR)
171 #include <vector>
172 #endif
173 
174 #if !defined(__NO_STD_STRING)
175 #include <string>
176 #endif
177 
178 #if defined(linux) || defined(__APPLE__) || defined(__MACOSX)
179 # include <alloca.h>
180 #endif // linux
181 
182 #include <cstring>
183 
184 /*! \namespace cl
185  *
186  * \brief The OpenCL C++ bindings are defined within this namespace.
187  *
188  */
189 namespace cl {
190 
191 #define __INIT_CL_EXT_FCN_PTR(name) \
192     if(!pfn_##name) { \
193         pfn_##name = (PFN_##name) \
194             clGetExtensionFunctionAddress(#name); \
195         if(!pfn_##name) { \
196         } \
197     }
198 
199 class Program;
200 class Device;
201 class Context;
202 class CommandQueue;
203 class Memory;
204 
205 #if defined(__CL_ENABLE_EXCEPTIONS)
206 #include <exception>
207 /*! \class Error
208  * \brief Exception class
209  */
210 class Error : public std::exception
211 {
212 private:
213     cl_int err_;
214     const char * errStr_;
215 public:
216     /*! Create a new CL error exception for a given error code
217      *  and corresponding message.
218      */
Error(cl_int err,const char * errStr=NULL)219     Error(cl_int err, const char * errStr = NULL) : err_(err), errStr_(errStr)
220     {}
221 
~Error()222     ~Error() throw() {}
223 
224     /*! \brief Get error string associated with exception
225      *
226      * \return A memory pointer to the error message string.
227      */
what() const228     virtual const char * what() const throw ()
229     {
230         if (errStr_ == NULL) {
231             return "empty";
232         }
233         else {
234             return errStr_;
235         }
236     }
237 
238     /*! \brief Get error code associated with exception
239      *
240      *  \return The error code.
241      */
err(void) const242     const cl_int err(void) const { return err_; }
243 };
244 
245 #define __ERR_STR(x) #x
246 #else
247 #define __ERR_STR(x) NULL
248 #endif // __CL_ENABLE_EXCEPTIONS
249 
250 //! \cond DOXYGEN_DETAIL
251 #if !defined(__CL_USER_OVERRIDE_ERROR_STRINGS)
252 #define __GET_DEVICE_INFO_ERR               __ERR_STR(clgetDeviceInfo)
253 #define __GET_PLATFORM_INFO_ERR             __ERR_STR(clGetPlatformInfo)
254 #define __GET_DEVICE_IDS_ERR                __ERR_STR(clGetDeviceIDs)
255 #define __GET_PLATFORM_IDS_ERR              __ERR_STR(clGetPlatformIDs)
256 #define __GET_CONTEXT_INFO_ERR              __ERR_STR(clGetContextInfo)
257 #define __GET_EVENT_INFO_ERR                __ERR_STR(clGetEventInfo)
258 #define __GET_EVENT_PROFILE_INFO_ERR        __ERR_STR(clGetEventProfileInfo)
259 #define __GET_MEM_OBJECT_INFO_ERR           __ERR_STR(clGetMemObjectInfo)
260 #define __GET_IMAGE_INFO_ERR                __ERR_STR(clGetImageInfo)
261 #define __GET_SAMPLER_INFO_ERR              __ERR_STR(clGetSamplerInfo)
262 #define __GET_KERNEL_INFO_ERR               __ERR_STR(clGetKernelInfo)
263 #define __GET_KERNEL_WORK_GROUP_INFO_ERR    __ERR_STR(clGetKernelWorkGroupInfo)
264 #define __GET_PROGRAM_INFO_ERR              __ERR_STR(clGetProgramInfo)
265 #define __GET_PROGRAM_BUILD_INFO_ERR        __ERR_STR(clGetProgramBuildInfo)
266 #define __GET_COMMAND_QUEUE_INFO_ERR        __ERR_STR(clGetCommandQueueInfo)
267 
268 #define __CREATE_CONTEXT_FROM_TYPE_ERR      __ERR_STR(clCreateContextFromType)
269 #define __GET_SUPPORTED_IMAGE_FORMATS_ERR   __ERR_STR(clGetSupportedImageFormats)
270 
271 #define __CREATE_BUFFER_ERR                 __ERR_STR(clCreateBuffer)
272 #define __CREATE_SUBBUFFER_ERR              __ERR_STR(clCreateSubBuffer)
273 #define __CREATE_GL_BUFFER_ERR              __ERR_STR(clCreateFromGLBuffer)
274 #define __GET_GL_OBJECT_INFO_ERR            __ERR_STR(clGetGLObjectInfo)
275 #define __CREATE_IMAGE2D_ERR                __ERR_STR(clCreateImage2D)
276 #define __CREATE_IMAGE3D_ERR                __ERR_STR(clCreateImage3D)
277 #define __CREATE_SAMPLER_ERR                __ERR_STR(clCreateSampler)
278 #define __SET_MEM_OBJECT_DESTRUCTOR_CALLBACK_ERR __ERR_STR(clSetMemObjectDestructorCallback)
279 
280 #define __CREATE_USER_EVENT_ERR             __ERR_STR(clCreateUserEvent)
281 #define __SET_USER_EVENT_STATUS_ERR         __ERR_STR(clSetUserEventStatus)
282 #define __SET_EVENT_CALLBACK_ERR            __ERR_STR(clSetEventCallback)
283 #define __WAIT_FOR_EVENTS_ERR               __ERR_STR(clWaitForEvents)
284 
285 #define __CREATE_KERNEL_ERR                 __ERR_STR(clCreateKernel)
286 #define __SET_KERNEL_ARGS_ERR               __ERR_STR(clSetKernelArg)
287 #define __CREATE_PROGRAM_WITH_SOURCE_ERR    __ERR_STR(clCreateProgramWithSource)
288 #define __CREATE_PROGRAM_WITH_BINARY_ERR    __ERR_STR(clCreateProgramWithBinary)
289 #define __BUILD_PROGRAM_ERR                 __ERR_STR(clBuildProgram)
290 #define __CREATE_KERNELS_IN_PROGRAM_ERR     __ERR_STR(clCreateKernelsInProgram)
291 
292 #define __CREATE_COMMAND_QUEUE_ERR          __ERR_STR(clCreateCommandQueue)
293 #define __SET_COMMAND_QUEUE_PROPERTY_ERR    __ERR_STR(clSetCommandQueueProperty)
294 #define __ENQUEUE_READ_BUFFER_ERR           __ERR_STR(clEnqueueReadBuffer)
295 #define __ENQUEUE_READ_BUFFER_RECT_ERR      __ERR_STR(clEnqueueReadBufferRect)
296 #define __ENQUEUE_WRITE_BUFFER_ERR          __ERR_STR(clEnqueueWriteBuffer)
297 #define __ENQUEUE_WRITE_BUFFER_RECT_ERR     __ERR_STR(clEnqueueWriteBufferRect)
298 #define __ENQEUE_COPY_BUFFER_ERR            __ERR_STR(clEnqueueCopyBuffer)
299 #define __ENQEUE_COPY_BUFFER_RECT_ERR       __ERR_STR(clEnqueueCopyBufferRect)
300 #define __ENQUEUE_READ_IMAGE_ERR            __ERR_STR(clEnqueueReadImage)
301 #define __ENQUEUE_WRITE_IMAGE_ERR           __ERR_STR(clEnqueueWriteImage)
302 #define __ENQUEUE_COPY_IMAGE_ERR            __ERR_STR(clEnqueueCopyImage)
303 #define __ENQUEUE_COPY_IMAGE_TO_BUFFER_ERR  __ERR_STR(clEnqueueCopyImageToBuffer)
304 #define __ENQUEUE_COPY_BUFFER_TO_IMAGE_ERR  __ERR_STR(clEnqueueCopyBufferToImage)
305 #define __ENQUEUE_MAP_BUFFER_ERR            __ERR_STR(clEnqueueMapBuffer)
306 #define __ENQUEUE_MAP_IMAGE_ERR             __ERR_STR(clEnqueueMapImage)
307 #define __ENQUEUE_UNMAP_MEM_OBJECT_ERR      __ERR_STR(clEnqueueUnMapMemObject)
308 #define __ENQUEUE_NDRANGE_KERNEL_ERR        __ERR_STR(clEnqueueNDRangeKernel)
309 #define __ENQUEUE_TASK_ERR                  __ERR_STR(clEnqueueTask)
310 #define __ENQUEUE_NATIVE_KERNEL             __ERR_STR(clEnqueueNativeKernel)
311 #define __ENQUEUE_MARKER_ERR                __ERR_STR(clEnqueueMarker)
312 #define __ENQUEUE_WAIT_FOR_EVENTS_ERR       __ERR_STR(clEnqueueWaitForEvents)
313 #define __ENQUEUE_BARRIER_ERR               __ERR_STR(clEnqueueBarrier)
314 
315 #define __ENQUEUE_ACQUIRE_GL_ERR            __ERR_STR(clEnqueueAcquireGLObjects)
316 #define __ENQUEUE_RELEASE_GL_ERR            __ERR_STR(clEnqueueReleaseGLObjects)
317 
318 #define __UNLOAD_COMPILER_ERR               __ERR_STR(clUnloadCompiler)
319 
320 #define __FLUSH_ERR                         __ERR_STR(clFlush)
321 #define __FINISH_ERR                        __ERR_STR(clFinish)
322 
323 #define __CREATE_SUB_DEVICES                __ERR_STR(clCreateSubDevicesEXT)
324 #endif // __CL_USER_OVERRIDE_ERROR_STRINGS
325 //! \endcond
326 
327 /*! \class string
328  * \brief Simple string class, that provides a limited subset of std::string
329  * functionality but avoids many of the issues that come with that class.
330  */
331 class string
332 {
333 private:
334     ::size_t size_;
335     char * str_;
336 public:
string(void)337     string(void) : size_(0), str_(NULL)
338     {
339     }
340 
string(char * str,::size_t size)341     string(char * str, ::size_t size) :
342         size_(size),
343         str_(NULL)
344     {
345         str_ = new char[size_+1];
346         if (str_ != NULL) {
347             memcpy(str_, str, size_  * sizeof(char));
348             str_[size_] = '\0';
349         }
350         else {
351             size_ = 0;
352         }
353     }
354 
string(char * str)355     string(char * str) :
356         str_(NULL)
357     {
358         size_= ::strlen(str);
359         str_ = new char[size_ + 1];
360         if (str_ != NULL) {
361             memcpy(str_, str, (size_ + 1) * sizeof(char));
362         }
363         else {
364             size_ = 0;
365         }
366     }
367 
operator =(const string & rhs)368     string& operator=(const string& rhs)
369     {
370         if (this == &rhs) {
371             return *this;
372         }
373 
374         if (rhs.size_ == 0 || rhs.str_ == NULL) {
375             size_ = 0;
376             str_  = NULL;
377         }
378         else {
379             size_ = rhs.size_;
380             str_ = new char[size_ + 1];
381             if (str_ != NULL) {
382                 memcpy(str_, rhs.str_, (size_ + 1) * sizeof(char));
383             }
384             else {
385                 size_ = 0;
386             }
387         }
388 
389         return *this;
390     }
391 
string(const string & rhs)392     string(const string& rhs)
393     {
394         *this = rhs;
395     }
396 
~string()397     ~string()
398     {
399         if (str_ != NULL) {
400             delete[] str_;
401         }
402     }
403 
size(void) const404     ::size_t size(void) const   { return size_; }
length(void) const405     ::size_t length(void) const { return size(); }
406 
c_str(void) const407     const char * c_str(void) const { return (str_) ? str_ : "";}
408 };
409 
410 #if !defined(__USE_DEV_STRING) && !defined(__NO_STD_STRING)
411 #include <string>
412 typedef std::string STRING_CLASS;
413 #elif !defined(__USE_DEV_STRING)
414 typedef cl::string STRING_CLASS;
415 #endif
416 
417 #if !defined(__USE_DEV_VECTOR) && !defined(__NO_STD_VECTOR)
418 #include <vector>
419 #define VECTOR_CLASS std::vector
420 #elif !defined(__USE_DEV_VECTOR)
421 #define VECTOR_CLASS cl::vector
422 #endif
423 
424 #if !defined(__MAX_DEFAULT_VECTOR_SIZE)
425 #define __MAX_DEFAULT_VECTOR_SIZE 10
426 #endif
427 
428 /*! \class vector
429  * \brief Fixed sized vector implementation that mirroring
430  * std::vector functionality.
431  */
432 template <typename T, unsigned int N = __MAX_DEFAULT_VECTOR_SIZE>
433 class vector
434 {
435 private:
436     T data_[N];
437     unsigned int size_;
438     bool empty_;
439 public:
vector()440     vector() :
441         size_(-1),
442         empty_(true)
443     {}
444 
~vector()445     ~vector() {}
446 
size(void) const447     unsigned int size(void) const
448     {
449         return size_ + 1;
450     }
451 
clear()452     void clear()
453     {
454         size_ = -1;
455         empty_ = true;
456     }
457 
push_back(const T & x)458     void push_back (const T& x)
459     {
460         if (size() < N) {
461             size_++;
462             data_[size_] = x;
463             empty_ = false;
464         }
465     }
466 
pop_back(void)467     void pop_back(void)
468     {
469         if (!empty_) {
470             data_[size_].~T();
471             size_--;
472             if (size_ == -1) {
473                 empty_ = true;
474             }
475         }
476     }
477 
vector(const vector<T,N> & vec)478     vector(const vector<T, N>& vec) :
479         size_(vec.size_),
480         empty_(vec.empty_)
481     {
482         if (!empty_) {
483             memcpy(&data_[0], &vec.data_[0], size() * sizeof(T));
484         }
485     }
486 
vector(unsigned int size,const T & val=T ())487     vector(unsigned int size, const T& val = T()) :
488         size_(-1),
489         empty_(true)
490     {
491         for (unsigned int i = 0; i < size; i++) {
492             push_back(val);
493         }
494     }
495 
operator =(const vector<T,N> & rhs)496     vector<T, N>& operator=(const vector<T, N>& rhs)
497     {
498         if (this == &rhs) {
499             return *this;
500         }
501 
502         size_  = rhs.size_;
503         empty_ = rhs.empty_;
504 
505         if (!empty_) {
506             memcpy(&data_[0], &rhs.data_[0], size() * sizeof(T));
507         }
508 
509         return *this;
510     }
511 
operator ==(vector<T,N> & vec)512     bool operator==(vector<T,N> &vec)
513     {
514         if (empty_ && vec.empty_) {
515             return true;
516         }
517 
518         if (size() != vec.size()) {
519             return false;
520         }
521 
522         return memcmp(&data_[0], &vec.data_[0], size() * sizeof(T)) == 0 ? true : false;
523     }
524 
operator T*()525     operator T* ()             { return data_; }
operator const T*() const526     operator const T* () const { return data_; }
527 
empty(void) const528     bool empty (void) const
529     {
530         return empty_;
531     }
532 
max_size(void) const533     unsigned int max_size (void) const
534     {
535         return N;
536     }
537 
capacity() const538     unsigned int capacity () const
539     {
540         return sizeof(T) * N;
541     }
542 
operator [](int index)543     T& operator[](int index)
544     {
545         return data_[index];
546     }
547 
operator [](int index) const548     T operator[](int index) const
549     {
550         return data_[index];
551     }
552 
553     template<class I>
assign(I start,I end)554     void assign(I start, I end)
555     {
556         clear();
557         while(start < end) {
558             push_back(*start);
559             start++;
560         }
561     }
562 
563     /*! \class iterator
564      * \brief Iterator class for vectors
565      */
566     class iterator
567     {
568     private:
569         vector<T,N> vec_;
570         int index_;
571         bool initialized_;
572     public:
iterator(void)573         iterator(void) :
574             index_(-1),
575             initialized_(false)
576         {
577             index_ = -1;
578             initialized_ = false;
579         }
580 
~iterator(void)581         ~iterator(void) {}
582 
begin(vector<T,N> & vec)583         static iterator begin(vector<T,N> &vec)
584         {
585             iterator i;
586 
587             if (!vec.empty()) {
588                 i.index_ = 0;
589             }
590 
591             i.vec_ = vec;
592             i.initialized_ = true;
593             return i;
594         }
595 
end(vector<T,N> & vec)596         static iterator end(vector<T,N> &vec)
597         {
598             iterator i;
599 
600             if (!vec.empty()) {
601                 i.index_ = vec.size();
602             }
603             i.vec_ = vec;
604             i.initialized_ = true;
605             return i;
606         }
607 
operator ==(iterator i)608         bool operator==(iterator i)
609         {
610             return ((vec_ == i.vec_) &&
611                     (index_ == i.index_) &&
612                     (initialized_ == i.initialized_));
613         }
614 
operator !=(iterator i)615         bool operator!=(iterator i)
616         {
617             return (!(*this==i));
618         }
619 
operator ++()620         void operator++()
621         {
622             index_++;
623         }
624 
operator ++(int x)625         void operator++(int x)
626         {
627             index_ += x;
628         }
629 
operator --()630         void operator--()
631         {
632             index_--;
633         }
634 
operator --(int x)635         void operator--(int x)
636         {
637             index_ -= x;
638         }
639 
operator *()640         T operator *()
641         {
642             return vec_[index_];
643         }
644     };
645 
begin(void)646     iterator begin(void)
647     {
648         return iterator::begin(*this);
649     }
650 
end(void)651     iterator end(void)
652     {
653         return iterator::end(*this);
654     }
655 
front(void)656     T& front(void)
657     {
658         return data_[0];
659     }
660 
back(void)661     T& back(void)
662     {
663         return data_[size_];
664     }
665 
front(void) const666     const T& front(void) const
667     {
668         return data_[0];
669     }
670 
back(void) const671     const T& back(void) const
672     {
673         return data_[size_];
674     }
675 };
676 
677 /*!
678  * \brief size_t class used to interface between C++ and
679  * OpenCL C calls that require arrays of size_t values, who's
680  * size is known statically.
681  */
682 template <int N>
683 struct size_t : public cl::vector< ::size_t, N> { };
684 
685 namespace detail {
686 
687 // GetInfo help struct
688 template <typename Functor, typename T>
689 struct GetInfoHelper
690 {
691     static cl_int
getcl::detail::GetInfoHelper692     get(Functor f, cl_uint name, T* param)
693     {
694         return f(name, sizeof(T), param, NULL);
695     }
696 };
697 
698 // Specialized GetInfoHelper for VECTOR_CLASS params
699 template <typename Func, typename T>
700 struct GetInfoHelper<Func, VECTOR_CLASS<T> >
701 {
getcl::detail::GetInfoHelper702     static cl_int get(Func f, cl_uint name, VECTOR_CLASS<T>* param)
703     {
704         ::size_t required;
705         cl_int err = f(name, 0, NULL, &required);
706         if (err != CL_SUCCESS) {
707             return err;
708         }
709 
710         T* value = (T*) alloca(required);
711         err = f(name, required, value, NULL);
712         if (err != CL_SUCCESS) {
713             return err;
714         }
715 
716         param->assign(&value[0], &value[required/sizeof(T)]);
717         return CL_SUCCESS;
718     }
719 };
720 
721 // Specialized for getInfo<CL_PROGRAM_BINARIES>
722 template <typename Func>
723 struct GetInfoHelper<Func, VECTOR_CLASS<char *> >
724 {
725     static cl_int
getcl::detail::GetInfoHelper726     get(Func f, cl_uint name, VECTOR_CLASS<char *>* param)
727     {
728       cl_uint err = f(name, param->size() * sizeof(char *), &(*param)[0], NULL);
729       if (err != CL_SUCCESS) {
730         return err;
731       }
732 
733       return CL_SUCCESS;
734     }
735 };
736 
737 // Specialized GetInfoHelper for STRING_CLASS params
738 template <typename Func>
739 struct GetInfoHelper<Func, STRING_CLASS>
740 {
getcl::detail::GetInfoHelper741     static cl_int get(Func f, cl_uint name, STRING_CLASS* param)
742     {
743         ::size_t required;
744         cl_int err = f(name, 0, NULL, &required);
745         if (err != CL_SUCCESS) {
746             return err;
747         }
748 
749         char* value = (char*) alloca(required);
750         err = f(name, required, value, NULL);
751         if (err != CL_SUCCESS) {
752             return err;
753         }
754 
755         *param = value;
756         return CL_SUCCESS;
757     }
758 };
759 
760 #define __GET_INFO_HELPER_WITH_RETAIN(CPP_TYPE) \
761 namespace detail { \
762 template <typename Func> \
763 struct GetInfoHelper<Func, CPP_TYPE> \
764 { \
765     static cl_int get(Func f, cl_uint name, CPP_TYPE* param) \
766     { \
767       cl_uint err = f(name, sizeof(CPP_TYPE), param, NULL); \
768       if (err != CL_SUCCESS) { \
769         return err; \
770       } \
771       \
772       return ReferenceHandler<CPP_TYPE::cl_type>::retain((*param)()); \
773     } \
774 }; \
775 }
776 
777 
778 #define __PARAM_NAME_INFO_1_0(F) \
779     F(cl_platform_info, CL_PLATFORM_PROFILE, STRING_CLASS) \
780     F(cl_platform_info, CL_PLATFORM_VERSION, STRING_CLASS) \
781     F(cl_platform_info, CL_PLATFORM_NAME, STRING_CLASS) \
782     F(cl_platform_info, CL_PLATFORM_VENDOR, STRING_CLASS) \
783     F(cl_platform_info, CL_PLATFORM_EXTENSIONS, STRING_CLASS) \
784     \
785     F(cl_device_info, CL_DEVICE_TYPE, cl_device_type) \
786     F(cl_device_info, CL_DEVICE_VENDOR_ID, cl_uint) \
787     F(cl_device_info, CL_DEVICE_MAX_COMPUTE_UNITS, cl_uint) \
788     F(cl_device_info, CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS, cl_uint) \
789     F(cl_device_info, CL_DEVICE_MAX_WORK_GROUP_SIZE, ::size_t) \
790     F(cl_device_info, CL_DEVICE_MAX_WORK_ITEM_SIZES, VECTOR_CLASS< ::size_t>) \
791     F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR, cl_uint) \
792     F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT, cl_uint) \
793     F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT, cl_uint) \
794     F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG, cl_uint) \
795     F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT, cl_uint) \
796     F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE, cl_uint) \
797     F(cl_device_info, CL_DEVICE_MAX_CLOCK_FREQUENCY, cl_uint) \
798     F(cl_device_info, CL_DEVICE_ADDRESS_BITS, cl_bitfield) \
799     F(cl_device_info, CL_DEVICE_MAX_READ_IMAGE_ARGS, cl_uint) \
800     F(cl_device_info, CL_DEVICE_MAX_WRITE_IMAGE_ARGS, cl_uint) \
801     F(cl_device_info, CL_DEVICE_MAX_MEM_ALLOC_SIZE, cl_ulong) \
802     F(cl_device_info, CL_DEVICE_IMAGE2D_MAX_WIDTH, ::size_t) \
803     F(cl_device_info, CL_DEVICE_IMAGE2D_MAX_HEIGHT, ::size_t) \
804     F(cl_device_info, CL_DEVICE_IMAGE3D_MAX_WIDTH, ::size_t) \
805     F(cl_device_info, CL_DEVICE_IMAGE3D_MAX_HEIGHT, ::size_t) \
806     F(cl_device_info, CL_DEVICE_IMAGE3D_MAX_DEPTH, ::size_t) \
807     F(cl_device_info, CL_DEVICE_IMAGE_SUPPORT, cl_uint) \
808     F(cl_device_info, CL_DEVICE_MAX_PARAMETER_SIZE, ::size_t) \
809     F(cl_device_info, CL_DEVICE_MAX_SAMPLERS, cl_uint) \
810     F(cl_device_info, CL_DEVICE_MEM_BASE_ADDR_ALIGN, cl_uint) \
811     F(cl_device_info, CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE, cl_uint) \
812     F(cl_device_info, CL_DEVICE_SINGLE_FP_CONFIG, cl_device_fp_config) \
813     F(cl_device_info, CL_DEVICE_GLOBAL_MEM_CACHE_TYPE, cl_device_mem_cache_type) \
814     F(cl_device_info, CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE, cl_uint)\
815     F(cl_device_info, CL_DEVICE_GLOBAL_MEM_CACHE_SIZE, cl_ulong) \
816     F(cl_device_info, CL_DEVICE_GLOBAL_MEM_SIZE, cl_ulong) \
817     F(cl_device_info, CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE, cl_ulong) \
818     F(cl_device_info, CL_DEVICE_MAX_CONSTANT_ARGS, cl_uint) \
819     F(cl_device_info, CL_DEVICE_LOCAL_MEM_TYPE, cl_device_local_mem_type) \
820     F(cl_device_info, CL_DEVICE_LOCAL_MEM_SIZE, cl_ulong) \
821     F(cl_device_info, CL_DEVICE_ERROR_CORRECTION_SUPPORT, cl_bool) \
822     F(cl_device_info, CL_DEVICE_PROFILING_TIMER_RESOLUTION, ::size_t) \
823     F(cl_device_info, CL_DEVICE_ENDIAN_LITTLE, cl_bool) \
824     F(cl_device_info, CL_DEVICE_AVAILABLE, cl_bool) \
825     F(cl_device_info, CL_DEVICE_COMPILER_AVAILABLE, cl_bool) \
826     F(cl_device_info, CL_DEVICE_EXECUTION_CAPABILITIES, cl_device_exec_capabilities) \
827     F(cl_device_info, CL_DEVICE_QUEUE_PROPERTIES, cl_command_queue_properties) \
828     F(cl_device_info, CL_DEVICE_PLATFORM, cl_platform_id) \
829     F(cl_device_info, CL_DEVICE_NAME, STRING_CLASS) \
830     F(cl_device_info, CL_DEVICE_VENDOR, STRING_CLASS) \
831     F(cl_device_info, CL_DRIVER_VERSION, STRING_CLASS) \
832     F(cl_device_info, CL_DEVICE_PROFILE, STRING_CLASS) \
833     F(cl_device_info, CL_DEVICE_VERSION, STRING_CLASS) \
834     F(cl_device_info, CL_DEVICE_EXTENSIONS, STRING_CLASS) \
835     \
836     F(cl_context_info, CL_CONTEXT_REFERENCE_COUNT, cl_uint) \
837     F(cl_context_info, CL_CONTEXT_DEVICES, VECTOR_CLASS<Device>) \
838     F(cl_context_info, CL_CONTEXT_PROPERTIES, VECTOR_CLASS<cl_context_properties>) \
839     \
840     F(cl_event_info, CL_EVENT_COMMAND_QUEUE, cl::CommandQueue) \
841     F(cl_event_info, CL_EVENT_COMMAND_TYPE, cl_command_type) \
842     F(cl_event_info, CL_EVENT_REFERENCE_COUNT, cl_uint) \
843     F(cl_event_info, CL_EVENT_COMMAND_EXECUTION_STATUS, cl_uint) \
844     \
845     F(cl_profiling_info, CL_PROFILING_COMMAND_QUEUED, cl_ulong) \
846     F(cl_profiling_info, CL_PROFILING_COMMAND_SUBMIT, cl_ulong) \
847     F(cl_profiling_info, CL_PROFILING_COMMAND_START, cl_ulong) \
848     F(cl_profiling_info, CL_PROFILING_COMMAND_END, cl_ulong) \
849     \
850     F(cl_mem_info, CL_MEM_TYPE, cl_mem_object_type) \
851     F(cl_mem_info, CL_MEM_FLAGS, cl_mem_flags) \
852     F(cl_mem_info, CL_MEM_SIZE, ::size_t) \
853     F(cl_mem_info, CL_MEM_HOST_PTR, void*) \
854     F(cl_mem_info, CL_MEM_MAP_COUNT, cl_uint) \
855     F(cl_mem_info, CL_MEM_REFERENCE_COUNT, cl_uint) \
856     F(cl_mem_info, CL_MEM_CONTEXT, cl::Context) \
857     \
858     F(cl_image_info, CL_IMAGE_FORMAT, cl_image_format) \
859     F(cl_image_info, CL_IMAGE_ELEMENT_SIZE, ::size_t) \
860     F(cl_image_info, CL_IMAGE_ROW_PITCH, ::size_t) \
861     F(cl_image_info, CL_IMAGE_SLICE_PITCH, ::size_t) \
862     F(cl_image_info, CL_IMAGE_WIDTH, ::size_t) \
863     F(cl_image_info, CL_IMAGE_HEIGHT, ::size_t) \
864     F(cl_image_info, CL_IMAGE_DEPTH, ::size_t) \
865     \
866     F(cl_sampler_info, CL_SAMPLER_REFERENCE_COUNT, cl_uint) \
867     F(cl_sampler_info, CL_SAMPLER_CONTEXT, cl::Context) \
868     F(cl_sampler_info, CL_SAMPLER_NORMALIZED_COORDS, cl_addressing_mode) \
869     F(cl_sampler_info, CL_SAMPLER_ADDRESSING_MODE, cl_filter_mode) \
870     F(cl_sampler_info, CL_SAMPLER_FILTER_MODE, cl_bool) \
871     \
872     F(cl_program_info, CL_PROGRAM_REFERENCE_COUNT, cl_uint) \
873     F(cl_program_info, CL_PROGRAM_CONTEXT, cl::Context) \
874     F(cl_program_info, CL_PROGRAM_NUM_DEVICES, cl_uint) \
875     F(cl_program_info, CL_PROGRAM_DEVICES, VECTOR_CLASS<cl_device_id>) \
876     F(cl_program_info, CL_PROGRAM_SOURCE, STRING_CLASS) \
877     F(cl_program_info, CL_PROGRAM_BINARY_SIZES, VECTOR_CLASS< ::size_t>) \
878     F(cl_program_info, CL_PROGRAM_BINARIES, VECTOR_CLASS<char *>) \
879     \
880     F(cl_program_build_info, CL_PROGRAM_BUILD_STATUS, cl_build_status) \
881     F(cl_program_build_info, CL_PROGRAM_BUILD_OPTIONS, STRING_CLASS) \
882     F(cl_program_build_info, CL_PROGRAM_BUILD_LOG, STRING_CLASS) \
883     \
884     F(cl_kernel_info, CL_KERNEL_FUNCTION_NAME, STRING_CLASS) \
885     F(cl_kernel_info, CL_KERNEL_NUM_ARGS, cl_uint) \
886     F(cl_kernel_info, CL_KERNEL_REFERENCE_COUNT, cl_uint) \
887     F(cl_kernel_info, CL_KERNEL_CONTEXT, cl::Context) \
888     F(cl_kernel_info, CL_KERNEL_PROGRAM, cl::Program) \
889     \
890     F(cl_kernel_work_group_info, CL_KERNEL_WORK_GROUP_SIZE, ::size_t) \
891     F(cl_kernel_work_group_info, CL_KERNEL_COMPILE_WORK_GROUP_SIZE, cl::size_t<3>) \
892     F(cl_kernel_work_group_info, CL_KERNEL_LOCAL_MEM_SIZE, cl_ulong) \
893     \
894     F(cl_command_queue_info, CL_QUEUE_CONTEXT, cl::Context) \
895     F(cl_command_queue_info, CL_QUEUE_DEVICE, cl::Device) \
896     F(cl_command_queue_info, CL_QUEUE_REFERENCE_COUNT, cl_uint) \
897     F(cl_command_queue_info, CL_QUEUE_PROPERTIES, cl_command_queue_properties)
898 
899 #if defined(CL_VERSION_1_1)
900 #define __PARAM_NAME_INFO_1_1(F) \
901     F(cl_context_info, CL_CONTEXT_NUM_DEVICES, cl_uint)\
902     F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF, cl_uint) \
903     F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR, cl_uint) \
904     F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT, cl_uint) \
905     F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_INT, cl_uint) \
906     F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG, cl_uint) \
907     F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT, cl_uint) \
908     F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE, cl_uint) \
909     F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF, cl_uint) \
910     F(cl_device_info, CL_DEVICE_DOUBLE_FP_CONFIG, cl_device_fp_config) \
911     F(cl_device_info, CL_DEVICE_HALF_FP_CONFIG, cl_device_fp_config) \
912     F(cl_device_info, CL_DEVICE_HOST_UNIFIED_MEMORY, cl_bool) \
913     \
914     F(cl_mem_info, CL_MEM_ASSOCIATED_MEMOBJECT, cl::Memory) \
915     F(cl_mem_info, CL_MEM_OFFSET, ::size_t) \
916     \
917     F(cl_kernel_work_group_info, CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE, ::size_t) \
918     F(cl_kernel_work_group_info, CL_KERNEL_PRIVATE_MEM_SIZE, cl_ulong) \
919     \
920     F(cl_event_info, CL_EVENT_CONTEXT, cl::Context)
921 #endif // CL_VERSION_1_1
922 
923 #if defined(USE_CL_DEVICE_FISSION)
924 #define __PARAM_NAME_DEVICE_FISSION(F) \
925     F(cl_device_info, CL_DEVICE_PARENT_DEVICE_EXT, cl_device_id) \
926 	F(cl_device_info, CL_DEVICE_PARTITION_TYPES_EXT, VECTOR_CLASS<cl_device_partition_property_ext>) \
927 	F(cl_device_info, CL_DEVICE_AFFINITY_DOMAINS_EXT, VECTOR_CLASS<cl_device_partition_property_ext>) \
928 	F(cl_device_info, CL_DEVICE_REFERENCE_COUNT_EXT , cl_uint) \
929 	F(cl_device_info, CL_DEVICE_PARTITION_STYLE_EXT, VECTOR_CLASS<cl_device_partition_property_ext>)
930 #endif // USE_CL_DEVICE_FISSION
931 
932 template <typename enum_type, cl_int Name>
933 struct param_traits {};
934 
935 #define __DECLARE_PARAM_TRAITS(token, param_name, T) \
936 struct token;                                        \
937 template<>                                           \
938 struct param_traits<detail:: token,param_name>       \
939 {                                                    \
940     enum { value = param_name };                     \
941     typedef T param_type;                            \
942 };
943 
944 __PARAM_NAME_INFO_1_0(__DECLARE_PARAM_TRAITS);
945 #if defined(CL_VERSION_1_1)
946 __PARAM_NAME_INFO_1_1(__DECLARE_PARAM_TRAITS);
947 #endif // CL_VERSION_1_1
948 
949 #if defined(USE_CL_DEVICE_FISSION)
950 __PARAM_NAME_DEVICE_FISSION(__DECLARE_PARAM_TRAITS);
951 #endif // USE_CL_DEVICE_FISSION
952 
953 #undef __DECLARE_PARAM_TRAITS
954 
955 // Convenience functions
956 
957 template <typename Func, typename T>
958 inline cl_int
getInfo(Func f,cl_uint name,T * param)959 getInfo(Func f, cl_uint name, T* param)
960 {
961     return GetInfoHelper<Func, T>::get(f, name, param);
962 }
963 
964 template <typename Func, typename Arg0>
965 struct GetInfoFunctor0
966 {
967     Func f_; const Arg0& arg0_;
operator ()cl::detail::GetInfoFunctor0968     cl_int operator ()(
969         cl_uint param, ::size_t size, void* value, ::size_t* size_ret)
970     { return f_(arg0_, param, size, value, size_ret); }
971 };
972 
973 template <typename Func, typename Arg0, typename Arg1>
974 struct GetInfoFunctor1
975 {
976     Func f_; const Arg0& arg0_; const Arg1& arg1_;
operator ()cl::detail::GetInfoFunctor1977     cl_int operator ()(
978         cl_uint param, ::size_t size, void* value, ::size_t* size_ret)
979     { return f_(arg0_, arg1_, param, size, value, size_ret); }
980 };
981 
982 template <typename Func, typename Arg0, typename T>
983 inline cl_int
getInfo(Func f,const Arg0 & arg0,cl_uint name,T * param)984 getInfo(Func f, const Arg0& arg0, cl_uint name, T* param)
985 {
986     GetInfoFunctor0<Func, Arg0> f0 = { f, arg0 };
987     return GetInfoHelper<GetInfoFunctor0<Func, Arg0>, T>
988         ::get(f0, name, param);
989 }
990 
991 template <typename Func, typename Arg0, typename Arg1, typename T>
992 inline cl_int
getInfo(Func f,const Arg0 & arg0,const Arg1 & arg1,cl_uint name,T * param)993 getInfo(Func f, const Arg0& arg0, const Arg1& arg1, cl_uint name, T* param)
994 {
995     GetInfoFunctor1<Func, Arg0, Arg1> f0 = { f, arg0, arg1 };
996     return GetInfoHelper<GetInfoFunctor1<Func, Arg0, Arg1>, T>
997         ::get(f0, name, param);
998 }
999 
1000 template<typename T>
1001 struct ReferenceHandler
1002 { };
1003 
1004 template <>
1005 struct ReferenceHandler<cl_device_id>
1006 {
1007     // cl_device_id does not have retain().
retaincl::detail::ReferenceHandler1008     static cl_int retain(cl_device_id)
1009     { return CL_INVALID_DEVICE; }
1010     // cl_device_id does not have release().
releasecl::detail::ReferenceHandler1011     static cl_int release(cl_device_id)
1012     { return CL_INVALID_DEVICE; }
1013 };
1014 
1015 template <>
1016 struct ReferenceHandler<cl_platform_id>
1017 {
1018     // cl_platform_id does not have retain().
retaincl::detail::ReferenceHandler1019     static cl_int retain(cl_platform_id)
1020     { return CL_INVALID_PLATFORM; }
1021     // cl_platform_id does not have release().
releasecl::detail::ReferenceHandler1022     static cl_int release(cl_platform_id)
1023     { return CL_INVALID_PLATFORM; }
1024 };
1025 
1026 template <>
1027 struct ReferenceHandler<cl_context>
1028 {
retaincl::detail::ReferenceHandler1029     static cl_int retain(cl_context context)
1030     { return ::clRetainContext(context); }
releasecl::detail::ReferenceHandler1031     static cl_int release(cl_context context)
1032     { return ::clReleaseContext(context); }
1033 };
1034 
1035 template <>
1036 struct ReferenceHandler<cl_command_queue>
1037 {
retaincl::detail::ReferenceHandler1038     static cl_int retain(cl_command_queue queue)
1039     { return ::clRetainCommandQueue(queue); }
releasecl::detail::ReferenceHandler1040     static cl_int release(cl_command_queue queue)
1041     { return ::clReleaseCommandQueue(queue); }
1042 };
1043 
1044 template <>
1045 struct ReferenceHandler<cl_mem>
1046 {
retaincl::detail::ReferenceHandler1047     static cl_int retain(cl_mem memory)
1048     { return ::clRetainMemObject(memory); }
releasecl::detail::ReferenceHandler1049     static cl_int release(cl_mem memory)
1050     { return ::clReleaseMemObject(memory); }
1051 };
1052 
1053 template <>
1054 struct ReferenceHandler<cl_sampler>
1055 {
retaincl::detail::ReferenceHandler1056     static cl_int retain(cl_sampler sampler)
1057     { return ::clRetainSampler(sampler); }
releasecl::detail::ReferenceHandler1058     static cl_int release(cl_sampler sampler)
1059     { return ::clReleaseSampler(sampler); }
1060 };
1061 
1062 template <>
1063 struct ReferenceHandler<cl_program>
1064 {
retaincl::detail::ReferenceHandler1065     static cl_int retain(cl_program program)
1066     { return ::clRetainProgram(program); }
releasecl::detail::ReferenceHandler1067     static cl_int release(cl_program program)
1068     { return ::clReleaseProgram(program); }
1069 };
1070 
1071 template <>
1072 struct ReferenceHandler<cl_kernel>
1073 {
retaincl::detail::ReferenceHandler1074     static cl_int retain(cl_kernel kernel)
1075     { return ::clRetainKernel(kernel); }
releasecl::detail::ReferenceHandler1076     static cl_int release(cl_kernel kernel)
1077     { return ::clReleaseKernel(kernel); }
1078 };
1079 
1080 template <>
1081 struct ReferenceHandler<cl_event>
1082 {
retaincl::detail::ReferenceHandler1083     static cl_int retain(cl_event event)
1084     { return ::clRetainEvent(event); }
releasecl::detail::ReferenceHandler1085     static cl_int release(cl_event event)
1086     { return ::clReleaseEvent(event); }
1087 };
1088 
1089 template <typename T>
1090 class Wrapper
1091 {
1092 public:
1093     typedef T cl_type;
1094 
1095 protected:
1096     cl_type object_;
1097 
1098 public:
Wrapper()1099     Wrapper() : object_(NULL) { }
1100 
~Wrapper()1101     ~Wrapper()
1102     {
1103         if (object_ != NULL) { release(); }
1104     }
1105 
Wrapper(const Wrapper<cl_type> & rhs)1106     Wrapper(const Wrapper<cl_type>& rhs)
1107     {
1108         object_ = rhs.object_;
1109         if (object_ != NULL) { retain(); }
1110     }
1111 
operator =(const Wrapper<cl_type> & rhs)1112     Wrapper<cl_type>& operator = (const Wrapper<cl_type>& rhs)
1113     {
1114         if (object_ != NULL) { release(); }
1115         object_ = rhs.object_;
1116         if (object_ != NULL) { retain(); }
1117         return *this;
1118     }
1119 
operator ()() const1120     cl_type operator ()() const { return object_; }
1121 
operator ()()1122     cl_type& operator ()() { return object_; }
1123 
1124 protected:
1125 
retain() const1126     cl_int retain() const
1127     {
1128         return ReferenceHandler<cl_type>::retain(object_);
1129     }
1130 
release() const1131     cl_int release() const
1132     {
1133         return ReferenceHandler<cl_type>::release(object_);
1134     }
1135 };
1136 
1137 #if defined(__CL_ENABLE_EXCEPTIONS)
errHandler(cl_int err,const char * errStr=NULL)1138 static inline cl_int errHandler (
1139     cl_int err,
1140     const char * errStr = NULL) throw(Error)
1141 {
1142     if (err != CL_SUCCESS) {
1143         throw Error(err, errStr);
1144     }
1145     return err;
1146 }
1147 #else
errHandler(cl_int err,const char * errStr=NULL)1148 static inline cl_int errHandler (cl_int err, const char * errStr = NULL)
1149 {
1150     return err;
1151 }
1152 #endif // __CL_ENABLE_EXCEPTIONS
1153 
1154 } // namespace detail
1155 //! \endcond
1156 
1157 /*! \stuct ImageFormat
1158  * \brief ImageFormat interface fro cl_image_format.
1159  */
1160 struct ImageFormat : public cl_image_format
1161 {
ImageFormatcl::ImageFormat1162     ImageFormat(){}
1163 
ImageFormatcl::ImageFormat1164     ImageFormat(cl_channel_order order, cl_channel_type type)
1165     {
1166         image_channel_order = order;
1167         image_channel_data_type = type;
1168     }
1169 
operator =cl::ImageFormat1170     ImageFormat& operator = (const ImageFormat& rhs)
1171     {
1172         if (this != &rhs) {
1173             this->image_channel_data_type = rhs.image_channel_data_type;
1174             this->image_channel_order     = rhs.image_channel_order;
1175         }
1176         return *this;
1177     }
1178 };
1179 
1180 /*! \class Device
1181  * \brief Device interface for cl_device_id.
1182  */
1183 class Device : public detail::Wrapper<cl_device_id>
1184 {
1185 public:
Device(cl_device_id device)1186     Device(cl_device_id device) { object_ = device; }
1187 
Device()1188     Device() : detail::Wrapper<cl_type>() { }
1189 
Device(const Device & device)1190     Device(const Device& device) : detail::Wrapper<cl_type>(device) { }
1191 
operator =(const Device & rhs)1192     Device& operator = (const Device& rhs)
1193     {
1194         if (this != &rhs) {
1195             detail::Wrapper<cl_type>::operator=(rhs);
1196         }
1197         return *this;
1198     }
1199 
1200     template <typename T>
getInfo(cl_device_info name,T * param) const1201     cl_int getInfo(cl_device_info name, T* param) const
1202     {
1203         return detail::errHandler(
1204             detail::getInfo(&::clGetDeviceInfo, object_, name, param),
1205             __GET_DEVICE_INFO_ERR);
1206     }
1207 
1208     template <cl_int name> typename
1209     detail::param_traits<detail::cl_device_info, name>::param_type
getInfo(cl_int * err=NULL) const1210     getInfo(cl_int* err = NULL) const
1211     {
1212         typename detail::param_traits<
1213             detail::cl_device_info, name>::param_type param;
1214         cl_int result = getInfo(name, &param);
1215         if (err != NULL) {
1216             *err = result;
1217         }
1218         return param;
1219     }
1220 
1221 #if defined(USE_CL_DEVICE_FISSION)
createSubDevices(const cl_device_partition_property_ext * properties,VECTOR_CLASS<Device> * devices)1222 	cl_int createSubDevices(
1223 		const cl_device_partition_property_ext * properties,
1224 		VECTOR_CLASS<Device>* devices)
1225 	{
1226 		typedef CL_API_ENTRY cl_int
1227 			( CL_API_CALL * PFN_clCreateSubDevicesEXT)(
1228 				cl_device_id /*in_device*/,
1229                 const cl_device_partition_property_ext * /* properties */,
1230                 cl_uint /*num_entries*/,
1231                 cl_device_id * /*out_devices*/,
1232                 cl_uint * /*num_devices*/ ) CL_EXT_SUFFIX__VERSION_1_1;
1233 
1234 		static PFN_clCreateSubDevicesEXT pfn_clCreateSubDevicesEXT = NULL;
1235 		__INIT_CL_EXT_FCN_PTR(clCreateSubDevicesEXT);
1236 
1237 		cl_uint n = 0;
1238         cl_int err = pfn_clCreateSubDevicesEXT(object_, properties, 0, NULL, &n);
1239         if (err != CL_SUCCESS) {
1240             return detail::errHandler(err, __CREATE_SUB_DEVICES);
1241         }
1242 
1243         cl_device_id* ids = (cl_device_id*) alloca(n * sizeof(cl_device_id));
1244         err = pfn_clCreateSubDevicesEXT(object_, properties, n, ids, NULL);
1245         if (err != CL_SUCCESS) {
1246             return detail::errHandler(err, __CREATE_SUB_DEVICES);
1247         }
1248 
1249         devices->assign(&ids[0], &ids[n]);
1250         return CL_SUCCESS;
1251  	}
1252 #endif
1253 };
1254 
1255 /*! \class Platform
1256  *  \brief Platform interface.
1257  */
1258 class Platform : public detail::Wrapper<cl_platform_id>
1259 {
1260 public:
1261     static const Platform null();
1262 
Platform(cl_platform_id platform)1263     Platform(cl_platform_id platform) { object_ = platform; }
1264 
Platform()1265     Platform() : detail::Wrapper<cl_type>()  { }
1266 
Platform(const Platform & platform)1267     Platform(const Platform& platform) : detail::Wrapper<cl_type>(platform) { }
1268 
operator =(const Platform & rhs)1269     Platform& operator = (const Platform& rhs)
1270     {
1271         if (this != &rhs) {
1272             detail::Wrapper<cl_type>::operator=(rhs);
1273         }
1274         return *this;
1275     }
1276 
getInfo(cl_platform_info name,STRING_CLASS * param) const1277     cl_int getInfo(cl_platform_info name, STRING_CLASS* param) const
1278     {
1279         return detail::errHandler(
1280             detail::getInfo(&::clGetPlatformInfo, object_, name, param),
1281             __GET_PLATFORM_INFO_ERR);
1282     }
1283 
1284     template <cl_int name> typename
1285     detail::param_traits<detail::cl_platform_info, name>::param_type
getInfo(cl_int * err=NULL) const1286     getInfo(cl_int* err = NULL) const
1287     {
1288         typename detail::param_traits<
1289             detail::cl_platform_info, name>::param_type param;
1290         cl_int result = getInfo(name, &param);
1291         if (err != NULL) {
1292             *err = result;
1293         }
1294         return param;
1295     }
1296 
getDevices(cl_device_type type,VECTOR_CLASS<Device> * devices) const1297     cl_int getDevices(
1298         cl_device_type type,
1299         VECTOR_CLASS<Device>* devices) const
1300     {
1301         cl_uint n = 0;
1302         cl_int err = ::clGetDeviceIDs(object_, type, 0, NULL, &n);
1303         if (err != CL_SUCCESS) {
1304             return detail::errHandler(err, __GET_DEVICE_IDS_ERR);
1305         }
1306 
1307         cl_device_id* ids = (cl_device_id*) alloca(n * sizeof(cl_device_id));
1308         err = ::clGetDeviceIDs(object_, type, n, ids, NULL);
1309         if (err != CL_SUCCESS) {
1310             return detail::errHandler(err, __GET_DEVICE_IDS_ERR);
1311         }
1312 
1313         devices->assign(&ids[0], &ids[n]);
1314         return CL_SUCCESS;
1315     }
1316 
1317 #if defined(USE_DX_INTEROP)
1318    /*! \brief Get the list of available D3D10 devices.
1319      *
1320      *  \param d3d_device_source.
1321      *
1322      *  \param d3d_object.
1323      *
1324      *  \param d3d_device_set.
1325      *
1326      *  \param devices returns a vector of OpenCL D3D10 devices found. The cl::Device
1327      *  values returned in devices can be used to identify a specific OpenCL
1328      *  device. If \a devices argument is NULL, this argument is ignored.
1329      *
1330      *  \return One of the following values:
1331      *    - CL_SUCCESS if the function is executed successfully.
1332      *
1333      *  The application can query specific capabilities of the OpenCL device(s)
1334      *  returned by cl::getDevices. This can be used by the application to
1335      *  determine which device(s) to use.
1336      *
1337      * \note In the case that exceptions are enabled and a return value
1338      * other than CL_SUCCESS is generated, then cl::Error exception is
1339      * generated.
1340      */
getDevices(cl_d3d10_device_source_khr d3d_device_source,void * d3d_object,cl_d3d10_device_set_khr d3d_device_set,VECTOR_CLASS<Device> * devices) const1341     cl_int getDevices(
1342         cl_d3d10_device_source_khr d3d_device_source,
1343         void *                     d3d_object,
1344         cl_d3d10_device_set_khr    d3d_device_set,
1345         VECTOR_CLASS<Device>* devices) const
1346     {
1347         typedef CL_API_ENTRY cl_int (CL_API_CALL *PFN_clGetDeviceIDsFromD3D10KHR)(
1348             cl_platform_id platform,
1349             cl_d3d10_device_source_khr d3d_device_source,
1350             void * d3d_object,
1351             cl_d3d10_device_set_khr d3d_device_set,
1352             cl_uint num_entries,
1353             cl_device_id * devices,
1354             cl_uint* num_devices);
1355 
1356         static PFN_clGetDeviceIDsFromD3D10KHR pfn_clGetDeviceIDsFromD3D10KHR = NULL;
1357         __INIT_CL_EXT_FCN_PTR(clGetDeviceIDsFromD3D10KHR);
1358 
1359         cl_uint n = 0;
1360         cl_int err = pfn_clGetDeviceIDsFromD3D10KHR(
1361             object_,
1362             d3d_device_source,
1363             d3d_object,
1364             d3d_device_set,
1365             0,
1366             NULL,
1367             &n);
1368         if (err != CL_SUCCESS) {
1369             return detail::errHandler(err, __GET_DEVICE_IDS_ERR);
1370         }
1371 
1372         cl_device_id* ids = (cl_device_id*) alloca(n * sizeof(cl_device_id));
1373         err = pfn_clGetDeviceIDsFromD3D10KHR(
1374             object_,
1375             d3d_device_source,
1376             d3d_object,
1377             d3d_device_set,
1378             n,
1379             ids,
1380             NULL);
1381         if (err != CL_SUCCESS) {
1382             return detail::errHandler(err, __GET_DEVICE_IDS_ERR);
1383         }
1384 
1385         devices->assign(&ids[0], &ids[n]);
1386         return CL_SUCCESS;
1387     }
1388 #endif
1389 
get(VECTOR_CLASS<Platform> * platforms)1390     static cl_int get(
1391         VECTOR_CLASS<Platform>* platforms)
1392     {
1393         cl_uint n = 0;
1394         cl_int err = ::clGetPlatformIDs(0, NULL, &n);
1395         if (err != CL_SUCCESS) {
1396             return detail::errHandler(err, __GET_PLATFORM_IDS_ERR);
1397         }
1398 
1399         cl_platform_id* ids = (cl_platform_id*) alloca(
1400             n * sizeof(cl_platform_id));
1401         err = ::clGetPlatformIDs(n, ids, NULL);
1402         if (err != CL_SUCCESS) {
1403             return detail::errHandler(err, __GET_PLATFORM_IDS_ERR);
1404         }
1405 
1406         platforms->assign(&ids[0], &ids[n]);
1407         return CL_SUCCESS;
1408     }
1409 };
1410 
1411 static inline cl_int
UnloadCompiler()1412 UnloadCompiler()
1413 {
1414     return ::clUnloadCompiler();
1415 }
1416 
1417 class Context : public detail::Wrapper<cl_context>
1418 {
1419 public:
Context(const VECTOR_CLASS<Device> & devices,cl_context_properties * properties=NULL,void (CL_CALLBACK * notifyFptr)(const char *,const void *,::size_t,void *)=NULL,void * data=NULL,cl_int * err=NULL)1420     Context(
1421         const VECTOR_CLASS<Device>& devices,
1422         cl_context_properties* properties = NULL,
1423         void (CL_CALLBACK * notifyFptr)(
1424             const char *,
1425             const void *,
1426             ::size_t,
1427             void *) = NULL,
1428         void* data = NULL,
1429         cl_int* err = NULL)
1430     {
1431         cl_int error;
1432         object_ = ::clCreateContext(
1433             properties, (cl_uint) devices.size(),
1434             (cl_device_id*) &devices.front(),
1435             notifyFptr, data, &error);
1436 
1437         detail::errHandler(error, __CREATE_CONTEXT_FROM_TYPE_ERR);
1438         if (err != NULL) {
1439             *err = error;
1440         }
1441     }
1442 
Context(cl_device_type type,cl_context_properties * properties=NULL,void (CL_CALLBACK * notifyFptr)(const char *,const void *,::size_t,void *)=NULL,void * data=NULL,cl_int * err=NULL)1443     Context(
1444         cl_device_type type,
1445         cl_context_properties* properties = NULL,
1446         void (CL_CALLBACK * notifyFptr)(
1447             const char *,
1448             const void *,
1449             ::size_t,
1450             void *) = NULL,
1451         void* data = NULL,
1452         cl_int* err = NULL)
1453     {
1454         cl_int error;
1455         object_ = ::clCreateContextFromType(
1456             properties, type, notifyFptr, data, &error);
1457 
1458         detail::errHandler(error, __CREATE_CONTEXT_FROM_TYPE_ERR);
1459         if (err != NULL) {
1460             *err = error;
1461         }
1462     }
1463 
Context()1464     Context() : detail::Wrapper<cl_type>() { }
1465 
Context(const Context & context)1466     Context(const Context& context) : detail::Wrapper<cl_type>(context) { }
1467 
operator =(const Context & rhs)1468     Context& operator = (const Context& rhs)
1469     {
1470         if (this != &rhs) {
1471             detail::Wrapper<cl_type>::operator=(rhs);
1472         }
1473         return *this;
1474     }
1475 
1476     template <typename T>
getInfo(cl_context_info name,T * param) const1477     cl_int getInfo(cl_context_info name, T* param) const
1478     {
1479         return detail::errHandler(
1480             detail::getInfo(&::clGetContextInfo, object_, name, param),
1481             __GET_CONTEXT_INFO_ERR);
1482     }
1483 
1484     template <cl_int name> typename
1485     detail::param_traits<detail::cl_context_info, name>::param_type
getInfo(cl_int * err=NULL) const1486     getInfo(cl_int* err = NULL) const
1487     {
1488         typename detail::param_traits<
1489             detail::cl_context_info, name>::param_type param;
1490         cl_int result = getInfo(name, &param);
1491         if (err != NULL) {
1492             *err = result;
1493         }
1494         return param;
1495     }
1496 
getSupportedImageFormats(cl_mem_flags flags,cl_mem_object_type type,VECTOR_CLASS<ImageFormat> * formats) const1497     cl_int getSupportedImageFormats(
1498         cl_mem_flags flags,
1499         cl_mem_object_type type,
1500         VECTOR_CLASS<ImageFormat>* formats) const
1501     {
1502         cl_uint numEntries;
1503         cl_int err = ::clGetSupportedImageFormats(
1504            object_,
1505            flags,
1506            type,
1507            0,
1508            NULL,
1509            &numEntries);
1510         if (err != CL_SUCCESS) {
1511             return detail::errHandler(err, __GET_SUPPORTED_IMAGE_FORMATS_ERR);
1512         }
1513 
1514         ImageFormat* value = (ImageFormat*)
1515             alloca(numEntries * sizeof(ImageFormat));
1516         err = ::clGetSupportedImageFormats(
1517             object_,
1518             flags,
1519             type,
1520             numEntries,
1521             (cl_image_format*) value,
1522             NULL);
1523         if (err != CL_SUCCESS) {
1524             return detail::errHandler(err, __GET_SUPPORTED_IMAGE_FORMATS_ERR);
1525         }
1526 
1527         formats->assign(&value[0], &value[numEntries]);
1528         return CL_SUCCESS;
1529     }
1530 };
1531 
1532 __GET_INFO_HELPER_WITH_RETAIN(cl::Context)
1533 
1534 /*! \class Event
1535  * \brief Event interface for cl_event.
1536  */
1537 class Event : public detail::Wrapper<cl_event>
1538 {
1539 public:
Event()1540     Event() : detail::Wrapper<cl_type>() { }
1541 
Event(const Event & event)1542     Event(const Event& event) : detail::Wrapper<cl_type>(event) { }
1543 
operator =(const Event & rhs)1544     Event& operator = (const Event& rhs)
1545     {
1546         if (this != &rhs) {
1547             detail::Wrapper<cl_type>::operator=(rhs);
1548         }
1549         return *this;
1550     }
1551 
1552     template <typename T>
getInfo(cl_event_info name,T * param) const1553     cl_int getInfo(cl_event_info name, T* param) const
1554     {
1555         return detail::errHandler(
1556             detail::getInfo(&::clGetEventInfo, object_, name, param),
1557             __GET_EVENT_INFO_ERR);
1558     }
1559 
1560     template <cl_int name> typename
1561     detail::param_traits<detail::cl_event_info, name>::param_type
getInfo(cl_int * err=NULL) const1562     getInfo(cl_int* err = NULL) const
1563     {
1564         typename detail::param_traits<
1565             detail::cl_event_info, name>::param_type param;
1566         cl_int result = getInfo(name, &param);
1567         if (err != NULL) {
1568             *err = result;
1569         }
1570         return param;
1571     }
1572 
1573     template <typename T>
getProfilingInfo(cl_profiling_info name,T * param) const1574     cl_int getProfilingInfo(cl_profiling_info name, T* param) const
1575     {
1576         return detail::errHandler(detail::getInfo(
1577             &::clGetEventProfilingInfo, object_, name, param),
1578             __GET_EVENT_PROFILE_INFO_ERR);
1579     }
1580 
1581     template <cl_int name> typename
1582     detail::param_traits<detail::cl_profiling_info, name>::param_type
getProfilingInfo(cl_int * err=NULL) const1583     getProfilingInfo(cl_int* err = NULL) const
1584     {
1585         typename detail::param_traits<
1586             detail::cl_profiling_info, name>::param_type param;
1587         cl_int result = getProfilingInfo(name, &param);
1588         if (err != NULL) {
1589             *err = result;
1590         }
1591         return param;
1592     }
1593 
wait() const1594     cl_int wait() const
1595     {
1596         return detail::errHandler(
1597             ::clWaitForEvents(1, &object_),
1598             __WAIT_FOR_EVENTS_ERR);
1599     }
1600 
1601 #if defined(CL_VERSION_1_1)
setCallback(cl_int type,void (CL_CALLBACK * pfn_notify)(cl_event,cl_int,void *),void * user_data=NULL)1602     cl_int setCallback(
1603         cl_int type,
1604         void (CL_CALLBACK * pfn_notify)(cl_event, cl_int, void *),
1605         void * user_data = NULL)
1606     {
1607         return detail::errHandler(
1608             ::clSetEventCallback(
1609                 object_,
1610                 type,
1611                 pfn_notify,
1612                 user_data),
1613             __SET_EVENT_CALLBACK_ERR);
1614     }
1615 #endif
1616 
1617     static cl_int
waitForEvents(const VECTOR_CLASS<Event> & events)1618     waitForEvents(const VECTOR_CLASS<Event>& events)
1619     {
1620         return detail::errHandler(
1621             ::clWaitForEvents(
1622                 (cl_uint) events.size(), (cl_event*)&events.front()),
1623             __WAIT_FOR_EVENTS_ERR);
1624     }
1625 };
1626 
1627 __GET_INFO_HELPER_WITH_RETAIN(cl::Event)
1628 
1629 #if defined(CL_VERSION_1_1)
1630 /*! \class UserEvent
1631  * \brief User event interface for cl_event.
1632  */
1633 class UserEvent : public Event
1634 {
1635 public:
UserEvent(const Context & context,cl_int * err=NULL)1636     UserEvent(
1637         const Context& context,
1638         cl_int * err = NULL)
1639     {
1640         cl_int error;
1641         object_ = ::clCreateUserEvent(
1642             context(),
1643             &error);
1644 
1645         detail::errHandler(error, __CREATE_USER_EVENT_ERR);
1646         if (err != NULL) {
1647             *err = error;
1648         }
1649     }
1650 
UserEvent()1651     UserEvent() : Event() { }
1652 
UserEvent(const UserEvent & event)1653     UserEvent(const UserEvent& event) : Event(event) { }
1654 
operator =(const UserEvent & rhs)1655     UserEvent& operator = (const UserEvent& rhs)
1656     {
1657         if (this != &rhs) {
1658             Event::operator=(rhs);
1659         }
1660         return *this;
1661     }
1662 
setStatus(cl_int status)1663     cl_int setStatus(cl_int status)
1664     {
1665         return detail::errHandler(
1666             ::clSetUserEventStatus(object_,status),
1667             __SET_USER_EVENT_STATUS_ERR);
1668     }
1669 };
1670 #endif
1671 
1672 inline static cl_int
WaitForEvents(const VECTOR_CLASS<Event> & events)1673 WaitForEvents(const VECTOR_CLASS<Event>& events)
1674 {
1675     return detail::errHandler(
1676         ::clWaitForEvents(
1677             (cl_uint) events.size(), (cl_event*)&events.front()),
1678         __WAIT_FOR_EVENTS_ERR);
1679 }
1680 
1681 /*! \class Memory
1682  * \brief Memory interface for cl_mem.
1683  */
1684 class Memory : public detail::Wrapper<cl_mem>
1685 {
1686 public:
Memory()1687     Memory() : detail::Wrapper<cl_type>() { }
1688 
Memory(const Memory & memory)1689     Memory(const Memory& memory) : detail::Wrapper<cl_type>(memory) { }
1690 
operator =(const Memory & rhs)1691     Memory& operator = (const Memory& rhs)
1692     {
1693         if (this != &rhs) {
1694             detail::Wrapper<cl_type>::operator=(rhs);
1695         }
1696         return *this;
1697     }
1698 
1699     template <typename T>
getInfo(cl_mem_info name,T * param) const1700     cl_int getInfo(cl_mem_info name, T* param) const
1701     {
1702         return detail::errHandler(
1703             detail::getInfo(&::clGetMemObjectInfo, object_, name, param),
1704             __GET_MEM_OBJECT_INFO_ERR);
1705     }
1706 
1707     template <cl_int name> typename
1708     detail::param_traits<detail::cl_mem_info, name>::param_type
getInfo(cl_int * err=NULL) const1709     getInfo(cl_int* err = NULL) const
1710     {
1711         typename detail::param_traits<
1712             detail::cl_mem_info, name>::param_type param;
1713         cl_int result = getInfo(name, &param);
1714         if (err != NULL) {
1715             *err = result;
1716         }
1717         return param;
1718     }
1719 
1720 #if defined(CL_VERSION_1_1)
setDestructorCallback(void (CL_CALLBACK * pfn_notify)(cl_mem,void *),void * user_data=NULL)1721     cl_int setDestructorCallback(
1722         void (CL_CALLBACK * pfn_notify)(cl_mem, void *),
1723         void * user_data = NULL)
1724     {
1725         return detail::errHandler(
1726             ::clSetMemObjectDestructorCallback(
1727                 object_,
1728                 pfn_notify,
1729                 user_data),
1730             __SET_MEM_OBJECT_DESTRUCTOR_CALLBACK_ERR);
1731     }
1732 #endif
1733 
1734 };
1735 
1736 __GET_INFO_HELPER_WITH_RETAIN(cl::Memory)
1737 
1738 /*! \class Buffer
1739  * \brief Memory buffer interface.
1740  */
1741 class Buffer : public Memory
1742 {
1743 public:
Buffer(const Context & context,cl_mem_flags flags,::size_t size,void * host_ptr=NULL,cl_int * err=NULL)1744     Buffer(
1745         const Context& context,
1746         cl_mem_flags flags,
1747         ::size_t size,
1748         void* host_ptr = NULL,
1749         cl_int* err = NULL)
1750     {
1751         cl_int error;
1752         object_ = ::clCreateBuffer(context(), flags, size, host_ptr, &error);
1753 
1754         detail::errHandler(error, __CREATE_BUFFER_ERR);
1755         if (err != NULL) {
1756             *err = error;
1757         }
1758     }
1759 
Buffer()1760     Buffer() : Memory() { }
1761 
Buffer(const Buffer & buffer)1762     Buffer(const Buffer& buffer) : Memory(buffer) { }
1763 
operator =(const Buffer & rhs)1764     Buffer& operator = (const Buffer& rhs)
1765     {
1766         if (this != &rhs) {
1767             Memory::operator=(rhs);
1768         }
1769         return *this;
1770     }
1771 
1772 #if defined(CL_VERSION_1_1)
createSubBuffer(cl_mem_flags flags,cl_buffer_create_type buffer_create_type,const void * buffer_create_info,cl_int * err=NULL)1773     Buffer createSubBuffer(
1774         cl_mem_flags flags,
1775         cl_buffer_create_type buffer_create_type,
1776         const void * buffer_create_info,
1777         cl_int * err = NULL)
1778     {
1779         Buffer result;
1780         cl_int error;
1781         result.object_ = ::clCreateSubBuffer(
1782             object_,
1783             flags,
1784             buffer_create_type,
1785             buffer_create_info,
1786             &error);
1787 
1788         detail::errHandler(error, __CREATE_SUBBUFFER_ERR);
1789         if (err != NULL) {
1790             *err = error;
1791         }
1792 
1793         return result;
1794 	}
1795 #endif
1796 };
1797 
1798 #if defined (USE_DX_INTEROP)
1799 class BufferD3D10 : public Buffer
1800 {
1801 public:
1802     typedef CL_API_ENTRY cl_mem (CL_API_CALL *PFN_clCreateFromD3D10BufferKHR)(
1803     cl_context context, cl_mem_flags flags, ID3D10Buffer*  buffer,
1804     cl_int* errcode_ret);
1805 
BufferD3D10(const Context & context,cl_mem_flags flags,ID3D10Buffer * bufobj,cl_int * err=NULL)1806     BufferD3D10(
1807         const Context& context,
1808         cl_mem_flags flags,
1809         ID3D10Buffer* bufobj,
1810         cl_int * err = NULL)
1811     {
1812         static PFN_clCreateFromD3D10BufferKHR pfn_clCreateFromD3D10BufferKHR = NULL;
1813         __INIT_CL_EXT_FCN_PTR(clCreateFromD3D10BufferKHR);
1814 
1815         cl_int error;
1816         object_ = pfn_clCreateFromD3D10BufferKHR(
1817             context(),
1818             flags,
1819             bufobj,
1820             &error);
1821 
1822         detail::errHandler(error, __CREATE_GL_BUFFER_ERR);
1823         if (err != NULL) {
1824             *err = error;
1825         }
1826     }
1827 
BufferD3D10()1828     BufferD3D10() : Buffer() { }
1829 
BufferD3D10(const BufferD3D10 & buffer)1830     BufferD3D10(const BufferD3D10& buffer) : Buffer(buffer) { }
1831 
operator =(const BufferD3D10 & rhs)1832     BufferD3D10& operator = (const BufferD3D10& rhs)
1833     {
1834         if (this != &rhs) {
1835             Buffer::operator=(rhs);
1836         }
1837         return *this;
1838     }
1839 };
1840 #endif
1841 
1842 /*! \class BufferGL
1843  * \brief Memory buffer interface for GL interop.
1844  */
1845 class BufferGL : public Buffer
1846 {
1847 public:
BufferGL(const Context & context,cl_mem_flags flags,GLuint bufobj,cl_int * err=NULL)1848     BufferGL(
1849         const Context& context,
1850         cl_mem_flags flags,
1851         GLuint bufobj,
1852         cl_int * err = NULL)
1853     {
1854         cl_int error;
1855         object_ = ::clCreateFromGLBuffer(
1856             context(),
1857             flags,
1858             bufobj,
1859             &error);
1860 
1861         detail::errHandler(error, __CREATE_GL_BUFFER_ERR);
1862         if (err != NULL) {
1863             *err = error;
1864         }
1865     }
1866 
BufferGL()1867     BufferGL() : Buffer() { }
1868 
BufferGL(const BufferGL & buffer)1869     BufferGL(const BufferGL& buffer) : Buffer(buffer) { }
1870 
operator =(const BufferGL & rhs)1871     BufferGL& operator = (const BufferGL& rhs)
1872     {
1873         if (this != &rhs) {
1874             Buffer::operator=(rhs);
1875         }
1876         return *this;
1877     }
1878 
getObjectInfo(cl_gl_object_type * type,GLuint * gl_object_name)1879     cl_int getObjectInfo(
1880         cl_gl_object_type *type,
1881         GLuint * gl_object_name)
1882     {
1883         return detail::errHandler(
1884             ::clGetGLObjectInfo(object_,type,gl_object_name),
1885             __GET_GL_OBJECT_INFO_ERR);
1886     }
1887 };
1888 
1889 /*! \class BufferRenderGL
1890  * \brief Memory buffer interface for GL interop with renderbuffer.
1891  */
1892 class BufferRenderGL : public Buffer
1893 {
1894 public:
BufferRenderGL(const Context & context,cl_mem_flags flags,GLuint bufobj,cl_int * err=NULL)1895     BufferRenderGL(
1896         const Context& context,
1897         cl_mem_flags flags,
1898         GLuint bufobj,
1899         cl_int * err = NULL)
1900     {
1901         cl_int error;
1902         object_ = ::clCreateFromGLRenderbuffer(
1903             context(),
1904             flags,
1905             bufobj,
1906             &error);
1907 
1908         detail::errHandler(error, __CREATE_GL_BUFFER_ERR);
1909         if (err != NULL) {
1910             *err = error;
1911         }
1912     }
1913 
BufferRenderGL()1914     BufferRenderGL() : Buffer() { }
1915 
BufferRenderGL(const BufferGL & buffer)1916     BufferRenderGL(const BufferGL& buffer) : Buffer(buffer) { }
1917 
operator =(const BufferRenderGL & rhs)1918     BufferRenderGL& operator = (const BufferRenderGL& rhs)
1919     {
1920         if (this != &rhs) {
1921             Buffer::operator=(rhs);
1922         }
1923         return *this;
1924     }
1925 
getObjectInfo(cl_gl_object_type * type,GLuint * gl_object_name)1926     cl_int getObjectInfo(
1927         cl_gl_object_type *type,
1928         GLuint * gl_object_name)
1929     {
1930         return detail::errHandler(
1931             ::clGetGLObjectInfo(object_,type,gl_object_name),
1932             __GET_GL_OBJECT_INFO_ERR);
1933     }
1934 };
1935 
1936 /*! \class Image
1937  * \brief Base class  interface for all images.
1938  */
1939 class Image : public Memory
1940 {
1941 protected:
Image()1942     Image() : Memory() { }
1943 
Image(const Image & image)1944     Image(const Image& image) : Memory(image) { }
1945 
operator =(const Image & rhs)1946     Image& operator = (const Image& rhs)
1947     {
1948         if (this != &rhs) {
1949             Memory::operator=(rhs);
1950         }
1951         return *this;
1952     }
1953 public:
1954     template <typename T>
getImageInfo(cl_image_info name,T * param) const1955     cl_int getImageInfo(cl_image_info name, T* param) const
1956     {
1957         return detail::errHandler(
1958             detail::getInfo(&::clGetImageInfo, object_, name, param),
1959             __GET_IMAGE_INFO_ERR);
1960     }
1961 
1962     template <cl_int name> typename
1963     detail::param_traits<detail::cl_image_info, name>::param_type
getImageInfo(cl_int * err=NULL) const1964     getImageInfo(cl_int* err = NULL) const
1965     {
1966         typename detail::param_traits<
1967             detail::cl_image_info, name>::param_type param;
1968         cl_int result = getImageInfo(name, &param);
1969         if (err != NULL) {
1970             *err = result;
1971         }
1972         return param;
1973     }
1974 };
1975 
1976 /*! \class Image2D
1977  * \brief Image interface for 2D images.
1978  */
1979 class Image2D : public Image
1980 {
1981 public:
Image2D(const Context & context,cl_mem_flags flags,ImageFormat format,::size_t width,::size_t height,::size_t row_pitch=0,void * host_ptr=NULL,cl_int * err=NULL)1982     Image2D(
1983         const Context& context,
1984         cl_mem_flags flags,
1985         ImageFormat format,
1986         ::size_t width,
1987         ::size_t height,
1988         ::size_t row_pitch = 0,
1989         void* host_ptr = NULL,
1990         cl_int* err = NULL)
1991     {
1992         cl_int error;
1993         object_ = ::clCreateImage2D(
1994             context(), flags,&format, width, height, row_pitch, host_ptr, &error);
1995 
1996         detail::errHandler(error, __CREATE_IMAGE2D_ERR);
1997         if (err != NULL) {
1998             *err = error;
1999         }
2000     }
2001 
Image2D()2002     Image2D() { }
2003 
Image2D(const Image2D & image2D)2004     Image2D(const Image2D& image2D) : Image(image2D) { }
2005 
operator =(const Image2D & rhs)2006     Image2D& operator = (const Image2D& rhs)
2007     {
2008         if (this != &rhs) {
2009             Image::operator=(rhs);
2010         }
2011         return *this;
2012     }
2013 };
2014 
2015 /*! \class Image2DGL
2016  * \brief 2D image interface for GL interop.
2017  */
2018 class Image2DGL : public Image2D
2019 {
2020 public:
Image2DGL(const Context & context,cl_mem_flags flags,GLenum target,GLint miplevel,GLuint texobj,cl_int * err=NULL)2021     Image2DGL(
2022         const Context& context,
2023         cl_mem_flags flags,
2024         GLenum target,
2025         GLint  miplevel,
2026         GLuint texobj,
2027         cl_int * err = NULL)
2028     {
2029         cl_int error;
2030         object_ = ::clCreateFromGLTexture2D(
2031             context(),
2032             flags,
2033             target,
2034             miplevel,
2035             texobj,
2036             &error);
2037 
2038         detail::errHandler(error, __CREATE_GL_BUFFER_ERR);
2039         if (err != NULL) {
2040             *err = error;
2041         }
2042     }
2043 
Image2DGL()2044     Image2DGL() : Image2D() { }
2045 
Image2DGL(const Image2DGL & image)2046     Image2DGL(const Image2DGL& image) : Image2D(image) { }
2047 
operator =(const Image2DGL & rhs)2048     Image2DGL& operator = (const Image2DGL& rhs)
2049     {
2050         if (this != &rhs) {
2051             Image2D::operator=(rhs);
2052         }
2053         return *this;
2054     }
2055 };
2056 
2057 /*! \class Image3D
2058  * \brief Image interface for 3D images.
2059  */
2060 class Image3D : public Image
2061 {
2062 public:
Image3D(const Context & context,cl_mem_flags flags,ImageFormat format,::size_t width,::size_t height,::size_t depth,::size_t row_pitch=0,::size_t slice_pitch=0,void * host_ptr=NULL,cl_int * err=NULL)2063     Image3D(
2064         const Context& context,
2065         cl_mem_flags flags,
2066         ImageFormat format,
2067         ::size_t width,
2068         ::size_t height,
2069         ::size_t depth,
2070         ::size_t row_pitch = 0,
2071         ::size_t slice_pitch = 0,
2072         void* host_ptr = NULL,
2073         cl_int* err = NULL)
2074     {
2075         cl_int error;
2076         object_ = ::clCreateImage3D(
2077             context(), flags, &format, width, height, depth, row_pitch,
2078             slice_pitch, host_ptr, &error);
2079 
2080         detail::errHandler(error, __CREATE_IMAGE3D_ERR);
2081         if (err != NULL) {
2082             *err = error;
2083         }
2084     }
2085 
Image3D()2086     Image3D() { }
2087 
Image3D(const Image3D & image3D)2088     Image3D(const Image3D& image3D) : Image(image3D) { }
2089 
operator =(const Image3D & rhs)2090     Image3D& operator = (const Image3D& rhs)
2091     {
2092         if (this != &rhs) {
2093             Image::operator=(rhs);
2094         }
2095         return *this;
2096     }
2097 };
2098 
2099 /*! \class Image2DGL
2100  * \brief 2D image interface for GL interop.
2101  */
2102 class Image3DGL : public Image3D
2103 {
2104 public:
Image3DGL(const Context & context,cl_mem_flags flags,GLenum target,GLint miplevel,GLuint texobj,cl_int * err=NULL)2105     Image3DGL(
2106         const Context& context,
2107         cl_mem_flags flags,
2108         GLenum target,
2109         GLint  miplevel,
2110         GLuint texobj,
2111         cl_int * err = NULL)
2112     {
2113         cl_int error;
2114         object_ = ::clCreateFromGLTexture3D(
2115             context(),
2116             flags,
2117             target,
2118             miplevel,
2119             texobj,
2120             &error);
2121 
2122         detail::errHandler(error, __CREATE_GL_BUFFER_ERR);
2123         if (err != NULL) {
2124             *err = error;
2125         }
2126     }
2127 
Image3DGL()2128     Image3DGL() : Image3D() { }
2129 
Image3DGL(const Image3DGL & image)2130     Image3DGL(const Image3DGL& image) : Image3D(image) { }
2131 
operator =(const Image3DGL & rhs)2132     Image3DGL& operator = (const Image3DGL& rhs)
2133     {
2134         if (this != &rhs) {
2135             Image3D::operator=(rhs);
2136         }
2137         return *this;
2138     }
2139 };
2140 
2141 /*! \class Sampler
2142  * \brief Sampler interface for cl_sampler.
2143  */
2144 class Sampler : public detail::Wrapper<cl_sampler>
2145 {
2146 public:
Sampler()2147     Sampler() { }
2148 
Sampler(const Context & context,cl_bool normalized_coords,cl_addressing_mode addressing_mode,cl_filter_mode filter_mode,cl_int * err=NULL)2149     Sampler(
2150         const Context& context,
2151         cl_bool normalized_coords,
2152         cl_addressing_mode addressing_mode,
2153         cl_filter_mode filter_mode,
2154         cl_int* err = NULL)
2155     {
2156         cl_int error;
2157         object_ = ::clCreateSampler(
2158             context(),
2159             normalized_coords,
2160             addressing_mode,
2161             filter_mode,
2162             &error);
2163 
2164         detail::errHandler(error, __CREATE_SAMPLER_ERR);
2165         if (err != NULL) {
2166             *err = error;
2167         }
2168     }
2169 
Sampler(const Sampler & sampler)2170     Sampler(const Sampler& sampler) : detail::Wrapper<cl_type>(sampler) { }
2171 
operator =(const Sampler & rhs)2172     Sampler& operator = (const Sampler& rhs)
2173     {
2174         if (this != &rhs) {
2175             detail::Wrapper<cl_type>::operator=(rhs);
2176         }
2177         return *this;
2178     }
2179 
2180     template <typename T>
getInfo(cl_sampler_info name,T * param) const2181     cl_int getInfo(cl_sampler_info name, T* param) const
2182     {
2183         return detail::errHandler(
2184             detail::getInfo(&::clGetSamplerInfo, object_, name, param),
2185             __GET_SAMPLER_INFO_ERR);
2186     }
2187 
2188     template <cl_int name> typename
2189     detail::param_traits<detail::cl_sampler_info, name>::param_type
getInfo(cl_int * err=NULL) const2190     getInfo(cl_int* err = NULL) const
2191     {
2192         typename detail::param_traits<
2193             detail::cl_sampler_info, name>::param_type param;
2194         cl_int result = getInfo(name, &param);
2195         if (err != NULL) {
2196             *err = result;
2197         }
2198         return param;
2199     }
2200 };
2201 
2202 __GET_INFO_HELPER_WITH_RETAIN(cl::Sampler)
2203 
2204 class Program;
2205 class CommandQueue;
2206 class Kernel;
2207 
2208 /*! \class NDRange
2209  * \brief NDRange interface
2210  */
2211 class NDRange
2212 {
2213 private:
2214     size_t<3> sizes_;
2215     cl_uint dimensions_;
2216 
2217 public:
NDRange()2218     NDRange()
2219         : dimensions_(0)
2220     { }
2221 
NDRange(::size_t size0)2222     NDRange(::size_t size0)
2223         : dimensions_(1)
2224     {
2225         sizes_.push_back(size0);
2226     }
2227 
NDRange(::size_t size0,::size_t size1)2228     NDRange(::size_t size0, ::size_t size1)
2229         : dimensions_(2)
2230     {
2231         sizes_.push_back(size0);
2232         sizes_.push_back(size1);
2233     }
2234 
NDRange(::size_t size0,::size_t size1,::size_t size2)2235     NDRange(::size_t size0, ::size_t size1, ::size_t size2)
2236         : dimensions_(3)
2237     {
2238         sizes_.push_back(size0);
2239         sizes_.push_back(size1);
2240         sizes_.push_back(size2);
2241     }
2242 
operator const::size_t*() const2243     operator const ::size_t*() const { return (const ::size_t*) sizes_; }
dimensions() const2244     ::size_t dimensions() const { return dimensions_; }
2245 };
2246 
2247 static const NDRange NullRange;
2248 
2249 /*!
2250  * \struct LocalSpaceArg
2251  * \brief Local address raper for use with Kernel::setArg
2252  */
2253 struct LocalSpaceArg
2254 {
2255     ::size_t size_;
2256 };
2257 
2258 namespace detail {
2259 
2260 template <typename T>
2261 struct KernelArgumentHandler
2262 {
sizecl::detail::KernelArgumentHandler2263     static ::size_t size(const T&) { return sizeof(T); }
ptrcl::detail::KernelArgumentHandler2264     static T* ptr(T& value) { return &value; }
2265 };
2266 
2267 template <>
2268 struct KernelArgumentHandler<LocalSpaceArg>
2269 {
sizecl::detail::KernelArgumentHandler2270     static ::size_t size(const LocalSpaceArg& value) { return value.size_; }
ptrcl::detail::KernelArgumentHandler2271     static void* ptr(LocalSpaceArg&) { return NULL; }
2272 };
2273 
2274 }
2275 //! \endcond
2276 
2277 inline LocalSpaceArg
__local(::size_t size)2278 __local(::size_t size)
2279 {
2280     LocalSpaceArg ret = { size };
2281     return ret;
2282 }
2283 
2284 class KernelFunctor;
2285 
2286 /*! \class Kernel
2287  * \brief Kernel interface that implements cl_kernel
2288  */
2289 class Kernel : public detail::Wrapper<cl_kernel>
2290 {
2291 public:
2292     inline Kernel(const Program& program, const char* name, cl_int* err = NULL);
2293 
Kernel()2294     Kernel() { }
2295 
Kernel(const Kernel & kernel)2296     Kernel(const Kernel& kernel) : detail::Wrapper<cl_type>(kernel) { }
2297 
operator =(const Kernel & rhs)2298     Kernel& operator = (const Kernel& rhs)
2299     {
2300         if (this != &rhs) {
2301             detail::Wrapper<cl_type>::operator=(rhs);
2302         }
2303         return *this;
2304     }
2305 
2306     template <typename T>
getInfo(cl_kernel_info name,T * param) const2307     cl_int getInfo(cl_kernel_info name, T* param) const
2308     {
2309         return detail::errHandler(
2310             detail::getInfo(&::clGetKernelInfo, object_, name, param),
2311             __GET_KERNEL_INFO_ERR);
2312     }
2313 
2314     template <cl_int name> typename
2315     detail::param_traits<detail::cl_kernel_info, name>::param_type
getInfo(cl_int * err=NULL) const2316     getInfo(cl_int* err = NULL) const
2317     {
2318         typename detail::param_traits<
2319             detail::cl_kernel_info, name>::param_type param;
2320         cl_int result = getInfo(name, &param);
2321         if (err != NULL) {
2322             *err = result;
2323         }
2324         return param;
2325     }
2326 
2327     template <typename T>
getWorkGroupInfo(const Device & device,cl_kernel_work_group_info name,T * param) const2328     cl_int getWorkGroupInfo(
2329         const Device& device, cl_kernel_work_group_info name, T* param) const
2330     {
2331         return detail::errHandler(
2332             detail::getInfo(
2333                 &::clGetKernelWorkGroupInfo, object_, device(), name, param),
2334                 __GET_KERNEL_WORK_GROUP_INFO_ERR);
2335     }
2336 
2337     template <cl_int name> typename
2338     detail::param_traits<detail::cl_kernel_work_group_info, name>::param_type
getWorkGroupInfo(const Device & device,cl_int * err=NULL) const2339         getWorkGroupInfo(const Device& device, cl_int* err = NULL) const
2340     {
2341         typename detail::param_traits<
2342         detail::cl_kernel_work_group_info, name>::param_type param;
2343         cl_int result = getWorkGroupInfo(device, name, &param);
2344         if (err != NULL) {
2345             *err = result;
2346         }
2347         return param;
2348     }
2349 
2350     template <typename T>
setArg(cl_uint index,T value)2351     cl_int setArg(cl_uint index, T value)
2352     {
2353         return detail::errHandler(
2354             ::clSetKernelArg(
2355                 object_,
2356                 index,
2357                 detail::KernelArgumentHandler<T>::size(value),
2358                 detail::KernelArgumentHandler<T>::ptr(value)),
2359             __SET_KERNEL_ARGS_ERR);
2360     }
2361 
setArg(cl_uint index,::size_t size,void * argPtr)2362     cl_int setArg(cl_uint index, ::size_t size, void* argPtr)
2363     {
2364         return detail::errHandler(
2365             ::clSetKernelArg(object_, index, size, argPtr),
2366             __SET_KERNEL_ARGS_ERR);
2367     }
2368 
2369     KernelFunctor bind(
2370         const CommandQueue& queue,
2371         const NDRange& offset,
2372         const NDRange& global,
2373         const NDRange& local);
2374 
2375     KernelFunctor bind(
2376         const CommandQueue& queue,
2377         const NDRange& global,
2378         const NDRange& local);
2379 };
2380 
2381 __GET_INFO_HELPER_WITH_RETAIN(cl::Kernel)
2382 
2383 /*! \class Program
2384  * \brief Program interface that implements cl_program.
2385  */
2386 class Program : public detail::Wrapper<cl_program>
2387 {
2388 public:
2389     typedef VECTOR_CLASS<std::pair<const void*, ::size_t> > Binaries;
2390     typedef VECTOR_CLASS<std::pair<const char*, ::size_t> > Sources;
2391 
Program(const Context & context,const Sources & sources,cl_int * err=NULL)2392     Program(
2393         const Context& context,
2394         const Sources& sources,
2395         cl_int* err = NULL)
2396     {
2397         cl_int error;
2398 
2399         const ::size_t n = (::size_t)sources.size();
2400         ::size_t* lengths = (::size_t*) alloca(n * sizeof(::size_t));
2401         const char** strings = (const char**) alloca(n * sizeof(const char*));
2402 
2403         for (::size_t i = 0; i < n; ++i) {
2404             strings[i] = sources[(int)i].first;
2405             lengths[i] = sources[(int)i].second;
2406         }
2407 
2408         object_ = ::clCreateProgramWithSource(
2409             context(), (cl_uint)n, strings, lengths, &error);
2410 
2411         detail::errHandler(error, __CREATE_PROGRAM_WITH_SOURCE_ERR);
2412         if (err != NULL) {
2413             *err = error;
2414         }
2415     }
2416 
Program(const Context & context,const VECTOR_CLASS<Device> & devices,const Binaries & binaries,VECTOR_CLASS<cl_int> * binaryStatus=NULL,cl_int * err=NULL)2417     Program(
2418         const Context& context,
2419         const VECTOR_CLASS<Device>& devices,
2420         const Binaries& binaries,
2421         VECTOR_CLASS<cl_int>* binaryStatus = NULL,
2422         cl_int* err = NULL)
2423     {
2424         cl_int error;
2425         const ::size_t n = binaries.size();
2426         ::size_t* lengths = (::size_t*) alloca(n * sizeof(::size_t));
2427         const unsigned char** images = (const unsigned char**) alloca(n * sizeof(const void*));
2428 
2429         for (::size_t i = 0; i < n; ++i) {
2430             images[i] = (const unsigned char*)binaries[(int)i].first;
2431             lengths[i] = binaries[(int)i].second;
2432         }
2433 
2434         object_ = ::clCreateProgramWithBinary(
2435             context(), (cl_uint) devices.size(),
2436             (cl_device_id*)&devices.front(),
2437             lengths, images, binaryStatus != NULL
2438                ? (cl_int*) &binaryStatus->front()
2439                : NULL, &error);
2440 
2441         detail::errHandler(error, __CREATE_PROGRAM_WITH_BINARY_ERR);
2442         if (err != NULL) {
2443             *err = error;
2444         }
2445     }
2446 
Program()2447     Program() { }
2448 
Program(const Program & program)2449     Program(const Program& program) : detail::Wrapper<cl_type>(program) { }
2450 
operator =(const Program & rhs)2451     Program& operator = (const Program& rhs)
2452     {
2453         if (this != &rhs) {
2454             detail::Wrapper<cl_type>::operator=(rhs);
2455         }
2456         return *this;
2457     }
2458 
build(const VECTOR_CLASS<Device> & devices,const char * options=NULL,void (CL_CALLBACK * notifyFptr)(cl_program,void *)=NULL,void * data=NULL) const2459     cl_int build(
2460         const VECTOR_CLASS<Device>& devices,
2461         const char* options = NULL,
2462         void (CL_CALLBACK * notifyFptr)(cl_program, void *) = NULL,
2463         void* data = NULL) const
2464     {
2465         return detail::errHandler(
2466             ::clBuildProgram(
2467                 object_,
2468                 (cl_uint)
2469                 devices.size(),
2470                 (cl_device_id*)&devices.front(),
2471                 options,
2472                 notifyFptr,
2473                 data),
2474                 __BUILD_PROGRAM_ERR);
2475     }
2476 
2477     template <typename T>
getInfo(cl_program_info name,T * param) const2478     cl_int getInfo(cl_program_info name, T* param) const
2479     {
2480         return detail::errHandler(
2481             detail::getInfo(&::clGetProgramInfo, object_, name, param),
2482             __GET_PROGRAM_INFO_ERR);
2483     }
2484 
2485     template <cl_int name> typename
2486     detail::param_traits<detail::cl_program_info, name>::param_type
getInfo(cl_int * err=NULL) const2487     getInfo(cl_int* err = NULL) const
2488     {
2489         typename detail::param_traits<
2490             detail::cl_program_info, name>::param_type param;
2491         cl_int result = getInfo(name, &param);
2492         if (err != NULL) {
2493             *err = result;
2494         }
2495         return param;
2496     }
2497 
2498     template <typename T>
getBuildInfo(const Device & device,cl_program_build_info name,T * param) const2499     cl_int getBuildInfo(
2500         const Device& device, cl_program_build_info name, T* param) const
2501     {
2502         return detail::errHandler(
2503             detail::getInfo(
2504                 &::clGetProgramBuildInfo, object_, device(), name, param),
2505                 __GET_PROGRAM_BUILD_INFO_ERR);
2506     }
2507 
2508     template <cl_int name> typename
2509     detail::param_traits<detail::cl_program_build_info, name>::param_type
getBuildInfo(const Device & device,cl_int * err=NULL) const2510     getBuildInfo(const Device& device, cl_int* err = NULL) const
2511     {
2512         typename detail::param_traits<
2513             detail::cl_program_build_info, name>::param_type param;
2514         cl_int result = getBuildInfo(device, name, &param);
2515         if (err != NULL) {
2516             *err = result;
2517         }
2518         return param;
2519     }
2520 
createKernels(VECTOR_CLASS<Kernel> * kernels)2521     cl_int createKernels(VECTOR_CLASS<Kernel>* kernels)
2522     {
2523         cl_uint numKernels;
2524         cl_int err = ::clCreateKernelsInProgram(object_, 0, NULL, &numKernels);
2525         if (err != CL_SUCCESS) {
2526             return detail::errHandler(err, __CREATE_KERNELS_IN_PROGRAM_ERR);
2527         }
2528 
2529         Kernel* value = (Kernel*) alloca(numKernels * sizeof(Kernel));
2530         err = ::clCreateKernelsInProgram(
2531             object_, numKernels, (cl_kernel*) value, NULL);
2532         if (err != CL_SUCCESS) {
2533             return detail::errHandler(err, __CREATE_KERNELS_IN_PROGRAM_ERR);
2534         }
2535 
2536         kernels->assign(&value[0], &value[numKernels]);
2537         return CL_SUCCESS;
2538     }
2539 };
2540 
__GET_INFO_HELPER_WITH_RETAIN(cl::Program)2541 __GET_INFO_HELPER_WITH_RETAIN(cl::Program)
2542 
2543 inline Kernel::Kernel(const Program& program, const char* name, cl_int* err)
2544 {
2545     cl_int error;
2546 
2547     object_ = ::clCreateKernel(program(), name, &error);
2548     detail::errHandler(error, __CREATE_KERNEL_ERR);
2549 
2550     if (err != NULL) {
2551         *err = error;
2552     }
2553 
2554 }
2555 
2556 /*! \class CommandQueue
2557  * \brief CommandQueue interface for cl_command_queue.
2558  */
2559 class CommandQueue : public detail::Wrapper<cl_command_queue>
2560 {
2561 public:
CommandQueue(const Context & context,const Device & device,cl_command_queue_properties properties=0,cl_int * err=NULL)2562     CommandQueue(
2563         const Context& context,
2564         const Device& device,
2565         cl_command_queue_properties properties = 0,
2566         cl_int* err = NULL)
2567     {
2568         cl_int error;
2569         object_ = ::clCreateCommandQueue(
2570             context(), device(), properties, &error);
2571 
2572         detail::errHandler(error, __CREATE_COMMAND_QUEUE_ERR);
2573         if (err != NULL) {
2574             *err = error;
2575         }
2576     }
2577 
CommandQueue()2578     CommandQueue() { }
2579 
CommandQueue(const CommandQueue & commandQueue)2580     CommandQueue(const CommandQueue& commandQueue) : detail::Wrapper<cl_type>(commandQueue) { }
2581 
operator =(const CommandQueue & rhs)2582     CommandQueue& operator = (const CommandQueue& rhs)
2583     {
2584         if (this != &rhs) {
2585             detail::Wrapper<cl_type>::operator=(rhs);
2586         }
2587         return *this;
2588     }
2589 
2590     template <typename T>
getInfo(cl_command_queue_info name,T * param) const2591     cl_int getInfo(cl_command_queue_info name, T* param) const
2592     {
2593         return detail::errHandler(
2594             detail::getInfo(
2595                 &::clGetCommandQueueInfo, object_, name, param),
2596                 __GET_COMMAND_QUEUE_INFO_ERR);
2597     }
2598 
2599     template <cl_int name> typename
2600     detail::param_traits<detail::cl_command_queue_info, name>::param_type
getInfo(cl_int * err=NULL) const2601     getInfo(cl_int* err = NULL) const
2602     {
2603         typename detail::param_traits<
2604             detail::cl_command_queue_info, name>::param_type param;
2605         cl_int result = getInfo(name, &param);
2606         if (err != NULL) {
2607             *err = result;
2608         }
2609         return param;
2610     }
2611 
enqueueReadBuffer(const Buffer & buffer,cl_bool blocking,::size_t offset,::size_t size,void * ptr,const VECTOR_CLASS<Event> * events=NULL,Event * event=NULL) const2612     cl_int enqueueReadBuffer(
2613         const Buffer& buffer,
2614         cl_bool blocking,
2615         ::size_t offset,
2616         ::size_t size,
2617         void* ptr,
2618         const VECTOR_CLASS<Event>* events = NULL,
2619         Event* event = NULL) const
2620     {
2621         return detail::errHandler(
2622             ::clEnqueueReadBuffer(
2623                 object_, buffer(), blocking, offset, size,
2624                 ptr,
2625                 (events != NULL) ? (cl_uint) events->size() : 0,
2626                 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
2627                 (cl_event*) event),
2628             __ENQUEUE_READ_BUFFER_ERR);
2629     }
2630 
enqueueWriteBuffer(const Buffer & buffer,cl_bool blocking,::size_t offset,::size_t size,const void * ptr,const VECTOR_CLASS<Event> * events=NULL,Event * event=NULL) const2631     cl_int enqueueWriteBuffer(
2632         const Buffer& buffer,
2633         cl_bool blocking,
2634         ::size_t offset,
2635         ::size_t size,
2636         const void* ptr,
2637         const VECTOR_CLASS<Event>* events = NULL,
2638         Event* event = NULL) const
2639     {
2640         return detail::errHandler(
2641             ::clEnqueueWriteBuffer(
2642                 object_, buffer(), blocking, offset, size,
2643                 ptr,
2644                 (events != NULL) ? (cl_uint) events->size() : 0,
2645                 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
2646                 (cl_event*) event),
2647                 __ENQUEUE_WRITE_BUFFER_ERR);
2648     }
2649 
enqueueCopyBuffer(const Buffer & src,const Buffer & dst,::size_t src_offset,::size_t dst_offset,::size_t size,const VECTOR_CLASS<Event> * events=NULL,Event * event=NULL) const2650     cl_int enqueueCopyBuffer(
2651         const Buffer& src,
2652         const Buffer& dst,
2653         ::size_t src_offset,
2654         ::size_t dst_offset,
2655         ::size_t size,
2656         const VECTOR_CLASS<Event>* events = NULL,
2657         Event* event = NULL) const
2658     {
2659         return detail::errHandler(
2660             ::clEnqueueCopyBuffer(
2661                 object_, src(), dst(), src_offset, dst_offset, size,
2662                 (events != NULL) ? (cl_uint) events->size() : 0,
2663                 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
2664                 (cl_event*) event),
2665             __ENQEUE_COPY_BUFFER_ERR);
2666     }
2667 
2668 #if defined(CL_VERSION_1_1)
enqueueReadBufferRect(const Buffer & buffer,cl_bool blocking,const size_t<3> & buffer_offset,const size_t<3> & host_offset,const size_t<3> & region,::size_t buffer_row_pitch,::size_t buffer_slice_pitch,::size_t host_row_pitch,::size_t host_slice_pitch,void * ptr,const VECTOR_CLASS<Event> * events=NULL,Event * event=NULL) const2669     cl_int enqueueReadBufferRect(
2670         const Buffer& buffer,
2671         cl_bool blocking,
2672         const size_t<3>& buffer_offset,
2673         const size_t<3>& host_offset,
2674         const size_t<3>& region,
2675         ::size_t buffer_row_pitch,
2676         ::size_t buffer_slice_pitch,
2677         ::size_t host_row_pitch,
2678         ::size_t host_slice_pitch,
2679         void *ptr,
2680         const VECTOR_CLASS<Event>* events = NULL,
2681         Event* event = NULL) const
2682     {
2683         return detail::errHandler(
2684             ::clEnqueueReadBufferRect(
2685                 object_,
2686                 buffer(),
2687                 blocking,
2688                 (const ::size_t *)buffer_offset,
2689                 (const ::size_t *)host_offset,
2690                 (const ::size_t *)region,
2691                 buffer_row_pitch,
2692                 buffer_slice_pitch,
2693                 host_row_pitch,
2694                 host_slice_pitch,
2695                 ptr,
2696                 (events != NULL) ? (cl_uint) events->size() : 0,
2697                 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
2698                 (cl_event*) event),
2699                 __ENQUEUE_READ_BUFFER_RECT_ERR);
2700     }
2701 
2702 
enqueueWriteBufferRect(const Buffer & buffer,cl_bool blocking,const size_t<3> & buffer_offset,const size_t<3> & host_offset,const size_t<3> & region,::size_t buffer_row_pitch,::size_t buffer_slice_pitch,::size_t host_row_pitch,::size_t host_slice_pitch,void * ptr,const VECTOR_CLASS<Event> * events=NULL,Event * event=NULL) const2703     cl_int enqueueWriteBufferRect(
2704         const Buffer& buffer,
2705         cl_bool blocking,
2706         const size_t<3>& buffer_offset,
2707         const size_t<3>& host_offset,
2708         const size_t<3>& region,
2709         ::size_t buffer_row_pitch,
2710         ::size_t buffer_slice_pitch,
2711         ::size_t host_row_pitch,
2712         ::size_t host_slice_pitch,
2713         void *ptr,
2714         const VECTOR_CLASS<Event>* events = NULL,
2715         Event* event = NULL) const
2716     {
2717         return detail::errHandler(
2718             ::clEnqueueWriteBufferRect(
2719                 object_,
2720                 buffer(),
2721                 blocking,
2722                 (const ::size_t *)buffer_offset,
2723                 (const ::size_t *)host_offset,
2724                 (const ::size_t *)region,
2725                 buffer_row_pitch,
2726                 buffer_slice_pitch,
2727                 host_row_pitch,
2728                 host_slice_pitch,
2729                 ptr,
2730                 (events != NULL) ? (cl_uint) events->size() : 0,
2731                 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
2732                 (cl_event*) event),
2733                 __ENQUEUE_WRITE_BUFFER_RECT_ERR);
2734     }
2735 
enqueueCopyBufferRect(const Buffer & src,const Buffer & dst,const size_t<3> & src_origin,const size_t<3> & dst_origin,const size_t<3> & region,::size_t src_row_pitch,::size_t src_slice_pitch,::size_t dst_row_pitch,::size_t dst_slice_pitch,const VECTOR_CLASS<Event> * events=NULL,Event * event=NULL) const2736     cl_int enqueueCopyBufferRect(
2737         const Buffer& src,
2738         const Buffer& dst,
2739         const size_t<3>& src_origin,
2740         const size_t<3>& dst_origin,
2741         const size_t<3>& region,
2742         ::size_t src_row_pitch,
2743         ::size_t src_slice_pitch,
2744         ::size_t dst_row_pitch,
2745         ::size_t dst_slice_pitch,
2746         const VECTOR_CLASS<Event>* events = NULL,
2747         Event* event = NULL) const
2748     {
2749         return detail::errHandler(
2750             ::clEnqueueCopyBufferRect(
2751                 object_,
2752                 src(),
2753                 dst(),
2754                 (const ::size_t *)src_origin,
2755                 (const ::size_t *)dst_origin,
2756                 (const ::size_t *)region,
2757                 src_row_pitch,
2758                 src_slice_pitch,
2759                 dst_row_pitch,
2760                 dst_slice_pitch,
2761                 (events != NULL) ? (cl_uint) events->size() : 0,
2762                 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
2763                 (cl_event*) event),
2764             __ENQEUE_COPY_BUFFER_RECT_ERR);
2765     }
2766 #endif
2767 
enqueueReadImage(const Image & image,cl_bool blocking,const size_t<3> & origin,const size_t<3> & region,::size_t row_pitch,::size_t slice_pitch,void * ptr,const VECTOR_CLASS<Event> * events=NULL,Event * event=NULL) const2768     cl_int enqueueReadImage(
2769         const Image& image,
2770         cl_bool blocking,
2771         const size_t<3>& origin,
2772         const size_t<3>& region,
2773         ::size_t row_pitch,
2774         ::size_t slice_pitch,
2775         void* ptr,
2776         const VECTOR_CLASS<Event>* events = NULL,
2777         Event* event = NULL) const
2778     {
2779         return detail::errHandler(
2780             ::clEnqueueReadImage(
2781                 object_, image(), blocking, (const ::size_t *) origin,
2782                 (const ::size_t *) region, row_pitch, slice_pitch, ptr,
2783                 (events != NULL) ? (cl_uint) events->size() : 0,
2784                 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
2785                 (cl_event*) event),
2786             __ENQUEUE_READ_IMAGE_ERR);
2787     }
2788 
enqueueWriteImage(const Image & image,cl_bool blocking,const size_t<3> & origin,const size_t<3> & region,::size_t row_pitch,::size_t slice_pitch,void * ptr,const VECTOR_CLASS<Event> * events=NULL,Event * event=NULL) const2789     cl_int enqueueWriteImage(
2790         const Image& image,
2791         cl_bool blocking,
2792         const size_t<3>& origin,
2793         const size_t<3>& region,
2794         ::size_t row_pitch,
2795         ::size_t slice_pitch,
2796         void* ptr,
2797         const VECTOR_CLASS<Event>* events = NULL,
2798         Event* event = NULL) const
2799     {
2800         return detail::errHandler(
2801             ::clEnqueueWriteImage(
2802                 object_, image(), blocking, (const ::size_t *) origin,
2803                 (const ::size_t *) region, row_pitch, slice_pitch, ptr,
2804                 (events != NULL) ? (cl_uint) events->size() : 0,
2805                 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
2806                 (cl_event*) event),
2807             __ENQUEUE_WRITE_IMAGE_ERR);
2808     }
2809 
enqueueCopyImage(const Image & src,const Image & dst,const size_t<3> & src_origin,const size_t<3> & dst_origin,const size_t<3> & region,const VECTOR_CLASS<Event> * events=NULL,Event * event=NULL) const2810     cl_int enqueueCopyImage(
2811         const Image& src,
2812         const Image& dst,
2813         const size_t<3>& src_origin,
2814         const size_t<3>& dst_origin,
2815         const size_t<3>& region,
2816         const VECTOR_CLASS<Event>* events = NULL,
2817         Event* event = NULL) const
2818     {
2819         return detail::errHandler(
2820             ::clEnqueueCopyImage(
2821                 object_, src(), dst(), (const ::size_t *) src_origin,
2822                 (const ::size_t *)dst_origin, (const ::size_t *) region,
2823                 (events != NULL) ? (cl_uint) events->size() : 0,
2824                 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
2825                 (cl_event*) event),
2826             __ENQUEUE_COPY_IMAGE_ERR);
2827     }
2828 
enqueueCopyImageToBuffer(const Image & src,const Buffer & dst,const size_t<3> & src_origin,const size_t<3> & region,::size_t dst_offset,const VECTOR_CLASS<Event> * events=NULL,Event * event=NULL) const2829     cl_int enqueueCopyImageToBuffer(
2830         const Image& src,
2831         const Buffer& dst,
2832         const size_t<3>& src_origin,
2833         const size_t<3>& region,
2834         ::size_t dst_offset,
2835         const VECTOR_CLASS<Event>* events = NULL,
2836         Event* event = NULL) const
2837     {
2838         return detail::errHandler(
2839             ::clEnqueueCopyImageToBuffer(
2840                 object_, src(), dst(), (const ::size_t *) src_origin,
2841                 (const ::size_t *) region, dst_offset,
2842                 (events != NULL) ? (cl_uint) events->size() : 0,
2843                 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
2844                 (cl_event*) event),
2845             __ENQUEUE_COPY_IMAGE_TO_BUFFER_ERR);
2846     }
2847 
enqueueCopyBufferToImage(const Buffer & src,const Image & dst,::size_t src_offset,const size_t<3> & dst_origin,const size_t<3> & region,const VECTOR_CLASS<Event> * events=NULL,Event * event=NULL) const2848     cl_int enqueueCopyBufferToImage(
2849         const Buffer& src,
2850         const Image& dst,
2851         ::size_t src_offset,
2852         const size_t<3>& dst_origin,
2853         const size_t<3>& region,
2854         const VECTOR_CLASS<Event>* events = NULL,
2855         Event* event = NULL) const
2856     {
2857         return detail::errHandler(
2858             ::clEnqueueCopyBufferToImage(
2859                 object_, src(), dst(), src_offset,
2860                 (const ::size_t *) dst_origin, (const ::size_t *) region,
2861                 (events != NULL) ? (cl_uint) events->size() : 0,
2862                 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
2863                 (cl_event*) event),
2864             __ENQUEUE_COPY_BUFFER_TO_IMAGE_ERR);
2865     }
2866 
enqueueMapBuffer(const Buffer & buffer,cl_bool blocking,cl_map_flags flags,::size_t offset,::size_t size,const VECTOR_CLASS<Event> * events=NULL,Event * event=NULL,cl_int * err=NULL) const2867     void* enqueueMapBuffer(
2868         const Buffer& buffer,
2869         cl_bool blocking,
2870         cl_map_flags flags,
2871         ::size_t offset,
2872         ::size_t size,
2873         const VECTOR_CLASS<Event>* events = NULL,
2874         Event* event = NULL,
2875         cl_int* err = NULL) const
2876     {
2877         cl_int error;
2878         void * result = ::clEnqueueMapBuffer(
2879             object_, buffer(), blocking, flags, offset, size,
2880             (events != NULL) ? (cl_uint) events->size() : 0,
2881             (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
2882             (cl_event*) event,
2883             &error);
2884 
2885         detail::errHandler(error, __ENQUEUE_MAP_BUFFER_ERR);
2886         if (err != NULL) {
2887             *err = error;
2888         }
2889         return result;
2890     }
2891 
enqueueMapImage(const Image & buffer,cl_bool blocking,cl_map_flags flags,const size_t<3> & origin,const size_t<3> & region,::size_t * row_pitch,::size_t * slice_pitch,const VECTOR_CLASS<Event> * events=NULL,Event * event=NULL,cl_int * err=NULL) const2892     void* enqueueMapImage(
2893         const Image& buffer,
2894         cl_bool blocking,
2895         cl_map_flags flags,
2896         const size_t<3>& origin,
2897         const size_t<3>& region,
2898         ::size_t * row_pitch,
2899         ::size_t * slice_pitch,
2900         const VECTOR_CLASS<Event>* events = NULL,
2901         Event* event = NULL,
2902         cl_int* err = NULL) const
2903     {
2904         cl_int error;
2905         void * result = ::clEnqueueMapImage(
2906             object_, buffer(), blocking, flags,
2907             (const ::size_t *) origin, (const ::size_t *) region,
2908             row_pitch, slice_pitch,
2909             (events != NULL) ? (cl_uint) events->size() : 0,
2910             (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
2911             (cl_event*) event,
2912             &error);
2913 
2914         detail::errHandler(error, __ENQUEUE_MAP_IMAGE_ERR);
2915         if (err != NULL) {
2916               *err = error;
2917         }
2918         return result;
2919     }
2920 
enqueueUnmapMemObject(const Memory & memory,void * mapped_ptr,const VECTOR_CLASS<Event> * events=NULL,Event * event=NULL) const2921     cl_int enqueueUnmapMemObject(
2922         const Memory& memory,
2923         void* mapped_ptr,
2924         const VECTOR_CLASS<Event>* events = NULL,
2925         Event* event = NULL) const
2926     {
2927         return detail::errHandler(
2928             ::clEnqueueUnmapMemObject(
2929                 object_, memory(), mapped_ptr,
2930                 (events != NULL) ? (cl_uint) events->size() : 0,
2931                 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
2932                 (cl_event*) event),
2933             __ENQUEUE_UNMAP_MEM_OBJECT_ERR);
2934     }
2935 
enqueueNDRangeKernel(const Kernel & kernel,const NDRange & offset,const NDRange & global,const NDRange & local,const VECTOR_CLASS<Event> * events=NULL,Event * event=NULL) const2936     cl_int enqueueNDRangeKernel(
2937         const Kernel& kernel,
2938         const NDRange& offset,
2939         const NDRange& global,
2940         const NDRange& local,
2941         const VECTOR_CLASS<Event>* events = NULL,
2942         Event* event = NULL) const
2943     {
2944         return detail::errHandler(
2945             ::clEnqueueNDRangeKernel(
2946                 object_, kernel(), (cl_uint) global.dimensions(),
2947                 offset.dimensions() != 0 ? (const ::size_t*) offset : NULL,
2948                 (const ::size_t*) global,
2949                 local.dimensions() != 0 ? (const ::size_t*) local : NULL,
2950                 (events != NULL) ? (cl_uint) events->size() : 0,
2951                 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
2952                 (cl_event*) event),
2953             __ENQUEUE_NDRANGE_KERNEL_ERR);
2954     }
2955 
enqueueTask(const Kernel & kernel,const VECTOR_CLASS<Event> * events=NULL,Event * event=NULL) const2956     cl_int enqueueTask(
2957         const Kernel& kernel,
2958         const VECTOR_CLASS<Event>* events = NULL,
2959         Event* event = NULL) const
2960     {
2961         return detail::errHandler(
2962             ::clEnqueueTask(
2963                 object_, kernel(),
2964                 (events != NULL) ? (cl_uint) events->size() : 0,
2965                 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
2966                 (cl_event*) event),
2967             __ENQUEUE_TASK_ERR);
2968     }
2969 
enqueueNativeKernel(void (* userFptr)(void *),std::pair<void *,::size_t> args,const VECTOR_CLASS<Memory> * mem_objects=NULL,const VECTOR_CLASS<const void * > * mem_locs=NULL,const VECTOR_CLASS<Event> * events=NULL,Event * event=NULL) const2970     cl_int enqueueNativeKernel(
2971         void (*userFptr)(void *),
2972         std::pair<void*, ::size_t> args,
2973         const VECTOR_CLASS<Memory>* mem_objects = NULL,
2974         const VECTOR_CLASS<const void*>* mem_locs = NULL,
2975         const VECTOR_CLASS<Event>* events = NULL,
2976         Event* event = NULL) const
2977     {
2978         cl_mem * mems = (mem_objects != NULL && mem_objects->size() > 0)
2979             ? (cl_mem*) alloca(mem_objects->size() * sizeof(cl_mem))
2980             : NULL;
2981 
2982         if (mems != NULL) {
2983             for (unsigned int i = 0; i < mem_objects->size(); i++) {
2984                 mems[i] = ((*mem_objects)[i])();
2985             }
2986         }
2987 
2988         return detail::errHandler(
2989             ::clEnqueueNativeKernel(
2990                 object_, userFptr, args.first, args.second,
2991                 (mem_objects != NULL) ? (cl_uint) mem_objects->size() : 0,
2992                 mems,
2993                 (mem_locs != NULL) ? (const void **) &mem_locs->front() : NULL,
2994                 (events != NULL) ? (cl_uint) events->size() : 0,
2995                 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
2996                 (cl_event*) event),
2997             __ENQUEUE_NATIVE_KERNEL);
2998     }
2999 
enqueueMarker(Event * event=NULL) const3000     cl_int enqueueMarker(Event* event = NULL) const
3001     {
3002         return detail::errHandler(
3003             ::clEnqueueMarker(object_, (cl_event*) event),
3004             __ENQUEUE_MARKER_ERR);
3005     }
3006 
enqueueWaitForEvents(const VECTOR_CLASS<Event> & events) const3007     cl_int enqueueWaitForEvents(const VECTOR_CLASS<Event>& events) const
3008     {
3009         return detail::errHandler(
3010             ::clEnqueueWaitForEvents(
3011                 object_,
3012                 (cl_uint) events.size(),
3013                 (const cl_event*) &events.front()),
3014             __ENQUEUE_WAIT_FOR_EVENTS_ERR);
3015     }
3016 
enqueueAcquireGLObjects(const VECTOR_CLASS<Memory> * mem_objects=NULL,const VECTOR_CLASS<Event> * events=NULL,Event * event=NULL) const3017     cl_int enqueueAcquireGLObjects(
3018          const VECTOR_CLASS<Memory>* mem_objects = NULL,
3019          const VECTOR_CLASS<Event>* events = NULL,
3020          Event* event = NULL) const
3021      {
3022          return detail::errHandler(
3023              ::clEnqueueAcquireGLObjects(
3024                  object_,
3025                  (mem_objects != NULL) ? (cl_uint) mem_objects->size() : 0,
3026                  (mem_objects != NULL) ? (const cl_mem *) &mem_objects->front(): NULL,
3027                  (events != NULL) ? (cl_uint) events->size() : 0,
3028                  (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
3029                  (cl_event*) event),
3030              __ENQUEUE_ACQUIRE_GL_ERR);
3031      }
3032 
enqueueReleaseGLObjects(const VECTOR_CLASS<Memory> * mem_objects=NULL,const VECTOR_CLASS<Event> * events=NULL,Event * event=NULL) const3033     cl_int enqueueReleaseGLObjects(
3034          const VECTOR_CLASS<Memory>* mem_objects = NULL,
3035          const VECTOR_CLASS<Event>* events = NULL,
3036          Event* event = NULL) const
3037      {
3038          return detail::errHandler(
3039              ::clEnqueueReleaseGLObjects(
3040                  object_,
3041                  (mem_objects != NULL) ? (cl_uint) mem_objects->size() : 0,
3042                  (mem_objects != NULL) ? (const cl_mem *) &mem_objects->front(): NULL,
3043                  (events != NULL) ? (cl_uint) events->size() : 0,
3044                  (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
3045                  (cl_event*) event),
3046              __ENQUEUE_RELEASE_GL_ERR);
3047      }
3048 
3049 #if defined (USE_DX_INTEROP)
3050 typedef CL_API_ENTRY cl_int (CL_API_CALL *PFN_clEnqueueAcquireD3D10ObjectsKHR)(
3051     cl_command_queue command_queue, cl_uint num_objects,
3052     const cl_mem* mem_objects, cl_uint num_events_in_wait_list,
3053     const cl_event* event_wait_list, cl_event* event);
3054 typedef CL_API_ENTRY cl_int (CL_API_CALL *PFN_clEnqueueReleaseD3D10ObjectsKHR)(
3055     cl_command_queue command_queue, cl_uint num_objects,
3056     const cl_mem* mem_objects,  cl_uint num_events_in_wait_list,
3057     const cl_event* event_wait_list, cl_event* event);
3058 
enqueueAcquireD3D10Objects(const VECTOR_CLASS<Memory> * mem_objects=NULL,const VECTOR_CLASS<Event> * events=NULL,Event * event=NULL) const3059     cl_int enqueueAcquireD3D10Objects(
3060          const VECTOR_CLASS<Memory>* mem_objects = NULL,
3061          const VECTOR_CLASS<Event>* events = NULL,
3062          Event* event = NULL) const
3063      {
3064          static PFN_clEnqueueAcquireD3D10ObjectsKHR pfn_clEnqueueAcquireD3D10ObjectsKHR = NULL;
3065          __INIT_CL_EXT_FCN_PTR(clEnqueueAcquireD3D10ObjectsKHR);
3066 
3067          return detail::errHandler(
3068              pfn_clEnqueueAcquireD3D10ObjectsKHR(
3069                  object_,
3070                  (mem_objects != NULL) ? (cl_uint) mem_objects->size() : 0,
3071                  (mem_objects != NULL) ? (const cl_mem *) &mem_objects->front(): NULL,
3072                  (events != NULL) ? (cl_uint) events->size() : 0,
3073                  (events != NULL) ? (cl_event*) &events->front() : NULL,
3074                  (cl_event*) event),
3075              __ENQUEUE_ACQUIRE_GL_ERR);
3076      }
3077 
enqueueReleaseD3D10Objects(const VECTOR_CLASS<Memory> * mem_objects=NULL,const VECTOR_CLASS<Event> * events=NULL,Event * event=NULL) const3078     cl_int enqueueReleaseD3D10Objects(
3079          const VECTOR_CLASS<Memory>* mem_objects = NULL,
3080          const VECTOR_CLASS<Event>* events = NULL,
3081          Event* event = NULL) const
3082     {
3083         static PFN_clEnqueueReleaseD3D10ObjectsKHR pfn_clEnqueueReleaseD3D10ObjectsKHR = NULL;
3084         __INIT_CL_EXT_FCN_PTR(clEnqueueReleaseD3D10ObjectsKHR);
3085 
3086         return detail::errHandler(
3087             pfn_clEnqueueReleaseD3D10ObjectsKHR(
3088                 object_,
3089                 (mem_objects != NULL) ? (cl_uint) mem_objects->size() : 0,
3090                 (mem_objects != NULL) ? (const cl_mem *) &mem_objects->front(): NULL,
3091                 (events != NULL) ? (cl_uint) events->size() : 0,
3092                 (events != NULL) ? (cl_event*) &events->front() : NULL,
3093                 (cl_event*) event),
3094             __ENQUEUE_RELEASE_GL_ERR);
3095     }
3096 #endif
3097 
enqueueBarrier() const3098     cl_int enqueueBarrier() const
3099     {
3100         return detail::errHandler(
3101             ::clEnqueueBarrier(object_),
3102             __ENQUEUE_BARRIER_ERR);
3103     }
3104 
flush() const3105     cl_int flush() const
3106     {
3107         return detail::errHandler(::clFlush(object_), __FLUSH_ERR);
3108     }
3109 
finish() const3110     cl_int finish() const
3111     {
3112         return detail::errHandler(::clFinish(object_), __FINISH_ERR);
3113     }
3114 };
3115 
3116 __GET_INFO_HELPER_WITH_RETAIN(cl::CommandQueue)
3117 
3118 /*! \class KernelFunctor
3119  * \brief Kernel functor interface
3120  *
3121  * \note Currently only functors of zero to ten arguments are supported. It
3122  * is straightforward to add more and a more general solution, similar to
3123  * Boost.Lambda could be followed if required in the future.
3124  */
3125 class KernelFunctor
3126 {
3127 private:
3128     Kernel kernel_;
3129     CommandQueue queue_;
3130     NDRange offset_;
3131     NDRange global_;
3132     NDRange local_;
3133 
3134     cl_int err_;
3135 public:
KernelFunctor()3136     KernelFunctor() { }
3137 
KernelFunctor(const Kernel & kernel,const CommandQueue & queue,const NDRange & offset,const NDRange & global,const NDRange & local)3138     KernelFunctor(
3139         const Kernel& kernel,
3140         const CommandQueue& queue,
3141         const NDRange& offset,
3142         const NDRange& global,
3143         const NDRange& local) :
3144             kernel_(kernel),
3145             queue_(queue),
3146             offset_(offset),
3147             global_(global),
3148             local_(local),
3149             err_(CL_SUCCESS)
3150     {}
3151 
3152     KernelFunctor& operator=(const KernelFunctor& rhs);
3153 
3154     KernelFunctor(const KernelFunctor& rhs);
3155 
getError()3156     cl_int getError() { return err_; }
3157 
3158     inline Event operator()(const VECTOR_CLASS<Event>* events = NULL);
3159 
3160     template<typename A1>
3161     inline Event operator()(
3162         const A1& a1,
3163         const VECTOR_CLASS<Event>* events = NULL);
3164 
3165     template<class A1, class A2>
3166     inline Event operator()(
3167         const A1& a1,
3168         const A2& a2,
3169         const VECTOR_CLASS<Event>* events = NULL);
3170 
3171     template<class A1, class A2, class A3>
3172     inline Event operator()(
3173         const A1& a1,
3174         const A2& a2,
3175         const A3& a3,
3176         const VECTOR_CLASS<Event>* events = NULL);
3177 
3178     template<class A1, class A2, class A3, class A4>
3179     inline Event operator()(
3180         const A1& a1,
3181         const A2& a2,
3182         const A3& a3,
3183         const A4& a4,
3184         const VECTOR_CLASS<Event>* events = NULL);
3185 
3186     template<class A1, class A2, class A3, class A4, class A5>
3187     inline Event operator()(
3188         const A1& a1,
3189         const A2& a2,
3190         const A3& a3,
3191         const A4& a4,
3192         const A5& a5,
3193         const VECTOR_CLASS<Event>* events = NULL);
3194 
3195     template<class A1, class A2, class A3, class A4, class A5, class A6>
3196     inline Event operator()(
3197         const A1& a1,
3198         const A2& a2,
3199         const A3& a3,
3200         const A4& a4,
3201         const A5& a5,
3202         const A6& a6,
3203         const VECTOR_CLASS<Event>* events = NULL);
3204 
3205     template<class A1, class A2, class A3, class A4,
3206              class A5, class A6, class A7>
3207     inline Event operator()(
3208         const A1& a1,
3209         const A2& a2,
3210         const A3& a3,
3211         const A4& a4,
3212         const A5& a5,
3213         const A6& a6,
3214         const A7& a7,
3215         const VECTOR_CLASS<Event>* events = NULL);
3216 
3217     template<class A1, class A2, class A3, class A4, class A5,
3218              class A6, class A7, class A8>
3219     inline Event operator()(
3220         const A1& a1,
3221         const A2& a2,
3222         const A3& a3,
3223         const A4& a4,
3224         const A5& a5,
3225         const A6& a6,
3226         const A7& a7,
3227         const A8& a8,
3228         const VECTOR_CLASS<Event>* events = NULL);
3229 
3230     template<class A1, class A2, class A3, class A4, class A5,
3231              class A6, class A7, class A8, class A9>
3232     inline Event operator()(
3233         const A1& a1,
3234         const A2& a2,
3235         const A3& a3,
3236         const A4& a4,
3237         const A5& a5,
3238         const A6& a6,
3239         const A7& a7,
3240         const A8& a8,
3241         const A9& a9,
3242         const VECTOR_CLASS<Event>* events = NULL);
3243 
3244     template<class A1, class A2, class A3, class A4, class A5,
3245              class A6, class A7, class A8, class A9, class A10>
3246     inline Event operator()(
3247         const A1& a1,
3248         const A2& a2,
3249         const A3& a3,
3250         const A4& a4,
3251         const A5& a5,
3252         const A6& a6,
3253         const A7& a7,
3254         const A8& a8,
3255         const A9& a9,
3256         const A10& a10,
3257         const VECTOR_CLASS<Event>* events = NULL);
3258 
3259     template<class A1, class A2, class A3, class A4, class A5,
3260              class A6, class A7, class A8, class A9, class A10,
3261              class A11>
3262     inline Event operator()(
3263         const A1& a1,
3264         const A2& a2,
3265         const A3& a3,
3266         const A4& a4,
3267         const A5& a5,
3268         const A6& a6,
3269         const A7& a7,
3270         const A8& a8,
3271         const A9& a9,
3272         const A10& a10,
3273         const A11& a11,
3274         const VECTOR_CLASS<Event>* events = NULL);
3275 
3276     template<class A1, class A2, class A3, class A4, class A5,
3277              class A6, class A7, class A8, class A9, class A10,
3278              class A11, class A12>
3279     inline Event operator()(
3280         const A1& a1,
3281         const A2& a2,
3282         const A3& a3,
3283         const A4& a4,
3284         const A5& a5,
3285         const A6& a6,
3286         const A7& a7,
3287         const A8& a8,
3288         const A9& a9,
3289         const A10& a10,
3290         const A11& a11,
3291         const A12& a12,
3292         const VECTOR_CLASS<Event>* events = NULL);
3293 
3294     template<class A1, class A2, class A3, class A4, class A5,
3295              class A6, class A7, class A8, class A9, class A10,
3296              class A11, class A12, class A13>
3297     inline Event operator()(
3298         const A1& a1,
3299         const A2& a2,
3300         const A3& a3,
3301         const A4& a4,
3302         const A5& a5,
3303         const A6& a6,
3304         const A7& a7,
3305         const A8& a8,
3306         const A9& a9,
3307         const A10& a10,
3308         const A11& a11,
3309         const A12& a12,
3310         const A13& a13,
3311         const VECTOR_CLASS<Event>* events = NULL);
3312 
3313     template<class A1, class A2, class A3, class A4, class A5,
3314              class A6, class A7, class A8, class A9, class A10,
3315              class A11, class A12, class A13, class A14>
3316     inline Event operator()(
3317         const A1& a1,
3318         const A2& a2,
3319         const A3& a3,
3320         const A4& a4,
3321         const A5& a5,
3322         const A6& a6,
3323         const A7& a7,
3324         const A8& a8,
3325         const A9& a9,
3326         const A10& a10,
3327         const A11& a11,
3328         const A12& a12,
3329         const A13& a13,
3330         const A14& a14,
3331         const VECTOR_CLASS<Event>* events = NULL);
3332 
3333     template<class A1, class A2, class A3, class A4, class A5,
3334              class A6, class A7, class A8, class A9, class A10,
3335              class A11, class A12, class A13, class A14, class A15>
3336     inline Event operator()(
3337         const A1& a1,
3338         const A2& a2,
3339         const A3& a3,
3340         const A4& a4,
3341         const A5& a5,
3342         const A6& a6,
3343         const A7& a7,
3344         const A8& a8,
3345         const A9& a9,
3346         const A10& a10,
3347         const A11& a11,
3348         const A12& a12,
3349         const A13& a13,
3350         const A14& a14,
3351         const A15& a15,
3352         const VECTOR_CLASS<Event>* events = NULL);
3353 };
3354 
bind(const CommandQueue & queue,const NDRange & offset,const NDRange & global,const NDRange & local)3355 inline KernelFunctor Kernel::bind(
3356     const CommandQueue& queue,
3357     const NDRange& offset,
3358     const NDRange& global,
3359     const NDRange& local)
3360 {
3361     return KernelFunctor(*this,queue,offset,global,local);
3362 }
3363 
bind(const CommandQueue & queue,const NDRange & global,const NDRange & local)3364 inline KernelFunctor Kernel::bind(
3365     const CommandQueue& queue,
3366     const NDRange& global,
3367     const NDRange& local)
3368 {
3369     return KernelFunctor(*this,queue,NullRange,global,local);
3370 }
3371 
operator =(const KernelFunctor & rhs)3372 inline KernelFunctor& KernelFunctor::operator=(const KernelFunctor& rhs)
3373 {
3374     if (this == &rhs) {
3375         return *this;
3376     }
3377 
3378     kernel_ = rhs.kernel_;
3379     queue_  = rhs.queue_;
3380     offset_ = rhs.offset_;
3381     global_ = rhs.global_;
3382     local_  = rhs.local_;
3383 
3384     return *this;
3385 }
3386 
KernelFunctor(const KernelFunctor & rhs)3387 inline KernelFunctor::KernelFunctor(const KernelFunctor& rhs) :
3388     kernel_(rhs.kernel_),
3389     queue_(rhs.queue_),
3390     offset_(rhs.offset_),
3391     global_(rhs.global_),
3392     local_(rhs.local_)
3393 {
3394 }
3395 
operator ()(const VECTOR_CLASS<Event> * events)3396 Event KernelFunctor::operator()(const VECTOR_CLASS<Event>* events)
3397 {
3398     Event event;
3399 
3400     err_ = queue_.enqueueNDRangeKernel(
3401         kernel_,
3402         offset_,
3403         global_,
3404         local_,
3405         NULL,    // bgaster_fixme - do we want to allow wait event lists?
3406         &event);
3407 
3408     return event;
3409 }
3410 
3411 template<typename A1>
operator ()(const A1 & a1,const VECTOR_CLASS<Event> * events)3412 Event KernelFunctor::operator()(
3413     const A1& a1,
3414     const VECTOR_CLASS<Event>* events)
3415 {
3416     Event event;
3417 
3418     kernel_.setArg(0,a1);
3419 
3420     err_ = queue_.enqueueNDRangeKernel(
3421         kernel_,
3422         offset_,
3423         global_,
3424         local_,
3425         NULL,    // bgaster_fixme - do we want to allow wait event lists?
3426         &event);
3427 
3428     return event;
3429 }
3430 
3431 template<typename A1, typename A2>
operator ()(const A1 & a1,const A2 & a2,const VECTOR_CLASS<Event> * events)3432 Event KernelFunctor::operator()(
3433     const A1& a1,
3434     const A2& a2,
3435     const VECTOR_CLASS<Event>* events)
3436 {
3437     Event event;
3438 
3439     kernel_.setArg(0,a1);
3440     kernel_.setArg(1,a2);
3441 
3442     err_ = queue_.enqueueNDRangeKernel(
3443         kernel_,
3444         offset_,
3445         global_,
3446         local_,
3447         NULL,    // bgaster_fixme - do we want to allow wait event lists?
3448         &event);
3449 
3450     return event;
3451 }
3452 
3453 template<typename A1, typename A2, typename A3>
operator ()(const A1 & a1,const A2 & a2,const A3 & a3,const VECTOR_CLASS<Event> * events)3454 Event KernelFunctor::operator()(
3455     const A1& a1,
3456     const A2& a2,
3457     const A3& a3,
3458     const VECTOR_CLASS<Event>* events)
3459 {
3460     Event event;
3461 
3462     kernel_.setArg(0,a1);
3463     kernel_.setArg(1,a2);
3464     kernel_.setArg(2,a3);
3465 
3466     err_ = queue_.enqueueNDRangeKernel(
3467         kernel_,
3468         offset_,
3469         global_,
3470         local_,
3471         NULL,    // bgaster_fixme - do we want to allow wait event lists?
3472         &event);
3473 
3474     return event;
3475 }
3476 
3477 template<typename A1, typename A2, typename A3, typename A4>
operator ()(const A1 & a1,const A2 & a2,const A3 & a3,const A4 & a4,const VECTOR_CLASS<Event> * events)3478 Event KernelFunctor::operator()(
3479     const A1& a1,
3480     const A2& a2,
3481     const A3& a3,
3482     const A4& a4,
3483     const VECTOR_CLASS<Event>* events)
3484 {
3485     Event event;
3486 
3487     kernel_.setArg(0,a1);
3488     kernel_.setArg(1,a2);
3489     kernel_.setArg(2,a3);
3490     kernel_.setArg(3,a4);
3491 
3492     err_ = queue_.enqueueNDRangeKernel(
3493         kernel_,
3494         offset_,
3495         global_,
3496         local_,
3497         NULL,    // bgaster_fixme - do we want to allow wait event lists?
3498         &event);
3499 
3500     return event;
3501 }
3502 
3503 template<typename A1, typename A2, typename A3, typename A4, typename A5>
operator ()(const A1 & a1,const A2 & a2,const A3 & a3,const A4 & a4,const A5 & a5,const VECTOR_CLASS<Event> * events)3504 Event KernelFunctor::operator()(
3505     const A1& a1,
3506     const A2& a2,
3507     const A3& a3,
3508     const A4& a4,
3509     const A5& a5,
3510     const VECTOR_CLASS<Event>* events)
3511 {
3512     Event event;
3513 
3514     kernel_.setArg(0,a1);
3515     kernel_.setArg(1,a2);
3516     kernel_.setArg(2,a3);
3517     kernel_.setArg(3,a4);
3518     kernel_.setArg(4,a5);
3519 
3520     err_ = queue_.enqueueNDRangeKernel(
3521         kernel_,
3522         offset_,
3523         global_,
3524         local_,
3525         NULL,    // bgaster_fixme - do we want to allow wait event lists?
3526         &event);
3527 
3528     return event;
3529 }
3530 
3531 template<typename A1, typename A2, typename A3, typename A4, typename A5,
3532          typename A6>
operator ()(const A1 & a1,const A2 & a2,const A3 & a3,const A4 & a4,const A5 & a5,const A6 & a6,const VECTOR_CLASS<Event> * events)3533 Event KernelFunctor::operator()(
3534     const A1& a1,
3535     const A2& a2,
3536     const A3& a3,
3537     const A4& a4,
3538     const A5& a5,
3539     const A6& a6,
3540     const VECTOR_CLASS<Event>* events)
3541 {
3542     Event event;
3543 
3544     kernel_.setArg(0,a1);
3545     kernel_.setArg(1,a2);
3546     kernel_.setArg(2,a3);
3547     kernel_.setArg(3,a4);
3548     kernel_.setArg(4,a5);
3549     kernel_.setArg(5,a6);
3550 
3551     err_ = queue_.enqueueNDRangeKernel(
3552         kernel_,
3553         offset_,
3554         global_,
3555         local_,
3556         NULL,    // bgaster_fixme - do we want to allow wait event lists?
3557         &event);
3558 
3559     return event;
3560 }
3561 
3562 template<typename A1, typename A2, typename A3, typename A4,
3563          typename A5, typename A6, typename A7>
operator ()(const A1 & a1,const A2 & a2,const A3 & a3,const A4 & a4,const A5 & a5,const A6 & a6,const A7 & a7,const VECTOR_CLASS<Event> * events)3564 Event KernelFunctor::operator()(
3565     const A1& a1,
3566     const A2& a2,
3567     const A3& a3,
3568     const A4& a4,
3569     const A5& a5,
3570     const A6& a6,
3571     const A7& a7,
3572     const VECTOR_CLASS<Event>* events)
3573 {
3574     Event event;
3575 
3576     kernel_.setArg(0,a1);
3577     kernel_.setArg(1,a2);
3578     kernel_.setArg(2,a3);
3579     kernel_.setArg(3,a4);
3580     kernel_.setArg(4,a5);
3581     kernel_.setArg(5,a6);
3582     kernel_.setArg(6,a7);
3583 
3584     err_ = queue_.enqueueNDRangeKernel(
3585         kernel_,
3586         offset_,
3587         global_,
3588         local_,
3589         NULL,    // bgaster_fixme - do we want to allow wait event lists?
3590         &event);
3591 
3592     return event;
3593 }
3594 
3595 template<typename A1, typename A2, typename A3, typename A4, typename A5,
3596          typename A6, typename A7, typename A8>
operator ()(const A1 & a1,const A2 & a2,const A3 & a3,const A4 & a4,const A5 & a5,const A6 & a6,const A7 & a7,const A8 & a8,const VECTOR_CLASS<Event> * events)3597 Event KernelFunctor::operator()(
3598     const A1& a1,
3599     const A2& a2,
3600     const A3& a3,
3601     const A4& a4,
3602     const A5& a5,
3603     const A6& a6,
3604     const A7& a7,
3605     const A8& a8,
3606     const VECTOR_CLASS<Event>* events)
3607 {
3608     Event event;
3609 
3610     kernel_.setArg(0,a1);
3611     kernel_.setArg(1,a2);
3612     kernel_.setArg(2,a3);
3613     kernel_.setArg(3,a4);
3614     kernel_.setArg(4,a5);
3615     kernel_.setArg(5,a6);
3616     kernel_.setArg(6,a7);
3617     kernel_.setArg(7,a8);
3618 
3619     err_ = queue_.enqueueNDRangeKernel(
3620         kernel_,
3621         offset_,
3622         global_,
3623         local_,
3624         NULL,    // bgaster_fixme - do we want to allow wait event lists?
3625         &event);
3626 
3627     return event;
3628 }
3629 
3630 template<typename A1, typename A2, typename A3, typename A4, typename A5,
3631          typename A6, typename A7, typename A8, typename A9>
operator ()(const A1 & a1,const A2 & a2,const A3 & a3,const A4 & a4,const A5 & a5,const A6 & a6,const A7 & a7,const A8 & a8,const A9 & a9,const VECTOR_CLASS<Event> * events)3632 Event KernelFunctor::operator()(
3633     const A1& a1,
3634     const A2& a2,
3635     const A3& a3,
3636     const A4& a4,
3637     const A5& a5,
3638     const A6& a6,
3639     const A7& a7,
3640     const A8& a8,
3641     const A9& a9,
3642     const VECTOR_CLASS<Event>* events)
3643 {
3644     Event event;
3645 
3646     kernel_.setArg(0,a1);
3647     kernel_.setArg(1,a2);
3648     kernel_.setArg(2,a3);
3649     kernel_.setArg(3,a4);
3650     kernel_.setArg(4,a5);
3651     kernel_.setArg(5,a6);
3652     kernel_.setArg(6,a7);
3653     kernel_.setArg(7,a8);
3654     kernel_.setArg(8,a9);
3655 
3656     err_ = queue_.enqueueNDRangeKernel(
3657         kernel_,
3658         offset_,
3659         global_,
3660         local_,
3661         NULL,    // bgaster_fixme - do we want to allow wait event lists?
3662         &event);
3663 
3664     return event;
3665 }
3666 
3667 template<typename A1, typename A2, typename A3, typename A4, typename A5,
3668          typename A6, typename A7, typename A8, typename A9, typename A10>
operator ()(const A1 & a1,const A2 & a2,const A3 & a3,const A4 & a4,const A5 & a5,const A6 & a6,const A7 & a7,const A8 & a8,const A9 & a9,const A10 & a10,const VECTOR_CLASS<Event> * events)3669 Event KernelFunctor::operator()(
3670     const A1& a1,
3671     const A2& a2,
3672     const A3& a3,
3673     const A4& a4,
3674     const A5& a5,
3675     const A6& a6,
3676     const A7& a7,
3677     const A8& a8,
3678     const A9& a9,
3679     const A10& a10,
3680     const VECTOR_CLASS<Event>* events)
3681 {
3682     Event event;
3683 
3684     kernel_.setArg(0,a1);
3685     kernel_.setArg(1,a2);
3686     kernel_.setArg(2,a3);
3687     kernel_.setArg(3,a4);
3688     kernel_.setArg(4,a5);
3689     kernel_.setArg(5,a6);
3690     kernel_.setArg(6,a7);
3691     kernel_.setArg(7,a8);
3692     kernel_.setArg(8,a9);
3693     kernel_.setArg(9,a10);
3694 
3695     err_ = queue_.enqueueNDRangeKernel(
3696         kernel_,
3697         offset_,
3698         global_,
3699         local_,
3700         NULL,    // bgaster_fixme - do we want to allow wait event lists?
3701         &event);
3702 
3703     return event;
3704 }
3705 
3706 template<class A1, class A2, class A3, class A4, class A5,
3707          class A6, class A7, class A8, class A9, class A10,
3708          class A11>
operator ()(const A1 & a1,const A2 & a2,const A3 & a3,const A4 & a4,const A5 & a5,const A6 & a6,const A7 & a7,const A8 & a8,const A9 & a9,const A10 & a10,const A11 & a11,const VECTOR_CLASS<Event> * events)3709 Event KernelFunctor::operator()(
3710     const A1& a1,
3711     const A2& a2,
3712     const A3& a3,
3713     const A4& a4,
3714     const A5& a5,
3715     const A6& a6,
3716     const A7& a7,
3717     const A8& a8,
3718     const A9& a9,
3719     const A10& a10,
3720     const A11& a11,
3721     const VECTOR_CLASS<Event>* events)
3722 {
3723     Event event;
3724 
3725     kernel_.setArg(0,a1);
3726     kernel_.setArg(1,a2);
3727     kernel_.setArg(2,a3);
3728     kernel_.setArg(3,a4);
3729     kernel_.setArg(4,a5);
3730     kernel_.setArg(5,a6);
3731     kernel_.setArg(6,a7);
3732     kernel_.setArg(7,a8);
3733     kernel_.setArg(8,a9);
3734     kernel_.setArg(9,a10);
3735     kernel_.setArg(10,a11);
3736 
3737     err_ = queue_.enqueueNDRangeKernel(
3738         kernel_,
3739         offset_,
3740         global_,
3741         local_,
3742         NULL,    // bgaster_fixme - do we want to allow wait event lists?
3743         &event);
3744 
3745     return event;
3746 }
3747 
3748 template<class A1, class A2, class A3, class A4, class A5,
3749          class A6, class A7, class A8, class A9, class A10,
3750          class A11, class A12>
operator ()(const A1 & a1,const A2 & a2,const A3 & a3,const A4 & a4,const A5 & a5,const A6 & a6,const A7 & a7,const A8 & a8,const A9 & a9,const A10 & a10,const A11 & a11,const A12 & a12,const VECTOR_CLASS<Event> * events)3751 Event KernelFunctor::operator()(
3752     const A1& a1,
3753     const A2& a2,
3754     const A3& a3,
3755     const A4& a4,
3756     const A5& a5,
3757     const A6& a6,
3758     const A7& a7,
3759     const A8& a8,
3760     const A9& a9,
3761     const A10& a10,
3762     const A11& a11,
3763     const A12& a12,
3764     const VECTOR_CLASS<Event>* events)
3765 {
3766     Event event;
3767 
3768     kernel_.setArg(0,a1);
3769     kernel_.setArg(1,a2);
3770     kernel_.setArg(2,a3);
3771     kernel_.setArg(3,a4);
3772     kernel_.setArg(4,a5);
3773     kernel_.setArg(5,a6);
3774     kernel_.setArg(6,a7);
3775     kernel_.setArg(7,a8);
3776     kernel_.setArg(8,a9);
3777     kernel_.setArg(9,a10);
3778     kernel_.setArg(10,a11);
3779     kernel_.setArg(11,a12);
3780 
3781     err_ = queue_.enqueueNDRangeKernel(
3782         kernel_,
3783         offset_,
3784         global_,
3785         local_,
3786         NULL,    // bgaster_fixme - do we want to allow wait event lists?
3787         &event);
3788 
3789     return event;
3790 }
3791 
3792 template<class A1, class A2, class A3, class A4, class A5,
3793          class A6, class A7, class A8, class A9, class A10,
3794          class A11, class A12, class A13>
operator ()(const A1 & a1,const A2 & a2,const A3 & a3,const A4 & a4,const A5 & a5,const A6 & a6,const A7 & a7,const A8 & a8,const A9 & a9,const A10 & a10,const A11 & a11,const A12 & a12,const A13 & a13,const VECTOR_CLASS<Event> * events)3795 Event KernelFunctor::operator()(
3796     const A1& a1,
3797     const A2& a2,
3798     const A3& a3,
3799     const A4& a4,
3800     const A5& a5,
3801     const A6& a6,
3802     const A7& a7,
3803     const A8& a8,
3804     const A9& a9,
3805     const A10& a10,
3806     const A11& a11,
3807     const A12& a12,
3808     const A13& a13,
3809     const VECTOR_CLASS<Event>* events)
3810 {
3811     Event event;
3812 
3813     kernel_.setArg(0,a1);
3814     kernel_.setArg(1,a2);
3815     kernel_.setArg(2,a3);
3816     kernel_.setArg(3,a4);
3817     kernel_.setArg(4,a5);
3818     kernel_.setArg(5,a6);
3819     kernel_.setArg(6,a7);
3820     kernel_.setArg(7,a8);
3821     kernel_.setArg(8,a9);
3822     kernel_.setArg(9,a10);
3823     kernel_.setArg(10,a11);
3824     kernel_.setArg(11,a12);
3825     kernel_.setArg(12,a13);
3826 
3827     err_ = queue_.enqueueNDRangeKernel(
3828         kernel_,
3829         offset_,
3830         global_,
3831         local_,
3832         NULL,    // bgaster_fixme - do we want to allow wait event lists?
3833         &event);
3834 
3835     return event;
3836 }
3837 
3838 template<class A1, class A2, class A3, class A4, class A5,
3839          class A6, class A7, class A8, class A9, class A10,
3840          class A11, class A12, class A13, class A14>
operator ()(const A1 & a1,const A2 & a2,const A3 & a3,const A4 & a4,const A5 & a5,const A6 & a6,const A7 & a7,const A8 & a8,const A9 & a9,const A10 & a10,const A11 & a11,const A12 & a12,const A13 & a13,const A14 & a14,const VECTOR_CLASS<Event> * events)3841 Event KernelFunctor::operator()(
3842     const A1& a1,
3843     const A2& a2,
3844     const A3& a3,
3845     const A4& a4,
3846     const A5& a5,
3847     const A6& a6,
3848     const A7& a7,
3849     const A8& a8,
3850     const A9& a9,
3851     const A10& a10,
3852     const A11& a11,
3853     const A12& a12,
3854     const A13& a13,
3855     const A14& a14,
3856     const VECTOR_CLASS<Event>* events)
3857 {
3858     Event event;
3859 
3860     kernel_.setArg(0,a1);
3861     kernel_.setArg(1,a2);
3862     kernel_.setArg(2,a3);
3863     kernel_.setArg(3,a4);
3864     kernel_.setArg(4,a5);
3865     kernel_.setArg(5,a6);
3866     kernel_.setArg(6,a7);
3867     kernel_.setArg(7,a8);
3868     kernel_.setArg(8,a9);
3869     kernel_.setArg(9,a10);
3870     kernel_.setArg(10,a11);
3871     kernel_.setArg(11,a12);
3872     kernel_.setArg(12,a13);
3873     kernel_.setArg(13,a14);
3874 
3875     err_ = queue_.enqueueNDRangeKernel(
3876         kernel_,
3877         offset_,
3878         global_,
3879         local_,
3880         NULL,    // bgaster_fixme - do we want to allow wait event lists?
3881         &event);
3882 
3883     return event;
3884 }
3885 
3886 template<class A1, class A2, class A3, class A4, class A5,
3887          class A6, class A7, class A8, class A9, class A10,
3888          class A11, class A12, class A13, class A14, class A15>
operator ()(const A1 & a1,const A2 & a2,const A3 & a3,const A4 & a4,const A5 & a5,const A6 & a6,const A7 & a7,const A8 & a8,const A9 & a9,const A10 & a10,const A11 & a11,const A12 & a12,const A13 & a13,const A14 & a14,const A15 & a15,const VECTOR_CLASS<Event> * events)3889 Event KernelFunctor::operator()(
3890     const A1& a1,
3891     const A2& a2,
3892     const A3& a3,
3893     const A4& a4,
3894     const A5& a5,
3895     const A6& a6,
3896     const A7& a7,
3897     const A8& a8,
3898     const A9& a9,
3899     const A10& a10,
3900     const A11& a11,
3901     const A12& a12,
3902     const A13& a13,
3903     const A14& a14,
3904     const A15& a15,
3905     const VECTOR_CLASS<Event>* events)
3906 {
3907     Event event;
3908 
3909     kernel_.setArg(0,a1);
3910     kernel_.setArg(1,a2);
3911     kernel_.setArg(2,a3);
3912     kernel_.setArg(3,a4);
3913     kernel_.setArg(4,a5);
3914     kernel_.setArg(5,a6);
3915     kernel_.setArg(6,a7);
3916     kernel_.setArg(7,a8);
3917     kernel_.setArg(8,a9);
3918     kernel_.setArg(9,a10);
3919     kernel_.setArg(10,a11);
3920     kernel_.setArg(11,a12);
3921     kernel_.setArg(12,a13);
3922     kernel_.setArg(13,a14);
3923     kernel_.setArg(14,a15);
3924 
3925     err_ = queue_.enqueueNDRangeKernel(
3926         kernel_,
3927         offset_,
3928         global_,
3929         local_,
3930         NULL,    // bgaster_fixme - do we want to allow wait event lists?
3931         &event);
3932 
3933     return event;
3934 }
3935 
3936 #undef __ERR_STR
3937 #if !defined(__CL_USER_OVERRIDE_ERROR_STRINGS)
3938 #undef __GET_DEVICE_INFO_ERR
3939 #undef __GET_PLATFORM_INFO_ERR
3940 #undef __GET_DEVICE_IDS_ERR
3941 #undef __GET_CONTEXT_INFO_ERR
3942 #undef __GET_EVENT_INFO_ERR
3943 #undef __GET_EVENT_PROFILE_INFO_ERR
3944 #undef __GET_MEM_OBJECT_INFO_ERR
3945 #undef __GET_IMAGE_INFO_ERR
3946 #undef __GET_SAMPLER_INFO_ERR
3947 #undef __GET_KERNEL_INFO_ERR
3948 #undef __GET_KERNEL_WORK_GROUP_INFO_ERR
3949 #undef __GET_PROGRAM_INFO_ERR
3950 #undef __GET_PROGRAM_BUILD_INFO_ERR
3951 #undef __GET_COMMAND_QUEUE_INFO_ERR
3952 
3953 #undef __CREATE_CONTEXT_FROM_TYPE_ERR
3954 #undef __GET_SUPPORTED_IMAGE_FORMATS_ERR
3955 
3956 #undef __CREATE_BUFFER_ERR
3957 #undef __CREATE_SUBBUFFER_ERR
3958 #undef __CREATE_IMAGE2D_ERR
3959 #undef __CREATE_IMAGE3D_ERR
3960 #undef __CREATE_SAMPLER_ERR
3961 #undef __SET_MEM_OBJECT_DESTRUCTOR_CALLBACK_ERR
3962 
3963 #undef __CREATE_USER_EVENT_ERR
3964 #undef __SET_USER_EVENT_STATUS_ERR
3965 #undef __SET_EVENT_CALLBACK_ERR
3966 
3967 #undef __WAIT_FOR_EVENTS_ERR
3968 
3969 #undef __CREATE_KERNEL_ERR
3970 #undef __SET_KERNEL_ARGS_ERR
3971 #undef __CREATE_PROGRAM_WITH_SOURCE_ERR
3972 #undef __CREATE_PROGRAM_WITH_BINARY_ERR
3973 #undef __BUILD_PROGRAM_ERR
3974 #undef __CREATE_KERNELS_IN_PROGRAM_ERR
3975 
3976 #undef __CREATE_COMMAND_QUEUE_ERR
3977 #undef __SET_COMMAND_QUEUE_PROPERTY_ERR
3978 #undef __ENQUEUE_READ_BUFFER_ERR
3979 #undef __ENQUEUE_WRITE_BUFFER_ERR
3980 #undef __ENQUEUE_READ_BUFFER_RECT_ERR
3981 #undef __ENQUEUE_WRITE_BUFFER_RECT_ERR
3982 #undef __ENQEUE_COPY_BUFFER_ERR
3983 #undef __ENQEUE_COPY_BUFFER_RECT_ERR
3984 #undef __ENQUEUE_READ_IMAGE_ERR
3985 #undef __ENQUEUE_WRITE_IMAGE_ERR
3986 #undef __ENQUEUE_COPY_IMAGE_ERR
3987 #undef __ENQUEUE_COPY_IMAGE_TO_BUFFER_ERR
3988 #undef __ENQUEUE_COPY_BUFFER_TO_IMAGE_ERR
3989 #undef __ENQUEUE_MAP_BUFFER_ERR
3990 #undef __ENQUEUE_MAP_IMAGE_ERR
3991 #undef __ENQUEUE_UNMAP_MEM_OBJECT_ERR
3992 #undef __ENQUEUE_NDRANGE_KERNEL_ERR
3993 #undef __ENQUEUE_TASK_ERR
3994 #undef __ENQUEUE_NATIVE_KERNEL
3995 
3996 #undef __UNLOAD_COMPILER_ERR
3997 #endif //__CL_USER_OVERRIDE_ERROR_STRINGS
3998 
3999 #undef __GET_INFO_HELPER_WITH_RETAIN
4000 
4001 // Extensions
4002 #undef __INIT_CL_EXT_FCN_PTR
4003 #undef __CREATE_SUB_DEVICES
4004 
4005 #if defined(USE_CL_DEVICE_FISSION)
4006 #undef __PARAM_NAME_DEVICE_FISSION
4007 #endif // USE_CL_DEVICE_FISSION
4008 
4009 } // namespace cl
4010 
4011 #endif // CL_HPP_
4012