Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-05 08:18:32

0001 /*******************************************************************************
0002  * Copyright (c) 2008-2010 The Khronos Group Inc.
0003  *
0004  * Permission is hereby granted, free of charge, to any person obtaining a
0005  * copy of this software and/or associated documentation files (the
0006  * "Materials"), to deal in the Materials without restriction, including
0007  * without limitation the rights to use, copy, modify, merge, publish,
0008  * distribute, sublicense, and/or sell copies of the Materials, and to
0009  * permit persons to whom the Materials are furnished to do so, subject to
0010  * the following conditions:
0011  *
0012  * The above copyright notice and this permission notice shall be included
0013  * in all copies or substantial portions of the Materials.
0014  *
0015  * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
0016  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
0017  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
0018  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
0019  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
0020  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
0021  * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
0022  ******************************************************************************/
0023 
0024 /*! \file
0025  *
0026  *   \brief C++ bindings for OpenCL 1.0 (rev 48) and OpenCL 1.1 (rev 33)    
0027  *   \author Benedict R. Gaster and Laurent Morichetti
0028  *   
0029  *   Additions and fixes from Brian Cole, March 3rd 2010.
0030  *   
0031  *   \version 1.1
0032  *   \date June 2010
0033  *
0034  *   Optional extension support
0035  *
0036  *         cl
0037  *         cl_ext_device_fission
0038  *              #define USE_CL_DEVICE_FISSION
0039  */
0040 
0041 /*! \mainpage
0042  * \section intro Introduction
0043  * For many large applications C++ is the language of choice and so it seems
0044  * reasonable to define C++ bindings for OpenCL.
0045  *
0046  *
0047  * The interface is contained with a single C++ header file \em cl.hpp and all
0048  * definitions are contained within the namespace \em cl. There is no additional
0049  * requirement to include \em cl.h and to use either the C++ or original C
0050  * bindings it is enough to simply include \em cl.hpp.
0051  *
0052  * The bindings themselves are lightweight and correspond closely to the
0053  * underlying C API. Using the C++ bindings introduces no additional execution
0054  * overhead.
0055  *
0056  * For detail documentation on the bindings see:
0057  *
0058  * The OpenCL C++ Wrapper API 1.1 (revision 04)
0059  *  http://www.khronos.org/registry/cl/specs/opencl-cplusplus-1.1.pdf
0060  *
0061  * \section example Example
0062  *
0063  * The following example shows a general use case for the C++
0064  * bindings, including support for the optional exception feature and
0065  * also the supplied vector and string classes, see following sections for
0066  * decriptions of these features.
0067  *
0068  * \code
0069  * #define __CL_ENABLE_EXCEPTIONS
0070  * 
0071  * #if defined(__APPLE__) || defined(__MACOSX)
0072  * #include <OpenCL/cl.hpp>
0073  * #else
0074  * #include <CL/cl.hpp>
0075  * #endif
0076  * #include <cstdio>
0077  * #include <cstdlib>
0078  * #include <iostream>
0079  * 
0080  *  const char * helloStr  = "__kernel void "
0081  *                           "hello(void) "
0082  *                           "{ "
0083  *                           "  "
0084  *                           "} ";
0085  * 
0086  *  int
0087  *  main(void)
0088  *  {
0089  *     cl_int err = CL_SUCCESS;
0090  *     try {
0091  *
0092  *       std::vector<cl::Platform> platforms;
0093  *       cl::Platform::get(&platforms);
0094  *       if (platforms.size() == 0) {
0095  *           std::cout << "Platform size 0\n";
0096  *           return -1;
0097  *       }
0098  *
0099  *       cl_context_properties properties[] = 
0100  *          { CL_CONTEXT_PLATFORM, (cl_context_properties)(platforms[0])(), 0};
0101  *       cl::Context context(CL_DEVICE_TYPE_CPU, properties); 
0102  * 
0103  *       std::vector<cl::Device> devices = context.getInfo<CL_CONTEXT_DEVICES>();
0104  * 
0105  *       cl::Program::Sources source(1,
0106  *           std::make_pair(helloStr,strlen(helloStr)));
0107  *       cl::Program program_ = cl::Program(context, source);
0108  *       program_.build(devices);
0109  * 
0110  *       cl::Kernel kernel(program_, "hello", &err);
0111  * 
0112  *       cl::Event event;
0113  *       cl::CommandQueue queue(context, devices[0], 0, &err);
0114  *       queue.enqueueNDRangeKernel(
0115  *           kernel, 
0116  *           cl::NullRange, 
0117  *           cl::NDRange(4,4),
0118  *           cl::NullRange,
0119  *           NULL,
0120  *           &event); 
0121  * 
0122  *       event.wait();
0123  *     }
0124  *     catch (cl::Error err) {
0125  *        std::cerr 
0126  *           << "ERROR: "
0127  *           << err.what()
0128  *           << "("
0129  *           << err.err()
0130  *           << ")"
0131  *           << std::endl;
0132  *     }
0133  * 
0134  *    return EXIT_SUCCESS;
0135  *  }
0136  * 
0137  * \endcode
0138  *
0139  */
0140 #ifndef CL_HPP_
0141 #define CL_HPP_
0142 
0143 #ifdef _WIN32
0144 #include <windows.h>
0145 #include <malloc.h>
0146 #if defined(USE_DX_INTEROP)
0147 #include <CL/cl_d3d10.h>
0148 #endif
0149 #endif // _WIN32
0150 
0151 // 
0152 #if defined(USE_CL_DEVICE_FISSION)
0153 #include <CL/cl_ext.h>
0154 #endif
0155 
0156 #if defined(__APPLE__) || defined(__MACOSX)
0157 #include <OpenGL/OpenGL.h>
0158 #include <OpenCL/opencl.h>
0159 #else
0160 #include <GL/gl.h>
0161 #include <CL/opencl.h>
0162 #endif // !__APPLE__
0163 
0164 #if !defined(CL_CALLBACK)
0165 #define CL_CALLBACK
0166 #endif //CL_CALLBACK
0167 
0168 #include <utility>
0169 
0170 #if !defined(__NO_STD_VECTOR)
0171 #include <vector>
0172 #endif
0173 
0174 #if !defined(__NO_STD_STRING)
0175 #include <string>
0176 #endif 
0177 
0178 #if defined(linux) || defined(__APPLE__) || defined(__MACOSX)
0179 # include <alloca.h>
0180 #endif // linux
0181 
0182 #include <cstring>
0183 
0184 /*! \namespace cl
0185  *
0186  * \brief The OpenCL C++ bindings are defined within this namespace.
0187  *
0188  */
0189 namespace cl {
0190 
0191 #define __INIT_CL_EXT_FCN_PTR(name) \
0192     if(!pfn_##name) { \
0193         pfn_##name = (PFN_##name) \
0194             clGetExtensionFunctionAddress(#name); \
0195         if(!pfn_##name) { \
0196         } \
0197     }
0198 
0199 class Program;
0200 class Device;
0201 class Context;
0202 class CommandQueue;
0203 class Memory;
0204 
0205 #if defined(__CL_ENABLE_EXCEPTIONS)
0206 #include <exception>
0207 /*! \class Error
0208  * \brief Exception class
0209  */
0210 class Error : public std::exception
0211 {
0212 private:
0213     cl_int err_;
0214     const char * errStr_;
0215 public:
0216     /*! Create a new CL error exception for a given error code
0217      *  and corresponding message.
0218      */
0219     Error(cl_int err, const char * errStr = NULL) : err_(err), errStr_(errStr)
0220     {}
0221 
0222     ~Error() throw() {}
0223 
0224     /*! \brief Get error string associated with exception
0225      *
0226      * \return A memory pointer to the error message string.
0227      */
0228     virtual const char * what() const throw ()
0229     {
0230         if (errStr_ == NULL) {
0231             return "empty";
0232         }
0233         else {
0234             return errStr_;
0235         }
0236     }
0237 
0238     /*! \brief Get error code associated with exception
0239      *
0240      *  \return The error code.
0241      */
0242     const cl_int err(void) const { return err_; }
0243 };
0244 
0245 #define __ERR_STR(x) #x
0246 #else
0247 #define __ERR_STR(x) NULL
0248 #endif // __CL_ENABLE_EXCEPTIONS
0249 
0250 //! \cond DOXYGEN_DETAIL
0251 #if !defined(__CL_USER_OVERRIDE_ERROR_STRINGS)
0252 #define __GET_DEVICE_INFO_ERR               __ERR_STR(clgetDeviceInfo)
0253 #define __GET_PLATFORM_INFO_ERR             __ERR_STR(clGetPlatformInfo)
0254 #define __GET_DEVICE_IDS_ERR                __ERR_STR(clGetDeviceIDs)
0255 #define __GET_PLATFORM_IDS_ERR              __ERR_STR(clGetPlatformIDs)
0256 #define __GET_CONTEXT_INFO_ERR              __ERR_STR(clGetContextInfo)
0257 #define __GET_EVENT_INFO_ERR                __ERR_STR(clGetEventInfo)
0258 #define __GET_EVENT_PROFILE_INFO_ERR        __ERR_STR(clGetEventProfileInfo)
0259 #define __GET_MEM_OBJECT_INFO_ERR           __ERR_STR(clGetMemObjectInfo)
0260 #define __GET_IMAGE_INFO_ERR                __ERR_STR(clGetImageInfo)
0261 #define __GET_SAMPLER_INFO_ERR              __ERR_STR(clGetSamplerInfo)
0262 #define __GET_KERNEL_INFO_ERR               __ERR_STR(clGetKernelInfo)
0263 #define __GET_KERNEL_WORK_GROUP_INFO_ERR    __ERR_STR(clGetKernelWorkGroupInfo)
0264 #define __GET_PROGRAM_INFO_ERR              __ERR_STR(clGetProgramInfo)
0265 #define __GET_PROGRAM_BUILD_INFO_ERR        __ERR_STR(clGetProgramBuildInfo)
0266 #define __GET_COMMAND_QUEUE_INFO_ERR        __ERR_STR(clGetCommandQueueInfo)
0267 
0268 #define __CREATE_CONTEXT_FROM_TYPE_ERR      __ERR_STR(clCreateContextFromType)
0269 #define __GET_SUPPORTED_IMAGE_FORMATS_ERR   __ERR_STR(clGetSupportedImageFormats)
0270 
0271 #define __CREATE_BUFFER_ERR                 __ERR_STR(clCreateBuffer)
0272 #define __CREATE_SUBBUFFER_ERR              __ERR_STR(clCreateSubBuffer)
0273 #define __CREATE_GL_BUFFER_ERR              __ERR_STR(clCreateFromGLBuffer)
0274 #define __GET_GL_OBJECT_INFO_ERR            __ERR_STR(clGetGLObjectInfo)
0275 #define __CREATE_IMAGE2D_ERR                __ERR_STR(clCreateImage2D)
0276 #define __CREATE_IMAGE3D_ERR                __ERR_STR(clCreateImage3D)
0277 #define __CREATE_SAMPLER_ERR                __ERR_STR(clCreateSampler)
0278 #define __SET_MEM_OBJECT_DESTRUCTOR_CALLBACK_ERR __ERR_STR(clSetMemObjectDestructorCallback)
0279 
0280 #define __CREATE_USER_EVENT_ERR             __ERR_STR(clCreateUserEvent)
0281 #define __SET_USER_EVENT_STATUS_ERR         __ERR_STR(clSetUserEventStatus)
0282 #define __SET_EVENT_CALLBACK_ERR            __ERR_STR(clSetEventCallback)
0283 #define __WAIT_FOR_EVENTS_ERR               __ERR_STR(clWaitForEvents)
0284 
0285 #define __CREATE_KERNEL_ERR                 __ERR_STR(clCreateKernel)
0286 #define __SET_KERNEL_ARGS_ERR               __ERR_STR(clSetKernelArg)
0287 #define __CREATE_PROGRAM_WITH_SOURCE_ERR    __ERR_STR(clCreateProgramWithSource)
0288 #define __CREATE_PROGRAM_WITH_BINARY_ERR    __ERR_STR(clCreateProgramWithBinary)
0289 #define __BUILD_PROGRAM_ERR                 __ERR_STR(clBuildProgram)
0290 #define __CREATE_KERNELS_IN_PROGRAM_ERR     __ERR_STR(clCreateKernelsInProgram)
0291 
0292 #define __CREATE_COMMAND_QUEUE_ERR          __ERR_STR(clCreateCommandQueue)
0293 #define __SET_COMMAND_QUEUE_PROPERTY_ERR    __ERR_STR(clSetCommandQueueProperty)
0294 #define __ENQUEUE_READ_BUFFER_ERR           __ERR_STR(clEnqueueReadBuffer)
0295 #define __ENQUEUE_READ_BUFFER_RECT_ERR      __ERR_STR(clEnqueueReadBufferRect)
0296 #define __ENQUEUE_WRITE_BUFFER_ERR          __ERR_STR(clEnqueueWriteBuffer)
0297 #define __ENQUEUE_WRITE_BUFFER_RECT_ERR     __ERR_STR(clEnqueueWriteBufferRect)
0298 #define __ENQEUE_COPY_BUFFER_ERR            __ERR_STR(clEnqueueCopyBuffer)
0299 #define __ENQEUE_COPY_BUFFER_RECT_ERR       __ERR_STR(clEnqueueCopyBufferRect)
0300 #define __ENQUEUE_READ_IMAGE_ERR            __ERR_STR(clEnqueueReadImage)
0301 #define __ENQUEUE_WRITE_IMAGE_ERR           __ERR_STR(clEnqueueWriteImage)
0302 #define __ENQUEUE_COPY_IMAGE_ERR            __ERR_STR(clEnqueueCopyImage)
0303 #define __ENQUEUE_COPY_IMAGE_TO_BUFFER_ERR  __ERR_STR(clEnqueueCopyImageToBuffer)
0304 #define __ENQUEUE_COPY_BUFFER_TO_IMAGE_ERR  __ERR_STR(clEnqueueCopyBufferToImage)
0305 #define __ENQUEUE_MAP_BUFFER_ERR            __ERR_STR(clEnqueueMapBuffer)
0306 #define __ENQUEUE_MAP_IMAGE_ERR             __ERR_STR(clEnqueueMapImage)
0307 #define __ENQUEUE_UNMAP_MEM_OBJECT_ERR      __ERR_STR(clEnqueueUnMapMemObject)
0308 #define __ENQUEUE_NDRANGE_KERNEL_ERR        __ERR_STR(clEnqueueNDRangeKernel)
0309 #define __ENQUEUE_TASK_ERR                  __ERR_STR(clEnqueueTask)
0310 #define __ENQUEUE_NATIVE_KERNEL             __ERR_STR(clEnqueueNativeKernel)
0311 #define __ENQUEUE_MARKER_ERR                __ERR_STR(clEnqueueMarker)
0312 #define __ENQUEUE_WAIT_FOR_EVENTS_ERR       __ERR_STR(clEnqueueWaitForEvents)
0313 #define __ENQUEUE_BARRIER_ERR               __ERR_STR(clEnqueueBarrier)
0314 
0315 #define __ENQUEUE_ACQUIRE_GL_ERR            __ERR_STR(clEnqueueAcquireGLObjects)
0316 #define __ENQUEUE_RELEASE_GL_ERR            __ERR_STR(clEnqueueReleaseGLObjects)
0317 
0318 #define __UNLOAD_COMPILER_ERR               __ERR_STR(clUnloadCompiler)
0319 
0320 #define __FLUSH_ERR                         __ERR_STR(clFlush)
0321 #define __FINISH_ERR                        __ERR_STR(clFinish)
0322 
0323 #define __CREATE_SUB_DEVICES                __ERR_STR(clCreateSubDevicesEXT)
0324 #endif // __CL_USER_OVERRIDE_ERROR_STRINGS
0325 //! \endcond
0326 
0327 /*! \class string
0328  * \brief Simple string class, that provides a limited subset of std::string
0329  * functionality but avoids many of the issues that come with that class.
0330  */
0331 class string
0332 {
0333 private:
0334     ::size_t size_;
0335     char * str_;
0336 public:
0337     string(void) : size_(0), str_(NULL)
0338     {
0339     }
0340 
0341     string(char * str, ::size_t size) :
0342         size_(size),
0343         str_(NULL)
0344     {
0345         str_ = new char[size_+1];
0346         if (str_ != NULL) {
0347             memcpy(str_, str, size_  * sizeof(char));
0348             str_[size_] = '\0';
0349         }
0350         else {
0351             size_ = 0;
0352         }
0353     }
0354 
0355     string(char * str) :
0356         str_(NULL)
0357     {
0358         size_= ::strlen(str);
0359         str_ = new char[size_ + 1];
0360         if (str_ != NULL) {
0361             memcpy(str_, str, (size_ + 1) * sizeof(char));
0362         }
0363         else {
0364             size_ = 0;
0365         }
0366     }
0367 
0368     string& operator=(const string& rhs)
0369     {
0370         if (this == &rhs) {
0371             return *this;
0372         }
0373 
0374         if (rhs.size_ == 0 || rhs.str_ == NULL) {
0375             size_ = 0;
0376             str_  = NULL;
0377         } 
0378         else {
0379             size_ = rhs.size_;
0380             str_ = new char[size_ + 1];
0381             if (str_ != NULL) {
0382                 memcpy(str_, rhs.str_, (size_ + 1) * sizeof(char));
0383             }
0384             else {
0385                 size_ = 0;
0386             }
0387         }
0388 
0389         return *this;
0390     }
0391 
0392     string(const string& rhs)
0393     {
0394         *this = rhs;
0395     }
0396 
0397     ~string()
0398     {
0399         if (str_ != NULL) {
0400             delete[] str_;
0401         }
0402     }
0403 
0404     ::size_t size(void) const   { return size_; }
0405     ::size_t length(void) const { return size(); }
0406 
0407     const char * c_str(void) const { return (str_) ? str_ : "";}
0408 };
0409 
0410 #if !defined(__USE_DEV_STRING) && !defined(__NO_STD_STRING)
0411 #include <string>
0412 typedef std::string STRING_CLASS;
0413 #elif !defined(__USE_DEV_STRING) 
0414 typedef cl::string STRING_CLASS;
0415 #endif
0416 
0417 #if !defined(__USE_DEV_VECTOR) && !defined(__NO_STD_VECTOR)
0418 #include <vector>
0419 #define VECTOR_CLASS std::vector
0420 #elif !defined(__USE_DEV_VECTOR) 
0421 #define VECTOR_CLASS cl::vector 
0422 #endif
0423 
0424 #if !defined(__MAX_DEFAULT_VECTOR_SIZE)
0425 #define __MAX_DEFAULT_VECTOR_SIZE 10
0426 #endif
0427 
0428 /*! \class vector
0429  * \brief Fixed sized vector implementation that mirroring 
0430  * std::vector functionality.
0431  */
0432 template <typename T, unsigned int N = __MAX_DEFAULT_VECTOR_SIZE>
0433 class vector
0434 {
0435 private:
0436     T data_[N];
0437     unsigned int size_;
0438     bool empty_;
0439 public:
0440     vector() : 
0441         size_(-1),
0442         empty_(true)
0443     {}
0444 
0445     ~vector() {}
0446 
0447     unsigned int size(void) const
0448     {
0449         return size_ + 1;
0450     }
0451 
0452     void clear()
0453     {
0454         size_ = -1;
0455         empty_ = true;
0456     }
0457 
0458     void push_back (const T& x)
0459     { 
0460         if (size() < N) {
0461             size_++;  
0462             data_[size_] = x;
0463             empty_ = false;
0464         }
0465     }
0466 
0467     void pop_back(void)
0468     {
0469         if (!empty_) {
0470             data_[size_].~T();
0471             size_--;
0472             if (size_ == -1) {
0473                 empty_ = true;
0474             }
0475         }
0476     }
0477   
0478     vector(const vector<T, N>& vec) : 
0479         size_(vec.size_),
0480         empty_(vec.empty_)
0481     {
0482         if (!empty_) {
0483             memcpy(&data_[0], &vec.data_[0], size() * sizeof(T));
0484         }
0485     } 
0486 
0487     vector(unsigned int size, const T& val = T()) :
0488         size_(-1),
0489         empty_(true)
0490     {
0491         for (unsigned int i = 0; i < size; i++) {
0492             push_back(val);
0493         }
0494     }
0495 
0496     vector<T, N>& operator=(const vector<T, N>& rhs)
0497     {
0498         if (this == &rhs) {
0499             return *this;
0500         }
0501 
0502         size_  = rhs.size_;
0503         empty_ = rhs.empty_;
0504 
0505         if (!empty_) {  
0506             memcpy(&data_[0], &rhs.data_[0], size() * sizeof(T));
0507         }
0508     
0509         return *this;
0510     }
0511 
0512     bool operator==(vector<T,N> &vec)
0513     {
0514         if (empty_ && vec.empty_) {
0515             return true;
0516         }
0517 
0518         if (size() != vec.size()) {
0519             return false;
0520         }
0521 
0522         return memcmp(&data_[0], &vec.data_[0], size() * sizeof(T)) == 0 ? true : false;
0523     }
0524   
0525     operator T* ()             { return data_; }
0526     operator const T* () const { return data_; }
0527    
0528     bool empty (void) const
0529     {
0530         return empty_;
0531     }
0532   
0533     unsigned int max_size (void) const
0534     {
0535         return N;
0536     }
0537 
0538     unsigned int capacity () const
0539     {
0540         return sizeof(T) * N;
0541     }
0542 
0543     T& operator[](int index)
0544     {
0545         return data_[index];
0546     }
0547   
0548     T operator[](int index) const
0549     {
0550         return data_[index];
0551     }
0552   
0553     template<class I>
0554     void assign(I start, I end)
0555     {
0556         clear();   
0557         while(start < end) {
0558             push_back(*start);
0559             start++;
0560         }
0561     }
0562 
0563     /*! \class iterator
0564      * \brief Iterator class for vectors
0565      */
0566     class iterator
0567     {
0568     private:
0569         vector<T,N> vec_;
0570         int index_;
0571         bool initialized_;
0572     public:
0573         iterator(void) : 
0574             index_(-1),
0575             initialized_(false)
0576         {
0577             index_ = -1;
0578             initialized_ = false;
0579         }
0580 
0581         ~iterator(void) {}
0582 
0583         static iterator begin(vector<T,N> &vec)
0584         {
0585             iterator i;
0586 
0587             if (!vec.empty()) {
0588                 i.index_ = 0;
0589             }
0590 
0591             i.vec_ = vec;
0592             i.initialized_ = true;
0593             return i;
0594         }
0595 
0596         static iterator end(vector<T,N> &vec)
0597         {
0598             iterator i;
0599 
0600             if (!vec.empty()) {
0601                 i.index_ = vec.size();
0602             }
0603             i.vec_ = vec;
0604             i.initialized_ = true;
0605             return i;
0606         }
0607     
0608         bool operator==(iterator i)
0609         {
0610             return ((vec_ == i.vec_) && 
0611                     (index_ == i.index_) && 
0612                     (initialized_ == i.initialized_));
0613         }
0614 
0615         bool operator!=(iterator i)
0616         {
0617             return (!(*this==i));
0618         }
0619 
0620         void operator++()
0621         {
0622             index_++;
0623         }
0624 
0625         void operator++(int x)
0626         {
0627             index_ += x;
0628         }
0629 
0630         void operator--()
0631         {
0632             index_--;
0633         }
0634 
0635         void operator--(int x)
0636         {
0637             index_ -= x;
0638         }
0639 
0640         T operator *()
0641         {
0642             return vec_[index_];
0643         }
0644     };
0645 
0646     iterator begin(void)
0647     {
0648         return iterator::begin(*this);
0649     }
0650 
0651     iterator end(void)
0652     {
0653         return iterator::end(*this);
0654     }
0655 
0656     T& front(void)
0657     {
0658         return data_[0];
0659     }
0660 
0661     T& back(void)
0662     {
0663         return data_[size_];
0664     }
0665 
0666     const T& front(void) const
0667     {
0668         return data_[0];
0669     }
0670 
0671     const T& back(void) const
0672     {
0673         return data_[size_];
0674     }
0675 };  
0676     
0677 /*!
0678  * \brief size_t class used to interface between C++ and
0679  * OpenCL C calls that require arrays of size_t values, who's
0680  * size is known statically.
0681  */
0682 template <int N>
0683 struct size_t : public cl::vector< ::size_t, N> { };
0684 
0685 namespace detail {
0686 
0687 // GetInfo help struct
0688 template <typename Functor, typename T>
0689 struct GetInfoHelper
0690 {
0691     static cl_int
0692     get(Functor f, cl_uint name, T* param)
0693     {
0694         return f(name, sizeof(T), param, NULL);
0695     }
0696 };
0697 
0698 // Specialized GetInfoHelper for VECTOR_CLASS params
0699 template <typename Func, typename T>
0700 struct GetInfoHelper<Func, VECTOR_CLASS<T> >
0701 {
0702     static cl_int get(Func f, cl_uint name, VECTOR_CLASS<T>* param)
0703     {
0704         ::size_t required;
0705         cl_int err = f(name, 0, NULL, &required);
0706         if (err != CL_SUCCESS) {
0707             return err;
0708         }
0709 
0710         T* value = (T*) alloca(required);
0711         err = f(name, required, value, NULL);
0712         if (err != CL_SUCCESS) {
0713             return err;
0714         }
0715 
0716         param->assign(&value[0], &value[required/sizeof(T)]);
0717         return CL_SUCCESS;
0718     }
0719 };
0720 
0721 // Specialized for getInfo<CL_PROGRAM_BINARIES>
0722 template <typename Func>
0723 struct GetInfoHelper<Func, VECTOR_CLASS<char *> >
0724 {
0725     static cl_int
0726     get(Func f, cl_uint name, VECTOR_CLASS<char *>* param)
0727     {
0728       cl_uint err = f(name, param->size() * sizeof(char *), &(*param)[0], NULL);
0729       if (err != CL_SUCCESS) {
0730         return err;
0731       }
0732       
0733       return CL_SUCCESS;
0734     }
0735 };
0736 
0737 // Specialized GetInfoHelper for STRING_CLASS params
0738 template <typename Func>
0739 struct GetInfoHelper<Func, STRING_CLASS>
0740 {
0741     static cl_int get(Func f, cl_uint name, STRING_CLASS* param)
0742     {
0743         ::size_t required;
0744         cl_int err = f(name, 0, NULL, &required);
0745         if (err != CL_SUCCESS) {
0746             return err;
0747         }
0748 
0749         char* value = (char*) alloca(required);
0750         err = f(name, required, value, NULL);
0751         if (err != CL_SUCCESS) {
0752             return err;
0753         }
0754 
0755         *param = value;
0756         return CL_SUCCESS;
0757     }
0758 };
0759 
0760 #define __GET_INFO_HELPER_WITH_RETAIN(CPP_TYPE) \
0761 namespace detail { \
0762 template <typename Func> \
0763 struct GetInfoHelper<Func, CPP_TYPE> \
0764 { \
0765     static cl_int get(Func f, cl_uint name, CPP_TYPE* param) \
0766     { \
0767       cl_uint err = f(name, sizeof(CPP_TYPE), param, NULL); \
0768       if (err != CL_SUCCESS) { \
0769         return err; \
0770       } \
0771       \
0772       return ReferenceHandler<CPP_TYPE::cl_type>::retain((*param)()); \
0773     } \
0774 }; \
0775 } 
0776 
0777 
0778 #define __PARAM_NAME_INFO_1_0(F) \
0779     F(cl_platform_info, CL_PLATFORM_PROFILE, STRING_CLASS) \
0780     F(cl_platform_info, CL_PLATFORM_VERSION, STRING_CLASS) \
0781     F(cl_platform_info, CL_PLATFORM_NAME, STRING_CLASS) \
0782     F(cl_platform_info, CL_PLATFORM_VENDOR, STRING_CLASS) \
0783     F(cl_platform_info, CL_PLATFORM_EXTENSIONS, STRING_CLASS) \
0784     \
0785     F(cl_device_info, CL_DEVICE_TYPE, cl_device_type) \
0786     F(cl_device_info, CL_DEVICE_VENDOR_ID, cl_uint) \
0787     F(cl_device_info, CL_DEVICE_MAX_COMPUTE_UNITS, cl_uint) \
0788     F(cl_device_info, CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS, cl_uint) \
0789     F(cl_device_info, CL_DEVICE_MAX_WORK_GROUP_SIZE, ::size_t) \
0790     F(cl_device_info, CL_DEVICE_MAX_WORK_ITEM_SIZES, VECTOR_CLASS< ::size_t>) \
0791     F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR, cl_uint) \
0792     F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT, cl_uint) \
0793     F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT, cl_uint) \
0794     F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG, cl_uint) \
0795     F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT, cl_uint) \
0796     F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE, cl_uint) \
0797     F(cl_device_info, CL_DEVICE_MAX_CLOCK_FREQUENCY, cl_uint) \
0798     F(cl_device_info, CL_DEVICE_ADDRESS_BITS, cl_bitfield) \
0799     F(cl_device_info, CL_DEVICE_MAX_READ_IMAGE_ARGS, cl_uint) \
0800     F(cl_device_info, CL_DEVICE_MAX_WRITE_IMAGE_ARGS, cl_uint) \
0801     F(cl_device_info, CL_DEVICE_MAX_MEM_ALLOC_SIZE, cl_ulong) \
0802     F(cl_device_info, CL_DEVICE_IMAGE2D_MAX_WIDTH, ::size_t) \
0803     F(cl_device_info, CL_DEVICE_IMAGE2D_MAX_HEIGHT, ::size_t) \
0804     F(cl_device_info, CL_DEVICE_IMAGE3D_MAX_WIDTH, ::size_t) \
0805     F(cl_device_info, CL_DEVICE_IMAGE3D_MAX_HEIGHT, ::size_t) \
0806     F(cl_device_info, CL_DEVICE_IMAGE3D_MAX_DEPTH, ::size_t) \
0807     F(cl_device_info, CL_DEVICE_IMAGE_SUPPORT, cl_uint) \
0808     F(cl_device_info, CL_DEVICE_MAX_PARAMETER_SIZE, ::size_t) \
0809     F(cl_device_info, CL_DEVICE_MAX_SAMPLERS, cl_uint) \
0810     F(cl_device_info, CL_DEVICE_MEM_BASE_ADDR_ALIGN, cl_uint) \
0811     F(cl_device_info, CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE, cl_uint) \
0812     F(cl_device_info, CL_DEVICE_SINGLE_FP_CONFIG, cl_device_fp_config) \
0813     F(cl_device_info, CL_DEVICE_GLOBAL_MEM_CACHE_TYPE, cl_device_mem_cache_type) \
0814     F(cl_device_info, CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE, cl_uint)\
0815     F(cl_device_info, CL_DEVICE_GLOBAL_MEM_CACHE_SIZE, cl_ulong) \
0816     F(cl_device_info, CL_DEVICE_GLOBAL_MEM_SIZE, cl_ulong) \
0817     F(cl_device_info, CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE, cl_ulong) \
0818     F(cl_device_info, CL_DEVICE_MAX_CONSTANT_ARGS, cl_uint) \
0819     F(cl_device_info, CL_DEVICE_LOCAL_MEM_TYPE, cl_device_local_mem_type) \
0820     F(cl_device_info, CL_DEVICE_LOCAL_MEM_SIZE, cl_ulong) \
0821     F(cl_device_info, CL_DEVICE_ERROR_CORRECTION_SUPPORT, cl_bool) \
0822     F(cl_device_info, CL_DEVICE_PROFILING_TIMER_RESOLUTION, ::size_t) \
0823     F(cl_device_info, CL_DEVICE_ENDIAN_LITTLE, cl_bool) \
0824     F(cl_device_info, CL_DEVICE_AVAILABLE, cl_bool) \
0825     F(cl_device_info, CL_DEVICE_COMPILER_AVAILABLE, cl_bool) \
0826     F(cl_device_info, CL_DEVICE_EXECUTION_CAPABILITIES, cl_device_exec_capabilities) \
0827     F(cl_device_info, CL_DEVICE_QUEUE_PROPERTIES, cl_command_queue_properties) \
0828     F(cl_device_info, CL_DEVICE_PLATFORM, cl_platform_id) \
0829     F(cl_device_info, CL_DEVICE_NAME, STRING_CLASS) \
0830     F(cl_device_info, CL_DEVICE_VENDOR, STRING_CLASS) \
0831     F(cl_device_info, CL_DRIVER_VERSION, STRING_CLASS) \
0832     F(cl_device_info, CL_DEVICE_PROFILE, STRING_CLASS) \
0833     F(cl_device_info, CL_DEVICE_VERSION, STRING_CLASS) \
0834     F(cl_device_info, CL_DEVICE_EXTENSIONS, STRING_CLASS) \
0835     \
0836     F(cl_context_info, CL_CONTEXT_REFERENCE_COUNT, cl_uint) \
0837     F(cl_context_info, CL_CONTEXT_DEVICES, VECTOR_CLASS<Device>) \
0838     F(cl_context_info, CL_CONTEXT_PROPERTIES, VECTOR_CLASS<cl_context_properties>) \
0839     \
0840     F(cl_event_info, CL_EVENT_COMMAND_QUEUE, cl::CommandQueue) \
0841     F(cl_event_info, CL_EVENT_COMMAND_TYPE, cl_command_type) \
0842     F(cl_event_info, CL_EVENT_REFERENCE_COUNT, cl_uint) \
0843     F(cl_event_info, CL_EVENT_COMMAND_EXECUTION_STATUS, cl_uint) \
0844     \
0845     F(cl_profiling_info, CL_PROFILING_COMMAND_QUEUED, cl_ulong) \
0846     F(cl_profiling_info, CL_PROFILING_COMMAND_SUBMIT, cl_ulong) \
0847     F(cl_profiling_info, CL_PROFILING_COMMAND_START, cl_ulong) \
0848     F(cl_profiling_info, CL_PROFILING_COMMAND_END, cl_ulong) \
0849     \
0850     F(cl_mem_info, CL_MEM_TYPE, cl_mem_object_type) \
0851     F(cl_mem_info, CL_MEM_FLAGS, cl_mem_flags) \
0852     F(cl_mem_info, CL_MEM_SIZE, ::size_t) \
0853     F(cl_mem_info, CL_MEM_HOST_PTR, void*) \
0854     F(cl_mem_info, CL_MEM_MAP_COUNT, cl_uint) \
0855     F(cl_mem_info, CL_MEM_REFERENCE_COUNT, cl_uint) \
0856     F(cl_mem_info, CL_MEM_CONTEXT, cl::Context) \
0857     \
0858     F(cl_image_info, CL_IMAGE_FORMAT, cl_image_format) \
0859     F(cl_image_info, CL_IMAGE_ELEMENT_SIZE, ::size_t) \
0860     F(cl_image_info, CL_IMAGE_ROW_PITCH, ::size_t) \
0861     F(cl_image_info, CL_IMAGE_SLICE_PITCH, ::size_t) \
0862     F(cl_image_info, CL_IMAGE_WIDTH, ::size_t) \
0863     F(cl_image_info, CL_IMAGE_HEIGHT, ::size_t) \
0864     F(cl_image_info, CL_IMAGE_DEPTH, ::size_t) \
0865     \
0866     F(cl_sampler_info, CL_SAMPLER_REFERENCE_COUNT, cl_uint) \
0867     F(cl_sampler_info, CL_SAMPLER_CONTEXT, cl::Context) \
0868     F(cl_sampler_info, CL_SAMPLER_NORMALIZED_COORDS, cl_addressing_mode) \
0869     F(cl_sampler_info, CL_SAMPLER_ADDRESSING_MODE, cl_filter_mode) \
0870     F(cl_sampler_info, CL_SAMPLER_FILTER_MODE, cl_bool) \
0871     \
0872     F(cl_program_info, CL_PROGRAM_REFERENCE_COUNT, cl_uint) \
0873     F(cl_program_info, CL_PROGRAM_CONTEXT, cl::Context) \
0874     F(cl_program_info, CL_PROGRAM_NUM_DEVICES, cl_uint) \
0875     F(cl_program_info, CL_PROGRAM_DEVICES, VECTOR_CLASS<cl_device_id>) \
0876     F(cl_program_info, CL_PROGRAM_SOURCE, STRING_CLASS) \
0877     F(cl_program_info, CL_PROGRAM_BINARY_SIZES, VECTOR_CLASS< ::size_t>) \
0878     F(cl_program_info, CL_PROGRAM_BINARIES, VECTOR_CLASS<char *>) \
0879     \
0880     F(cl_program_build_info, CL_PROGRAM_BUILD_STATUS, cl_build_status) \
0881     F(cl_program_build_info, CL_PROGRAM_BUILD_OPTIONS, STRING_CLASS) \
0882     F(cl_program_build_info, CL_PROGRAM_BUILD_LOG, STRING_CLASS) \
0883     \
0884     F(cl_kernel_info, CL_KERNEL_FUNCTION_NAME, STRING_CLASS) \
0885     F(cl_kernel_info, CL_KERNEL_NUM_ARGS, cl_uint) \
0886     F(cl_kernel_info, CL_KERNEL_REFERENCE_COUNT, cl_uint) \
0887     F(cl_kernel_info, CL_KERNEL_CONTEXT, cl::Context) \
0888     F(cl_kernel_info, CL_KERNEL_PROGRAM, cl::Program) \
0889     \
0890     F(cl_kernel_work_group_info, CL_KERNEL_WORK_GROUP_SIZE, ::size_t) \
0891     F(cl_kernel_work_group_info, CL_KERNEL_COMPILE_WORK_GROUP_SIZE, cl::size_t<3>) \
0892     F(cl_kernel_work_group_info, CL_KERNEL_LOCAL_MEM_SIZE, cl_ulong) \
0893     \
0894     F(cl_command_queue_info, CL_QUEUE_CONTEXT, cl::Context) \
0895     F(cl_command_queue_info, CL_QUEUE_DEVICE, cl::Device) \
0896     F(cl_command_queue_info, CL_QUEUE_REFERENCE_COUNT, cl_uint) \
0897     F(cl_command_queue_info, CL_QUEUE_PROPERTIES, cl_command_queue_properties)
0898 
0899 #if defined(CL_VERSION_1_1)
0900 #define __PARAM_NAME_INFO_1_1(F) \
0901     F(cl_context_info, CL_CONTEXT_NUM_DEVICES, cl_uint)\
0902     F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF, cl_uint) \
0903     F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR, cl_uint) \
0904     F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT, cl_uint) \
0905     F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_INT, cl_uint) \
0906     F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG, cl_uint) \
0907     F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT, cl_uint) \
0908     F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE, cl_uint) \
0909     F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF, cl_uint) \
0910     F(cl_device_info, CL_DEVICE_DOUBLE_FP_CONFIG, cl_device_fp_config) \
0911     F(cl_device_info, CL_DEVICE_HALF_FP_CONFIG, cl_device_fp_config) \
0912     F(cl_device_info, CL_DEVICE_HOST_UNIFIED_MEMORY, cl_bool) \
0913     \
0914     F(cl_mem_info, CL_MEM_ASSOCIATED_MEMOBJECT, cl::Memory) \
0915     F(cl_mem_info, CL_MEM_OFFSET, ::size_t) \
0916     \
0917     F(cl_kernel_work_group_info, CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE, ::size_t) \
0918     F(cl_kernel_work_group_info, CL_KERNEL_PRIVATE_MEM_SIZE, cl_ulong) \
0919     \
0920     F(cl_event_info, CL_EVENT_CONTEXT, cl::Context)
0921 #endif // CL_VERSION_1_1
0922 
0923 #if defined(USE_CL_DEVICE_FISSION)
0924 #define __PARAM_NAME_DEVICE_FISSION(F) \
0925     F(cl_device_info, CL_DEVICE_PARENT_DEVICE_EXT, cl_device_id) \
0926     F(cl_device_info, CL_DEVICE_PARTITION_TYPES_EXT, VECTOR_CLASS<cl_device_partition_property_ext>) \
0927     F(cl_device_info, CL_DEVICE_AFFINITY_DOMAINS_EXT, VECTOR_CLASS<cl_device_partition_property_ext>) \
0928     F(cl_device_info, CL_DEVICE_REFERENCE_COUNT_EXT , cl_uint) \
0929     F(cl_device_info, CL_DEVICE_PARTITION_STYLE_EXT, VECTOR_CLASS<cl_device_partition_property_ext>)
0930 #endif // USE_CL_DEVICE_FISSION
0931 
0932 template <typename enum_type, cl_int Name>
0933 struct param_traits {};
0934 
0935 #define __DECLARE_PARAM_TRAITS(token, param_name, T) \
0936 struct token;                                        \
0937 template<>                                           \
0938 struct param_traits<detail:: token,param_name>       \
0939 {                                                    \
0940     enum { value = param_name };                     \
0941     typedef T param_type;                            \
0942 };
0943 
0944 __PARAM_NAME_INFO_1_0(__DECLARE_PARAM_TRAITS);
0945 #if defined(CL_VERSION_1_1)
0946 __PARAM_NAME_INFO_1_1(__DECLARE_PARAM_TRAITS);
0947 #endif // CL_VERSION_1_1
0948 
0949 #if defined(USE_CL_DEVICE_FISSION)
0950 __PARAM_NAME_DEVICE_FISSION(__DECLARE_PARAM_TRAITS);
0951 #endif // USE_CL_DEVICE_FISSION
0952 
0953 #undef __DECLARE_PARAM_TRAITS
0954 
0955 // Convenience functions
0956 
0957 template <typename Func, typename T>
0958 inline cl_int
0959 getInfo(Func f, cl_uint name, T* param)
0960 {
0961     return GetInfoHelper<Func, T>::get(f, name, param);
0962 }
0963 
0964 template <typename Func, typename Arg0>
0965 struct GetInfoFunctor0
0966 {
0967     Func f_; const Arg0& arg0_;
0968     cl_int operator ()(
0969         cl_uint param, ::size_t size, void* value, ::size_t* size_ret)
0970     { return f_(arg0_, param, size, value, size_ret); }
0971 };
0972 
0973 template <typename Func, typename Arg0, typename Arg1>
0974 struct GetInfoFunctor1
0975 {
0976     Func f_; const Arg0& arg0_; const Arg1& arg1_;
0977     cl_int operator ()(
0978         cl_uint param, ::size_t size, void* value, ::size_t* size_ret)
0979     { return f_(arg0_, arg1_, param, size, value, size_ret); }
0980 };
0981 
0982 template <typename Func, typename Arg0, typename T>
0983 inline cl_int
0984 getInfo(Func f, const Arg0& arg0, cl_uint name, T* param)
0985 {
0986     GetInfoFunctor0<Func, Arg0> f0 = { f, arg0 };
0987     return GetInfoHelper<GetInfoFunctor0<Func, Arg0>, T>
0988         ::get(f0, name, param);
0989 }
0990 
0991 template <typename Func, typename Arg0, typename Arg1, typename T>
0992 inline cl_int
0993 getInfo(Func f, const Arg0& arg0, const Arg1& arg1, cl_uint name, T* param)
0994 {
0995     GetInfoFunctor1<Func, Arg0, Arg1> f0 = { f, arg0, arg1 };
0996     return GetInfoHelper<GetInfoFunctor1<Func, Arg0, Arg1>, T>
0997         ::get(f0, name, param);
0998 }
0999 
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_