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