blob: c6cd8a716c91b165a2e5a4d5b8fa1239ad604a00 [file] [log] [blame]
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001/*******************************************************************************
2 * Copyright (c) 2008-2015 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), OpenCL 1.1 (rev 33),
27 * OpenCL 1.2 (rev 15) and OpenCL 2.0 (rev 29)
28 * \author Lee Howes and Bruce Merry
29 *
30 * Derived from the OpenCL 1.x C++ bindings written by
31 * Benedict R. Gaster, Laurent Morichetti and Lee Howes
32 * With additions and fixes from:
33 * Brian Cole, March 3rd 2010 and April 2012
34 * Matt Gruenke, April 2012.
35 * Bruce Merry, February 2013.
36 * Tom Deakin and Simon McIntosh-Smith, July 2013
37 * James Price, June-November 2015
38 *
39 * \version 2.0.8
40 * \date 2015-11-03
41 *
42 * Optional extension support
43 *
44 * cl_ext_device_fission
45 * #define CL_HPP_USE_CL_DEVICE_FISSION
46 * cl_khr_d3d10_sharing
47 * #define CL_HPP_USE_DX_INTEROP
48 * cl_khr_sub_groups
49 * #define CL_HPP_USE_CL_SUB_GROUPS_KHR
50 */
51
52/*! \mainpage
53 * \section intro Introduction
54 * For many large applications C++ is the language of choice and so it seems
55 * reasonable to define C++ bindings for OpenCL.
56 *
57 * The interface is contained with a single C++ header file \em cl2.hpp and all
58 * definitions are contained within the namespace \em cl. There is no additional
59 * requirement to include \em cl.h and to use either the C++ or original C
60 * bindings; it is enough to simply include \em cl.hpp.
61 *
62 * The bindings themselves are lightweight and correspond closely to the
63 * underlying C API. Using the C++ bindings introduces no additional execution
64 * overhead.
65 *
66 * There are numerous compatibility, portability and memory management
67 * fixes in the new header as well as additional OpenCL 2.0 features.
68 * As a result the header is not directly backward compatible and for this
69 * reason we release it as cl2.hpp rather than a new version of cl.hpp.
70 *
71 *
72 * \section compatibility Compatibility
73 * Due to the evolution of the underlying OpenCL API the 2.0 C++ bindings
74 * include an updated approach to defining supported feature versions
75 * and the range of valid underlying OpenCL runtime versions supported.
76 *
77 * The combination of preprocessor macros CL_HPP_TARGET_OPENCL_VERSION and
78 * CL_HPP_MINIMUM_OPENCL_VERSION control this range. These are three digit
79 * decimal values representing OpenCL runime versions. The default for
80 * the target is 200, representing OpenCL 2.0 and the minimum is also
81 * defined as 200. These settings would use 2.0 API calls only.
82 * If backward compatibility with a 1.2 runtime is required, the minimum
83 * version may be set to 120.
84 *
85 * Note that this is a compile-time setting, and so affects linking against
86 * a particular SDK version rather than the versioning of the loaded runtime.
87 *
88 * The earlier versions of the header included basic vector and string
89 * classes based loosely on STL versions. These were difficult to
90 * maintain and very rarely used. For the 2.0 header we now assume
91 * the presence of the standard library unless requested otherwise.
92 * We use std::array, std::vector, std::shared_ptr and std::string
93 * throughout to safely manage memory and reduce the chance of a
94 * recurrance of earlier memory management bugs.
95 *
96 * These classes are used through typedefs in the cl namespace:
97 * cl::array, cl::vector, cl::pointer and cl::string.
98 * In addition cl::allocate_pointer forwards to std::allocate_shared
99 * by default.
100 * In all cases these standard library classes can be replaced with
101 * custom interface-compatible versions using the CL_HPP_NO_STD_ARRAY,
102 * CL_HPP_NO_STD_VECTOR, CL_HPP_NO_STD_UNIQUE_PTR and
103 * CL_HPP_NO_STD_STRING macros.
104 *
105 * The OpenCL 1.x versions of the C++ bindings included a size_t wrapper
106 * class to interface with kernel enqueue. This caused unpleasant interactions
107 * with the standard size_t declaration and led to namespacing bugs.
108 * In the 2.0 version we have replaced this with a std::array-based interface.
109 * However, the old behaviour can be regained for backward compatibility
110 * using the CL_HPP_ENABLE_SIZE_T_COMPATIBILITY macro.
111 *
112 * Finally, the program construction interface used a clumsy vector-of-pairs
113 * design in the earlier versions. We have replaced that with a cleaner
114 * vector-of-vectors and vector-of-strings design. However, for backward
115 * compatibility old behaviour can be regained with the
116 * CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY macro.
117 *
118 * In OpenCL 2.0 OpenCL C is not entirely backward compatibility with
119 * earlier versions. As a result a flag must be passed to the OpenCL C
120 * compiled to request OpenCL 2.0 compilation of kernels with 1.2 as
121 * the default in the absence of the flag.
122 * In some cases the C++ bindings automatically compile code for ease.
123 * For those cases the compilation defaults to OpenCL C 2.0.
124 * If this is not wanted, the CL_HPP_CL_1_2_DEFAULT_BUILD macro may
125 * be specified to assume 1.2 compilation.
126 * If more fine-grained decisions on a per-kernel bases are required
127 * then explicit build operations that take the flag should be used.
128 *
129 *
130 * \section parameterization Parameters
131 * This header may be parameterized by a set of preprocessor macros.
132 * CL_HPP_TARGET_OPENCL_VERSION
133 * - Defines the target OpenCL runtime version to build the header against.
134 * Defaults to 200, representing OpenCL 2.0.
135 * CL_HPP_NO_STD_STRING
136 * - Do not use the standard library string class.
137 * cl::string is not defined and may be defined by the user before
138 * cl2.hpp is included.
139 * CL_HPP_NO_STD_VECTOR
140 * - Do not use the standard library vector class.
141 * cl::vector is not defined and may be defined by the user before
142 * cl2.hpp is included.
143 * CL_HPP_NO_STD_ARRAY
144 * - Do not use the standard library array class.
145 * cl::array is not defined and may be defined by the user before
146 * cl2.hpp is included.
147 * CL_HPP_NO_STD_UNIQUE_PTR
148 * - Do not use the standard library unique_ptr class.
149 * cl::pointer and the cl::allocate_pointer function are not defined
150 * and may be defined by the user before cl2.hpp is included.
151 * CL_HPP_ENABLE_DEVICE_FISSION
152 * - Enables device fission for OpenCL 1.2 platforms
153 * CL_HPP_ENABLE_EXCEPTIONS
154 * - Enable exceptions for use in the C++ bindings header.
155 * This is the preferred error handling mechanism but is not required.
156 * CL_HPP_ENABLE_SIZE_T_COMPATIBILITY
157 * - Backward compatibility option to support cl.hpp-style size_t class.
158 * Replaces the updated std::array derived version and removal of size_t
159 * from the namespace. Note that in this case the new size_t class
160 * is placed in the cl::compatibility namespace and thus requires
161 * an additional using declaration for direct backward compatibility.
162 * CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY
163 * - Enable older vector of pairs interface for construction of programs.
164 * CL_HPP_CL_1_2_DEFAULT_BUILD
165 * - Default to OpenCL C 1.2 compilation rather than OpenCL C 2.0
166 * - applies to use of cl::Program construction and other program build variants.
167 *
168 *
169 * \section example Example
170 *
171 * The following example shows a general use case for the C++
172 * bindings, including support for the optional exception feature and
173 * also the supplied vector and string classes, see following sections for
174 * decriptions of these features.
175 *
176 * \code
177 #define CL_HPP_ENABLE_EXCEPTIONS
178 #define CL_HPP_TARGET_OPENCL_VERSION 200
179
180 #include <CL/cl2.hpp>
181 #include <iostream>
182 #include <vector>
183 #include <memory>
184 #include <algorithm>
185
186 const int numElements = 32;
187
188 int main(void)
189 {
190 // Filter for a 2.0 platform and set it as the default
191 std::vector<cl::Platform> platforms;
192 cl::Platform::get(&platforms);
193 cl::Platform plat;
194 for (auto &p : platforms) {
195 std::string platver = p.getInfo<CL_PLATFORM_VERSION>();
196 if (platver.find("OpenCL 2.") != std::string::npos) {
197 plat = p;
198 }
199 }
200 if (plat() == 0) {
201 std::cout << "No OpenCL 2.0 platform found.";
202 return -1;
203 }
204
205 cl::Platform newP = cl::Platform::setDefault(plat);
206 if (newP != plat) {
207 std::cout << "Error setting default platform.";
208 return -1;
209 }
210
211 std::string kernel1{
212 "global int globalA;"
213 "kernel void updateGlobal(){"
214 " globalA = 75;"
215 "}"};
216 std::string kernel2{
217 "typedef struct { global int *bar; } Foo; kernel void vectorAdd(global const Foo* aNum, global const int *inputA, global const int *inputB, global int *output, int val, write_only pipe int outPipe, queue_t childQueue){"
218 " output[get_global_id(0)] = inputA[get_global_id(0)] + inputB[get_global_id(0)] + val + *(aNum->bar);"
219 " write_pipe(outPipe, &val);"
220 " queue_t default_queue = get_default_queue(); "
221 " ndrange_t ndrange = ndrange_1D(get_global_size(0)/2, get_global_size(0)/2); "
222 // Have a child kernel write into third quarter of output
223 " enqueue_kernel(default_queue, CLK_ENQUEUE_FLAGS_WAIT_KERNEL, ndrange, "
224 " ^{"
225 " output[get_global_size(0)*2 + get_global_id(0)] = inputA[get_global_size(0)*2+get_global_id(0)] + inputB[get_global_size(0)*2+get_global_id(0)] + globalA;"
226 " });"
227 // Have a child kernel write into last quarter of output
228 " enqueue_kernel(childQueue, CLK_ENQUEUE_FLAGS_WAIT_KERNEL, ndrange, "
229 " ^{"
230 " output[get_global_size(0)*3 + get_global_id(0)] = inputA[get_global_size(0)*3 + get_global_id(0)] + inputB[get_global_size(0)*3 + get_global_id(0)] + globalA + 2;"
231 " });"
232 "}" };
233
234 // New simpler string interface style
235 std::vector<std::string> programStrings {kernel1, kernel2};
236
237 cl::Program vectorAddProgram(
238 programStrings);
239 try {
240 vectorAddProgram.build("-cl-std=CL2.0");
241 }
242 catch (...) {
243 // Print build info for all devices
244 cl_int buildErr = CL_SUCCESS;
245 auto buildInfo = vectorAddProgram.getBuildInfo<CL_PROGRAM_BUILD_LOG>(&buildErr);
246 for (auto &pair : buildInfo) {
247 std::cerr << pair.second << std::endl << std::endl;
248 }
249
250 return 1;
251 }
252
253 typedef struct { int *bar; } Foo;
254
255 // Get and run kernel that initializes the program-scope global
256 // A test for kernels that take no arguments
257 auto program2Kernel =
258 cl::KernelFunctor<>(vectorAddProgram, "updateGlobal");
259 program2Kernel(
260 cl::EnqueueArgs(
261 cl::NDRange(1)));
262
263 //////////////////
264 // SVM allocations
265
266 cl::pointer<int> anSVMInt = cl::allocate_svm<int, cl::SVMTraitCoarse<>>();
267 *anSVMInt = 5;
268 cl::SVMAllocator<int, cl::SVMTraitCoarse<cl::SVMTraitReadOnly<>>> svmAllocReadOnly;
269 auto fooPointer = cl::allocate_pointer<Foo>(svmAllocReadOnly);
270 fooPointer->bar = anSVMInt.get();
271 cl::SVMAllocator<int, cl::SVMTraitCoarse<>> svmAlloc;
272 std::vector<int, cl::SVMAllocator<int, cl::SVMTraitCoarse<>>> inputA(numElements, 1, svmAlloc);
273 cl::coarse_svm_vector<int> inputB(numElements, 2, svmAlloc);
274
275 //
276 //////////////
277
278 // Traditional cl_mem allocations
279 std::vector<int> output(numElements, 0xdeadbeef);
280 cl::Buffer outputBuffer(begin(output), end(output), false);
281 cl::Pipe aPipe(sizeof(cl_int), numElements / 2);
282
283 // Default command queue, also passed in as a parameter
284 cl::DeviceCommandQueue defaultDeviceQueue = cl::DeviceCommandQueue::makeDefault(
285 cl::Context::getDefault(), cl::Device::getDefault());
286
287 auto vectorAddKernel =
288 cl::KernelFunctor<
289 decltype(fooPointer)&,
290 int*,
291 cl::coarse_svm_vector<int>&,
292 cl::Buffer,
293 int,
294 cl::Pipe&,
295 cl::DeviceCommandQueue
296 >(vectorAddProgram, "vectorAdd");
297
298 // Ensure that the additional SVM pointer is available to the kernel
299 // This one was not passed as a parameter
300 vectorAddKernel.setSVMPointers(anSVMInt);
301
302 // Hand control of coarse allocations to runtime
303 cl::enqueueUnmapSVM(anSVMInt);
304 cl::enqueueUnmapSVM(fooPointer);
305 cl::unmapSVM(inputB);
306 cl::unmapSVM(output2);
307
308 cl_int error;
309 vectorAddKernel(
310 cl::EnqueueArgs(
311 cl::NDRange(numElements/2),
312 cl::NDRange(numElements/2)),
313 fooPointer,
314 inputA.data(),
315 inputB,
316 outputBuffer,
317 3,
318 aPipe,
319 defaultDeviceQueue,
320 error
321 );
322
323 cl::copy(outputBuffer, begin(output), end(output));
324 // Grab the SVM output vector using a map
325 cl::mapSVM(output2);
326
327 cl::Device d = cl::Device::getDefault();
328
329 std::cout << "Output:\n";
330 for (int i = 1; i < numElements; ++i) {
331 std::cout << "\t" << output[i] << "\n";
332 }
333 std::cout << "\n\n";
334
335 return 0;
336 }
337 *
338 * \endcode
339 *
340 */
341#ifndef CL_HPP_
342#define CL_HPP_
343
344#ifdef __GNUC__
345#pragma GCC system_header
346#endif
347
348/* Handle deprecated preprocessor definitions. In each case, we only check for
349 * the old name if the new name is not defined, so that user code can define
350 * both and hence work with either version of the bindings.
351 */
352#if !defined(CL_HPP_USE_DX_INTEROP) && defined(USE_DX_INTEROP)
353# pragma message("cl2.hpp: USE_DX_INTEROP is deprecated. Define CL_HPP_USE_DX_INTEROP instead")
354# define CL_HPP_USE_DX_INTEROP
355#endif
356#if !defined(CL_HPP_USE_CL_DEVICE_FISSION) && defined(USE_CL_DEVICE_FISSION)
357# pragma message("cl2.hpp: USE_CL_DEVICE_FISSION is deprecated. Define CL_HPP_USE_CL_DEVICE_FISSION instead")
358# define CL_HPP_USE_CL_DEVICE_FISSION
359#endif
360#if !defined(CL_HPP_ENABLE_EXCEPTIONS) && defined(__CL_ENABLE_EXCEPTIONS)
361# pragma message("cl2.hpp: __CL_ENABLE_EXCEPTIONS is deprecated. Define CL_HPP_ENABLE_EXCEPTIONS instead")
362# define CL_HPP_ENABLE_EXCEPTIONS
363#endif
364#if !defined(CL_HPP_NO_STD_VECTOR) && defined(__NO_STD_VECTOR)
365# pragma message("cl2.hpp: __NO_STD_VECTOR is deprecated. Define CL_HPP_NO_STD_VECTOR instead")
366# define CL_HPP_NO_STD_VECTOR
367#endif
368#if !defined(CL_HPP_NO_STD_STRING) && defined(__NO_STD_STRING)
369# pragma message("cl2.hpp: __NO_STD_STRING is deprecated. Define CL_HPP_NO_STD_STRING instead")
370# define CL_HPP_NO_STD_STRING
371#endif
372#if defined(VECTOR_CLASS)
373# pragma message("cl2.hpp: VECTOR_CLASS is deprecated. Alias cl::vector instead")
374#endif
375#if defined(STRING_CLASS)
376# pragma message("cl2.hpp: STRING_CLASS is deprecated. Alias cl::string instead.")
377#endif
378#if !defined(CL_HPP_USER_OVERRIDE_ERROR_STRINGS) && defined(__CL_USER_OVERRIDE_ERROR_STRINGS)
379# pragma message("cl2.hpp: __CL_USER_OVERRIDE_ERROR_STRINGS is deprecated. Define CL_HPP_USER_OVERRIDE_ERROR_STRINGS instead")
380# define CL_HPP_USER_OVERRIDE_ERROR_STRINGS
381#endif
382
383/* Warn about features that are no longer supported
384 */
385#if defined(__USE_DEV_VECTOR)
386# pragma message("cl2.hpp: __USE_DEV_VECTOR is no longer supported. Expect compilation errors")
387#endif
388#if defined(__USE_DEV_STRING)
389# pragma message("cl2.hpp: __USE_DEV_STRING is no longer supported. Expect compilation errors")
390#endif
391
392/* Detect which version to target */
393#if !defined(CL_HPP_TARGET_OPENCL_VERSION)
394# pragma message("cl2.hpp: CL_HPP_TARGET_OPENCL_VERSION is not defined. It will default to 200 (OpenCL 2.0)")
395# define CL_HPP_TARGET_OPENCL_VERSION 200
396#endif
397#if CL_HPP_TARGET_OPENCL_VERSION != 100 && CL_HPP_TARGET_OPENCL_VERSION != 110 && CL_HPP_TARGET_OPENCL_VERSION != 120 && CL_HPP_TARGET_OPENCL_VERSION != 200
398# pragma message("cl2.hpp: CL_HPP_TARGET_OPENCL_VERSION is not a valid value (100, 110, 120 or 200). It will be set to 200")
399# undef CL_HPP_TARGET_OPENCL_VERSION
400# define CL_HPP_TARGET_OPENCL_VERSION 200
401#endif
402
403#if !defined(CL_HPP_MINIMUM_OPENCL_VERSION)
404# define CL_HPP_MINIMUM_OPENCL_VERSION 200
405#endif
406#if CL_HPP_MINIMUM_OPENCL_VERSION != 100 && CL_HPP_MINIMUM_OPENCL_VERSION != 110 && CL_HPP_MINIMUM_OPENCL_VERSION != 120 && CL_HPP_MINIMUM_OPENCL_VERSION != 200
407# pragma message("cl2.hpp: CL_HPP_MINIMUM_OPENCL_VERSION is not a valid value (100, 110, 120 or 200). It will be set to 100")
408# undef CL_HPP_MINIMUM_OPENCL_VERSION
409# define CL_HPP_MINIMUM_OPENCL_VERSION 100
410#endif
411#if CL_HPP_MINIMUM_OPENCL_VERSION > CL_HPP_TARGET_OPENCL_VERSION
412# error "CL_HPP_MINIMUM_OPENCL_VERSION must not be greater than CL_HPP_TARGET_OPENCL_VERSION"
413#endif
414
415#if CL_HPP_MINIMUM_OPENCL_VERSION <= 100 && !defined(CL_USE_DEPRECATED_OPENCL_1_0_APIS)
416# define CL_USE_DEPRECATED_OPENCL_1_0_APIS
417#endif
418#if CL_HPP_MINIMUM_OPENCL_VERSION <= 110 && !defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
419# define CL_USE_DEPRECATED_OPENCL_1_1_APIS
420#endif
421#if CL_HPP_MINIMUM_OPENCL_VERSION <= 120 && !defined(CL_USE_DEPRECATED_OPENCL_1_2_APIS)
422# define CL_USE_DEPRECATED_OPENCL_1_2_APIS
423#endif
424#if CL_HPP_MINIMUM_OPENCL_VERSION <= 200 && !defined(CL_USE_DEPRECATED_OPENCL_2_0_APIS)
425# define CL_USE_DEPRECATED_OPENCL_2_0_APIS
426#endif
427
428#ifdef _WIN32
429
430#include <malloc.h>
431
432#if defined(CL_HPP_USE_DX_INTEROP)
433#include <CL/cl_d3d10.h>
434#include <CL/cl_dx9_media_sharing.h>
435#endif
436#endif // _WIN32
437
438#if defined(_MSC_VER)
439#include <intrin.h>
440#endif // _MSC_VER
441
442 // Check for a valid C++ version
443
444// Need to do both tests here because for some reason __cplusplus is not
445// updated in visual studio
446#if (!defined(_MSC_VER) && __cplusplus < 201103L) || (defined(_MSC_VER) && _MSC_VER < 1700)
447#error Visual studio 2013 or another C++11-supporting compiler required
448#endif
449
450//
451#if defined(CL_HPP_USE_CL_DEVICE_FISSION) || defined(CL_HPP_USE_CL_SUB_GROUPS_KHR)
452#include <CL/cl_ext.h>
453#endif
454
455#if defined(__APPLE__) || defined(__MACOSX)
456#include <OpenCL/opencl.h>
457#else
458#include <CL/opencl.h>
459#endif // !__APPLE__
460
461#if (__cplusplus >= 201103L)
462#define CL_HPP_NOEXCEPT_ noexcept
463#else
464#define CL_HPP_NOEXCEPT_
465#endif
466
467#if defined(_MSC_VER)
468# define CL_HPP_DEFINE_STATIC_MEMBER_ __declspec(selectany)
469#else
470# define CL_HPP_DEFINE_STATIC_MEMBER_ __attribute__((weak))
471#endif // !_MSC_VER
472
473// Define deprecated prefixes and suffixes to ensure compilation
474// in case they are not pre-defined
475#if !defined(CL_EXT_PREFIX__VERSION_1_1_DEPRECATED)
476#define CL_EXT_PREFIX__VERSION_1_1_DEPRECATED
477#endif // #if !defined(CL_EXT_PREFIX__VERSION_1_1_DEPRECATED)
478#if !defined(CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED)
479#define CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED
480#endif // #if !defined(CL_EXT_PREFIX__VERSION_1_1_DEPRECATED)
481
482#if !defined(CL_EXT_PREFIX__VERSION_1_2_DEPRECATED)
483#define CL_EXT_PREFIX__VERSION_1_2_DEPRECATED
484#endif // #if !defined(CL_EXT_PREFIX__VERSION_1_2_DEPRECATED)
485#if !defined(CL_EXT_SUFFIX__VERSION_1_2_DEPRECATED)
486#define CL_EXT_SUFFIX__VERSION_1_2_DEPRECATED
487#endif // #if !defined(CL_EXT_PREFIX__VERSION_1_2_DEPRECATED)
488
489#if !defined(CL_CALLBACK)
490#define CL_CALLBACK
491#endif //CL_CALLBACK
492
493#include <utility>
494#include <limits>
495#include <iterator>
496#include <mutex>
497#include <cstring>
498#include <functional>
499
500
501// Define a size_type to represent a correctly resolved size_t
502#if defined(CL_HPP_ENABLE_SIZE_T_COMPATIBILITY)
503namespace cl {
504 using size_type = ::size_t;
505} // namespace cl
506#else // #if defined(CL_HPP_ENABLE_SIZE_T_COMPATIBILITY)
507namespace cl {
508 using size_type = size_t;
509} // namespace cl
510#endif // #if defined(CL_HPP_ENABLE_SIZE_T_COMPATIBILITY)
511
512
513#if defined(CL_HPP_ENABLE_EXCEPTIONS)
514#include <exception>
515#endif // #if defined(CL_HPP_ENABLE_EXCEPTIONS)
516
517#if !defined(CL_HPP_NO_STD_VECTOR)
518#include <vector>
519namespace cl {
520 template < class T, class Alloc = std::allocator<T> >
521 using vector = std::vector<T, Alloc>;
522} // namespace cl
523#endif // #if !defined(CL_HPP_NO_STD_VECTOR)
524
525#if !defined(CL_HPP_NO_STD_STRING)
526#include <string>
527namespace cl {
528 using string = std::string;
529} // namespace cl
530#endif // #if !defined(CL_HPP_NO_STD_STRING)
531
532#if CL_HPP_TARGET_OPENCL_VERSION >= 200
533
534#if !defined(CL_HPP_NO_STD_UNIQUE_PTR)
535#include <memory>
536namespace cl {
537 // Replace unique_ptr and allocate_pointer for internal use
538 // to allow user to replace them
539 template<class T, class D>
540 using pointer = std::unique_ptr<T, D>;
541} // namespace cl
542#endif
543#endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 200
544#if !defined(CL_HPP_NO_STD_ARRAY)
545#include <array>
546namespace cl {
547 template < class T, size_type N >
548 using array = std::array<T, N>;
549} // namespace cl
550#endif // #if !defined(CL_HPP_NO_STD_ARRAY)
551
552// Define size_type appropriately to allow backward-compatibility
553// use of the old size_t interface class
554#if defined(CL_HPP_ENABLE_SIZE_T_COMPATIBILITY)
555namespace cl {
556 namespace compatibility {
557 /*! \brief class used to interface between C++ and
558 * OpenCL C calls that require arrays of size_t values, whose
559 * size is known statically.
560 */
561 template <int N>
562 class size_t
563 {
564 private:
565 size_type data_[N];
566
567 public:
568 //! \brief Initialize size_t to all 0s
569 size_t()
570 {
571 for (int i = 0; i < N; ++i) {
572 data_[i] = 0;
573 }
574 }
575
576 size_t(const array<size_type, N> &rhs)
577 {
578 for (int i = 0; i < N; ++i) {
579 data_[i] = rhs[i];
580 }
581 }
582
583 size_type& operator[](int index)
584 {
585 return data_[index];
586 }
587
588 const size_type& operator[](int index) const
589 {
590 return data_[index];
591 }
592
593 //! \brief Conversion operator to T*.
594 operator size_type* () { return data_; }
595
596 //! \brief Conversion operator to const T*.
597 operator const size_type* () const { return data_; }
598
599 operator array<size_type, N>() const
600 {
601 array<size_type, N> ret;
602
603 for (int i = 0; i < N; ++i) {
604 ret[i] = data_[i];
605 }
606 return ret;
607 }
608 };
609 } // namespace compatibility
610
611 template<int N>
612 using size_t = compatibility::size_t<N>;
613} // namespace cl
614#endif // #if defined(CL_HPP_ENABLE_SIZE_T_COMPATIBILITY)
615
616// Helper alias to avoid confusing the macros
617namespace cl {
618 namespace detail {
619 using size_t_array = array<size_type, 3>;
620 } // namespace detail
621} // namespace cl
622
623
624/*! \namespace cl
625 *
626 * \brief The OpenCL C++ bindings are defined within this namespace.
627 *
628 */
629namespace cl {
630 class Memory;
631
632#define CL_HPP_INIT_CL_EXT_FCN_PTR_(name) \
633 if (!pfn_##name) { \
634 pfn_##name = (PFN_##name) \
635 clGetExtensionFunctionAddress(#name); \
636 if (!pfn_##name) { \
637 } \
638 }
639
640#define CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, name) \
641 if (!pfn_##name) { \
642 pfn_##name = (PFN_##name) \
643 clGetExtensionFunctionAddressForPlatform(platform, #name); \
644 if (!pfn_##name) { \
645 } \
646 }
647
648 class Program;
649 class Device;
650 class Context;
651 class CommandQueue;
652 class DeviceCommandQueue;
653 class Memory;
654 class Buffer;
655 class Pipe;
656
657#if defined(CL_HPP_ENABLE_EXCEPTIONS)
658 /*! \brief Exception class
659 *
660 * This may be thrown by API functions when CL_HPP_ENABLE_EXCEPTIONS is defined.
661 */
662 class Error : public std::exception
663 {
664 private:
665 cl_int err_;
666 const char * errStr_;
667 public:
668 /*! \brief Create a new CL error exception for a given error code
669 * and corresponding message.
670 *
671 * \param err error code value.
672 *
673 * \param errStr a descriptive string that must remain in scope until
674 * handling of the exception has concluded. If set, it
675 * will be returned by what().
676 */
677 Error(cl_int err, const char * errStr = NULL) : err_(err), errStr_(errStr)
678 {}
679
680 ~Error() throw() {}
681
682 /*! \brief Get error string associated with exception
683 *
684 * \return A memory pointer to the error message string.
685 */
686 virtual const char * what() const throw ()
687 {
688 if (errStr_ == NULL) {
689 return "empty";
690 }
691 else {
692 return errStr_;
693 }
694 }
695
696 /*! \brief Get error code associated with exception
697 *
698 * \return The error code.
699 */
700 cl_int err(void) const { return err_; }
701 };
702#define CL_HPP_ERR_STR_(x) #x
703#else
704#define CL_HPP_ERR_STR_(x) NULL
705#endif // CL_HPP_ENABLE_EXCEPTIONS
706
707
708namespace detail
709{
710#if defined(CL_HPP_ENABLE_EXCEPTIONS)
711static inline cl_int errHandler (
712 cl_int err,
713 const char * errStr = NULL)
714{
715 if (err != CL_SUCCESS) {
716 throw Error(err, errStr);
717 }
718 return err;
719}
720#else
721static inline cl_int errHandler (cl_int err, const char * errStr = NULL)
722{
723 (void) errStr; // suppress unused variable warning
724 return err;
725}
726#endif // CL_HPP_ENABLE_EXCEPTIONS
727}
728
729
730
731//! \cond DOXYGEN_DETAIL
732#if !defined(CL_HPP_USER_OVERRIDE_ERROR_STRINGS)
733#define __GET_DEVICE_INFO_ERR CL_HPP_ERR_STR_(clGetDeviceInfo)
734#define __GET_PLATFORM_INFO_ERR CL_HPP_ERR_STR_(clGetPlatformInfo)
735#define __GET_DEVICE_IDS_ERR CL_HPP_ERR_STR_(clGetDeviceIDs)
736#define __GET_PLATFORM_IDS_ERR CL_HPP_ERR_STR_(clGetPlatformIDs)
737#define __GET_CONTEXT_INFO_ERR CL_HPP_ERR_STR_(clGetContextInfo)
738#define __GET_EVENT_INFO_ERR CL_HPP_ERR_STR_(clGetEventInfo)
739#define __GET_EVENT_PROFILE_INFO_ERR CL_HPP_ERR_STR_(clGetEventProfileInfo)
740#define __GET_MEM_OBJECT_INFO_ERR CL_HPP_ERR_STR_(clGetMemObjectInfo)
741#define __GET_IMAGE_INFO_ERR CL_HPP_ERR_STR_(clGetImageInfo)
742#define __GET_SAMPLER_INFO_ERR CL_HPP_ERR_STR_(clGetSamplerInfo)
743#define __GET_KERNEL_INFO_ERR CL_HPP_ERR_STR_(clGetKernelInfo)
744#if CL_HPP_TARGET_OPENCL_VERSION >= 120
745#define __GET_KERNEL_ARG_INFO_ERR CL_HPP_ERR_STR_(clGetKernelArgInfo)
746#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
747#define __GET_KERNEL_WORK_GROUP_INFO_ERR CL_HPP_ERR_STR_(clGetKernelWorkGroupInfo)
748#define __GET_PROGRAM_INFO_ERR CL_HPP_ERR_STR_(clGetProgramInfo)
749#define __GET_PROGRAM_BUILD_INFO_ERR CL_HPP_ERR_STR_(clGetProgramBuildInfo)
750#define __GET_COMMAND_QUEUE_INFO_ERR CL_HPP_ERR_STR_(clGetCommandQueueInfo)
751
752#define __CREATE_CONTEXT_ERR CL_HPP_ERR_STR_(clCreateContext)
753#define __CREATE_CONTEXT_FROM_TYPE_ERR CL_HPP_ERR_STR_(clCreateContextFromType)
754#define __GET_SUPPORTED_IMAGE_FORMATS_ERR CL_HPP_ERR_STR_(clGetSupportedImageFormats)
755
756#define __CREATE_BUFFER_ERR CL_HPP_ERR_STR_(clCreateBuffer)
757#define __COPY_ERR CL_HPP_ERR_STR_(cl::copy)
758#define __CREATE_SUBBUFFER_ERR CL_HPP_ERR_STR_(clCreateSubBuffer)
759#define __CREATE_GL_BUFFER_ERR CL_HPP_ERR_STR_(clCreateFromGLBuffer)
760#define __CREATE_GL_RENDER_BUFFER_ERR CL_HPP_ERR_STR_(clCreateFromGLBuffer)
761#define __GET_GL_OBJECT_INFO_ERR CL_HPP_ERR_STR_(clGetGLObjectInfo)
762#if CL_HPP_TARGET_OPENCL_VERSION >= 120
763#define __CREATE_IMAGE_ERR CL_HPP_ERR_STR_(clCreateImage)
764#define __CREATE_GL_TEXTURE_ERR CL_HPP_ERR_STR_(clCreateFromGLTexture)
765#define __IMAGE_DIMENSION_ERR CL_HPP_ERR_STR_(Incorrect image dimensions)
766#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
767#define __SET_MEM_OBJECT_DESTRUCTOR_CALLBACK_ERR CL_HPP_ERR_STR_(clSetMemObjectDestructorCallback)
768
769#define __CREATE_USER_EVENT_ERR CL_HPP_ERR_STR_(clCreateUserEvent)
770#define __SET_USER_EVENT_STATUS_ERR CL_HPP_ERR_STR_(clSetUserEventStatus)
771#define __SET_EVENT_CALLBACK_ERR CL_HPP_ERR_STR_(clSetEventCallback)
772#define __WAIT_FOR_EVENTS_ERR CL_HPP_ERR_STR_(clWaitForEvents)
773
774#define __CREATE_KERNEL_ERR CL_HPP_ERR_STR_(clCreateKernel)
775#define __SET_KERNEL_ARGS_ERR CL_HPP_ERR_STR_(clSetKernelArg)
776#define __CREATE_PROGRAM_WITH_SOURCE_ERR CL_HPP_ERR_STR_(clCreateProgramWithSource)
777#define __CREATE_PROGRAM_WITH_BINARY_ERR CL_HPP_ERR_STR_(clCreateProgramWithBinary)
778#if CL_HPP_TARGET_OPENCL_VERSION >= 120
779#define __CREATE_PROGRAM_WITH_BUILT_IN_KERNELS_ERR CL_HPP_ERR_STR_(clCreateProgramWithBuiltInKernels)
780#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
781#define __BUILD_PROGRAM_ERR CL_HPP_ERR_STR_(clBuildProgram)
782#if CL_HPP_TARGET_OPENCL_VERSION >= 120
783#define __COMPILE_PROGRAM_ERR CL_HPP_ERR_STR_(clCompileProgram)
784#define __LINK_PROGRAM_ERR CL_HPP_ERR_STR_(clLinkProgram)
785#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
786#define __CREATE_KERNELS_IN_PROGRAM_ERR CL_HPP_ERR_STR_(clCreateKernelsInProgram)
787
788#if CL_HPP_TARGET_OPENCL_VERSION >= 200
789#define __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR CL_HPP_ERR_STR_(clCreateCommandQueueWithProperties)
790#define __CREATE_SAMPLER_WITH_PROPERTIES_ERR CL_HPP_ERR_STR_(clCreateSamplerWithProperties)
791#endif // CL_HPP_TARGET_OPENCL_VERSION >= 200
792#define __SET_COMMAND_QUEUE_PROPERTY_ERR CL_HPP_ERR_STR_(clSetCommandQueueProperty)
793#define __ENQUEUE_READ_BUFFER_ERR CL_HPP_ERR_STR_(clEnqueueReadBuffer)
794#define __ENQUEUE_READ_BUFFER_RECT_ERR CL_HPP_ERR_STR_(clEnqueueReadBufferRect)
795#define __ENQUEUE_WRITE_BUFFER_ERR CL_HPP_ERR_STR_(clEnqueueWriteBuffer)
796#define __ENQUEUE_WRITE_BUFFER_RECT_ERR CL_HPP_ERR_STR_(clEnqueueWriteBufferRect)
797#define __ENQEUE_COPY_BUFFER_ERR CL_HPP_ERR_STR_(clEnqueueCopyBuffer)
798#define __ENQEUE_COPY_BUFFER_RECT_ERR CL_HPP_ERR_STR_(clEnqueueCopyBufferRect)
799#define __ENQUEUE_FILL_BUFFER_ERR CL_HPP_ERR_STR_(clEnqueueFillBuffer)
800#define __ENQUEUE_READ_IMAGE_ERR CL_HPP_ERR_STR_(clEnqueueReadImage)
801#define __ENQUEUE_WRITE_IMAGE_ERR CL_HPP_ERR_STR_(clEnqueueWriteImage)
802#define __ENQUEUE_COPY_IMAGE_ERR CL_HPP_ERR_STR_(clEnqueueCopyImage)
803#define __ENQUEUE_FILL_IMAGE_ERR CL_HPP_ERR_STR_(clEnqueueFillImage)
804#define __ENQUEUE_COPY_IMAGE_TO_BUFFER_ERR CL_HPP_ERR_STR_(clEnqueueCopyImageToBuffer)
805#define __ENQUEUE_COPY_BUFFER_TO_IMAGE_ERR CL_HPP_ERR_STR_(clEnqueueCopyBufferToImage)
806#define __ENQUEUE_MAP_BUFFER_ERR CL_HPP_ERR_STR_(clEnqueueMapBuffer)
807#define __ENQUEUE_MAP_IMAGE_ERR CL_HPP_ERR_STR_(clEnqueueMapImage)
808#define __ENQUEUE_UNMAP_MEM_OBJECT_ERR CL_HPP_ERR_STR_(clEnqueueUnMapMemObject)
809#define __ENQUEUE_NDRANGE_KERNEL_ERR CL_HPP_ERR_STR_(clEnqueueNDRangeKernel)
810#define __ENQUEUE_NATIVE_KERNEL CL_HPP_ERR_STR_(clEnqueueNativeKernel)
811#if CL_HPP_TARGET_OPENCL_VERSION >= 120
812#define __ENQUEUE_MIGRATE_MEM_OBJECTS_ERR CL_HPP_ERR_STR_(clEnqueueMigrateMemObjects)
813#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
814
815#define __ENQUEUE_ACQUIRE_GL_ERR CL_HPP_ERR_STR_(clEnqueueAcquireGLObjects)
816#define __ENQUEUE_RELEASE_GL_ERR CL_HPP_ERR_STR_(clEnqueueReleaseGLObjects)
817
818#define __CREATE_PIPE_ERR CL_HPP_ERR_STR_(clCreatePipe)
819#define __GET_PIPE_INFO_ERR CL_HPP_ERR_STR_(clGetPipeInfo)
820
821
822#define __RETAIN_ERR CL_HPP_ERR_STR_(Retain Object)
823#define __RELEASE_ERR CL_HPP_ERR_STR_(Release Object)
824#define __FLUSH_ERR CL_HPP_ERR_STR_(clFlush)
825#define __FINISH_ERR CL_HPP_ERR_STR_(clFinish)
826#define __VECTOR_CAPACITY_ERR CL_HPP_ERR_STR_(Vector capacity error)
827
828/**
829 * CL 1.2 version that uses device fission.
830 */
831#if CL_HPP_TARGET_OPENCL_VERSION >= 120
832#define __CREATE_SUB_DEVICES_ERR CL_HPP_ERR_STR_(clCreateSubDevices)
833#else
834#define __CREATE_SUB_DEVICES_ERR CL_HPP_ERR_STR_(clCreateSubDevicesEXT)
835#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
836
837/**
838 * Deprecated APIs for 1.2
839 */
840#if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
841#define __ENQUEUE_MARKER_ERR CL_HPP_ERR_STR_(clEnqueueMarker)
842#define __ENQUEUE_WAIT_FOR_EVENTS_ERR CL_HPP_ERR_STR_(clEnqueueWaitForEvents)
843#define __ENQUEUE_BARRIER_ERR CL_HPP_ERR_STR_(clEnqueueBarrier)
844#define __UNLOAD_COMPILER_ERR CL_HPP_ERR_STR_(clUnloadCompiler)
845#define __CREATE_GL_TEXTURE_2D_ERR CL_HPP_ERR_STR_(clCreateFromGLTexture2D)
846#define __CREATE_GL_TEXTURE_3D_ERR CL_HPP_ERR_STR_(clCreateFromGLTexture3D)
847#define __CREATE_IMAGE2D_ERR CL_HPP_ERR_STR_(clCreateImage2D)
848#define __CREATE_IMAGE3D_ERR CL_HPP_ERR_STR_(clCreateImage3D)
849#endif // #if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
850
851/**
852 * Deprecated APIs for 2.0
853 */
854#if defined(CL_USE_DEPRECATED_OPENCL_1_2_APIS)
855#define __CREATE_COMMAND_QUEUE_ERR CL_HPP_ERR_STR_(clCreateCommandQueue)
856#define __ENQUEUE_TASK_ERR CL_HPP_ERR_STR_(clEnqueueTask)
857#define __CREATE_SAMPLER_ERR CL_HPP_ERR_STR_(clCreateSampler)
858#endif // #if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
859
860/**
861 * CL 1.2 marker and barrier commands
862 */
863#if CL_HPP_TARGET_OPENCL_VERSION >= 120
864#define __ENQUEUE_MARKER_WAIT_LIST_ERR CL_HPP_ERR_STR_(clEnqueueMarkerWithWaitList)
865#define __ENQUEUE_BARRIER_WAIT_LIST_ERR CL_HPP_ERR_STR_(clEnqueueBarrierWithWaitList)
866#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
867
868#endif // CL_HPP_USER_OVERRIDE_ERROR_STRINGS
869//! \endcond
870
871
872namespace detail {
873
874// Generic getInfoHelper. The final parameter is used to guide overload
875// resolution: the actual parameter passed is an int, which makes this
876// a worse conversion sequence than a specialization that declares the
877// parameter as an int.
878template<typename Functor, typename T>
879inline cl_int getInfoHelper(Functor f, cl_uint name, T* param, long)
880{
881 return f(name, sizeof(T), param, NULL);
882}
883
884// Specialized for getInfo<CL_PROGRAM_BINARIES>
885// Assumes that the output vector was correctly resized on the way in
886template <typename Func>
887inline cl_int getInfoHelper(Func f, cl_uint name, vector<vector<unsigned char>>* param, int)
888{
889 if (name != CL_PROGRAM_BINARIES) {
890 return CL_INVALID_VALUE;
891 }
892 if (param) {
893 // Create array of pointers, calculate total size and pass pointer array in
894 size_type numBinaries = param->size();
895 vector<unsigned char*> binariesPointers(numBinaries);
896
897 size_type totalSize = 0;
898 for (size_type i = 0; i < numBinaries; ++i)
899 {
900 binariesPointers[i] = (*param)[i].data();
901 totalSize += (*param)[i].size();
902 }
903
904 cl_int err = f(name, totalSize, binariesPointers.data(), NULL);
905
906 if (err != CL_SUCCESS) {
907 return err;
908 }
909 }
910
911
912 return CL_SUCCESS;
913}
914
915// Specialized getInfoHelper for vector params
916template <typename Func, typename T>
917inline cl_int getInfoHelper(Func f, cl_uint name, vector<T>* param, long)
918{
919 size_type required;
920 cl_int err = f(name, 0, NULL, &required);
921 if (err != CL_SUCCESS) {
922 return err;
923 }
924 const size_type elements = required / sizeof(T);
925
926 // Temporary to avoid changing param on an error
927 vector<T> localData(elements);
928 err = f(name, required, localData.data(), NULL);
929 if (err != CL_SUCCESS) {
930 return err;
931 }
932 if (param) {
933 *param = std::move(localData);
934 }
935
936 return CL_SUCCESS;
937}
938
939/* Specialization for reference-counted types. This depends on the
940 * existence of Wrapper<T>::cl_type, and none of the other types having the
941 * cl_type member. Note that simplify specifying the parameter as Wrapper<T>
942 * does not work, because when using a derived type (e.g. Context) the generic
943 * template will provide a better match.
944 */
945template <typename Func, typename T>
946inline cl_int getInfoHelper(
947 Func f, cl_uint name, vector<T>* param, int, typename T::cl_type = 0)
948{
949 size_type required;
950 cl_int err = f(name, 0, NULL, &required);
951 if (err != CL_SUCCESS) {
952 return err;
953 }
954
955 const size_type elements = required / sizeof(typename T::cl_type);
956
957 vector<typename T::cl_type> value(elements);
958 err = f(name, required, value.data(), NULL);
959 if (err != CL_SUCCESS) {
960 return err;
961 }
962
963 if (param) {
964 // Assign to convert CL type to T for each element
965 param->resize(elements);
966
967 // Assign to param, constructing with retain behaviour
968 // to correctly capture each underlying CL object
969 for (size_type i = 0; i < elements; i++) {
970 (*param)[i] = T(value[i], true);
971 }
972 }
973 return CL_SUCCESS;
974}
975
976// Specialized GetInfoHelper for string params
977template <typename Func>
978inline cl_int getInfoHelper(Func f, cl_uint name, string* param, long)
979{
980 size_type required;
981 cl_int err = f(name, 0, NULL, &required);
982 if (err != CL_SUCCESS) {
983 return err;
984 }
985
986 // std::string has a constant data member
987 // a char vector does not
988 if (required > 0) {
989 vector<char> value(required);
990 err = f(name, required, value.data(), NULL);
991 if (err != CL_SUCCESS) {
992 return err;
993 }
994 if (param) {
995 param->assign(begin(value), prev(end(value)));
996 }
997 }
998 else if (param) {
999 param->assign("");
1000 }
1001 return CL_SUCCESS;
1002}
1003
1004// Specialized GetInfoHelper for clsize_t params
1005template <typename Func, size_type N>
1006inline cl_int getInfoHelper(Func f, cl_uint name, array<size_type, N>* param, long)
1007{
1008 size_type required;
1009 cl_int err = f(name, 0, NULL, &required);
1010 if (err != CL_SUCCESS) {
1011 return err;
1012 }
1013
1014 size_type elements = required / sizeof(size_type);
1015 vector<size_type> value(elements, 0);
1016
1017 err = f(name, required, value.data(), NULL);
1018 if (err != CL_SUCCESS) {
1019 return err;
1020 }
1021
1022 // Bound the copy with N to prevent overruns
1023 // if passed N > than the amount copied
1024 if (elements > N) {
1025 elements = N;
1026 }
1027 for (size_type i = 0; i < elements; ++i) {
1028 (*param)[i] = value[i];
1029 }
1030
1031 return CL_SUCCESS;
1032}
1033
1034template<typename T> struct ReferenceHandler;
1035
1036/* Specialization for reference-counted types. This depends on the
1037 * existence of Wrapper<T>::cl_type, and none of the other types having the
1038 * cl_type member. Note that simplify specifying the parameter as Wrapper<T>
1039 * does not work, because when using a derived type (e.g. Context) the generic
1040 * template will provide a better match.
1041 */
1042template<typename Func, typename T>
1043inline cl_int getInfoHelper(Func f, cl_uint name, T* param, int, typename T::cl_type = 0)
1044{
1045 typename T::cl_type value;
1046 cl_int err = f(name, sizeof(value), &value, NULL);
1047 if (err != CL_SUCCESS) {
1048 return err;
1049 }
1050 *param = value;
1051 if (value != NULL)
1052 {
1053 err = param->retain();
1054 if (err != CL_SUCCESS) {
1055 return err;
1056 }
1057 }
1058 return CL_SUCCESS;
1059}
1060
1061#define CL_HPP_PARAM_NAME_INFO_1_0_(F) \
1062 F(cl_platform_info, CL_PLATFORM_PROFILE, string) \
1063 F(cl_platform_info, CL_PLATFORM_VERSION, string) \
1064 F(cl_platform_info, CL_PLATFORM_NAME, string) \
1065 F(cl_platform_info, CL_PLATFORM_VENDOR, string) \
1066 F(cl_platform_info, CL_PLATFORM_EXTENSIONS, string) \
1067 \
1068 F(cl_device_info, CL_DEVICE_TYPE, cl_device_type) \
1069 F(cl_device_info, CL_DEVICE_VENDOR_ID, cl_uint) \
1070 F(cl_device_info, CL_DEVICE_MAX_COMPUTE_UNITS, cl_uint) \
1071 F(cl_device_info, CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS, cl_uint) \
1072 F(cl_device_info, CL_DEVICE_MAX_WORK_GROUP_SIZE, size_type) \
1073 F(cl_device_info, CL_DEVICE_MAX_WORK_ITEM_SIZES, cl::vector<size_type>) \
1074 F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR, cl_uint) \
1075 F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT, cl_uint) \
1076 F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT, cl_uint) \
1077 F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG, cl_uint) \
1078 F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT, cl_uint) \
1079 F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE, cl_uint) \
1080 F(cl_device_info, CL_DEVICE_MAX_CLOCK_FREQUENCY, cl_uint) \
1081 F(cl_device_info, CL_DEVICE_ADDRESS_BITS, cl_uint) \
1082 F(cl_device_info, CL_DEVICE_MAX_READ_IMAGE_ARGS, cl_uint) \
1083 F(cl_device_info, CL_DEVICE_MAX_WRITE_IMAGE_ARGS, cl_uint) \
1084 F(cl_device_info, CL_DEVICE_MAX_MEM_ALLOC_SIZE, cl_ulong) \
1085 F(cl_device_info, CL_DEVICE_IMAGE2D_MAX_WIDTH, size_type) \
1086 F(cl_device_info, CL_DEVICE_IMAGE2D_MAX_HEIGHT, size_type) \
1087 F(cl_device_info, CL_DEVICE_IMAGE3D_MAX_WIDTH, size_type) \
1088 F(cl_device_info, CL_DEVICE_IMAGE3D_MAX_HEIGHT, size_type) \
1089 F(cl_device_info, CL_DEVICE_IMAGE3D_MAX_DEPTH, size_type) \
1090 F(cl_device_info, CL_DEVICE_IMAGE_SUPPORT, cl_bool) \
1091 F(cl_device_info, CL_DEVICE_MAX_PARAMETER_SIZE, size_type) \
1092 F(cl_device_info, CL_DEVICE_MAX_SAMPLERS, cl_uint) \
1093 F(cl_device_info, CL_DEVICE_MEM_BASE_ADDR_ALIGN, cl_uint) \
1094 F(cl_device_info, CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE, cl_uint) \
1095 F(cl_device_info, CL_DEVICE_SINGLE_FP_CONFIG, cl_device_fp_config) \
1096 F(cl_device_info, CL_DEVICE_GLOBAL_MEM_CACHE_TYPE, cl_device_mem_cache_type) \
1097 F(cl_device_info, CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE, cl_uint)\
1098 F(cl_device_info, CL_DEVICE_GLOBAL_MEM_CACHE_SIZE, cl_ulong) \
1099 F(cl_device_info, CL_DEVICE_GLOBAL_MEM_SIZE, cl_ulong) \
1100 F(cl_device_info, CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE, cl_ulong) \
1101 F(cl_device_info, CL_DEVICE_MAX_CONSTANT_ARGS, cl_uint) \
1102 F(cl_device_info, CL_DEVICE_LOCAL_MEM_TYPE, cl_device_local_mem_type) \
1103 F(cl_device_info, CL_DEVICE_LOCAL_MEM_SIZE, cl_ulong) \
1104 F(cl_device_info, CL_DEVICE_ERROR_CORRECTION_SUPPORT, cl_bool) \
1105 F(cl_device_info, CL_DEVICE_PROFILING_TIMER_RESOLUTION, size_type) \
1106 F(cl_device_info, CL_DEVICE_ENDIAN_LITTLE, cl_bool) \
1107 F(cl_device_info, CL_DEVICE_AVAILABLE, cl_bool) \
1108 F(cl_device_info, CL_DEVICE_COMPILER_AVAILABLE, cl_bool) \
1109 F(cl_device_info, CL_DEVICE_EXECUTION_CAPABILITIES, cl_device_exec_capabilities) \
1110 F(cl_device_info, CL_DEVICE_PLATFORM, cl_platform_id) \
1111 F(cl_device_info, CL_DEVICE_NAME, string) \
1112 F(cl_device_info, CL_DEVICE_VENDOR, string) \
1113 F(cl_device_info, CL_DRIVER_VERSION, string) \
1114 F(cl_device_info, CL_DEVICE_PROFILE, string) \
1115 F(cl_device_info, CL_DEVICE_VERSION, string) \
1116 F(cl_device_info, CL_DEVICE_EXTENSIONS, string) \
1117 \
1118 F(cl_context_info, CL_CONTEXT_REFERENCE_COUNT, cl_uint) \
1119 F(cl_context_info, CL_CONTEXT_DEVICES, cl::vector<Device>) \
1120 F(cl_context_info, CL_CONTEXT_PROPERTIES, cl::vector<cl_context_properties>) \
1121 \
1122 F(cl_event_info, CL_EVENT_COMMAND_QUEUE, cl::CommandQueue) \
1123 F(cl_event_info, CL_EVENT_COMMAND_TYPE, cl_command_type) \
1124 F(cl_event_info, CL_EVENT_REFERENCE_COUNT, cl_uint) \
1125 F(cl_event_info, CL_EVENT_COMMAND_EXECUTION_STATUS, cl_int) \
1126 \
1127 F(cl_profiling_info, CL_PROFILING_COMMAND_QUEUED, cl_ulong) \
1128 F(cl_profiling_info, CL_PROFILING_COMMAND_SUBMIT, cl_ulong) \
1129 F(cl_profiling_info, CL_PROFILING_COMMAND_START, cl_ulong) \
1130 F(cl_profiling_info, CL_PROFILING_COMMAND_END, cl_ulong) \
1131 \
1132 F(cl_mem_info, CL_MEM_TYPE, cl_mem_object_type) \
1133 F(cl_mem_info, CL_MEM_FLAGS, cl_mem_flags) \
1134 F(cl_mem_info, CL_MEM_SIZE, size_type) \
1135 F(cl_mem_info, CL_MEM_HOST_PTR, void*) \
1136 F(cl_mem_info, CL_MEM_MAP_COUNT, cl_uint) \
1137 F(cl_mem_info, CL_MEM_REFERENCE_COUNT, cl_uint) \
1138 F(cl_mem_info, CL_MEM_CONTEXT, cl::Context) \
1139 \
1140 F(cl_image_info, CL_IMAGE_FORMAT, cl_image_format) \
1141 F(cl_image_info, CL_IMAGE_ELEMENT_SIZE, size_type) \
1142 F(cl_image_info, CL_IMAGE_ROW_PITCH, size_type) \
1143 F(cl_image_info, CL_IMAGE_SLICE_PITCH, size_type) \
1144 F(cl_image_info, CL_IMAGE_WIDTH, size_type) \
1145 F(cl_image_info, CL_IMAGE_HEIGHT, size_type) \
1146 F(cl_image_info, CL_IMAGE_DEPTH, size_type) \
1147 \
1148 F(cl_sampler_info, CL_SAMPLER_REFERENCE_COUNT, cl_uint) \
1149 F(cl_sampler_info, CL_SAMPLER_CONTEXT, cl::Context) \
1150 F(cl_sampler_info, CL_SAMPLER_NORMALIZED_COORDS, cl_bool) \
1151 F(cl_sampler_info, CL_SAMPLER_ADDRESSING_MODE, cl_addressing_mode) \
1152 F(cl_sampler_info, CL_SAMPLER_FILTER_MODE, cl_filter_mode) \
1153 \
1154 F(cl_program_info, CL_PROGRAM_REFERENCE_COUNT, cl_uint) \
1155 F(cl_program_info, CL_PROGRAM_CONTEXT, cl::Context) \
1156 F(cl_program_info, CL_PROGRAM_NUM_DEVICES, cl_uint) \
1157 F(cl_program_info, CL_PROGRAM_DEVICES, cl::vector<Device>) \
1158 F(cl_program_info, CL_PROGRAM_SOURCE, string) \
1159 F(cl_program_info, CL_PROGRAM_BINARY_SIZES, cl::vector<size_type>) \
1160 F(cl_program_info, CL_PROGRAM_BINARIES, cl::vector<cl::vector<unsigned char>>) \
1161 \
1162 F(cl_program_build_info, CL_PROGRAM_BUILD_STATUS, cl_build_status) \
1163 F(cl_program_build_info, CL_PROGRAM_BUILD_OPTIONS, string) \
1164 F(cl_program_build_info, CL_PROGRAM_BUILD_LOG, string) \
1165 \
1166 F(cl_kernel_info, CL_KERNEL_FUNCTION_NAME, string) \
1167 F(cl_kernel_info, CL_KERNEL_NUM_ARGS, cl_uint) \
1168 F(cl_kernel_info, CL_KERNEL_REFERENCE_COUNT, cl_uint) \
1169 F(cl_kernel_info, CL_KERNEL_CONTEXT, cl::Context) \
1170 F(cl_kernel_info, CL_KERNEL_PROGRAM, cl::Program) \
1171 \
1172 F(cl_kernel_work_group_info, CL_KERNEL_WORK_GROUP_SIZE, size_type) \
1173 F(cl_kernel_work_group_info, CL_KERNEL_COMPILE_WORK_GROUP_SIZE, cl::detail::size_t_array) \
1174 F(cl_kernel_work_group_info, CL_KERNEL_LOCAL_MEM_SIZE, cl_ulong) \
1175 \
1176 F(cl_command_queue_info, CL_QUEUE_CONTEXT, cl::Context) \
1177 F(cl_command_queue_info, CL_QUEUE_DEVICE, cl::Device) \
1178 F(cl_command_queue_info, CL_QUEUE_REFERENCE_COUNT, cl_uint) \
1179 F(cl_command_queue_info, CL_QUEUE_PROPERTIES, cl_command_queue_properties)
1180
1181
1182#define CL_HPP_PARAM_NAME_INFO_1_1_(F) \
1183 F(cl_context_info, CL_CONTEXT_NUM_DEVICES, cl_uint)\
1184 F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF, cl_uint) \
1185 F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR, cl_uint) \
1186 F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT, cl_uint) \
1187 F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_INT, cl_uint) \
1188 F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG, cl_uint) \
1189 F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT, cl_uint) \
1190 F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE, cl_uint) \
1191 F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF, cl_uint) \
1192 F(cl_device_info, CL_DEVICE_DOUBLE_FP_CONFIG, cl_device_fp_config) \
1193 F(cl_device_info, CL_DEVICE_HALF_FP_CONFIG, cl_device_fp_config) \
1194 F(cl_device_info, CL_DEVICE_OPENCL_C_VERSION, string) \
1195 \
1196 F(cl_mem_info, CL_MEM_ASSOCIATED_MEMOBJECT, cl::Memory) \
1197 F(cl_mem_info, CL_MEM_OFFSET, size_type) \
1198 \
1199 F(cl_kernel_work_group_info, CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE, size_type) \
1200 F(cl_kernel_work_group_info, CL_KERNEL_PRIVATE_MEM_SIZE, cl_ulong) \
1201 \
1202 F(cl_event_info, CL_EVENT_CONTEXT, cl::Context)
1203
1204#define CL_HPP_PARAM_NAME_INFO_1_2_(F) \
1205 F(cl_program_info, CL_PROGRAM_NUM_KERNELS, size_type) \
1206 F(cl_program_info, CL_PROGRAM_KERNEL_NAMES, string) \
1207 \
1208 F(cl_program_build_info, CL_PROGRAM_BINARY_TYPE, cl_program_binary_type) \
1209 \
1210 F(cl_kernel_info, CL_KERNEL_ATTRIBUTES, string) \
1211 \
1212 F(cl_kernel_arg_info, CL_KERNEL_ARG_ADDRESS_QUALIFIER, cl_kernel_arg_address_qualifier) \
1213 F(cl_kernel_arg_info, CL_KERNEL_ARG_ACCESS_QUALIFIER, cl_kernel_arg_access_qualifier) \
1214 F(cl_kernel_arg_info, CL_KERNEL_ARG_TYPE_NAME, string) \
1215 F(cl_kernel_arg_info, CL_KERNEL_ARG_NAME, string) \
1216 F(cl_kernel_arg_info, CL_KERNEL_ARG_TYPE_QUALIFIER, cl_kernel_arg_type_qualifier) \
1217 \
1218 F(cl_device_info, CL_DEVICE_PARENT_DEVICE, cl::Device) \
1219 F(cl_device_info, CL_DEVICE_PARTITION_PROPERTIES, cl::vector<cl_device_partition_property>) \
1220 F(cl_device_info, CL_DEVICE_PARTITION_TYPE, cl::vector<cl_device_partition_property>) \
1221 F(cl_device_info, CL_DEVICE_REFERENCE_COUNT, cl_uint) \
1222 F(cl_device_info, CL_DEVICE_PREFERRED_INTEROP_USER_SYNC, size_type) \
1223 F(cl_device_info, CL_DEVICE_PARTITION_AFFINITY_DOMAIN, cl_device_affinity_domain) \
1224 F(cl_device_info, CL_DEVICE_BUILT_IN_KERNELS, string) \
1225 \
1226 F(cl_image_info, CL_IMAGE_ARRAY_SIZE, size_type) \
1227 F(cl_image_info, CL_IMAGE_NUM_MIP_LEVELS, cl_uint) \
1228 F(cl_image_info, CL_IMAGE_NUM_SAMPLES, cl_uint)
1229
1230#define CL_HPP_PARAM_NAME_INFO_2_0_(F) \
1231 F(cl_device_info, CL_DEVICE_QUEUE_ON_HOST_PROPERTIES, cl_command_queue_properties) \
1232 F(cl_device_info, CL_DEVICE_QUEUE_ON_DEVICE_PROPERTIES, cl_command_queue_properties) \
1233 F(cl_device_info, CL_DEVICE_QUEUE_ON_DEVICE_PREFERRED_SIZE, cl_uint) \
1234 F(cl_device_info, CL_DEVICE_QUEUE_ON_DEVICE_MAX_SIZE, cl_uint) \
1235 F(cl_device_info, CL_DEVICE_MAX_ON_DEVICE_QUEUES, cl_uint) \
1236 F(cl_device_info, CL_DEVICE_MAX_ON_DEVICE_EVENTS, cl_uint) \
1237 F(cl_device_info, CL_DEVICE_MAX_PIPE_ARGS, cl_uint) \
1238 F(cl_device_info, CL_DEVICE_PIPE_MAX_ACTIVE_RESERVATIONS, cl_uint) \
1239 F(cl_device_info, CL_DEVICE_PIPE_MAX_PACKET_SIZE, cl_uint) \
1240 F(cl_device_info, CL_DEVICE_SVM_CAPABILITIES, cl_device_svm_capabilities) \
1241 F(cl_device_info, CL_DEVICE_PREFERRED_PLATFORM_ATOMIC_ALIGNMENT, cl_uint) \
1242 F(cl_device_info, CL_DEVICE_PREFERRED_GLOBAL_ATOMIC_ALIGNMENT, cl_uint) \
1243 F(cl_device_info, CL_DEVICE_PREFERRED_LOCAL_ATOMIC_ALIGNMENT, cl_uint) \
1244 F(cl_command_queue_info, CL_QUEUE_SIZE, cl_uint) \
1245 F(cl_mem_info, CL_MEM_USES_SVM_POINTER, cl_bool) \
1246 F(cl_program_build_info, CL_PROGRAM_BUILD_GLOBAL_VARIABLE_TOTAL_SIZE, size_type) \
1247 F(cl_pipe_info, CL_PIPE_PACKET_SIZE, cl_uint) \
1248 F(cl_pipe_info, CL_PIPE_MAX_PACKETS, cl_uint)
1249
1250#define CL_HPP_PARAM_NAME_DEVICE_FISSION_(F) \
1251 F(cl_device_info, CL_DEVICE_PARENT_DEVICE_EXT, cl_device_id) \
1252 F(cl_device_info, CL_DEVICE_PARTITION_TYPES_EXT, cl::vector<cl_device_partition_property_ext>) \
1253 F(cl_device_info, CL_DEVICE_AFFINITY_DOMAINS_EXT, cl::vector<cl_device_partition_property_ext>) \
1254 F(cl_device_info, CL_DEVICE_REFERENCE_COUNT_EXT , cl_uint) \
1255 F(cl_device_info, CL_DEVICE_PARTITION_STYLE_EXT, cl::vector<cl_device_partition_property_ext>)
1256
1257template <typename enum_type, cl_int Name>
1258struct param_traits {};
1259
1260#define CL_HPP_DECLARE_PARAM_TRAITS_(token, param_name, T) \
1261struct token; \
1262template<> \
1263struct param_traits<detail:: token,param_name> \
1264{ \
1265 enum { value = param_name }; \
1266 typedef T param_type; \
1267};
1268
1269CL_HPP_PARAM_NAME_INFO_1_0_(CL_HPP_DECLARE_PARAM_TRAITS_)
1270#if CL_HPP_TARGET_OPENCL_VERSION >= 110
1271CL_HPP_PARAM_NAME_INFO_1_1_(CL_HPP_DECLARE_PARAM_TRAITS_)
1272#endif // CL_HPP_TARGET_OPENCL_VERSION >= 110
1273#if CL_HPP_TARGET_OPENCL_VERSION >= 120
1274CL_HPP_PARAM_NAME_INFO_1_2_(CL_HPP_DECLARE_PARAM_TRAITS_)
1275#endif // CL_HPP_TARGET_OPENCL_VERSION >= 110
1276#if CL_HPP_TARGET_OPENCL_VERSION >= 200
1277CL_HPP_PARAM_NAME_INFO_2_0_(CL_HPP_DECLARE_PARAM_TRAITS_)
1278#endif // CL_HPP_TARGET_OPENCL_VERSION >= 110
1279
1280
1281// Flags deprecated in OpenCL 2.0
1282#define CL_HPP_PARAM_NAME_INFO_1_0_DEPRECATED_IN_2_0_(F) \
1283 F(cl_device_info, CL_DEVICE_QUEUE_PROPERTIES, cl_command_queue_properties)
1284
1285#define CL_HPP_PARAM_NAME_INFO_1_1_DEPRECATED_IN_2_0_(F) \
1286 F(cl_device_info, CL_DEVICE_HOST_UNIFIED_MEMORY, cl_bool)
1287
1288#define CL_HPP_PARAM_NAME_INFO_1_2_DEPRECATED_IN_2_0_(F) \
1289 F(cl_image_info, CL_IMAGE_BUFFER, cl::Buffer)
1290
1291// Include deprecated query flags based on versions
1292// Only include deprecated 1.0 flags if 2.0 not active as there is an enum clash
1293#if CL_HPP_TARGET_OPENCL_VERSION > 100 && CL_HPP_MINIMUM_OPENCL_VERSION < 200 && CL_HPP_TARGET_OPENCL_VERSION < 200
1294CL_HPP_PARAM_NAME_INFO_1_0_DEPRECATED_IN_2_0_(CL_HPP_DECLARE_PARAM_TRAITS_)
1295#endif // CL_HPP_MINIMUM_OPENCL_VERSION < 110
1296#if CL_HPP_TARGET_OPENCL_VERSION > 110 && CL_HPP_MINIMUM_OPENCL_VERSION < 200
1297CL_HPP_PARAM_NAME_INFO_1_1_DEPRECATED_IN_2_0_(CL_HPP_DECLARE_PARAM_TRAITS_)
1298#endif // CL_HPP_MINIMUM_OPENCL_VERSION < 120
1299#if CL_HPP_TARGET_OPENCL_VERSION > 120 && CL_HPP_MINIMUM_OPENCL_VERSION < 200
1300CL_HPP_PARAM_NAME_INFO_1_2_DEPRECATED_IN_2_0_(CL_HPP_DECLARE_PARAM_TRAITS_)
1301#endif // CL_HPP_MINIMUM_OPENCL_VERSION < 200
1302
1303#if defined(CL_HPP_USE_CL_DEVICE_FISSION)
1304CL_HPP_PARAM_NAME_DEVICE_FISSION_(CL_HPP_DECLARE_PARAM_TRAITS_);
1305#endif // CL_HPP_USE_CL_DEVICE_FISSION
1306
1307#ifdef CL_PLATFORM_ICD_SUFFIX_KHR
1308CL_HPP_DECLARE_PARAM_TRAITS_(cl_platform_info, CL_PLATFORM_ICD_SUFFIX_KHR, string)
1309#endif
1310
1311#ifdef CL_DEVICE_PROFILING_TIMER_OFFSET_AMD
1312CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_PROFILING_TIMER_OFFSET_AMD, cl_ulong)
1313#endif
1314
1315#ifdef CL_DEVICE_GLOBAL_FREE_MEMORY_AMD
1316CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_GLOBAL_FREE_MEMORY_AMD, vector<size_type>)
1317#endif
1318#ifdef CL_DEVICE_SIMD_PER_COMPUTE_UNIT_AMD
1319CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_SIMD_PER_COMPUTE_UNIT_AMD, cl_uint)
1320#endif
1321#ifdef CL_DEVICE_SIMD_WIDTH_AMD
1322CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_SIMD_WIDTH_AMD, cl_uint)
1323#endif
1324#ifdef CL_DEVICE_SIMD_INSTRUCTION_WIDTH_AMD
1325CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_SIMD_INSTRUCTION_WIDTH_AMD, cl_uint)
1326#endif
1327#ifdef CL_DEVICE_WAVEFRONT_WIDTH_AMD
1328CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_WAVEFRONT_WIDTH_AMD, cl_uint)
1329#endif
1330#ifdef CL_DEVICE_GLOBAL_MEM_CHANNELS_AMD
1331CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_GLOBAL_MEM_CHANNELS_AMD, cl_uint)
1332#endif
1333#ifdef CL_DEVICE_GLOBAL_MEM_CHANNEL_BANKS_AMD
1334CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_GLOBAL_MEM_CHANNEL_BANKS_AMD, cl_uint)
1335#endif
1336#ifdef CL_DEVICE_GLOBAL_MEM_CHANNEL_BANK_WIDTH_AMD
1337CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_GLOBAL_MEM_CHANNEL_BANK_WIDTH_AMD, cl_uint)
1338#endif
1339#ifdef CL_DEVICE_LOCAL_MEM_SIZE_PER_COMPUTE_UNIT_AMD
1340CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_LOCAL_MEM_SIZE_PER_COMPUTE_UNIT_AMD, cl_uint)
1341#endif
1342#ifdef CL_DEVICE_LOCAL_MEM_BANKS_AMD
1343CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_LOCAL_MEM_BANKS_AMD, cl_uint)
1344#endif
1345
1346#ifdef CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV
1347CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV, cl_uint)
1348#endif
1349#ifdef CL_DEVICE_COMPUTE_CAPABILITY_MINOR_NV
1350CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_COMPUTE_CAPABILITY_MINOR_NV, cl_uint)
1351#endif
1352#ifdef CL_DEVICE_REGISTERS_PER_BLOCK_NV
1353CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_REGISTERS_PER_BLOCK_NV, cl_uint)
1354#endif
1355#ifdef CL_DEVICE_WARP_SIZE_NV
1356CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_WARP_SIZE_NV, cl_uint)
1357#endif
1358#ifdef CL_DEVICE_GPU_OVERLAP_NV
1359CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_GPU_OVERLAP_NV, cl_bool)
1360#endif
1361#ifdef CL_DEVICE_KERNEL_EXEC_TIMEOUT_NV
1362CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_KERNEL_EXEC_TIMEOUT_NV, cl_bool)
1363#endif
1364#ifdef CL_DEVICE_INTEGRATED_MEMORY_NV
1365CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_INTEGRATED_MEMORY_NV, cl_bool)
1366#endif
1367
1368// Convenience functions
1369
1370template <typename Func, typename T>
1371inline cl_int
1372getInfo(Func f, cl_uint name, T* param)
1373{
1374 return getInfoHelper(f, name, param, 0);
1375}
1376
1377template <typename Func, typename Arg0>
1378struct GetInfoFunctor0
1379{
1380 Func f_; const Arg0& arg0_;
1381 cl_int operator ()(
1382 cl_uint param, size_type size, void* value, size_type* size_ret)
1383 { return f_(arg0_, param, size, value, size_ret); }
1384};
1385
1386template <typename Func, typename Arg0, typename Arg1>
1387struct GetInfoFunctor1
1388{
1389 Func f_; const Arg0& arg0_; const Arg1& arg1_;
1390 cl_int operator ()(
1391 cl_uint param, size_type size, void* value, size_type* size_ret)
1392 { return f_(arg0_, arg1_, param, size, value, size_ret); }
1393};
1394
1395template <typename Func, typename Arg0, typename T>
1396inline cl_int
1397getInfo(Func f, const Arg0& arg0, cl_uint name, T* param)
1398{
1399 GetInfoFunctor0<Func, Arg0> f0 = { f, arg0 };
1400 return getInfoHelper(f0, name, param, 0);
1401}
1402
1403template <typename Func, typename Arg0, typename Arg1, typename T>
1404inline cl_int
1405getInfo(Func f, const Arg0& arg0, const Arg1& arg1, cl_uint name, T* param)
1406{
1407 GetInfoFunctor1<Func, Arg0, Arg1> f0 = { f, arg0, arg1 };
1408 return getInfoHelper(f0, name, param, 0);
1409}
1410
1411
1412template<typename T>
1413struct ReferenceHandler
1414{ };
1415
1416#if CL_HPP_TARGET_OPENCL_VERSION >= 120
1417/**
1418 * OpenCL 1.2 devices do have retain/release.
1419 */
1420template <>
1421struct ReferenceHandler<cl_device_id>
1422{
1423 /**
1424 * Retain the device.
1425 * \param device A valid device created using createSubDevices
1426 * \return
1427 * CL_SUCCESS if the function executed successfully.
1428 * CL_INVALID_DEVICE if device was not a valid subdevice
1429 * CL_OUT_OF_RESOURCES
1430 * CL_OUT_OF_HOST_MEMORY
1431 */
1432 static cl_int retain(cl_device_id device)
1433 { return ::clRetainDevice(device); }
1434 /**
1435 * Retain the device.
1436 * \param device A valid device created using createSubDevices
1437 * \return
1438 * CL_SUCCESS if the function executed successfully.
1439 * CL_INVALID_DEVICE if device was not a valid subdevice
1440 * CL_OUT_OF_RESOURCES
1441 * CL_OUT_OF_HOST_MEMORY
1442 */
1443 static cl_int release(cl_device_id device)
1444 { return ::clReleaseDevice(device); }
1445};
1446#else // CL_HPP_TARGET_OPENCL_VERSION >= 120
1447/**
1448 * OpenCL 1.1 devices do not have retain/release.
1449 */
1450template <>
1451struct ReferenceHandler<cl_device_id>
1452{
1453 // cl_device_id does not have retain().
1454 static cl_int retain(cl_device_id)
1455 { return CL_SUCCESS; }
1456 // cl_device_id does not have release().
1457 static cl_int release(cl_device_id)
1458 { return CL_SUCCESS; }
1459};
1460#endif // ! (CL_HPP_TARGET_OPENCL_VERSION >= 120)
1461
1462template <>
1463struct ReferenceHandler<cl_platform_id>
1464{
1465 // cl_platform_id does not have retain().
1466 static cl_int retain(cl_platform_id)
1467 { return CL_SUCCESS; }
1468 // cl_platform_id does not have release().
1469 static cl_int release(cl_platform_id)
1470 { return CL_SUCCESS; }
1471};
1472
1473template <>
1474struct ReferenceHandler<cl_context>
1475{
1476 static cl_int retain(cl_context context)
1477 { return ::clRetainContext(context); }
1478 static cl_int release(cl_context context)
1479 { return ::clReleaseContext(context); }
1480};
1481
1482template <>
1483struct ReferenceHandler<cl_command_queue>
1484{
1485 static cl_int retain(cl_command_queue queue)
1486 { return ::clRetainCommandQueue(queue); }
1487 static cl_int release(cl_command_queue queue)
1488 { return ::clReleaseCommandQueue(queue); }
1489};
1490
1491template <>
1492struct ReferenceHandler<cl_mem>
1493{
1494 static cl_int retain(cl_mem memory)
1495 { return ::clRetainMemObject(memory); }
1496 static cl_int release(cl_mem memory)
1497 { return ::clReleaseMemObject(memory); }
1498};
1499
1500template <>
1501struct ReferenceHandler<cl_sampler>
1502{
1503 static cl_int retain(cl_sampler sampler)
1504 { return ::clRetainSampler(sampler); }
1505 static cl_int release(cl_sampler sampler)
1506 { return ::clReleaseSampler(sampler); }
1507};
1508
1509template <>
1510struct ReferenceHandler<cl_program>
1511{
1512 static cl_int retain(cl_program program)
1513 { return ::clRetainProgram(program); }
1514 static cl_int release(cl_program program)
1515 { return ::clReleaseProgram(program); }
1516};
1517
1518template <>
1519struct ReferenceHandler<cl_kernel>
1520{
1521 static cl_int retain(cl_kernel kernel)
1522 { return ::clRetainKernel(kernel); }
1523 static cl_int release(cl_kernel kernel)
1524 { return ::clReleaseKernel(kernel); }
1525};
1526
1527template <>
1528struct ReferenceHandler<cl_event>
1529{
1530 static cl_int retain(cl_event event)
1531 { return ::clRetainEvent(event); }
1532 static cl_int release(cl_event event)
1533 { return ::clReleaseEvent(event); }
1534};
1535
1536
1537// Extracts version number with major in the upper 16 bits, minor in the lower 16
1538static cl_uint getVersion(const vector<char> &versionInfo)
1539{
1540 int highVersion = 0;
1541 int lowVersion = 0;
1542 int index = 7;
1543 while(versionInfo[index] != '.' ) {
1544 highVersion *= 10;
1545 highVersion += versionInfo[index]-'0';
1546 ++index;
1547 }
1548 ++index;
1549 while(versionInfo[index] != ' ' && versionInfo[index] != '\0') {
1550 lowVersion *= 10;
1551 lowVersion += versionInfo[index]-'0';
1552 ++index;
1553 }
1554 return (highVersion << 16) | lowVersion;
1555}
1556
1557#if CL_HPP_TARGET_OPENCL_VERSION >= 120 && CL_HPP_MINIMUM_OPENCL_VERSION < 120
1558static cl_uint getPlatformVersion(cl_platform_id platform)
1559{
1560 size_type size = 0;
1561 clGetPlatformInfo(platform, CL_PLATFORM_VERSION, 0, NULL, &size);
1562
1563 vector<char> versionInfo(size);
1564 clGetPlatformInfo(platform, CL_PLATFORM_VERSION, size, versionInfo.data(), &size);
1565 return getVersion(versionInfo);
1566}
1567
1568static cl_uint getDevicePlatformVersion(cl_device_id device)
1569{
1570 cl_platform_id platform;
1571 clGetDeviceInfo(device, CL_DEVICE_PLATFORM, sizeof(platform), &platform, NULL);
1572 return getPlatformVersion(platform);
1573}
1574
1575static cl_uint getContextPlatformVersion(cl_context context)
1576{
1577 // The platform cannot be queried directly, so we first have to grab a
1578 // device and obtain its context
1579 size_type size = 0;
1580 clGetContextInfo(context, CL_CONTEXT_DEVICES, 0, NULL, &size);
1581 if (size == 0)
1582 return 0;
1583 vector<cl_device_id> devices(size/sizeof(cl_device_id));
1584 clGetContextInfo(context, CL_CONTEXT_DEVICES, size, devices.data(), NULL);
1585 return getDevicePlatformVersion(devices[0]);
1586}
1587#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120 && CL_HPP_MINIMUM_OPENCL_VERSION < 120
1588
1589template <typename T>
1590class Wrapper
1591{
1592public:
1593 typedef T cl_type;
1594
1595protected:
1596 cl_type object_;
1597
1598public:
1599 Wrapper() : object_(NULL) { }
1600
1601 Wrapper(const cl_type &obj, bool retainObject) : object_(obj)
1602 {
1603 if (retainObject) {
1604 detail::errHandler(retain(), __RETAIN_ERR);
1605 }
1606 }
1607
1608 ~Wrapper()
1609 {
1610 if (object_ != NULL) { release(); }
1611 }
1612
1613 Wrapper(const Wrapper<cl_type>& rhs)
1614 {
1615 object_ = rhs.object_;
1616 detail::errHandler(retain(), __RETAIN_ERR);
1617 }
1618
1619 Wrapper(Wrapper<cl_type>&& rhs) CL_HPP_NOEXCEPT_
1620 {
1621 object_ = rhs.object_;
1622 rhs.object_ = NULL;
1623 }
1624
1625 Wrapper<cl_type>& operator = (const Wrapper<cl_type>& rhs)
1626 {
1627 if (this != &rhs) {
1628 detail::errHandler(release(), __RELEASE_ERR);
1629 object_ = rhs.object_;
1630 detail::errHandler(retain(), __RETAIN_ERR);
1631 }
1632 return *this;
1633 }
1634
1635 Wrapper<cl_type>& operator = (Wrapper<cl_type>&& rhs)
1636 {
1637 if (this != &rhs) {
1638 detail::errHandler(release(), __RELEASE_ERR);
1639 object_ = rhs.object_;
1640 rhs.object_ = NULL;
1641 }
1642 return *this;
1643 }
1644
1645 Wrapper<cl_type>& operator = (const cl_type &rhs)
1646 {
1647 detail::errHandler(release(), __RELEASE_ERR);
1648 object_ = rhs;
1649 return *this;
1650 }
1651
1652 const cl_type& operator ()() const { return object_; }
1653
1654 cl_type& operator ()() { return object_; }
1655
1656 const cl_type get() const { return object_; }
1657
1658 cl_type get() { return object_; }
1659
1660
1661protected:
1662 template<typename Func, typename U>
1663 friend inline cl_int getInfoHelper(Func, cl_uint, U*, int, typename U::cl_type);
1664
1665 cl_int retain() const
1666 {
1667 if (object_ != nullptr) {
1668 return ReferenceHandler<cl_type>::retain(object_);
1669 }
1670 else {
1671 return CL_SUCCESS;
1672 }
1673 }
1674
1675 cl_int release() const
1676 {
1677 if (object_ != nullptr) {
1678 return ReferenceHandler<cl_type>::release(object_);
1679 }
1680 else {
1681 return CL_SUCCESS;
1682 }
1683 }
1684};
1685
1686template <>
1687class Wrapper<cl_device_id>
1688{
1689public:
1690 typedef cl_device_id cl_type;
1691
1692protected:
1693 cl_type object_;
1694 bool referenceCountable_;
1695
1696 static bool isReferenceCountable(cl_device_id device)
1697 {
1698 bool retVal = false;
1699#if CL_HPP_TARGET_OPENCL_VERSION >= 120
1700#if CL_HPP_MINIMUM_OPENCL_VERSION < 120
1701 if (device != NULL) {
1702 int version = getDevicePlatformVersion(device);
1703 if(version > ((1 << 16) + 1)) {
1704 retVal = true;
1705 }
1706 }
1707#else // CL_HPP_MINIMUM_OPENCL_VERSION < 120
1708 retVal = true;
1709#endif // CL_HPP_MINIMUM_OPENCL_VERSION < 120
1710#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
1711 return retVal;
1712 }
1713
1714public:
1715 Wrapper() : object_(NULL), referenceCountable_(false)
1716 {
1717 }
1718
1719 Wrapper(const cl_type &obj, bool retainObject) :
1720 object_(obj),
1721 referenceCountable_(false)
1722 {
1723 referenceCountable_ = isReferenceCountable(obj);
1724
1725 if (retainObject) {
1726 detail::errHandler(retain(), __RETAIN_ERR);
1727 }
1728 }
1729
1730 ~Wrapper()
1731 {
1732 release();
1733 }
1734
1735 Wrapper(const Wrapper<cl_type>& rhs)
1736 {
1737 object_ = rhs.object_;
1738 referenceCountable_ = isReferenceCountable(object_);
1739 detail::errHandler(retain(), __RETAIN_ERR);
1740 }
1741
1742 Wrapper(Wrapper<cl_type>&& rhs) CL_HPP_NOEXCEPT_
1743 {
1744 object_ = rhs.object_;
1745 referenceCountable_ = rhs.referenceCountable_;
1746 rhs.object_ = NULL;
1747 rhs.referenceCountable_ = false;
1748 }
1749
1750 Wrapper<cl_type>& operator = (const Wrapper<cl_type>& rhs)
1751 {
1752 if (this != &rhs) {
1753 detail::errHandler(release(), __RELEASE_ERR);
1754 object_ = rhs.object_;
1755 referenceCountable_ = rhs.referenceCountable_;
1756 detail::errHandler(retain(), __RETAIN_ERR);
1757 }
1758 return *this;
1759 }
1760
1761 Wrapper<cl_type>& operator = (Wrapper<cl_type>&& rhs)
1762 {
1763 if (this != &rhs) {
1764 detail::errHandler(release(), __RELEASE_ERR);
1765 object_ = rhs.object_;
1766 referenceCountable_ = rhs.referenceCountable_;
1767 rhs.object_ = NULL;
1768 rhs.referenceCountable_ = false;
1769 }
1770 return *this;
1771 }
1772
1773 Wrapper<cl_type>& operator = (const cl_type &rhs)
1774 {
1775 detail::errHandler(release(), __RELEASE_ERR);
1776 object_ = rhs;
1777 referenceCountable_ = isReferenceCountable(object_);
1778 return *this;
1779 }
1780
1781 const cl_type& operator ()() const { return object_; }
1782
1783 cl_type& operator ()() { return object_; }
1784
1785 const cl_type get() const { return object_; }
1786
1787 cl_type get() { return object_; }
1788
1789protected:
1790 template<typename Func, typename U>
1791 friend inline cl_int getInfoHelper(Func, cl_uint, U*, int, typename U::cl_type);
1792
1793 template<typename Func, typename U>
1794 friend inline cl_int getInfoHelper(Func, cl_uint, vector<U>*, int, typename U::cl_type);
1795
1796 cl_int retain() const
1797 {
1798 if( object_ != nullptr && referenceCountable_ ) {
1799 return ReferenceHandler<cl_type>::retain(object_);
1800 }
1801 else {
1802 return CL_SUCCESS;
1803 }
1804 }
1805
1806 cl_int release() const
1807 {
1808 if (object_ != nullptr && referenceCountable_) {
1809 return ReferenceHandler<cl_type>::release(object_);
1810 }
1811 else {
1812 return CL_SUCCESS;
1813 }
1814 }
1815};
1816
1817template <typename T>
1818inline bool operator==(const Wrapper<T> &lhs, const Wrapper<T> &rhs)
1819{
1820 return lhs() == rhs();
1821}
1822
1823template <typename T>
1824inline bool operator!=(const Wrapper<T> &lhs, const Wrapper<T> &rhs)
1825{
1826 return !operator==(lhs, rhs);
1827}
1828
1829} // namespace detail
1830//! \endcond
1831
1832
1833using BuildLogType = vector<std::pair<cl::Device, typename detail::param_traits<detail::cl_program_build_info, CL_PROGRAM_BUILD_LOG>::param_type>>;
1834#if defined(CL_HPP_ENABLE_EXCEPTIONS)
1835/**
1836* Exception class for build errors to carry build info
1837*/
1838class BuildError : public Error
1839{
1840private:
1841 BuildLogType buildLogs;
1842public:
1843 BuildError(cl_int err, const char * errStr, const BuildLogType &vec) : Error(err, errStr), buildLogs(vec)
1844 {
1845 }
1846
1847 BuildLogType getBuildLog() const
1848 {
1849 return buildLogs;
1850 }
1851};
1852namespace detail {
1853 static inline cl_int buildErrHandler(
1854 cl_int err,
1855 const char * errStr,
1856 const BuildLogType &buildLogs)
1857 {
1858 if (err != CL_SUCCESS) {
1859 throw BuildError(err, errStr, buildLogs);
1860 }
1861 return err;
1862 }
1863} // namespace detail
1864
1865#else
1866namespace detail {
1867 static inline cl_int buildErrHandler(
1868 cl_int err,
1869 const char * errStr,
1870 const BuildLogType &buildLogs)
1871 {
1872 (void)buildLogs; // suppress unused variable warning
1873 (void)errStr;
1874 return err;
1875 }
1876} // namespace detail
1877#endif // #if defined(CL_HPP_ENABLE_EXCEPTIONS)
1878
1879
1880/*! \stuct ImageFormat
1881 * \brief Adds constructors and member functions for cl_image_format.
1882 *
1883 * \see cl_image_format
1884 */
1885struct ImageFormat : public cl_image_format
1886{
1887 //! \brief Default constructor - performs no initialization.
1888 ImageFormat(){}
1889
1890 //! \brief Initializing constructor.
1891 ImageFormat(cl_channel_order order, cl_channel_type type)
1892 {
1893 image_channel_order = order;
1894 image_channel_data_type = type;
1895 }
1896
1897 //! \brief Assignment operator.
1898 ImageFormat& operator = (const ImageFormat& rhs)
1899 {
1900 if (this != &rhs) {
1901 this->image_channel_data_type = rhs.image_channel_data_type;
1902 this->image_channel_order = rhs.image_channel_order;
1903 }
1904 return *this;
1905 }
1906};
1907
1908/*! \brief Class interface for cl_device_id.
1909 *
1910 * \note Copies of these objects are inexpensive, since they don't 'own'
1911 * any underlying resources or data structures.
1912 *
1913 * \see cl_device_id
1914 */
1915class Device : public detail::Wrapper<cl_device_id>
1916{
1917private:
1918 static std::once_flag default_initialized_;
1919 static Device default_;
1920 static cl_int default_error_;
1921
1922 /*! \brief Create the default context.
1923 *
1924 * This sets @c default_ and @c default_error_. It does not throw
1925 * @c cl::Error.
1926 */
1927 static void makeDefault();
1928
1929 /*! \brief Create the default platform from a provided platform.
1930 *
1931 * This sets @c default_. It does not throw
1932 * @c cl::Error.
1933 */
1934 static void makeDefaultProvided(const Device &p) {
1935 default_ = p;
1936 }
1937
1938public:
1939#ifdef CL_HPP_UNIT_TEST_ENABLE
1940 /*! \brief Reset the default.
1941 *
1942 * This sets @c default_ to an empty value to support cleanup in
1943 * the unit test framework.
1944 * This function is not thread safe.
1945 */
1946 static void unitTestClearDefault() {
1947 default_ = Device();
1948 }
1949#endif // #ifdef CL_HPP_UNIT_TEST_ENABLE
1950
1951 //! \brief Default constructor - initializes to NULL.
1952 Device() : detail::Wrapper<cl_type>() { }
1953
1954 /*! \brief Constructor from cl_device_id.
1955 *
1956 * This simply copies the device ID value, which is an inexpensive operation.
1957 */
1958 explicit Device(const cl_device_id &device, bool retainObject = false) :
1959 detail::Wrapper<cl_type>(device, retainObject) { }
1960
1961 /*! \brief Returns the first device on the default context.
1962 *
1963 * \see Context::getDefault()
1964 */
1965 static Device getDefault(
1966 cl_int *errResult = NULL)
1967 {
1968 std::call_once(default_initialized_, makeDefault);
1969 detail::errHandler(default_error_);
1970 if (errResult != NULL) {
1971 *errResult = default_error_;
1972 }
1973 return default_;
1974 }
1975
1976 /**
1977 * Modify the default device to be used by
1978 * subsequent operations.
1979 * Will only set the default if no default was previously created.
1980 * @return updated default device.
1981 * Should be compared to the passed value to ensure that it was updated.
1982 */
1983 static Device setDefault(const Device &default_device)
1984 {
1985 std::call_once(default_initialized_, makeDefaultProvided, std::cref(default_device));
1986 detail::errHandler(default_error_);
1987 return default_;
1988 }
1989
1990 /*! \brief Assignment operator from cl_device_id.
1991 *
1992 * This simply copies the device ID value, which is an inexpensive operation.
1993 */
1994 Device& operator = (const cl_device_id& rhs)
1995 {
1996 detail::Wrapper<cl_type>::operator=(rhs);
1997 return *this;
1998 }
1999
2000 /*! \brief Copy constructor to forward copy to the superclass correctly.
2001 * Required for MSVC.
2002 */
2003 Device(const Device& dev) : detail::Wrapper<cl_type>(dev) {}
2004
2005 /*! \brief Copy assignment to forward copy to the superclass correctly.
2006 * Required for MSVC.
2007 */
2008 Device& operator = (const Device &dev)
2009 {
2010 detail::Wrapper<cl_type>::operator=(dev);
2011 return *this;
2012 }
2013
2014 /*! \brief Move constructor to forward move to the superclass correctly.
2015 * Required for MSVC.
2016 */
2017 Device(Device&& dev) CL_HPP_NOEXCEPT_ : detail::Wrapper<cl_type>(std::move(dev)) {}
2018
2019 /*! \brief Move assignment to forward move to the superclass correctly.
2020 * Required for MSVC.
2021 */
2022 Device& operator = (Device &&dev)
2023 {
2024 detail::Wrapper<cl_type>::operator=(std::move(dev));
2025 return *this;
2026 }
2027
2028 //! \brief Wrapper for clGetDeviceInfo().
2029 template <typename T>
2030 cl_int getInfo(cl_device_info name, T* param) const
2031 {
2032 return detail::errHandler(
2033 detail::getInfo(&::clGetDeviceInfo, object_, name, param),
2034 __GET_DEVICE_INFO_ERR);
2035 }
2036
2037 //! \brief Wrapper for clGetDeviceInfo() that returns by value.
2038 template <cl_int name> typename
2039 detail::param_traits<detail::cl_device_info, name>::param_type
2040 getInfo(cl_int* err = NULL) const
2041 {
2042 typename detail::param_traits<
2043 detail::cl_device_info, name>::param_type param;
2044 cl_int result = getInfo(name, &param);
2045 if (err != NULL) {
2046 *err = result;
2047 }
2048 return param;
2049 }
2050
2051 /**
2052 * CL 1.2 version
2053 */
2054#if CL_HPP_TARGET_OPENCL_VERSION >= 120
2055 //! \brief Wrapper for clCreateSubDevices().
2056 cl_int createSubDevices(
2057 const cl_device_partition_property * properties,
2058 vector<Device>* devices)
2059 {
2060 cl_uint n = 0;
2061 cl_int err = clCreateSubDevices(object_, properties, 0, NULL, &n);
2062 if (err != CL_SUCCESS) {
2063 return detail::errHandler(err, __CREATE_SUB_DEVICES_ERR);
2064 }
2065
2066 vector<cl_device_id> ids(n);
2067 err = clCreateSubDevices(object_, properties, n, ids.data(), NULL);
2068 if (err != CL_SUCCESS) {
2069 return detail::errHandler(err, __CREATE_SUB_DEVICES_ERR);
2070 }
2071
2072 // Cannot trivially assign because we need to capture intermediates
2073 // with safe construction
2074 if (devices) {
2075 devices->resize(ids.size());
2076
2077 // Assign to param, constructing with retain behaviour
2078 // to correctly capture each underlying CL object
2079 for (size_type i = 0; i < ids.size(); i++) {
2080 // We do not need to retain because this device is being created
2081 // by the runtime
2082 (*devices)[i] = Device(ids[i], false);
2083 }
2084 }
2085
2086 return CL_SUCCESS;
2087 }
2088#elif defined(CL_HPP_USE_CL_DEVICE_FISSION)
2089
2090/**
2091 * CL 1.1 version that uses device fission extension.
2092 */
2093 cl_int createSubDevices(
2094 const cl_device_partition_property_ext * properties,
2095 vector<Device>* devices)
2096 {
2097 typedef CL_API_ENTRY cl_int
2098 ( CL_API_CALL * PFN_clCreateSubDevicesEXT)(
2099 cl_device_id /*in_device*/,
2100 const cl_device_partition_property_ext * /* properties */,
2101 cl_uint /*num_entries*/,
2102 cl_device_id * /*out_devices*/,
2103 cl_uint * /*num_devices*/ ) CL_EXT_SUFFIX__VERSION_1_1;
2104
2105 static PFN_clCreateSubDevicesEXT pfn_clCreateSubDevicesEXT = NULL;
2106 CL_HPP_INIT_CL_EXT_FCN_PTR_(clCreateSubDevicesEXT);
2107
2108 cl_uint n = 0;
2109 cl_int err = pfn_clCreateSubDevicesEXT(object_, properties, 0, NULL, &n);
2110 if (err != CL_SUCCESS) {
2111 return detail::errHandler(err, __CREATE_SUB_DEVICES_ERR);
2112 }
2113
2114 vector<cl_device_id> ids(n);
2115 err = pfn_clCreateSubDevicesEXT(object_, properties, n, ids.data(), NULL);
2116 if (err != CL_SUCCESS) {
2117 return detail::errHandler(err, __CREATE_SUB_DEVICES_ERR);
2118 }
2119 // Cannot trivially assign because we need to capture intermediates
2120 // with safe construction
2121 if (devices) {
2122 devices->resize(ids.size());
2123
2124 // Assign to param, constructing with retain behaviour
2125 // to correctly capture each underlying CL object
2126 for (size_type i = 0; i < ids.size(); i++) {
2127 // We do not need to retain because this device is being created
2128 // by the runtime
2129 (*devices)[i] = Device(ids[i], false);
2130 }
2131 }
2132 return CL_SUCCESS;
2133 }
2134#endif // defined(CL_HPP_USE_CL_DEVICE_FISSION)
2135};
2136
2137CL_HPP_DEFINE_STATIC_MEMBER_ std::once_flag Device::default_initialized_;
2138CL_HPP_DEFINE_STATIC_MEMBER_ Device Device::default_;
2139CL_HPP_DEFINE_STATIC_MEMBER_ cl_int Device::default_error_ = CL_SUCCESS;
2140
2141/*! \brief Class interface for cl_platform_id.
2142 *
2143 * \note Copies of these objects are inexpensive, since they don't 'own'
2144 * any underlying resources or data structures.
2145 *
2146 * \see cl_platform_id
2147 */
2148class Platform : public detail::Wrapper<cl_platform_id>
2149{
2150private:
2151 static std::once_flag default_initialized_;
2152 static Platform default_;
2153 static cl_int default_error_;
2154
2155 /*! \brief Create the default context.
2156 *
2157 * This sets @c default_ and @c default_error_. It does not throw
2158 * @c cl::Error.
2159 */
2160 static void makeDefault() {
2161 /* Throwing an exception from a call_once invocation does not do
2162 * what we wish, so we catch it and save the error.
2163 */
2164#if defined(CL_HPP_ENABLE_EXCEPTIONS)
2165 try
2166#endif
2167 {
2168 // If default wasn't passed ,generate one
2169 // Otherwise set it
2170 cl_uint n = 0;
2171
2172 cl_int err = ::clGetPlatformIDs(0, NULL, &n);
2173 if (err != CL_SUCCESS) {
2174 default_error_ = err;
2175 return;
2176 }
2177 if (n == 0) {
2178 default_error_ = CL_INVALID_PLATFORM;
2179 return;
2180 }
2181
2182 vector<cl_platform_id> ids(n);
2183 err = ::clGetPlatformIDs(n, ids.data(), NULL);
2184 if (err != CL_SUCCESS) {
2185 default_error_ = err;
2186 return;
2187 }
2188
2189 default_ = Platform(ids[0]);
2190 }
2191#if defined(CL_HPP_ENABLE_EXCEPTIONS)
2192 catch (cl::Error &e) {
2193 default_error_ = e.err();
2194 }
2195#endif
2196 }
2197
2198 /*! \brief Create the default platform from a provided platform.
2199 *
2200 * This sets @c default_. It does not throw
2201 * @c cl::Error.
2202 */
2203 static void makeDefaultProvided(const Platform &p) {
2204 default_ = p;
2205 }
2206
2207public:
2208#ifdef CL_HPP_UNIT_TEST_ENABLE
2209 /*! \brief Reset the default.
2210 *
2211 * This sets @c default_ to an empty value to support cleanup in
2212 * the unit test framework.
2213 * This function is not thread safe.
2214 */
2215 static void unitTestClearDefault() {
2216 default_ = Platform();
2217 }
2218#endif // #ifdef CL_HPP_UNIT_TEST_ENABLE
2219
2220 //! \brief Default constructor - initializes to NULL.
2221 Platform() : detail::Wrapper<cl_type>() { }
2222
2223 /*! \brief Constructor from cl_platform_id.
2224 *
2225 * \param retainObject will cause the constructor to retain its cl object.
2226 * Defaults to false to maintain compatibility with
2227 * earlier versions.
2228 * This simply copies the platform ID value, which is an inexpensive operation.
2229 */
2230 explicit Platform(const cl_platform_id &platform, bool retainObject = false) :
2231 detail::Wrapper<cl_type>(platform, retainObject) { }
2232
2233 /*! \brief Assignment operator from cl_platform_id.
2234 *
2235 * This simply copies the platform ID value, which is an inexpensive operation.
2236 */
2237 Platform& operator = (const cl_platform_id& rhs)
2238 {
2239 detail::Wrapper<cl_type>::operator=(rhs);
2240 return *this;
2241 }
2242
2243 static Platform getDefault(
2244 cl_int *errResult = NULL)
2245 {
2246 std::call_once(default_initialized_, makeDefault);
2247 detail::errHandler(default_error_);
2248 if (errResult != NULL) {
2249 *errResult = default_error_;
2250 }
2251 return default_;
2252 }
2253
2254 /**
2255 * Modify the default platform to be used by
2256 * subsequent operations.
2257 * Will only set the default if no default was previously created.
2258 * @return updated default platform.
2259 * Should be compared to the passed value to ensure that it was updated.
2260 */
2261 static Platform setDefault(const Platform &default_platform)
2262 {
2263 std::call_once(default_initialized_, makeDefaultProvided, std::cref(default_platform));
2264 detail::errHandler(default_error_);
2265 return default_;
2266 }
2267
2268 //! \brief Wrapper for clGetPlatformInfo().
2269 cl_int getInfo(cl_platform_info name, string* param) const
2270 {
2271 return detail::errHandler(
2272 detail::getInfo(&::clGetPlatformInfo, object_, name, param),
2273 __GET_PLATFORM_INFO_ERR);
2274 }
2275
2276 //! \brief Wrapper for clGetPlatformInfo() that returns by value.
2277 template <cl_int name> typename
2278 detail::param_traits<detail::cl_platform_info, name>::param_type
2279 getInfo(cl_int* err = NULL) const
2280 {
2281 typename detail::param_traits<
2282 detail::cl_platform_info, name>::param_type param;
2283 cl_int result = getInfo(name, &param);
2284 if (err != NULL) {
2285 *err = result;
2286 }
2287 return param;
2288 }
2289
2290 /*! \brief Gets a list of devices for this platform.
2291 *
2292 * Wraps clGetDeviceIDs().
2293 */
2294 cl_int getDevices(
2295 cl_device_type type,
2296 vector<Device>* devices) const
2297 {
2298 cl_uint n = 0;
2299 if( devices == NULL ) {
2300 return detail::errHandler(CL_INVALID_ARG_VALUE, __GET_DEVICE_IDS_ERR);
2301 }
2302 cl_int err = ::clGetDeviceIDs(object_, type, 0, NULL, &n);
2303 if (err != CL_SUCCESS) {
2304 return detail::errHandler(err, __GET_DEVICE_IDS_ERR);
2305 }
2306
2307 vector<cl_device_id> ids(n);
2308 err = ::clGetDeviceIDs(object_, type, n, ids.data(), NULL);
2309 if (err != CL_SUCCESS) {
2310 return detail::errHandler(err, __GET_DEVICE_IDS_ERR);
2311 }
2312
2313 // Cannot trivially assign because we need to capture intermediates
2314 // with safe construction
2315 // We must retain things we obtain from the API to avoid releasing
2316 // API-owned objects.
2317 if (devices) {
2318 devices->resize(ids.size());
2319
2320 // Assign to param, constructing with retain behaviour
2321 // to correctly capture each underlying CL object
2322 for (size_type i = 0; i < ids.size(); i++) {
2323 (*devices)[i] = Device(ids[i], true);
2324 }
2325 }
2326 return CL_SUCCESS;
2327 }
2328
2329#if defined(CL_HPP_USE_DX_INTEROP)
2330 /*! \brief Get the list of available D3D10 devices.
2331 *
2332 * \param d3d_device_source.
2333 *
2334 * \param d3d_object.
2335 *
2336 * \param d3d_device_set.
2337 *
2338 * \param devices returns a vector of OpenCL D3D10 devices found. The cl::Device
2339 * values returned in devices can be used to identify a specific OpenCL
2340 * device. If \a devices argument is NULL, this argument is ignored.
2341 *
2342 * \return One of the following values:
2343 * - CL_SUCCESS if the function is executed successfully.
2344 *
2345 * The application can query specific capabilities of the OpenCL device(s)
2346 * returned by cl::getDevices. This can be used by the application to
2347 * determine which device(s) to use.
2348 *
2349 * \note In the case that exceptions are enabled and a return value
2350 * other than CL_SUCCESS is generated, then cl::Error exception is
2351 * generated.
2352 */
2353 cl_int getDevices(
2354 cl_d3d10_device_source_khr d3d_device_source,
2355 void * d3d_object,
2356 cl_d3d10_device_set_khr d3d_device_set,
2357 vector<Device>* devices) const
2358 {
2359 typedef CL_API_ENTRY cl_int (CL_API_CALL *PFN_clGetDeviceIDsFromD3D10KHR)(
2360 cl_platform_id platform,
2361 cl_d3d10_device_source_khr d3d_device_source,
2362 void * d3d_object,
2363 cl_d3d10_device_set_khr d3d_device_set,
2364 cl_uint num_entries,
2365 cl_device_id * devices,
2366 cl_uint* num_devices);
2367
2368 if( devices == NULL ) {
2369 return detail::errHandler(CL_INVALID_ARG_VALUE, __GET_DEVICE_IDS_ERR);
2370 }
2371
2372 static PFN_clGetDeviceIDsFromD3D10KHR pfn_clGetDeviceIDsFromD3D10KHR = NULL;
2373 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(object_, clGetDeviceIDsFromD3D10KHR);
2374
2375 cl_uint n = 0;
2376 cl_int err = pfn_clGetDeviceIDsFromD3D10KHR(
2377 object_,
2378 d3d_device_source,
2379 d3d_object,
2380 d3d_device_set,
2381 0,
2382 NULL,
2383 &n);
2384 if (err != CL_SUCCESS) {
2385 return detail::errHandler(err, __GET_DEVICE_IDS_ERR);
2386 }
2387
2388 vector<cl_device_id> ids(n);
2389 err = pfn_clGetDeviceIDsFromD3D10KHR(
2390 object_,
2391 d3d_device_source,
2392 d3d_object,
2393 d3d_device_set,
2394 n,
2395 ids.data(),
2396 NULL);
2397 if (err != CL_SUCCESS) {
2398 return detail::errHandler(err, __GET_DEVICE_IDS_ERR);
2399 }
2400
2401 // Cannot trivially assign because we need to capture intermediates
2402 // with safe construction
2403 // We must retain things we obtain from the API to avoid releasing
2404 // API-owned objects.
2405 if (devices) {
2406 devices->resize(ids.size());
2407
2408 // Assign to param, constructing with retain behaviour
2409 // to correctly capture each underlying CL object
2410 for (size_type i = 0; i < ids.size(); i++) {
2411 (*devices)[i] = Device(ids[i], true);
2412 }
2413 }
2414 return CL_SUCCESS;
2415 }
2416#endif
2417
2418 /*! \brief Gets a list of available platforms.
2419 *
2420 * Wraps clGetPlatformIDs().
2421 */
2422 static cl_int get(
2423 vector<Platform>* platforms)
2424 {
2425 cl_uint n = 0;
2426
2427 if( platforms == NULL ) {
2428 return detail::errHandler(CL_INVALID_ARG_VALUE, __GET_PLATFORM_IDS_ERR);
2429 }
2430
2431 cl_int err = ::clGetPlatformIDs(0, NULL, &n);
2432 if (err != CL_SUCCESS) {
2433 return detail::errHandler(err, __GET_PLATFORM_IDS_ERR);
2434 }
2435
2436 vector<cl_platform_id> ids(n);
2437 err = ::clGetPlatformIDs(n, ids.data(), NULL);
2438 if (err != CL_SUCCESS) {
2439 return detail::errHandler(err, __GET_PLATFORM_IDS_ERR);
2440 }
2441
2442 if (platforms) {
2443 platforms->resize(ids.size());
2444
2445 // Platforms don't reference count
2446 for (size_type i = 0; i < ids.size(); i++) {
2447 (*platforms)[i] = Platform(ids[i]);
2448 }
2449 }
2450 return CL_SUCCESS;
2451 }
2452
2453 /*! \brief Gets the first available platform.
2454 *
2455 * Wraps clGetPlatformIDs(), returning the first result.
2456 */
2457 static cl_int get(
2458 Platform * platform)
2459 {
2460 cl_int err;
2461 Platform default_platform = Platform::getDefault(&err);
2462 if (platform) {
2463 *platform = default_platform;
2464 }
2465 return err;
2466 }
2467
2468 /*! \brief Gets the first available platform, returning it by value.
2469 *
2470 * \return Returns a valid platform if one is available.
2471 * If no platform is available will return a null platform.
2472 * Throws an exception if no platforms are available
2473 * or an error condition occurs.
2474 * Wraps clGetPlatformIDs(), returning the first result.
2475 */
2476 static Platform get(
2477 cl_int * errResult = NULL)
2478 {
2479 cl_int err;
2480 Platform default_platform = Platform::getDefault(&err);
2481 if (errResult) {
2482 *errResult = err;
2483 }
2484 return default_platform;
2485 }
2486
2487#if CL_HPP_TARGET_OPENCL_VERSION >= 120
2488 //! \brief Wrapper for clUnloadCompiler().
2489 cl_int
2490 unloadCompiler()
2491 {
2492 return ::clUnloadPlatformCompiler(object_);
2493 }
2494#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
2495}; // class Platform
2496
2497CL_HPP_DEFINE_STATIC_MEMBER_ std::once_flag Platform::default_initialized_;
2498CL_HPP_DEFINE_STATIC_MEMBER_ Platform Platform::default_;
2499CL_HPP_DEFINE_STATIC_MEMBER_ cl_int Platform::default_error_ = CL_SUCCESS;
2500
2501
2502/**
2503 * Deprecated APIs for 1.2
2504 */
2505#if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
2506/**
2507 * Unload the OpenCL compiler.
2508 * \note Deprecated for OpenCL 1.2. Use Platform::unloadCompiler instead.
2509 */
2510inline CL_EXT_PREFIX__VERSION_1_1_DEPRECATED cl_int
2511UnloadCompiler() CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED;
2512inline cl_int
2513UnloadCompiler()
2514{
2515 return ::clUnloadCompiler();
2516}
2517#endif // #if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
2518
2519/*! \brief Class interface for cl_context.
2520 *
2521 * \note Copies of these objects are shallow, meaning that the copy will refer
2522 * to the same underlying cl_context as the original. For details, see
2523 * clRetainContext() and clReleaseContext().
2524 *
2525 * \see cl_context
2526 */
2527class Context
2528 : public detail::Wrapper<cl_context>
2529{
2530private:
2531 static std::once_flag default_initialized_;
2532 static Context default_;
2533 static cl_int default_error_;
2534
2535 /*! \brief Create the default context from the default device type in the default platform.
2536 *
2537 * This sets @c default_ and @c default_error_. It does not throw
2538 * @c cl::Error.
2539 */
2540 static void makeDefault() {
2541 /* Throwing an exception from a call_once invocation does not do
2542 * what we wish, so we catch it and save the error.
2543 */
2544#if defined(CL_HPP_ENABLE_EXCEPTIONS)
2545 try
2546#endif
2547 {
2548#if !defined(__APPLE__) && !defined(__MACOS)
2549 const Platform &p = Platform::getDefault();
2550 cl_platform_id defaultPlatform = p();
2551 cl_context_properties properties[3] = {
2552 CL_CONTEXT_PLATFORM, (cl_context_properties)defaultPlatform, 0
2553 };
2554#else // #if !defined(__APPLE__) && !defined(__MACOS)
2555 cl_context_properties *properties = nullptr;
2556#endif // #if !defined(__APPLE__) && !defined(__MACOS)
2557
2558 default_ = Context(
2559 CL_DEVICE_TYPE_DEFAULT,
2560 properties,
2561 NULL,
2562 NULL,
2563 &default_error_);
2564 }
2565#if defined(CL_HPP_ENABLE_EXCEPTIONS)
2566 catch (cl::Error &e) {
2567 default_error_ = e.err();
2568 }
2569#endif
2570 }
2571
2572
2573 /*! \brief Create the default context from a provided Context.
2574 *
2575 * This sets @c default_. It does not throw
2576 * @c cl::Error.
2577 */
2578 static void makeDefaultProvided(const Context &c) {
2579 default_ = c;
2580 }
2581
2582public:
2583#ifdef CL_HPP_UNIT_TEST_ENABLE
2584 /*! \brief Reset the default.
2585 *
2586 * This sets @c default_ to an empty value to support cleanup in
2587 * the unit test framework.
2588 * This function is not thread safe.
2589 */
2590 static void unitTestClearDefault() {
2591 default_ = Context();
2592 }
2593#endif // #ifdef CL_HPP_UNIT_TEST_ENABLE
2594
2595 /*! \brief Constructs a context including a list of specified devices.
2596 *
2597 * Wraps clCreateContext().
2598 */
2599 Context(
2600 const vector<Device>& devices,
2601 cl_context_properties* properties = NULL,
2602 void (CL_CALLBACK * notifyFptr)(
2603 const char *,
2604 const void *,
2605 size_type,
2606 void *) = NULL,
2607 void* data = NULL,
2608 cl_int* err = NULL)
2609 {
2610 cl_int error;
2611
2612 size_type numDevices = devices.size();
2613 vector<cl_device_id> deviceIDs(numDevices);
2614
2615 for( size_type deviceIndex = 0; deviceIndex < numDevices; ++deviceIndex ) {
2616 deviceIDs[deviceIndex] = (devices[deviceIndex])();
2617 }
2618
2619 object_ = ::clCreateContext(
2620 properties, (cl_uint) numDevices,
2621 deviceIDs.data(),
2622 notifyFptr, data, &error);
2623
2624 detail::errHandler(error, __CREATE_CONTEXT_ERR);
2625 if (err != NULL) {
2626 *err = error;
2627 }
2628 }
2629
2630 Context(
2631 const Device& device,
2632 cl_context_properties* properties = NULL,
2633 void (CL_CALLBACK * notifyFptr)(
2634 const char *,
2635 const void *,
2636 size_type,
2637 void *) = NULL,
2638 void* data = NULL,
2639 cl_int* err = NULL)
2640 {
2641 cl_int error;
2642
2643 cl_device_id deviceID = device();
2644
2645 object_ = ::clCreateContext(
2646 properties, 1,
2647 &deviceID,
2648 notifyFptr, data, &error);
2649
2650 detail::errHandler(error, __CREATE_CONTEXT_ERR);
2651 if (err != NULL) {
2652 *err = error;
2653 }
2654 }
2655
2656 /*! \brief Constructs a context including all or a subset of devices of a specified type.
2657 *
2658 * Wraps clCreateContextFromType().
2659 */
2660 Context(
2661 cl_device_type type,
2662 cl_context_properties* properties = NULL,
2663 void (CL_CALLBACK * notifyFptr)(
2664 const char *,
2665 const void *,
2666 size_type,
2667 void *) = NULL,
2668 void* data = NULL,
2669 cl_int* err = NULL)
2670 {
2671 cl_int error;
2672
2673#if !defined(__APPLE__) && !defined(__MACOS)
2674 cl_context_properties prop[4] = {CL_CONTEXT_PLATFORM, 0, 0, 0 };
2675
2676 if (properties == NULL) {
2677 // Get a valid platform ID as we cannot send in a blank one
2678 vector<Platform> platforms;
2679 error = Platform::get(&platforms);
2680 if (error != CL_SUCCESS) {
2681 detail::errHandler(error, __CREATE_CONTEXT_FROM_TYPE_ERR);
2682 if (err != NULL) {
2683 *err = error;
2684 }
2685 return;
2686 }
2687
2688 // Check the platforms we found for a device of our specified type
2689 cl_context_properties platform_id = 0;
2690 for (unsigned int i = 0; i < platforms.size(); i++) {
2691
2692 vector<Device> devices;
2693
2694#if defined(CL_HPP_ENABLE_EXCEPTIONS)
2695 try {
2696#endif
2697
2698 error = platforms[i].getDevices(type, &devices);
2699
2700#if defined(CL_HPP_ENABLE_EXCEPTIONS)
2701 } catch (Error) {}
2702 // Catch if exceptions are enabled as we don't want to exit if first platform has no devices of type
2703 // We do error checking next anyway, and can throw there if needed
2704#endif
2705
2706 // Only squash CL_SUCCESS and CL_DEVICE_NOT_FOUND
2707 if (error != CL_SUCCESS && error != CL_DEVICE_NOT_FOUND) {
2708 detail::errHandler(error, __CREATE_CONTEXT_FROM_TYPE_ERR);
2709 if (err != NULL) {
2710 *err = error;
2711 }
2712 }
2713
2714 if (devices.size() > 0) {
2715 platform_id = (cl_context_properties)platforms[i]();
2716 break;
2717 }
2718 }
2719
2720 if (platform_id == 0) {
2721 detail::errHandler(CL_DEVICE_NOT_FOUND, __CREATE_CONTEXT_FROM_TYPE_ERR);
2722 if (err != NULL) {
2723 *err = CL_DEVICE_NOT_FOUND;
2724 }
2725 return;
2726 }
2727
2728 prop[1] = platform_id;
2729 properties = &prop[0];
2730 }
2731#endif
2732 object_ = ::clCreateContextFromType(
2733 properties, type, notifyFptr, data, &error);
2734
2735 detail::errHandler(error, __CREATE_CONTEXT_FROM_TYPE_ERR);
2736 if (err != NULL) {
2737 *err = error;
2738 }
2739 }
2740
2741 /*! \brief Copy constructor to forward copy to the superclass correctly.
2742 * Required for MSVC.
2743 */
2744 Context(const Context& ctx) : detail::Wrapper<cl_type>(ctx) {}
2745
2746 /*! \brief Copy assignment to forward copy to the superclass correctly.
2747 * Required for MSVC.
2748 */
2749 Context& operator = (const Context &ctx)
2750 {
2751 detail::Wrapper<cl_type>::operator=(ctx);
2752 return *this;
2753 }
2754
2755 /*! \brief Move constructor to forward move to the superclass correctly.
2756 * Required for MSVC.
2757 */
2758 Context(Context&& ctx) CL_HPP_NOEXCEPT_ : detail::Wrapper<cl_type>(std::move(ctx)) {}
2759
2760 /*! \brief Move assignment to forward move to the superclass correctly.
2761 * Required for MSVC.
2762 */
2763 Context& operator = (Context &&ctx)
2764 {
2765 detail::Wrapper<cl_type>::operator=(std::move(ctx));
2766 return *this;
2767 }
2768
2769
2770 /*! \brief Returns a singleton context including all devices of CL_DEVICE_TYPE_DEFAULT.
2771 *
2772 * \note All calls to this function return the same cl_context as the first.
2773 */
2774 static Context getDefault(cl_int * err = NULL)
2775 {
2776 std::call_once(default_initialized_, makeDefault);
2777 detail::errHandler(default_error_);
2778 if (err != NULL) {
2779 *err = default_error_;
2780 }
2781 return default_;
2782 }
2783
2784 /**
2785 * Modify the default context to be used by
2786 * subsequent operations.
2787 * Will only set the default if no default was previously created.
2788 * @return updated default context.
2789 * Should be compared to the passed value to ensure that it was updated.
2790 */
2791 static Context setDefault(const Context &default_context)
2792 {
2793 std::call_once(default_initialized_, makeDefaultProvided, std::cref(default_context));
2794 detail::errHandler(default_error_);
2795 return default_;
2796 }
2797
2798 //! \brief Default constructor - initializes to NULL.
2799 Context() : detail::Wrapper<cl_type>() { }
2800
2801 /*! \brief Constructor from cl_context - takes ownership.
2802 *
2803 * This effectively transfers ownership of a refcount on the cl_context
2804 * into the new Context object.
2805 */
2806 explicit Context(const cl_context& context, bool retainObject = false) :
2807 detail::Wrapper<cl_type>(context, retainObject) { }
2808
2809 /*! \brief Assignment operator from cl_context - takes ownership.
2810 *
2811 * This effectively transfers ownership of a refcount on the rhs and calls
2812 * clReleaseContext() on the value previously held by this instance.
2813 */
2814 Context& operator = (const cl_context& rhs)
2815 {
2816 detail::Wrapper<cl_type>::operator=(rhs);
2817 return *this;
2818 }
2819
2820 //! \brief Wrapper for clGetContextInfo().
2821 template <typename T>
2822 cl_int getInfo(cl_context_info name, T* param) const
2823 {
2824 return detail::errHandler(
2825 detail::getInfo(&::clGetContextInfo, object_, name, param),
2826 __GET_CONTEXT_INFO_ERR);
2827 }
2828
2829 //! \brief Wrapper for clGetContextInfo() that returns by value.
2830 template <cl_int name> typename
2831 detail::param_traits<detail::cl_context_info, name>::param_type
2832 getInfo(cl_int* err = NULL) const
2833 {
2834 typename detail::param_traits<
2835 detail::cl_context_info, name>::param_type param;
2836 cl_int result = getInfo(name, &param);
2837 if (err != NULL) {
2838 *err = result;
2839 }
2840 return param;
2841 }
2842
2843 /*! \brief Gets a list of supported image formats.
2844 *
2845 * Wraps clGetSupportedImageFormats().
2846 */
2847 cl_int getSupportedImageFormats(
2848 cl_mem_flags flags,
2849 cl_mem_object_type type,
2850 vector<ImageFormat>* formats) const
2851 {
2852 cl_uint numEntries;
2853
2854 if (!formats) {
2855 return CL_SUCCESS;
2856 }
2857
2858 cl_int err = ::clGetSupportedImageFormats(
2859 object_,
2860 flags,
2861 type,
2862 0,
2863 NULL,
2864 &numEntries);
2865 if (err != CL_SUCCESS) {
2866 return detail::errHandler(err, __GET_SUPPORTED_IMAGE_FORMATS_ERR);
2867 }
2868
2869 if (numEntries > 0) {
2870 vector<ImageFormat> value(numEntries);
2871 err = ::clGetSupportedImageFormats(
2872 object_,
2873 flags,
2874 type,
2875 numEntries,
2876 (cl_image_format*)value.data(),
2877 NULL);
2878 if (err != CL_SUCCESS) {
2879 return detail::errHandler(err, __GET_SUPPORTED_IMAGE_FORMATS_ERR);
2880 }
2881
2882 formats->assign(begin(value), end(value));
2883 }
2884 else {
2885 // If no values are being returned, ensure an empty vector comes back
2886 formats->clear();
2887 }
2888
2889 return CL_SUCCESS;
2890 }
2891};
2892
2893inline void Device::makeDefault()
2894{
2895 /* Throwing an exception from a call_once invocation does not do
2896 * what we wish, so we catch it and save the error.
2897 */
2898#if defined(CL_HPP_ENABLE_EXCEPTIONS)
2899 try
2900#endif
2901 {
2902 cl_int error = 0;
2903
2904 Context context = Context::getDefault(&error);
2905 detail::errHandler(error, __CREATE_CONTEXT_ERR);
2906
2907 if (error != CL_SUCCESS) {
2908 default_error_ = error;
2909 }
2910 else {
2911 default_ = context.getInfo<CL_CONTEXT_DEVICES>()[0];
2912 default_error_ = CL_SUCCESS;
2913 }
2914 }
2915#if defined(CL_HPP_ENABLE_EXCEPTIONS)
2916 catch (cl::Error &e) {
2917 default_error_ = e.err();
2918 }
2919#endif
2920}
2921
2922CL_HPP_DEFINE_STATIC_MEMBER_ std::once_flag Context::default_initialized_;
2923CL_HPP_DEFINE_STATIC_MEMBER_ Context Context::default_;
2924CL_HPP_DEFINE_STATIC_MEMBER_ cl_int Context::default_error_ = CL_SUCCESS;
2925
2926/*! \brief Class interface for cl_event.
2927 *
2928 * \note Copies of these objects are shallow, meaning that the copy will refer
2929 * to the same underlying cl_event as the original. For details, see
2930 * clRetainEvent() and clReleaseEvent().
2931 *
2932 * \see cl_event
2933 */
2934class Event : public detail::Wrapper<cl_event>
2935{
2936public:
2937 //! \brief Default constructor - initializes to NULL.
2938 Event() : detail::Wrapper<cl_type>() { }
2939
2940 /*! \brief Constructor from cl_event - takes ownership.
2941 *
2942 * \param retainObject will cause the constructor to retain its cl object.
2943 * Defaults to false to maintain compatibility with
2944 * earlier versions.
2945 * This effectively transfers ownership of a refcount on the cl_event
2946 * into the new Event object.
2947 */
2948 explicit Event(const cl_event& event, bool retainObject = false) :
2949 detail::Wrapper<cl_type>(event, retainObject) { }
2950
2951 /*! \brief Assignment operator from cl_event - takes ownership.
2952 *
2953 * This effectively transfers ownership of a refcount on the rhs and calls
2954 * clReleaseEvent() on the value previously held by this instance.
2955 */
2956 Event& operator = (const cl_event& rhs)
2957 {
2958 detail::Wrapper<cl_type>::operator=(rhs);
2959 return *this;
2960 }
2961
2962 //! \brief Wrapper for clGetEventInfo().
2963 template <typename T>
2964 cl_int getInfo(cl_event_info name, T* param) const
2965 {
2966 return detail::errHandler(
2967 detail::getInfo(&::clGetEventInfo, object_, name, param),
2968 __GET_EVENT_INFO_ERR);
2969 }
2970
2971 //! \brief Wrapper for clGetEventInfo() that returns by value.
2972 template <cl_int name> typename
2973 detail::param_traits<detail::cl_event_info, name>::param_type
2974 getInfo(cl_int* err = NULL) const
2975 {
2976 typename detail::param_traits<
2977 detail::cl_event_info, name>::param_type param;
2978 cl_int result = getInfo(name, &param);
2979 if (err != NULL) {
2980 *err = result;
2981 }
2982 return param;
2983 }
2984
2985 //! \brief Wrapper for clGetEventProfilingInfo().
2986 template <typename T>
2987 cl_int getProfilingInfo(cl_profiling_info name, T* param) const
2988 {
2989 return detail::errHandler(detail::getInfo(
2990 &::clGetEventProfilingInfo, object_, name, param),
2991 __GET_EVENT_PROFILE_INFO_ERR);
2992 }
2993
2994 //! \brief Wrapper for clGetEventProfilingInfo() that returns by value.
2995 template <cl_int name> typename
2996 detail::param_traits<detail::cl_profiling_info, name>::param_type
2997 getProfilingInfo(cl_int* err = NULL) const
2998 {
2999 typename detail::param_traits<
3000 detail::cl_profiling_info, name>::param_type param;
3001 cl_int result = getProfilingInfo(name, &param);
3002 if (err != NULL) {
3003 *err = result;
3004 }
3005 return param;
3006 }
3007
3008 /*! \brief Blocks the calling thread until this event completes.
3009 *
3010 * Wraps clWaitForEvents().
3011 */
3012 cl_int wait() const
3013 {
3014 return detail::errHandler(
3015 ::clWaitForEvents(1, &object_),
3016 __WAIT_FOR_EVENTS_ERR);
3017 }
3018
3019#if CL_HPP_TARGET_OPENCL_VERSION >= 110
3020 /*! \brief Registers a user callback function for a specific command execution status.
3021 *
3022 * Wraps clSetEventCallback().
3023 */
3024 cl_int setCallback(
3025 cl_int type,
3026 void (CL_CALLBACK * pfn_notify)(cl_event, cl_int, void *),
3027 void * user_data = NULL)
3028 {
3029 return detail::errHandler(
3030 ::clSetEventCallback(
3031 object_,
3032 type,
3033 pfn_notify,
3034 user_data),
3035 __SET_EVENT_CALLBACK_ERR);
3036 }
3037#endif // CL_HPP_TARGET_OPENCL_VERSION >= 110
3038
3039 /*! \brief Blocks the calling thread until every event specified is complete.
3040 *
3041 * Wraps clWaitForEvents().
3042 */
3043 static cl_int
3044 waitForEvents(const vector<Event>& events)
3045 {
3046 return detail::errHandler(
3047 ::clWaitForEvents(
3048 (cl_uint) events.size(), (events.size() > 0) ? (cl_event*)&events.front() : NULL),
3049 __WAIT_FOR_EVENTS_ERR);
3050 }
3051};
3052
3053#if CL_HPP_TARGET_OPENCL_VERSION >= 110
3054/*! \brief Class interface for user events (a subset of cl_event's).
3055 *
3056 * See Event for details about copy semantics, etc.
3057 */
3058class UserEvent : public Event
3059{
3060public:
3061 /*! \brief Constructs a user event on a given context.
3062 *
3063 * Wraps clCreateUserEvent().
3064 */
3065 UserEvent(
3066 const Context& context,
3067 cl_int * err = NULL)
3068 {
3069 cl_int error;
3070 object_ = ::clCreateUserEvent(
3071 context(),
3072 &error);
3073
3074 detail::errHandler(error, __CREATE_USER_EVENT_ERR);
3075 if (err != NULL) {
3076 *err = error;
3077 }
3078 }
3079
3080 //! \brief Default constructor - initializes to NULL.
3081 UserEvent() : Event() { }
3082
3083 /*! \brief Sets the execution status of a user event object.
3084 *
3085 * Wraps clSetUserEventStatus().
3086 */
3087 cl_int setStatus(cl_int status)
3088 {
3089 return detail::errHandler(
3090 ::clSetUserEventStatus(object_,status),
3091 __SET_USER_EVENT_STATUS_ERR);
3092 }
3093};
3094#endif // CL_HPP_TARGET_OPENCL_VERSION >= 110
3095
3096/*! \brief Blocks the calling thread until every event specified is complete.
3097 *
3098 * Wraps clWaitForEvents().
3099 */
3100inline static cl_int
3101WaitForEvents(const vector<Event>& events)
3102{
3103 return detail::errHandler(
3104 ::clWaitForEvents(
3105 (cl_uint) events.size(), (events.size() > 0) ? (cl_event*)&events.front() : NULL),
3106 __WAIT_FOR_EVENTS_ERR);
3107}
3108
3109/*! \brief Class interface for cl_mem.
3110 *
3111 * \note Copies of these objects are shallow, meaning that the copy will refer
3112 * to the same underlying cl_mem as the original. For details, see
3113 * clRetainMemObject() and clReleaseMemObject().
3114 *
3115 * \see cl_mem
3116 */
3117class Memory : public detail::Wrapper<cl_mem>
3118{
3119public:
3120 //! \brief Default constructor - initializes to NULL.
3121 Memory() : detail::Wrapper<cl_type>() { }
3122
3123 /*! \brief Constructor from cl_mem - takes ownership.
3124 *
3125 * Optionally transfer ownership of a refcount on the cl_mem
3126 * into the new Memory object.
3127 *
3128 * \param retainObject will cause the constructor to retain its cl object.
3129 * Defaults to false to maintain compatibility with
3130 * earlier versions.
3131 *
3132 * See Memory for further details.
3133 */
3134 explicit Memory(const cl_mem& memory, bool retainObject) :
3135 detail::Wrapper<cl_type>(memory, retainObject) { }
3136
3137 /*! \brief Assignment operator from cl_mem - takes ownership.
3138 *
3139 * This effectively transfers ownership of a refcount on the rhs and calls
3140 * clReleaseMemObject() on the value previously held by this instance.
3141 */
3142 Memory& operator = (const cl_mem& rhs)
3143 {
3144 detail::Wrapper<cl_type>::operator=(rhs);
3145 return *this;
3146 }
3147
3148 /*! \brief Copy constructor to forward copy to the superclass correctly.
3149 * Required for MSVC.
3150 */
3151 Memory(const Memory& mem) : detail::Wrapper<cl_type>(mem) {}
3152
3153 /*! \brief Copy assignment to forward copy to the superclass correctly.
3154 * Required for MSVC.
3155 */
3156 Memory& operator = (const Memory &mem)
3157 {
3158 detail::Wrapper<cl_type>::operator=(mem);
3159 return *this;
3160 }
3161
3162 /*! \brief Move constructor to forward move to the superclass correctly.
3163 * Required for MSVC.
3164 */
3165 Memory(Memory&& mem) CL_HPP_NOEXCEPT_ : detail::Wrapper<cl_type>(std::move(mem)) {}
3166
3167 /*! \brief Move assignment to forward move to the superclass correctly.
3168 * Required for MSVC.
3169 */
3170 Memory& operator = (Memory &&mem)
3171 {
3172 detail::Wrapper<cl_type>::operator=(std::move(mem));
3173 return *this;
3174 }
3175
3176
3177 //! \brief Wrapper for clGetMemObjectInfo().
3178 template <typename T>
3179 cl_int getInfo(cl_mem_info name, T* param) const
3180 {
3181 return detail::errHandler(
3182 detail::getInfo(&::clGetMemObjectInfo, object_, name, param),
3183 __GET_MEM_OBJECT_INFO_ERR);
3184 }
3185
3186 //! \brief Wrapper for clGetMemObjectInfo() that returns by value.
3187 template <cl_int name> typename
3188 detail::param_traits<detail::cl_mem_info, name>::param_type
3189 getInfo(cl_int* err = NULL) const
3190 {
3191 typename detail::param_traits<
3192 detail::cl_mem_info, name>::param_type param;
3193 cl_int result = getInfo(name, &param);
3194 if (err != NULL) {
3195 *err = result;
3196 }
3197 return param;
3198 }
3199
3200#if CL_HPP_TARGET_OPENCL_VERSION >= 110
3201 /*! \brief Registers a callback function to be called when the memory object
3202 * is no longer needed.
3203 *
3204 * Wraps clSetMemObjectDestructorCallback().
3205 *
3206 * Repeated calls to this function, for a given cl_mem value, will append
3207 * to the list of functions called (in reverse order) when memory object's
3208 * resources are freed and the memory object is deleted.
3209 *
3210 * \note
3211 * The registered callbacks are associated with the underlying cl_mem
3212 * value - not the Memory class instance.
3213 */
3214 cl_int setDestructorCallback(
3215 void (CL_CALLBACK * pfn_notify)(cl_mem, void *),
3216 void * user_data = NULL)
3217 {
3218 return detail::errHandler(
3219 ::clSetMemObjectDestructorCallback(
3220 object_,
3221 pfn_notify,
3222 user_data),
3223 __SET_MEM_OBJECT_DESTRUCTOR_CALLBACK_ERR);
3224 }
3225#endif // CL_HPP_TARGET_OPENCL_VERSION >= 110
3226
3227};
3228
3229// Pre-declare copy functions
3230class Buffer;
3231template< typename IteratorType >
3232cl_int copy( IteratorType startIterator, IteratorType endIterator, cl::Buffer &buffer );
3233template< typename IteratorType >
3234cl_int copy( const cl::Buffer &buffer, IteratorType startIterator, IteratorType endIterator );
3235template< typename IteratorType >
3236cl_int copy( const CommandQueue &queue, IteratorType startIterator, IteratorType endIterator, cl::Buffer &buffer );
3237template< typename IteratorType >
3238cl_int copy( const CommandQueue &queue, const cl::Buffer &buffer, IteratorType startIterator, IteratorType endIterator );
3239
3240
3241#if CL_HPP_TARGET_OPENCL_VERSION >= 200
3242namespace detail
3243{
3244 class SVMTraitNull
3245 {
3246 public:
3247 static cl_svm_mem_flags getSVMMemFlags()
3248 {
3249 return 0;
3250 }
3251 };
3252} // namespace detail
3253
3254template<class Trait = detail::SVMTraitNull>
3255class SVMTraitReadWrite
3256{
3257public:
3258 static cl_svm_mem_flags getSVMMemFlags()
3259 {
3260 return CL_MEM_READ_WRITE |
3261 Trait::getSVMMemFlags();
3262 }
3263};
3264
3265template<class Trait = detail::SVMTraitNull>
3266class SVMTraitReadOnly
3267{
3268public:
3269 static cl_svm_mem_flags getSVMMemFlags()
3270 {
3271 return CL_MEM_READ_ONLY |
3272 Trait::getSVMMemFlags();
3273 }
3274};
3275
3276template<class Trait = detail::SVMTraitNull>
3277class SVMTraitWriteOnly
3278{
3279public:
3280 static cl_svm_mem_flags getSVMMemFlags()
3281 {
3282 return CL_MEM_WRITE_ONLY |
3283 Trait::getSVMMemFlags();
3284 }
3285};
3286
3287template<class Trait = SVMTraitReadWrite<>>
3288class SVMTraitCoarse
3289{
3290public:
3291 static cl_svm_mem_flags getSVMMemFlags()
3292 {
3293 return Trait::getSVMMemFlags();
3294 }
3295};
3296
3297template<class Trait = SVMTraitReadWrite<>>
3298class SVMTraitFine
3299{
3300public:
3301 static cl_svm_mem_flags getSVMMemFlags()
3302 {
3303 return CL_MEM_SVM_FINE_GRAIN_BUFFER |
3304 Trait::getSVMMemFlags();
3305 }
3306};
3307
3308template<class Trait = SVMTraitReadWrite<>>
3309class SVMTraitAtomic
3310{
3311public:
3312 static cl_svm_mem_flags getSVMMemFlags()
3313 {
3314 return
3315 CL_MEM_SVM_FINE_GRAIN_BUFFER |
3316 CL_MEM_SVM_ATOMICS |
3317 Trait::getSVMMemFlags();
3318 }
3319};
3320
3321// Pre-declare SVM map function
3322template<typename T>
3323inline cl_int enqueueMapSVM(
3324 T* ptr,
3325 cl_bool blocking,
3326 cl_map_flags flags,
3327 size_type size,
3328 const vector<Event>* events = NULL,
3329 Event* event = NULL);
3330
3331/**
3332 * STL-like allocator class for managing SVM objects provided for convenience.
3333 *
3334 * Note that while this behaves like an allocator for the purposes of constructing vectors and similar objects,
3335 * care must be taken when using with smart pointers.
3336 * The allocator should not be used to construct a unique_ptr if we are using coarse-grained SVM mode because
3337 * the coarse-grained management behaviour would behave incorrectly with respect to reference counting.
3338 *
3339 * Instead the allocator embeds a Deleter which may be used with unique_ptr and is used
3340 * with the allocate_shared and allocate_ptr supplied operations.
3341 */
3342template<typename T, class SVMTrait>
3343class SVMAllocator {
3344private:
3345 Context context_;
3346
3347public:
3348 typedef T value_type;
3349 typedef value_type* pointer;
3350 typedef const value_type* const_pointer;
3351 typedef value_type& reference;
3352 typedef const value_type& const_reference;
3353 typedef std::size_t size_type;
3354 typedef std::ptrdiff_t difference_type;
3355
3356 template<typename U>
3357 struct rebind
3358 {
3359 typedef SVMAllocator<U, SVMTrait> other;
3360 };
3361
3362 template<typename U, typename V>
3363 friend class SVMAllocator;
3364
3365 SVMAllocator() :
3366 context_(Context::getDefault())
3367 {
3368 }
3369
3370 explicit SVMAllocator(cl::Context context) :
3371 context_(context)
3372 {
3373 }
3374
3375
3376 SVMAllocator(const SVMAllocator &other) :
3377 context_(other.context_)
3378 {
3379 }
3380
3381 template<typename U>
3382 SVMAllocator(const SVMAllocator<U, SVMTrait> &other) :
3383 context_(other.context_)
3384 {
3385 }
3386
3387 ~SVMAllocator()
3388 {
3389 }
3390
3391 pointer address(reference r) CL_HPP_NOEXCEPT_
3392 {
3393 return std::addressof(r);
3394 }
3395
3396 const_pointer address(const_reference r) CL_HPP_NOEXCEPT_
3397 {
3398 return std::addressof(r);
3399 }
3400
3401 /**
3402 * Allocate an SVM pointer.
3403 *
3404 * If the allocator is coarse-grained, this will take ownership to allow
3405 * containers to correctly construct data in place.
3406 */
3407 pointer allocate(
3408 size_type size,
3409 typename cl::SVMAllocator<void, SVMTrait>::const_pointer = 0)
3410 {
3411 // Allocate memory with default alignment matching the size of the type
3412 void* voidPointer =
3413 clSVMAlloc(
3414 context_(),
3415 SVMTrait::getSVMMemFlags(),
3416 size*sizeof(T),
3417 sizeof(T));
3418 pointer retValue = reinterpret_cast<pointer>(
3419 voidPointer);
3420#if defined(CL_HPP_ENABLE_EXCEPTIONS)
3421 if (!retValue) {
3422 std::bad_alloc excep;
3423 throw excep;
3424 }
3425#endif // #if defined(CL_HPP_ENABLE_EXCEPTIONS)
3426
3427 // If allocation was coarse-grained then map it
3428 if (!(SVMTrait::getSVMMemFlags() & CL_MEM_SVM_FINE_GRAIN_BUFFER)) {
3429 cl_int err = enqueueMapSVM(retValue, CL_TRUE, CL_MAP_READ | CL_MAP_WRITE, size*sizeof(T));
3430 if (err != CL_SUCCESS) {
3431 std::bad_alloc excep;
3432 throw excep;
3433 }
3434 }
3435
3436 // If exceptions disabled, return null pointer from allocator
3437 return retValue;
3438 }
3439
3440 void deallocate(pointer p, size_type)
3441 {
3442 clSVMFree(context_(), p);
3443 }
3444
3445 /**
3446 * Return the maximum possible allocation size.
3447 * This is the minimum of the maximum sizes of all devices in the context.
3448 */
3449 size_type max_size() const CL_HPP_NOEXCEPT_
3450 {
3451 size_type maxSize = std::numeric_limits<size_type>::max() / sizeof(T);
3452
3453 for (Device &d : context_.getInfo<CL_CONTEXT_DEVICES>()) {
3454 maxSize = std::min(
3455 maxSize,
3456 static_cast<size_type>(d.getInfo<CL_DEVICE_MAX_MEM_ALLOC_SIZE>()));
3457 }
3458
3459 return maxSize;
3460 }
3461
3462 template< class U, class... Args >
3463 void construct(U* p, Args&&... args)
3464 {
3465 new(p)T(args...);
3466 }
3467
3468 template< class U >
3469 void destroy(U* p)
3470 {
3471 p->~U();
3472 }
3473
3474 /**
3475 * Returns true if the contexts match.
3476 */
3477 inline bool operator==(SVMAllocator const& rhs)
3478 {
3479 return (context_==rhs.context_);
3480 }
3481
3482 inline bool operator!=(SVMAllocator const& a)
3483 {
3484 return !operator==(a);
3485 }
3486}; // class SVMAllocator return cl::pointer<T>(tmp, detail::Deleter<T, Alloc>{alloc, copies});
3487
3488
3489template<class SVMTrait>
3490class SVMAllocator<void, SVMTrait> {
3491public:
3492 typedef void value_type;
3493 typedef value_type* pointer;
3494 typedef const value_type* const_pointer;
3495
3496 template<typename U>
3497 struct rebind
3498 {
3499 typedef SVMAllocator<U, SVMTrait> other;
3500 };
3501
3502 template<typename U, typename V>
3503 friend class SVMAllocator;
3504};
3505
3506#if !defined(CL_HPP_NO_STD_UNIQUE_PTR)
3507namespace detail
3508{
3509 template<class Alloc>
3510 class Deleter {
3511 private:
3512 Alloc alloc_;
3513 size_type copies_;
3514
3515 public:
3516 typedef typename std::allocator_traits<Alloc>::pointer pointer;
3517
3518 Deleter(const Alloc &alloc, size_type copies) : alloc_{ alloc }, copies_{ copies }
3519 {
3520 }
3521
3522 void operator()(pointer ptr) const {
3523 Alloc tmpAlloc{ alloc_ };
3524 std::allocator_traits<Alloc>::destroy(tmpAlloc, std::addressof(*ptr));
3525 std::allocator_traits<Alloc>::deallocate(tmpAlloc, ptr, copies_);
3526 }
3527 };
3528} // namespace detail
3529
3530/**
3531 * Allocation operation compatible with std::allocate_ptr.
3532 * Creates a unique_ptr<T> by default.
3533 * This requirement is to ensure that the control block is not
3534 * allocated in memory inaccessible to the host.
3535 */
3536template <class T, class Alloc, class... Args>
3537cl::pointer<T, detail::Deleter<Alloc>> allocate_pointer(const Alloc &alloc_, Args&&... args)
3538{
3539 Alloc alloc(alloc_);
3540 static const size_t copies = 1;
3541
3542 // Ensure that creation of the management block and the
3543 // object are dealt with separately such that we only provide a deleter
3544
3545 T* tmp = std::allocator_traits<Alloc>::allocate(alloc, copies);
3546 if (!tmp) {
3547 std::bad_alloc excep;
3548 throw excep;
3549 }
3550 try {
3551 std::allocator_traits<Alloc>::construct(
3552 alloc,
3553 std::addressof(*tmp),
3554 std::forward<Args>(args)...);
3555
3556 return cl::pointer<T, detail::Deleter<Alloc>>(tmp, detail::Deleter<Alloc>{alloc, copies});
3557 }
3558 catch (std::bad_alloc b)
3559 {
3560 std::allocator_traits<Alloc>::deallocate(alloc, tmp, copies);
3561 throw;
3562 }
3563}
3564
3565template< class T, class SVMTrait, class... Args >
3566cl::pointer<T, detail::Deleter<SVMAllocator<T, SVMTrait>>> allocate_svm(Args... args)
3567{
3568 SVMAllocator<T, SVMTrait> alloc;
3569 return cl::allocate_pointer<T>(alloc, args...);
3570}
3571
3572template< class T, class SVMTrait, class... Args >
3573cl::pointer<T, detail::Deleter<SVMAllocator<T, SVMTrait>>> allocate_svm(const cl::Context &c, Args... args)
3574{
3575 SVMAllocator<T, SVMTrait> alloc(c);
3576 return cl::allocate_pointer<T>(alloc, args...);
3577}
3578#endif // #if !defined(CL_HPP_NO_STD_UNIQUE_PTR)
3579
3580/*! \brief Vector alias to simplify contruction of coarse-grained SVM containers.
3581 *
3582 */
3583template < class T >
3584using coarse_svm_vector = vector<T, cl::SVMAllocator<int, cl::SVMTraitCoarse<>>>;
3585
3586/*! \brief Vector alias to simplify contruction of fine-grained SVM containers.
3587*
3588*/
3589template < class T >
3590using fine_svm_vector = vector<T, cl::SVMAllocator<int, cl::SVMTraitFine<>>>;
3591
3592/*! \brief Vector alias to simplify contruction of fine-grained SVM containers that support platform atomics.
3593*
3594*/
3595template < class T >
3596using atomic_svm_vector = vector<T, cl::SVMAllocator<int, cl::SVMTraitAtomic<>>>;
3597
3598#endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 200
3599
3600
3601/*! \brief Class interface for Buffer Memory Objects.
3602 *
3603 * See Memory for details about copy semantics, etc.
3604 *
3605 * \see Memory
3606 */
3607class Buffer : public Memory
3608{
3609public:
3610
3611 /*! \brief Constructs a Buffer in a specified context.
3612 *
3613 * Wraps clCreateBuffer().
3614 *
3615 * \param host_ptr Storage to be used if the CL_MEM_USE_HOST_PTR flag was
3616 * specified. Note alignment & exclusivity requirements.
3617 */
3618 Buffer(
3619 const Context& context,
3620 cl_mem_flags flags,
3621 size_type size,
3622 void* host_ptr = NULL,
3623 cl_int* err = NULL)
3624 {
3625 cl_int error;
3626 object_ = ::clCreateBuffer(context(), flags, size, host_ptr, &error);
3627
3628 detail::errHandler(error, __CREATE_BUFFER_ERR);
3629 if (err != NULL) {
3630 *err = error;
3631 }
3632 }
3633
3634 /*! \brief Constructs a Buffer in the default context.
3635 *
3636 * Wraps clCreateBuffer().
3637 *
3638 * \param host_ptr Storage to be used if the CL_MEM_USE_HOST_PTR flag was
3639 * specified. Note alignment & exclusivity requirements.
3640 *
3641 * \see Context::getDefault()
3642 */
3643 Buffer(
3644 cl_mem_flags flags,
3645 size_type size,
3646 void* host_ptr = NULL,
3647 cl_int* err = NULL)
3648 {
3649 cl_int error;
3650
3651 Context context = Context::getDefault(err);
3652
3653 object_ = ::clCreateBuffer(context(), flags, size, host_ptr, &error);
3654
3655 detail::errHandler(error, __CREATE_BUFFER_ERR);
3656 if (err != NULL) {
3657 *err = error;
3658 }
3659 }
3660
3661 /*!
3662 * \brief Construct a Buffer from a host container via iterators.
3663 * IteratorType must be random access.
3664 * If useHostPtr is specified iterators must represent contiguous data.
3665 */
3666 template< typename IteratorType >
3667 Buffer(
3668 IteratorType startIterator,
3669 IteratorType endIterator,
3670 bool readOnly,
3671 bool useHostPtr = false,
3672 cl_int* err = NULL)
3673 {
3674 typedef typename std::iterator_traits<IteratorType>::value_type DataType;
3675 cl_int error;
3676
3677 cl_mem_flags flags = 0;
3678 if( readOnly ) {
3679 flags |= CL_MEM_READ_ONLY;
3680 }
3681 else {
3682 flags |= CL_MEM_READ_WRITE;
3683 }
3684 if( useHostPtr ) {
3685 flags |= CL_MEM_USE_HOST_PTR;
3686 }
3687
3688 size_type size = sizeof(DataType)*(endIterator - startIterator);
3689
3690 Context context = Context::getDefault(err);
3691
3692 if( useHostPtr ) {
3693 object_ = ::clCreateBuffer(context(), flags, size, static_cast<DataType*>(&*startIterator), &error);
3694 } else {
3695 object_ = ::clCreateBuffer(context(), flags, size, 0, &error);
3696 }
3697
3698 detail::errHandler(error, __CREATE_BUFFER_ERR);
3699 if (err != NULL) {
3700 *err = error;
3701 }
3702
3703 if( !useHostPtr ) {
3704 error = cl::copy(startIterator, endIterator, *this);
3705 detail::errHandler(error, __CREATE_BUFFER_ERR);
3706 if (err != NULL) {
3707 *err = error;
3708 }
3709 }
3710 }
3711
3712 /*!
3713 * \brief Construct a Buffer from a host container via iterators using a specified context.
3714 * IteratorType must be random access.
3715 * If useHostPtr is specified iterators must represent contiguous data.
3716 */
3717 template< typename IteratorType >
3718 Buffer(const Context &context, IteratorType startIterator, IteratorType endIterator,
3719 bool readOnly, bool useHostPtr = false, cl_int* err = NULL);
3720
3721 /*!
3722 * \brief Construct a Buffer from a host container via iterators using a specified queue.
3723 * If useHostPtr is specified iterators must be random access.
3724 */
3725 template< typename IteratorType >
3726 Buffer(const CommandQueue &queue, IteratorType startIterator, IteratorType endIterator,
3727 bool readOnly, bool useHostPtr = false, cl_int* err = NULL);
3728
3729 //! \brief Default constructor - initializes to NULL.
3730 Buffer() : Memory() { }
3731
3732 /*! \brief Constructor from cl_mem - takes ownership.
3733 *
3734 * \param retainObject will cause the constructor to retain its cl object.
3735 * Defaults to false to maintain compatibility with earlier versions.
3736 *
3737 * See Memory for further details.
3738 */
3739 explicit Buffer(const cl_mem& buffer, bool retainObject = false) :
3740 Memory(buffer, retainObject) { }
3741
3742 /*! \brief Assignment from cl_mem - performs shallow copy.
3743 *
3744 * See Memory for further details.
3745 */
3746 Buffer& operator = (const cl_mem& rhs)
3747 {
3748 Memory::operator=(rhs);
3749 return *this;
3750 }
3751
3752 /*! \brief Copy constructor to forward copy to the superclass correctly.
3753 * Required for MSVC.
3754 */
3755 Buffer(const Buffer& buf) : Memory(buf) {}
3756
3757 /*! \brief Copy assignment to forward copy to the superclass correctly.
3758 * Required for MSVC.
3759 */
3760 Buffer& operator = (const Buffer &buf)
3761 {
3762 Memory::operator=(buf);
3763 return *this;
3764 }
3765
3766 /*! \brief Move constructor to forward move to the superclass correctly.
3767 * Required for MSVC.
3768 */
3769 Buffer(Buffer&& buf) CL_HPP_NOEXCEPT_ : Memory(std::move(buf)) {}
3770
3771 /*! \brief Move assignment to forward move to the superclass correctly.
3772 * Required for MSVC.
3773 */
3774 Buffer& operator = (Buffer &&buf)
3775 {
3776 Memory::operator=(std::move(buf));
3777 return *this;
3778 }
3779
3780#if CL_HPP_TARGET_OPENCL_VERSION >= 110
3781 /*! \brief Creates a new buffer object from this.
3782 *
3783 * Wraps clCreateSubBuffer().
3784 */
3785 Buffer createSubBuffer(
3786 cl_mem_flags flags,
3787 cl_buffer_create_type buffer_create_type,
3788 const void * buffer_create_info,
3789 cl_int * err = NULL)
3790 {
3791 Buffer result;
3792 cl_int error;
3793 result.object_ = ::clCreateSubBuffer(
3794 object_,
3795 flags,
3796 buffer_create_type,
3797 buffer_create_info,
3798 &error);
3799
3800 detail::errHandler(error, __CREATE_SUBBUFFER_ERR);
3801 if (err != NULL) {
3802 *err = error;
3803 }
3804
3805 return result;
3806 }
3807#endif // CL_HPP_TARGET_OPENCL_VERSION >= 110
3808};
3809
3810#if defined (CL_HPP_USE_DX_INTEROP)
3811/*! \brief Class interface for creating OpenCL buffers from ID3D10Buffer's.
3812 *
3813 * This is provided to facilitate interoperability with Direct3D.
3814 *
3815 * See Memory for details about copy semantics, etc.
3816 *
3817 * \see Memory
3818 */
3819class BufferD3D10 : public Buffer
3820{
3821public:
3822
3823
3824 /*! \brief Constructs a BufferD3D10, in a specified context, from a
3825 * given ID3D10Buffer.
3826 *
3827 * Wraps clCreateFromD3D10BufferKHR().
3828 */
3829 BufferD3D10(
3830 const Context& context,
3831 cl_mem_flags flags,
3832 ID3D10Buffer* bufobj,
3833 cl_int * err = NULL) : pfn_clCreateFromD3D10BufferKHR(nullptr)
3834 {
3835 typedef CL_API_ENTRY cl_mem (CL_API_CALL *PFN_clCreateFromD3D10BufferKHR)(
3836 cl_context context, cl_mem_flags flags, ID3D10Buffer* buffer,
3837 cl_int* errcode_ret);
3838 PFN_clCreateFromD3D10BufferKHR pfn_clCreateFromD3D10BufferKHR;
3839#if CL_HPP_TARGET_OPENCL_VERSION >= 120
3840 vector<cl_context_properties> props = context.getInfo<CL_CONTEXT_PROPERTIES>();
3841 cl_platform platform = -1;
3842 for( int i = 0; i < props.size(); ++i ) {
3843 if( props[i] == CL_CONTEXT_PLATFORM ) {
3844 platform = props[i+1];
3845 }
3846 }
3847 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clCreateFromD3D10BufferKHR);
3848#elif CL_HPP_TARGET_OPENCL_VERSION >= 110
3849 CL_HPP_INIT_CL_EXT_FCN_PTR_(clCreateFromD3D10BufferKHR);
3850#endif
3851
3852 cl_int error;
3853 object_ = pfn_clCreateFromD3D10BufferKHR(
3854 context(),
3855 flags,
3856 bufobj,
3857 &error);
3858
3859 detail::errHandler(error, __CREATE_GL_BUFFER_ERR);
3860 if (err != NULL) {
3861 *err = error;
3862 }
3863 }
3864
3865 //! \brief Default constructor - initializes to NULL.
3866 BufferD3D10() : Buffer() { }
3867
3868 /*! \brief Constructor from cl_mem - takes ownership.
3869 *
3870 * \param retainObject will cause the constructor to retain its cl object.
3871 * Defaults to false to maintain compatibility with
3872 * earlier versions.
3873 * See Memory for further details.
3874 */
3875 explicit BufferD3D10(const cl_mem& buffer, bool retainObject = false) :
3876 Buffer(buffer, retainObject) { }
3877
3878 /*! \brief Assignment from cl_mem - performs shallow copy.
3879 *
3880 * See Memory for further details.
3881 */
3882 BufferD3D10& operator = (const cl_mem& rhs)
3883 {
3884 Buffer::operator=(rhs);
3885 return *this;
3886 }
3887
3888 /*! \brief Copy constructor to forward copy to the superclass correctly.
3889 * Required for MSVC.
3890 */
3891 BufferD3D10(const BufferD3D10& buf) :
3892 Buffer(buf) {}
3893
3894 /*! \brief Copy assignment to forward copy to the superclass correctly.
3895 * Required for MSVC.
3896 */
3897 BufferD3D10& operator = (const BufferD3D10 &buf)
3898 {
3899 Buffer::operator=(buf);
3900 return *this;
3901 }
3902
3903 /*! \brief Move constructor to forward move to the superclass correctly.
3904 * Required for MSVC.
3905 */
3906 BufferD3D10(BufferD3D10&& buf) CL_HPP_NOEXCEPT_ : Buffer(std::move(buf)) {}
3907
3908 /*! \brief Move assignment to forward move to the superclass correctly.
3909 * Required for MSVC.
3910 */
3911 BufferD3D10& operator = (BufferD3D10 &&buf)
3912 {
3913 Buffer::operator=(std::move(buf));
3914 return *this;
3915 }
3916};
3917#endif
3918
3919/*! \brief Class interface for GL Buffer Memory Objects.
3920 *
3921 * This is provided to facilitate interoperability with OpenGL.
3922 *
3923 * See Memory for details about copy semantics, etc.
3924 *
3925 * \see Memory
3926 */
3927class BufferGL : public Buffer
3928{
3929public:
3930 /*! \brief Constructs a BufferGL in a specified context, from a given
3931 * GL buffer.
3932 *
3933 * Wraps clCreateFromGLBuffer().
3934 */
3935 BufferGL(
3936 const Context& context,
3937 cl_mem_flags flags,
3938 cl_GLuint bufobj,
3939 cl_int * err = NULL)
3940 {
3941 cl_int error;
3942 object_ = ::clCreateFromGLBuffer(
3943 context(),
3944 flags,
3945 bufobj,
3946 &error);
3947
3948 detail::errHandler(error, __CREATE_GL_BUFFER_ERR);
3949 if (err != NULL) {
3950 *err = error;
3951 }
3952 }
3953
3954 //! \brief Default constructor - initializes to NULL.
3955 BufferGL() : Buffer() { }
3956
3957 /*! \brief Constructor from cl_mem - takes ownership.
3958 *
3959 * \param retainObject will cause the constructor to retain its cl object.
3960 * Defaults to false to maintain compatibility with
3961 * earlier versions.
3962 * See Memory for further details.
3963 */
3964 explicit BufferGL(const cl_mem& buffer, bool retainObject = false) :
3965 Buffer(buffer, retainObject) { }
3966
3967 /*! \brief Assignment from cl_mem - performs shallow copy.
3968 *
3969 * See Memory for further details.
3970 */
3971 BufferGL& operator = (const cl_mem& rhs)
3972 {
3973 Buffer::operator=(rhs);
3974 return *this;
3975 }
3976
3977 /*! \brief Copy constructor to forward copy to the superclass correctly.
3978 * Required for MSVC.
3979 */
3980 BufferGL(const BufferGL& buf) : Buffer(buf) {}
3981
3982 /*! \brief Copy assignment to forward copy to the superclass correctly.
3983 * Required for MSVC.
3984 */
3985 BufferGL& operator = (const BufferGL &buf)
3986 {
3987 Buffer::operator=(buf);
3988 return *this;
3989 }
3990
3991 /*! \brief Move constructor to forward move to the superclass correctly.
3992 * Required for MSVC.
3993 */
3994 BufferGL(BufferGL&& buf) CL_HPP_NOEXCEPT_ : Buffer(std::move(buf)) {}
3995
3996 /*! \brief Move assignment to forward move to the superclass correctly.
3997 * Required for MSVC.
3998 */
3999 BufferGL& operator = (BufferGL &&buf)
4000 {
4001 Buffer::operator=(std::move(buf));
4002 return *this;
4003 }
4004
4005 //! \brief Wrapper for clGetGLObjectInfo().
4006 cl_int getObjectInfo(
4007 cl_gl_object_type *type,
4008 cl_GLuint * gl_object_name)
4009 {
4010 return detail::errHandler(
4011 ::clGetGLObjectInfo(object_,type,gl_object_name),
4012 __GET_GL_OBJECT_INFO_ERR);
4013 }
4014};
4015
4016/*! \brief Class interface for GL Render Buffer Memory Objects.
4017 *
4018 * This is provided to facilitate interoperability with OpenGL.
4019 *
4020 * See Memory for details about copy semantics, etc.
4021 *
4022 * \see Memory
4023 */
4024class BufferRenderGL : public Buffer
4025{
4026public:
4027 /*! \brief Constructs a BufferRenderGL in a specified context, from a given
4028 * GL Renderbuffer.
4029 *
4030 * Wraps clCreateFromGLRenderbuffer().
4031 */
4032 BufferRenderGL(
4033 const Context& context,
4034 cl_mem_flags flags,
4035 cl_GLuint bufobj,
4036 cl_int * err = NULL)
4037 {
4038 cl_int error;
4039 object_ = ::clCreateFromGLRenderbuffer(
4040 context(),
4041 flags,
4042 bufobj,
4043 &error);
4044
4045 detail::errHandler(error, __CREATE_GL_RENDER_BUFFER_ERR);
4046 if (err != NULL) {
4047 *err = error;
4048 }
4049 }
4050
4051 //! \brief Default constructor - initializes to NULL.
4052 BufferRenderGL() : Buffer() { }
4053
4054 /*! \brief Constructor from cl_mem - takes ownership.
4055 *
4056 * \param retainObject will cause the constructor to retain its cl object.
4057 * Defaults to false to maintain compatibility with
4058 * earlier versions.
4059 * See Memory for further details.
4060 */
4061 explicit BufferRenderGL(const cl_mem& buffer, bool retainObject = false) :
4062 Buffer(buffer, retainObject) { }
4063
4064 /*! \brief Assignment from cl_mem - performs shallow copy.
4065 *
4066 * See Memory for further details.
4067 */
4068 BufferRenderGL& operator = (const cl_mem& rhs)
4069 {
4070 Buffer::operator=(rhs);
4071 return *this;
4072 }
4073
4074 /*! \brief Copy constructor to forward copy to the superclass correctly.
4075 * Required for MSVC.
4076 */
4077 BufferRenderGL(const BufferRenderGL& buf) : Buffer(buf) {}
4078
4079 /*! \brief Copy assignment to forward copy to the superclass correctly.
4080 * Required for MSVC.
4081 */
4082 BufferRenderGL& operator = (const BufferRenderGL &buf)
4083 {
4084 Buffer::operator=(buf);
4085 return *this;
4086 }
4087
4088 /*! \brief Move constructor to forward move to the superclass correctly.
4089 * Required for MSVC.
4090 */
4091 BufferRenderGL(BufferRenderGL&& buf) CL_HPP_NOEXCEPT_ : Buffer(std::move(buf)) {}
4092
4093 /*! \brief Move assignment to forward move to the superclass correctly.
4094 * Required for MSVC.
4095 */
4096 BufferRenderGL& operator = (BufferRenderGL &&buf)
4097 {
4098 Buffer::operator=(std::move(buf));
4099 return *this;
4100 }
4101
4102 //! \brief Wrapper for clGetGLObjectInfo().
4103 cl_int getObjectInfo(
4104 cl_gl_object_type *type,
4105 cl_GLuint * gl_object_name)
4106 {
4107 return detail::errHandler(
4108 ::clGetGLObjectInfo(object_,type,gl_object_name),
4109 __GET_GL_OBJECT_INFO_ERR);
4110 }
4111};
4112
4113/*! \brief C++ base class for Image Memory objects.
4114 *
4115 * See Memory for details about copy semantics, etc.
4116 *
4117 * \see Memory
4118 */
4119class Image : public Memory
4120{
4121protected:
4122 //! \brief Default constructor - initializes to NULL.
4123 Image() : Memory() { }
4124
4125 /*! \brief Constructor from cl_mem - takes ownership.
4126 *
4127 * \param retainObject will cause the constructor to retain its cl object.
4128 * Defaults to false to maintain compatibility with
4129 * earlier versions.
4130 * See Memory for further details.
4131 */
4132 explicit Image(const cl_mem& image, bool retainObject = false) :
4133 Memory(image, retainObject) { }
4134
4135 /*! \brief Assignment from cl_mem - performs shallow copy.
4136 *
4137 * See Memory for further details.
4138 */
4139 Image& operator = (const cl_mem& rhs)
4140 {
4141 Memory::operator=(rhs);
4142 return *this;
4143 }
4144
4145 /*! \brief Copy constructor to forward copy to the superclass correctly.
4146 * Required for MSVC.
4147 */
4148 Image(const Image& img) : Memory(img) {}
4149
4150 /*! \brief Copy assignment to forward copy to the superclass correctly.
4151 * Required for MSVC.
4152 */
4153 Image& operator = (const Image &img)
4154 {
4155 Memory::operator=(img);
4156 return *this;
4157 }
4158
4159 /*! \brief Move constructor to forward move to the superclass correctly.
4160 * Required for MSVC.
4161 */
4162 Image(Image&& img) CL_HPP_NOEXCEPT_ : Memory(std::move(img)) {}
4163
4164 /*! \brief Move assignment to forward move to the superclass correctly.
4165 * Required for MSVC.
4166 */
4167 Image& operator = (Image &&img)
4168 {
4169 Memory::operator=(std::move(img));
4170 return *this;
4171 }
4172
4173
4174public:
4175 //! \brief Wrapper for clGetImageInfo().
4176 template <typename T>
4177 cl_int getImageInfo(cl_image_info name, T* param) const
4178 {
4179 return detail::errHandler(
4180 detail::getInfo(&::clGetImageInfo, object_, name, param),
4181 __GET_IMAGE_INFO_ERR);
4182 }
4183
4184 //! \brief Wrapper for clGetImageInfo() that returns by value.
4185 template <cl_int name> typename
4186 detail::param_traits<detail::cl_image_info, name>::param_type
4187 getImageInfo(cl_int* err = NULL) const
4188 {
4189 typename detail::param_traits<
4190 detail::cl_image_info, name>::param_type param;
4191 cl_int result = getImageInfo(name, &param);
4192 if (err != NULL) {
4193 *err = result;
4194 }
4195 return param;
4196 }
4197};
4198
4199#if CL_HPP_TARGET_OPENCL_VERSION >= 120
4200/*! \brief Class interface for 1D Image Memory objects.
4201 *
4202 * See Memory for details about copy semantics, etc.
4203 *
4204 * \see Memory
4205 */
4206class Image1D : public Image
4207{
4208public:
4209 /*! \brief Constructs a 1D Image in a specified context.
4210 *
4211 * Wraps clCreateImage().
4212 */
4213 Image1D(
4214 const Context& context,
4215 cl_mem_flags flags,
4216 ImageFormat format,
4217 size_type width,
4218 void* host_ptr = NULL,
4219 cl_int* err = NULL)
4220 {
4221 cl_int error;
4222 cl_image_desc desc =
4223 {
4224 CL_MEM_OBJECT_IMAGE1D,
4225 width,
4226 0, 0, 0, 0, 0, 0, 0, 0
4227 };
4228 object_ = ::clCreateImage(
4229 context(),
4230 flags,
4231 &format,
4232 &desc,
4233 host_ptr,
4234 &error);
4235
4236 detail::errHandler(error, __CREATE_IMAGE_ERR);
4237 if (err != NULL) {
4238 *err = error;
4239 }
4240 }
4241
4242 //! \brief Default constructor - initializes to NULL.
4243 Image1D() { }
4244
4245 /*! \brief Constructor from cl_mem - takes ownership.
4246 *
4247 * \param retainObject will cause the constructor to retain its cl object.
4248 * Defaults to false to maintain compatibility with
4249 * earlier versions.
4250 * See Memory for further details.
4251 */
4252 explicit Image1D(const cl_mem& image1D, bool retainObject = false) :
4253 Image(image1D, retainObject) { }
4254
4255 /*! \brief Assignment from cl_mem - performs shallow copy.
4256 *
4257 * See Memory for further details.
4258 */
4259 Image1D& operator = (const cl_mem& rhs)
4260 {
4261 Image::operator=(rhs);
4262 return *this;
4263 }
4264
4265 /*! \brief Copy constructor to forward copy to the superclass correctly.
4266 * Required for MSVC.
4267 */
4268 Image1D(const Image1D& img) : Image(img) {}
4269
4270 /*! \brief Copy assignment to forward copy to the superclass correctly.
4271 * Required for MSVC.
4272 */
4273 Image1D& operator = (const Image1D &img)
4274 {
4275 Image::operator=(img);
4276 return *this;
4277 }
4278
4279 /*! \brief Move constructor to forward move to the superclass correctly.
4280 * Required for MSVC.
4281 */
4282 Image1D(Image1D&& img) CL_HPP_NOEXCEPT_ : Image(std::move(img)) {}
4283
4284 /*! \brief Move assignment to forward move to the superclass correctly.
4285 * Required for MSVC.
4286 */
4287 Image1D& operator = (Image1D &&img)
4288 {
4289 Image::operator=(std::move(img));
4290 return *this;
4291 }
4292
4293};
4294
4295/*! \class Image1DBuffer
4296 * \brief Image interface for 1D buffer images.
4297 */
4298class Image1DBuffer : public Image
4299{
4300public:
4301 Image1DBuffer(
4302 const Context& context,
4303 cl_mem_flags flags,
4304 ImageFormat format,
4305 size_type width,
4306 const Buffer &buffer,
4307 cl_int* err = NULL)
4308 {
4309 cl_int error;
4310 cl_image_desc desc =
4311 {
4312 CL_MEM_OBJECT_IMAGE1D_BUFFER,
4313 width,
4314 0, 0, 0, 0, 0, 0, 0,
4315 buffer()
4316 };
4317 object_ = ::clCreateImage(
4318 context(),
4319 flags,
4320 &format,
4321 &desc,
4322 NULL,
4323 &error);
4324
4325 detail::errHandler(error, __CREATE_IMAGE_ERR);
4326 if (err != NULL) {
4327 *err = error;
4328 }
4329 }
4330
4331 Image1DBuffer() { }
4332
4333 /*! \brief Constructor from cl_mem - takes ownership.
4334 *
4335 * \param retainObject will cause the constructor to retain its cl object.
4336 * Defaults to false to maintain compatibility with
4337 * earlier versions.
4338 * See Memory for further details.
4339 */
4340 explicit Image1DBuffer(const cl_mem& image1D, bool retainObject = false) :
4341 Image(image1D, retainObject) { }
4342
4343 Image1DBuffer& operator = (const cl_mem& rhs)
4344 {
4345 Image::operator=(rhs);
4346 return *this;
4347 }
4348
4349 /*! \brief Copy constructor to forward copy to the superclass correctly.
4350 * Required for MSVC.
4351 */
4352 Image1DBuffer(const Image1DBuffer& img) : Image(img) {}
4353
4354 /*! \brief Copy assignment to forward copy to the superclass correctly.
4355 * Required for MSVC.
4356 */
4357 Image1DBuffer& operator = (const Image1DBuffer &img)
4358 {
4359 Image::operator=(img);
4360 return *this;
4361 }
4362
4363 /*! \brief Move constructor to forward move to the superclass correctly.
4364 * Required for MSVC.
4365 */
4366 Image1DBuffer(Image1DBuffer&& img) CL_HPP_NOEXCEPT_ : Image(std::move(img)) {}
4367
4368 /*! \brief Move assignment to forward move to the superclass correctly.
4369 * Required for MSVC.
4370 */
4371 Image1DBuffer& operator = (Image1DBuffer &&img)
4372 {
4373 Image::operator=(std::move(img));
4374 return *this;
4375 }
4376
4377};
4378
4379/*! \class Image1DArray
4380 * \brief Image interface for arrays of 1D images.
4381 */
4382class Image1DArray : public Image
4383{
4384public:
4385 Image1DArray(
4386 const Context& context,
4387 cl_mem_flags flags,
4388 ImageFormat format,
4389 size_type arraySize,
4390 size_type width,
4391 size_type rowPitch,
4392 void* host_ptr = NULL,
4393 cl_int* err = NULL)
4394 {
4395 cl_int error;
4396 cl_image_desc desc =
4397 {
4398 CL_MEM_OBJECT_IMAGE1D_ARRAY,
4399 width,
4400 0, 0, // height, depth (unused)
4401 arraySize,
4402 rowPitch,
4403 0, 0, 0, 0
4404 };
4405 object_ = ::clCreateImage(
4406 context(),
4407 flags,
4408 &format,
4409 &desc,
4410 host_ptr,
4411 &error);
4412
4413 detail::errHandler(error, __CREATE_IMAGE_ERR);
4414 if (err != NULL) {
4415 *err = error;
4416 }
4417 }
4418
4419 Image1DArray() { }
4420
4421 /*! \brief Constructor from cl_mem - takes ownership.
4422 *
4423 * \param retainObject will cause the constructor to retain its cl object.
4424 * Defaults to false to maintain compatibility with
4425 * earlier versions.
4426 * See Memory for further details.
4427 */
4428 explicit Image1DArray(const cl_mem& imageArray, bool retainObject = false) :
4429 Image(imageArray, retainObject) { }
4430
4431
4432 Image1DArray& operator = (const cl_mem& rhs)
4433 {
4434 Image::operator=(rhs);
4435 return *this;
4436 }
4437
4438 /*! \brief Copy constructor to forward copy to the superclass correctly.
4439 * Required for MSVC.
4440 */
4441 Image1DArray(const Image1DArray& img) : Image(img) {}
4442
4443 /*! \brief Copy assignment to forward copy to the superclass correctly.
4444 * Required for MSVC.
4445 */
4446 Image1DArray& operator = (const Image1DArray &img)
4447 {
4448 Image::operator=(img);
4449 return *this;
4450 }
4451
4452 /*! \brief Move constructor to forward move to the superclass correctly.
4453 * Required for MSVC.
4454 */
4455 Image1DArray(Image1DArray&& img) CL_HPP_NOEXCEPT_ : Image(std::move(img)) {}
4456
4457 /*! \brief Move assignment to forward move to the superclass correctly.
4458 * Required for MSVC.
4459 */
4460 Image1DArray& operator = (Image1DArray &&img)
4461 {
4462 Image::operator=(std::move(img));
4463 return *this;
4464 }
4465
4466};
4467#endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 120
4468
4469
4470/*! \brief Class interface for 2D Image Memory objects.
4471 *
4472 * See Memory for details about copy semantics, etc.
4473 *
4474 * \see Memory
4475 */
4476class Image2D : public Image
4477{
4478public:
4479 /*! \brief Constructs a 2D Image in a specified context.
4480 *
4481 * Wraps clCreateImage().
4482 */
4483 Image2D(
4484 const Context& context,
4485 cl_mem_flags flags,
4486 ImageFormat format,
4487 size_type width,
4488 size_type height,
4489 size_type row_pitch = 0,
4490 void* host_ptr = NULL,
4491 cl_int* err = NULL)
4492 {
4493 cl_int error;
4494 bool useCreateImage;
4495
4496#if CL_HPP_TARGET_OPENCL_VERSION >= 120 && CL_HPP_MINIMUM_OPENCL_VERSION < 120
4497 // Run-time decision based on the actual platform
4498 {
4499 cl_uint version = detail::getContextPlatformVersion(context());
4500 useCreateImage = (version >= 0x10002); // OpenCL 1.2 or above
4501 }
4502#elif CL_HPP_TARGET_OPENCL_VERSION >= 120
4503 useCreateImage = true;
4504#else
4505 useCreateImage = false;
4506#endif
4507
4508#if CL_HPP_TARGET_OPENCL_VERSION >= 120
4509 if (useCreateImage)
4510 {
4511 cl_image_desc desc =
4512 {
4513 CL_MEM_OBJECT_IMAGE2D,
4514 width,
4515 height,
4516 0, 0, // depth, array size (unused)
4517 row_pitch,
4518 0, 0, 0, 0
4519 };
4520 object_ = ::clCreateImage(
4521 context(),
4522 flags,
4523 &format,
4524 &desc,
4525 host_ptr,
4526 &error);
4527
4528 detail::errHandler(error, __CREATE_IMAGE_ERR);
4529 if (err != NULL) {
4530 *err = error;
4531 }
4532 }
4533#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
4534#if CL_HPP_MINIMUM_OPENCL_VERSION < 120
4535 if (!useCreateImage)
4536 {
4537 object_ = ::clCreateImage2D(
4538 context(), flags,&format, width, height, row_pitch, host_ptr, &error);
4539
4540 detail::errHandler(error, __CREATE_IMAGE2D_ERR);
4541 if (err != NULL) {
4542 *err = error;
4543 }
4544 }
4545#endif // CL_HPP_MINIMUM_OPENCL_VERSION < 120
4546 }
4547
4548#if CL_HPP_TARGET_OPENCL_VERSION >= 200
4549 /*! \brief Constructs a 2D Image from a buffer.
4550 * \note This will share storage with the underlying buffer.
4551 *
4552 * Wraps clCreateImage().
4553 */
4554 Image2D(
4555 const Context& context,
4556 ImageFormat format,
4557 const Buffer &sourceBuffer,
4558 size_type width,
4559 size_type height,
4560 size_type row_pitch = 0,
4561 cl_int* err = nullptr)
4562 {
4563 cl_int error;
4564
4565 cl_image_desc desc =
4566 {
4567 CL_MEM_OBJECT_IMAGE2D,
4568 width,
4569 height,
4570 0, 0, // depth, array size (unused)
4571 row_pitch,
4572 0, 0, 0,
4573 // Use buffer as input to image
4574 sourceBuffer()
4575 };
4576 object_ = ::clCreateImage(
4577 context(),
4578 0, // flags inherited from buffer
4579 &format,
4580 &desc,
4581 nullptr,
4582 &error);
4583
4584 detail::errHandler(error, __CREATE_IMAGE_ERR);
4585 if (err != nullptr) {
4586 *err = error;
4587 }
4588 }
4589#endif //#if CL_HPP_TARGET_OPENCL_VERSION >= 200
4590
4591#if CL_HPP_TARGET_OPENCL_VERSION >= 200
4592 /*! \brief Constructs a 2D Image from an image.
4593 * \note This will share storage with the underlying image but may
4594 * reinterpret the channel order and type.
4595 *
4596 * The image will be created matching with a descriptor matching the source.
4597 *
4598 * \param order is the channel order to reinterpret the image data as.
4599 * The channel order may differ as described in the OpenCL
4600 * 2.0 API specification.
4601 *
4602 * Wraps clCreateImage().
4603 */
4604 Image2D(
4605 const Context& context,
4606 cl_channel_order order,
4607 const Image &sourceImage,
4608 cl_int* err = nullptr)
4609 {
4610 cl_int error;
4611
4612 // Descriptor fields have to match source image
4613 size_type sourceWidth =
4614 sourceImage.getImageInfo<CL_IMAGE_WIDTH>();
4615 size_type sourceHeight =
4616 sourceImage.getImageInfo<CL_IMAGE_HEIGHT>();
4617 size_type sourceRowPitch =
4618 sourceImage.getImageInfo<CL_IMAGE_ROW_PITCH>();
4619 cl_uint sourceNumMIPLevels =
4620 sourceImage.getImageInfo<CL_IMAGE_NUM_MIP_LEVELS>();
4621 cl_uint sourceNumSamples =
4622 sourceImage.getImageInfo<CL_IMAGE_NUM_SAMPLES>();
4623 cl_image_format sourceFormat =
4624 sourceImage.getImageInfo<CL_IMAGE_FORMAT>();
4625
4626 // Update only the channel order.
4627 // Channel format inherited from source.
4628 sourceFormat.image_channel_order = order;
4629 cl_image_desc desc =
4630 {
4631 CL_MEM_OBJECT_IMAGE2D,
4632 sourceWidth,
4633 sourceHeight,
4634 0, 0, // depth (unused), array size (unused)
4635 sourceRowPitch,
4636 0, // slice pitch (unused)
4637 sourceNumMIPLevels,
4638 sourceNumSamples,
4639 // Use buffer as input to image
4640 sourceImage()
4641 };
4642 object_ = ::clCreateImage(
4643 context(),
4644 0, // flags should be inherited from mem_object
4645 &sourceFormat,
4646 &desc,
4647 nullptr,
4648 &error);
4649
4650 detail::errHandler(error, __CREATE_IMAGE_ERR);
4651 if (err != nullptr) {
4652 *err = error;
4653 }
4654 }
4655#endif //#if CL_HPP_TARGET_OPENCL_VERSION >= 200
4656
4657 //! \brief Default constructor - initializes to NULL.
4658 Image2D() { }
4659
4660 /*! \brief Constructor from cl_mem - takes ownership.
4661 *
4662 * \param retainObject will cause the constructor to retain its cl object.
4663 * Defaults to false to maintain compatibility with
4664 * earlier versions.
4665 * See Memory for further details.
4666 */
4667 explicit Image2D(const cl_mem& image2D, bool retainObject = false) :
4668 Image(image2D, retainObject) { }
4669
4670 /*! \brief Assignment from cl_mem - performs shallow copy.
4671 *
4672 * See Memory for further details.
4673 */
4674 Image2D& operator = (const cl_mem& rhs)
4675 {
4676 Image::operator=(rhs);
4677 return *this;
4678 }
4679
4680 /*! \brief Copy constructor to forward copy to the superclass correctly.
4681 * Required for MSVC.
4682 */
4683 Image2D(const Image2D& img) : Image(img) {}
4684
4685 /*! \brief Copy assignment to forward copy to the superclass correctly.
4686 * Required for MSVC.
4687 */
4688 Image2D& operator = (const Image2D &img)
4689 {
4690 Image::operator=(img);
4691 return *this;
4692 }
4693
4694 /*! \brief Move constructor to forward move to the superclass correctly.
4695 * Required for MSVC.
4696 */
4697 Image2D(Image2D&& img) CL_HPP_NOEXCEPT_ : Image(std::move(img)) {}
4698
4699 /*! \brief Move assignment to forward move to the superclass correctly.
4700 * Required for MSVC.
4701 */
4702 Image2D& operator = (Image2D &&img)
4703 {
4704 Image::operator=(std::move(img));
4705 return *this;
4706 }
4707
4708};
4709
4710
4711#if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
4712/*! \brief Class interface for GL 2D Image Memory objects.
4713 *
4714 * This is provided to facilitate interoperability with OpenGL.
4715 *
4716 * See Memory for details about copy semantics, etc.
4717 *
4718 * \see Memory
4719 * \note Deprecated for OpenCL 1.2. Please use ImageGL instead.
4720 */
4721class CL_EXT_PREFIX__VERSION_1_1_DEPRECATED Image2DGL : public Image2D
4722{
4723public:
4724 /*! \brief Constructs an Image2DGL in a specified context, from a given
4725 * GL Texture.
4726 *
4727 * Wraps clCreateFromGLTexture2D().
4728 */
4729 Image2DGL(
4730 const Context& context,
4731 cl_mem_flags flags,
4732 cl_GLenum target,
4733 cl_GLint miplevel,
4734 cl_GLuint texobj,
4735 cl_int * err = NULL)
4736 {
4737 cl_int error;
4738 object_ = ::clCreateFromGLTexture2D(
4739 context(),
4740 flags,
4741 target,
4742 miplevel,
4743 texobj,
4744 &error);
4745
4746 detail::errHandler(error, __CREATE_GL_TEXTURE_2D_ERR);
4747 if (err != NULL) {
4748 *err = error;
4749 }
4750
4751 }
4752
4753 //! \brief Default constructor - initializes to NULL.
4754 Image2DGL() : Image2D() { }
4755
4756 /*! \brief Constructor from cl_mem - takes ownership.
4757 *
4758 * \param retainObject will cause the constructor to retain its cl object.
4759 * Defaults to false to maintain compatibility with
4760 * earlier versions.
4761 * See Memory for further details.
4762 */
4763 explicit Image2DGL(const cl_mem& image, bool retainObject = false) :
4764 Image2D(image, retainObject) { }
4765
4766 /*! \brief Assignment from cl_mem - performs shallow copy.
4767 *c
4768 * See Memory for further details.
4769 */
4770 Image2DGL& operator = (const cl_mem& rhs)
4771 {
4772 Image2D::operator=(rhs);
4773 return *this;
4774 }
4775
4776 /*! \brief Copy constructor to forward copy to the superclass correctly.
4777 * Required for MSVC.
4778 */
4779 Image2DGL(const Image2DGL& img) : Image2D(img) {}
4780
4781 /*! \brief Copy assignment to forward copy to the superclass correctly.
4782 * Required for MSVC.
4783 */
4784 Image2DGL& operator = (const Image2DGL &img)
4785 {
4786 Image2D::operator=(img);
4787 return *this;
4788 }
4789
4790 /*! \brief Move constructor to forward move to the superclass correctly.
4791 * Required for MSVC.
4792 */
4793 Image2DGL(Image2DGL&& img) CL_HPP_NOEXCEPT_ : Image2D(std::move(img)) {}
4794
4795 /*! \brief Move assignment to forward move to the superclass correctly.
4796 * Required for MSVC.
4797 */
4798 Image2DGL& operator = (Image2DGL &&img)
4799 {
4800 Image2D::operator=(std::move(img));
4801 return *this;
4802 }
4803
4804} CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED;
4805#endif // CL_USE_DEPRECATED_OPENCL_1_1_APIS
4806
4807#if CL_HPP_TARGET_OPENCL_VERSION >= 120
4808/*! \class Image2DArray
4809 * \brief Image interface for arrays of 2D images.
4810 */
4811class Image2DArray : public Image
4812{
4813public:
4814 Image2DArray(
4815 const Context& context,
4816 cl_mem_flags flags,
4817 ImageFormat format,
4818 size_type arraySize,
4819 size_type width,
4820 size_type height,
4821 size_type rowPitch,
4822 size_type slicePitch,
4823 void* host_ptr = NULL,
4824 cl_int* err = NULL)
4825 {
4826 cl_int error;
4827 cl_image_desc desc =
4828 {
4829 CL_MEM_OBJECT_IMAGE2D_ARRAY,
4830 width,
4831 height,
4832 0, // depth (unused)
4833 arraySize,
4834 rowPitch,
4835 slicePitch,
4836 0, 0, 0
4837 };
4838 object_ = ::clCreateImage(
4839 context(),
4840 flags,
4841 &format,
4842 &desc,
4843 host_ptr,
4844 &error);
4845
4846 detail::errHandler(error, __CREATE_IMAGE_ERR);
4847 if (err != NULL) {
4848 *err = error;
4849 }
4850 }
4851
4852 Image2DArray() { }
4853
4854 /*! \brief Constructor from cl_mem - takes ownership.
4855 *
4856 * \param retainObject will cause the constructor to retain its cl object.
4857 * Defaults to false to maintain compatibility with
4858 * earlier versions.
4859 * See Memory for further details.
4860 */
4861 explicit Image2DArray(const cl_mem& imageArray, bool retainObject = false) : Image(imageArray, retainObject) { }
4862
4863 Image2DArray& operator = (const cl_mem& rhs)
4864 {
4865 Image::operator=(rhs);
4866 return *this;
4867 }
4868
4869 /*! \brief Copy constructor to forward copy to the superclass correctly.
4870 * Required for MSVC.
4871 */
4872 Image2DArray(const Image2DArray& img) : Image(img) {}
4873
4874 /*! \brief Copy assignment to forward copy to the superclass correctly.
4875 * Required for MSVC.
4876 */
4877 Image2DArray& operator = (const Image2DArray &img)
4878 {
4879 Image::operator=(img);
4880 return *this;
4881 }
4882
4883 /*! \brief Move constructor to forward move to the superclass correctly.
4884 * Required for MSVC.
4885 */
4886 Image2DArray(Image2DArray&& img) CL_HPP_NOEXCEPT_ : Image(std::move(img)) {}
4887
4888 /*! \brief Move assignment to forward move to the superclass correctly.
4889 * Required for MSVC.
4890 */
4891 Image2DArray& operator = (Image2DArray &&img)
4892 {
4893 Image::operator=(std::move(img));
4894 return *this;
4895 }
4896};
4897#endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 120
4898
4899/*! \brief Class interface for 3D Image Memory objects.
4900 *
4901 * See Memory for details about copy semantics, etc.
4902 *
4903 * \see Memory
4904 */
4905class Image3D : public Image
4906{
4907public:
4908 /*! \brief Constructs a 3D Image in a specified context.
4909 *
4910 * Wraps clCreateImage().
4911 */
4912 Image3D(
4913 const Context& context,
4914 cl_mem_flags flags,
4915 ImageFormat format,
4916 size_type width,
4917 size_type height,
4918 size_type depth,
4919 size_type row_pitch = 0,
4920 size_type slice_pitch = 0,
4921 void* host_ptr = NULL,
4922 cl_int* err = NULL)
4923 {
4924 cl_int error;
4925 bool useCreateImage;
4926
4927#if CL_HPP_TARGET_OPENCL_VERSION >= 120 && CL_HPP_MINIMUM_OPENCL_VERSION < 120
4928 // Run-time decision based on the actual platform
4929 {
4930 cl_uint version = detail::getContextPlatformVersion(context());
4931 useCreateImage = (version >= 0x10002); // OpenCL 1.2 or above
4932 }
4933#elif CL_HPP_TARGET_OPENCL_VERSION >= 120
4934 useCreateImage = true;
4935#else
4936 useCreateImage = false;
4937#endif
4938
4939#if CL_HPP_TARGET_OPENCL_VERSION >= 120
4940 if (useCreateImage)
4941 {
4942 cl_image_desc desc =
4943 {
4944 CL_MEM_OBJECT_IMAGE3D,
4945 width,
4946 height,
4947 depth,
4948 0, // array size (unused)
4949 row_pitch,
4950 slice_pitch,
4951 0, 0, 0
4952 };
4953 object_ = ::clCreateImage(
4954 context(),
4955 flags,
4956 &format,
4957 &desc,
4958 host_ptr,
4959 &error);
4960
4961 detail::errHandler(error, __CREATE_IMAGE_ERR);
4962 if (err != NULL) {
4963 *err = error;
4964 }
4965 }
4966#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
4967#if CL_HPP_MINIMUM_OPENCL_VERSION < 120
4968 if (!useCreateImage)
4969 {
4970 object_ = ::clCreateImage3D(
4971 context(), flags, &format, width, height, depth, row_pitch,
4972 slice_pitch, host_ptr, &error);
4973
4974 detail::errHandler(error, __CREATE_IMAGE3D_ERR);
4975 if (err != NULL) {
4976 *err = error;
4977 }
4978 }
4979#endif // CL_HPP_MINIMUM_OPENCL_VERSION < 120
4980 }
4981
4982 //! \brief Default constructor - initializes to NULL.
4983 Image3D() : Image() { }
4984
4985 /*! \brief Constructor from cl_mem - takes ownership.
4986 *
4987 * \param retainObject will cause the constructor to retain its cl object.
4988 * Defaults to false to maintain compatibility with
4989 * earlier versions.
4990 * See Memory for further details.
4991 */
4992 explicit Image3D(const cl_mem& image3D, bool retainObject = false) :
4993 Image(image3D, retainObject) { }
4994
4995 /*! \brief Assignment from cl_mem - performs shallow copy.
4996 *
4997 * See Memory for further details.
4998 */
4999 Image3D& operator = (const cl_mem& rhs)
5000 {
5001 Image::operator=(rhs);
5002 return *this;
5003 }
5004
5005 /*! \brief Copy constructor to forward copy to the superclass correctly.
5006 * Required for MSVC.
5007 */
5008 Image3D(const Image3D& img) : Image(img) {}
5009
5010 /*! \brief Copy assignment to forward copy to the superclass correctly.
5011 * Required for MSVC.
5012 */
5013 Image3D& operator = (const Image3D &img)
5014 {
5015 Image::operator=(img);
5016 return *this;
5017 }
5018
5019 /*! \brief Move constructor to forward move to the superclass correctly.
5020 * Required for MSVC.
5021 */
5022 Image3D(Image3D&& img) CL_HPP_NOEXCEPT_ : Image(std::move(img)) {}
5023
5024 /*! \brief Move assignment to forward move to the superclass correctly.
5025 * Required for MSVC.
5026 */
5027 Image3D& operator = (Image3D &&img)
5028 {
5029 Image::operator=(std::move(img));
5030 return *this;
5031 }
5032};
5033
5034#if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
5035/*! \brief Class interface for GL 3D Image Memory objects.
5036 *
5037 * This is provided to facilitate interoperability with OpenGL.
5038 *
5039 * See Memory for details about copy semantics, etc.
5040 *
5041 * \see Memory
5042 */
5043class Image3DGL : public Image3D
5044{
5045public:
5046 /*! \brief Constructs an Image3DGL in a specified context, from a given
5047 * GL Texture.
5048 *
5049 * Wraps clCreateFromGLTexture3D().
5050 */
5051 Image3DGL(
5052 const Context& context,
5053 cl_mem_flags flags,
5054 cl_GLenum target,
5055 cl_GLint miplevel,
5056 cl_GLuint texobj,
5057 cl_int * err = NULL)
5058 {
5059 cl_int error;
5060 object_ = ::clCreateFromGLTexture3D(
5061 context(),
5062 flags,
5063 target,
5064 miplevel,
5065 texobj,
5066 &error);
5067
5068 detail::errHandler(error, __CREATE_GL_TEXTURE_3D_ERR);
5069 if (err != NULL) {
5070 *err = error;
5071 }
5072 }
5073
5074 //! \brief Default constructor - initializes to NULL.
5075 Image3DGL() : Image3D() { }
5076
5077 /*! \brief Constructor from cl_mem - takes ownership.
5078 *
5079 * \param retainObject will cause the constructor to retain its cl object.
5080 * Defaults to false to maintain compatibility with
5081 * earlier versions.
5082 * See Memory for further details.
5083 */
5084 explicit Image3DGL(const cl_mem& image, bool retainObject = false) :
5085 Image3D(image, retainObject) { }
5086
5087 /*! \brief Assignment from cl_mem - performs shallow copy.
5088 *
5089 * See Memory for further details.
5090 */
5091 Image3DGL& operator = (const cl_mem& rhs)
5092 {
5093 Image3D::operator=(rhs);
5094 return *this;
5095 }
5096
5097 /*! \brief Copy constructor to forward copy to the superclass correctly.
5098 * Required for MSVC.
5099 */
5100 Image3DGL(const Image3DGL& img) : Image3D(img) {}
5101
5102 /*! \brief Copy assignment to forward copy to the superclass correctly.
5103 * Required for MSVC.
5104 */
5105 Image3DGL& operator = (const Image3DGL &img)
5106 {
5107 Image3D::operator=(img);
5108 return *this;
5109 }
5110
5111 /*! \brief Move constructor to forward move to the superclass correctly.
5112 * Required for MSVC.
5113 */
5114 Image3DGL(Image3DGL&& img) CL_HPP_NOEXCEPT_ : Image3D(std::move(img)) {}
5115
5116 /*! \brief Move assignment to forward move to the superclass correctly.
5117 * Required for MSVC.
5118 */
5119 Image3DGL& operator = (Image3DGL &&img)
5120 {
5121 Image3D::operator=(std::move(img));
5122 return *this;
5123 }
5124};
5125#endif // CL_USE_DEPRECATED_OPENCL_1_1_APIS
5126
5127#if CL_HPP_TARGET_OPENCL_VERSION >= 120
5128/*! \class ImageGL
5129 * \brief general image interface for GL interop.
5130 * We abstract the 2D and 3D GL images into a single instance here
5131 * that wraps all GL sourced images on the grounds that setup information
5132 * was performed by OpenCL anyway.
5133 */
5134class ImageGL : public Image
5135{
5136public:
5137 ImageGL(
5138 const Context& context,
5139 cl_mem_flags flags,
5140 cl_GLenum target,
5141 cl_GLint miplevel,
5142 cl_GLuint texobj,
5143 cl_int * err = NULL)
5144 {
5145 cl_int error;
5146 object_ = ::clCreateFromGLTexture(
5147 context(),
5148 flags,
5149 target,
5150 miplevel,
5151 texobj,
5152 &error);
5153
5154 detail::errHandler(error, __CREATE_GL_TEXTURE_ERR);
5155 if (err != NULL) {
5156 *err = error;
5157 }
5158 }
5159
5160 ImageGL() : Image() { }
5161
5162 /*! \brief Constructor from cl_mem - takes ownership.
5163 *
5164 * \param retainObject will cause the constructor to retain its cl object.
5165 * Defaults to false to maintain compatibility with
5166 * earlier versions.
5167 * See Memory for further details.
5168 */
5169 explicit ImageGL(const cl_mem& image, bool retainObject = false) :
5170 Image(image, retainObject) { }
5171
5172 ImageGL& operator = (const cl_mem& rhs)
5173 {
5174 Image::operator=(rhs);
5175 return *this;
5176 }
5177
5178 /*! \brief Copy constructor to forward copy to the superclass correctly.
5179 * Required for MSVC.
5180 */
5181 ImageGL(const ImageGL& img) : Image(img) {}
5182
5183 /*! \brief Copy assignment to forward copy to the superclass correctly.
5184 * Required for MSVC.
5185 */
5186 ImageGL& operator = (const ImageGL &img)
5187 {
5188 Image::operator=(img);
5189 return *this;
5190 }
5191
5192 /*! \brief Move constructor to forward move to the superclass correctly.
5193 * Required for MSVC.
5194 */
5195 ImageGL(ImageGL&& img) CL_HPP_NOEXCEPT_ : Image(std::move(img)) {}
5196
5197 /*! \brief Move assignment to forward move to the superclass correctly.
5198 * Required for MSVC.
5199 */
5200 ImageGL& operator = (ImageGL &&img)
5201 {
5202 Image::operator=(std::move(img));
5203 return *this;
5204 }
5205};
5206#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
5207
5208
5209
5210#if CL_HPP_TARGET_OPENCL_VERSION >= 200
5211/*! \brief Class interface for Pipe Memory Objects.
5212*
5213* See Memory for details about copy semantics, etc.
5214*
5215* \see Memory
5216*/
5217class Pipe : public Memory
5218{
5219public:
5220
5221 /*! \brief Constructs a Pipe in a specified context.
5222 *
5223 * Wraps clCreatePipe().
5224 * @param context Context in which to create the pipe.
5225 * @param flags Bitfield. Only CL_MEM_READ_WRITE and CL_MEM_HOST_NO_ACCESS are valid.
5226 * @param packet_size Size in bytes of a single packet of the pipe.
5227 * @param max_packets Number of packets that may be stored in the pipe.
5228 *
5229 */
5230 Pipe(
5231 const Context& context,
5232 cl_uint packet_size,
5233 cl_uint max_packets,
5234 cl_int* err = NULL)
5235 {
5236 cl_int error;
5237
5238 cl_mem_flags flags = CL_MEM_READ_WRITE | CL_MEM_HOST_NO_ACCESS;
5239 object_ = ::clCreatePipe(context(), flags, packet_size, max_packets, nullptr, &error);
5240
5241 detail::errHandler(error, __CREATE_PIPE_ERR);
5242 if (err != NULL) {
5243 *err = error;
5244 }
5245 }
5246
5247 /*! \brief Constructs a Pipe in a the default context.
5248 *
5249 * Wraps clCreatePipe().
5250 * @param flags Bitfield. Only CL_MEM_READ_WRITE and CL_MEM_HOST_NO_ACCESS are valid.
5251 * @param packet_size Size in bytes of a single packet of the pipe.
5252 * @param max_packets Number of packets that may be stored in the pipe.
5253 *
5254 */
5255 Pipe(
5256 cl_uint packet_size,
5257 cl_uint max_packets,
5258 cl_int* err = NULL)
5259 {
5260 cl_int error;
5261
5262 Context context = Context::getDefault(err);
5263
5264 cl_mem_flags flags = CL_MEM_READ_WRITE | CL_MEM_HOST_NO_ACCESS;
5265 object_ = ::clCreatePipe(context(), flags, packet_size, max_packets, nullptr, &error);
5266
5267 detail::errHandler(error, __CREATE_PIPE_ERR);
5268 if (err != NULL) {
5269 *err = error;
5270 }
5271 }
5272
5273 //! \brief Default constructor - initializes to NULL.
5274 Pipe() : Memory() { }
5275
5276 /*! \brief Constructor from cl_mem - takes ownership.
5277 *
5278 * \param retainObject will cause the constructor to retain its cl object.
5279 * Defaults to false to maintain compatibility with earlier versions.
5280 *
5281 * See Memory for further details.
5282 */
5283 explicit Pipe(const cl_mem& pipe, bool retainObject = false) :
5284 Memory(pipe, retainObject) { }
5285
5286 /*! \brief Assignment from cl_mem - performs shallow copy.
5287 *
5288 * See Memory for further details.
5289 */
5290 Pipe& operator = (const cl_mem& rhs)
5291 {
5292 Memory::operator=(rhs);
5293 return *this;
5294 }
5295
5296 /*! \brief Copy constructor to forward copy to the superclass correctly.
5297 * Required for MSVC.
5298 */
5299 Pipe(const Pipe& pipe) : Memory(pipe) {}
5300
5301 /*! \brief Copy assignment to forward copy to the superclass correctly.
5302 * Required for MSVC.
5303 */
5304 Pipe& operator = (const Pipe &pipe)
5305 {
5306 Memory::operator=(pipe);
5307 return *this;
5308 }
5309
5310 /*! \brief Move constructor to forward move to the superclass correctly.
5311 * Required for MSVC.
5312 */
5313 Pipe(Pipe&& pipe) CL_HPP_NOEXCEPT_ : Memory(std::move(pipe)) {}
5314
5315 /*! \brief Move assignment to forward move to the superclass correctly.
5316 * Required for MSVC.
5317 */
5318 Pipe& operator = (Pipe &&pipe)
5319 {
5320 Memory::operator=(std::move(pipe));
5321 return *this;
5322 }
5323
5324 //! \brief Wrapper for clGetMemObjectInfo().
5325 template <typename T>
5326 cl_int getInfo(cl_pipe_info name, T* param) const
5327 {
5328 return detail::errHandler(
5329 detail::getInfo(&::clGetPipeInfo, object_, name, param),
5330 __GET_PIPE_INFO_ERR);
5331 }
5332
5333 //! \brief Wrapper for clGetMemObjectInfo() that returns by value.
5334 template <cl_int name> typename
5335 detail::param_traits<detail::cl_pipe_info, name>::param_type
5336 getInfo(cl_int* err = NULL) const
5337 {
5338 typename detail::param_traits<
5339 detail::cl_pipe_info, name>::param_type param;
5340 cl_int result = getInfo(name, &param);
5341 if (err != NULL) {
5342 *err = result;
5343 }
5344 return param;
5345 }
5346}; // class Pipe
5347#endif // CL_HPP_TARGET_OPENCL_VERSION >= 200
5348
5349
5350/*! \brief Class interface for cl_sampler.
5351 *
5352 * \note Copies of these objects are shallow, meaning that the copy will refer
5353 * to the same underlying cl_sampler as the original. For details, see
5354 * clRetainSampler() and clReleaseSampler().
5355 *
5356 * \see cl_sampler
5357 */
5358class Sampler : public detail::Wrapper<cl_sampler>
5359{
5360public:
5361 //! \brief Default constructor - initializes to NULL.
5362 Sampler() { }
5363
5364 /*! \brief Constructs a Sampler in a specified context.
5365 *
5366 * Wraps clCreateSampler().
5367 */
5368 Sampler(
5369 const Context& context,
5370 cl_bool normalized_coords,
5371 cl_addressing_mode addressing_mode,
5372 cl_filter_mode filter_mode,
5373 cl_int* err = NULL)
5374 {
5375 cl_int error;
5376
5377#if CL_HPP_TARGET_OPENCL_VERSION >= 200
5378 cl_sampler_properties sampler_properties[] = {
5379 CL_SAMPLER_NORMALIZED_COORDS, normalized_coords,
5380 CL_SAMPLER_ADDRESSING_MODE, addressing_mode,
5381 CL_SAMPLER_FILTER_MODE, filter_mode,
5382 0 };
5383 object_ = ::clCreateSamplerWithProperties(
5384 context(),
5385 sampler_properties,
5386 &error);
5387
5388 detail::errHandler(error, __CREATE_SAMPLER_WITH_PROPERTIES_ERR);
5389 if (err != NULL) {
5390 *err = error;
5391 }
5392#else
5393 object_ = ::clCreateSampler(
5394 context(),
5395 normalized_coords,
5396 addressing_mode,
5397 filter_mode,
5398 &error);
5399
5400 detail::errHandler(error, __CREATE_SAMPLER_ERR);
5401 if (err != NULL) {
5402 *err = error;
5403 }
5404#endif
5405 }
5406
5407 /*! \brief Constructor from cl_sampler - takes ownership.
5408 *
5409 * \param retainObject will cause the constructor to retain its cl object.
5410 * Defaults to false to maintain compatibility with
5411 * earlier versions.
5412 * This effectively transfers ownership of a refcount on the cl_sampler
5413 * into the new Sampler object.
5414 */
5415 explicit Sampler(const cl_sampler& sampler, bool retainObject = false) :
5416 detail::Wrapper<cl_type>(sampler, retainObject) { }
5417
5418 /*! \brief Assignment operator from cl_sampler - takes ownership.
5419 *
5420 * This effectively transfers ownership of a refcount on the rhs and calls
5421 * clReleaseSampler() on the value previously held by this instance.
5422 */
5423 Sampler& operator = (const cl_sampler& rhs)
5424 {
5425 detail::Wrapper<cl_type>::operator=(rhs);
5426 return *this;
5427 }
5428
5429 /*! \brief Copy constructor to forward copy to the superclass correctly.
5430 * Required for MSVC.
5431 */
5432 Sampler(const Sampler& sam) : detail::Wrapper<cl_type>(sam) {}
5433
5434 /*! \brief Copy assignment to forward copy to the superclass correctly.
5435 * Required for MSVC.
5436 */
5437 Sampler& operator = (const Sampler &sam)
5438 {
5439 detail::Wrapper<cl_type>::operator=(sam);
5440 return *this;
5441 }
5442
5443 /*! \brief Move constructor to forward move to the superclass correctly.
5444 * Required for MSVC.
5445 */
5446 Sampler(Sampler&& sam) CL_HPP_NOEXCEPT_ : detail::Wrapper<cl_type>(std::move(sam)) {}
5447
5448 /*! \brief Move assignment to forward move to the superclass correctly.
5449 * Required for MSVC.
5450 */
5451 Sampler& operator = (Sampler &&sam)
5452 {
5453 detail::Wrapper<cl_type>::operator=(std::move(sam));
5454 return *this;
5455 }
5456
5457 //! \brief Wrapper for clGetSamplerInfo().
5458 template <typename T>
5459 cl_int getInfo(cl_sampler_info name, T* param) const
5460 {
5461 return detail::errHandler(
5462 detail::getInfo(&::clGetSamplerInfo, object_, name, param),
5463 __GET_SAMPLER_INFO_ERR);
5464 }
5465
5466 //! \brief Wrapper for clGetSamplerInfo() that returns by value.
5467 template <cl_int name> typename
5468 detail::param_traits<detail::cl_sampler_info, name>::param_type
5469 getInfo(cl_int* err = NULL) const
5470 {
5471 typename detail::param_traits<
5472 detail::cl_sampler_info, name>::param_type param;
5473 cl_int result = getInfo(name, &param);
5474 if (err != NULL) {
5475 *err = result;
5476 }
5477 return param;
5478 }
5479};
5480
5481class Program;
5482class CommandQueue;
5483class DeviceCommandQueue;
5484class Kernel;
5485
5486//! \brief Class interface for specifying NDRange values.
5487class NDRange
5488{
5489private:
5490 size_type sizes_[3];
5491 cl_uint dimensions_;
5492
5493public:
5494 //! \brief Default constructor - resulting range has zero dimensions.
5495 NDRange()
5496 : dimensions_(0)
5497 {
5498 sizes_[0] = 0;
5499 sizes_[1] = 0;
5500 sizes_[2] = 0;
5501 }
5502
5503 //! \brief Constructs one-dimensional range.
5504 NDRange(size_type size0)
5505 : dimensions_(1)
5506 {
5507 sizes_[0] = size0;
5508 sizes_[1] = 1;
5509 sizes_[2] = 1;
5510 }
5511
5512 //! \brief Constructs two-dimensional range.
5513 NDRange(size_type size0, size_type size1)
5514 : dimensions_(2)
5515 {
5516 sizes_[0] = size0;
5517 sizes_[1] = size1;
5518 sizes_[2] = 1;
5519 }
5520
5521 //! \brief Constructs three-dimensional range.
5522 NDRange(size_type size0, size_type size1, size_type size2)
5523 : dimensions_(3)
5524 {
5525 sizes_[0] = size0;
5526 sizes_[1] = size1;
5527 sizes_[2] = size2;
5528 }
5529
5530 /*! \brief Conversion operator to const size_type *.
5531 *
5532 * \returns a pointer to the size of the first dimension.
5533 */
5534 operator const size_type*() const {
5535 return sizes_;
5536 }
5537
5538 //! \brief Queries the number of dimensions in the range.
5539 size_type dimensions() const
5540 {
5541 return dimensions_;
5542 }
5543
5544 //! \brief Returns the size of the object in bytes based on the
5545 // runtime number of dimensions
5546 size_type size() const
5547 {
5548 return dimensions_*sizeof(size_type);
5549 }
5550
5551 size_type* get()
5552 {
5553 return sizes_;
5554 }
5555
5556 const size_type* get() const
5557 {
5558 return sizes_;
5559 }
5560};
5561
5562//! \brief A zero-dimensional range.
5563static const NDRange NullRange;
5564
5565//! \brief Local address wrapper for use with Kernel::setArg
5566struct LocalSpaceArg
5567{
5568 size_type size_;
5569};
5570
5571namespace detail {
5572
5573template <typename T, class Enable = void>
5574struct KernelArgumentHandler;
5575
5576// Enable for objects that are not subclasses of memory
5577// Pointers, constants etc
5578template <typename T>
5579struct KernelArgumentHandler<T, typename std::enable_if<!std::is_base_of<cl::Memory, T>::value>::type>
5580{
5581 static size_type size(const T&) { return sizeof(T); }
5582 static const T* ptr(const T& value) { return &value; }
5583};
5584
5585// Enable for subclasses of memory where we want to get a reference to the cl_mem out
5586// and pass that in for safety
5587template <typename T>
5588struct KernelArgumentHandler<T, typename std::enable_if<std::is_base_of<cl::Memory, T>::value>::type>
5589{
5590 static size_type size(const T&) { return sizeof(cl_mem); }
5591 static const cl_mem* ptr(const T& value) { return &(value()); }
5592};
5593
5594// Specialization for DeviceCommandQueue defined later
5595
5596template <>
5597struct KernelArgumentHandler<LocalSpaceArg, void>
5598{
5599 static size_type size(const LocalSpaceArg& value) { return value.size_; }
5600 static const void* ptr(const LocalSpaceArg&) { return NULL; }
5601};
5602
5603}
5604//! \endcond
5605
5606/*! Local
5607 * \brief Helper function for generating LocalSpaceArg objects.
5608 */
5609inline LocalSpaceArg
5610Local(size_type size)
5611{
5612 LocalSpaceArg ret = { size };
5613 return ret;
5614}
5615
5616/*! \brief Class interface for cl_kernel.
5617 *
5618 * \note Copies of these objects are shallow, meaning that the copy will refer
5619 * to the same underlying cl_kernel as the original. For details, see
5620 * clRetainKernel() and clReleaseKernel().
5621 *
5622 * \see cl_kernel
5623 */
5624class Kernel : public detail::Wrapper<cl_kernel>
5625{
5626public:
5627 inline Kernel(const Program& program, const char* name, cl_int* err = NULL);
5628
5629 //! \brief Default constructor - initializes to NULL.
5630 Kernel() { }
5631
5632 /*! \brief Constructor from cl_kernel - takes ownership.
5633 *
5634 * \param retainObject will cause the constructor to retain its cl object.
5635 * Defaults to false to maintain compatibility with
5636 * earlier versions.
5637 * This effectively transfers ownership of a refcount on the cl_kernel
5638 * into the new Kernel object.
5639 */
5640 explicit Kernel(const cl_kernel& kernel, bool retainObject = false) :
5641 detail::Wrapper<cl_type>(kernel, retainObject) { }
5642
5643 /*! \brief Assignment operator from cl_kernel - takes ownership.
5644 *
5645 * This effectively transfers ownership of a refcount on the rhs and calls
5646 * clReleaseKernel() on the value previously held by this instance.
5647 */
5648 Kernel& operator = (const cl_kernel& rhs)
5649 {
5650 detail::Wrapper<cl_type>::operator=(rhs);
5651 return *this;
5652 }
5653
5654 /*! \brief Copy constructor to forward copy to the superclass correctly.
5655 * Required for MSVC.
5656 */
5657 Kernel(const Kernel& kernel) : detail::Wrapper<cl_type>(kernel) {}
5658
5659 /*! \brief Copy assignment to forward copy to the superclass correctly.
5660 * Required for MSVC.
5661 */
5662 Kernel& operator = (const Kernel &kernel)
5663 {
5664 detail::Wrapper<cl_type>::operator=(kernel);
5665 return *this;
5666 }
5667
5668 /*! \brief Move constructor to forward move to the superclass correctly.
5669 * Required for MSVC.
5670 */
5671 Kernel(Kernel&& kernel) CL_HPP_NOEXCEPT_ : detail::Wrapper<cl_type>(std::move(kernel)) {}
5672
5673 /*! \brief Move assignment to forward move to the superclass correctly.
5674 * Required for MSVC.
5675 */
5676 Kernel& operator = (Kernel &&kernel)
5677 {
5678 detail::Wrapper<cl_type>::operator=(std::move(kernel));
5679 return *this;
5680 }
5681
5682 template <typename T>
5683 cl_int getInfo(cl_kernel_info name, T* param) const
5684 {
5685 return detail::errHandler(
5686 detail::getInfo(&::clGetKernelInfo, object_, name, param),
5687 __GET_KERNEL_INFO_ERR);
5688 }
5689
5690 template <cl_int name> typename
5691 detail::param_traits<detail::cl_kernel_info, name>::param_type
5692 getInfo(cl_int* err = NULL) const
5693 {
5694 typename detail::param_traits<
5695 detail::cl_kernel_info, name>::param_type param;
5696 cl_int result = getInfo(name, &param);
5697 if (err != NULL) {
5698 *err = result;
5699 }
5700 return param;
5701 }
5702
5703#if CL_HPP_TARGET_OPENCL_VERSION >= 120
5704 template <typename T>
5705 cl_int getArgInfo(cl_uint argIndex, cl_kernel_arg_info name, T* param) const
5706 {
5707 return detail::errHandler(
5708 detail::getInfo(&::clGetKernelArgInfo, object_, argIndex, name, param),
5709 __GET_KERNEL_ARG_INFO_ERR);
5710 }
5711
5712 template <cl_int name> typename
5713 detail::param_traits<detail::cl_kernel_arg_info, name>::param_type
5714 getArgInfo(cl_uint argIndex, cl_int* err = NULL) const
5715 {
5716 typename detail::param_traits<
5717 detail::cl_kernel_arg_info, name>::param_type param;
5718 cl_int result = getArgInfo(argIndex, name, &param);
5719 if (err != NULL) {
5720 *err = result;
5721 }
5722 return param;
5723 }
5724#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
5725
5726 template <typename T>
5727 cl_int getWorkGroupInfo(
5728 const Device& device, cl_kernel_work_group_info name, T* param) const
5729 {
5730 return detail::errHandler(
5731 detail::getInfo(
5732 &::clGetKernelWorkGroupInfo, object_, device(), name, param),
5733 __GET_KERNEL_WORK_GROUP_INFO_ERR);
5734 }
5735
5736 template <cl_int name> typename
5737 detail::param_traits<detail::cl_kernel_work_group_info, name>::param_type
5738 getWorkGroupInfo(const Device& device, cl_int* err = NULL) const
5739 {
5740 typename detail::param_traits<
5741 detail::cl_kernel_work_group_info, name>::param_type param;
5742 cl_int result = getWorkGroupInfo(device, name, &param);
5743 if (err != NULL) {
5744 *err = result;
5745 }
5746 return param;
5747 }
5748
5749#if CL_HPP_TARGET_OPENCL_VERSION >= 200
5750#if defined(CL_HPP_USE_CL_SUB_GROUPS_KHR)
5751 cl_int getSubGroupInfo(const cl::Device &dev, cl_kernel_sub_group_info name, const cl::NDRange &range, size_type* param) const
5752 {
5753 typedef clGetKernelSubGroupInfoKHR_fn PFN_clGetKernelSubGroupInfoKHR;
5754 static PFN_clGetKernelSubGroupInfoKHR pfn_clGetKernelSubGroupInfoKHR = NULL;
5755 CL_HPP_INIT_CL_EXT_FCN_PTR_(clGetKernelSubGroupInfoKHR);
5756
5757 return detail::errHandler(
5758 pfn_clGetKernelSubGroupInfoKHR(object_, dev(), name, range.size(), range.get(), sizeof(size_type), param, nullptr),
5759 __GET_KERNEL_ARG_INFO_ERR);
5760 }
5761
5762 template <cl_int name>
5763 size_type getSubGroupInfo(const cl::Device &dev, const cl::NDRange &range, cl_int* err = NULL) const
5764 {
5765 size_type param;
5766 cl_int result = getSubGroupInfo(dev, name, range, &param);
5767 if (err != NULL) {
5768 *err = result;
5769 }
5770 return param;
5771 }
5772#endif // #if defined(CL_HPP_USE_CL_SUB_GROUPS_KHR)
5773#endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 200
5774
5775#if CL_HPP_TARGET_OPENCL_VERSION >= 200
5776 /*! \brief setArg overload taking a shared_ptr type
5777 */
5778 template<typename T, class D>
5779 cl_int setArg(cl_uint index, const cl::pointer<T, D> &argPtr)
5780 {
5781 return detail::errHandler(
5782 ::clSetKernelArgSVMPointer(object_, index, argPtr.get()),
5783 __SET_KERNEL_ARGS_ERR);
5784 }
5785
5786 /*! \brief setArg overload taking a vector type.
5787 */
5788 template<typename T, class Alloc>
5789 cl_int setArg(cl_uint index, const cl::vector<T, Alloc> &argPtr)
5790 {
5791 return detail::errHandler(
5792 ::clSetKernelArgSVMPointer(object_, index, argPtr.data()),
5793 __SET_KERNEL_ARGS_ERR);
5794 }
5795
5796 /*! \brief setArg overload taking a pointer type
5797 */
5798 template<typename T>
5799 typename std::enable_if<std::is_pointer<T>::value, cl_int>::type
5800 setArg(cl_uint index, const T argPtr)
5801 {
5802 return detail::errHandler(
5803 ::clSetKernelArgSVMPointer(object_, index, argPtr),
5804 __SET_KERNEL_ARGS_ERR);
5805 }
5806#endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 200
5807
5808 /*! \brief setArg overload taking a POD type
5809 */
5810 template <typename T>
5811 typename std::enable_if<!std::is_pointer<T>::value, cl_int>::type
5812 setArg(cl_uint index, const T &value)
5813 {
5814 return detail::errHandler(
5815 ::clSetKernelArg(
5816 object_,
5817 index,
5818 detail::KernelArgumentHandler<T>::size(value),
5819 detail::KernelArgumentHandler<T>::ptr(value)),
5820 __SET_KERNEL_ARGS_ERR);
5821 }
5822
5823 cl_int setArg(cl_uint index, size_type size, const void* argPtr)
5824 {
5825 return detail::errHandler(
5826 ::clSetKernelArg(object_, index, size, argPtr),
5827 __SET_KERNEL_ARGS_ERR);
5828 }
5829
5830#if CL_HPP_TARGET_OPENCL_VERSION >= 200
5831 /*!
5832 * Specify a vector of SVM pointers that the kernel may access in
5833 * addition to its arguments.
5834 */
5835 cl_int setSVMPointers(const vector<void*> &pointerList)
5836 {
5837 return detail::errHandler(
5838 ::clSetKernelExecInfo(
5839 object_,
5840 CL_KERNEL_EXEC_INFO_SVM_PTRS,
5841 sizeof(void*)*pointerList.size(),
5842 pointerList.data()));
5843 }
5844
5845 /*!
5846 * Specify a std::array of SVM pointers that the kernel may access in
5847 * addition to its arguments.
5848 */
5849 template<int ArrayLength>
5850 cl_int setSVMPointers(const std::array<void*, ArrayLength> &pointerList)
5851 {
5852 return detail::errHandler(
5853 ::clSetKernelExecInfo(
5854 object_,
5855 CL_KERNEL_EXEC_INFO_SVM_PTRS,
5856 sizeof(void*)*pointerList.size(),
5857 pointerList.data()));
5858 }
5859
5860 /*! \brief Enable fine-grained system SVM.
5861 *
5862 * \note It is only possible to enable fine-grained system SVM if all devices
5863 * in the context associated with kernel support it.
5864 *
5865 * \param svmEnabled True if fine-grained system SVM is requested. False otherwise.
5866 * \return CL_SUCCESS if the function was executed succesfully. CL_INVALID_OPERATION
5867 * if no devices in the context support fine-grained system SVM.
5868 *
5869 * \see clSetKernelExecInfo
5870 */
5871 cl_int enableFineGrainedSystemSVM(bool svmEnabled)
5872 {
5873 cl_bool svmEnabled_ = svmEnabled ? CL_TRUE : CL_FALSE;
5874 return detail::errHandler(
5875 ::clSetKernelExecInfo(
5876 object_,
5877 CL_KERNEL_EXEC_INFO_SVM_FINE_GRAIN_SYSTEM,
5878 sizeof(cl_bool),
5879 &svmEnabled_
5880 )
5881 );
5882 }
5883
5884 template<int index, int ArrayLength, class D, typename T0, typename... Ts>
5885 void setSVMPointersHelper(std::array<void*, ArrayLength> &pointerList, const pointer<T0, D> &t0, Ts... ts)
5886 {
5887 pointerList[index] = static_cast<void*>(t0.get());
5888 setSVMPointersHelper<index + 1, Ts...>(ts...);
5889 }
5890
5891 template<int index, int ArrayLength, typename T0, typename... Ts>
5892 typename std::enable_if<std::is_pointer<T0>::value, void>::type
5893 setSVMPointersHelper(std::array<void*, ArrayLength> &pointerList, T0 t0, Ts... ts)
5894 {
5895 pointerList[index] = static_cast<void*>(t0);
5896 setSVMPointersHelper<index + 1, Ts...>(ts...);
5897 }
5898
5899 template<int index, int ArrayLength, typename T0, class D>
5900 void setSVMPointersHelper(std::array<void*, ArrayLength> &pointerList, const pointer<T0, D> &t0)
5901 {
5902 pointerList[index] = static_cast<void*>(t0.get());
5903 }
5904
5905 template<int index, int ArrayLength, typename T0>
5906 typename std::enable_if<std::is_pointer<T0>::value, void>::type
5907 setSVMPointersHelper(std::array<void*, ArrayLength> &pointerList, T0 t0)
5908 {
5909 pointerList[index] = static_cast<void*>(t0);
5910 }
5911
5912 template<typename T0, typename... Ts>
5913 cl_int setSVMPointers(const T0 &t0, Ts... ts)
5914 {
5915 std::array<void*, 1 + sizeof...(Ts)> pointerList;
5916
5917 setSVMPointersHelper<0, 1 + sizeof...(Ts)>(pointerList, t0, ts...);
5918 return detail::errHandler(
5919 ::clSetKernelExecInfo(
5920 object_,
5921 CL_KERNEL_EXEC_INFO_SVM_PTRS,
5922 sizeof(void*)*(1 + sizeof...(Ts)),
5923 pointerList.data()));
5924 }
5925#endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 200
5926};
5927
5928/*! \class Program
5929 * \brief Program interface that implements cl_program.
5930 */
5931class Program : public detail::Wrapper<cl_program>
5932{
5933public:
5934#if !defined(CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY)
5935 typedef vector<vector<unsigned char>> Binaries;
5936 typedef vector<string> Sources;
5937#else // #if !defined(CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY)
5938 typedef vector<std::pair<const void*, size_type> > Binaries;
5939 typedef vector<std::pair<const char*, size_type> > Sources;
5940#endif // #if !defined(CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY)
5941
5942 Program(
5943 const string& source,
5944 bool build = false,
5945 cl_int* err = NULL)
5946 {
5947 cl_int error;
5948
5949 const char * strings = source.c_str();
5950 const size_type length = source.size();
5951
5952 Context context = Context::getDefault(err);
5953
5954 object_ = ::clCreateProgramWithSource(
5955 context(), (cl_uint)1, &strings, &length, &error);
5956
5957 detail::errHandler(error, __CREATE_PROGRAM_WITH_SOURCE_ERR);
5958
5959 if (error == CL_SUCCESS && build) {
5960
5961 error = ::clBuildProgram(
5962 object_,
5963 0,
5964 NULL,
5965#if !defined(CL_HPP_CL_1_2_DEFAULT_BUILD)
5966 "-cl-std=CL2.0",
5967#else
5968 "",
5969#endif // #if !defined(CL_HPP_CL_1_2_DEFAULT_BUILD)
5970 NULL,
5971 NULL);
5972
5973 detail::buildErrHandler(error, __BUILD_PROGRAM_ERR, getBuildInfo<CL_PROGRAM_BUILD_LOG>());
5974 }
5975
5976 if (err != NULL) {
5977 *err = error;
5978 }
5979 }
5980
5981 Program(
5982 const Context& context,
5983 const string& source,
5984 bool build = false,
5985 cl_int* err = NULL)
5986 {
5987 cl_int error;
5988
5989 const char * strings = source.c_str();
5990 const size_type length = source.size();
5991
5992 object_ = ::clCreateProgramWithSource(
5993 context(), (cl_uint)1, &strings, &length, &error);
5994
5995 detail::errHandler(error, __CREATE_PROGRAM_WITH_SOURCE_ERR);
5996
5997 if (error == CL_SUCCESS && build) {
5998 error = ::clBuildProgram(
5999 object_,
6000 0,
6001 NULL,
6002#if !defined(CL_HPP_CL_1_2_DEFAULT_BUILD)
6003 "-cl-std=CL2.0",
6004#else
6005 "",
6006#endif // #if !defined(CL_HPP_CL_1_2_DEFAULT_BUILD)
6007 NULL,
6008 NULL);
6009
6010 detail::buildErrHandler(error, __BUILD_PROGRAM_ERR, getBuildInfo<CL_PROGRAM_BUILD_LOG>());
6011 }
6012
6013 if (err != NULL) {
6014 *err = error;
6015 }
6016 }
6017
6018 /**
6019 * Create a program from a vector of source strings and the default context.
6020 * Does not compile or link the program.
6021 */
6022 Program(
6023 const Sources& sources,
6024 cl_int* err = NULL)
6025 {
6026 cl_int error;
6027 Context context = Context::getDefault(err);
6028
6029 const size_type n = (size_type)sources.size();
6030
6031 vector<size_type> lengths(n);
6032 vector<const char*> strings(n);
6033
6034 for (size_type i = 0; i < n; ++i) {
6035#if !defined(CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY)
6036 strings[i] = sources[(int)i].data();
6037 lengths[i] = sources[(int)i].length();
6038#else // #if !defined(CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY)
6039 strings[i] = sources[(int)i].first;
6040 lengths[i] = sources[(int)i].second;
6041#endif // #if !defined(CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY)
6042 }
6043
6044 object_ = ::clCreateProgramWithSource(
6045 context(), (cl_uint)n, strings.data(), lengths.data(), &error);
6046
6047 detail::errHandler(error, __CREATE_PROGRAM_WITH_SOURCE_ERR);
6048 if (err != NULL) {
6049 *err = error;
6050 }
6051 }
6052
6053 /**
6054 * Create a program from a vector of source strings and a provided context.
6055 * Does not compile or link the program.
6056 */
6057 Program(
6058 const Context& context,
6059 const Sources& sources,
6060 cl_int* err = NULL)
6061 {
6062 cl_int error;
6063
6064 const size_type n = (size_type)sources.size();
6065
6066 vector<size_type> lengths(n);
6067 vector<const char*> strings(n);
6068
6069 for (size_type i = 0; i < n; ++i) {
6070#if !defined(CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY)
6071 strings[i] = sources[(int)i].data();
6072 lengths[i] = sources[(int)i].length();
6073#else // #if !defined(CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY)
6074 strings[i] = sources[(int)i].first;
6075 lengths[i] = sources[(int)i].second;
6076#endif // #if !defined(CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY)
6077 }
6078
6079 object_ = ::clCreateProgramWithSource(
6080 context(), (cl_uint)n, strings.data(), lengths.data(), &error);
6081
6082 detail::errHandler(error, __CREATE_PROGRAM_WITH_SOURCE_ERR);
6083 if (err != NULL) {
6084 *err = error;
6085 }
6086 }
6087
6088 /**
6089 * Construct a program object from a list of devices and a per-device list of binaries.
6090 * \param context A valid OpenCL context in which to construct the program.
6091 * \param devices A vector of OpenCL device objects for which the program will be created.
6092 * \param binaries A vector of pairs of a pointer to a binary object and its length.
6093 * \param binaryStatus An optional vector that on completion will be resized to
6094 * match the size of binaries and filled with values to specify if each binary
6095 * was successfully loaded.
6096 * Set to CL_SUCCESS if the binary was successfully loaded.
6097 * Set to CL_INVALID_VALUE if the length is 0 or the binary pointer is NULL.
6098 * Set to CL_INVALID_BINARY if the binary provided is not valid for the matching device.
6099 * \param err if non-NULL will be set to CL_SUCCESS on successful operation or one of the following errors:
6100 * CL_INVALID_CONTEXT if context is not a valid context.
6101 * CL_INVALID_VALUE if the length of devices is zero; or if the length of binaries does not match the length of devices;
6102 * or if any entry in binaries is NULL or has length 0.
6103 * CL_INVALID_DEVICE if OpenCL devices listed in devices are not in the list of devices associated with context.
6104 * CL_INVALID_BINARY if an invalid program binary was encountered for any device. binaryStatus will return specific status for each device.
6105 * CL_OUT_OF_HOST_MEMORY if there is a failure to allocate resources required by the OpenCL implementation on the host.
6106 */
6107 Program(
6108 const Context& context,
6109 const vector<Device>& devices,
6110 const Binaries& binaries,
6111 vector<cl_int>* binaryStatus = NULL,
6112 cl_int* err = NULL)
6113 {
6114 cl_int error;
6115
6116 const size_type numDevices = devices.size();
6117
6118 // Catch size mismatch early and return
6119 if(binaries.size() != numDevices) {
6120 error = CL_INVALID_VALUE;
6121 detail::errHandler(error, __CREATE_PROGRAM_WITH_BINARY_ERR);
6122 if (err != NULL) {
6123 *err = error;
6124 }
6125 return;
6126 }
6127
6128
6129 vector<size_type> lengths(numDevices);
6130 vector<const unsigned char*> images(numDevices);
6131#if !defined(CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY)
6132 for (size_type i = 0; i < numDevices; ++i) {
6133 images[i] = binaries[i].data();
6134 lengths[i] = binaries[(int)i].size();
6135 }
6136#else // #if !defined(CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY)
6137 for (size_type i = 0; i < numDevices; ++i) {
6138 images[i] = (const unsigned char*)binaries[i].first;
6139 lengths[i] = binaries[(int)i].second;
6140 }
6141#endif // #if !defined(CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY)
6142
6143 vector<cl_device_id> deviceIDs(numDevices);
6144 for( size_type deviceIndex = 0; deviceIndex < numDevices; ++deviceIndex ) {
6145 deviceIDs[deviceIndex] = (devices[deviceIndex])();
6146 }
6147
6148 if(binaryStatus) {
6149 binaryStatus->resize(numDevices);
6150 }
6151
6152 object_ = ::clCreateProgramWithBinary(
6153 context(), (cl_uint) devices.size(),
6154 deviceIDs.data(),
6155 lengths.data(), images.data(), (binaryStatus != NULL && numDevices > 0)
6156 ? &binaryStatus->front()
6157 : NULL, &error);
6158
6159 detail::errHandler(error, __CREATE_PROGRAM_WITH_BINARY_ERR);
6160 if (err != NULL) {
6161 *err = error;
6162 }
6163 }
6164
6165
6166#if CL_HPP_TARGET_OPENCL_VERSION >= 120
6167 /**
6168 * Create program using builtin kernels.
6169 * \param kernelNames Semi-colon separated list of builtin kernel names
6170 */
6171 Program(
6172 const Context& context,
6173 const vector<Device>& devices,
6174 const string& kernelNames,
6175 cl_int* err = NULL)
6176 {
6177 cl_int error;
6178
6179
6180 size_type numDevices = devices.size();
6181 vector<cl_device_id> deviceIDs(numDevices);
6182 for( size_type deviceIndex = 0; deviceIndex < numDevices; ++deviceIndex ) {
6183 deviceIDs[deviceIndex] = (devices[deviceIndex])();
6184 }
6185
6186 object_ = ::clCreateProgramWithBuiltInKernels(
6187 context(),
6188 (cl_uint) devices.size(),
6189 deviceIDs.data(),
6190 kernelNames.c_str(),
6191 &error);
6192
6193 detail::errHandler(error, __CREATE_PROGRAM_WITH_BUILT_IN_KERNELS_ERR);
6194 if (err != NULL) {
6195 *err = error;
6196 }
6197 }
6198#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
6199
6200 Program() { }
6201
6202
6203 /*! \brief Constructor from cl_mem - takes ownership.
6204 *
6205 * \param retainObject will cause the constructor to retain its cl object.
6206 * Defaults to false to maintain compatibility with
6207 * earlier versions.
6208 */
6209 explicit Program(const cl_program& program, bool retainObject = false) :
6210 detail::Wrapper<cl_type>(program, retainObject) { }
6211
6212 Program& operator = (const cl_program& rhs)
6213 {
6214 detail::Wrapper<cl_type>::operator=(rhs);
6215 return *this;
6216 }
6217
6218 /*! \brief Copy constructor to forward copy to the superclass correctly.
6219 * Required for MSVC.
6220 */
6221 Program(const Program& program) : detail::Wrapper<cl_type>(program) {}
6222
6223 /*! \brief Copy assignment to forward copy to the superclass correctly.
6224 * Required for MSVC.
6225 */
6226 Program& operator = (const Program &program)
6227 {
6228 detail::Wrapper<cl_type>::operator=(program);
6229 return *this;
6230 }
6231
6232 /*! \brief Move constructor to forward move to the superclass correctly.
6233 * Required for MSVC.
6234 */
6235 Program(Program&& program) CL_HPP_NOEXCEPT_ : detail::Wrapper<cl_type>(std::move(program)) {}
6236
6237 /*! \brief Move assignment to forward move to the superclass correctly.
6238 * Required for MSVC.
6239 */
6240 Program& operator = (Program &&program)
6241 {
6242 detail::Wrapper<cl_type>::operator=(std::move(program));
6243 return *this;
6244 }
6245
6246 cl_int build(
6247 const vector<Device>& devices,
6248 const char* options = NULL,
6249 void (CL_CALLBACK * notifyFptr)(cl_program, void *) = NULL,
6250 void* data = NULL) const
6251 {
6252 size_type numDevices = devices.size();
6253 vector<cl_device_id> deviceIDs(numDevices);
6254
6255 for( size_type deviceIndex = 0; deviceIndex < numDevices; ++deviceIndex ) {
6256 deviceIDs[deviceIndex] = (devices[deviceIndex])();
6257 }
6258
6259 cl_int buildError = ::clBuildProgram(
6260 object_,
6261 (cl_uint)
6262 devices.size(),
6263 deviceIDs.data(),
6264 options,
6265 notifyFptr,
6266 data);
6267
6268 return detail::buildErrHandler(buildError, __BUILD_PROGRAM_ERR, getBuildInfo<CL_PROGRAM_BUILD_LOG>());
6269 }
6270
6271 cl_int build(
6272 const char* options = NULL,
6273 void (CL_CALLBACK * notifyFptr)(cl_program, void *) = NULL,
6274 void* data = NULL) const
6275 {
6276 cl_int buildError = ::clBuildProgram(
6277 object_,
6278 0,
6279 NULL,
6280 options,
6281 notifyFptr,
6282 data);
6283
6284
6285 return detail::buildErrHandler(buildError, __BUILD_PROGRAM_ERR, getBuildInfo<CL_PROGRAM_BUILD_LOG>());
6286 }
6287
6288#if CL_HPP_TARGET_OPENCL_VERSION >= 120
6289 cl_int compile(
6290 const char* options = NULL,
6291 void (CL_CALLBACK * notifyFptr)(cl_program, void *) = NULL,
6292 void* data = NULL) const
6293 {
6294 cl_int error = ::clCompileProgram(
6295 object_,
6296 0,
6297 NULL,
6298 options,
6299 0,
6300 NULL,
6301 NULL,
6302 notifyFptr,
6303 data);
6304 return detail::buildErrHandler(error, __COMPILE_PROGRAM_ERR, getBuildInfo<CL_PROGRAM_BUILD_LOG>());
6305 }
6306#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
6307
6308 template <typename T>
6309 cl_int getInfo(cl_program_info name, T* param) const
6310 {
6311 return detail::errHandler(
6312 detail::getInfo(&::clGetProgramInfo, object_, name, param),
6313 __GET_PROGRAM_INFO_ERR);
6314 }
6315
6316 template <cl_int name> typename
6317 detail::param_traits<detail::cl_program_info, name>::param_type
6318 getInfo(cl_int* err = NULL) const
6319 {
6320 typename detail::param_traits<
6321 detail::cl_program_info, name>::param_type param;
6322 cl_int result = getInfo(name, &param);
6323 if (err != NULL) {
6324 *err = result;
6325 }
6326 return param;
6327 }
6328
6329 template <typename T>
6330 cl_int getBuildInfo(
6331 const Device& device, cl_program_build_info name, T* param) const
6332 {
6333 return detail::errHandler(
6334 detail::getInfo(
6335 &::clGetProgramBuildInfo, object_, device(), name, param),
6336 __GET_PROGRAM_BUILD_INFO_ERR);
6337 }
6338
6339 template <cl_int name> typename
6340 detail::param_traits<detail::cl_program_build_info, name>::param_type
6341 getBuildInfo(const Device& device, cl_int* err = NULL) const
6342 {
6343 typename detail::param_traits<
6344 detail::cl_program_build_info, name>::param_type param;
6345 cl_int result = getBuildInfo(device, name, &param);
6346 if (err != NULL) {
6347 *err = result;
6348 }
6349 return param;
6350 }
6351
6352 /**
6353 * Build info function that returns a vector of device/info pairs for the specified
6354 * info type and for all devices in the program.
6355 * On an error reading the info for any device, an empty vector of info will be returned.
6356 */
6357 template <cl_int name>
6358 vector<std::pair<cl::Device, typename detail::param_traits<detail::cl_program_build_info, name>::param_type>>
6359 getBuildInfo(cl_int *err = NULL) const
6360 {
6361 cl_int result = CL_SUCCESS;
6362
6363 auto devs = getInfo<CL_PROGRAM_DEVICES>(&result);
6364 vector<std::pair<cl::Device, typename detail::param_traits<detail::cl_program_build_info, name>::param_type>>
6365 devInfo;
6366
6367 // If there was an initial error from getInfo return the error
6368 if (result != CL_SUCCESS) {
6369 if (err != NULL) {
6370 *err = result;
6371 }
6372 return devInfo;
6373 }
6374
6375 for (cl::Device d : devs) {
6376 typename detail::param_traits<
6377 detail::cl_program_build_info, name>::param_type param;
6378 result = getBuildInfo(d, name, &param);
6379 devInfo.push_back(
6380 std::pair<cl::Device, typename detail::param_traits<detail::cl_program_build_info, name>::param_type>
6381 (d, param));
6382 if (result != CL_SUCCESS) {
6383 // On error, leave the loop and return the error code
6384 break;
6385 }
6386 }
6387 if (err != NULL) {
6388 *err = result;
6389 }
6390 if (result != CL_SUCCESS) {
6391 devInfo.clear();
6392 }
6393 return devInfo;
6394 }
6395
6396 cl_int createKernels(vector<Kernel>* kernels)
6397 {
6398 cl_uint numKernels;
6399 cl_int err = ::clCreateKernelsInProgram(object_, 0, NULL, &numKernels);
6400 if (err != CL_SUCCESS) {
6401 return detail::errHandler(err, __CREATE_KERNELS_IN_PROGRAM_ERR);
6402 }
6403
6404 vector<cl_kernel> value(numKernels);
6405
6406 err = ::clCreateKernelsInProgram(
6407 object_, numKernels, value.data(), NULL);
6408 if (err != CL_SUCCESS) {
6409 return detail::errHandler(err, __CREATE_KERNELS_IN_PROGRAM_ERR);
6410 }
6411
6412 if (kernels) {
6413 kernels->resize(value.size());
6414
6415 // Assign to param, constructing with retain behaviour
6416 // to correctly capture each underlying CL object
6417 for (size_type i = 0; i < value.size(); i++) {
6418 // We do not need to retain because this kernel is being created
6419 // by the runtime
6420 (*kernels)[i] = Kernel(value[i], false);
6421 }
6422 }
6423 return CL_SUCCESS;
6424 }
6425};
6426
6427#if CL_HPP_TARGET_OPENCL_VERSION >= 120
6428inline Program linkProgram(
6429 Program input1,
6430 Program input2,
6431 const char* options = NULL,
6432 void (CL_CALLBACK * notifyFptr)(cl_program, void *) = NULL,
6433 void* data = NULL,
6434 cl_int* err = NULL)
6435{
6436 cl_int error_local = CL_SUCCESS;
6437
6438 cl_program programs[2] = { input1(), input2() };
6439
6440 Context ctx = input1.getInfo<CL_PROGRAM_CONTEXT>(&error_local);
6441 if(error_local!=CL_SUCCESS) {
6442 detail::errHandler(error_local, __LINK_PROGRAM_ERR);
6443 }
6444
6445 cl_program prog = ::clLinkProgram(
6446 ctx(),
6447 0,
6448 NULL,
6449 options,
6450 2,
6451 programs,
6452 notifyFptr,
6453 data,
6454 &error_local);
6455
6456 detail::errHandler(error_local,__COMPILE_PROGRAM_ERR);
6457 if (err != NULL) {
6458 *err = error_local;
6459 }
6460
6461 return Program(prog);
6462}
6463
6464inline Program linkProgram(
6465 vector<Program> inputPrograms,
6466 const char* options = NULL,
6467 void (CL_CALLBACK * notifyFptr)(cl_program, void *) = NULL,
6468 void* data = NULL,
6469 cl_int* err = NULL)
6470{
6471 cl_int error_local = CL_SUCCESS;
6472
6473 vector<cl_program> programs(inputPrograms.size());
6474
6475 for (unsigned int i = 0; i < inputPrograms.size(); i++) {
6476 programs[i] = inputPrograms[i]();
6477 }
6478
6479 Context ctx;
6480 if(inputPrograms.size() > 0) {
6481 ctx = inputPrograms[0].getInfo<CL_PROGRAM_CONTEXT>(&error_local);
6482 if(error_local!=CL_SUCCESS) {
6483 detail::errHandler(error_local, __LINK_PROGRAM_ERR);
6484 }
6485 }
6486 cl_program prog = ::clLinkProgram(
6487 ctx(),
6488 0,
6489 NULL,
6490 options,
6491 (cl_uint)inputPrograms.size(),
6492 programs.data(),
6493 notifyFptr,
6494 data,
6495 &error_local);
6496
6497 detail::errHandler(error_local,__COMPILE_PROGRAM_ERR);
6498 if (err != NULL) {
6499 *err = error_local;
6500 }
6501
6502 return Program(prog, false);
6503}
6504#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
6505
6506// Template specialization for CL_PROGRAM_BINARIES
6507template <>
6508inline cl_int cl::Program::getInfo(cl_program_info name, vector<vector<unsigned char>>* param) const
6509{
6510 if (name != CL_PROGRAM_BINARIES) {
6511 return CL_INVALID_VALUE;
6512 }
6513 if (param) {
6514 // Resize the parameter array appropriately for each allocation
6515 // and pass down to the helper
6516
6517 vector<size_type> sizes = getInfo<CL_PROGRAM_BINARY_SIZES>();
6518 size_type numBinaries = sizes.size();
6519
6520 // Resize the parameter array and constituent arrays
6521 param->resize(numBinaries);
6522 for (int i = 0; i < numBinaries; ++i) {
6523 (*param)[i].resize(sizes[i]);
6524 }
6525
6526 return detail::errHandler(
6527 detail::getInfo(&::clGetProgramInfo, object_, name, param),
6528 __GET_PROGRAM_INFO_ERR);
6529 }
6530
6531 return CL_SUCCESS;
6532}
6533
6534template<>
6535inline vector<vector<unsigned char>> cl::Program::getInfo<CL_PROGRAM_BINARIES>(cl_int* err) const
6536{
6537 vector<vector<unsigned char>> binariesVectors;
6538
6539 cl_int result = getInfo(CL_PROGRAM_BINARIES, &binariesVectors);
6540 if (err != NULL) {
6541 *err = result;
6542 }
6543 return binariesVectors;
6544}
6545
6546inline Kernel::Kernel(const Program& program, const char* name, cl_int* err)
6547{
6548 cl_int error;
6549
6550 object_ = ::clCreateKernel(program(), name, &error);
6551 detail::errHandler(error, __CREATE_KERNEL_ERR);
6552
6553 if (err != NULL) {
6554 *err = error;
6555 }
6556
6557}
6558
6559enum class QueueProperties : cl_command_queue_properties
6560{
6561 None = 0,
6562 Profiling = CL_QUEUE_PROFILING_ENABLE,
6563 OutOfOrder = CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE,
6564};
6565
6566inline QueueProperties operator|(QueueProperties lhs, QueueProperties rhs)
6567{
6568 return static_cast<QueueProperties>(static_cast<cl_command_queue_properties>(lhs) | static_cast<cl_command_queue_properties>(rhs));
6569}
6570
6571/*! \class CommandQueue
6572 * \brief CommandQueue interface for cl_command_queue.
6573 */
6574class CommandQueue : public detail::Wrapper<cl_command_queue>
6575{
6576private:
6577 static std::once_flag default_initialized_;
6578 static CommandQueue default_;
6579 static cl_int default_error_;
6580
6581 /*! \brief Create the default command queue returned by @ref getDefault.
6582 *
6583 * It sets default_error_ to indicate success or failure. It does not throw
6584 * @c cl::Error.
6585 */
6586 static void makeDefault()
6587 {
6588 /* We don't want to throw an error from this function, so we have to
6589 * catch and set the error flag.
6590 */
6591#if defined(CL_HPP_ENABLE_EXCEPTIONS)
6592 try
6593#endif
6594 {
6595 int error;
6596 Context context = Context::getDefault(&error);
6597
6598 if (error != CL_SUCCESS) {
6599 default_error_ = error;
6600 }
6601 else {
6602 Device device = Device::getDefault();
6603 default_ = CommandQueue(context, device, 0, &default_error_);
6604 }
6605 }
6606#if defined(CL_HPP_ENABLE_EXCEPTIONS)
6607 catch (cl::Error &e) {
6608 default_error_ = e.err();
6609 }
6610#endif
6611 }
6612
6613 /*! \brief Create the default command queue.
6614 *
6615 * This sets @c default_. It does not throw
6616 * @c cl::Error.
6617 */
6618 static void makeDefaultProvided(const CommandQueue &c) {
6619 default_ = c;
6620 }
6621
6622public:
6623#ifdef CL_HPP_UNIT_TEST_ENABLE
6624 /*! \brief Reset the default.
6625 *
6626 * This sets @c default_ to an empty value to support cleanup in
6627 * the unit test framework.
6628 * This function is not thread safe.
6629 */
6630 static void unitTestClearDefault() {
6631 default_ = CommandQueue();
6632 }
6633#endif // #ifdef CL_HPP_UNIT_TEST_ENABLE
6634
6635
6636 /*!
6637 * \brief Constructs a CommandQueue based on passed properties.
6638 * Will return an CL_INVALID_QUEUE_PROPERTIES error if CL_QUEUE_ON_DEVICE is specified.
6639 */
6640 CommandQueue(
6641 cl_command_queue_properties properties,
6642 cl_int* err = NULL)
6643 {
6644 cl_int error;
6645
6646 Context context = Context::getDefault(&error);
6647 detail::errHandler(error, __CREATE_CONTEXT_ERR);
6648
6649 if (error != CL_SUCCESS) {
6650 if (err != NULL) {
6651 *err = error;
6652 }
6653 }
6654 else {
6655 Device device = context.getInfo<CL_CONTEXT_DEVICES>()[0];
6656
6657#if CL_HPP_TARGET_OPENCL_VERSION >= 200
6658 cl_queue_properties queue_properties[] = {
6659 CL_QUEUE_PROPERTIES, properties, 0 };
6660 if ((properties & CL_QUEUE_ON_DEVICE) == 0) {
6661 object_ = ::clCreateCommandQueueWithProperties(
6662 context(), device(), queue_properties, &error);
6663 }
6664 else {
6665 error = CL_INVALID_QUEUE_PROPERTIES;
6666 }
6667
6668 detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR);
6669 if (err != NULL) {
6670 *err = error;
6671 }
6672#else
6673 object_ = ::clCreateCommandQueue(
6674 context(), device(), properties, &error);
6675
6676 detail::errHandler(error, __CREATE_COMMAND_QUEUE_ERR);
6677 if (err != NULL) {
6678 *err = error;
6679 }
6680#endif
6681 }
6682 }
6683
6684 /*!
6685 * \brief Constructs a CommandQueue based on passed properties.
6686 * Will return an CL_INVALID_QUEUE_PROPERTIES error if CL_QUEUE_ON_DEVICE is specified.
6687 */
6688 CommandQueue(
6689 QueueProperties properties,
6690 cl_int* err = NULL)
6691 {
6692 cl_int error;
6693
6694 Context context = Context::getDefault(&error);
6695 detail::errHandler(error, __CREATE_CONTEXT_ERR);
6696
6697 if (error != CL_SUCCESS) {
6698 if (err != NULL) {
6699 *err = error;
6700 }
6701 }
6702 else {
6703 Device device = context.getInfo<CL_CONTEXT_DEVICES>()[0];
6704
6705#if CL_HPP_TARGET_OPENCL_VERSION >= 200
6706 cl_queue_properties queue_properties[] = {
6707 CL_QUEUE_PROPERTIES, static_cast<cl_queue_properties>(properties), 0 };
6708
6709 object_ = ::clCreateCommandQueueWithProperties(
6710 context(), device(), queue_properties, &error);
6711
6712
6713 detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR);
6714 if (err != NULL) {
6715 *err = error;
6716 }
6717#else
6718 object_ = ::clCreateCommandQueue(
6719 context(), device(), static_cast<cl_command_queue_properties>(properties), &error);
6720
6721 detail::errHandler(error, __CREATE_COMMAND_QUEUE_ERR);
6722 if (err != NULL) {
6723 *err = error;
6724 }
6725#endif
6726 }
6727 }
6728
6729 /*!
6730 * \brief Constructs a CommandQueue for an implementation defined device in the given context
6731 * Will return an CL_INVALID_QUEUE_PROPERTIES error if CL_QUEUE_ON_DEVICE is specified.
6732 */
6733 explicit CommandQueue(
6734 const Context& context,
6735 cl_command_queue_properties properties = 0,
6736 cl_int* err = NULL)
6737 {
6738 cl_int error;
6739 vector<cl::Device> devices;
6740 error = context.getInfo(CL_CONTEXT_DEVICES, &devices);
6741
6742 detail::errHandler(error, __CREATE_CONTEXT_ERR);
6743
6744 if (error != CL_SUCCESS)
6745 {
6746 if (err != NULL) {
6747 *err = error;
6748 }
6749 return;
6750 }
6751
6752#if CL_HPP_TARGET_OPENCL_VERSION >= 200
6753 cl_queue_properties queue_properties[] = {
6754 CL_QUEUE_PROPERTIES, properties, 0 };
6755 if ((properties & CL_QUEUE_ON_DEVICE) == 0) {
6756 object_ = ::clCreateCommandQueueWithProperties(
6757 context(), devices[0](), queue_properties, &error);
6758 }
6759 else {
6760 error = CL_INVALID_QUEUE_PROPERTIES;
6761 }
6762
6763 detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR);
6764 if (err != NULL) {
6765 *err = error;
6766 }
6767#else
6768 object_ = ::clCreateCommandQueue(
6769 context(), devices[0](), properties, &error);
6770
6771 detail::errHandler(error, __CREATE_COMMAND_QUEUE_ERR);
6772 if (err != NULL) {
6773 *err = error;
6774 }
6775#endif
6776
6777 }
6778
6779 /*!
6780 * \brief Constructs a CommandQueue for an implementation defined device in the given context
6781 * Will return an CL_INVALID_QUEUE_PROPERTIES error if CL_QUEUE_ON_DEVICE is specified.
6782 */
6783 explicit CommandQueue(
6784 const Context& context,
6785 QueueProperties properties,
6786 cl_int* err = NULL)
6787 {
6788 cl_int error;
6789 vector<cl::Device> devices;
6790 error = context.getInfo(CL_CONTEXT_DEVICES, &devices);
6791
6792 detail::errHandler(error, __CREATE_CONTEXT_ERR);
6793
6794 if (error != CL_SUCCESS)
6795 {
6796 if (err != NULL) {
6797 *err = error;
6798 }
6799 return;
6800 }
6801
6802#if CL_HPP_TARGET_OPENCL_VERSION >= 200
6803 cl_queue_properties queue_properties[] = {
6804 CL_QUEUE_PROPERTIES, static_cast<cl_queue_properties>(properties), 0 };
6805 object_ = ::clCreateCommandQueueWithProperties(
6806 context(), devices[0](), queue_properties, &error);
6807
6808 detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR);
6809 if (err != NULL) {
6810 *err = error;
6811 }
6812#else
6813 object_ = ::clCreateCommandQueue(
6814 context(), devices[0](), static_cast<cl_command_queue_properties>(properties), &error);
6815
6816 detail::errHandler(error, __CREATE_COMMAND_QUEUE_ERR);
6817 if (err != NULL) {
6818 *err = error;
6819 }
6820#endif
6821
6822 }
6823
6824 /*!
6825 * \brief Constructs a CommandQueue for a passed device and context
6826 * Will return an CL_INVALID_QUEUE_PROPERTIES error if CL_QUEUE_ON_DEVICE is specified.
6827 */
6828 CommandQueue(
6829 const Context& context,
6830 const Device& device,
6831 cl_command_queue_properties properties = 0,
6832 cl_int* err = NULL)
6833 {
6834 cl_int error;
6835
6836#if CL_HPP_TARGET_OPENCL_VERSION >= 200
6837 cl_queue_properties queue_properties[] = {
6838 CL_QUEUE_PROPERTIES, properties, 0 };
6839 object_ = ::clCreateCommandQueueWithProperties(
6840 context(), device(), queue_properties, &error);
6841
6842 detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR);
6843 if (err != NULL) {
6844 *err = error;
6845 }
6846#else
6847 object_ = ::clCreateCommandQueue(
6848 context(), device(), properties, &error);
6849
6850 detail::errHandler(error, __CREATE_COMMAND_QUEUE_ERR);
6851 if (err != NULL) {
6852 *err = error;
6853 }
6854#endif
6855 }
6856
6857 /*!
6858 * \brief Constructs a CommandQueue for a passed device and context
6859 * Will return an CL_INVALID_QUEUE_PROPERTIES error if CL_QUEUE_ON_DEVICE is specified.
6860 */
6861 CommandQueue(
6862 const Context& context,
6863 const Device& device,
6864 QueueProperties properties,
6865 cl_int* err = NULL)
6866 {
6867 cl_int error;
6868
6869#if CL_HPP_TARGET_OPENCL_VERSION >= 200
6870 cl_queue_properties queue_properties[] = {
6871 CL_QUEUE_PROPERTIES, static_cast<cl_queue_properties>(properties), 0 };
6872 object_ = ::clCreateCommandQueueWithProperties(
6873 context(), device(), queue_properties, &error);
6874
6875 detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR);
6876 if (err != NULL) {
6877 *err = error;
6878 }
6879#else
6880 object_ = ::clCreateCommandQueue(
6881 context(), device(), static_cast<cl_command_queue_properties>(properties), &error);
6882
6883 detail::errHandler(error, __CREATE_COMMAND_QUEUE_ERR);
6884 if (err != NULL) {
6885 *err = error;
6886 }
6887#endif
6888 }
6889
6890 static CommandQueue getDefault(cl_int * err = NULL)
6891 {
6892 std::call_once(default_initialized_, makeDefault);
6893#if CL_HPP_TARGET_OPENCL_VERSION >= 200
6894 detail::errHandler(default_error_, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR);
6895#else // CL_HPP_TARGET_OPENCL_VERSION >= 200
6896 detail::errHandler(default_error_, __CREATE_COMMAND_QUEUE_ERR);
6897#endif // CL_HPP_TARGET_OPENCL_VERSION >= 200
6898 if (err != NULL) {
6899 *err = default_error_;
6900 }
6901 return default_;
6902 }
6903
6904 /**
6905 * Modify the default command queue to be used by
6906 * subsequent operations.
6907 * Will only set the default if no default was previously created.
6908 * @return updated default command queue.
6909 * Should be compared to the passed value to ensure that it was updated.
6910 */
6911 static CommandQueue setDefault(const CommandQueue &default_queue)
6912 {
6913 std::call_once(default_initialized_, makeDefaultProvided, std::cref(default_queue));
6914 detail::errHandler(default_error_);
6915 return default_;
6916 }
6917
6918 CommandQueue() { }
6919
6920
6921 /*! \brief Constructor from cl_mem - takes ownership.
6922 *
6923 * \param retainObject will cause the constructor to retain its cl object.
6924 * Defaults to false to maintain compatibility with
6925 * earlier versions.
6926 */
6927 explicit CommandQueue(const cl_command_queue& commandQueue, bool retainObject = false) :
6928 detail::Wrapper<cl_type>(commandQueue, retainObject) { }
6929
6930 CommandQueue& operator = (const cl_command_queue& rhs)
6931 {
6932 detail::Wrapper<cl_type>::operator=(rhs);
6933 return *this;
6934 }
6935
6936 /*! \brief Copy constructor to forward copy to the superclass correctly.
6937 * Required for MSVC.
6938 */
6939 CommandQueue(const CommandQueue& queue) : detail::Wrapper<cl_type>(queue) {}
6940
6941 /*! \brief Copy assignment to forward copy to the superclass correctly.
6942 * Required for MSVC.
6943 */
6944 CommandQueue& operator = (const CommandQueue &queue)
6945 {
6946 detail::Wrapper<cl_type>::operator=(queue);
6947 return *this;
6948 }
6949
6950 /*! \brief Move constructor to forward move to the superclass correctly.
6951 * Required for MSVC.
6952 */
6953 CommandQueue(CommandQueue&& queue) CL_HPP_NOEXCEPT_ : detail::Wrapper<cl_type>(std::move(queue)) {}
6954
6955 /*! \brief Move assignment to forward move to the superclass correctly.
6956 * Required for MSVC.
6957 */
6958 CommandQueue& operator = (CommandQueue &&queue)
6959 {
6960 detail::Wrapper<cl_type>::operator=(std::move(queue));
6961 return *this;
6962 }
6963
6964 template <typename T>
6965 cl_int getInfo(cl_command_queue_info name, T* param) const
6966 {
6967 return detail::errHandler(
6968 detail::getInfo(
6969 &::clGetCommandQueueInfo, object_, name, param),
6970 __GET_COMMAND_QUEUE_INFO_ERR);
6971 }
6972
6973 template <cl_int name> typename
6974 detail::param_traits<detail::cl_command_queue_info, name>::param_type
6975 getInfo(cl_int* err = NULL) const
6976 {
6977 typename detail::param_traits<
6978 detail::cl_command_queue_info, name>::param_type param;
6979 cl_int result = getInfo(name, &param);
6980 if (err != NULL) {
6981 *err = result;
6982 }
6983 return param;
6984 }
6985
6986 cl_int enqueueReadBuffer(
6987 const Buffer& buffer,
6988 cl_bool blocking,
6989 size_type offset,
6990 size_type size,
6991 void* ptr,
6992 const vector<Event>* events = NULL,
6993 Event* event = NULL) const
6994 {
6995 cl_event tmp;
6996 cl_int err = detail::errHandler(
6997 ::clEnqueueReadBuffer(
6998 object_, buffer(), blocking, offset, size,
6999 ptr,
7000 (events != NULL) ? (cl_uint) events->size() : 0,
7001 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
7002 (event != NULL) ? &tmp : NULL),
7003 __ENQUEUE_READ_BUFFER_ERR);
7004
7005 if (event != NULL && err == CL_SUCCESS)
7006 *event = tmp;
7007
7008 return err;
7009 }
7010
7011 cl_int enqueueWriteBuffer(
7012 const Buffer& buffer,
7013 cl_bool blocking,
7014 size_type offset,
7015 size_type size,
7016 const void* ptr,
7017 const vector<Event>* events = NULL,
7018 Event* event = NULL) const
7019 {
7020 cl_event tmp;
7021 cl_int err = detail::errHandler(
7022 ::clEnqueueWriteBuffer(
7023 object_, buffer(), blocking, offset, size,
7024 ptr,
7025 (events != NULL) ? (cl_uint) events->size() : 0,
7026 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
7027 (event != NULL) ? &tmp : NULL),
7028 __ENQUEUE_WRITE_BUFFER_ERR);
7029
7030 if (event != NULL && err == CL_SUCCESS)
7031 *event = tmp;
7032
7033 return err;
7034 }
7035
7036 cl_int enqueueCopyBuffer(
7037 const Buffer& src,
7038 const Buffer& dst,
7039 size_type src_offset,
7040 size_type dst_offset,
7041 size_type size,
7042 const vector<Event>* events = NULL,
7043 Event* event = NULL) const
7044 {
7045 cl_event tmp;
7046 cl_int err = detail::errHandler(
7047 ::clEnqueueCopyBuffer(
7048 object_, src(), dst(), src_offset, dst_offset, size,
7049 (events != NULL) ? (cl_uint) events->size() : 0,
7050 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
7051 (event != NULL) ? &tmp : NULL),
7052 __ENQEUE_COPY_BUFFER_ERR);
7053
7054 if (event != NULL && err == CL_SUCCESS)
7055 *event = tmp;
7056
7057 return err;
7058 }
7059
7060 cl_int enqueueReadBufferRect(
7061 const Buffer& buffer,
7062 cl_bool blocking,
7063 const array<size_type, 3>& buffer_offset,
7064 const array<size_type, 3>& host_offset,
7065 const array<size_type, 3>& region,
7066 size_type buffer_row_pitch,
7067 size_type buffer_slice_pitch,
7068 size_type host_row_pitch,
7069 size_type host_slice_pitch,
7070 void *ptr,
7071 const vector<Event>* events = NULL,
7072 Event* event = NULL) const
7073 {
7074 cl_event tmp;
7075 cl_int err = detail::errHandler(
7076 ::clEnqueueReadBufferRect(
7077 object_,
7078 buffer(),
7079 blocking,
7080 buffer_offset.data(),
7081 host_offset.data(),
7082 region.data(),
7083 buffer_row_pitch,
7084 buffer_slice_pitch,
7085 host_row_pitch,
7086 host_slice_pitch,
7087 ptr,
7088 (events != NULL) ? (cl_uint) events->size() : 0,
7089 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
7090 (event != NULL) ? &tmp : NULL),
7091 __ENQUEUE_READ_BUFFER_RECT_ERR);
7092
7093 if (event != NULL && err == CL_SUCCESS)
7094 *event = tmp;
7095
7096 return err;
7097 }
7098
7099 cl_int enqueueWriteBufferRect(
7100 const Buffer& buffer,
7101 cl_bool blocking,
7102 const array<size_type, 3>& buffer_offset,
7103 const array<size_type, 3>& host_offset,
7104 const array<size_type, 3>& region,
7105 size_type buffer_row_pitch,
7106 size_type buffer_slice_pitch,
7107 size_type host_row_pitch,
7108 size_type host_slice_pitch,
7109 void *ptr,
7110 const vector<Event>* events = NULL,
7111 Event* event = NULL) const
7112 {
7113 cl_event tmp;
7114 cl_int err = detail::errHandler(
7115 ::clEnqueueWriteBufferRect(
7116 object_,
7117 buffer(),
7118 blocking,
7119 buffer_offset.data(),
7120 host_offset.data(),
7121 region.data(),
7122 buffer_row_pitch,
7123 buffer_slice_pitch,
7124 host_row_pitch,
7125 host_slice_pitch,
7126 ptr,
7127 (events != NULL) ? (cl_uint) events->size() : 0,
7128 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
7129 (event != NULL) ? &tmp : NULL),
7130 __ENQUEUE_WRITE_BUFFER_RECT_ERR);
7131
7132 if (event != NULL && err == CL_SUCCESS)
7133 *event = tmp;
7134
7135 return err;
7136 }
7137
7138 cl_int enqueueCopyBufferRect(
7139 const Buffer& src,
7140 const Buffer& dst,
7141 const array<size_type, 3>& src_origin,
7142 const array<size_type, 3>& dst_origin,
7143 const array<size_type, 3>& region,
7144 size_type src_row_pitch,
7145 size_type src_slice_pitch,
7146 size_type dst_row_pitch,
7147 size_type dst_slice_pitch,
7148 const vector<Event>* events = NULL,
7149 Event* event = NULL) const
7150 {
7151 cl_event tmp;
7152 cl_int err = detail::errHandler(
7153 ::clEnqueueCopyBufferRect(
7154 object_,
7155 src(),
7156 dst(),
7157 src_origin.data(),
7158 dst_origin.data(),
7159 region.data(),
7160 src_row_pitch,
7161 src_slice_pitch,
7162 dst_row_pitch,
7163 dst_slice_pitch,
7164 (events != NULL) ? (cl_uint) events->size() : 0,
7165 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
7166 (event != NULL) ? &tmp : NULL),
7167 __ENQEUE_COPY_BUFFER_RECT_ERR);
7168
7169 if (event != NULL && err == CL_SUCCESS)
7170 *event = tmp;
7171
7172 return err;
7173 }
7174
7175#if CL_HPP_TARGET_OPENCL_VERSION >= 120
7176 /**
7177 * Enqueue a command to fill a buffer object with a pattern
7178 * of a given size. The pattern is specified as a vector type.
7179 * \tparam PatternType The datatype of the pattern field.
7180 * The pattern type must be an accepted OpenCL data type.
7181 * \tparam offset Is the offset in bytes into the buffer at
7182 * which to start filling. This must be a multiple of
7183 * the pattern size.
7184 * \tparam size Is the size in bytes of the region to fill.
7185 * This must be a multiple of the pattern size.
7186 */
7187 template<typename PatternType>
7188 cl_int enqueueFillBuffer(
7189 const Buffer& buffer,
7190 PatternType pattern,
7191 size_type offset,
7192 size_type size,
7193 const vector<Event>* events = NULL,
7194 Event* event = NULL) const
7195 {
7196 cl_event tmp;
7197 cl_int err = detail::errHandler(
7198 ::clEnqueueFillBuffer(
7199 object_,
7200 buffer(),
7201 static_cast<void*>(&pattern),
7202 sizeof(PatternType),
7203 offset,
7204 size,
7205 (events != NULL) ? (cl_uint) events->size() : 0,
7206 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
7207 (event != NULL) ? &tmp : NULL),
7208 __ENQUEUE_FILL_BUFFER_ERR);
7209
7210 if (event != NULL && err == CL_SUCCESS)
7211 *event = tmp;
7212
7213 return err;
7214 }
7215#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
7216
7217 cl_int enqueueReadImage(
7218 const Image& image,
7219 cl_bool blocking,
7220 const array<size_type, 3>& origin,
7221 const array<size_type, 3>& region,
7222 size_type row_pitch,
7223 size_type slice_pitch,
7224 void* ptr,
7225 const vector<Event>* events = NULL,
7226 Event* event = NULL) const
7227 {
7228 cl_event tmp;
7229 cl_int err = detail::errHandler(
7230 ::clEnqueueReadImage(
7231 object_,
7232 image(),
7233 blocking,
7234 origin.data(),
7235 region.data(),
7236 row_pitch,
7237 slice_pitch,
7238 ptr,
7239 (events != NULL) ? (cl_uint) events->size() : 0,
7240 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
7241 (event != NULL) ? &tmp : NULL),
7242 __ENQUEUE_READ_IMAGE_ERR);
7243
7244 if (event != NULL && err == CL_SUCCESS)
7245 *event = tmp;
7246
7247 return err;
7248 }
7249
7250 cl_int enqueueWriteImage(
7251 const Image& image,
7252 cl_bool blocking,
7253 const array<size_type, 3>& origin,
7254 const array<size_type, 3>& region,
7255 size_type row_pitch,
7256 size_type slice_pitch,
7257 void* ptr,
7258 const vector<Event>* events = NULL,
7259 Event* event = NULL) const
7260 {
7261 cl_event tmp;
7262 cl_int err = detail::errHandler(
7263 ::clEnqueueWriteImage(
7264 object_,
7265 image(),
7266 blocking,
7267 origin.data(),
7268 region.data(),
7269 row_pitch,
7270 slice_pitch,
7271 ptr,
7272 (events != NULL) ? (cl_uint) events->size() : 0,
7273 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
7274 (event != NULL) ? &tmp : NULL),
7275 __ENQUEUE_WRITE_IMAGE_ERR);
7276
7277 if (event != NULL && err == CL_SUCCESS)
7278 *event = tmp;
7279
7280 return err;
7281 }
7282
7283 cl_int enqueueCopyImage(
7284 const Image& src,
7285 const Image& dst,
7286 const array<size_type, 3>& src_origin,
7287 const array<size_type, 3>& dst_origin,
7288 const array<size_type, 3>& region,
7289 const vector<Event>* events = NULL,
7290 Event* event = NULL) const
7291 {
7292 cl_event tmp;
7293 cl_int err = detail::errHandler(
7294 ::clEnqueueCopyImage(
7295 object_,
7296 src(),
7297 dst(),
7298 src_origin.data(),
7299 dst_origin.data(),
7300 region.data(),
7301 (events != NULL) ? (cl_uint) events->size() : 0,
7302 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
7303 (event != NULL) ? &tmp : NULL),
7304 __ENQUEUE_COPY_IMAGE_ERR);
7305
7306 if (event != NULL && err == CL_SUCCESS)
7307 *event = tmp;
7308
7309 return err;
7310 }
7311
7312#if CL_HPP_TARGET_OPENCL_VERSION >= 120
7313 /**
7314 * Enqueue a command to fill an image object with a specified color.
7315 * \param fillColor is the color to use to fill the image.
7316 * This is a four component RGBA floating-point color value if
7317 * the image channel data type is not an unnormalized signed or
7318 * unsigned data type.
7319 */
7320 cl_int enqueueFillImage(
7321 const Image& image,
7322 cl_float4 fillColor,
7323 const array<size_type, 3>& origin,
7324 const array<size_type, 3>& region,
7325 const vector<Event>* events = NULL,
7326 Event* event = NULL) const
7327 {
7328 cl_event tmp;
7329 cl_int err = detail::errHandler(
7330 ::clEnqueueFillImage(
7331 object_,
7332 image(),
7333 static_cast<void*>(&fillColor),
7334 origin.data(),
7335 region.data(),
7336 (events != NULL) ? (cl_uint) events->size() : 0,
7337 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
7338 (event != NULL) ? &tmp : NULL),
7339 __ENQUEUE_FILL_IMAGE_ERR);
7340
7341 if (event != NULL && err == CL_SUCCESS)
7342 *event = tmp;
7343
7344 return err;
7345 }
7346
7347 /**
7348 * Enqueue a command to fill an image object with a specified color.
7349 * \param fillColor is the color to use to fill the image.
7350 * This is a four component RGBA signed integer color value if
7351 * the image channel data type is an unnormalized signed integer
7352 * type.
7353 */
7354 cl_int enqueueFillImage(
7355 const Image& image,
7356 cl_int4 fillColor,
7357 const array<size_type, 3>& origin,
7358 const array<size_type, 3>& region,
7359 const vector<Event>* events = NULL,
7360 Event* event = NULL) const
7361 {
7362 cl_event tmp;
7363 cl_int err = detail::errHandler(
7364 ::clEnqueueFillImage(
7365 object_,
7366 image(),
7367 static_cast<void*>(&fillColor),
7368 origin.data(),
7369 region.data(),
7370 (events != NULL) ? (cl_uint) events->size() : 0,
7371 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
7372 (event != NULL) ? &tmp : NULL),
7373 __ENQUEUE_FILL_IMAGE_ERR);
7374
7375 if (event != NULL && err == CL_SUCCESS)
7376 *event = tmp;
7377
7378 return err;
7379 }
7380
7381 /**
7382 * Enqueue a command to fill an image object with a specified color.
7383 * \param fillColor is the color to use to fill the image.
7384 * This is a four component RGBA unsigned integer color value if
7385 * the image channel data type is an unnormalized unsigned integer
7386 * type.
7387 */
7388 cl_int enqueueFillImage(
7389 const Image& image,
7390 cl_uint4 fillColor,
7391 const array<size_type, 3>& origin,
7392 const array<size_type, 3>& region,
7393 const vector<Event>* events = NULL,
7394 Event* event = NULL) const
7395 {
7396 cl_event tmp;
7397 cl_int err = detail::errHandler(
7398 ::clEnqueueFillImage(
7399 object_,
7400 image(),
7401 static_cast<void*>(&fillColor),
7402 origin.data(),
7403 region.data(),
7404 (events != NULL) ? (cl_uint) events->size() : 0,
7405 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
7406 (event != NULL) ? &tmp : NULL),
7407 __ENQUEUE_FILL_IMAGE_ERR);
7408
7409 if (event != NULL && err == CL_SUCCESS)
7410 *event = tmp;
7411
7412 return err;
7413 }
7414#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
7415
7416 cl_int enqueueCopyImageToBuffer(
7417 const Image& src,
7418 const Buffer& dst,
7419 const array<size_type, 3>& src_origin,
7420 const array<size_type, 3>& region,
7421 size_type dst_offset,
7422 const vector<Event>* events = NULL,
7423 Event* event = NULL) const
7424 {
7425 cl_event tmp;
7426 cl_int err = detail::errHandler(
7427 ::clEnqueueCopyImageToBuffer(
7428 object_,
7429 src(),
7430 dst(),
7431 src_origin.data(),
7432 region.data(),
7433 dst_offset,
7434 (events != NULL) ? (cl_uint) events->size() : 0,
7435 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
7436 (event != NULL) ? &tmp : NULL),
7437 __ENQUEUE_COPY_IMAGE_TO_BUFFER_ERR);
7438
7439 if (event != NULL && err == CL_SUCCESS)
7440 *event = tmp;
7441
7442 return err;
7443 }
7444
7445 cl_int enqueueCopyBufferToImage(
7446 const Buffer& src,
7447 const Image& dst,
7448 size_type src_offset,
7449 const array<size_type, 3>& dst_origin,
7450 const array<size_type, 3>& region,
7451 const vector<Event>* events = NULL,
7452 Event* event = NULL) const
7453 {
7454 cl_event tmp;
7455 cl_int err = detail::errHandler(
7456 ::clEnqueueCopyBufferToImage(
7457 object_,
7458 src(),
7459 dst(),
7460 src_offset,
7461 dst_origin.data(),
7462 region.data(),
7463 (events != NULL) ? (cl_uint) events->size() : 0,
7464 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
7465 (event != NULL) ? &tmp : NULL),
7466 __ENQUEUE_COPY_BUFFER_TO_IMAGE_ERR);
7467
7468 if (event != NULL && err == CL_SUCCESS)
7469 *event = tmp;
7470
7471 return err;
7472 }
7473
7474 void* enqueueMapBuffer(
7475 const Buffer& buffer,
7476 cl_bool blocking,
7477 cl_map_flags flags,
7478 size_type offset,
7479 size_type size,
7480 const vector<Event>* events = NULL,
7481 Event* event = NULL,
7482 cl_int* err = NULL) const
7483 {
7484 cl_event tmp;
7485 cl_int error;
7486 void * result = ::clEnqueueMapBuffer(
7487 object_, buffer(), blocking, flags, offset, size,
7488 (events != NULL) ? (cl_uint) events->size() : 0,
7489 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
7490 (event != NULL) ? &tmp : NULL,
7491 &error);
7492
7493 detail::errHandler(error, __ENQUEUE_MAP_BUFFER_ERR);
7494 if (err != NULL) {
7495 *err = error;
7496 }
7497 if (event != NULL && error == CL_SUCCESS)
7498 *event = tmp;
7499
7500 return result;
7501 }
7502
7503 void* enqueueMapImage(
7504 const Image& buffer,
7505 cl_bool blocking,
7506 cl_map_flags flags,
7507 const array<size_type, 3>& origin,
7508 const array<size_type, 3>& region,
7509 size_type * row_pitch,
7510 size_type * slice_pitch,
7511 const vector<Event>* events = NULL,
7512 Event* event = NULL,
7513 cl_int* err = NULL) const
7514 {
7515 cl_event tmp;
7516 cl_int error;
7517 void * result = ::clEnqueueMapImage(
7518 object_, buffer(), blocking, flags,
7519 origin.data(),
7520 region.data(),
7521 row_pitch, slice_pitch,
7522 (events != NULL) ? (cl_uint) events->size() : 0,
7523 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
7524 (event != NULL) ? &tmp : NULL,
7525 &error);
7526
7527 detail::errHandler(error, __ENQUEUE_MAP_IMAGE_ERR);
7528 if (err != NULL) {
7529 *err = error;
7530 }
7531 if (event != NULL && error == CL_SUCCESS)
7532 *event = tmp;
7533 return result;
7534 }
7535
7536#if CL_HPP_TARGET_OPENCL_VERSION >= 200
7537 /**
7538 * Enqueues a command that will allow the host to update a region of a coarse-grained SVM buffer.
7539 * This variant takes a raw SVM pointer.
7540 */
7541 template<typename T>
7542 cl_int enqueueMapSVM(
7543 T* ptr,
7544 cl_bool blocking,
7545 cl_map_flags flags,
7546 size_type size,
7547 const vector<Event>* events = NULL,
7548 Event* event = NULL) const
7549 {
7550 cl_event tmp;
7551 cl_int err = detail::errHandler(::clEnqueueSVMMap(
7552 object_, blocking, flags, static_cast<void*>(ptr), size,
7553 (events != NULL) ? (cl_uint)events->size() : 0,
7554 (events != NULL && events->size() > 0) ? (cl_event*)&events->front() : NULL,
7555 (event != NULL) ? &tmp : NULL),
7556 __ENQUEUE_MAP_BUFFER_ERR);
7557
7558 if (event != NULL && err == CL_SUCCESS)
7559 *event = tmp;
7560
7561 return err;
7562 }
7563
7564
7565 /**
7566 * Enqueues a command that will allow the host to update a region of a coarse-grained SVM buffer.
7567 * This variant takes a cl::pointer instance.
7568 */
7569 template<typename T, class D>
7570 cl_int enqueueMapSVM(
7571 cl::pointer<T, D> &ptr,
7572 cl_bool blocking,
7573 cl_map_flags flags,
7574 size_type size,
7575 const vector<Event>* events = NULL,
7576 Event* event = NULL) const
7577 {
7578 cl_event tmp;
7579 cl_int err = detail::errHandler(::clEnqueueSVMMap(
7580 object_, blocking, flags, static_cast<void*>(ptr.get()), size,
7581 (events != NULL) ? (cl_uint)events->size() : 0,
7582 (events != NULL && events->size() > 0) ? (cl_event*)&events->front() : NULL,
7583 (event != NULL) ? &tmp : NULL),
7584 __ENQUEUE_MAP_BUFFER_ERR);
7585
7586 if (event != NULL && err == CL_SUCCESS)
7587 *event = tmp;
7588
7589 return err;
7590 }
7591
7592 /**
7593 * Enqueues a command that will allow the host to update a region of a coarse-grained SVM buffer.
7594 * This variant takes a cl::vector instance.
7595 */
7596 template<typename T, class Alloc>
7597 cl_int enqueueMapSVM(
7598 cl::vector<T, Alloc> &container,
7599 cl_bool blocking,
7600 cl_map_flags flags,
7601 const vector<Event>* events = NULL,
7602 Event* event = NULL) const
7603 {
7604 cl_event tmp;
7605 cl_int err = detail::errHandler(::clEnqueueSVMMap(
7606 object_, blocking, flags, static_cast<void*>(container.data()), container.size(),
7607 (events != NULL) ? (cl_uint)events->size() : 0,
7608 (events != NULL && events->size() > 0) ? (cl_event*)&events->front() : NULL,
7609 (event != NULL) ? &tmp : NULL),
7610 __ENQUEUE_MAP_BUFFER_ERR);
7611
7612 if (event != NULL && err == CL_SUCCESS)
7613 *event = tmp;
7614
7615 return err;
7616 }
7617#endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 200
7618
7619 cl_int enqueueUnmapMemObject(
7620 const Memory& memory,
7621 void* mapped_ptr,
7622 const vector<Event>* events = NULL,
7623 Event* event = NULL) const
7624 {
7625 cl_event tmp;
7626 cl_int err = detail::errHandler(
7627 ::clEnqueueUnmapMemObject(
7628 object_, memory(), mapped_ptr,
7629 (events != NULL) ? (cl_uint) events->size() : 0,
7630 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
7631 (event != NULL) ? &tmp : NULL),
7632 __ENQUEUE_UNMAP_MEM_OBJECT_ERR);
7633
7634 if (event != NULL && err == CL_SUCCESS)
7635 *event = tmp;
7636
7637 return err;
7638 }
7639
7640
7641#if CL_HPP_TARGET_OPENCL_VERSION >= 200
7642 /**
7643 * Enqueues a command that will release a coarse-grained SVM buffer back to the OpenCL runtime.
7644 * This variant takes a raw SVM pointer.
7645 */
7646 template<typename T>
7647 cl_int enqueueUnmapSVM(
7648 T* ptr,
7649 const vector<Event>* events = NULL,
7650 Event* event = NULL) const
7651 {
7652 cl_event tmp;
7653 cl_int err = detail::errHandler(
7654 ::clEnqueueSVMUnmap(
7655 object_, static_cast<void*>(ptr),
7656 (events != NULL) ? (cl_uint)events->size() : 0,
7657 (events != NULL && events->size() > 0) ? (cl_event*)&events->front() : NULL,
7658 (event != NULL) ? &tmp : NULL),
7659 __ENQUEUE_UNMAP_MEM_OBJECT_ERR);
7660
7661 if (event != NULL && err == CL_SUCCESS)
7662 *event = tmp;
7663
7664 return err;
7665 }
7666
7667 /**
7668 * Enqueues a command that will release a coarse-grained SVM buffer back to the OpenCL runtime.
7669 * This variant takes a cl::pointer instance.
7670 */
7671 template<typename T, class D>
7672 cl_int enqueueUnmapSVM(
7673 cl::pointer<T, D> &ptr,
7674 const vector<Event>* events = NULL,
7675 Event* event = NULL) const
7676 {
7677 cl_event tmp;
7678 cl_int err = detail::errHandler(
7679 ::clEnqueueSVMUnmap(
7680 object_, static_cast<void*>(ptr.get()),
7681 (events != NULL) ? (cl_uint)events->size() : 0,
7682 (events != NULL && events->size() > 0) ? (cl_event*)&events->front() : NULL,
7683 (event != NULL) ? &tmp : NULL),
7684 __ENQUEUE_UNMAP_MEM_OBJECT_ERR);
7685
7686 if (event != NULL && err == CL_SUCCESS)
7687 *event = tmp;
7688
7689 return err;
7690 }
7691
7692 /**
7693 * Enqueues a command that will release a coarse-grained SVM buffer back to the OpenCL runtime.
7694 * This variant takes a cl::vector instance.
7695 */
7696 template<typename T, class Alloc>
7697 cl_int enqueueUnmapSVM(
7698 cl::vector<T, Alloc> &container,
7699 const vector<Event>* events = NULL,
7700 Event* event = NULL) const
7701 {
7702 cl_event tmp;
7703 cl_int err = detail::errHandler(
7704 ::clEnqueueSVMUnmap(
7705 object_, static_cast<void*>(container.data()),
7706 (events != NULL) ? (cl_uint)events->size() : 0,
7707 (events != NULL && events->size() > 0) ? (cl_event*)&events->front() : NULL,
7708 (event != NULL) ? &tmp : NULL),
7709 __ENQUEUE_UNMAP_MEM_OBJECT_ERR);
7710
7711 if (event != NULL && err == CL_SUCCESS)
7712 *event = tmp;
7713
7714 return err;
7715 }
7716#endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 200
7717
7718#if CL_HPP_TARGET_OPENCL_VERSION >= 120
7719 /**
7720 * Enqueues a marker command which waits for either a list of events to complete,
7721 * or all previously enqueued commands to complete.
7722 *
7723 * Enqueues a marker command which waits for either a list of events to complete,
7724 * or if the list is empty it waits for all commands previously enqueued in command_queue
7725 * to complete before it completes. This command returns an event which can be waited on,
7726 * i.e. this event can be waited on to insure that all events either in the event_wait_list
7727 * or all previously enqueued commands, queued before this command to command_queue,
7728 * have completed.
7729 */
7730 cl_int enqueueMarkerWithWaitList(
7731 const vector<Event> *events = 0,
7732 Event *event = 0)
7733 {
7734 cl_event tmp;
7735 cl_int err = detail::errHandler(
7736 ::clEnqueueMarkerWithWaitList(
7737 object_,
7738 (events != NULL) ? (cl_uint) events->size() : 0,
7739 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
7740 (event != NULL) ? &tmp : NULL),
7741 __ENQUEUE_MARKER_WAIT_LIST_ERR);
7742
7743 if (event != NULL && err == CL_SUCCESS)
7744 *event = tmp;
7745
7746 return err;
7747 }
7748
7749 /**
7750 * A synchronization point that enqueues a barrier operation.
7751 *
7752 * Enqueues a barrier command which waits for either a list of events to complete,
7753 * or if the list is empty it waits for all commands previously enqueued in command_queue
7754 * to complete before it completes. This command blocks command execution, that is, any
7755 * following commands enqueued after it do not execute until it completes. This command
7756 * returns an event which can be waited on, i.e. this event can be waited on to insure that
7757 * all events either in the event_wait_list or all previously enqueued commands, queued
7758 * before this command to command_queue, have completed.
7759 */
7760 cl_int enqueueBarrierWithWaitList(
7761 const vector<Event> *events = 0,
7762 Event *event = 0)
7763 {
7764 cl_event tmp;
7765 cl_int err = detail::errHandler(
7766 ::clEnqueueBarrierWithWaitList(
7767 object_,
7768 (events != NULL) ? (cl_uint) events->size() : 0,
7769 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
7770 (event != NULL) ? &tmp : NULL),
7771 __ENQUEUE_BARRIER_WAIT_LIST_ERR);
7772
7773 if (event != NULL && err == CL_SUCCESS)
7774 *event = tmp;
7775
7776 return err;
7777 }
7778
7779 /**
7780 * Enqueues a command to indicate with which device a set of memory objects
7781 * should be associated.
7782 */
7783 cl_int enqueueMigrateMemObjects(
7784 const vector<Memory> &memObjects,
7785 cl_mem_migration_flags flags,
7786 const vector<Event>* events = NULL,
7787 Event* event = NULL
7788 )
7789 {
7790 cl_event tmp;
7791
7792 vector<cl_mem> localMemObjects(memObjects.size());
7793
7794 for( int i = 0; i < (int)memObjects.size(); ++i ) {
7795 localMemObjects[i] = memObjects[i]();
7796 }
7797
7798
7799 cl_int err = detail::errHandler(
7800 ::clEnqueueMigrateMemObjects(
7801 object_,
7802 (cl_uint)memObjects.size(),
7803 localMemObjects.data(),
7804 flags,
7805 (events != NULL) ? (cl_uint) events->size() : 0,
7806 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
7807 (event != NULL) ? &tmp : NULL),
7808 __ENQUEUE_UNMAP_MEM_OBJECT_ERR);
7809
7810 if (event != NULL && err == CL_SUCCESS)
7811 *event = tmp;
7812
7813 return err;
7814 }
7815#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
7816
7817 cl_int enqueueNDRangeKernel(
7818 const Kernel& kernel,
7819 const NDRange& offset,
7820 const NDRange& global,
7821 const NDRange& local = NullRange,
7822 const vector<Event>* events = NULL,
7823 Event* event = NULL) const
7824 {
7825 cl_event tmp;
7826 cl_int err = detail::errHandler(
7827 ::clEnqueueNDRangeKernel(
7828 object_, kernel(), (cl_uint) global.dimensions(),
7829 offset.dimensions() != 0 ? (const size_type*) offset : NULL,
7830 (const size_type*) global,
7831 local.dimensions() != 0 ? (const size_type*) local : NULL,
7832 (events != NULL) ? (cl_uint) events->size() : 0,
7833 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
7834 (event != NULL) ? &tmp : NULL),
7835 __ENQUEUE_NDRANGE_KERNEL_ERR);
7836
7837 if (event != NULL && err == CL_SUCCESS)
7838 *event = tmp;
7839
7840 return err;
7841 }
7842
7843#if defined(CL_USE_DEPRECATED_OPENCL_1_2_APIS)
7844 CL_EXT_PREFIX__VERSION_1_2_DEPRECATED cl_int enqueueTask(
7845 const Kernel& kernel,
7846 const vector<Event>* events = NULL,
7847 Event* event = NULL) CL_EXT_SUFFIX__VERSION_1_2_DEPRECATED const
7848 {
7849 cl_event tmp;
7850 cl_int err = detail::errHandler(
7851 ::clEnqueueTask(
7852 object_, kernel(),
7853 (events != NULL) ? (cl_uint) events->size() : 0,
7854 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
7855 (event != NULL) ? &tmp : NULL),
7856 __ENQUEUE_TASK_ERR);
7857
7858 if (event != NULL && err == CL_SUCCESS)
7859 *event = tmp;
7860
7861 return err;
7862 }
7863#endif // #if defined(CL_USE_DEPRECATED_OPENCL_1_2_APIS)
7864
7865 cl_int enqueueNativeKernel(
7866 void (CL_CALLBACK *userFptr)(void *),
7867 std::pair<void*, size_type> args,
7868 const vector<Memory>* mem_objects = NULL,
7869 const vector<const void*>* mem_locs = NULL,
7870 const vector<Event>* events = NULL,
7871 Event* event = NULL) const
7872 {
7873 size_type elements = 0;
7874 if (mem_objects != NULL) {
7875 elements = mem_objects->size();
7876 }
7877 vector<cl_mem> mems(elements);
7878 for (unsigned int i = 0; i < elements; i++) {
7879 mems[i] = ((*mem_objects)[i])();
7880 }
7881
7882 cl_event tmp;
7883 cl_int err = detail::errHandler(
7884 ::clEnqueueNativeKernel(
7885 object_, userFptr, args.first, args.second,
7886 (mem_objects != NULL) ? (cl_uint) mem_objects->size() : 0,
7887 mems.data(),
7888 (mem_locs != NULL && mem_locs->size() > 0) ? (const void **) &mem_locs->front() : NULL,
7889 (events != NULL) ? (cl_uint) events->size() : 0,
7890 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
7891 (event != NULL) ? &tmp : NULL),
7892 __ENQUEUE_NATIVE_KERNEL);
7893
7894 if (event != NULL && err == CL_SUCCESS)
7895 *event = tmp;
7896
7897 return err;
7898 }
7899
7900/**
7901 * Deprecated APIs for 1.2
7902 */
7903#if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
7904 CL_EXT_PREFIX__VERSION_1_1_DEPRECATED
7905 cl_int enqueueMarker(Event* event = NULL) const CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED
7906 {
7907 cl_event tmp;
7908 cl_int err = detail::errHandler(
7909 ::clEnqueueMarker(
7910 object_,
7911 (event != NULL) ? &tmp : NULL),
7912 __ENQUEUE_MARKER_ERR);
7913
7914 if (event != NULL && err == CL_SUCCESS)
7915 *event = tmp;
7916
7917 return err;
7918 }
7919
7920 CL_EXT_PREFIX__VERSION_1_1_DEPRECATED
7921 cl_int enqueueWaitForEvents(const vector<Event>& events) const CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED
7922 {
7923 return detail::errHandler(
7924 ::clEnqueueWaitForEvents(
7925 object_,
7926 (cl_uint) events.size(),
7927 events.size() > 0 ? (const cl_event*) &events.front() : NULL),
7928 __ENQUEUE_WAIT_FOR_EVENTS_ERR);
7929 }
7930#endif // defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
7931
7932 cl_int enqueueAcquireGLObjects(
7933 const vector<Memory>* mem_objects = NULL,
7934 const vector<Event>* events = NULL,
7935 Event* event = NULL) const
7936 {
7937 cl_event tmp;
7938 cl_int err = detail::errHandler(
7939 ::clEnqueueAcquireGLObjects(
7940 object_,
7941 (mem_objects != NULL) ? (cl_uint) mem_objects->size() : 0,
7942 (mem_objects != NULL && mem_objects->size() > 0) ? (const cl_mem *) &mem_objects->front(): NULL,
7943 (events != NULL) ? (cl_uint) events->size() : 0,
7944 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
7945 (event != NULL) ? &tmp : NULL),
7946 __ENQUEUE_ACQUIRE_GL_ERR);
7947
7948 if (event != NULL && err == CL_SUCCESS)
7949 *event = tmp;
7950
7951 return err;
7952 }
7953
7954 cl_int enqueueReleaseGLObjects(
7955 const vector<Memory>* mem_objects = NULL,
7956 const vector<Event>* events = NULL,
7957 Event* event = NULL) const
7958 {
7959 cl_event tmp;
7960 cl_int err = detail::errHandler(
7961 ::clEnqueueReleaseGLObjects(
7962 object_,
7963 (mem_objects != NULL) ? (cl_uint) mem_objects->size() : 0,
7964 (mem_objects != NULL && mem_objects->size() > 0) ? (const cl_mem *) &mem_objects->front(): NULL,
7965 (events != NULL) ? (cl_uint) events->size() : 0,
7966 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
7967 (event != NULL) ? &tmp : NULL),
7968 __ENQUEUE_RELEASE_GL_ERR);
7969
7970 if (event != NULL && err == CL_SUCCESS)
7971 *event = tmp;
7972
7973 return err;
7974 }
7975
7976#if defined (CL_HPP_USE_DX_INTEROP)
7977typedef CL_API_ENTRY cl_int (CL_API_CALL *PFN_clEnqueueAcquireD3D10ObjectsKHR)(
7978 cl_command_queue command_queue, cl_uint num_objects,
7979 const cl_mem* mem_objects, cl_uint num_events_in_wait_list,
7980 const cl_event* event_wait_list, cl_event* event);
7981typedef CL_API_ENTRY cl_int (CL_API_CALL *PFN_clEnqueueReleaseD3D10ObjectsKHR)(
7982 cl_command_queue command_queue, cl_uint num_objects,
7983 const cl_mem* mem_objects, cl_uint num_events_in_wait_list,
7984 const cl_event* event_wait_list, cl_event* event);
7985
7986 cl_int enqueueAcquireD3D10Objects(
7987 const vector<Memory>* mem_objects = NULL,
7988 const vector<Event>* events = NULL,
7989 Event* event = NULL) const
7990 {
7991 static PFN_clEnqueueAcquireD3D10ObjectsKHR pfn_clEnqueueAcquireD3D10ObjectsKHR = NULL;
7992#if CL_HPP_TARGET_OPENCL_VERSION >= 120
7993 cl_context context = getInfo<CL_QUEUE_CONTEXT>();
7994 cl::Device device(getInfo<CL_QUEUE_DEVICE>());
7995 cl_platform_id platform = device.getInfo<CL_DEVICE_PLATFORM>();
7996 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clEnqueueAcquireD3D10ObjectsKHR);
7997#endif
7998#if CL_HPP_TARGET_OPENCL_VERSION >= 110
7999 CL_HPP_INIT_CL_EXT_FCN_PTR_(clEnqueueAcquireD3D10ObjectsKHR);
8000#endif
8001
8002 cl_event tmp;
8003 cl_int err = detail::errHandler(
8004 pfn_clEnqueueAcquireD3D10ObjectsKHR(
8005 object_,
8006 (mem_objects != NULL) ? (cl_uint) mem_objects->size() : 0,
8007 (mem_objects != NULL && mem_objects->size() > 0) ? (const cl_mem *) &mem_objects->front(): NULL,
8008 (events != NULL) ? (cl_uint) events->size() : 0,
8009 (events != NULL) ? (cl_event*) &events->front() : NULL,
8010 (event != NULL) ? &tmp : NULL),
8011 __ENQUEUE_ACQUIRE_GL_ERR);
8012
8013 if (event != NULL && err == CL_SUCCESS)
8014 *event = tmp;
8015
8016 return err;
8017 }
8018
8019 cl_int enqueueReleaseD3D10Objects(
8020 const vector<Memory>* mem_objects = NULL,
8021 const vector<Event>* events = NULL,
8022 Event* event = NULL) const
8023 {
8024 static PFN_clEnqueueReleaseD3D10ObjectsKHR pfn_clEnqueueReleaseD3D10ObjectsKHR = NULL;
8025#if CL_HPP_TARGET_OPENCL_VERSION >= 120
8026 cl_context context = getInfo<CL_QUEUE_CONTEXT>();
8027 cl::Device device(getInfo<CL_QUEUE_DEVICE>());
8028 cl_platform_id platform = device.getInfo<CL_DEVICE_PLATFORM>();
8029 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clEnqueueReleaseD3D10ObjectsKHR);
8030#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
8031#if CL_HPP_TARGET_OPENCL_VERSION >= 110
8032 CL_HPP_INIT_CL_EXT_FCN_PTR_(clEnqueueReleaseD3D10ObjectsKHR);
8033#endif // CL_HPP_TARGET_OPENCL_VERSION >= 110
8034
8035 cl_event tmp;
8036 cl_int err = detail::errHandler(
8037 pfn_clEnqueueReleaseD3D10ObjectsKHR(
8038 object_,
8039 (mem_objects != NULL) ? (cl_uint) mem_objects->size() : 0,
8040 (mem_objects != NULL && mem_objects->size() > 0) ? (const cl_mem *) &mem_objects->front(): NULL,
8041 (events != NULL) ? (cl_uint) events->size() : 0,
8042 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
8043 (event != NULL) ? &tmp : NULL),
8044 __ENQUEUE_RELEASE_GL_ERR);
8045
8046 if (event != NULL && err == CL_SUCCESS)
8047 *event = tmp;
8048
8049 return err;
8050 }
8051#endif
8052
8053/**
8054 * Deprecated APIs for 1.2
8055 */
8056#if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
8057 CL_EXT_PREFIX__VERSION_1_1_DEPRECATED
8058 cl_int enqueueBarrier() const CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED
8059 {
8060 return detail::errHandler(
8061 ::clEnqueueBarrier(object_),
8062 __ENQUEUE_BARRIER_ERR);
8063 }
8064#endif // CL_USE_DEPRECATED_OPENCL_1_1_APIS
8065
8066 cl_int flush() const
8067 {
8068 return detail::errHandler(::clFlush(object_), __FLUSH_ERR);
8069 }
8070
8071 cl_int finish() const
8072 {
8073 return detail::errHandler(::clFinish(object_), __FINISH_ERR);
8074 }
8075}; // CommandQueue
8076
8077CL_HPP_DEFINE_STATIC_MEMBER_ std::once_flag CommandQueue::default_initialized_;
8078CL_HPP_DEFINE_STATIC_MEMBER_ CommandQueue CommandQueue::default_;
8079CL_HPP_DEFINE_STATIC_MEMBER_ cl_int CommandQueue::default_error_ = CL_SUCCESS;
8080
8081
8082#if CL_HPP_TARGET_OPENCL_VERSION >= 200
8083enum class DeviceQueueProperties : cl_command_queue_properties
8084{
8085 None = 0,
8086 Profiling = CL_QUEUE_PROFILING_ENABLE,
8087};
8088
8089inline DeviceQueueProperties operator|(DeviceQueueProperties lhs, DeviceQueueProperties rhs)
8090{
8091 return static_cast<DeviceQueueProperties>(static_cast<cl_command_queue_properties>(lhs) | static_cast<cl_command_queue_properties>(rhs));
8092}
8093
8094/*! \class DeviceCommandQueue
8095 * \brief DeviceCommandQueue interface for device cl_command_queues.
8096 */
8097class DeviceCommandQueue : public detail::Wrapper<cl_command_queue>
8098{
8099public:
8100
8101 /*!
8102 * Trivial empty constructor to create a null queue.
8103 */
8104 DeviceCommandQueue() { }
8105
8106 /*!
8107 * Default construct device command queue on default context and device
8108 */
8109 DeviceCommandQueue(DeviceQueueProperties properties, cl_int* err = NULL)
8110 {
8111 cl_int error;
8112 cl::Context context = cl::Context::getDefault();
8113 cl::Device device = cl::Device::getDefault();
8114
8115 cl_command_queue_properties mergedProperties =
8116 CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE | CL_QUEUE_ON_DEVICE | static_cast<cl_command_queue_properties>(properties);
8117
8118 cl_queue_properties queue_properties[] = {
8119 CL_QUEUE_PROPERTIES, mergedProperties, 0 };
8120 object_ = ::clCreateCommandQueueWithProperties(
8121 context(), device(), queue_properties, &error);
8122
8123 detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR);
8124 if (err != NULL) {
8125 *err = error;
8126 }
8127 }
8128
8129 /*!
8130 * Create a device command queue for a specified device in the passed context.
8131 */
8132 DeviceCommandQueue(
8133 const Context& context,
8134 const Device& device,
8135 DeviceQueueProperties properties = DeviceQueueProperties::None,
8136 cl_int* err = NULL)
8137 {
8138 cl_int error;
8139
8140 cl_command_queue_properties mergedProperties =
8141 CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE | CL_QUEUE_ON_DEVICE | static_cast<cl_command_queue_properties>(properties);
8142 cl_queue_properties queue_properties[] = {
8143 CL_QUEUE_PROPERTIES, mergedProperties, 0 };
8144 object_ = ::clCreateCommandQueueWithProperties(
8145 context(), device(), queue_properties, &error);
8146
8147 detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR);
8148 if (err != NULL) {
8149 *err = error;
8150 }
8151 }
8152
8153 /*!
8154 * Create a device command queue for a specified device in the passed context.
8155 */
8156 DeviceCommandQueue(
8157 const Context& context,
8158 const Device& device,
8159 cl_uint queueSize,
8160 DeviceQueueProperties properties = DeviceQueueProperties::None,
8161 cl_int* err = NULL)
8162 {
8163 cl_int error;
8164
8165 cl_command_queue_properties mergedProperties =
8166 CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE | CL_QUEUE_ON_DEVICE | static_cast<cl_command_queue_properties>(properties);
8167 cl_queue_properties queue_properties[] = {
8168 CL_QUEUE_PROPERTIES, mergedProperties,
8169 CL_QUEUE_SIZE, queueSize,
8170 0 };
8171 object_ = ::clCreateCommandQueueWithProperties(
8172 context(), device(), queue_properties, &error);
8173
8174 detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR);
8175 if (err != NULL) {
8176 *err = error;
8177 }
8178 }
8179
8180 /*! \brief Constructor from cl_command_queue - takes ownership.
8181 *
8182 * \param retainObject will cause the constructor to retain its cl object.
8183 * Defaults to false to maintain compatibility with
8184 * earlier versions.
8185 */
8186 explicit DeviceCommandQueue(const cl_command_queue& commandQueue, bool retainObject = false) :
8187 detail::Wrapper<cl_type>(commandQueue, retainObject) { }
8188
8189 DeviceCommandQueue& operator = (const cl_command_queue& rhs)
8190 {
8191 detail::Wrapper<cl_type>::operator=(rhs);
8192 return *this;
8193 }
8194
8195 /*! \brief Copy constructor to forward copy to the superclass correctly.
8196 * Required for MSVC.
8197 */
8198 DeviceCommandQueue(const DeviceCommandQueue& queue) : detail::Wrapper<cl_type>(queue) {}
8199
8200 /*! \brief Copy assignment to forward copy to the superclass correctly.
8201 * Required for MSVC.
8202 */
8203 DeviceCommandQueue& operator = (const DeviceCommandQueue &queue)
8204 {
8205 detail::Wrapper<cl_type>::operator=(queue);
8206 return *this;
8207 }
8208
8209 /*! \brief Move constructor to forward move to the superclass correctly.
8210 * Required for MSVC.
8211 */
8212 DeviceCommandQueue(DeviceCommandQueue&& queue) CL_HPP_NOEXCEPT_ : detail::Wrapper<cl_type>(std::move(queue)) {}
8213
8214 /*! \brief Move assignment to forward move to the superclass correctly.
8215 * Required for MSVC.
8216 */
8217 DeviceCommandQueue& operator = (DeviceCommandQueue &&queue)
8218 {
8219 detail::Wrapper<cl_type>::operator=(std::move(queue));
8220 return *this;
8221 }
8222
8223 template <typename T>
8224 cl_int getInfo(cl_command_queue_info name, T* param) const
8225 {
8226 return detail::errHandler(
8227 detail::getInfo(
8228 &::clGetCommandQueueInfo, object_, name, param),
8229 __GET_COMMAND_QUEUE_INFO_ERR);
8230 }
8231
8232 template <cl_int name> typename
8233 detail::param_traits<detail::cl_command_queue_info, name>::param_type
8234 getInfo(cl_int* err = NULL) const
8235 {
8236 typename detail::param_traits<
8237 detail::cl_command_queue_info, name>::param_type param;
8238 cl_int result = getInfo(name, &param);
8239 if (err != NULL) {
8240 *err = result;
8241 }
8242 return param;
8243 }
8244
8245 /*!
8246 * Create a new default device command queue for the default device,
8247 * in the default context and of the default size.
8248 * If there is already a default queue for the specified device this
8249 * function will return the pre-existing queue.
8250 */
8251 static DeviceCommandQueue makeDefault(
8252 cl_int *err = nullptr)
8253 {
8254 cl_int error;
8255 cl::Context context = cl::Context::getDefault();
8256 cl::Device device = cl::Device::getDefault();
8257
8258 cl_command_queue_properties properties =
8259 CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE | CL_QUEUE_ON_DEVICE | CL_QUEUE_ON_DEVICE_DEFAULT;
8260 cl_queue_properties queue_properties[] = {
8261 CL_QUEUE_PROPERTIES, properties,
8262 0 };
8263 DeviceCommandQueue deviceQueue(
8264 ::clCreateCommandQueueWithProperties(
8265 context(), device(), queue_properties, &error));
8266
8267 detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR);
8268 if (err != NULL) {
8269 *err = error;
8270 }
8271
8272 return deviceQueue;
8273 }
8274
8275 /*!
8276 * Create a new default device command queue for the specified device
8277 * and of the default size.
8278 * If there is already a default queue for the specified device this
8279 * function will return the pre-existing queue.
8280 */
8281 static DeviceCommandQueue makeDefault(
8282 const Context &context, const Device &device, cl_int *err = nullptr)
8283 {
8284 cl_int error;
8285
8286 cl_command_queue_properties properties =
8287 CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE | CL_QUEUE_ON_DEVICE | CL_QUEUE_ON_DEVICE_DEFAULT;
8288 cl_queue_properties queue_properties[] = {
8289 CL_QUEUE_PROPERTIES, properties,
8290 0 };
8291 DeviceCommandQueue deviceQueue(
8292 ::clCreateCommandQueueWithProperties(
8293 context(), device(), queue_properties, &error));
8294
8295 detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR);
8296 if (err != NULL) {
8297 *err = error;
8298 }
8299
8300 return deviceQueue;
8301 }
8302
8303 /*!
8304 * Create a new default device command queue for the specified device
8305 * and of the requested size in bytes.
8306 * If there is already a default queue for the specified device this
8307 * function will return the pre-existing queue.
8308 */
8309 static DeviceCommandQueue makeDefault(
8310 const Context &context, const Device &device, cl_uint queueSize, cl_int *err = nullptr)
8311 {
8312 cl_int error;
8313
8314 cl_command_queue_properties properties =
8315 CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE | CL_QUEUE_ON_DEVICE | CL_QUEUE_ON_DEVICE_DEFAULT;
8316 cl_queue_properties queue_properties[] = {
8317 CL_QUEUE_PROPERTIES, properties,
8318 CL_QUEUE_SIZE, queueSize,
8319 0 };
8320 DeviceCommandQueue deviceQueue(
8321 ::clCreateCommandQueueWithProperties(
8322 context(), device(), queue_properties, &error));
8323
8324 detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR);
8325 if (err != NULL) {
8326 *err = error;
8327 }
8328
8329 return deviceQueue;
8330 }
8331}; // DeviceCommandQueue
8332
8333namespace detail
8334{
8335 // Specialization for device command queue
8336 template <>
8337 struct KernelArgumentHandler<cl::DeviceCommandQueue, void>
8338 {
8339 static size_type size(const cl::DeviceCommandQueue&) { return sizeof(cl_command_queue); }
8340 static const cl_command_queue* ptr(const cl::DeviceCommandQueue& value) { return &(value()); }
8341 };
8342} // namespace detail
8343
8344#endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 200
8345
8346
8347template< typename IteratorType >
8348Buffer::Buffer(
8349 const Context &context,
8350 IteratorType startIterator,
8351 IteratorType endIterator,
8352 bool readOnly,
8353 bool useHostPtr,
8354 cl_int* err)
8355{
8356 typedef typename std::iterator_traits<IteratorType>::value_type DataType;
8357 cl_int error;
8358
8359 cl_mem_flags flags = 0;
8360 if( readOnly ) {
8361 flags |= CL_MEM_READ_ONLY;
8362 }
8363 else {
8364 flags |= CL_MEM_READ_WRITE;
8365 }
8366 if( useHostPtr ) {
8367 flags |= CL_MEM_USE_HOST_PTR;
8368 }
8369
8370 size_type size = sizeof(DataType)*(endIterator - startIterator);
8371
8372 if( useHostPtr ) {
8373 object_ = ::clCreateBuffer(context(), flags, size, static_cast<DataType*>(&*startIterator), &error);
8374 } else {
8375 object_ = ::clCreateBuffer(context(), flags, size, 0, &error);
8376 }
8377
8378 detail::errHandler(error, __CREATE_BUFFER_ERR);
8379 if (err != NULL) {
8380 *err = error;
8381 }
8382
8383 if( !useHostPtr ) {
8384 CommandQueue queue(context, 0, &error);
8385 detail::errHandler(error, __CREATE_BUFFER_ERR);
8386 if (err != NULL) {
8387 *err = error;
8388 }
8389
8390 error = cl::copy(queue, startIterator, endIterator, *this);
8391 detail::errHandler(error, __CREATE_BUFFER_ERR);
8392 if (err != NULL) {
8393 *err = error;
8394 }
8395 }
8396}
8397
8398template< typename IteratorType >
8399Buffer::Buffer(
8400 const CommandQueue &queue,
8401 IteratorType startIterator,
8402 IteratorType endIterator,
8403 bool readOnly,
8404 bool useHostPtr,
8405 cl_int* err)
8406{
8407 typedef typename std::iterator_traits<IteratorType>::value_type DataType;
8408 cl_int error;
8409
8410 cl_mem_flags flags = 0;
8411 if (readOnly) {
8412 flags |= CL_MEM_READ_ONLY;
8413 }
8414 else {
8415 flags |= CL_MEM_READ_WRITE;
8416 }
8417 if (useHostPtr) {
8418 flags |= CL_MEM_USE_HOST_PTR;
8419 }
8420
8421 size_type size = sizeof(DataType)*(endIterator - startIterator);
8422
8423 Context context = queue.getInfo<CL_QUEUE_CONTEXT>();
8424
8425 if (useHostPtr) {
8426 object_ = ::clCreateBuffer(context(), flags, size, static_cast<DataType*>(&*startIterator), &error);
8427 }
8428 else {
8429 object_ = ::clCreateBuffer(context(), flags, size, 0, &error);
8430 }
8431
8432 detail::errHandler(error, __CREATE_BUFFER_ERR);
8433 if (err != NULL) {
8434 *err = error;
8435 }
8436
8437 if (!useHostPtr) {
8438 error = cl::copy(queue, startIterator, endIterator, *this);
8439 detail::errHandler(error, __CREATE_BUFFER_ERR);
8440 if (err != NULL) {
8441 *err = error;
8442 }
8443 }
8444}
8445
8446inline cl_int enqueueReadBuffer(
8447 const Buffer& buffer,
8448 cl_bool blocking,
8449 size_type offset,
8450 size_type size,
8451 void* ptr,
8452 const vector<Event>* events = NULL,
8453 Event* event = NULL)
8454{
8455 cl_int error;
8456 CommandQueue queue = CommandQueue::getDefault(&error);
8457
8458 if (error != CL_SUCCESS) {
8459 return error;
8460 }
8461
8462 return queue.enqueueReadBuffer(buffer, blocking, offset, size, ptr, events, event);
8463}
8464
8465inline cl_int enqueueWriteBuffer(
8466 const Buffer& buffer,
8467 cl_bool blocking,
8468 size_type offset,
8469 size_type size,
8470 const void* ptr,
8471 const vector<Event>* events = NULL,
8472 Event* event = NULL)
8473{
8474 cl_int error;
8475 CommandQueue queue = CommandQueue::getDefault(&error);
8476
8477 if (error != CL_SUCCESS) {
8478 return error;
8479 }
8480
8481 return queue.enqueueWriteBuffer(buffer, blocking, offset, size, ptr, events, event);
8482}
8483
8484inline void* enqueueMapBuffer(
8485 const Buffer& buffer,
8486 cl_bool blocking,
8487 cl_map_flags flags,
8488 size_type offset,
8489 size_type size,
8490 const vector<Event>* events = NULL,
8491 Event* event = NULL,
8492 cl_int* err = NULL)
8493{
8494 cl_int error;
8495 CommandQueue queue = CommandQueue::getDefault(&error);
8496 detail::errHandler(error, __ENQUEUE_MAP_BUFFER_ERR);
8497 if (err != NULL) {
8498 *err = error;
8499 }
8500
8501 void * result = ::clEnqueueMapBuffer(
8502 queue(), buffer(), blocking, flags, offset, size,
8503 (events != NULL) ? (cl_uint) events->size() : 0,
8504 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
8505 (cl_event*) event,
8506 &error);
8507
8508 detail::errHandler(error, __ENQUEUE_MAP_BUFFER_ERR);
8509 if (err != NULL) {
8510 *err = error;
8511 }
8512 return result;
8513}
8514
8515
8516#if CL_HPP_TARGET_OPENCL_VERSION >= 200
8517/**
8518 * Enqueues to the default queue a command that will allow the host to
8519 * update a region of a coarse-grained SVM buffer.
8520 * This variant takes a raw SVM pointer.
8521 */
8522template<typename T>
8523inline cl_int enqueueMapSVM(
8524 T* ptr,
8525 cl_bool blocking,
8526 cl_map_flags flags,
8527 size_type size,
8528 const vector<Event>* events,
8529 Event* event)
8530{
8531 cl_int error;
8532 CommandQueue queue = CommandQueue::getDefault(&error);
8533 if (error != CL_SUCCESS) {
8534 return detail::errHandler(error, __ENQUEUE_MAP_BUFFER_ERR);
8535 }
8536
8537 return queue.enqueueMapSVM(
8538 ptr, blocking, flags, size, events, event);
8539}
8540
8541/**
8542 * Enqueues to the default queue a command that will allow the host to
8543 * update a region of a coarse-grained SVM buffer.
8544 * This variant takes a cl::pointer instance.
8545 */
8546template<typename T, class D>
8547inline cl_int enqueueMapSVM(
8548 cl::pointer<T, D> ptr,
8549 cl_bool blocking,
8550 cl_map_flags flags,
8551 size_type size,
8552 const vector<Event>* events = NULL,
8553 Event* event = NULL)
8554{
8555 cl_int error;
8556 CommandQueue queue = CommandQueue::getDefault(&error);
8557 if (error != CL_SUCCESS) {
8558 return detail::errHandler(error, __ENQUEUE_MAP_BUFFER_ERR);
8559 }
8560
8561 return queue.enqueueMapSVM(
8562 ptr, blocking, flags, size, events, event);
8563}
8564
8565/**
8566 * Enqueues to the default queue a command that will allow the host to
8567 * update a region of a coarse-grained SVM buffer.
8568 * This variant takes a cl::vector instance.
8569 */
8570template<typename T, class Alloc>
8571inline cl_int enqueueMapSVM(
8572 cl::vector<T, Alloc> container,
8573 cl_bool blocking,
8574 cl_map_flags flags,
8575 const vector<Event>* events = NULL,
8576 Event* event = NULL)
8577{
8578 cl_int error;
8579 CommandQueue queue = CommandQueue::getDefault(&error);
8580 if (error != CL_SUCCESS) {
8581 return detail::errHandler(error, __ENQUEUE_MAP_BUFFER_ERR);
8582 }
8583
8584 return queue.enqueueMapSVM(
8585 container, blocking, flags, events, event);
8586}
8587
8588#endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 200
8589
8590inline cl_int enqueueUnmapMemObject(
8591 const Memory& memory,
8592 void* mapped_ptr,
8593 const vector<Event>* events = NULL,
8594 Event* event = NULL)
8595{
8596 cl_int error;
8597 CommandQueue queue = CommandQueue::getDefault(&error);
8598 detail::errHandler(error, __ENQUEUE_MAP_BUFFER_ERR);
8599 if (error != CL_SUCCESS) {
8600 return error;
8601 }
8602
8603 cl_event tmp;
8604 cl_int err = detail::errHandler(
8605 ::clEnqueueUnmapMemObject(
8606 queue(), memory(), mapped_ptr,
8607 (events != NULL) ? (cl_uint)events->size() : 0,
8608 (events != NULL && events->size() > 0) ? (cl_event*)&events->front() : NULL,
8609 (event != NULL) ? &tmp : NULL),
8610 __ENQUEUE_UNMAP_MEM_OBJECT_ERR);
8611
8612 if (event != NULL && err == CL_SUCCESS)
8613 *event = tmp;
8614
8615 return err;
8616}
8617
8618#if CL_HPP_TARGET_OPENCL_VERSION >= 200
8619/**
8620 * Enqueues to the default queue a command that will release a coarse-grained
8621 * SVM buffer back to the OpenCL runtime.
8622 * This variant takes a raw SVM pointer.
8623 */
8624template<typename T>
8625inline cl_int enqueueUnmapSVM(
8626 T* ptr,
8627 const vector<Event>* events = NULL,
8628 Event* event = NULL)
8629{
8630 cl_int error;
8631 CommandQueue queue = CommandQueue::getDefault(&error);
8632 if (error != CL_SUCCESS) {
8633 return detail::errHandler(error, __ENQUEUE_UNMAP_MEM_OBJECT_ERR);
8634 }
8635
8636 return detail::errHandler(queue.enqueueUnmapSVM(ptr, events, event),
8637 __ENQUEUE_UNMAP_MEM_OBJECT_ERR);
8638
8639}
8640
8641/**
8642 * Enqueues to the default queue a command that will release a coarse-grained
8643 * SVM buffer back to the OpenCL runtime.
8644 * This variant takes a cl::pointer instance.
8645 */
8646template<typename T, class D>
8647inline cl_int enqueueUnmapSVM(
8648 cl::pointer<T, D> &ptr,
8649 const vector<Event>* events = NULL,
8650 Event* event = NULL)
8651{
8652 cl_int error;
8653 CommandQueue queue = CommandQueue::getDefault(&error);
8654 if (error != CL_SUCCESS) {
8655 return detail::errHandler(error, __ENQUEUE_UNMAP_MEM_OBJECT_ERR);
8656 }
8657
8658 return detail::errHandler(queue.enqueueUnmapSVM(ptr, events, event),
8659 __ENQUEUE_UNMAP_MEM_OBJECT_ERR);
8660}
8661
8662/**
8663 * Enqueues to the default queue a command that will release a coarse-grained
8664 * SVM buffer back to the OpenCL runtime.
8665 * This variant takes a cl::vector instance.
8666 */
8667template<typename T, class Alloc>
8668inline cl_int enqueueUnmapSVM(
8669 cl::vector<T, Alloc> &container,
8670 const vector<Event>* events = NULL,
8671 Event* event = NULL)
8672{
8673 cl_int error;
8674 CommandQueue queue = CommandQueue::getDefault(&error);
8675 if (error != CL_SUCCESS) {
8676 return detail::errHandler(error, __ENQUEUE_UNMAP_MEM_OBJECT_ERR);
8677 }
8678
8679 return detail::errHandler(queue.enqueueUnmapSVM(container, events, event),
8680 __ENQUEUE_UNMAP_MEM_OBJECT_ERR);
8681}
8682
8683#endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 200
8684
8685inline cl_int enqueueCopyBuffer(
8686 const Buffer& src,
8687 const Buffer& dst,
8688 size_type src_offset,
8689 size_type dst_offset,
8690 size_type size,
8691 const vector<Event>* events = NULL,
8692 Event* event = NULL)
8693{
8694 cl_int error;
8695 CommandQueue queue = CommandQueue::getDefault(&error);
8696
8697 if (error != CL_SUCCESS) {
8698 return error;
8699 }
8700
8701 return queue.enqueueCopyBuffer(src, dst, src_offset, dst_offset, size, events, event);
8702}
8703
8704/**
8705 * Blocking copy operation between iterators and a buffer.
8706 * Host to Device.
8707 * Uses default command queue.
8708 */
8709template< typename IteratorType >
8710inline cl_int copy( IteratorType startIterator, IteratorType endIterator, cl::Buffer &buffer )
8711{
8712 cl_int error;
8713 CommandQueue queue = CommandQueue::getDefault(&error);
8714 if (error != CL_SUCCESS)
8715 return error;
8716
8717 return cl::copy(queue, startIterator, endIterator, buffer);
8718}
8719
8720/**
8721 * Blocking copy operation between iterators and a buffer.
8722 * Device to Host.
8723 * Uses default command queue.
8724 */
8725template< typename IteratorType >
8726inline cl_int copy( const cl::Buffer &buffer, IteratorType startIterator, IteratorType endIterator )
8727{
8728 cl_int error;
8729 CommandQueue queue = CommandQueue::getDefault(&error);
8730 if (error != CL_SUCCESS)
8731 return error;
8732
8733 return cl::copy(queue, buffer, startIterator, endIterator);
8734}
8735
8736/**
8737 * Blocking copy operation between iterators and a buffer.
8738 * Host to Device.
8739 * Uses specified queue.
8740 */
8741template< typename IteratorType >
8742inline cl_int copy( const CommandQueue &queue, IteratorType startIterator, IteratorType endIterator, cl::Buffer &buffer )
8743{
8744 typedef typename std::iterator_traits<IteratorType>::value_type DataType;
8745 cl_int error;
8746
8747 size_type length = endIterator-startIterator;
8748 size_type byteLength = length*sizeof(DataType);
8749
8750 DataType *pointer =
8751 static_cast<DataType*>(queue.enqueueMapBuffer(buffer, CL_TRUE, CL_MAP_WRITE, 0, byteLength, 0, 0, &error));
8752 // if exceptions enabled, enqueueMapBuffer will throw
8753 if( error != CL_SUCCESS ) {
8754 return error;
8755 }
8756#if defined(_MSC_VER)
8757 std::copy(
8758 startIterator,
8759 endIterator,
8760 stdext::checked_array_iterator<DataType*>(
8761 pointer, length));
8762#else
8763 std::copy(startIterator, endIterator, pointer);
8764#endif
8765 Event endEvent;
8766 error = queue.enqueueUnmapMemObject(buffer, pointer, 0, &endEvent);
8767 // if exceptions enabled, enqueueUnmapMemObject will throw
8768 if( error != CL_SUCCESS ) {
8769 return error;
8770 }
8771 endEvent.wait();
8772 return CL_SUCCESS;
8773}
8774
8775/**
8776 * Blocking copy operation between iterators and a buffer.
8777 * Device to Host.
8778 * Uses specified queue.
8779 */
8780template< typename IteratorType >
8781inline cl_int copy( const CommandQueue &queue, const cl::Buffer &buffer, IteratorType startIterator, IteratorType endIterator )
8782{
8783 typedef typename std::iterator_traits<IteratorType>::value_type DataType;
8784 cl_int error;
8785
8786 size_type length = endIterator-startIterator;
8787 size_type byteLength = length*sizeof(DataType);
8788
8789 DataType *pointer =
8790 static_cast<DataType*>(queue.enqueueMapBuffer(buffer, CL_TRUE, CL_MAP_READ, 0, byteLength, 0, 0, &error));
8791 // if exceptions enabled, enqueueMapBuffer will throw
8792 if( error != CL_SUCCESS ) {
8793 return error;
8794 }
8795 std::copy(pointer, pointer + length, startIterator);
8796 Event endEvent;
8797 error = queue.enqueueUnmapMemObject(buffer, pointer, 0, &endEvent);
8798 // if exceptions enabled, enqueueUnmapMemObject will throw
8799 if( error != CL_SUCCESS ) {
8800 return error;
8801 }
8802 endEvent.wait();
8803 return CL_SUCCESS;
8804}
8805
8806
8807#if CL_HPP_TARGET_OPENCL_VERSION >= 200
8808/**
8809 * Blocking SVM map operation - performs a blocking map underneath.
8810 */
8811template<typename T, class Alloc>
8812inline cl_int mapSVM(cl::vector<T, Alloc> &container)
8813{
8814 return enqueueMapSVM(container, CL_TRUE, CL_MAP_READ | CL_MAP_WRITE);
8815}
8816
8817/**
8818* Blocking SVM map operation - performs a blocking map underneath.
8819*/
8820template<typename T, class Alloc>
8821inline cl_int unmapSVM(cl::vector<T, Alloc> &container)
8822{
8823 return enqueueUnmapSVM(container);
8824}
8825
8826#endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 200
8827
8828#if CL_HPP_TARGET_OPENCL_VERSION >= 110
8829inline cl_int enqueueReadBufferRect(
8830 const Buffer& buffer,
8831 cl_bool blocking,
8832 const array<size_type, 3>& buffer_offset,
8833 const array<size_type, 3>& host_offset,
8834 const array<size_type, 3>& region,
8835 size_type buffer_row_pitch,
8836 size_type buffer_slice_pitch,
8837 size_type host_row_pitch,
8838 size_type host_slice_pitch,
8839 void *ptr,
8840 const vector<Event>* events = NULL,
8841 Event* event = NULL)
8842{
8843 cl_int error;
8844 CommandQueue queue = CommandQueue::getDefault(&error);
8845
8846 if (error != CL_SUCCESS) {
8847 return error;
8848 }
8849
8850 return queue.enqueueReadBufferRect(
8851 buffer,
8852 blocking,
8853 buffer_offset,
8854 host_offset,
8855 region,
8856 buffer_row_pitch,
8857 buffer_slice_pitch,
8858 host_row_pitch,
8859 host_slice_pitch,
8860 ptr,
8861 events,
8862 event);
8863}
8864
8865inline cl_int enqueueWriteBufferRect(
8866 const Buffer& buffer,
8867 cl_bool blocking,
8868 const array<size_type, 3>& buffer_offset,
8869 const array<size_type, 3>& host_offset,
8870 const array<size_type, 3>& region,
8871 size_type buffer_row_pitch,
8872 size_type buffer_slice_pitch,
8873 size_type host_row_pitch,
8874 size_type host_slice_pitch,
8875 void *ptr,
8876 const vector<Event>* events = NULL,
8877 Event* event = NULL)
8878{
8879 cl_int error;
8880 CommandQueue queue = CommandQueue::getDefault(&error);
8881
8882 if (error != CL_SUCCESS) {
8883 return error;
8884 }
8885
8886 return queue.enqueueWriteBufferRect(
8887 buffer,
8888 blocking,
8889 buffer_offset,
8890 host_offset,
8891 region,
8892 buffer_row_pitch,
8893 buffer_slice_pitch,
8894 host_row_pitch,
8895 host_slice_pitch,
8896 ptr,
8897 events,
8898 event);
8899}
8900
8901inline cl_int enqueueCopyBufferRect(
8902 const Buffer& src,
8903 const Buffer& dst,
8904 const array<size_type, 3>& src_origin,
8905 const array<size_type, 3>& dst_origin,
8906 const array<size_type, 3>& region,
8907 size_type src_row_pitch,
8908 size_type src_slice_pitch,
8909 size_type dst_row_pitch,
8910 size_type dst_slice_pitch,
8911 const vector<Event>* events = NULL,
8912 Event* event = NULL)
8913{
8914 cl_int error;
8915 CommandQueue queue = CommandQueue::getDefault(&error);
8916
8917 if (error != CL_SUCCESS) {
8918 return error;
8919 }
8920
8921 return queue.enqueueCopyBufferRect(
8922 src,
8923 dst,
8924 src_origin,
8925 dst_origin,
8926 region,
8927 src_row_pitch,
8928 src_slice_pitch,
8929 dst_row_pitch,
8930 dst_slice_pitch,
8931 events,
8932 event);
8933}
8934#endif // CL_HPP_TARGET_OPENCL_VERSION >= 110
8935
8936inline cl_int enqueueReadImage(
8937 const Image& image,
8938 cl_bool blocking,
8939 const array<size_type, 3>& origin,
8940 const array<size_type, 3>& region,
8941 size_type row_pitch,
8942 size_type slice_pitch,
8943 void* ptr,
8944 const vector<Event>* events = NULL,
8945 Event* event = NULL)
8946{
8947 cl_int error;
8948 CommandQueue queue = CommandQueue::getDefault(&error);
8949
8950 if (error != CL_SUCCESS) {
8951 return error;
8952 }
8953
8954 return queue.enqueueReadImage(
8955 image,
8956 blocking,
8957 origin,
8958 region,
8959 row_pitch,
8960 slice_pitch,
8961 ptr,
8962 events,
8963 event);
8964}
8965
8966inline cl_int enqueueWriteImage(
8967 const Image& image,
8968 cl_bool blocking,
8969 const array<size_type, 3>& origin,
8970 const array<size_type, 3>& region,
8971 size_type row_pitch,
8972 size_type slice_pitch,
8973 void* ptr,
8974 const vector<Event>* events = NULL,
8975 Event* event = NULL)
8976{
8977 cl_int error;
8978 CommandQueue queue = CommandQueue::getDefault(&error);
8979
8980 if (error != CL_SUCCESS) {
8981 return error;
8982 }
8983
8984 return queue.enqueueWriteImage(
8985 image,
8986 blocking,
8987 origin,
8988 region,
8989 row_pitch,
8990 slice_pitch,
8991 ptr,
8992 events,
8993 event);
8994}
8995
8996inline cl_int enqueueCopyImage(
8997 const Image& src,
8998 const Image& dst,
8999 const array<size_type, 3>& src_origin,
9000 const array<size_type, 3>& dst_origin,
9001 const array<size_type, 3>& region,
9002 const vector<Event>* events = NULL,
9003 Event* event = NULL)
9004{
9005 cl_int error;
9006 CommandQueue queue = CommandQueue::getDefault(&error);
9007
9008 if (error != CL_SUCCESS) {
9009 return error;
9010 }
9011
9012 return queue.enqueueCopyImage(
9013 src,
9014 dst,
9015 src_origin,
9016 dst_origin,
9017 region,
9018 events,
9019 event);
9020}
9021
9022inline cl_int enqueueCopyImageToBuffer(
9023 const Image& src,
9024 const Buffer& dst,
9025 const array<size_type, 3>& src_origin,
9026 const array<size_type, 3>& region,
9027 size_type dst_offset,
9028 const vector<Event>* events = NULL,
9029 Event* event = NULL)
9030{
9031 cl_int error;
9032 CommandQueue queue = CommandQueue::getDefault(&error);
9033
9034 if (error != CL_SUCCESS) {
9035 return error;
9036 }
9037
9038 return queue.enqueueCopyImageToBuffer(
9039 src,
9040 dst,
9041 src_origin,
9042 region,
9043 dst_offset,
9044 events,
9045 event);
9046}
9047
9048inline cl_int enqueueCopyBufferToImage(
9049 const Buffer& src,
9050 const Image& dst,
9051 size_type src_offset,
9052 const array<size_type, 3>& dst_origin,
9053 const array<size_type, 3>& region,
9054 const vector<Event>* events = NULL,
9055 Event* event = NULL)
9056{
9057 cl_int error;
9058 CommandQueue queue = CommandQueue::getDefault(&error);
9059
9060 if (error != CL_SUCCESS) {
9061 return error;
9062 }
9063
9064 return queue.enqueueCopyBufferToImage(
9065 src,
9066 dst,
9067 src_offset,
9068 dst_origin,
9069 region,
9070 events,
9071 event);
9072}
9073
9074
9075inline cl_int flush(void)
9076{
9077 cl_int error;
9078 CommandQueue queue = CommandQueue::getDefault(&error);
9079
9080 if (error != CL_SUCCESS) {
9081 return error;
9082 }
9083
9084 return queue.flush();
9085}
9086
9087inline cl_int finish(void)
9088{
9089 cl_int error;
9090 CommandQueue queue = CommandQueue::getDefault(&error);
9091
9092 if (error != CL_SUCCESS) {
9093 return error;
9094 }
9095
9096
9097 return queue.finish();
9098}
9099
9100class EnqueueArgs
9101{
9102private:
9103 CommandQueue queue_;
9104 const NDRange offset_;
9105 const NDRange global_;
9106 const NDRange local_;
9107 vector<Event> events_;
9108
9109 template<typename... Ts>
9110 friend class KernelFunctor;
9111
9112public:
9113 EnqueueArgs(NDRange global) :
9114 queue_(CommandQueue::getDefault()),
9115 offset_(NullRange),
9116 global_(global),
9117 local_(NullRange)
9118 {
9119
9120 }
9121
9122 EnqueueArgs(NDRange global, NDRange local) :
9123 queue_(CommandQueue::getDefault()),
9124 offset_(NullRange),
9125 global_(global),
9126 local_(local)
9127 {
9128
9129 }
9130
9131 EnqueueArgs(NDRange offset, NDRange global, NDRange local) :
9132 queue_(CommandQueue::getDefault()),
9133 offset_(offset),
9134 global_(global),
9135 local_(local)
9136 {
9137
9138 }
9139
9140 EnqueueArgs(Event e, NDRange global) :
9141 queue_(CommandQueue::getDefault()),
9142 offset_(NullRange),
9143 global_(global),
9144 local_(NullRange)
9145 {
9146 events_.push_back(e);
9147 }
9148
9149 EnqueueArgs(Event e, NDRange global, NDRange local) :
9150 queue_(CommandQueue::getDefault()),
9151 offset_(NullRange),
9152 global_(global),
9153 local_(local)
9154 {
9155 events_.push_back(e);
9156 }
9157
9158 EnqueueArgs(Event e, NDRange offset, NDRange global, NDRange local) :
9159 queue_(CommandQueue::getDefault()),
9160 offset_(offset),
9161 global_(global),
9162 local_(local)
9163 {
9164 events_.push_back(e);
9165 }
9166
9167 EnqueueArgs(const vector<Event> &events, NDRange global) :
9168 queue_(CommandQueue::getDefault()),
9169 offset_(NullRange),
9170 global_(global),
9171 local_(NullRange),
9172 events_(events)
9173 {
9174
9175 }
9176
9177 EnqueueArgs(const vector<Event> &events, NDRange global, NDRange local) :
9178 queue_(CommandQueue::getDefault()),
9179 offset_(NullRange),
9180 global_(global),
9181 local_(local),
9182 events_(events)
9183 {
9184
9185 }
9186
9187 EnqueueArgs(const vector<Event> &events, NDRange offset, NDRange global, NDRange local) :
9188 queue_(CommandQueue::getDefault()),
9189 offset_(offset),
9190 global_(global),
9191 local_(local),
9192 events_(events)
9193 {
9194
9195 }
9196
9197 EnqueueArgs(CommandQueue &queue, NDRange global) :
9198 queue_(queue),
9199 offset_(NullRange),
9200 global_(global),
9201 local_(NullRange)
9202 {
9203
9204 }
9205
9206 EnqueueArgs(CommandQueue &queue, NDRange global, NDRange local) :
9207 queue_(queue),
9208 offset_(NullRange),
9209 global_(global),
9210 local_(local)
9211 {
9212
9213 }
9214
9215 EnqueueArgs(CommandQueue &queue, NDRange offset, NDRange global, NDRange local) :
9216 queue_(queue),
9217 offset_(offset),
9218 global_(global),
9219 local_(local)
9220 {
9221
9222 }
9223
9224 EnqueueArgs(CommandQueue &queue, Event e, NDRange global) :
9225 queue_(queue),
9226 offset_(NullRange),
9227 global_(global),
9228 local_(NullRange)
9229 {
9230 events_.push_back(e);
9231 }
9232
9233 EnqueueArgs(CommandQueue &queue, Event e, NDRange global, NDRange local) :
9234 queue_(queue),
9235 offset_(NullRange),
9236 global_(global),
9237 local_(local)
9238 {
9239 events_.push_back(e);
9240 }
9241
9242 EnqueueArgs(CommandQueue &queue, Event e, NDRange offset, NDRange global, NDRange local) :
9243 queue_(queue),
9244 offset_(offset),
9245 global_(global),
9246 local_(local)
9247 {
9248 events_.push_back(e);
9249 }
9250
9251 EnqueueArgs(CommandQueue &queue, const vector<Event> &events, NDRange global) :
9252 queue_(queue),
9253 offset_(NullRange),
9254 global_(global),
9255 local_(NullRange),
9256 events_(events)
9257 {
9258
9259 }
9260
9261 EnqueueArgs(CommandQueue &queue, const vector<Event> &events, NDRange global, NDRange local) :
9262 queue_(queue),
9263 offset_(NullRange),
9264 global_(global),
9265 local_(local),
9266 events_(events)
9267 {
9268
9269 }
9270
9271 EnqueueArgs(CommandQueue &queue, const vector<Event> &events, NDRange offset, NDRange global, NDRange local) :
9272 queue_(queue),
9273 offset_(offset),
9274 global_(global),
9275 local_(local),
9276 events_(events)
9277 {
9278
9279 }
9280};
9281
9282
9283//----------------------------------------------------------------------------------------------
9284
9285
9286/**
9287 * Type safe kernel functor.
9288 *
9289 */
9290template<typename... Ts>
9291class KernelFunctor
9292{
9293private:
9294 Kernel kernel_;
9295
9296 template<int index, typename T0, typename... T1s>
9297 void setArgs(T0&& t0, T1s&&... t1s)
9298 {
9299 kernel_.setArg(index, t0);
9300 setArgs<index + 1, T1s...>(std::forward<T1s>(t1s)...);
9301 }
9302
9303 template<int index, typename T0>
9304 void setArgs(T0&& t0)
9305 {
9306 kernel_.setArg(index, t0);
9307 }
9308
9309 template<int index>
9310 void setArgs()
9311 {
9312 }
9313
9314
9315public:
9316 KernelFunctor(Kernel kernel) : kernel_(kernel)
9317 {}
9318
9319 KernelFunctor(
9320 const Program& program,
9321 const string name,
9322 cl_int * err = NULL) :
9323 kernel_(program, name.c_str(), err)
9324 {}
9325
9326 //! \brief Return type of the functor
9327 typedef Event result_type;
9328
9329 /**
9330 * Enqueue kernel.
9331 * @param args Launch parameters of the kernel.
9332 * @param t0... List of kernel arguments based on the template type of the functor.
9333 */
9334 Event operator() (
9335 const EnqueueArgs& args,
9336 Ts... ts)
9337 {
9338 Event event;
9339 setArgs<0>(std::forward<Ts>(ts)...);
9340
9341 args.queue_.enqueueNDRangeKernel(
9342 kernel_,
9343 args.offset_,
9344 args.global_,
9345 args.local_,
9346 &args.events_,
9347 &event);
9348
9349 return event;
9350 }
9351
9352 /**
9353 * Enqueue kernel with support for error code.
9354 * @param args Launch parameters of the kernel.
9355 * @param t0... List of kernel arguments based on the template type of the functor.
9356 * @param error Out parameter returning the error code from the execution.
9357 */
9358 Event operator() (
9359 const EnqueueArgs& args,
9360 Ts... ts,
9361 cl_int &error)
9362 {
9363 Event event;
9364 setArgs<0>(std::forward<Ts>(ts)...);
9365
9366 error = args.queue_.enqueueNDRangeKernel(
9367 kernel_,
9368 args.offset_,
9369 args.global_,
9370 args.local_,
9371 &args.events_,
9372 &event);
9373
9374 return event;
9375 }
9376
9377#if CL_HPP_TARGET_OPENCL_VERSION >= 200
9378 cl_int setSVMPointers(const vector<void*> &pointerList)
9379 {
9380 return kernel_.setSVMPointers(pointerList);
9381 }
9382
9383 template<typename T0, typename... T1s>
9384 cl_int setSVMPointers(const T0 &t0, T1s... ts)
9385 {
9386 return kernel_.setSVMPointers(t0, ts...);
9387 }
9388#endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 200
9389
9390 Kernel getKernel()
9391 {
9392 return kernel_;
9393 }
9394};
9395
9396namespace compatibility {
9397 /**
9398 * Backward compatibility class to ensure that cl.hpp code works with cl2.hpp.
9399 * Please use KernelFunctor directly.
9400 */
9401 template<typename... Ts>
9402 struct make_kernel
9403 {
9404 typedef KernelFunctor<Ts...> FunctorType;
9405
9406 FunctorType functor_;
9407
9408 make_kernel(
9409 const Program& program,
9410 const string name,
9411 cl_int * err = NULL) :
9412 functor_(FunctorType(program, name, err))
9413 {}
9414
9415 make_kernel(
9416 const Kernel kernel) :
9417 functor_(FunctorType(kernel))
9418 {}
9419
9420 //! \brief Return type of the functor
9421 typedef Event result_type;
9422
9423 //! \brief Function signature of kernel functor with no event dependency.
9424 typedef Event type_(
9425 const EnqueueArgs&,
9426 Ts...);
9427
9428 Event operator()(
9429 const EnqueueArgs& enqueueArgs,
9430 Ts... args)
9431 {
9432 return functor_(
9433 enqueueArgs, args...);
9434 }
9435 };
9436} // namespace compatibility
9437
9438
9439//----------------------------------------------------------------------------------------------------------------------
9440
9441#undef CL_HPP_ERR_STR_
9442#if !defined(CL_HPP_USER_OVERRIDE_ERROR_STRINGS)
9443#undef __GET_DEVICE_INFO_ERR
9444#undef __GET_PLATFORM_INFO_ERR
9445#undef __GET_DEVICE_IDS_ERR
9446#undef __GET_CONTEXT_INFO_ERR
9447#undef __GET_EVENT_INFO_ERR
9448#undef __GET_EVENT_PROFILE_INFO_ERR
9449#undef __GET_MEM_OBJECT_INFO_ERR
9450#undef __GET_IMAGE_INFO_ERR
9451#undef __GET_SAMPLER_INFO_ERR
9452#undef __GET_KERNEL_INFO_ERR
9453#undef __GET_KERNEL_ARG_INFO_ERR
9454#undef __GET_KERNEL_WORK_GROUP_INFO_ERR
9455#undef __GET_PROGRAM_INFO_ERR
9456#undef __GET_PROGRAM_BUILD_INFO_ERR
9457#undef __GET_COMMAND_QUEUE_INFO_ERR
9458
9459#undef __CREATE_CONTEXT_ERR
9460#undef __CREATE_CONTEXT_FROM_TYPE_ERR
9461#undef __GET_SUPPORTED_IMAGE_FORMATS_ERR
9462
9463#undef __CREATE_BUFFER_ERR
9464#undef __CREATE_SUBBUFFER_ERR
9465#undef __CREATE_IMAGE2D_ERR
9466#undef __CREATE_IMAGE3D_ERR
9467#undef __CREATE_SAMPLER_ERR
9468#undef __SET_MEM_OBJECT_DESTRUCTOR_CALLBACK_ERR
9469
9470#undef __CREATE_USER_EVENT_ERR
9471#undef __SET_USER_EVENT_STATUS_ERR
9472#undef __SET_EVENT_CALLBACK_ERR
9473#undef __SET_PRINTF_CALLBACK_ERR
9474
9475#undef __WAIT_FOR_EVENTS_ERR
9476
9477#undef __CREATE_KERNEL_ERR
9478#undef __SET_KERNEL_ARGS_ERR
9479#undef __CREATE_PROGRAM_WITH_SOURCE_ERR
9480#undef __CREATE_PROGRAM_WITH_BINARY_ERR
9481#undef __CREATE_PROGRAM_WITH_BUILT_IN_KERNELS_ERR
9482#undef __BUILD_PROGRAM_ERR
9483#undef __CREATE_KERNELS_IN_PROGRAM_ERR
9484
9485#undef __CREATE_COMMAND_QUEUE_ERR
9486#undef __SET_COMMAND_QUEUE_PROPERTY_ERR
9487#undef __ENQUEUE_READ_BUFFER_ERR
9488#undef __ENQUEUE_WRITE_BUFFER_ERR
9489#undef __ENQUEUE_READ_BUFFER_RECT_ERR
9490#undef __ENQUEUE_WRITE_BUFFER_RECT_ERR
9491#undef __ENQEUE_COPY_BUFFER_ERR
9492#undef __ENQEUE_COPY_BUFFER_RECT_ERR
9493#undef __ENQUEUE_READ_IMAGE_ERR
9494#undef __ENQUEUE_WRITE_IMAGE_ERR
9495#undef __ENQUEUE_COPY_IMAGE_ERR
9496#undef __ENQUEUE_COPY_IMAGE_TO_BUFFER_ERR
9497#undef __ENQUEUE_COPY_BUFFER_TO_IMAGE_ERR
9498#undef __ENQUEUE_MAP_BUFFER_ERR
9499#undef __ENQUEUE_MAP_IMAGE_ERR
9500#undef __ENQUEUE_UNMAP_MEM_OBJECT_ERR
9501#undef __ENQUEUE_NDRANGE_KERNEL_ERR
9502#undef __ENQUEUE_TASK_ERR
9503#undef __ENQUEUE_NATIVE_KERNEL
9504
9505#undef __UNLOAD_COMPILER_ERR
9506#undef __CREATE_SUB_DEVICES_ERR
9507
9508#undef __CREATE_PIPE_ERR
9509#undef __GET_PIPE_INFO_ERR
9510
9511#endif //CL_HPP_USER_OVERRIDE_ERROR_STRINGS
9512
9513// Extensions
9514#undef CL_HPP_INIT_CL_EXT_FCN_PTR_
9515#undef CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_
9516
9517#if defined(CL_HPP_USE_CL_DEVICE_FISSION)
9518#undef CL_HPP_PARAM_NAME_DEVICE_FISSION_
9519#endif // CL_HPP_USE_CL_DEVICE_FISSION
9520
9521#undef CL_HPP_NOEXCEPT_
9522#undef CL_HPP_DEFINE_STATIC_MEMBER_
9523
9524} // namespace cl
9525
9526#endif // CL_HPP_