codekingpro/portable-devtools
114k
1//
2// Copyright (c) 2008-2023 The Khronos Group Inc.
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
16
17/*! \file
18 *
19 * \brief C++ bindings for OpenCL 1.0, OpenCL 1.1, OpenCL 1.2,
20 * OpenCL 2.0, OpenCL 2.1, OpenCL 2.2, and OpenCL 3.0.
21 * \author Lee Howes and Bruce Merry
22 *
23 * Derived from the OpenCL 1.x C++ bindings written by
24 * Benedict R. Gaster, Laurent Morichetti and Lee Howes
25 * With additions and fixes from:
26 * Brian Cole, March 3rd 2010 and April 2012
27 * Matt Gruenke, April 2012.
28 * Bruce Merry, February 2013.
29 * Tom Deakin and Simon McIntosh-Smith, July 2013
30 * James Price, 2015-
31 * \version 2.2.0
32 * \date 2019-09-18
33 *
34 * Optional extension support
35 *
36 * cl_khr_d3d10_sharing
37 * #define CL_HPP_USE_DX_INTEROP
38 * cl_khr_il_program
39 * #define CL_HPP_USE_IL_KHR
40 * cl_khr_sub_groups
41 * #define CL_HPP_USE_CL_SUB_GROUPS_KHR
42 *
43 * Doxygen documentation for this header is available here:
44 *
45 * http://khronosgroup.github.io/OpenCL-CLHPP/
46 *
47 * The latest version of this header can be found on the GitHub releases page:
48 *
49 * https://github.com/KhronosGroup/OpenCL-CLHPP/releases
50 *
51 * Bugs and patches can be submitted to the GitHub repository:
52 *
53 * https://github.com/KhronosGroup/OpenCL-CLHPP
54 */
55
56/*! \mainpage
57 * \section intro Introduction
58 * For many large applications C++ is the language of choice and so it seems
59 * reasonable to define C++ bindings for OpenCL.
60 *
61 * The interface is contained with a single C++ header file \em opencl.hpp and all
62 * definitions are contained within the namespace \em cl. There is no additional
63 * requirement to include \em cl.h and to use either the C++ or original C
64 * bindings; it is enough to simply include \em opencl.hpp.
65 *
66 * The bindings themselves are lightweight and correspond closely to the
67 * underlying C API. Using the C++ bindings introduces no additional execution
68 * overhead.
69 *
70 * There are numerous compatibility, portability and memory management
71 * fixes in the new header as well as additional OpenCL 2.0 features.
72 * As a result the header is not directly backward compatible and for this
73 * reason we release it as opencl.hpp rather than a new version of cl.hpp.
74 *
75 *
76 * \section compatibility Compatibility
77 * Due to the evolution of the underlying OpenCL API the 2.0 C++ bindings
78 * include an updated approach to defining supported feature versions
79 * and the range of valid underlying OpenCL runtime versions supported.
80 *
81 * The combination of preprocessor macros CL_HPP_TARGET_OPENCL_VERSION and
82 * CL_HPP_MINIMUM_OPENCL_VERSION control this range. These are three digit
83 * decimal values representing OpenCL runtime versions. The default for
84 * the target is 300, representing OpenCL 3.0. The minimum is defined as 200.
85 * These settings would use 2.0 and newer API calls only.
86 * If backward compatibility with a 1.2 runtime is required, the minimum
87 * version may be set to 120.
88 *
89 * Note that this is a compile-time setting, and so affects linking against
90 * a particular SDK version rather than the versioning of the loaded runtime.
91 *
92 * The earlier versions of the header included basic vector and string
93 * classes based loosely on STL versions. These were difficult to
94 * maintain and very rarely used. For the 2.0 header we now assume
95 * the presence of the standard library unless requested otherwise.
96 * We use std::array, std::vector, std::shared_ptr and std::string
97 * throughout to safely manage memory and reduce the chance of a
98 * recurrance of earlier memory management bugs.
99 *
100 * These classes are used through typedefs in the cl namespace:
101 * cl::array, cl::vector, cl::pointer and cl::string.
102 * In addition cl::allocate_pointer forwards to std::allocate_shared
103 * by default.
104 * In all cases these standard library classes can be replaced with
105 * custom interface-compatible versions using the CL_HPP_NO_STD_ARRAY,
106 * CL_HPP_NO_STD_VECTOR, CL_HPP_NO_STD_UNIQUE_PTR and
107 * CL_HPP_NO_STD_STRING macros.
108 *
109 * The OpenCL 1.x versions of the C++ bindings included a size_t wrapper
110 * class to interface with kernel enqueue. This caused unpleasant interactions
111 * with the standard size_t declaration and led to namespacing bugs.
112 * In the 2.0 version we have replaced this with a std::array-based interface.
113 * However, the old behaviour can be regained for backward compatibility
114 * using the CL_HPP_ENABLE_SIZE_T_COMPATIBILITY macro.
115 *
116 * Finally, the program construction interface used a clumsy vector-of-pairs
117 * design in the earlier versions. We have replaced that with a cleaner
118 * vector-of-vectors and vector-of-strings design. However, for backward
119 * compatibility old behaviour can be regained with the
120 * CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY macro.
121 *
122 * In OpenCL 2.0 OpenCL C is not entirely backward compatibility with
123 * earlier versions. As a result a flag must be passed to the OpenCL C
124 * compiled to request OpenCL 2.0 compilation of kernels with 1.2 as
125 * the default in the absence of the flag.
126 * In some cases the C++ bindings automatically compile code for ease.
127 * For those cases the compilation defaults to OpenCL C 2.0.
128 * If this is not wanted, the CL_HPP_CL_1_2_DEFAULT_BUILD macro may
129 * be specified to assume 1.2 compilation.
130 * If more fine-grained decisions on a per-kernel bases are required
131 * then explicit build operations that take the flag should be used.
132 *
133 *
134 * \section parameterization Parameters
135 * This header may be parameterized by a set of preprocessor macros.
136 *
137 * - CL_HPP_TARGET_OPENCL_VERSION
138 *
139 * Defines the target OpenCL runtime version to build the header
140 * against. Defaults to 300, representing OpenCL 3.0.
141 *
142 * - CL_HPP_MINIMUM_OPENCL_VERSION
143 *
144 * Defines the minimum OpenCL runtime version to build the header
145 * against. Defaults to 200, representing OpenCL 2.0.
146 *
147 * - CL_HPP_NO_STD_STRING
148 *
149 * Do not use the standard library string class. cl::string is not
150 * defined and may be defined by the user before opencl.hpp is
151 * included.
152 *
153 * - CL_HPP_NO_STD_VECTOR
154 *
155 * Do not use the standard library vector class. cl::vector is not
156 * defined and may be defined by the user before opencl.hpp is
157 * included.
158 *
159 * - CL_HPP_NO_STD_ARRAY
160 *
161 * Do not use the standard library array class. cl::array is not
162 * defined and may be defined by the user before opencl.hpp is
163 * included.
164 *
165 * - CL_HPP_NO_STD_UNIQUE_PTR
166 *
167 * Do not use the standard library unique_ptr class. cl::pointer and
168 * the cl::allocate_pointer functions are not defined and may be
169 * defined by the user before opencl.hpp is included.
170 *
171 * - CL_HPP_ENABLE_EXCEPTIONS
172 *
173 * Enable exceptions for use in the C++ bindings header. This is the
174 * preferred error handling mechanism but is not required.
175 *
176 * - CL_HPP_ENABLE_SIZE_T_COMPATIBILITY
177 *
178 * Backward compatibility option to support cl.hpp-style size_t
179 * class. Replaces the updated std::array derived version and
180 * removal of size_t from the namespace. Note that in this case the
181 * new size_t class is placed in the cl::compatibility namespace and
182 * thus requires an additional using declaration for direct backward
183 * compatibility.
184 *
185 * - CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY
186 *
187 * Enable older vector of pairs interface for construction of
188 * programs.
189 *
190 * - CL_HPP_CL_1_2_DEFAULT_BUILD
191 *
192 * Default to OpenCL C 1.2 compilation rather than OpenCL C 2.0
193 * applies to use of cl::Program construction and other program
194 * build variants.
195 *
196 *
197 * - CL_HPP_USE_CL_SUB_GROUPS_KHR
198 *
199 * Enable the cl_khr_subgroups extension.
200 *
201 * - CL_HPP_USE_DX_INTEROP
202 *
203 * Enable the cl_khr_d3d10_sharing extension.
204 *
205 * - CL_HPP_USE_IL_KHR
206 *
207 * Enable the cl_khr_il_program extension.
208 *
209 *
210 * \section example Example
211 *
212 * The following example shows a general use case for the C++
213 * bindings, including support for the optional exception feature and
214 * also the supplied vector and string classes, see following sections for
215 * decriptions of these features.
216 *
217 * Note: the C++ bindings use std::call_once and therefore may need to be
218 * compiled using special command-line options (such as "-pthread") on some
219 * platforms!
220 *
221 * \code
222 #define CL_HPP_ENABLE_EXCEPTIONS
223 #define CL_HPP_TARGET_OPENCL_VERSION 200
224
225 #include <CL/opencl.hpp>
226 #include <iostream>
227 #include <vector>
228 #include <memory>
229 #include <algorithm>
230
231 const int numElements = 32;
232
233 int main(void)
234 {
235 // Filter for a 2.0 or newer platform and set it as the default
236 std::vector<cl::Platform> platforms;
237 cl::Platform::get(&platforms);
238 cl::Platform plat;
239 for (auto &p : platforms) {
240 std::string platver = p.getInfo<CL_PLATFORM_VERSION>();
241 if (platver.find("OpenCL 2.") != std::string::npos ||
242 platver.find("OpenCL 3.") != std::string::npos) {
243 // Note: an OpenCL 3.x platform may not support all required features!
244 plat = p;
245 }
246 }
247 if (plat() == 0) {
248 std::cout << "No OpenCL 2.0 or newer platform found.\n";
249 return -1;
250 }
251
252 cl::Platform newP = cl::Platform::setDefault(plat);
253 if (newP != plat) {
254 std::cout << "Error setting default platform.\n";
255 return -1;
256 }
257
258 // C++11 raw string literal for the first kernel
259 std::string kernel1{R"CLC(
260 global int globalA;
261 kernel void updateGlobal()
262 {
263 globalA = 75;
264 }
265 )CLC"};
266
267 // Raw string literal for the second kernel
268 std::string kernel2{R"CLC(
269 typedef struct { global int *bar; } Foo;
270 kernel void vectorAdd(global const Foo* aNum, global const int *inputA, global const int *inputB,
271 global int *output, int val, write_only pipe int outPipe, queue_t childQueue)
272 {
273 output[get_global_id(0)] = inputA[get_global_id(0)] + inputB[get_global_id(0)] + val + *(aNum->bar);
274 write_pipe(outPipe, &val);
275 queue_t default_queue = get_default_queue();
276 ndrange_t ndrange = ndrange_1D(get_global_size(0)/2, get_global_size(0)/2);
277
278 // Have a child kernel write into third quarter of output
279 enqueue_kernel(default_queue, CLK_ENQUEUE_FLAGS_WAIT_KERNEL, ndrange,
280 ^{
281 output[get_global_size(0)*2 + get_global_id(0)] =
282 inputA[get_global_size(0)*2 + get_global_id(0)] + inputB[get_global_size(0)*2 + get_global_id(0)] + globalA;
283 });
284
285 // Have a child kernel write into last quarter of output
286 enqueue_kernel(childQueue, CLK_ENQUEUE_FLAGS_WAIT_KERNEL, ndrange,
287 ^{
288 output[get_global_size(0)*3 + get_global_id(0)] =
289 inputA[get_global_size(0)*3 + get_global_id(0)] + inputB[get_global_size(0)*3 + get_global_id(0)] + globalA + 2;
290 });
291 }
292 )CLC"};
293
294 std::vector<std::string> programStrings;
295 programStrings.push_back(kernel1);
296 programStrings.push_back(kernel2);
297
298 cl::Program vectorAddProgram(programStrings);
299 try {
300 vectorAddProgram.build("-cl-std=CL2.0");
301 }
302 catch (...) {
303 // Print build info for all devices
304 cl_int buildErr = CL_SUCCESS;
305 auto buildInfo = vectorAddProgram.getBuildInfo<CL_PROGRAM_BUILD_LOG>(&buildErr);
306 for (auto &pair : buildInfo) {
307 std::cerr << pair.second << std::endl << std::endl;
308 }
309
310 return 1;
311 }
312
313 typedef struct { int *bar; } Foo;
314
315 // Get and run kernel that initializes the program-scope global
316 // A test for kernels that take no arguments
317 auto program2Kernel =
318 cl::KernelFunctor<>(vectorAddProgram, "updateGlobal");
319 program2Kernel(
320 cl::EnqueueArgs(
321 cl::NDRange(1)));
322
323 //////////////////
324 // SVM allocations
325
326 auto anSVMInt = cl::allocate_svm<int, cl::SVMTraitCoarse<>>();
327 *anSVMInt = 5;
328 cl::SVMAllocator<Foo, cl::SVMTraitCoarse<cl::SVMTraitReadOnly<>>> svmAllocReadOnly;
329 auto fooPointer = cl::allocate_pointer<Foo>(svmAllocReadOnly);
330 fooPointer->bar = anSVMInt.get();
331 cl::SVMAllocator<int, cl::SVMTraitCoarse<>> svmAlloc;
332 std::vector<int, cl::SVMAllocator<int, cl::SVMTraitCoarse<>>> inputA(numElements, 1, svmAlloc);
333 cl::coarse_svm_vector<int> inputB(numElements, 2, svmAlloc);
334
335 //////////////
336 // Traditional cl_mem allocations
337
338 std::vector<int> output(numElements, 0xdeadbeef);
339 cl::Buffer outputBuffer(output.begin(), output.end(), false);
340 cl::Pipe aPipe(sizeof(cl_int), numElements / 2);
341
342 // Default command queue, also passed in as a parameter
343 cl::DeviceCommandQueue defaultDeviceQueue = cl::DeviceCommandQueue::makeDefault(
344 cl::Context::getDefault(), cl::Device::getDefault());
345
346 auto vectorAddKernel =
347 cl::KernelFunctor<
348 decltype(fooPointer)&,
349 int*,
350 cl::coarse_svm_vector<int>&,
351 cl::Buffer,
352 int,
353 cl::Pipe&,
354 cl::DeviceCommandQueue
355 >(vectorAddProgram, "vectorAdd");
356
357 // Ensure that the additional SVM pointer is available to the kernel
358 // This one was not passed as a parameter
359 vectorAddKernel.setSVMPointers(anSVMInt);
360
361 cl_int error;
362 vectorAddKernel(
363 cl::EnqueueArgs(
364 cl::NDRange(numElements/2),
365 cl::NDRange(numElements/2)),
366 fooPointer,
367 inputA.data(),
368 inputB,
369 outputBuffer,
370 3,
371 aPipe,
372 defaultDeviceQueue,
373 error
374 );
375
376 cl::copy(outputBuffer, output.begin(), output.end());
377
378 cl::Device d = cl::Device::getDefault();
379
380 std::cout << "Output:\n";
381 for (int i = 1; i < numElements; ++i) {
382 std::cout << "\t" << output[i] << "\n";
383 }
384 std::cout << "\n\n";
385
386 return 0;
387 }
388 *
389 * \endcode
390 *
391 */
392#ifndef CL_HPP_
393#define CL_HPP_
394
395/* Handle deprecated preprocessor definitions. In each case, we only check for
396 * the old name if the new name is not defined, so that user code can define
397 * both and hence work with either version of the bindings.
398 */
399#if !defined(CL_HPP_USE_DX_INTEROP) && defined(USE_DX_INTEROP)
400# pragma message("opencl.hpp: USE_DX_INTEROP is deprecated. Define CL_HPP_USE_DX_INTEROP instead")
401# define CL_HPP_USE_DX_INTEROP
402#endif
403#if !defined(CL_HPP_ENABLE_EXCEPTIONS) && defined(__CL_ENABLE_EXCEPTIONS)
404# pragma message("opencl.hpp: __CL_ENABLE_EXCEPTIONS is deprecated. Define CL_HPP_ENABLE_EXCEPTIONS instead")
405# define CL_HPP_ENABLE_EXCEPTIONS
406#endif
407#if !defined(CL_HPP_NO_STD_VECTOR) && defined(__NO_STD_VECTOR)
408# pragma message("opencl.hpp: __NO_STD_VECTOR is deprecated. Define CL_HPP_NO_STD_VECTOR instead")
409# define CL_HPP_NO_STD_VECTOR
410#endif
411#if !defined(CL_HPP_NO_STD_STRING) && defined(__NO_STD_STRING)
412# pragma message("opencl.hpp: __NO_STD_STRING is deprecated. Define CL_HPP_NO_STD_STRING instead")
413# define CL_HPP_NO_STD_STRING
414#endif
415#if defined(VECTOR_CLASS)
416# pragma message("opencl.hpp: VECTOR_CLASS is deprecated. Alias cl::vector instead")
417#endif
418#if defined(STRING_CLASS)
419# pragma message("opencl.hpp: STRING_CLASS is deprecated. Alias cl::string instead.")
420#endif
421#if !defined(CL_HPP_USER_OVERRIDE_ERROR_STRINGS) && defined(__CL_USER_OVERRIDE_ERROR_STRINGS)
422# pragma message("opencl.hpp: __CL_USER_OVERRIDE_ERROR_STRINGS is deprecated. Define CL_HPP_USER_OVERRIDE_ERROR_STRINGS instead")
423# define CL_HPP_USER_OVERRIDE_ERROR_STRINGS
424#endif
425
426/* Warn about features that are no longer supported
427 */
428#if defined(__USE_DEV_VECTOR)
429# pragma message("opencl.hpp: __USE_DEV_VECTOR is no longer supported. Expect compilation errors")
430#endif
431#if defined(__USE_DEV_STRING)
432# pragma message("opencl.hpp: __USE_DEV_STRING is no longer supported. Expect compilation errors")
433#endif
434
435/* Detect which version to target */
436#if !defined(CL_HPP_TARGET_OPENCL_VERSION)
437# pragma message("opencl.hpp: CL_HPP_TARGET_OPENCL_VERSION is not defined. It will default to 300 (OpenCL 3.0)")
438# define CL_HPP_TARGET_OPENCL_VERSION 300
439#endif
440#if CL_HPP_TARGET_OPENCL_VERSION != 100 && \
441 CL_HPP_TARGET_OPENCL_VERSION != 110 && \
442 CL_HPP_TARGET_OPENCL_VERSION != 120 && \
443 CL_HPP_TARGET_OPENCL_VERSION != 200 && \
444 CL_HPP_TARGET_OPENCL_VERSION != 210 && \
445 CL_HPP_TARGET_OPENCL_VERSION != 220 && \
446 CL_HPP_TARGET_OPENCL_VERSION != 300
447# pragma message("opencl.hpp: CL_HPP_TARGET_OPENCL_VERSION is not a valid value (100, 110, 120, 200, 210, 220 or 300). It will be set to 300 (OpenCL 3.0).")
448# undef CL_HPP_TARGET_OPENCL_VERSION
449# define CL_HPP_TARGET_OPENCL_VERSION 300
450#endif
451
452/* Forward target OpenCL version to C headers if necessary */
453#if defined(CL_TARGET_OPENCL_VERSION)
454/* Warn if prior definition of CL_TARGET_OPENCL_VERSION is lower than
455 * requested C++ bindings version */
456#if CL_TARGET_OPENCL_VERSION < CL_HPP_TARGET_OPENCL_VERSION
457# pragma message("CL_TARGET_OPENCL_VERSION is already defined as is lower than CL_HPP_TARGET_OPENCL_VERSION")
458#endif
459#else
460# define CL_TARGET_OPENCL_VERSION CL_HPP_TARGET_OPENCL_VERSION
461#endif
462
463#if !defined(CL_HPP_MINIMUM_OPENCL_VERSION)
464# define CL_HPP_MINIMUM_OPENCL_VERSION 200
465#endif
466#if CL_HPP_MINIMUM_OPENCL_VERSION != 100 && \
467 CL_HPP_MINIMUM_OPENCL_VERSION != 110 && \
468 CL_HPP_MINIMUM_OPENCL_VERSION != 120 && \
469 CL_HPP_MINIMUM_OPENCL_VERSION != 200 && \
470 CL_HPP_MINIMUM_OPENCL_VERSION != 210 && \
471 CL_HPP_MINIMUM_OPENCL_VERSION != 220 && \
472 CL_HPP_MINIMUM_OPENCL_VERSION != 300
473# pragma message("opencl.hpp: CL_HPP_MINIMUM_OPENCL_VERSION is not a valid value (100, 110, 120, 200, 210, 220 or 300). It will be set to 100")
474# undef CL_HPP_MINIMUM_OPENCL_VERSION
475# define CL_HPP_MINIMUM_OPENCL_VERSION 100
476#endif
477#if CL_HPP_MINIMUM_OPENCL_VERSION > CL_HPP_TARGET_OPENCL_VERSION
478# error "CL_HPP_MINIMUM_OPENCL_VERSION must not be greater than CL_HPP_TARGET_OPENCL_VERSION"
479#endif
480
481#if CL_HPP_MINIMUM_OPENCL_VERSION <= 100 && !defined(CL_USE_DEPRECATED_OPENCL_1_0_APIS)
482# define CL_USE_DEPRECATED_OPENCL_1_0_APIS
483#endif
484#if CL_HPP_MINIMUM_OPENCL_VERSION <= 110 && !defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
485# define CL_USE_DEPRECATED_OPENCL_1_1_APIS
486#endif
487#if CL_HPP_MINIMUM_OPENCL_VERSION <= 120 && !defined(CL_USE_DEPRECATED_OPENCL_1_2_APIS)
488# define CL_USE_DEPRECATED_OPENCL_1_2_APIS
489#endif
490#if CL_HPP_MINIMUM_OPENCL_VERSION <= 200 && !defined(CL_USE_DEPRECATED_OPENCL_2_0_APIS)
491# define CL_USE_DEPRECATED_OPENCL_2_0_APIS
492#endif
493#if CL_HPP_MINIMUM_OPENCL_VERSION <= 210 && !defined(CL_USE_DEPRECATED_OPENCL_2_1_APIS)
494# define CL_USE_DEPRECATED_OPENCL_2_1_APIS
495#endif
496#if CL_HPP_MINIMUM_OPENCL_VERSION <= 220 && !defined(CL_USE_DEPRECATED_OPENCL_2_2_APIS)
497# define CL_USE_DEPRECATED_OPENCL_2_2_APIS
498#endif
499
500#ifdef _WIN32
501
502#include <malloc.h>
503
504#if defined(CL_HPP_USE_DX_INTEROP)
505#include <CL/cl_d3d10.h>
506#include <CL/cl_dx9_media_sharing.h>
507#endif
508#endif // _WIN32
509
510#if defined(_MSC_VER)
511#include <intrin.h>
512#endif // _MSC_VER
513
514 // Check for a valid C++ version
515
516// Need to do both tests here because for some reason __cplusplus is not
517// updated in visual studio
518#if (!defined(_MSC_VER) && __cplusplus < 201103L) || (defined(_MSC_VER) && _MSC_VER < 1700)
519#error Visual studio 2013 or another C++11-supporting compiler required
520#endif
521
522#if defined(__APPLE__) || defined(__MACOSX)
523#include <OpenCL/opencl.h>
524#else
525#include <CL/opencl.h>
526#endif // !__APPLE__
527
528#if __cplusplus >= 201703L
529# define CL_HPP_DEFINE_STATIC_MEMBER_ inline
530#elif defined(_MSC_VER)
531# define CL_HPP_DEFINE_STATIC_MEMBER_ __declspec(selectany)
532#elif defined(__MINGW32__)
533# define CL_HPP_DEFINE_STATIC_MEMBER_ __attribute__((selectany))
534#else
535# define CL_HPP_DEFINE_STATIC_MEMBER_ __attribute__((weak))
536#endif // !_MSC_VER
537
538// Define deprecated prefixes and suffixes to ensure compilation
539// in case they are not pre-defined
540#if !defined(CL_API_PREFIX__VERSION_1_1_DEPRECATED)
541#define CL_API_PREFIX__VERSION_1_1_DEPRECATED
542#endif // #if !defined(CL_API_PREFIX__VERSION_1_1_DEPRECATED)
543#if !defined(CL_API_SUFFIX__VERSION_1_1_DEPRECATED)
544#define CL_API_SUFFIX__VERSION_1_1_DEPRECATED
545#endif // #if !defined(CL_API_SUFFIX__VERSION_1_1_DEPRECATED)
546
547#if !defined(CL_API_PREFIX__VERSION_1_2_DEPRECATED)
548#define CL_API_PREFIX__VERSION_1_2_DEPRECATED
549#endif // #if !defined(CL_API_PREFIX__VERSION_1_2_DEPRECATED)
550#if !defined(CL_API_SUFFIX__VERSION_1_2_DEPRECATED)
551#define CL_API_SUFFIX__VERSION_1_2_DEPRECATED
552#endif // #if !defined(CL_API_SUFFIX__VERSION_1_2_DEPRECATED)
553
554#if !defined(CL_API_PREFIX__VERSION_2_2_DEPRECATED)
555#define CL_API_PREFIX__VERSION_2_2_DEPRECATED
556#endif // #if !defined(CL_API_PREFIX__VERSION_2_2_DEPRECATED)
557#if !defined(CL_API_SUFFIX__VERSION_2_2_DEPRECATED)
558#define CL_API_SUFFIX__VERSION_2_2_DEPRECATED
559#endif // #if !defined(CL_API_SUFFIX__VERSION_2_2_DEPRECATED)
560
561#if !defined(CL_CALLBACK)
562#define CL_CALLBACK
563#endif //CL_CALLBACK
564
565#include <utility>
566#include <limits>
567#include <iterator>
568#include <mutex>
569#include <cstring>
570#include <functional>
571
572
573// Define a size_type to represent a correctly resolved size_t
574#if defined(CL_HPP_ENABLE_SIZE_T_COMPATIBILITY)
575namespace cl {
576 using size_type = ::size_t;
577} // namespace cl
578#else // #if defined(CL_HPP_ENABLE_SIZE_T_COMPATIBILITY)
579namespace cl {
580 using size_type = size_t;
581} // namespace cl
582#endif // #if defined(CL_HPP_ENABLE_SIZE_T_COMPATIBILITY)
583
584
585#if defined(CL_HPP_ENABLE_EXCEPTIONS)
586#include <exception>
587#endif // #if defined(CL_HPP_ENABLE_EXCEPTIONS)
588
589#if !defined(CL_HPP_NO_STD_VECTOR)
590#include <vector>
591namespace cl {
592 template < class T, class Alloc = std::allocator<T> >
593 using vector = std::vector<T, Alloc>;
594} // namespace cl
595#endif // #if !defined(CL_HPP_NO_STD_VECTOR)
596
597#if !defined(CL_HPP_NO_STD_STRING)
598#include <string>
599namespace cl {
600 using string = std::string;
601} // namespace cl
602#endif // #if !defined(CL_HPP_NO_STD_STRING)
603
604#if CL_HPP_TARGET_OPENCL_VERSION >= 200
605
606#if !defined(CL_HPP_NO_STD_UNIQUE_PTR)
607#include <memory>
608namespace cl {
609 // Replace unique_ptr and allocate_pointer for internal use
610 // to allow user to replace them
611 template<class T, class D>
612 using pointer = std::unique_ptr<T, D>;
613} // namespace cl
614#endif
615#endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 200
616#if !defined(CL_HPP_NO_STD_ARRAY)
617#include <array>
618namespace cl {
619 template < class T, size_type N >
620 using array = std::array<T, N>;
621} // namespace cl
622#endif // #if !defined(CL_HPP_NO_STD_ARRAY)
623
624// Define size_type appropriately to allow backward-compatibility
625// use of the old size_t interface class
626#if defined(CL_HPP_ENABLE_SIZE_T_COMPATIBILITY)
627namespace cl {
628 namespace compatibility {
629 /*! \brief class used to interface between C++ and
630 * OpenCL C calls that require arrays of size_t values, whose
631 * size is known statically.
632 */
633 template <int N>
634 class size_t
635 {
636 private:
637 size_type data_[N];
638
639 public:
640 //! \brief Initialize size_t to all 0s
641 size_t()
642 {
643 for (int i = 0; i < N; ++i) {
644 data_[i] = 0;
645 }
646 }
647
648 size_t(const array<size_type, N> &rhs)
649 {
650 for (int i = 0; i < N; ++i) {
651 data_[i] = rhs[i];
652 }
653 }
654
655 size_type& operator[](int index)
656 {
657 return data_[index];
658 }
659
660 const size_type& operator[](int index) const
661 {
662 return data_[index];
663 }
664
665 //! \brief Conversion operator to T*.
666 operator size_type* () { return data_; }
667
668 //! \brief Conversion operator to const T*.
669 operator const size_type* () const { return data_; }
670
671 operator array<size_type, N>() const
672 {
673 array<size_type, N> ret;
674
675 for (int i = 0; i < N; ++i) {
676 ret[i] = data_[i];
677 }
678 return ret;
679 }
680 };
681 } // namespace compatibility
682
683 template<int N>
684 using size_t = compatibility::size_t<N>;
685} // namespace cl
686#endif // #if defined(CL_HPP_ENABLE_SIZE_T_COMPATIBILITY)
687
688// Helper alias to avoid confusing the macros
689namespace cl {
690 namespace detail {
691 using size_t_array = array<size_type, 3>;
692 } // namespace detail
693} // namespace cl
694
695
696/*! \namespace cl
697 *
698 * \brief The OpenCL C++ bindings are defined within this namespace.
699 *
700 */
701namespace cl {
702
703#define CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(name) \
704 using PFN_##name = name##_fn
705
706#define CL_HPP_INIT_CL_EXT_FCN_PTR_(name) \
707 if (!pfn_##name) { \
708 pfn_##name = (PFN_##name)clGetExtensionFunctionAddress(#name); \
709 }
710
711#define CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, name) \
712 if (!pfn_##name) { \
713 pfn_##name = (PFN_##name) \
714 clGetExtensionFunctionAddressForPlatform(platform, #name); \
715 }
716
717#ifdef cl_khr_external_memory
718 enum class ExternalMemoryType : cl_external_memory_handle_type_khr;
719#endif
720
721 class Memory;
722 class Platform;
723 class Program;
724 class Device;
725 class Context;
726 class CommandQueue;
727 class DeviceCommandQueue;
728 class Memory;
729 class Buffer;
730 class Pipe;
731#ifdef cl_khr_semaphore
732 class Semaphore;
733#endif
734#if defined(cl_khr_command_buffer)
735 class CommandBufferKhr;
736 class MutableCommandKhr;
737#endif // cl_khr_command_buffer
738
739#if defined(CL_HPP_ENABLE_EXCEPTIONS)
740 /*! \brief Exception class
741 *
742 * This may be thrown by API functions when CL_HPP_ENABLE_EXCEPTIONS is defined.
743 */
744 class Error : public std::exception
745 {
746 private:
747 cl_int err_;
748 const char * errStr_;
749 public:
750 /*! \brief Create a new CL error exception for a given error code
751 * and corresponding message.
752 *
753 * \param err error code value.
754 *
755 * \param errStr a descriptive string that must remain in scope until
756 * handling of the exception has concluded. If set, it
757 * will be returned by what().
758 */
759 Error(cl_int err, const char * errStr = nullptr) : err_(err), errStr_(errStr)
760 {}
761
762 /*! \brief Get error string associated with exception
763 *
764 * \return A memory pointer to the error message string.
765 */
766 const char * what() const noexcept override
767 {
768 if (errStr_ == nullptr) {
769 return "empty";
770 }
771 else {
772 return errStr_;
773 }
774 }
775
776 /*! \brief Get error code associated with exception
777 *
778 * \return The error code.
779 */
780 cl_int err(void) const { return err_; }
781 };
782#define CL_HPP_ERR_STR_(x) #x
783#else
784#define CL_HPP_ERR_STR_(x) nullptr
785#endif // CL_HPP_ENABLE_EXCEPTIONS
786
787
788namespace detail
789{
790#if defined(CL_HPP_ENABLE_EXCEPTIONS)
791static inline cl_int errHandler (
792 cl_int err,
793 const char * errStr = nullptr)
794{
795 if (err != CL_SUCCESS) {
796 throw Error(err, errStr);
797 }
798 return err;
799}
800#else
801static inline cl_int errHandler (cl_int err, const char * errStr = nullptr)
802{
803 (void) errStr; // suppress unused variable warning
804 return err;
805}
806#endif // CL_HPP_ENABLE_EXCEPTIONS
807}
808
809
810
811//! \cond DOXYGEN_DETAIL
812#if !defined(CL_HPP_USER_OVERRIDE_ERROR_STRINGS)
813#define __GET_DEVICE_INFO_ERR CL_HPP_ERR_STR_(clGetDeviceInfo)
814#define __GET_PLATFORM_INFO_ERR CL_HPP_ERR_STR_(clGetPlatformInfo)
815#define __GET_DEVICE_IDS_ERR CL_HPP_ERR_STR_(clGetDeviceIDs)
816#define __GET_PLATFORM_IDS_ERR CL_HPP_ERR_STR_(clGetPlatformIDs)
817#define __GET_CONTEXT_INFO_ERR CL_HPP_ERR_STR_(clGetContextInfo)
818#define __GET_EVENT_INFO_ERR CL_HPP_ERR_STR_(clGetEventInfo)
819#define __GET_EVENT_PROFILE_INFO_ERR CL_HPP_ERR_STR_(clGetEventProfileInfo)
820#define __GET_MEM_OBJECT_INFO_ERR CL_HPP_ERR_STR_(clGetMemObjectInfo)
821#define __GET_IMAGE_INFO_ERR CL_HPP_ERR_STR_(clGetImageInfo)
822#define __GET_SAMPLER_INFO_ERR CL_HPP_ERR_STR_(clGetSamplerInfo)
823#define __GET_KERNEL_INFO_ERR CL_HPP_ERR_STR_(clGetKernelInfo)
824#if CL_HPP_TARGET_OPENCL_VERSION >= 120
825#define __GET_KERNEL_ARG_INFO_ERR CL_HPP_ERR_STR_(clGetKernelArgInfo)
826#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
827#if CL_HPP_TARGET_OPENCL_VERSION >= 210
828#define __GET_KERNEL_SUB_GROUP_INFO_ERR CL_HPP_ERR_STR_(clGetKernelSubGroupInfo)
829#else
830#define __GET_KERNEL_SUB_GROUP_INFO_ERR CL_HPP_ERR_STR_(clGetKernelSubGroupInfoKHR)
831#endif // CL_HPP_TARGET_OPENCL_VERSION >= 210
832#define __GET_KERNEL_WORK_GROUP_INFO_ERR CL_HPP_ERR_STR_(clGetKernelWorkGroupInfo)
833#define __GET_PROGRAM_INFO_ERR CL_HPP_ERR_STR_(clGetProgramInfo)
834#define __GET_PROGRAM_BUILD_INFO_ERR CL_HPP_ERR_STR_(clGetProgramBuildInfo)
835#define __GET_COMMAND_QUEUE_INFO_ERR CL_HPP_ERR_STR_(clGetCommandQueueInfo)
836
837#define __CREATE_CONTEXT_ERR CL_HPP_ERR_STR_(clCreateContext)
838#define __CREATE_CONTEXT_FROM_TYPE_ERR CL_HPP_ERR_STR_(clCreateContextFromType)
839#define __GET_SUPPORTED_IMAGE_FORMATS_ERR CL_HPP_ERR_STR_(clGetSupportedImageFormats)
840#if CL_HPP_TARGET_OPENCL_VERSION >= 300
841#define __SET_CONTEXT_DESCTRUCTOR_CALLBACK_ERR CL_HPP_ERR_STR_(clSetContextDestructorCallback)
842#endif // CL_HPP_TARGET_OPENCL_VERSION >= 300
843
844#define __CREATE_BUFFER_ERR CL_HPP_ERR_STR_(clCreateBuffer)
845#define __COPY_ERR CL_HPP_ERR_STR_(cl::copy)
846#define __CREATE_SUBBUFFER_ERR CL_HPP_ERR_STR_(clCreateSubBuffer)
847#define __CREATE_GL_BUFFER_ERR CL_HPP_ERR_STR_(clCreateFromGLBuffer)
848#define __CREATE_GL_RENDER_BUFFER_ERR CL_HPP_ERR_STR_(clCreateFromGLBuffer)
849#define __GET_GL_OBJECT_INFO_ERR CL_HPP_ERR_STR_(clGetGLObjectInfo)
850#if CL_HPP_TARGET_OPENCL_VERSION >= 120
851#define __CREATE_IMAGE_ERR CL_HPP_ERR_STR_(clCreateImage)
852#define __CREATE_GL_TEXTURE_ERR CL_HPP_ERR_STR_(clCreateFromGLTexture)
853#define __IMAGE_DIMENSION_ERR CL_HPP_ERR_STR_(Incorrect image dimensions)
854#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
855#define __SET_MEM_OBJECT_DESTRUCTOR_CALLBACK_ERR CL_HPP_ERR_STR_(clSetMemObjectDestructorCallback)
856
857#define __CREATE_USER_EVENT_ERR CL_HPP_ERR_STR_(clCreateUserEvent)
858#define __SET_USER_EVENT_STATUS_ERR CL_HPP_ERR_STR_(clSetUserEventStatus)
859#define __SET_EVENT_CALLBACK_ERR CL_HPP_ERR_STR_(clSetEventCallback)
860#define __WAIT_FOR_EVENTS_ERR CL_HPP_ERR_STR_(clWaitForEvents)
861
862#define __CREATE_KERNEL_ERR CL_HPP_ERR_STR_(clCreateKernel)
863#define __SET_KERNEL_ARGS_ERR CL_HPP_ERR_STR_(clSetKernelArg)
864#define __CREATE_PROGRAM_WITH_SOURCE_ERR CL_HPP_ERR_STR_(clCreateProgramWithSource)
865#define __CREATE_PROGRAM_WITH_BINARY_ERR CL_HPP_ERR_STR_(clCreateProgramWithBinary)
866#if CL_HPP_TARGET_OPENCL_VERSION >= 210
867#define __CREATE_PROGRAM_WITH_IL_ERR CL_HPP_ERR_STR_(clCreateProgramWithIL)
868#else
869#define __CREATE_PROGRAM_WITH_IL_ERR CL_HPP_ERR_STR_(clCreateProgramWithILKHR)
870#endif // CL_HPP_TARGET_OPENCL_VERSION >= 210
871#if CL_HPP_TARGET_OPENCL_VERSION >= 120
872#define __CREATE_PROGRAM_WITH_BUILT_IN_KERNELS_ERR CL_HPP_ERR_STR_(clCreateProgramWithBuiltInKernels)
873#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
874#define __BUILD_PROGRAM_ERR CL_HPP_ERR_STR_(clBuildProgram)
875#if CL_HPP_TARGET_OPENCL_VERSION >= 120
876#define __COMPILE_PROGRAM_ERR CL_HPP_ERR_STR_(clCompileProgram)
877#define __LINK_PROGRAM_ERR CL_HPP_ERR_STR_(clLinkProgram)
878#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
879#define __CREATE_KERNELS_IN_PROGRAM_ERR CL_HPP_ERR_STR_(clCreateKernelsInProgram)
880
881#if CL_HPP_TARGET_OPENCL_VERSION >= 200
882#define __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR CL_HPP_ERR_STR_(clCreateCommandQueueWithProperties)
883#define __CREATE_SAMPLER_WITH_PROPERTIES_ERR CL_HPP_ERR_STR_(clCreateSamplerWithProperties)
884#endif // CL_HPP_TARGET_OPENCL_VERSION >= 200
885#define __SET_COMMAND_QUEUE_PROPERTY_ERR CL_HPP_ERR_STR_(clSetCommandQueueProperty)
886#define __ENQUEUE_READ_BUFFER_ERR CL_HPP_ERR_STR_(clEnqueueReadBuffer)
887#define __ENQUEUE_READ_BUFFER_RECT_ERR CL_HPP_ERR_STR_(clEnqueueReadBufferRect)
888#define __ENQUEUE_WRITE_BUFFER_ERR CL_HPP_ERR_STR_(clEnqueueWriteBuffer)
889#define __ENQUEUE_WRITE_BUFFER_RECT_ERR CL_HPP_ERR_STR_(clEnqueueWriteBufferRect)
890#define __ENQEUE_COPY_BUFFER_ERR CL_HPP_ERR_STR_(clEnqueueCopyBuffer)
891#define __ENQEUE_COPY_BUFFER_RECT_ERR CL_HPP_ERR_STR_(clEnqueueCopyBufferRect)
892#define __ENQUEUE_FILL_BUFFER_ERR CL_HPP_ERR_STR_(clEnqueueFillBuffer)
893#define __ENQUEUE_READ_IMAGE_ERR CL_HPP_ERR_STR_(clEnqueueReadImage)
894#define __ENQUEUE_WRITE_IMAGE_ERR CL_HPP_ERR_STR_(clEnqueueWriteImage)
895#define __ENQUEUE_COPY_IMAGE_ERR CL_HPP_ERR_STR_(clEnqueueCopyImage)
896#define __ENQUEUE_FILL_IMAGE_ERR CL_HPP_ERR_STR_(clEnqueueFillImage)
897#define __ENQUEUE_COPY_IMAGE_TO_BUFFER_ERR CL_HPP_ERR_STR_(clEnqueueCopyImageToBuffer)
898#define __ENQUEUE_COPY_BUFFER_TO_IMAGE_ERR CL_HPP_ERR_STR_(clEnqueueCopyBufferToImage)
899#define __ENQUEUE_MAP_BUFFER_ERR CL_HPP_ERR_STR_(clEnqueueMapBuffer)
900#define __ENQUEUE_MAP_SVM_ERR CL_HPP_ERR_STR_(clEnqueueSVMMap)
901#define __ENQUEUE_FILL_SVM_ERR CL_HPP_ERR_STR_(clEnqueueSVMMemFill)
902#define __ENQUEUE_COPY_SVM_ERR CL_HPP_ERR_STR_(clEnqueueSVMMemcpy)
903#define __ENQUEUE_UNMAP_SVM_ERR CL_HPP_ERR_STR_(clEnqueueSVMUnmap)
904#define __ENQUEUE_MAP_IMAGE_ERR CL_HPP_ERR_STR_(clEnqueueMapImage)
905#define __ENQUEUE_UNMAP_MEM_OBJECT_ERR CL_HPP_ERR_STR_(clEnqueueUnMapMemObject)
906#define __ENQUEUE_NDRANGE_KERNEL_ERR CL_HPP_ERR_STR_(clEnqueueNDRangeKernel)
907#define __ENQUEUE_NATIVE_KERNEL CL_HPP_ERR_STR_(clEnqueueNativeKernel)
908#if CL_HPP_TARGET_OPENCL_VERSION >= 120
909#define __ENQUEUE_MIGRATE_MEM_OBJECTS_ERR CL_HPP_ERR_STR_(clEnqueueMigrateMemObjects)
910#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
911#if CL_HPP_TARGET_OPENCL_VERSION >= 210
912#define __ENQUEUE_MIGRATE_SVM_ERR CL_HPP_ERR_STR_(clEnqueueSVMMigrateMem)
913#define __SET_DEFAULT_DEVICE_COMMAND_QUEUE_ERR CL_HPP_ERR_STR_(clSetDefaultDeviceCommandQueue)
914#endif // CL_HPP_TARGET_OPENCL_VERSION >= 210
915
916
917#define __ENQUEUE_ACQUIRE_GL_ERR CL_HPP_ERR_STR_(clEnqueueAcquireGLObjects)
918#define __ENQUEUE_RELEASE_GL_ERR CL_HPP_ERR_STR_(clEnqueueReleaseGLObjects)
919
920#define __CREATE_PIPE_ERR CL_HPP_ERR_STR_(clCreatePipe)
921#define __GET_PIPE_INFO_ERR CL_HPP_ERR_STR_(clGetPipeInfo)
922
923#define __RETAIN_ERR CL_HPP_ERR_STR_(Retain Object)
924#define __RELEASE_ERR CL_HPP_ERR_STR_(Release Object)
925#define __FLUSH_ERR CL_HPP_ERR_STR_(clFlush)
926#define __FINISH_ERR CL_HPP_ERR_STR_(clFinish)
927#define __VECTOR_CAPACITY_ERR CL_HPP_ERR_STR_(Vector capacity error)
928
929#if CL_HPP_TARGET_OPENCL_VERSION >= 210
930#define __GET_HOST_TIMER_ERR CL_HPP_ERR_STR_(clGetHostTimer)
931#define __GET_DEVICE_AND_HOST_TIMER_ERR CL_HPP_ERR_STR_(clGetDeviceAndHostTimer)
932#endif
933#if CL_HPP_TARGET_OPENCL_VERSION >= 220
934#define __SET_PROGRAM_RELEASE_CALLBACK_ERR CL_HPP_ERR_STR_(clSetProgramReleaseCallback)
935#define __SET_PROGRAM_SPECIALIZATION_CONSTANT_ERR CL_HPP_ERR_STR_(clSetProgramSpecializationConstant)
936#endif
937
938#ifdef cl_khr_external_memory
939#define __ENQUEUE_ACQUIRE_EXTERNAL_MEMORY_ERR CL_HPP_ERR_STR_(clEnqueueAcquireExternalMemObjectsKHR)
940#define __ENQUEUE_RELEASE_EXTERNAL_MEMORY_ERR CL_HPP_ERR_STR_(clEnqueueReleaseExternalMemObjectsKHR)
941#endif
942
943#ifdef cl_khr_semaphore
944#define __GET_SEMAPHORE_KHR_INFO_ERR CL_HPP_ERR_STR_(clGetSemaphoreInfoKHR)
945#define __CREATE_SEMAPHORE_KHR_WITH_PROPERTIES_ERR CL_HPP_ERR_STR_(clCreateSemaphoreWithPropertiesKHR)
946#define __ENQUEUE_WAIT_SEMAPHORE_KHR_ERR CL_HPP_ERR_STR_(clEnqueueWaitSemaphoresKHR)
947#define __ENQUEUE_SIGNAL_SEMAPHORE_KHR_ERR CL_HPP_ERR_STR_(clEnqueueSignalSemaphoresKHR)
948#define __RETAIN_SEMAPHORE_KHR_ERR CL_HPP_ERR_STR_(clRetainSemaphoreKHR)
949#define __RELEASE_SEMAPHORE_KHR_ERR CL_HPP_ERR_STR_(clReleaseSemaphoreKHR)
950#endif
951
952#ifdef cl_khr_external_semaphore
953#define __GET_SEMAPHORE_HANDLE_FOR_TYPE_KHR_ERR CL_HPP_ERR_STR_(clGetSemaphoreHandleForTypeKHR)
954#endif // cl_khr_external_semaphore
955
956#if defined(cl_khr_command_buffer)
957#define __CREATE_COMMAND_BUFFER_KHR_ERR CL_HPP_ERR_STR_(clCreateCommandBufferKHR)
958#define __GET_COMMAND_BUFFER_INFO_KHR_ERR CL_HPP_ERR_STR_(clGetCommandBufferInfoKHR)
959#define __FINALIZE_COMMAND_BUFFER_KHR_ERR CL_HPP_ERR_STR_(clFinalizeCommandBufferKHR)
960#define __ENQUEUE_COMMAND_BUFFER_KHR_ERR CL_HPP_ERR_STR_(clEnqueueCommandBufferKHR)
961#define __COMMAND_BARRIER_WITH_WAIT_LIST_KHR_ERR CL_HPP_ERR_STR_(clCommandBarrierWithWaitListKHR)
962#define __COMMAND_COPY_BUFFER_KHR_ERR CL_HPP_ERR_STR_(clCommandCopyBufferKHR)
963#define __COMMAND_COPY_BUFFER_RECT_KHR_ERR CL_HPP_ERR_STR_(clCommandCopyBufferRectKHR)
964#define __COMMAND_COPY_BUFFER_TO_IMAGE_KHR_ERR CL_HPP_ERR_STR_(clCommandCopyBufferToImageKHR)
965#define __COMMAND_COPY_IMAGE_KHR_ERR CL_HPP_ERR_STR_(clCommandCopyImageKHR)
966#define __COMMAND_COPY_IMAGE_TO_BUFFER_KHR_ERR CL_HPP_ERR_STR_(clCommandCopyImageToBufferKHR)
967#define __COMMAND_FILL_BUFFER_KHR_ERR CL_HPP_ERR_STR_(clCommandFillBufferKHR)
968#define __COMMAND_FILL_IMAGE_KHR_ERR CL_HPP_ERR_STR_(clCommandFillImageKHR)
969#define __COMMAND_NDRANGE_KERNEL_KHR_ERR CL_HPP_ERR_STR_(clCommandNDRangeKernelKHR)
970#define __UPDATE_MUTABLE_COMMANDS_KHR_ERR CL_HPP_ERR_STR_(clUpdateMutableCommandsKHR)
971#define __GET_MUTABLE_COMMAND_INFO_KHR_ERR CL_HPP_ERR_STR_(clGetMutableCommandInfoKHR)
972#define __RETAIN_COMMAND_BUFFER_KHR_ERR CL_HPP_ERR_STR_(clRetainCommandBufferKHR)
973#define __RELEASE_COMMAND_BUFFER_KHR_ERR CL_HPP_ERR_STR_(clReleaseCommandBufferKHR)
974#endif // cl_khr_command_buffer
975
976#if defined(cl_ext_image_requirements_info)
977#define __GET_IMAGE_REQUIREMENT_INFO_EXT_ERR CL_HPP_ERR_STR_(clGetImageRequirementsInfoEXT)
978#endif //cl_ext_image_requirements_info
979
980/**
981 * CL 1.2 version that uses device fission.
982 */
983#if CL_HPP_TARGET_OPENCL_VERSION >= 120
984#define __CREATE_SUB_DEVICES_ERR CL_HPP_ERR_STR_(clCreateSubDevices)
985#else
986#define __CREATE_SUB_DEVICES_ERR CL_HPP_ERR_STR_(clCreateSubDevicesEXT)
987#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
988
989/**
990 * Deprecated APIs for 1.2
991 */
992#if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
993#define __ENQUEUE_MARKER_ERR CL_HPP_ERR_STR_(clEnqueueMarker)
994#define __ENQUEUE_WAIT_FOR_EVENTS_ERR CL_HPP_ERR_STR_(clEnqueueWaitForEvents)
995#define __ENQUEUE_BARRIER_ERR CL_HPP_ERR_STR_(clEnqueueBarrier)
996#define __UNLOAD_COMPILER_ERR CL_HPP_ERR_STR_(clUnloadCompiler)
997#define __CREATE_GL_TEXTURE_2D_ERR CL_HPP_ERR_STR_(clCreateFromGLTexture2D)
998#define __CREATE_GL_TEXTURE_3D_ERR CL_HPP_ERR_STR_(clCreateFromGLTexture3D)
999#define __CREATE_IMAGE2D_ERR CL_HPP_ERR_STR_(clCreateImage2D)
1000#define __CREATE_IMAGE3D_ERR CL_HPP_ERR_STR_(clCreateImage3D)
1001#endif // #if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
1002
1003/**
1004 * Deprecated APIs for 2.0
1005 */
1006#if defined(CL_USE_DEPRECATED_OPENCL_1_2_APIS)
1007#define __CREATE_COMMAND_QUEUE_ERR CL_HPP_ERR_STR_(clCreateCommandQueue)
1008#define __ENQUEUE_TASK_ERR CL_HPP_ERR_STR_(clEnqueueTask)
1009#define __CREATE_SAMPLER_ERR CL_HPP_ERR_STR_(clCreateSampler)
1010#endif // #if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
1011
1012/**
1013 * CL 1.2 marker and barrier commands
1014 */
1015#if CL_HPP_TARGET_OPENCL_VERSION >= 120
1016#define __ENQUEUE_MARKER_WAIT_LIST_ERR CL_HPP_ERR_STR_(clEnqueueMarkerWithWaitList)
1017#define __ENQUEUE_BARRIER_WAIT_LIST_ERR CL_HPP_ERR_STR_(clEnqueueBarrierWithWaitList)
1018#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
1019
1020#if CL_HPP_TARGET_OPENCL_VERSION >= 210
1021#define __CLONE_KERNEL_ERR CL_HPP_ERR_STR_(clCloneKernel)
1022#endif // CL_HPP_TARGET_OPENCL_VERSION >= 210
1023
1024#endif // CL_HPP_USER_OVERRIDE_ERROR_STRINGS
1025//! \endcond
1026
1027#ifdef cl_khr_external_memory
1028CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clEnqueueAcquireExternalMemObjectsKHR);
1029CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clEnqueueReleaseExternalMemObjectsKHR);
1030
1031CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clEnqueueAcquireExternalMemObjectsKHR pfn_clEnqueueAcquireExternalMemObjectsKHR = nullptr;
1032CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clEnqueueReleaseExternalMemObjectsKHR pfn_clEnqueueReleaseExternalMemObjectsKHR = nullptr;
1033#endif // cl_khr_external_memory
1034
1035#ifdef cl_khr_semaphore
1036CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCreateSemaphoreWithPropertiesKHR);
1037CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clReleaseSemaphoreKHR);
1038CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clRetainSemaphoreKHR);
1039CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clEnqueueWaitSemaphoresKHR);
1040CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clEnqueueSignalSemaphoresKHR);
1041CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clGetSemaphoreInfoKHR);
1042
1043CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCreateSemaphoreWithPropertiesKHR pfn_clCreateSemaphoreWithPropertiesKHR = nullptr;
1044CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clReleaseSemaphoreKHR pfn_clReleaseSemaphoreKHR = nullptr;
1045CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clRetainSemaphoreKHR pfn_clRetainSemaphoreKHR = nullptr;
1046CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clEnqueueWaitSemaphoresKHR pfn_clEnqueueWaitSemaphoresKHR = nullptr;
1047CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clEnqueueSignalSemaphoresKHR pfn_clEnqueueSignalSemaphoresKHR = nullptr;
1048CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clGetSemaphoreInfoKHR pfn_clGetSemaphoreInfoKHR = nullptr;
1049#endif // cl_khr_semaphore
1050
1051#ifdef cl_khr_external_semaphore
1052CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clGetSemaphoreHandleForTypeKHR);
1053CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clGetSemaphoreHandleForTypeKHR pfn_clGetSemaphoreHandleForTypeKHR = nullptr;
1054#endif // cl_khr_external_semaphore
1055
1056#if defined(cl_khr_command_buffer)
1057CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCreateCommandBufferKHR);
1058CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clFinalizeCommandBufferKHR);
1059CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clRetainCommandBufferKHR);
1060CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clReleaseCommandBufferKHR);
1061CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clGetCommandBufferInfoKHR);
1062CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clEnqueueCommandBufferKHR);
1063CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCommandBarrierWithWaitListKHR);
1064CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCommandCopyBufferKHR);
1065CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCommandCopyBufferRectKHR);
1066CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCommandCopyBufferToImageKHR);
1067CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCommandCopyImageKHR);
1068CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCommandCopyImageToBufferKHR);
1069CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCommandFillBufferKHR);
1070CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCommandFillImageKHR);
1071CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCommandNDRangeKernelKHR);
1072
1073CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCreateCommandBufferKHR pfn_clCreateCommandBufferKHR = nullptr;
1074CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clFinalizeCommandBufferKHR pfn_clFinalizeCommandBufferKHR = nullptr;
1075CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clRetainCommandBufferKHR pfn_clRetainCommandBufferKHR = nullptr;
1076CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clReleaseCommandBufferKHR pfn_clReleaseCommandBufferKHR = nullptr;
1077CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clGetCommandBufferInfoKHR pfn_clGetCommandBufferInfoKHR = nullptr;
1078CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clEnqueueCommandBufferKHR pfn_clEnqueueCommandBufferKHR = nullptr;
1079CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCommandBarrierWithWaitListKHR pfn_clCommandBarrierWithWaitListKHR = nullptr;
1080CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCommandCopyBufferKHR pfn_clCommandCopyBufferKHR = nullptr;
1081CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCommandCopyBufferRectKHR pfn_clCommandCopyBufferRectKHR = nullptr;
1082CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCommandCopyBufferToImageKHR pfn_clCommandCopyBufferToImageKHR = nullptr;
1083CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCommandCopyImageKHR pfn_clCommandCopyImageKHR = nullptr;
1084CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCommandCopyImageToBufferKHR pfn_clCommandCopyImageToBufferKHR = nullptr;
1085CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCommandFillBufferKHR pfn_clCommandFillBufferKHR = nullptr;
1086CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCommandFillImageKHR pfn_clCommandFillImageKHR = nullptr;
1087CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCommandNDRangeKernelKHR pfn_clCommandNDRangeKernelKHR = nullptr;
1088#endif /* cl_khr_command_buffer */
1089
1090#if defined(cl_khr_command_buffer_mutable_dispatch)
1091CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clUpdateMutableCommandsKHR);
1092CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clGetMutableCommandInfoKHR);
1093
1094CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clUpdateMutableCommandsKHR pfn_clUpdateMutableCommandsKHR = nullptr;
1095CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clGetMutableCommandInfoKHR pfn_clGetMutableCommandInfoKHR = nullptr;
1096#endif /* cl_khr_command_buffer_mutable_dispatch */
1097
1098#if defined(cl_ext_image_requirements_info)
1099CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clGetImageRequirementsInfoEXT);
1100CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clGetImageRequirementsInfoEXT pfn_clGetImageRequirementsInfoEXT = nullptr;
1101#endif
1102
1103namespace detail {
1104
1105// Generic getInfoHelper. The final parameter is used to guide overload
1106// resolution: the actual parameter passed is an int, which makes this
1107// a worse conversion sequence than a specialization that declares the
1108// parameter as an int.
1109template<typename Functor, typename T>
1110inline cl_int getInfoHelper(Functor f, cl_uint name, T* param, long)
1111{
1112 return f(name, sizeof(T), param, nullptr);
1113}
1114
1115// Specialized for getInfo<CL_PROGRAM_BINARIES>
1116// Assumes that the output vector was correctly resized on the way in
1117template <typename Func>
1118inline cl_int getInfoHelper(Func f, cl_uint name, vector<vector<unsigned char>>* param, int)
1119{
1120 if (name != CL_PROGRAM_BINARIES) {
1121 return CL_INVALID_VALUE;
1122 }
1123 if (param) {
1124 // Create array of pointers, calculate total size and pass pointer array in
1125 size_type numBinaries = param->size();
1126 vector<unsigned char*> binariesPointers(numBinaries);
1127
1128 for (size_type i = 0; i < numBinaries; ++i)
1129 {
1130 binariesPointers[i] = (*param)[i].data();
1131 }
1132
1133 cl_int err = f(name, numBinaries * sizeof(unsigned char*), binariesPointers.data(), nullptr);
1134
1135 if (err != CL_SUCCESS) {
1136 return err;
1137 }
1138 }
1139
1140
1141 return CL_SUCCESS;
1142}
1143
1144// Specialized getInfoHelper for vector params
1145template <typename Func, typename T>
1146inline cl_int getInfoHelper(Func f, cl_uint name, vector<T>* param, long)
1147{
1148 size_type required;
1149 cl_int err = f(name, 0, nullptr, &required);
1150 if (err != CL_SUCCESS) {
1151 return err;
1152 }
1153 const size_type elements = required / sizeof(T);
1154
1155 // Temporary to avoid changing param on an error
1156 vector<T> localData(elements);
1157 err = f(name, required, localData.data(), nullptr);
1158 if (err != CL_SUCCESS) {
1159 return err;
1160 }
1161 if (param) {
1162 *param = std::move(localData);
1163 }
1164
1165 return CL_SUCCESS;
1166}
1167
1168/* Specialization for reference-counted types. This depends on the
1169 * existence of Wrapper<T>::cl_type, and none of the other types having the
1170 * cl_type member. Note that simplify specifying the parameter as Wrapper<T>
1171 * does not work, because when using a derived type (e.g. Context) the generic
1172 * template will provide a better match.
1173 */
1174template <typename Func, typename T>
1175inline cl_int getInfoHelper(
1176 Func f, cl_uint name, vector<T>* param, int, typename T::cl_type = 0)
1177{
1178 size_type required;
1179 cl_int err = f(name, 0, nullptr, &required);
1180 if (err != CL_SUCCESS) {
1181 return err;
1182 }
1183
1184 const size_type elements = required / sizeof(typename T::cl_type);
1185
1186 vector<typename T::cl_type> value(elements);
1187 err = f(name, required, value.data(), nullptr);
1188 if (err != CL_SUCCESS) {
1189 return err;
1190 }
1191
1192 if (param) {
1193 // Assign to convert CL type to T for each element
1194 param->resize(elements);
1195
1196 // Assign to param, constructing with retain behaviour
1197 // to correctly capture each underlying CL object
1198 for (size_type i = 0; i < elements; i++) {
1199 (*param)[i] = T(value[i], true);
1200 }
