Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  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.