Upstream version 11.39.266.0
[platform/framework/web/crosswalk.git] / src / third_party / mesa / src / include / CL / cl.hpp
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      */
219     Error(cl_int err, const char * errStr = NULL) : err_(err), errStr_(errStr)
220     {}
221
222     ~Error() throw() {}
223
224     /*! \brief Get error string associated with exception
225      *
226      * \return A memory pointer to the error message string.
227      */
228     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      */
242     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:
337     string(void) : size_(0), str_(NULL)
338     {
339     }
340
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
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
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
392     string(const string& rhs)
393     {
394         *this = rhs;
395     }
396
397     ~string()
398     {
399         if (str_ != NULL) {
400             delete[] str_;
401         }
402     }
403
404     ::size_t size(void) const   { return size_; }
405     ::size_t length(void) const { return size(); }
406
407     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:
440     vector() : 
441         size_(-1),
442         empty_(true)
443     {}
444
445     ~vector() {}
446
447     unsigned int size(void) const
448     {
449         return size_ + 1;
450     }
451
452     void clear()
453     {
454         size_ = -1;
455         empty_ = true;
456     }
457
458     void push_back (const T& x)
459     { 
460         if (size() < N) {
461             size_++;  
462             data_[size_] = x;
463             empty_ = false;
464         }
465     }
466
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   
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
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
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
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   
525     operator T* ()             { return data_; }
526     operator const T* () const { return data_; }
527    
528     bool empty (void) const
529     {
530         return empty_;
531     }
532   
533     unsigned int max_size (void) const
534     {
535         return N;
536     }
537
538     unsigned int capacity () const
539     {
540         return sizeof(T) * N;
541     }
542
543     T& operator[](int index)
544     {
545         return data_[index];
546     }
547   
548     T operator[](int index) const
549     {
550         return data_[index];
551     }
552   
553     template<class I>
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:
573         iterator(void) : 
574             index_(-1),
575             initialized_(false)
576         {
577             index_ = -1;
578             initialized_ = false;
579         }
580
581         ~iterator(void) {}
582
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
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     
608         bool operator==(iterator i)
609         {
610             return ((vec_ == i.vec_) && 
611                     (index_ == i.index_) && 
612                     (initialized_ == i.initialized_));
613         }
614
615         bool operator!=(iterator i)
616         {
617             return (!(*this==i));
618         }
619
620         void operator++()
621         {
622             index_++;
623         }
624
625         void operator++(int x)
626         {
627             index_ += x;
628         }
629
630         void operator--()
631         {
632             index_--;
633         }
634
635         void operator--(int x)
636         {
637             index_ -= x;
638         }
639
640         T operator *()
641         {
642             return vec_[index_];
643         }
644     };
645
646     iterator begin(void)
647     {
648         return iterator::begin(*this);
649     }
650
651     iterator end(void)
652     {
653         return iterator::end(*this);
654     }
655
656     T& front(void)
657     {
658         return data_[0];
659     }
660
661     T& back(void)
662     {
663         return data_[size_];
664     }
665
666     const T& front(void) const
667     {
668         return data_[0];
669     }
670
671     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
692     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 {
702     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
726     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 {
741     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
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_;
968     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_;
977     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
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
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().
1008     static cl_int retain(cl_device_id)
1009     { return CL_INVALID_DEVICE; }
1010     // cl_device_id does not have release().
1011     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().
1019     static cl_int retain(cl_platform_id)
1020     { return CL_INVALID_PLATFORM; }
1021     // cl_platform_id does not have release().
1022     static cl_int release(cl_platform_id)
1023     { return CL_INVALID_PLATFORM; }
1024 };
1025
1026 template <>
1027 struct ReferenceHandler<cl_context>
1028 {
1029     static cl_int retain(cl_context context)
1030     { return ::clRetainContext(context); }
1031     static cl_int release(cl_context context)
1032     { return ::clReleaseContext(context); }
1033 };
1034
1035 template <>
1036 struct ReferenceHandler<cl_command_queue>
1037 {
1038     static cl_int retain(cl_command_queue queue)
1039     { return ::clRetainCommandQueue(queue); }
1040     static cl_int release(cl_command_queue queue)
1041     { return ::clReleaseCommandQueue(queue); }
1042 };
1043
1044 template <>
1045 struct ReferenceHandler<cl_mem>
1046 {
1047     static cl_int retain(cl_mem memory)
1048     { return ::clRetainMemObject(memory); }
1049     static cl_int release(cl_mem memory)
1050     { return ::clReleaseMemObject(memory); }
1051 };
1052
1053 template <>
1054 struct ReferenceHandler<cl_sampler>
1055 {
1056     static cl_int retain(cl_sampler sampler)
1057     { return ::clRetainSampler(sampler); }
1058     static cl_int release(cl_sampler sampler)
1059     { return ::clReleaseSampler(sampler); }
1060 };
1061
1062 template <>
1063 struct ReferenceHandler<cl_program>
1064 {
1065     static cl_int retain(cl_program program)
1066     { return ::clRetainProgram(program); }
1067     static cl_int release(cl_program program)
1068     { return ::clReleaseProgram(program); }
1069 };
1070
1071 template <>
1072 struct ReferenceHandler<cl_kernel>
1073 {
1074     static cl_int retain(cl_kernel kernel)
1075     { return ::clRetainKernel(kernel); }
1076     static cl_int release(cl_kernel kernel)
1077     { return ::clReleaseKernel(kernel); }
1078 };
1079
1080 template <>
1081 struct ReferenceHandler<cl_event>
1082 {
1083     static cl_int retain(cl_event event)
1084     { return ::clRetainEvent(event); }
1085     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:
1099     Wrapper() : object_(NULL) { }
1100
1101     ~Wrapper()
1102     {
1103         if (object_ != NULL) { release(); }
1104     }
1105
1106     Wrapper(const Wrapper<cl_type>& rhs)
1107     {
1108         object_ = rhs.object_;
1109         if (object_ != NULL) { retain(); }
1110     }
1111
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
1120     cl_type operator ()() const { return object_; }
1121
1122     cl_type& operator ()() { return object_; }
1123
1124 protected:
1125
1126     cl_int retain() const
1127     {
1128         return ReferenceHandler<cl_type>::retain(object_);
1129     }
1130
1131     cl_int release() const
1132     {
1133         return ReferenceHandler<cl_type>::release(object_);
1134     }
1135 };
1136
1137 #if defined(__CL_ENABLE_EXCEPTIONS)
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
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 {
1162     ImageFormat(){}
1163
1164     ImageFormat(cl_channel_order order, cl_channel_type type)
1165     {
1166         image_channel_order = order;
1167         image_channel_data_type = type;
1168     }
1169
1170     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:
1186     Device(cl_device_id device) { object_ = device; }
1187
1188     Device() : detail::Wrapper<cl_type>() { }
1189
1190     Device(const Device& device) : detail::Wrapper<cl_type>(device) { }
1191
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>
1201     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
1210     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)
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
1263     Platform(cl_platform_id platform) { object_ = platform; }
1264
1265     Platform() : detail::Wrapper<cl_type>()  { }
1266
1267     Platform(const Platform& platform) : detail::Wrapper<cl_type>(platform) { }
1268
1269     Platform& operator = (const Platform& rhs)
1270     {
1271         if (this != &rhs) {
1272             detail::Wrapper<cl_type>::operator=(rhs);
1273         }
1274         return *this;
1275     }
1276
1277     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
1286     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
1297     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      */
1341     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
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
1412 UnloadCompiler()
1413 {
1414     return ::clUnloadCompiler();
1415 }
1416
1417 class Context : public detail::Wrapper<cl_context>
1418 {
1419 public:
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
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
1464     Context() : detail::Wrapper<cl_type>() { }
1465
1466     Context(const Context& context) : detail::Wrapper<cl_type>(context) { }
1467
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>
1477     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
1486     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
1497     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:
1540     Event() : detail::Wrapper<cl_type>() { }
1541
1542     Event(const Event& event) : detail::Wrapper<cl_type>(event) { }
1543
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>
1553     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
1562     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>
1574     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
1583     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
1594     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)
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
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:
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
1651     UserEvent() : Event() { }
1652
1653     UserEvent(const UserEvent& event) : Event(event) { }
1654
1655     UserEvent& operator = (const UserEvent& rhs)
1656     {
1657         if (this != &rhs) {
1658             Event::operator=(rhs);
1659         }
1660         return *this;
1661     }
1662
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
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:
1687     Memory() : detail::Wrapper<cl_type>() { }
1688
1689     Memory(const Memory& memory) : detail::Wrapper<cl_type>(memory) { }
1690
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>
1700     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
1709     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)
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:
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
1760     Buffer() : Memory() { }
1761
1762     Buffer(const Buffer& buffer) : Memory(buffer) { }
1763
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)
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
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
1828     BufferD3D10() : Buffer() { }
1829
1830     BufferD3D10(const BufferD3D10& buffer) : Buffer(buffer) { }
1831
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:
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
1867     BufferGL() : Buffer() { }
1868
1869     BufferGL(const BufferGL& buffer) : Buffer(buffer) { }
1870
1871     BufferGL& operator = (const BufferGL& rhs)
1872     {
1873         if (this != &rhs) {
1874             Buffer::operator=(rhs);
1875         }
1876         return *this;
1877     }
1878
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:
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
1914     BufferRenderGL() : Buffer() { }
1915
1916     BufferRenderGL(const BufferGL& buffer) : Buffer(buffer) { }
1917
1918     BufferRenderGL& operator = (const BufferRenderGL& rhs)
1919     {
1920         if (this != &rhs) {
1921             Buffer::operator=(rhs);
1922         }
1923         return *this;
1924     }
1925
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:
1942     Image() : Memory() { }
1943
1944     Image(const Image& image) : Memory(image) { }
1945
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>
1955     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
1964     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:
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
2002     Image2D() { }
2003
2004     Image2D(const Image2D& image2D) : Image(image2D) { }
2005
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:
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
2044     Image2DGL() : Image2D() { }
2045
2046     Image2DGL(const Image2DGL& image) : Image2D(image) { }
2047
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:
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
2086     Image3D() { }
2087
2088     Image3D(const Image3D& image3D) : Image(image3D) { }
2089
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:
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
2128     Image3DGL() : Image3D() { }
2129
2130     Image3DGL(const Image3DGL& image) : Image3D(image) { }
2131
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:
2147     Sampler() { }
2148
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
2170     Sampler(const Sampler& sampler) : detail::Wrapper<cl_type>(sampler) { }
2171
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>
2181     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
2190     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:
2218     NDRange()
2219         : dimensions_(0)
2220     { }
2221
2222     NDRange(::size_t size0)
2223         : dimensions_(1)
2224     {
2225         sizes_.push_back(size0);
2226     }
2227
2228     NDRange(::size_t size0, ::size_t size1)
2229         : dimensions_(2)
2230     {
2231         sizes_.push_back(size0);
2232         sizes_.push_back(size1);
2233     }
2234
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
2243     operator const ::size_t*() const { return (const ::size_t*) sizes_; }
2244     ::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 {
2263     static ::size_t size(const T&) { return sizeof(T); }
2264     static T* ptr(T& value) { return &value; }
2265 };
2266
2267 template <>
2268 struct KernelArgumentHandler<LocalSpaceArg>
2269 {
2270     static ::size_t size(const LocalSpaceArg& value) { return value.size_; }
2271     static void* ptr(LocalSpaceArg&) { return NULL; }
2272 };
2273
2274
2275 //! \endcond
2276
2277 inline LocalSpaceArg
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
2294     Kernel() { }
2295
2296     Kernel(const Kernel& kernel) : detail::Wrapper<cl_type>(kernel) { }
2297
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>
2307     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
2316     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>
2328     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
2339         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>
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
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
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
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
2447     Program() { }
2448
2449     Program(const Program& program) : detail::Wrapper<cl_type>(program) { }
2450
2451     Program& operator = (const Program& rhs)
2452     {
2453         if (this != &rhs) {
2454             detail::Wrapper<cl_type>::operator=(rhs);
2455         }
2456         return *this;
2457     }
2458
2459     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>
2478     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
2487     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>
2499     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
2510     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
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
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:
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
2578     CommandQueue() { }
2579
2580     CommandQueue(const CommandQueue& commandQueue) : detail::Wrapper<cl_type>(commandQueue) { }
2581
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>
2591     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
2601     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
2612     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
2631     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
2650     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)
2669     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
2703     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
2736     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
2768     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
2789     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
2810     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
2829     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
2848     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
2867     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
2892     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
2921     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
2936     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
2956     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
2970     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
3000     cl_int enqueueMarker(Event* event = NULL) const
3001     {
3002         return detail::errHandler(
3003             ::clEnqueueMarker(object_, (cl_event*) event),
3004             __ENQUEUE_MARKER_ERR);
3005     }
3006
3007     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
3017     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
3033     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
3059     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
3078     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
3098     cl_int enqueueBarrier() const
3099     {
3100         return detail::errHandler(
3101             ::clEnqueueBarrier(object_),
3102             __ENQUEUE_BARRIER_ERR);
3103     }
3104
3105     cl_int flush() const
3106     {
3107         return detail::errHandler(::clFlush(object_), __FLUSH_ERR);
3108     }
3109
3110     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:
3136     KernelFunctor() { }
3137
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
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
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
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
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
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
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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_