Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
cl.hpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file cl.hpp
1 /*******************************************************************************
2  * Copyright (c) 2008-2010 The Khronos Group Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and/or associated documentation files (the
6  * "Materials"), to deal in the Materials without restriction, including
7  * without limitation the rights to use, copy, modify, merge, publish,
8  * distribute, sublicense, and/or sell copies of the Materials, and to
9  * permit persons to whom the Materials are furnished to do so, subject to
10  * the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included
13  * in all copies or substantial portions of the Materials.
14  *
15  * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21  * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
22  ******************************************************************************/
23 
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 
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>
210 class Error : public std::exception
211 {
212 private:
213  cl_int err_;
214  const char * errStr_;
215 public:
219  Error(cl_int err, const char * errStr = NULL) : err_(err), errStr_(errStr)
220  {}
221 
222  ~Error() throw() {}
223 
228  virtual const char * what() const throw ()
229  {
230  if (errStr_ == NULL) {
231  return "empty";
232  }
233  else {
234  return errStr_;
235  }
236  }
237 
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 
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 
326 
331 class string
332 {
333 private:
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 
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>
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 
432 template <typename T, unsigned int N = __MAX_DEFAULT_VECTOR_SIZE>
433 class vector
434 {
435 private:
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 
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 
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 
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 
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 
566  class iterator
567  {
568  private:
570  int index_;
572  public:
573  iterator(void) :
574  index_(-1),
576  {
577  index_ = -1;
578  initialized_ = false;
579  }
580 
581  ~iterator(void) {}
582 
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 
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 
609  {
610  return ((vec_ == i.vec_) &&
611  (index_ == i.index_) &&
612  (initialized_ == i.initialized_));
613  }
614 
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 
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 
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>
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>
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 
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>
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>
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 };
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 };
997  ::get(f0, name, param);
998 }
999 
1000 template<typename T>
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:
1097 
1098 public:
1099  Wrapper() : object_(NULL) { }
1100 
1102  {
1103  if (object_ != NULL) { release(); }
1104  }
1105 
1107  {
1108  object_ = rhs.object_;
1109  if (object_ != NULL) { retain(); }
1110  }
1111 
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  {
1129  }
1130 
1131  cl_int release() const
1132  {
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
1156 
1160 struct ImageFormat : public cl_image_format
1161 {
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 
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 
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 
1193  {
1194  if (this != &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
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 
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 
1270  {
1271  if (this != &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
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 
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
1413 {
1414  return ::clUnloadCompiler();
1415 }
1416 
1417 class Context : public detail::Wrapper<cl_context>
1418 {
1419 public:
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 
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 
1469  {
1470  if (this != &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
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 
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 
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 
1533 
1534 
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 
1545  {
1546  if (this != &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
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  {
1577  &::clGetEventProfilingInfo, object_, name, param),
1578  __GET_EVENT_PROFILE_INFO_ERR);
1579  }
1580 
1581  template <cl_int name> typename
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 
1628 
1629 #if defined(CL_VERSION_1_1)
1630 
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 
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 
1692  {
1693  if (this != &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
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 
1737 
1738 
1741 class Buffer : public Memory
1742 {
1743 public:
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 
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 
1845 class BufferGL : public Buffer
1846 {
1847 public:
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 
1872  {
1873  if (this != &rhs) {
1874  Buffer::operator=(rhs);
1875  }
1876  return *this;
1877  }
1878 
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 
1892 class BufferRenderGL : public Buffer
1893 {
1894 public:
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 
1915 
1916  BufferRenderGL(const BufferGL& buffer) : Buffer(buffer) { }
1917 
1919  {
1920  if (this != &rhs) {
1921  Buffer::operator=(rhs);
1922  }
1923  return *this;
1924  }
1925 
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 
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
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 
1979 class Image2D : public Image
1980 {
1981 public:
1983  const Context& context,
1984  cl_mem_flags flags,
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 
2007  {
2008  if (this != &rhs) {
2009  Image::operator=(rhs);
2010  }
2011  return *this;
2012  }
2013 };
2014 
2018 class Image2DGL : public Image2D
2019 {
2020 public:
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 
2049  {
2050  if (this != &rhs) {
2051  Image2D::operator=(rhs);
2052  }
2053  return *this;
2054  }
2055 };
2056 
2060 class Image3D : public Image
2061 {
2062 public:
2064  const Context& context,
2065  cl_mem_flags flags,
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 
2091  {
2092  if (this != &rhs) {
2093  Image::operator=(rhs);
2094  }
2095  return *this;
2096  }
2097 };
2098 
2102 class Image3DGL : public Image3D
2103 {
2104 public:
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 
2133  {
2134  if (this != &rhs) {
2135  Image3D::operator=(rhs);
2136  }
2137  return *this;
2138  }
2139 };
2140 
2144 class Sampler : public detail::Wrapper<cl_sampler>
2145 {
2146 public:
2147  Sampler() { }
2148 
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 
2173  {
2174  if (this != &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
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 
2203 
2204 class Program;
2205 class CommandQueue;
2206 class Kernel;
2207 
2211 class NDRange
2212 {
2213 private:
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 
2254 {
2256 };
2257 
2258 namespace detail {
2259 
2260 template <typename T>
2262 {
2263  static ::size_t size(const T&) { return sizeof(T); }
2264  static T* ptr(T& value) { return &value; }
2265 };
2266 
2267 template <>
2269 {
2270  static ::size_t size(const LocalSpaceArg& value) { return value.size_; }
2271  static void* ptr(LocalSpaceArg&) { return NULL; }
2272 };
2273 
2274 }
2276 
2277 inline LocalSpaceArg
2278 __local(::size_t size)
2279 {
2280  LocalSpaceArg ret = { size };
2281  return ret;
2282 }
2283 
2284 class KernelFunctor;
2285 
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 
2299  {
2300  if (this != &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
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>
2329  const Device& device, cl_kernel_work_group_info name, T* param) const
2330  {
2331  return detail::errHandler(
2333  &::clGetKernelWorkGroupInfo, object_, device(), name, param),
2334  __GET_KERNEL_WORK_GROUP_INFO_ERR);
2335  }
2336 
2337  template <cl_int name> typename
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,
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 
2370  const CommandQueue& queue,
2371  const NDRange& offset,
2372  const NDRange& global,
2373  const NDRange& local);
2374 
2376  const CommandQueue& queue,
2377  const NDRange& global,
2378  const NDRange& local);
2379 };
2380 
2382 
2383 
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 
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 
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 
2452  {
2453  if (this != &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
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(
2504  &::clGetProgramBuildInfo, object_, device(), name, param),
2505  __GET_PROGRAM_BUILD_INFO_ERR);
2506  }
2507 
2508  template <cl_int name> typename
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 
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 
2559 class CommandQueue : public detail::Wrapper<cl_command_queue>
2560 {
2561 public:
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 
2579 
2580  CommandQueue(const CommandQueue& commandQueue) : detail::Wrapper<cl_type>(commandQueue) { }
2581 
2583  {
2584  if (this != &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(
2595  &::clGetCommandQueueInfo, object_, name, param),
2596  __GET_COMMAND_QUEUE_INFO_ERR);
2597  }
2598 
2599  template <cl_int name> typename
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
3117 
3118 
3126 {
3127 private:
3133 
3134  cl_int err_;
3135 public:
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 
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 
3365  const CommandQueue& queue,
3366  const NDRange& global,
3367  const NDRange& local)
3368 {
3369  return KernelFunctor(*this,queue,NullRange,global,local);
3370 }
3371 
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 
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 
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>
3413  const A1& a1,
3414  const VECTOR_CLASS<Event>* events)
3415 {
3416  Event event;
3417 
3418  kernel_.setArg(0,a1);
3419 
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>
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 
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>
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 
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>
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 
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>
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 
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>
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 
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>
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 
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>
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 
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>
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 
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>
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 
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>
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 
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>
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 
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>
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 
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>
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 
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>
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 
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_