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