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)
575 namespace cl {
576 using size_type = ::size_t;
577 } // namespace cl
578 #else // #if defined(CL_HPP_ENABLE_SIZE_T_COMPATIBILITY)
579 namespace 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>
591 namespace 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>
599 namespace 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>
608 namespace 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>
618 namespace 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)
627 namespace 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
size_t()641 size_t()
642 {
643 for (int i = 0; i < N; ++i) {
644 data_[i] = 0;
645 }
646 }
647
size_t(const array<size_type,N> & rhs)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
operator [](int index)655 size_type& operator[](int index)
656 {
657 return data_[index];
658 }
659
operator [](int index) const660 const size_type& operator[](int index) const
661 {
662 return data_[index];
663 }
664
665 //! \brief Conversion operator to T*.
operator size_type*()666 operator size_type* () { return data_; }
667
668 //! \brief Conversion operator to const T*.
operator const size_type*() const669 operator const size_type* () const { return data_; }
670
operator array<size_type,N>() const671 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
689 namespace 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 */
701 namespace 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 */
Error(cl_int err,const char * errStr=nullptr)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 */
what() const766 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 */
err(void) const780 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
788 namespace detail
789 {
790 #if defined(CL_HPP_ENABLE_EXCEPTIONS)
errHandler(cl_int err,const char * errStr=nullptr)791 static 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
801 static 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
1028 CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clEnqueueAcquireExternalMemObjectsKHR);
1029 CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clEnqueueReleaseExternalMemObjectsKHR);
1030
1031 CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clEnqueueAcquireExternalMemObjectsKHR pfn_clEnqueueAcquireExternalMemObjectsKHR = nullptr;
1032 CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clEnqueueReleaseExternalMemObjectsKHR pfn_clEnqueueReleaseExternalMemObjectsKHR = nullptr;
1033 #endif // cl_khr_external_memory
1034
1035 #ifdef cl_khr_semaphore
1036 CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCreateSemaphoreWithPropertiesKHR);
1037 CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clReleaseSemaphoreKHR);
1038 CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clRetainSemaphoreKHR);
1039 CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clEnqueueWaitSemaphoresKHR);
1040 CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clEnqueueSignalSemaphoresKHR);
1041 CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clGetSemaphoreInfoKHR);
1042
1043 CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCreateSemaphoreWithPropertiesKHR pfn_clCreateSemaphoreWithPropertiesKHR = nullptr;
1044 CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clReleaseSemaphoreKHR pfn_clReleaseSemaphoreKHR = nullptr;
1045 CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clRetainSemaphoreKHR pfn_clRetainSemaphoreKHR = nullptr;
1046 CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clEnqueueWaitSemaphoresKHR pfn_clEnqueueWaitSemaphoresKHR = nullptr;
1047 CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clEnqueueSignalSemaphoresKHR pfn_clEnqueueSignalSemaphoresKHR = nullptr;
1048 CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clGetSemaphoreInfoKHR pfn_clGetSemaphoreInfoKHR = nullptr;
1049 #endif // cl_khr_semaphore
1050
1051 #ifdef cl_khr_external_semaphore
1052 CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clGetSemaphoreHandleForTypeKHR);
1053 CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clGetSemaphoreHandleForTypeKHR pfn_clGetSemaphoreHandleForTypeKHR = nullptr;
1054 #endif // cl_khr_external_semaphore
1055
1056 #if defined(cl_khr_command_buffer)
1057 CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCreateCommandBufferKHR);
1058 CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clFinalizeCommandBufferKHR);
1059 CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clRetainCommandBufferKHR);
1060 CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clReleaseCommandBufferKHR);
1061 CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clGetCommandBufferInfoKHR);
1062 CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clEnqueueCommandBufferKHR);
1063 CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCommandBarrierWithWaitListKHR);
1064 CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCommandCopyBufferKHR);
1065 CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCommandCopyBufferRectKHR);
1066 CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCommandCopyBufferToImageKHR);
1067 CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCommandCopyImageKHR);
1068 CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCommandCopyImageToBufferKHR);
1069 CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCommandFillBufferKHR);
1070 CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCommandFillImageKHR);
1071 CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCommandNDRangeKernelKHR);
1072
1073 CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCreateCommandBufferKHR pfn_clCreateCommandBufferKHR = nullptr;
1074 CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clFinalizeCommandBufferKHR pfn_clFinalizeCommandBufferKHR = nullptr;
1075 CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clRetainCommandBufferKHR pfn_clRetainCommandBufferKHR = nullptr;
1076 CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clReleaseCommandBufferKHR pfn_clReleaseCommandBufferKHR = nullptr;
1077 CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clGetCommandBufferInfoKHR pfn_clGetCommandBufferInfoKHR = nullptr;
1078 CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clEnqueueCommandBufferKHR pfn_clEnqueueCommandBufferKHR = nullptr;
1079 CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCommandBarrierWithWaitListKHR pfn_clCommandBarrierWithWaitListKHR = nullptr;
1080 CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCommandCopyBufferKHR pfn_clCommandCopyBufferKHR = nullptr;
1081 CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCommandCopyBufferRectKHR pfn_clCommandCopyBufferRectKHR = nullptr;
1082 CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCommandCopyBufferToImageKHR pfn_clCommandCopyBufferToImageKHR = nullptr;
1083 CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCommandCopyImageKHR pfn_clCommandCopyImageKHR = nullptr;
1084 CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCommandCopyImageToBufferKHR pfn_clCommandCopyImageToBufferKHR = nullptr;
1085 CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCommandFillBufferKHR pfn_clCommandFillBufferKHR = nullptr;
1086 CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCommandFillImageKHR pfn_clCommandFillImageKHR = nullptr;
1087 CL_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)
1091 CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clUpdateMutableCommandsKHR);
1092 CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clGetMutableCommandInfoKHR);
1093
1094 CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clUpdateMutableCommandsKHR pfn_clUpdateMutableCommandsKHR = nullptr;
1095 CL_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)
1099 CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clGetImageRequirementsInfoEXT);
1100 CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clGetImageRequirementsInfoEXT pfn_clGetImageRequirementsInfoEXT = nullptr;
1101 #endif
1102
1103 #if defined(cl_ext_device_fission)
1104 CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCreateSubDevicesEXT);
1105 CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCreateSubDevicesEXT
1106 pfn_clCreateSubDevicesEXT = nullptr;
1107 #endif
1108
1109 namespace detail {
1110
1111 // Generic getInfoHelper. The final parameter is used to guide overload
1112 // resolution: the actual parameter passed is an int, which makes this
1113 // a worse conversion sequence than a specialization that declares the
1114 // parameter as an int.
1115 template<typename Functor, typename T>
getInfoHelper(Functor f,cl_uint name,T * param,long)1116 inline cl_int getInfoHelper(Functor f, cl_uint name, T* param, long)
1117 {
1118 return f(name, sizeof(T), param, nullptr);
1119 }
1120
1121 // Specialized for getInfo<CL_PROGRAM_BINARIES>
1122 // Assumes that the output vector was correctly resized on the way in
1123 template <typename Func>
getInfoHelper(Func f,cl_uint name,vector<vector<unsigned char>> * param,int)1124 inline cl_int getInfoHelper(Func f, cl_uint name, vector<vector<unsigned char>>* param, int)
1125 {
1126 if (name != CL_PROGRAM_BINARIES) {
1127 return CL_INVALID_VALUE;
1128 }
1129 if (param) {
1130 // Create array of pointers, calculate total size and pass pointer array in
1131 size_type numBinaries = param->size();
1132 vector<unsigned char*> binariesPointers(numBinaries);
1133
1134 for (size_type i = 0; i < numBinaries; ++i)
1135 {
1136 binariesPointers[i] = (*param)[i].data();
1137 }
1138
1139 cl_int err = f(name, numBinaries * sizeof(unsigned char*), binariesPointers.data(), nullptr);
1140
1141 if (err != CL_SUCCESS) {
1142 return err;
1143 }
1144 }
1145
1146
1147 return CL_SUCCESS;
1148 }
1149
1150 // Specialized getInfoHelper for vector params
1151 template <typename Func, typename T>
getInfoHelper(Func f,cl_uint name,vector<T> * param,long)1152 inline cl_int getInfoHelper(Func f, cl_uint name, vector<T>* param, long)
1153 {
1154 size_type required;
1155 cl_int err = f(name, 0, nullptr, &required);
1156 if (err != CL_SUCCESS) {
1157 return err;
1158 }
1159 const size_type elements = required / sizeof(T);
1160
1161 // Temporary to avoid changing param on an error
1162 vector<T> localData(elements);
1163 err = f(name, required, localData.data(), nullptr);
1164 if (err != CL_SUCCESS) {
1165 return err;
1166 }
1167 if (param) {
1168 *param = std::move(localData);
1169 }
1170
1171 return CL_SUCCESS;
1172 }
1173
1174 /* Specialization for reference-counted types. This depends on the
1175 * existence of Wrapper<T>::cl_type, and none of the other types having the
1176 * cl_type member. Note that simplify specifying the parameter as Wrapper<T>
1177 * does not work, because when using a derived type (e.g. Context) the generic
1178 * template will provide a better match.
1179 */
1180 template <typename Func, typename T>
getInfoHelper(Func f,cl_uint name,vector<T> * param,int,typename T::cl_type=0)1181 inline cl_int getInfoHelper(
1182 Func f, cl_uint name, vector<T>* param, int, typename T::cl_type = 0)
1183 {
1184 size_type required;
1185 cl_int err = f(name, 0, nullptr, &required);
1186 if (err != CL_SUCCESS) {
1187 return err;
1188 }
1189
1190 const size_type elements = required / sizeof(typename T::cl_type);
1191
1192 vector<typename T::cl_type> value(elements);
1193 err = f(name, required, value.data(), nullptr);
1194 if (err != CL_SUCCESS) {
1195 return err;
1196 }
1197
1198 if (param) {
1199 // Assign to convert CL type to T for each element
1200 param->resize(elements);
1201
1202 // Assign to param, constructing with retain behaviour
1203 // to correctly capture each underlying CL object
1204 for (size_type i = 0; i < elements; i++) {
1205 (*param)[i] = T(value[i], true);
1206 }
1207 }
1208 return CL_SUCCESS;
1209 }
1210
1211 // Specialized GetInfoHelper for string params
1212 template <typename Func>
getInfoHelper(Func f,cl_uint name,string * param,long)1213 inline cl_int getInfoHelper(Func f, cl_uint name, string* param, long)
1214 {
1215 size_type required;
1216 cl_int err = f(name, 0, nullptr, &required);
1217 if (err != CL_SUCCESS) {
1218 return err;
1219 }
1220
1221 // std::string has a constant data member
1222 // a char vector does not
1223 if (required > 0) {
1224 vector<char> value(required);
1225 err = f(name, required, value.data(), nullptr);
1226 if (err != CL_SUCCESS) {
1227 return err;
1228 }
1229 if (param) {
1230 param->assign(value.begin(), value.end() - 1);
1231 }
1232 }
1233 else if (param) {
1234 param->assign("");
1235 }
1236 return CL_SUCCESS;
1237 }
1238
1239 // Specialized GetInfoHelper for clsize_t params
1240 template <typename Func, size_type N>
getInfoHelper(Func f,cl_uint name,array<size_type,N> * param,long)1241 inline cl_int getInfoHelper(Func f, cl_uint name, array<size_type, N>* param, long)
1242 {
1243 size_type required;
1244 cl_int err = f(name, 0, nullptr, &required);
1245 if (err != CL_SUCCESS) {
1246 return err;
1247 }
1248
1249 size_type elements = required / sizeof(size_type);
1250 vector<size_type> value(elements, 0);
1251
1252 err = f(name, required, value.data(), nullptr);
1253 if (err != CL_SUCCESS) {
1254 return err;
1255 }
1256
1257 // Bound the copy with N to prevent overruns
1258 // if passed N > than the amount copied
1259 if (elements > N) {
1260 elements = N;
1261 }
1262 for (size_type i = 0; i < elements; ++i) {
1263 (*param)[i] = value[i];
1264 }
1265
1266 return CL_SUCCESS;
1267 }
1268
1269 template<typename T> struct ReferenceHandler;
1270
1271 /* Specialization for reference-counted types. This depends on the
1272 * existence of Wrapper<T>::cl_type, and none of the other types having the
1273 * cl_type member. Note that simplify specifying the parameter as Wrapper<T>
1274 * does not work, because when using a derived type (e.g. Context) the generic
1275 * template will provide a better match.
1276 */
1277 template<typename Func, typename T>
getInfoHelper(Func f,cl_uint name,T * param,int,typename T::cl_type=0)1278 inline cl_int getInfoHelper(Func f, cl_uint name, T* param, int, typename T::cl_type = 0)
1279 {
1280 typename T::cl_type value;
1281 cl_int err = f(name, sizeof(value), &value, nullptr);
1282 if (err != CL_SUCCESS) {
1283 return err;
1284 }
1285 *param = value;
1286 if (value != nullptr)
1287 {
1288 err = param->retain();
1289 if (err != CL_SUCCESS) {
1290 return err;
1291 }
1292 }
1293 return CL_SUCCESS;
1294 }
1295
1296 #define CL_HPP_PARAM_NAME_INFO_1_0_(F) \
1297 F(cl_platform_info, CL_PLATFORM_PROFILE, string) \
1298 F(cl_platform_info, CL_PLATFORM_VERSION, string) \
1299 F(cl_platform_info, CL_PLATFORM_NAME, string) \
1300 F(cl_platform_info, CL_PLATFORM_VENDOR, string) \
1301 F(cl_platform_info, CL_PLATFORM_EXTENSIONS, string) \
1302 \
1303 F(cl_device_info, CL_DEVICE_TYPE, cl_device_type) \
1304 F(cl_device_info, CL_DEVICE_VENDOR_ID, cl_uint) \
1305 F(cl_device_info, CL_DEVICE_MAX_COMPUTE_UNITS, cl_uint) \
1306 F(cl_device_info, CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS, cl_uint) \
1307 F(cl_device_info, CL_DEVICE_MAX_WORK_GROUP_SIZE, size_type) \
1308 F(cl_device_info, CL_DEVICE_MAX_WORK_ITEM_SIZES, cl::vector<size_type>) \
1309 F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR, cl_uint) \
1310 F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT, cl_uint) \
1311 F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT, cl_uint) \
1312 F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG, cl_uint) \
1313 F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT, cl_uint) \
1314 F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE, cl_uint) \
1315 F(cl_device_info, CL_DEVICE_MAX_CLOCK_FREQUENCY, cl_uint) \
1316 F(cl_device_info, CL_DEVICE_ADDRESS_BITS, cl_uint) \
1317 F(cl_device_info, CL_DEVICE_MAX_READ_IMAGE_ARGS, cl_uint) \
1318 F(cl_device_info, CL_DEVICE_MAX_WRITE_IMAGE_ARGS, cl_uint) \
1319 F(cl_device_info, CL_DEVICE_MAX_MEM_ALLOC_SIZE, cl_ulong) \
1320 F(cl_device_info, CL_DEVICE_IMAGE2D_MAX_WIDTH, size_type) \
1321 F(cl_device_info, CL_DEVICE_IMAGE2D_MAX_HEIGHT, size_type) \
1322 F(cl_device_info, CL_DEVICE_IMAGE3D_MAX_WIDTH, size_type) \
1323 F(cl_device_info, CL_DEVICE_IMAGE3D_MAX_HEIGHT, size_type) \
1324 F(cl_device_info, CL_DEVICE_IMAGE3D_MAX_DEPTH, size_type) \
1325 F(cl_device_info, CL_DEVICE_IMAGE_SUPPORT, cl_bool) \
1326 F(cl_device_info, CL_DEVICE_MAX_PARAMETER_SIZE, size_type) \
1327 F(cl_device_info, CL_DEVICE_MAX_SAMPLERS, cl_uint) \
1328 F(cl_device_info, CL_DEVICE_MEM_BASE_ADDR_ALIGN, cl_uint) \
1329 F(cl_device_info, CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE, cl_uint) \
1330 F(cl_device_info, CL_DEVICE_SINGLE_FP_CONFIG, cl_device_fp_config) \
1331 F(cl_device_info, CL_DEVICE_DOUBLE_FP_CONFIG, cl_device_fp_config) \
1332 F(cl_device_info, CL_DEVICE_HALF_FP_CONFIG, cl_device_fp_config) \
1333 F(cl_device_info, CL_DEVICE_GLOBAL_MEM_CACHE_TYPE, cl_device_mem_cache_type) \
1334 F(cl_device_info, CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE, cl_uint)\
1335 F(cl_device_info, CL_DEVICE_GLOBAL_MEM_CACHE_SIZE, cl_ulong) \
1336 F(cl_device_info, CL_DEVICE_GLOBAL_MEM_SIZE, cl_ulong) \
1337 F(cl_device_info, CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE, cl_ulong) \
1338 F(cl_device_info, CL_DEVICE_MAX_CONSTANT_ARGS, cl_uint) \
1339 F(cl_device_info, CL_DEVICE_LOCAL_MEM_TYPE, cl_device_local_mem_type) \
1340 F(cl_device_info, CL_DEVICE_LOCAL_MEM_SIZE, cl_ulong) \
1341 F(cl_device_info, CL_DEVICE_ERROR_CORRECTION_SUPPORT, cl_bool) \
1342 F(cl_device_info, CL_DEVICE_PROFILING_TIMER_RESOLUTION, size_type) \
1343 F(cl_device_info, CL_DEVICE_ENDIAN_LITTLE, cl_bool) \
1344 F(cl_device_info, CL_DEVICE_AVAILABLE, cl_bool) \
1345 F(cl_device_info, CL_DEVICE_COMPILER_AVAILABLE, cl_bool) \
1346 F(cl_device_info, CL_DEVICE_EXECUTION_CAPABILITIES, cl_device_exec_capabilities) \
1347 F(cl_device_info, CL_DEVICE_PLATFORM, cl::Platform) \
1348 F(cl_device_info, CL_DEVICE_NAME, string) \
1349 F(cl_device_info, CL_DEVICE_VENDOR, string) \
1350 F(cl_device_info, CL_DRIVER_VERSION, string) \
1351 F(cl_device_info, CL_DEVICE_PROFILE, string) \
1352 F(cl_device_info, CL_DEVICE_VERSION, string) \
1353 F(cl_device_info, CL_DEVICE_EXTENSIONS, string) \
1354 \
1355 F(cl_context_info, CL_CONTEXT_REFERENCE_COUNT, cl_uint) \
1356 F(cl_context_info, CL_CONTEXT_DEVICES, cl::vector<Device>) \
1357 F(cl_context_info, CL_CONTEXT_PROPERTIES, cl::vector<cl_context_properties>) \
1358 \
1359 F(cl_event_info, CL_EVENT_COMMAND_QUEUE, cl::CommandQueue) \
1360 F(cl_event_info, CL_EVENT_COMMAND_TYPE, cl_command_type) \
1361 F(cl_event_info, CL_EVENT_REFERENCE_COUNT, cl_uint) \
1362 F(cl_event_info, CL_EVENT_COMMAND_EXECUTION_STATUS, cl_int) \
1363 \
1364 F(cl_profiling_info, CL_PROFILING_COMMAND_QUEUED, cl_ulong) \
1365 F(cl_profiling_info, CL_PROFILING_COMMAND_SUBMIT, cl_ulong) \
1366 F(cl_profiling_info, CL_PROFILING_COMMAND_START, cl_ulong) \
1367 F(cl_profiling_info, CL_PROFILING_COMMAND_END, cl_ulong) \
1368 \
1369 F(cl_mem_info, CL_MEM_TYPE, cl_mem_object_type) \
1370 F(cl_mem_info, CL_MEM_FLAGS, cl_mem_flags) \
1371 F(cl_mem_info, CL_MEM_SIZE, size_type) \
1372 F(cl_mem_info, CL_MEM_HOST_PTR, void*) \
1373 F(cl_mem_info, CL_MEM_MAP_COUNT, cl_uint) \
1374 F(cl_mem_info, CL_MEM_REFERENCE_COUNT, cl_uint) \
1375 F(cl_mem_info, CL_MEM_CONTEXT, cl::Context) \
1376 \
1377 F(cl_image_info, CL_IMAGE_FORMAT, cl_image_format) \
1378 F(cl_image_info, CL_IMAGE_ELEMENT_SIZE, size_type) \
1379 F(cl_image_info, CL_IMAGE_ROW_PITCH, size_type) \
1380 F(cl_image_info, CL_IMAGE_SLICE_PITCH, size_type) \
1381 F(cl_image_info, CL_IMAGE_WIDTH, size_type) \
1382 F(cl_image_info, CL_IMAGE_HEIGHT, size_type) \
1383 F(cl_image_info, CL_IMAGE_DEPTH, size_type) \
1384 \
1385 F(cl_sampler_info, CL_SAMPLER_REFERENCE_COUNT, cl_uint) \
1386 F(cl_sampler_info, CL_SAMPLER_CONTEXT, cl::Context) \
1387 F(cl_sampler_info, CL_SAMPLER_NORMALIZED_COORDS, cl_bool) \
1388 F(cl_sampler_info, CL_SAMPLER_ADDRESSING_MODE, cl_addressing_mode) \
1389 F(cl_sampler_info, CL_SAMPLER_FILTER_MODE, cl_filter_mode) \
1390 \
1391 F(cl_program_info, CL_PROGRAM_REFERENCE_COUNT, cl_uint) \
1392 F(cl_program_info, CL_PROGRAM_CONTEXT, cl::Context) \
1393 F(cl_program_info, CL_PROGRAM_NUM_DEVICES, cl_uint) \
1394 F(cl_program_info, CL_PROGRAM_DEVICES, cl::vector<Device>) \
1395 F(cl_program_info, CL_PROGRAM_SOURCE, string) \
1396 F(cl_program_info, CL_PROGRAM_BINARY_SIZES, cl::vector<size_type>) \
1397 F(cl_program_info, CL_PROGRAM_BINARIES, cl::vector<cl::vector<unsigned char>>) \
1398 \
1399 F(cl_program_build_info, CL_PROGRAM_BUILD_STATUS, cl_build_status) \
1400 F(cl_program_build_info, CL_PROGRAM_BUILD_OPTIONS, string) \
1401 F(cl_program_build_info, CL_PROGRAM_BUILD_LOG, string) \
1402 \
1403 F(cl_kernel_info, CL_KERNEL_FUNCTION_NAME, string) \
1404 F(cl_kernel_info, CL_KERNEL_NUM_ARGS, cl_uint) \
1405 F(cl_kernel_info, CL_KERNEL_REFERENCE_COUNT, cl_uint) \
1406 F(cl_kernel_info, CL_KERNEL_CONTEXT, cl::Context) \
1407 F(cl_kernel_info, CL_KERNEL_PROGRAM, cl::Program) \
1408 \
1409 F(cl_kernel_work_group_info, CL_KERNEL_WORK_GROUP_SIZE, size_type) \
1410 F(cl_kernel_work_group_info, CL_KERNEL_COMPILE_WORK_GROUP_SIZE, cl::detail::size_t_array) \
1411 F(cl_kernel_work_group_info, CL_KERNEL_LOCAL_MEM_SIZE, cl_ulong) \
1412 \
1413 F(cl_command_queue_info, CL_QUEUE_CONTEXT, cl::Context) \
1414 F(cl_command_queue_info, CL_QUEUE_DEVICE, cl::Device) \
1415 F(cl_command_queue_info, CL_QUEUE_REFERENCE_COUNT, cl_uint) \
1416 F(cl_command_queue_info, CL_QUEUE_PROPERTIES, cl_command_queue_properties)
1417
1418
1419 #define CL_HPP_PARAM_NAME_INFO_1_1_(F) \
1420 F(cl_context_info, CL_CONTEXT_NUM_DEVICES, cl_uint)\
1421 F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF, cl_uint) \
1422 F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR, cl_uint) \
1423 F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT, cl_uint) \
1424 F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_INT, cl_uint) \
1425 F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG, cl_uint) \
1426 F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT, cl_uint) \
1427 F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE, cl_uint) \
1428 F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF, cl_uint) \
1429 F(cl_device_info, CL_DEVICE_OPENCL_C_VERSION, string) \
1430 \
1431 F(cl_mem_info, CL_MEM_ASSOCIATED_MEMOBJECT, cl::Memory) \
1432 F(cl_mem_info, CL_MEM_OFFSET, size_type) \
1433 \
1434 F(cl_kernel_work_group_info, CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE, size_type) \
1435 F(cl_kernel_work_group_info, CL_KERNEL_PRIVATE_MEM_SIZE, cl_ulong) \
1436 \
1437 F(cl_event_info, CL_EVENT_CONTEXT, cl::Context)
1438
1439 #define CL_HPP_PARAM_NAME_INFO_1_2_(F) \
1440 F(cl_program_info, CL_PROGRAM_NUM_KERNELS, size_type) \
1441 F(cl_program_info, CL_PROGRAM_KERNEL_NAMES, string) \
1442 \
1443 F(cl_program_build_info, CL_PROGRAM_BINARY_TYPE, cl_program_binary_type) \
1444 \
1445 F(cl_kernel_info, CL_KERNEL_ATTRIBUTES, string) \
1446 \
1447 F(cl_kernel_arg_info, CL_KERNEL_ARG_ADDRESS_QUALIFIER, cl_kernel_arg_address_qualifier) \
1448 F(cl_kernel_arg_info, CL_KERNEL_ARG_ACCESS_QUALIFIER, cl_kernel_arg_access_qualifier) \
1449 F(cl_kernel_arg_info, CL_KERNEL_ARG_TYPE_NAME, string) \
1450 F(cl_kernel_arg_info, CL_KERNEL_ARG_NAME, string) \
1451 F(cl_kernel_arg_info, CL_KERNEL_ARG_TYPE_QUALIFIER, cl_kernel_arg_type_qualifier) \
1452 \
1453 F(cl_kernel_work_group_info, CL_KERNEL_GLOBAL_WORK_SIZE, cl::detail::size_t_array) \
1454 \
1455 F(cl_device_info, CL_DEVICE_LINKER_AVAILABLE, cl_bool) \
1456 F(cl_device_info, CL_DEVICE_IMAGE_MAX_BUFFER_SIZE, size_type) \
1457 F(cl_device_info, CL_DEVICE_IMAGE_MAX_ARRAY_SIZE, size_type) \
1458 F(cl_device_info, CL_DEVICE_PARENT_DEVICE, cl::Device) \
1459 F(cl_device_info, CL_DEVICE_PARTITION_MAX_SUB_DEVICES, cl_uint) \
1460 F(cl_device_info, CL_DEVICE_PARTITION_PROPERTIES, cl::vector<cl_device_partition_property>) \
1461 F(cl_device_info, CL_DEVICE_PARTITION_TYPE, cl::vector<cl_device_partition_property>) \
1462 F(cl_device_info, CL_DEVICE_REFERENCE_COUNT, cl_uint) \
1463 F(cl_device_info, CL_DEVICE_PREFERRED_INTEROP_USER_SYNC, cl_bool) \
1464 F(cl_device_info, CL_DEVICE_PARTITION_AFFINITY_DOMAIN, cl_device_affinity_domain) \
1465 F(cl_device_info, CL_DEVICE_BUILT_IN_KERNELS, string) \
1466 F(cl_device_info, CL_DEVICE_PRINTF_BUFFER_SIZE, size_type) \
1467 \
1468 F(cl_image_info, CL_IMAGE_ARRAY_SIZE, size_type) \
1469 F(cl_image_info, CL_IMAGE_NUM_MIP_LEVELS, cl_uint) \
1470 F(cl_image_info, CL_IMAGE_NUM_SAMPLES, cl_uint)
1471
1472 #define CL_HPP_PARAM_NAME_INFO_2_0_(F) \
1473 F(cl_device_info, CL_DEVICE_QUEUE_ON_HOST_PROPERTIES, cl_command_queue_properties) \
1474 F(cl_device_info, CL_DEVICE_QUEUE_ON_DEVICE_PROPERTIES, cl_command_queue_properties) \
1475 F(cl_device_info, CL_DEVICE_QUEUE_ON_DEVICE_PREFERRED_SIZE, cl_uint) \
1476 F(cl_device_info, CL_DEVICE_QUEUE_ON_DEVICE_MAX_SIZE, cl_uint) \
1477 F(cl_device_info, CL_DEVICE_MAX_ON_DEVICE_QUEUES, cl_uint) \
1478 F(cl_device_info, CL_DEVICE_MAX_ON_DEVICE_EVENTS, cl_uint) \
1479 F(cl_device_info, CL_DEVICE_MAX_PIPE_ARGS, cl_uint) \
1480 F(cl_device_info, CL_DEVICE_PIPE_MAX_ACTIVE_RESERVATIONS, cl_uint) \
1481 F(cl_device_info, CL_DEVICE_PIPE_MAX_PACKET_SIZE, cl_uint) \
1482 F(cl_device_info, CL_DEVICE_SVM_CAPABILITIES, cl_device_svm_capabilities) \
1483 F(cl_device_info, CL_DEVICE_PREFERRED_PLATFORM_ATOMIC_ALIGNMENT, cl_uint) \
1484 F(cl_device_info, CL_DEVICE_PREFERRED_GLOBAL_ATOMIC_ALIGNMENT, cl_uint) \
1485 F(cl_device_info, CL_DEVICE_PREFERRED_LOCAL_ATOMIC_ALIGNMENT, cl_uint) \
1486 F(cl_device_info, CL_DEVICE_IMAGE_PITCH_ALIGNMENT, cl_uint) \
1487 F(cl_device_info, CL_DEVICE_IMAGE_BASE_ADDRESS_ALIGNMENT, cl_uint) \
1488 F(cl_device_info, CL_DEVICE_MAX_READ_WRITE_IMAGE_ARGS, cl_uint ) \
1489 F(cl_device_info, CL_DEVICE_MAX_GLOBAL_VARIABLE_SIZE, size_type ) \
1490 F(cl_device_info, CL_DEVICE_GLOBAL_VARIABLE_PREFERRED_TOTAL_SIZE, size_type ) \
1491 F(cl_profiling_info, CL_PROFILING_COMMAND_COMPLETE, cl_ulong) \
1492 F(cl_kernel_exec_info, CL_KERNEL_EXEC_INFO_SVM_FINE_GRAIN_SYSTEM, cl_bool) \
1493 F(cl_kernel_exec_info, CL_KERNEL_EXEC_INFO_SVM_PTRS, void**) \
1494 F(cl_command_queue_info, CL_QUEUE_SIZE, cl_uint) \
1495 F(cl_mem_info, CL_MEM_USES_SVM_POINTER, cl_bool) \
1496 F(cl_program_build_info, CL_PROGRAM_BUILD_GLOBAL_VARIABLE_TOTAL_SIZE, size_type) \
1497 F(cl_pipe_info, CL_PIPE_PACKET_SIZE, cl_uint) \
1498 F(cl_pipe_info, CL_PIPE_MAX_PACKETS, cl_uint)
1499
1500 #define CL_HPP_PARAM_NAME_INFO_SUBGROUP_KHR_(F) \
1501 F(cl_kernel_sub_group_info, CL_KERNEL_MAX_SUB_GROUP_SIZE_FOR_NDRANGE_KHR, size_type) \
1502 F(cl_kernel_sub_group_info, CL_KERNEL_SUB_GROUP_COUNT_FOR_NDRANGE_KHR, size_type)
1503
1504 #define CL_HPP_PARAM_NAME_INFO_IL_KHR_(F) \
1505 F(cl_device_info, CL_DEVICE_IL_VERSION_KHR, string) \
1506 F(cl_program_info, CL_PROGRAM_IL_KHR, cl::vector<unsigned char>)
1507
1508 #define CL_HPP_PARAM_NAME_INFO_2_1_(F) \
1509 F(cl_platform_info, CL_PLATFORM_HOST_TIMER_RESOLUTION, cl_ulong) \
1510 F(cl_program_info, CL_PROGRAM_IL, cl::vector<unsigned char>) \
1511 F(cl_device_info, CL_DEVICE_MAX_NUM_SUB_GROUPS, cl_uint) \
1512 F(cl_device_info, CL_DEVICE_IL_VERSION, string) \
1513 F(cl_device_info, CL_DEVICE_SUB_GROUP_INDEPENDENT_FORWARD_PROGRESS, cl_bool) \
1514 F(cl_command_queue_info, CL_QUEUE_DEVICE_DEFAULT, cl::DeviceCommandQueue) \
1515 F(cl_kernel_sub_group_info, CL_KERNEL_MAX_SUB_GROUP_SIZE_FOR_NDRANGE, size_type) \
1516 F(cl_kernel_sub_group_info, CL_KERNEL_SUB_GROUP_COUNT_FOR_NDRANGE, size_type) \
1517 F(cl_kernel_sub_group_info, CL_KERNEL_LOCAL_SIZE_FOR_SUB_GROUP_COUNT, cl::detail::size_t_array) \
1518 F(cl_kernel_sub_group_info, CL_KERNEL_MAX_NUM_SUB_GROUPS, size_type) \
1519 F(cl_kernel_sub_group_info, CL_KERNEL_COMPILE_NUM_SUB_GROUPS, size_type)
1520
1521 #define CL_HPP_PARAM_NAME_INFO_2_2_(F) \
1522 F(cl_program_info, CL_PROGRAM_SCOPE_GLOBAL_CTORS_PRESENT, cl_bool) \
1523 F(cl_program_info, CL_PROGRAM_SCOPE_GLOBAL_DTORS_PRESENT, cl_bool)
1524
1525 #define CL_HPP_PARAM_NAME_DEVICE_FISSION_EXT_(F) \
1526 F(cl_device_info, CL_DEVICE_PARENT_DEVICE_EXT, cl::Device) \
1527 F(cl_device_info, CL_DEVICE_PARTITION_TYPES_EXT, cl::vector<cl_device_partition_property_ext>) \
1528 F(cl_device_info, CL_DEVICE_AFFINITY_DOMAINS_EXT, cl::vector<cl_device_partition_property_ext>) \
1529 F(cl_device_info, CL_DEVICE_REFERENCE_COUNT_EXT , cl_uint) \
1530 F(cl_device_info, CL_DEVICE_PARTITION_STYLE_EXT, cl::vector<cl_device_partition_property_ext>)
1531
1532 #define CL_HPP_PARAM_NAME_CL_KHR_EXTENDED_VERSIONING_CL3_SHARED_(F) \
1533 F(cl_platform_info, CL_PLATFORM_NUMERIC_VERSION_KHR, cl_version_khr) \
1534 F(cl_platform_info, CL_PLATFORM_EXTENSIONS_WITH_VERSION_KHR, cl::vector<cl_name_version_khr>) \
1535 \
1536 F(cl_device_info, CL_DEVICE_NUMERIC_VERSION_KHR, cl_version_khr) \
1537 F(cl_device_info, CL_DEVICE_EXTENSIONS_WITH_VERSION_KHR, cl::vector<cl_name_version_khr>) \
1538 F(cl_device_info, CL_DEVICE_ILS_WITH_VERSION_KHR, cl::vector<cl_name_version_khr>) \
1539 F(cl_device_info, CL_DEVICE_BUILT_IN_KERNELS_WITH_VERSION_KHR, cl::vector<cl_name_version_khr>)
1540
1541 #define CL_HPP_PARAM_NAME_CL_KHR_EXTENDED_VERSIONING_KHRONLY_(F) \
1542 F(cl_device_info, CL_DEVICE_OPENCL_C_NUMERIC_VERSION_KHR, cl_version_khr)
1543
1544 // Note: the query for CL_SEMAPHORE_DEVICE_HANDLE_LIST_KHR is handled specially!
1545 #define CL_HPP_PARAM_NAME_CL_KHR_SEMAPHORE_(F) \
1546 F(cl_semaphore_info_khr, CL_SEMAPHORE_CONTEXT_KHR, cl::Context) \
1547 F(cl_semaphore_info_khr, CL_SEMAPHORE_REFERENCE_COUNT_KHR, cl_uint) \
1548 F(cl_semaphore_info_khr, CL_SEMAPHORE_PROPERTIES_KHR, cl::vector<cl_semaphore_properties_khr>) \
1549 F(cl_semaphore_info_khr, CL_SEMAPHORE_TYPE_KHR, cl_semaphore_type_khr) \
1550 F(cl_semaphore_info_khr, CL_SEMAPHORE_PAYLOAD_KHR, cl_semaphore_payload_khr) \
1551 F(cl_platform_info, CL_PLATFORM_SEMAPHORE_TYPES_KHR, cl::vector<cl_semaphore_type_khr>) \
1552 F(cl_device_info, CL_DEVICE_SEMAPHORE_TYPES_KHR, cl::vector<cl_semaphore_type_khr>) \
1553
1554 #define CL_HPP_PARAM_NAME_CL_KHR_EXTERNAL_MEMORY_(F) \
1555 F(cl_device_info, CL_DEVICE_EXTERNAL_MEMORY_IMPORT_HANDLE_TYPES_KHR, cl::vector<cl::ExternalMemoryType>) \
1556 F(cl_platform_info, CL_PLATFORM_EXTERNAL_MEMORY_IMPORT_HANDLE_TYPES_KHR, cl::vector<cl::ExternalMemoryType>)
1557
1558 #define CL_HPP_PARAM_NAME_CL_KHR_EXTERNAL_SEMAPHORE_(F) \
1559 F(cl_platform_info, CL_PLATFORM_SEMAPHORE_IMPORT_HANDLE_TYPES_KHR, cl::vector<cl_external_semaphore_handle_type_khr>) \
1560 F(cl_platform_info, CL_PLATFORM_SEMAPHORE_EXPORT_HANDLE_TYPES_KHR, cl::vector<cl_external_semaphore_handle_type_khr>) \
1561 F(cl_device_info, CL_DEVICE_SEMAPHORE_IMPORT_HANDLE_TYPES_KHR, cl::vector<cl_external_semaphore_handle_type_khr>) \
1562 F(cl_device_info, CL_DEVICE_SEMAPHORE_EXPORT_HANDLE_TYPES_KHR, cl::vector<cl_external_semaphore_handle_type_khr>) \
1563 F(cl_semaphore_info_khr, CL_SEMAPHORE_EXPORT_HANDLE_TYPES_KHR, cl::vector<cl_external_semaphore_handle_type_khr>) \
1564
1565 #define CL_HPP_PARAM_NAME_CL_KHR_EXTERNAL_SEMAPHORE_DX_FENCE_EXT(F) \
1566 F(cl_external_semaphore_handle_type_khr, CL_SEMAPHORE_HANDLE_D3D12_FENCE_KHR, void*) \
1567
1568 #define CL_HPP_PARAM_NAME_CL_KHR_EXTERNAL_SEMAPHORE_OPAQUE_FD_EXT(F) \
1569 F(cl_external_semaphore_handle_type_khr, CL_SEMAPHORE_HANDLE_OPAQUE_FD_KHR, int) \
1570
1571 #define CL_HPP_PARAM_NAME_CL_KHR_EXTERNAL_SEMAPHORE_SYNC_FD_EXT(F) \
1572 F(cl_external_semaphore_handle_type_khr, CL_SEMAPHORE_HANDLE_SYNC_FD_KHR, int) \
1573
1574 #define CL_HPP_PARAM_NAME_CL_KHR_EXTERNAL_SEMAPHORE_WIN32_EXT(F) \
1575 F(cl_external_semaphore_handle_type_khr, CL_SEMAPHORE_HANDLE_OPAQUE_WIN32_KHR, void*) \
1576 F(cl_external_semaphore_handle_type_khr, CL_SEMAPHORE_HANDLE_OPAQUE_WIN32_KMT_KHR, void*) \
1577
1578 #define CL_HPP_PARAM_NAME_INFO_3_0_(F) \
1579 F(cl_platform_info, CL_PLATFORM_NUMERIC_VERSION, cl_version) \
1580 F(cl_platform_info, CL_PLATFORM_EXTENSIONS_WITH_VERSION, cl::vector<cl_name_version>) \
1581 \
1582 F(cl_device_info, CL_DEVICE_NUMERIC_VERSION, cl_version) \
1583 F(cl_device_info, CL_DEVICE_EXTENSIONS_WITH_VERSION, cl::vector<cl_name_version>) \
1584 F(cl_device_info, CL_DEVICE_ILS_WITH_VERSION, cl::vector<cl_name_version>) \
1585 F(cl_device_info, CL_DEVICE_BUILT_IN_KERNELS_WITH_VERSION, cl::vector<cl_name_version>) \
1586 F(cl_device_info, CL_DEVICE_ATOMIC_MEMORY_CAPABILITIES, cl_device_atomic_capabilities) \
1587 F(cl_device_info, CL_DEVICE_ATOMIC_FENCE_CAPABILITIES, cl_device_atomic_capabilities) \
1588 F(cl_device_info, CL_DEVICE_NON_UNIFORM_WORK_GROUP_SUPPORT, cl_bool) \
1589 F(cl_device_info, CL_DEVICE_OPENCL_C_ALL_VERSIONS, cl::vector<cl_name_version>) \
1590 F(cl_device_info, CL_DEVICE_PREFERRED_WORK_GROUP_SIZE_MULTIPLE, size_type) \
1591 F(cl_device_info, CL_DEVICE_WORK_GROUP_COLLECTIVE_FUNCTIONS_SUPPORT, cl_bool) \
1592 F(cl_device_info, CL_DEVICE_GENERIC_ADDRESS_SPACE_SUPPORT, cl_bool) \
1593 F(cl_device_info, CL_DEVICE_OPENCL_C_FEATURES, cl::vector<cl_name_version>) \
1594 F(cl_device_info, CL_DEVICE_DEVICE_ENQUEUE_CAPABILITIES, cl_device_device_enqueue_capabilities) \
1595 F(cl_device_info, CL_DEVICE_PIPE_SUPPORT, cl_bool) \
1596 F(cl_device_info, CL_DEVICE_LATEST_CONFORMANCE_VERSION_PASSED, string) \
1597 \
1598 F(cl_command_queue_info, CL_QUEUE_PROPERTIES_ARRAY, cl::vector<cl_queue_properties>) \
1599 F(cl_mem_info, CL_MEM_PROPERTIES, cl::vector<cl_mem_properties>) \
1600 F(cl_pipe_info, CL_PIPE_PROPERTIES, cl::vector<cl_pipe_properties>) \
1601 F(cl_sampler_info, CL_SAMPLER_PROPERTIES, cl::vector<cl_sampler_properties>) \
1602
1603 #define CL_HPP_PARAM_NAME_CL_IMAGE_REQUIREMENTS_EXT(F) \
1604 F(cl_image_requirements_info_ext, CL_IMAGE_REQUIREMENTS_ROW_PITCH_ALIGNMENT_EXT, size_type) \
1605 F(cl_image_requirements_info_ext, CL_IMAGE_REQUIREMENTS_BASE_ADDRESS_ALIGNMENT_EXT, size_type) \
1606 F(cl_image_requirements_info_ext, CL_IMAGE_REQUIREMENTS_SIZE_EXT, size_type) \
1607 F(cl_image_requirements_info_ext, CL_IMAGE_REQUIREMENTS_MAX_WIDTH_EXT, cl_uint) \
1608 F(cl_image_requirements_info_ext, CL_IMAGE_REQUIREMENTS_MAX_HEIGHT_EXT, cl_uint) \
1609 F(cl_image_requirements_info_ext, CL_IMAGE_REQUIREMENTS_MAX_DEPTH_EXT, cl_uint) \
1610 F(cl_image_requirements_info_ext, CL_IMAGE_REQUIREMENTS_MAX_ARRAY_SIZE_EXT, cl_uint) \
1611
1612 #define CL_HPP_PARAM_NAME_CL_IMAGE_REQUIREMENTS_SLICE_PITCH_ALIGNMENT_EXT(F) \
1613 F(cl_image_requirements_info_ext, CL_IMAGE_REQUIREMENTS_SLICE_PITCH_ALIGNMENT_EXT, size_type) \
1614
1615 template <typename enum_type, cl_int Name>
1616 struct param_traits {};
1617
1618 #define CL_HPP_DECLARE_PARAM_TRAITS_(token, param_name, T) \
1619 struct token; \
1620 template<> \
1621 struct param_traits<detail:: token,param_name> \
1622 { \
1623 enum { value = param_name }; \
1624 typedef T param_type; \
1625 };
1626
1627 CL_HPP_PARAM_NAME_INFO_1_0_(CL_HPP_DECLARE_PARAM_TRAITS_)
1628 #if CL_HPP_TARGET_OPENCL_VERSION >= 110
1629 CL_HPP_PARAM_NAME_INFO_1_1_(CL_HPP_DECLARE_PARAM_TRAITS_)
1630 #endif // CL_HPP_TARGET_OPENCL_VERSION >= 110
1631 #if CL_HPP_TARGET_OPENCL_VERSION >= 120
1632 CL_HPP_PARAM_NAME_INFO_1_2_(CL_HPP_DECLARE_PARAM_TRAITS_)
1633 #endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
1634 #if CL_HPP_TARGET_OPENCL_VERSION >= 200
1635 CL_HPP_PARAM_NAME_INFO_2_0_(CL_HPP_DECLARE_PARAM_TRAITS_)
1636 #endif // CL_HPP_TARGET_OPENCL_VERSION >= 200
1637 #if CL_HPP_TARGET_OPENCL_VERSION >= 210
1638 CL_HPP_PARAM_NAME_INFO_2_1_(CL_HPP_DECLARE_PARAM_TRAITS_)
1639 #endif // CL_HPP_TARGET_OPENCL_VERSION >= 210
1640 #if CL_HPP_TARGET_OPENCL_VERSION >= 220
1641 CL_HPP_PARAM_NAME_INFO_2_2_(CL_HPP_DECLARE_PARAM_TRAITS_)
1642 #endif // CL_HPP_TARGET_OPENCL_VERSION >= 220
1643 #if CL_HPP_TARGET_OPENCL_VERSION >= 300
1644 CL_HPP_PARAM_NAME_INFO_3_0_(CL_HPP_DECLARE_PARAM_TRAITS_)
1645 #endif // CL_HPP_TARGET_OPENCL_VERSION >= 300
1646
1647 #if defined(cl_khr_subgroups) && CL_HPP_TARGET_OPENCL_VERSION < 210
1648 CL_HPP_PARAM_NAME_INFO_SUBGROUP_KHR_(CL_HPP_DECLARE_PARAM_TRAITS_)
1649 #endif // #if defined(cl_khr_subgroups) && CL_HPP_TARGET_OPENCL_VERSION < 210
1650
1651 #if defined(cl_khr_il_program) && CL_HPP_TARGET_OPENCL_VERSION < 210
1652 CL_HPP_PARAM_NAME_INFO_IL_KHR_(CL_HPP_DECLARE_PARAM_TRAITS_)
1653 #endif // #if defined(cl_khr_il_program) && CL_HPP_TARGET_OPENCL_VERSION < 210
1654
1655
1656 // Flags deprecated in OpenCL 2.0
1657 #define CL_HPP_PARAM_NAME_INFO_1_0_DEPRECATED_IN_2_0_(F) \
1658 F(cl_device_info, CL_DEVICE_QUEUE_PROPERTIES, cl_command_queue_properties)
1659
1660 #define CL_HPP_PARAM_NAME_INFO_1_1_DEPRECATED_IN_2_0_(F) \
1661 F(cl_device_info, CL_DEVICE_HOST_UNIFIED_MEMORY, cl_bool)
1662
1663 #define CL_HPP_PARAM_NAME_INFO_1_2_DEPRECATED_IN_2_0_(F) \
1664 F(cl_image_info, CL_IMAGE_BUFFER, cl::Buffer)
1665
1666 // Include deprecated query flags based on versions
1667 // Only include deprecated 1.0 flags if 2.0 not active as there is an enum clash
1668 #if CL_HPP_TARGET_OPENCL_VERSION > 100 && CL_HPP_MINIMUM_OPENCL_VERSION < 200 && CL_HPP_TARGET_OPENCL_VERSION < 200
1669 CL_HPP_PARAM_NAME_INFO_1_0_DEPRECATED_IN_2_0_(CL_HPP_DECLARE_PARAM_TRAITS_)
1670 #endif // CL_HPP_MINIMUM_OPENCL_VERSION < 110
1671 #if CL_HPP_TARGET_OPENCL_VERSION > 110 && CL_HPP_MINIMUM_OPENCL_VERSION < 200
1672 CL_HPP_PARAM_NAME_INFO_1_1_DEPRECATED_IN_2_0_(CL_HPP_DECLARE_PARAM_TRAITS_)
1673 #endif // CL_HPP_MINIMUM_OPENCL_VERSION < 120
1674 #if CL_HPP_TARGET_OPENCL_VERSION > 120 && CL_HPP_MINIMUM_OPENCL_VERSION < 200
1675 CL_HPP_PARAM_NAME_INFO_1_2_DEPRECATED_IN_2_0_(CL_HPP_DECLARE_PARAM_TRAITS_)
1676 #endif // CL_HPP_MINIMUM_OPENCL_VERSION < 200
1677
1678 #if defined(cl_ext_device_fission)
1679 CL_HPP_PARAM_NAME_DEVICE_FISSION_EXT_(CL_HPP_DECLARE_PARAM_TRAITS_)
1680 #endif // cl_ext_device_fission
1681
1682 #if defined(cl_khr_extended_versioning)
1683 #if CL_HPP_TARGET_OPENCL_VERSION < 300
1684 CL_HPP_PARAM_NAME_CL_KHR_EXTENDED_VERSIONING_CL3_SHARED_(CL_HPP_DECLARE_PARAM_TRAITS_)
1685 #endif // CL_HPP_TARGET_OPENCL_VERSION < 300
1686 CL_HPP_PARAM_NAME_CL_KHR_EXTENDED_VERSIONING_KHRONLY_(CL_HPP_DECLARE_PARAM_TRAITS_)
1687 #endif // cl_khr_extended_versioning
1688
1689 #if defined(cl_khr_semaphore)
1690 CL_HPP_PARAM_NAME_CL_KHR_SEMAPHORE_(CL_HPP_DECLARE_PARAM_TRAITS_)
1691 #if defined(CL_SEMAPHORE_DEVICE_HANDLE_LIST_KHR)
1692 CL_HPP_DECLARE_PARAM_TRAITS_(cl_semaphore_info_khr, CL_SEMAPHORE_DEVICE_HANDLE_LIST_KHR, cl::vector<cl::Device>)
1693 #endif // defined(CL_SEMAPHORE_DEVICE_HANDLE_LIST_KHR)
1694 #endif // defined(cl_khr_semaphore)
1695
1696 #ifdef cl_khr_external_memory
1697 CL_HPP_PARAM_NAME_CL_KHR_EXTERNAL_MEMORY_(CL_HPP_DECLARE_PARAM_TRAITS_)
1698 #endif // cl_khr_external_memory
1699
1700 #if defined(cl_khr_external_semaphore)
1701 CL_HPP_PARAM_NAME_CL_KHR_EXTERNAL_SEMAPHORE_(CL_HPP_DECLARE_PARAM_TRAITS_)
1702 #endif // cl_khr_external_semaphore
1703
1704 #if defined(cl_khr_external_semaphore_dx_fence)
1705 CL_HPP_PARAM_NAME_CL_KHR_EXTERNAL_SEMAPHORE_DX_FENCE_EXT(CL_HPP_DECLARE_PARAM_TRAITS_)
1706 #endif // cl_khr_external_semaphore_dx_fence
1707 #if defined(cl_khr_external_semaphore_opaque_fd)
1708 CL_HPP_PARAM_NAME_CL_KHR_EXTERNAL_SEMAPHORE_OPAQUE_FD_EXT(CL_HPP_DECLARE_PARAM_TRAITS_)
1709 #endif // cl_khr_external_semaphore_opaque_fd
1710 #if defined(cl_khr_external_semaphore_sync_fd)
1711 CL_HPP_PARAM_NAME_CL_KHR_EXTERNAL_SEMAPHORE_SYNC_FD_EXT(CL_HPP_DECLARE_PARAM_TRAITS_)
1712 #endif // cl_khr_external_semaphore_sync_fd
1713 #if defined(cl_khr_external_semaphore_win32)
1714 CL_HPP_PARAM_NAME_CL_KHR_EXTERNAL_SEMAPHORE_WIN32_EXT(CL_HPP_DECLARE_PARAM_TRAITS_)
1715 #endif // cl_khr_external_semaphore_win32
1716
1717 #if defined(cl_khr_device_uuid)
1718 using uuid_array = array<cl_uchar, CL_UUID_SIZE_KHR>;
1719 using luid_array = array<cl_uchar, CL_LUID_SIZE_KHR>;
CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info,CL_DEVICE_UUID_KHR,uuid_array)1720 CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_UUID_KHR, uuid_array)
1721 CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DRIVER_UUID_KHR, uuid_array)
1722 CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_LUID_VALID_KHR, cl_bool)
1723 CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_LUID_KHR, luid_array)
1724 CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_NODE_MASK_KHR, cl_uint)
1725 #endif
1726
1727 #if defined(cl_khr_pci_bus_info)
1728 CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_PCI_BUS_INFO_KHR, cl_device_pci_bus_info_khr)
1729 #endif
1730
1731 // Note: some headers do not define cl_khr_image2d_from_buffer
1732 #if CL_HPP_TARGET_OPENCL_VERSION < 200
1733 #if defined(CL_DEVICE_IMAGE_PITCH_ALIGNMENT_KHR)
1734 CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_IMAGE_PITCH_ALIGNMENT_KHR, cl_uint)
1735 #endif
1736 #if defined(CL_DEVICE_IMAGE_BASE_ADDRESS_ALIGNMENT_KHR)
1737 CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_IMAGE_BASE_ADDRESS_ALIGNMENT_KHR, cl_uint)
1738 #endif
1739 #endif // CL_HPP_TARGET_OPENCL_VERSION < 200
1740
1741 #if defined(cl_khr_integer_dot_product)
1742 CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_INTEGER_DOT_PRODUCT_CAPABILITIES_KHR, cl_device_integer_dot_product_capabilities_khr)
1743 #if defined(CL_DEVICE_INTEGER_DOT_PRODUCT_ACCELERATION_PROPERTIES_8BIT_KHR)
1744 CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_INTEGER_DOT_PRODUCT_ACCELERATION_PROPERTIES_8BIT_KHR, cl_device_integer_dot_product_acceleration_properties_khr)
1745 CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_INTEGER_DOT_PRODUCT_ACCELERATION_PROPERTIES_4x8BIT_PACKED_KHR, cl_device_integer_dot_product_acceleration_properties_khr)
1746 #endif // defined(CL_DEVICE_INTEGER_DOT_PRODUCT_ACCELERATION_PROPERTIES_8BIT_KHR)
1747 #endif // defined(cl_khr_integer_dot_product)
1748
1749 #if defined(cl_ext_image_requirements_info)
1750 CL_HPP_PARAM_NAME_CL_IMAGE_REQUIREMENTS_EXT(CL_HPP_DECLARE_PARAM_TRAITS_)
1751 #endif // cl_ext_image_requirements_info
1752
1753 #if defined(cl_ext_image_from_buffer)
1754 CL_HPP_PARAM_NAME_CL_IMAGE_REQUIREMENTS_SLICE_PITCH_ALIGNMENT_EXT(CL_HPP_DECLARE_PARAM_TRAITS_)
1755 #endif // cl_ext_image_from_buffer
1756
1757 #ifdef CL_PLATFORM_ICD_SUFFIX_KHR
1758 CL_HPP_DECLARE_PARAM_TRAITS_(cl_platform_info, CL_PLATFORM_ICD_SUFFIX_KHR, string)
1759 #endif
1760
1761 #ifdef CL_DEVICE_PROFILING_TIMER_OFFSET_AMD
1762 CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_PROFILING_TIMER_OFFSET_AMD, cl_ulong)
1763 #endif
1764 #ifdef CL_DEVICE_GLOBAL_FREE_MEMORY_AMD
1765 CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_GLOBAL_FREE_MEMORY_AMD, vector<size_type>)
1766 #endif
1767 #ifdef CL_DEVICE_SIMD_PER_COMPUTE_UNIT_AMD
1768 CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_SIMD_PER_COMPUTE_UNIT_AMD, cl_uint)
1769 #endif
1770 #ifdef CL_DEVICE_SIMD_WIDTH_AMD
1771 CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_SIMD_WIDTH_AMD, cl_uint)
1772 #endif
1773 #ifdef CL_DEVICE_SIMD_INSTRUCTION_WIDTH_AMD
1774 CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_SIMD_INSTRUCTION_WIDTH_AMD, cl_uint)
1775 #endif
1776 #ifdef CL_DEVICE_WAVEFRONT_WIDTH_AMD
1777 CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_WAVEFRONT_WIDTH_AMD, cl_uint)
1778 #endif
1779 #ifdef CL_DEVICE_GLOBAL_MEM_CHANNELS_AMD
1780 CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_GLOBAL_MEM_CHANNELS_AMD, cl_uint)
1781 #endif
1782 #ifdef CL_DEVICE_GLOBAL_MEM_CHANNEL_BANKS_AMD
1783 CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_GLOBAL_MEM_CHANNEL_BANKS_AMD, cl_uint)
1784 #endif
1785 #ifdef CL_DEVICE_GLOBAL_MEM_CHANNEL_BANK_WIDTH_AMD
1786 CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_GLOBAL_MEM_CHANNEL_BANK_WIDTH_AMD, cl_uint)
1787 #endif
1788 #ifdef CL_DEVICE_LOCAL_MEM_SIZE_PER_COMPUTE_UNIT_AMD
1789 CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_LOCAL_MEM_SIZE_PER_COMPUTE_UNIT_AMD, cl_uint)
1790 #endif
1791 #ifdef CL_DEVICE_LOCAL_MEM_BANKS_AMD
1792 CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_LOCAL_MEM_BANKS_AMD, cl_uint)
1793 #endif
1794 #ifdef CL_DEVICE_BOARD_NAME_AMD
1795 CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_BOARD_NAME_AMD, string)
1796 #endif
1797
1798 #ifdef CL_DEVICE_COMPUTE_UNITS_BITFIELD_ARM
1799 CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_COMPUTE_UNITS_BITFIELD_ARM, cl_ulong)
1800 #endif
1801 #ifdef CL_DEVICE_JOB_SLOTS_ARM
1802 CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_JOB_SLOTS_ARM, cl_uint)
1803 #endif
1804 #ifdef CL_DEVICE_SCHEDULING_CONTROLS_CAPABILITIES_ARM
1805 CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_SCHEDULING_CONTROLS_CAPABILITIES_ARM, cl_bitfield)
1806 #endif
1807 #ifdef CL_DEVICE_SUPPORTED_REGISTER_ALLOCATIONS_ARM
1808 CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_SUPPORTED_REGISTER_ALLOCATIONS_ARM, vector<cl_uint>)
1809 #endif
1810 #ifdef CL_DEVICE_MAX_WARP_COUNT_ARM
1811 CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_MAX_WARP_COUNT_ARM, cl_uint)
1812 #endif
1813 #ifdef CL_KERNEL_MAX_WARP_COUNT_ARM
1814 CL_HPP_DECLARE_PARAM_TRAITS_(cl_kernel_info, CL_KERNEL_MAX_WARP_COUNT_ARM, cl_uint)
1815 #endif
1816 #ifdef CL_KERNEL_EXEC_INFO_WORKGROUP_BATCH_SIZE_ARM
1817 CL_HPP_DECLARE_PARAM_TRAITS_(cl_kernel_exec_info, CL_KERNEL_EXEC_INFO_WORKGROUP_BATCH_SIZE_ARM, cl_uint)
1818 #endif
1819 #ifdef CL_KERNEL_EXEC_INFO_WORKGROUP_BATCH_SIZE_MODIFIER_ARM
1820 CL_HPP_DECLARE_PARAM_TRAITS_(cl_kernel_exec_info, CL_KERNEL_EXEC_INFO_WORKGROUP_BATCH_SIZE_MODIFIER_ARM, cl_int)
1821 #endif
1822 #ifdef CL_KERNEL_EXEC_INFO_WARP_COUNT_LIMIT_ARM
1823 CL_HPP_DECLARE_PARAM_TRAITS_(cl_kernel_exec_info, CL_KERNEL_EXEC_INFO_WARP_COUNT_LIMIT_ARM, cl_uint)
1824 #endif
1825 #ifdef CL_KERNEL_EXEC_INFO_COMPUTE_UNIT_MAX_QUEUED_BATCHES_ARM
1826 CL_HPP_DECLARE_PARAM_TRAITS_(cl_kernel_exec_info, CL_KERNEL_EXEC_INFO_COMPUTE_UNIT_MAX_QUEUED_BATCHES_ARM, cl_uint)
1827 #endif
1828
1829 #ifdef CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV
1830 CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV, cl_uint)
1831 #endif
1832 #ifdef CL_DEVICE_COMPUTE_CAPABILITY_MINOR_NV
1833 CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_COMPUTE_CAPABILITY_MINOR_NV, cl_uint)
1834 #endif
1835 #ifdef CL_DEVICE_REGISTERS_PER_BLOCK_NV
1836 CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_REGISTERS_PER_BLOCK_NV, cl_uint)
1837 #endif
1838 #ifdef CL_DEVICE_WARP_SIZE_NV
1839 CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_WARP_SIZE_NV, cl_uint)
1840 #endif
1841 #ifdef CL_DEVICE_GPU_OVERLAP_NV
1842 CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_GPU_OVERLAP_NV, cl_bool)
1843 #endif
1844 #ifdef CL_DEVICE_KERNEL_EXEC_TIMEOUT_NV
1845 CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_KERNEL_EXEC_TIMEOUT_NV, cl_bool)
1846 #endif
1847 #ifdef CL_DEVICE_INTEGRATED_MEMORY_NV
1848 CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_INTEGRATED_MEMORY_NV, cl_bool)
1849 #endif
1850
1851 #if defined(cl_khr_command_buffer)
1852 CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_COMMAND_BUFFER_CAPABILITIES_KHR, cl_device_command_buffer_capabilities_khr)
1853 CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_COMMAND_BUFFER_REQUIRED_QUEUE_PROPERTIES_KHR, cl_command_buffer_properties_khr)
1854 CL_HPP_DECLARE_PARAM_TRAITS_(cl_command_buffer_info_khr, CL_COMMAND_BUFFER_QUEUES_KHR, cl::vector<CommandQueue>)
1855 CL_HPP_DECLARE_PARAM_TRAITS_(cl_command_buffer_info_khr, CL_COMMAND_BUFFER_NUM_QUEUES_KHR, cl_uint)
1856 CL_HPP_DECLARE_PARAM_TRAITS_(cl_command_buffer_info_khr, CL_COMMAND_BUFFER_REFERENCE_COUNT_KHR, cl_uint)
1857 CL_HPP_DECLARE_PARAM_TRAITS_(cl_command_buffer_info_khr, CL_COMMAND_BUFFER_STATE_KHR, cl_command_buffer_state_khr)
1858 CL_HPP_DECLARE_PARAM_TRAITS_(cl_command_buffer_info_khr, CL_COMMAND_BUFFER_PROPERTIES_ARRAY_KHR, cl::vector<cl_command_buffer_properties_khr>)
1859 #endif /* cl_khr_command_buffer */
1860
1861 #if defined(cl_khr_command_buffer_mutable_dispatch)
1862 CL_HPP_DECLARE_PARAM_TRAITS_(cl_mutable_command_info_khr, CL_MUTABLE_COMMAND_COMMAND_QUEUE_KHR, CommandQueue)
1863 CL_HPP_DECLARE_PARAM_TRAITS_(cl_mutable_command_info_khr, CL_MUTABLE_COMMAND_COMMAND_BUFFER_KHR, CommandBufferKhr)
1864 CL_HPP_DECLARE_PARAM_TRAITS_(cl_mutable_command_info_khr, CL_MUTABLE_COMMAND_COMMAND_TYPE_KHR, cl_command_type)
1865 CL_HPP_DECLARE_PARAM_TRAITS_(cl_mutable_command_info_khr, CL_MUTABLE_DISPATCH_PROPERTIES_ARRAY_KHR, cl::vector<cl_ndrange_kernel_command_properties_khr>)
1866 CL_HPP_DECLARE_PARAM_TRAITS_(cl_mutable_command_info_khr, CL_MUTABLE_DISPATCH_KERNEL_KHR, cl_kernel)
1867 CL_HPP_DECLARE_PARAM_TRAITS_(cl_mutable_command_info_khr, CL_MUTABLE_DISPATCH_DIMENSIONS_KHR, cl_uint)
1868 CL_HPP_DECLARE_PARAM_TRAITS_(cl_mutable_command_info_khr, CL_MUTABLE_DISPATCH_GLOBAL_WORK_OFFSET_KHR, cl::vector<size_type>)
1869 CL_HPP_DECLARE_PARAM_TRAITS_(cl_mutable_command_info_khr, CL_MUTABLE_DISPATCH_GLOBAL_WORK_SIZE_KHR, cl::vector<size_type>)
1870 CL_HPP_DECLARE_PARAM_TRAITS_(cl_mutable_command_info_khr, CL_MUTABLE_DISPATCH_LOCAL_WORK_SIZE_KHR, cl::vector<size_type>)
1871 #endif /* cl_khr_command_buffer_mutable_dispatch */
1872
1873 // Convenience functions
1874
1875 template <typename Func, typename T>
1876 inline cl_int
1877 getInfo(Func f, cl_uint name, T* param)
1878 {
1879 return getInfoHelper(f, name, param, 0);
1880 }
1881
1882 template <typename Func, typename Arg0>
1883 struct GetInfoFunctor0
1884 {
1885 Func f_; const Arg0& arg0_;
operator ()cl::detail::GetInfoFunctor01886 cl_int operator ()(
1887 cl_uint param, size_type size, void* value, size_type* size_ret)
1888 { return f_(arg0_, param, size, value, size_ret); }
1889 };
1890
1891 template <typename Func, typename Arg0, typename Arg1>
1892 struct GetInfoFunctor1
1893 {
1894 Func f_; const Arg0& arg0_; const Arg1& arg1_;
operator ()cl::detail::GetInfoFunctor11895 cl_int operator ()(
1896 cl_uint param, size_type size, void* value, size_type* size_ret)
1897 { return f_(arg0_, arg1_, param, size, value, size_ret); }
1898 };
1899
1900 template <typename Func, typename Arg0, typename T>
1901 inline cl_int
getInfo(Func f,const Arg0 & arg0,cl_uint name,T * param)1902 getInfo(Func f, const Arg0& arg0, cl_uint name, T* param)
1903 {
1904 GetInfoFunctor0<Func, Arg0> f0 = { f, arg0 };
1905 return getInfoHelper(f0, name, param, 0);
1906 }
1907
1908 template <typename Func, typename Arg0, typename Arg1, typename T>
1909 inline cl_int
getInfo(Func f,const Arg0 & arg0,const Arg1 & arg1,cl_uint name,T * param)1910 getInfo(Func f, const Arg0& arg0, const Arg1& arg1, cl_uint name, T* param)
1911 {
1912 GetInfoFunctor1<Func, Arg0, Arg1> f0 = { f, arg0, arg1 };
1913 return getInfoHelper(f0, name, param, 0);
1914 }
1915
1916
1917 template<typename T>
1918 struct ReferenceHandler
1919 { };
1920
1921 #if CL_HPP_TARGET_OPENCL_VERSION >= 120
1922 /**
1923 * OpenCL 1.2 devices do have retain/release.
1924 */
1925 template <>
1926 struct ReferenceHandler<cl_device_id>
1927 {
1928 /**
1929 * Retain the device.
1930 * \param device A valid device created using createSubDevices
1931 * \return
1932 * CL_SUCCESS if the function executed successfully.
1933 * CL_INVALID_DEVICE if device was not a valid subdevice
1934 * CL_OUT_OF_RESOURCES
1935 * CL_OUT_OF_HOST_MEMORY
1936 */
retaincl::detail::ReferenceHandler1937 static cl_int retain(cl_device_id device)
1938 { return ::clRetainDevice(device); }
1939 /**
1940 * Retain the device.
1941 * \param device A valid device created using createSubDevices
1942 * \return
1943 * CL_SUCCESS if the function executed successfully.
1944 * CL_INVALID_DEVICE if device was not a valid subdevice
1945 * CL_OUT_OF_RESOURCES
1946 * CL_OUT_OF_HOST_MEMORY
1947 */
releasecl::detail::ReferenceHandler1948 static cl_int release(cl_device_id device)
1949 { return ::clReleaseDevice(device); }
1950 };
1951 #else // CL_HPP_TARGET_OPENCL_VERSION >= 120
1952 /**
1953 * OpenCL 1.1 devices do not have retain/release.
1954 */
1955 template <>
1956 struct ReferenceHandler<cl_device_id>
1957 {
1958 // cl_device_id does not have retain().
retaincl::detail::ReferenceHandler1959 static cl_int retain(cl_device_id)
1960 { return CL_SUCCESS; }
1961 // cl_device_id does not have release().
releasecl::detail::ReferenceHandler1962 static cl_int release(cl_device_id)
1963 { return CL_SUCCESS; }
1964 };
1965 #endif // ! (CL_HPP_TARGET_OPENCL_VERSION >= 120)
1966
1967 template <>
1968 struct ReferenceHandler<cl_platform_id>
1969 {
1970 // cl_platform_id does not have retain().
retaincl::detail::ReferenceHandler1971 static cl_int retain(cl_platform_id)
1972 { return CL_SUCCESS; }
1973 // cl_platform_id does not have release().
releasecl::detail::ReferenceHandler1974 static cl_int release(cl_platform_id)
1975 { return CL_SUCCESS; }
1976 };
1977
1978 template <>
1979 struct ReferenceHandler<cl_context>
1980 {
retaincl::detail::ReferenceHandler1981 static cl_int retain(cl_context context)
1982 { return ::clRetainContext(context); }
releasecl::detail::ReferenceHandler1983 static cl_int release(cl_context context)
1984 { return ::clReleaseContext(context); }
1985 };
1986
1987 template <>
1988 struct ReferenceHandler<cl_command_queue>
1989 {
retaincl::detail::ReferenceHandler1990 static cl_int retain(cl_command_queue queue)
1991 { return ::clRetainCommandQueue(queue); }
releasecl::detail::ReferenceHandler1992 static cl_int release(cl_command_queue queue)
1993 { return ::clReleaseCommandQueue(queue); }
1994 };
1995
1996 template <>
1997 struct ReferenceHandler<cl_mem>
1998 {
retaincl::detail::ReferenceHandler1999 static cl_int retain(cl_mem memory)
2000 { return ::clRetainMemObject(memory); }
releasecl::detail::ReferenceHandler2001 static cl_int release(cl_mem memory)
2002 { return ::clReleaseMemObject(memory); }
2003 };
2004
2005 template <>
2006 struct ReferenceHandler<cl_sampler>
2007 {
retaincl::detail::ReferenceHandler2008 static cl_int retain(cl_sampler sampler)
2009 { return ::clRetainSampler(sampler); }
releasecl::detail::ReferenceHandler2010 static cl_int release(cl_sampler sampler)
2011 { return ::clReleaseSampler(sampler); }
2012 };
2013
2014 template <>
2015 struct ReferenceHandler<cl_program>
2016 {
retaincl::detail::ReferenceHandler2017 static cl_int retain(cl_program program)
2018 { return ::clRetainProgram(program); }
releasecl::detail::ReferenceHandler2019 static cl_int release(cl_program program)
2020 { return ::clReleaseProgram(program); }
2021 };
2022
2023 template <>
2024 struct ReferenceHandler<cl_kernel>
2025 {
retaincl::detail::ReferenceHandler2026 static cl_int retain(cl_kernel kernel)
2027 { return ::clRetainKernel(kernel); }
releasecl::detail::ReferenceHandler2028 static cl_int release(cl_kernel kernel)
2029 { return ::clReleaseKernel(kernel); }
2030 };
2031
2032 template <>
2033 struct ReferenceHandler<cl_event>
2034 {
retaincl::detail::ReferenceHandler2035 static cl_int retain(cl_event event)
2036 { return ::clRetainEvent(event); }
releasecl::detail::ReferenceHandler2037 static cl_int release(cl_event event)
2038 { return ::clReleaseEvent(event); }
2039 };
2040
2041 #ifdef cl_khr_semaphore
2042 template <>
2043 struct ReferenceHandler<cl_semaphore_khr>
2044 {
retaincl::detail::ReferenceHandler2045 static cl_int retain(cl_semaphore_khr semaphore)
2046 {
2047 if (pfn_clRetainSemaphoreKHR != nullptr) {
2048 return pfn_clRetainSemaphoreKHR(semaphore);
2049 }
2050
2051 return CL_INVALID_OPERATION;
2052 }
2053
releasecl::detail::ReferenceHandler2054 static cl_int release(cl_semaphore_khr semaphore)
2055 {
2056 if (pfn_clReleaseSemaphoreKHR != nullptr) {
2057 return pfn_clReleaseSemaphoreKHR(semaphore);
2058 }
2059
2060 return CL_INVALID_OPERATION;
2061 }
2062 };
2063 #endif // cl_khr_semaphore
2064 #if defined(cl_khr_command_buffer)
2065 template <>
2066 struct ReferenceHandler<cl_command_buffer_khr>
2067 {
retaincl::detail::ReferenceHandler2068 static cl_int retain(cl_command_buffer_khr cmdBufferKhr)
2069 {
2070 if (pfn_clRetainCommandBufferKHR == nullptr) {
2071 return detail::errHandler(CL_INVALID_OPERATION, __RETAIN_COMMAND_BUFFER_KHR_ERR);
2072 }
2073 return pfn_clRetainCommandBufferKHR(cmdBufferKhr);
2074 }
2075
releasecl::detail::ReferenceHandler2076 static cl_int release(cl_command_buffer_khr cmdBufferKhr)
2077 {
2078 if (pfn_clReleaseCommandBufferKHR == nullptr) {
2079 return detail::errHandler(CL_INVALID_OPERATION, __RELEASE_COMMAND_BUFFER_KHR_ERR);
2080 }
2081 return pfn_clReleaseCommandBufferKHR(cmdBufferKhr);
2082 }
2083 };
2084
2085 template <>
2086 struct ReferenceHandler<cl_mutable_command_khr>
2087 {
2088 // cl_mutable_command_khr does not have retain().
retaincl::detail::ReferenceHandler2089 static cl_int retain(cl_mutable_command_khr)
2090 { return CL_SUCCESS; }
2091 // cl_mutable_command_khr does not have release().
releasecl::detail::ReferenceHandler2092 static cl_int release(cl_mutable_command_khr)
2093 { return CL_SUCCESS; }
2094 };
2095 #endif // cl_khr_command_buffer
2096
2097
2098 #if CL_HPP_TARGET_OPENCL_VERSION >= 120 && CL_HPP_MINIMUM_OPENCL_VERSION < 200
2099 // Extracts version number with major in the upper 16 bits, minor in the lower 16
getVersion(const vector<char> & versionInfo)2100 static cl_uint getVersion(const vector<char> &versionInfo)
2101 {
2102 int highVersion = 0;
2103 int lowVersion = 0;
2104 int index = 7;
2105 while(versionInfo[index] != '.' ) {
2106 highVersion *= 10;
2107 highVersion += versionInfo[index]-'0';
2108 ++index;
2109 }
2110 ++index;
2111 while(versionInfo[index] != ' ' && versionInfo[index] != '\0') {
2112 lowVersion *= 10;
2113 lowVersion += versionInfo[index]-'0';
2114 ++index;
2115 }
2116 return (highVersion << 16) | lowVersion;
2117 }
2118
getPlatformVersion(cl_platform_id platform)2119 static cl_uint getPlatformVersion(cl_platform_id platform)
2120 {
2121 size_type size = 0;
2122 clGetPlatformInfo(platform, CL_PLATFORM_VERSION, 0, nullptr, &size);
2123
2124 vector<char> versionInfo(size);
2125 clGetPlatformInfo(platform, CL_PLATFORM_VERSION, size, versionInfo.data(), &size);
2126 return getVersion(versionInfo);
2127 }
2128
getDevicePlatformVersion(cl_device_id device)2129 static cl_uint getDevicePlatformVersion(cl_device_id device)
2130 {
2131 cl_platform_id platform;
2132 clGetDeviceInfo(device, CL_DEVICE_PLATFORM, sizeof(platform), &platform, nullptr);
2133 return getPlatformVersion(platform);
2134 }
2135
getContextPlatformVersion(cl_context context)2136 static cl_uint getContextPlatformVersion(cl_context context)
2137 {
2138 // The platform cannot be queried directly, so we first have to grab a
2139 // device and obtain its context
2140 size_type size = 0;
2141 clGetContextInfo(context, CL_CONTEXT_DEVICES, 0, nullptr, &size);
2142 if (size == 0)
2143 return 0;
2144 vector<cl_device_id> devices(size/sizeof(cl_device_id));
2145 clGetContextInfo(context, CL_CONTEXT_DEVICES, size, devices.data(), nullptr);
2146 return getDevicePlatformVersion(devices[0]);
2147 }
2148 #endif // CL_HPP_TARGET_OPENCL_VERSION >= 120 && CL_HPP_MINIMUM_OPENCL_VERSION < 200
2149
2150 template <typename T>
2151 class Wrapper
2152 {
2153 public:
2154 typedef T cl_type;
2155
2156 protected:
2157 cl_type object_;
2158
2159 public:
Wrapper()2160 Wrapper() : object_(nullptr) { }
2161
Wrapper(const cl_type & obj,bool retainObject)2162 Wrapper(const cl_type &obj, bool retainObject) : object_(obj)
2163 {
2164 if (retainObject) {
2165 detail::errHandler(retain(), __RETAIN_ERR);
2166 }
2167 }
2168
~Wrapper()2169 ~Wrapper()
2170 {
2171 if (object_ != nullptr) { release(); }
2172 }
2173
Wrapper(const Wrapper<cl_type> & rhs)2174 Wrapper(const Wrapper<cl_type>& rhs)
2175 {
2176 object_ = rhs.object_;
2177 detail::errHandler(retain(), __RETAIN_ERR);
2178 }
2179
Wrapper(Wrapper<cl_type> && rhs)2180 Wrapper(Wrapper<cl_type>&& rhs) noexcept
2181 {
2182 object_ = rhs.object_;
2183 rhs.object_ = nullptr;
2184 }
2185
operator =(const Wrapper<cl_type> & rhs)2186 Wrapper<cl_type>& operator = (const Wrapper<cl_type>& rhs)
2187 {
2188 if (this != &rhs) {
2189 detail::errHandler(release(), __RELEASE_ERR);
2190 object_ = rhs.object_;
2191 detail::errHandler(retain(), __RETAIN_ERR);
2192 }
2193 return *this;
2194 }
2195
operator =(Wrapper<cl_type> && rhs)2196 Wrapper<cl_type>& operator = (Wrapper<cl_type>&& rhs)
2197 {
2198 if (this != &rhs) {
2199 detail::errHandler(release(), __RELEASE_ERR);
2200 object_ = rhs.object_;
2201 rhs.object_ = nullptr;
2202 }
2203 return *this;
2204 }
2205
operator =(const cl_type & rhs)2206 Wrapper<cl_type>& operator = (const cl_type &rhs)
2207 {
2208 detail::errHandler(release(), __RELEASE_ERR);
2209 object_ = rhs;
2210 return *this;
2211 }
2212
operator ()() const2213 const cl_type& operator ()() const { return object_; }
2214
operator ()()2215 cl_type& operator ()() { return object_; }
2216
get() const2217 cl_type get() const { return object_; }
2218
2219 protected:
2220 template<typename Func, typename U>
2221 friend inline cl_int getInfoHelper(Func, cl_uint, U*, int, typename U::cl_type);
2222
retain() const2223 cl_int retain() const
2224 {
2225 if (object_ != nullptr) {
2226 return ReferenceHandler<cl_type>::retain(object_);
2227 }
2228 else {
2229 return CL_SUCCESS;
2230 }
2231 }
2232
release() const2233 cl_int release() const
2234 {
2235 if (object_ != nullptr) {
2236 return ReferenceHandler<cl_type>::release(object_);
2237 }
2238 else {
2239 return CL_SUCCESS;
2240 }
2241 }
2242 };
2243
2244 template <>
2245 class Wrapper<cl_device_id>
2246 {
2247 public:
2248 typedef cl_device_id cl_type;
2249
2250 protected:
2251 cl_type object_;
2252 bool referenceCountable_;
2253
isReferenceCountable(cl_device_id device)2254 static bool isReferenceCountable(cl_device_id device)
2255 {
2256 bool retVal = false;
2257 #if CL_HPP_TARGET_OPENCL_VERSION >= 120
2258 #if CL_HPP_MINIMUM_OPENCL_VERSION < 120
2259 if (device != nullptr) {
2260 int version = getDevicePlatformVersion(device);
2261 if(version > ((1 << 16) + 1)) {
2262 retVal = true;
2263 }
2264 }
2265 #else // CL_HPP_MINIMUM_OPENCL_VERSION < 120
2266 retVal = true;
2267 #endif // CL_HPP_MINIMUM_OPENCL_VERSION < 120
2268 #endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
2269 (void)device;
2270 return retVal;
2271 }
2272
2273 public:
Wrapper()2274 Wrapper() : object_(nullptr), referenceCountable_(false)
2275 {
2276 }
2277
Wrapper(const cl_type & obj,bool retainObject)2278 Wrapper(const cl_type &obj, bool retainObject) :
2279 object_(obj),
2280 referenceCountable_(false)
2281 {
2282 referenceCountable_ = isReferenceCountable(obj);
2283
2284 if (retainObject) {
2285 detail::errHandler(retain(), __RETAIN_ERR);
2286 }
2287 }
2288
~Wrapper()2289 ~Wrapper()
2290 {
2291 release();
2292 }
2293
Wrapper(const Wrapper<cl_type> & rhs)2294 Wrapper(const Wrapper<cl_type>& rhs)
2295 {
2296 object_ = rhs.object_;
2297 referenceCountable_ = isReferenceCountable(object_);
2298 detail::errHandler(retain(), __RETAIN_ERR);
2299 }
2300
Wrapper(Wrapper<cl_type> && rhs)2301 Wrapper(Wrapper<cl_type>&& rhs) noexcept
2302 {
2303 object_ = rhs.object_;
2304 referenceCountable_ = rhs.referenceCountable_;
2305 rhs.object_ = nullptr;
2306 rhs.referenceCountable_ = false;
2307 }
2308
operator =(const Wrapper<cl_type> & rhs)2309 Wrapper<cl_type>& operator = (const Wrapper<cl_type>& rhs)
2310 {
2311 if (this != &rhs) {
2312 detail::errHandler(release(), __RELEASE_ERR);
2313 object_ = rhs.object_;
2314 referenceCountable_ = rhs.referenceCountable_;
2315 detail::errHandler(retain(), __RETAIN_ERR);
2316 }
2317 return *this;
2318 }
2319
operator =(Wrapper<cl_type> && rhs)2320 Wrapper<cl_type>& operator = (Wrapper<cl_type>&& rhs)
2321 {
2322 if (this != &rhs) {
2323 detail::errHandler(release(), __RELEASE_ERR);
2324 object_ = rhs.object_;
2325 referenceCountable_ = rhs.referenceCountable_;
2326 rhs.object_ = nullptr;
2327 rhs.referenceCountable_ = false;
2328 }
2329 return *this;
2330 }
2331
operator =(const cl_type & rhs)2332 Wrapper<cl_type>& operator = (const cl_type &rhs)
2333 {
2334 detail::errHandler(release(), __RELEASE_ERR);
2335 object_ = rhs;
2336 referenceCountable_ = isReferenceCountable(object_);
2337 return *this;
2338 }
2339
operator ()() const2340 const cl_type& operator ()() const { return object_; }
2341
operator ()()2342 cl_type& operator ()() { return object_; }
2343
get() const2344 cl_type get() const { return object_; }
2345
2346 protected:
2347 template<typename Func, typename U>
2348 friend inline cl_int getInfoHelper(Func, cl_uint, U*, int, typename U::cl_type);
2349
2350 template<typename Func, typename U>
2351 friend inline cl_int getInfoHelper(Func, cl_uint, vector<U>*, int, typename U::cl_type);
2352
retain() const2353 cl_int retain() const
2354 {
2355 if( object_ != nullptr && referenceCountable_ ) {
2356 return ReferenceHandler<cl_type>::retain(object_);
2357 }
2358 else {
2359 return CL_SUCCESS;
2360 }
2361 }
2362
release() const2363 cl_int release() const
2364 {
2365 if (object_ != nullptr && referenceCountable_) {
2366 return ReferenceHandler<cl_type>::release(object_);
2367 }
2368 else {
2369 return CL_SUCCESS;
2370 }
2371 }
2372 };
2373
2374 template <typename T>
operator ==(const Wrapper<T> & lhs,const Wrapper<T> & rhs)2375 inline bool operator==(const Wrapper<T> &lhs, const Wrapper<T> &rhs)
2376 {
2377 return lhs() == rhs();
2378 }
2379
2380 template <typename T>
operator !=(const Wrapper<T> & lhs,const Wrapper<T> & rhs)2381 inline bool operator!=(const Wrapper<T> &lhs, const Wrapper<T> &rhs)
2382 {
2383 return !operator==(lhs, rhs);
2384 }
2385
2386 } // namespace detail
2387 //! \endcond
2388
2389
2390
2391
2392
2393 /*! \stuct ImageFormat
2394 * \brief Adds constructors and member functions for cl_image_format.
2395 *
2396 * \see cl_image_format
2397 */
2398 struct ImageFormat : public cl_image_format
2399 {
2400 //! \brief Default constructor - performs no initialization.
ImageFormatcl::ImageFormat2401 ImageFormat(){}
2402
2403 //! \brief Initializing constructor.
ImageFormatcl::ImageFormat2404 ImageFormat(cl_channel_order order, cl_channel_type type)
2405 {
2406 image_channel_order = order;
2407 image_channel_data_type = type;
2408 }
2409
2410 //! \brief Copy constructor.
ImageFormatcl::ImageFormat2411 ImageFormat(const ImageFormat &other) { *this = other; }
2412
2413 //! \brief Assignment operator.
operator =cl::ImageFormat2414 ImageFormat& operator = (const ImageFormat& rhs)
2415 {
2416 if (this != &rhs) {
2417 this->image_channel_data_type = rhs.image_channel_data_type;
2418 this->image_channel_order = rhs.image_channel_order;
2419 }
2420 return *this;
2421 }
2422 };
2423
2424 /*! \brief Class interface for cl_device_id.
2425 *
2426 * \note Copies of these objects are inexpensive, since they don't 'own'
2427 * any underlying resources or data structures.
2428 *
2429 * \see cl_device_id
2430 */
2431 class Device : public detail::Wrapper<cl_device_id>
2432 {
2433 private:
2434 static std::once_flag default_initialized_;
2435 static Device default_;
2436 static cl_int default_error_;
2437
2438 /*! \brief Create the default context.
2439 *
2440 * This sets @c default_ and @c default_error_. It does not throw
2441 * @c cl::Error.
2442 */
2443 static void makeDefault();
2444
2445 /*! \brief Create the default platform from a provided platform.
2446 *
2447 * This sets @c default_. It does not throw
2448 * @c cl::Error.
2449 */
makeDefaultProvided(const Device & p)2450 static void makeDefaultProvided(const Device &p) {
2451 default_ = p;
2452 }
2453
2454 public:
2455 #ifdef CL_HPP_UNIT_TEST_ENABLE
2456 /*! \brief Reset the default.
2457 *
2458 * This sets @c default_ to an empty value to support cleanup in
2459 * the unit test framework.
2460 * This function is not thread safe.
2461 */
unitTestClearDefault()2462 static void unitTestClearDefault() {
2463 default_ = Device();
2464 }
2465 #endif // #ifdef CL_HPP_UNIT_TEST_ENABLE
2466
2467 //! \brief Default constructor - initializes to nullptr.
Device()2468 Device() : detail::Wrapper<cl_type>() { }
2469
2470 /*! \brief Constructor from cl_device_id.
2471 *
2472 * This simply copies the device ID value, which is an inexpensive operation.
2473 */
Device(const cl_device_id & device,bool retainObject=false)2474 explicit Device(const cl_device_id &device, bool retainObject = false) :
2475 detail::Wrapper<cl_type>(device, retainObject) { }
2476
2477 /*! \brief Returns the first device on the default context.
2478 *
2479 * \see Context::getDefault()
2480 */
getDefault(cl_int * errResult=nullptr)2481 static Device getDefault(
2482 cl_int *errResult = nullptr)
2483 {
2484 std::call_once(default_initialized_, makeDefault);
2485 detail::errHandler(default_error_);
2486 if (errResult != nullptr) {
2487 *errResult = default_error_;
2488 }
2489 return default_;
2490 }
2491
2492 /**
2493 * Modify the default device to be used by
2494 * subsequent operations.
2495 * Will only set the default if no default was previously created.
2496 * @return updated default device.
2497 * Should be compared to the passed value to ensure that it was updated.
2498 */
setDefault(const Device & default_device)2499 static Device setDefault(const Device &default_device)
2500 {
2501 std::call_once(default_initialized_, makeDefaultProvided, std::cref(default_device));
2502 detail::errHandler(default_error_);
2503 return default_;
2504 }
2505
2506 /*! \brief Assignment operator from cl_device_id.
2507 *
2508 * This simply copies the device ID value, which is an inexpensive operation.
2509 */
operator =(const cl_device_id & rhs)2510 Device& operator = (const cl_device_id& rhs)
2511 {
2512 detail::Wrapper<cl_type>::operator=(rhs);
2513 return *this;
2514 }
2515
2516
2517 //! \brief Wrapper for clGetDeviceInfo().
2518 template <typename T>
getInfo(cl_device_info name,T * param) const2519 cl_int getInfo(cl_device_info name, T* param) const
2520 {
2521 return detail::errHandler(
2522 detail::getInfo(&::clGetDeviceInfo, object_, name, param),
2523 __GET_DEVICE_INFO_ERR);
2524 }
2525
2526 //! \brief Wrapper for clGetDeviceInfo() that returns by value.
2527 template <cl_device_info name> typename
2528 detail::param_traits<detail::cl_device_info, name>::param_type
getInfo(cl_int * err=nullptr) const2529 getInfo(cl_int* err = nullptr) const
2530 {
2531 typename detail::param_traits<
2532 detail::cl_device_info, name>::param_type param;
2533 cl_int result = getInfo(name, ¶m);
2534 if (err != nullptr) {
2535 *err = result;
2536 }
2537 return param;
2538 }
2539
2540 #if CL_HPP_TARGET_OPENCL_VERSION >= 210
2541 /**
2542 * Return the current value of the host clock as seen by the device.
2543 * The resolution of the device timer may be queried with the
2544 * CL_DEVICE_PROFILING_TIMER_RESOLUTION query.
2545 * @return The host timer value.
2546 */
getHostTimer(cl_int * error=nullptr)2547 cl_ulong getHostTimer(cl_int *error = nullptr)
2548 {
2549 cl_ulong retVal = 0;
2550 cl_int err =
2551 clGetHostTimer(this->get(), &retVal);
2552 detail::errHandler(
2553 err,
2554 __GET_HOST_TIMER_ERR);
2555 if (error) {
2556 *error = err;
2557 }
2558 return retVal;
2559 }
2560
2561 /**
2562 * Return a synchronized pair of host and device timestamps as seen by device.
2563 * Use to correlate the clocks and get the host timer only using getHostTimer
2564 * as a lower cost mechanism in between calls.
2565 * The resolution of the host timer may be queried with the
2566 * CL_PLATFORM_HOST_TIMER_RESOLUTION query.
2567 * The resolution of the device timer may be queried with the
2568 * CL_DEVICE_PROFILING_TIMER_RESOLUTION query.
2569 * @return A pair of (device timer, host timer) timer values.
2570 */
getDeviceAndHostTimer(cl_int * error=nullptr)2571 std::pair<cl_ulong, cl_ulong> getDeviceAndHostTimer(cl_int *error = nullptr)
2572 {
2573 std::pair<cl_ulong, cl_ulong> retVal;
2574 cl_int err =
2575 clGetDeviceAndHostTimer(this->get(), &(retVal.first), &(retVal.second));
2576 detail::errHandler(
2577 err,
2578 __GET_DEVICE_AND_HOST_TIMER_ERR);
2579 if (error) {
2580 *error = err;
2581 }
2582 return retVal;
2583 }
2584 #endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 210
2585
2586 #if CL_HPP_TARGET_OPENCL_VERSION >= 120
2587 //! \brief Wrapper for clCreateSubDevices().
2588 cl_int createSubDevices(const cl_device_partition_property* properties,
2589 vector<Device>* devices);
2590 #endif // defined (CL_HPP_TARGET_OPENCL_VERSION >= 120)
2591
2592 #if defined(cl_ext_device_fission)
2593 //! \brief Wrapper for clCreateSubDevices().
2594 cl_int createSubDevices(const cl_device_partition_property_ext* properties,
2595 vector<Device>* devices);
2596 #endif // defined(cl_ext_device_fission)
2597 };
2598
2599 using BuildLogType = vector<std::pair<cl::Device, typename detail::param_traits<detail::cl_program_build_info, CL_PROGRAM_BUILD_LOG>::param_type>>;
2600 #if defined(CL_HPP_ENABLE_EXCEPTIONS)
2601 /**
2602 * Exception class for build errors to carry build info
2603 */
2604 class BuildError : public Error
2605 {
2606 private:
2607 BuildLogType buildLogs;
2608 public:
BuildError(cl_int err,const char * errStr,const BuildLogType & vec)2609 BuildError(cl_int err, const char * errStr, const BuildLogType &vec) : Error(err, errStr), buildLogs(vec)
2610 {
2611 }
2612
getBuildLog() const2613 BuildLogType getBuildLog() const
2614 {
2615 return buildLogs;
2616 }
2617 };
2618 namespace detail {
buildErrHandler(cl_int err,const char * errStr,const BuildLogType & buildLogs)2619 static inline cl_int buildErrHandler(
2620 cl_int err,
2621 const char * errStr,
2622 const BuildLogType &buildLogs)
2623 {
2624 if (err != CL_SUCCESS) {
2625 throw BuildError(err, errStr, buildLogs);
2626 }
2627 return err;
2628 }
2629 } // namespace detail
2630
2631 #else
2632 namespace detail {
buildErrHandler(cl_int err,const char * errStr,const BuildLogType & buildLogs)2633 static inline cl_int buildErrHandler(
2634 cl_int err,
2635 const char * errStr,
2636 const BuildLogType &buildLogs)
2637 {
2638 (void)buildLogs; // suppress unused variable warning
2639 (void)errStr;
2640 return err;
2641 }
2642 } // namespace detail
2643 #endif // #if defined(CL_HPP_ENABLE_EXCEPTIONS)
2644
2645 CL_HPP_DEFINE_STATIC_MEMBER_ std::once_flag Device::default_initialized_;
2646 CL_HPP_DEFINE_STATIC_MEMBER_ Device Device::default_;
2647 CL_HPP_DEFINE_STATIC_MEMBER_ cl_int Device::default_error_ = CL_SUCCESS;
2648
2649 /*! \brief Class interface for cl_platform_id.
2650 *
2651 * \note Copies of these objects are inexpensive, since they don't 'own'
2652 * any underlying resources or data structures.
2653 *
2654 * \see cl_platform_id
2655 */
2656 class Platform : public detail::Wrapper<cl_platform_id>
2657 {
2658 private:
2659 static std::once_flag default_initialized_;
2660 static Platform default_;
2661 static cl_int default_error_;
2662
2663 /*! \brief Create the default context.
2664 *
2665 * This sets @c default_ and @c default_error_. It does not throw
2666 * @c cl::Error.
2667 */
makeDefault()2668 static void makeDefault() {
2669 /* Throwing an exception from a call_once invocation does not do
2670 * what we wish, so we catch it and save the error.
2671 */
2672 #if defined(CL_HPP_ENABLE_EXCEPTIONS)
2673 try
2674 #endif
2675 {
2676 // If default wasn't passed ,generate one
2677 // Otherwise set it
2678 cl_uint n = 0;
2679
2680 cl_int err = ::clGetPlatformIDs(0, nullptr, &n);
2681 if (err != CL_SUCCESS) {
2682 default_error_ = err;
2683 return;
2684 }
2685 if (n == 0) {
2686 default_error_ = CL_INVALID_PLATFORM;
2687 return;
2688 }
2689
2690 vector<cl_platform_id> ids(n);
2691 err = ::clGetPlatformIDs(n, ids.data(), nullptr);
2692 if (err != CL_SUCCESS) {
2693 default_error_ = err;
2694 return;
2695 }
2696
2697 default_ = Platform(ids[0]);
2698 }
2699 #if defined(CL_HPP_ENABLE_EXCEPTIONS)
2700 catch (cl::Error &e) {
2701 default_error_ = e.err();
2702 }
2703 #endif
2704 }
2705
2706 /*! \brief Create the default platform from a provided platform.
2707 *
2708 * This sets @c default_. It does not throw
2709 * @c cl::Error.
2710 */
makeDefaultProvided(const Platform & p)2711 static void makeDefaultProvided(const Platform &p) {
2712 default_ = p;
2713 }
2714
2715 public:
2716 #ifdef CL_HPP_UNIT_TEST_ENABLE
2717 /*! \brief Reset the default.
2718 *
2719 * This sets @c default_ to an empty value to support cleanup in
2720 * the unit test framework.
2721 * This function is not thread safe.
2722 */
unitTestClearDefault()2723 static void unitTestClearDefault() {
2724 default_ = Platform();
2725 }
2726 #endif // #ifdef CL_HPP_UNIT_TEST_ENABLE
2727
2728 //! \brief Default constructor - initializes to nullptr.
Platform()2729 Platform() : detail::Wrapper<cl_type>() { }
2730
2731 /*! \brief Constructor from cl_platform_id.
2732 *
2733 * \param retainObject will cause the constructor to retain its cl object.
2734 * Defaults to false to maintain compatibility with
2735 * earlier versions.
2736 * This simply copies the platform ID value, which is an inexpensive operation.
2737 */
Platform(const cl_platform_id & platform,bool retainObject=false)2738 explicit Platform(const cl_platform_id &platform, bool retainObject = false) :
2739 detail::Wrapper<cl_type>(platform, retainObject) { }
2740
2741 /*! \brief Assignment operator from cl_platform_id.
2742 *
2743 * This simply copies the platform ID value, which is an inexpensive operation.
2744 */
operator =(const cl_platform_id & rhs)2745 Platform& operator = (const cl_platform_id& rhs)
2746 {
2747 detail::Wrapper<cl_type>::operator=(rhs);
2748 return *this;
2749 }
2750
getDefault(cl_int * errResult=nullptr)2751 static Platform getDefault(
2752 cl_int *errResult = nullptr)
2753 {
2754 std::call_once(default_initialized_, makeDefault);
2755 detail::errHandler(default_error_);
2756 if (errResult != nullptr) {
2757 *errResult = default_error_;
2758 }
2759 return default_;
2760 }
2761
2762 /**
2763 * Modify the default platform to be used by
2764 * subsequent operations.
2765 * Will only set the default if no default was previously created.
2766 * @return updated default platform.
2767 * Should be compared to the passed value to ensure that it was updated.
2768 */
setDefault(const Platform & default_platform)2769 static Platform setDefault(const Platform &default_platform)
2770 {
2771 std::call_once(default_initialized_, makeDefaultProvided, std::cref(default_platform));
2772 detail::errHandler(default_error_);
2773 return default_;
2774 }
2775
2776 //! \brief Wrapper for clGetPlatformInfo().
2777 template <typename T>
getInfo(cl_platform_info name,T * param) const2778 cl_int getInfo(cl_platform_info name, T* param) const
2779 {
2780 return detail::errHandler(
2781 detail::getInfo(&::clGetPlatformInfo, object_, name, param),
2782 __GET_PLATFORM_INFO_ERR);
2783 }
2784
2785 //! \brief Wrapper for clGetPlatformInfo() that returns by value.
2786 template <cl_platform_info name> typename
2787 detail::param_traits<detail::cl_platform_info, name>::param_type
getInfo(cl_int * err=nullptr) const2788 getInfo(cl_int* err = nullptr) const
2789 {
2790 typename detail::param_traits<
2791 detail::cl_platform_info, name>::param_type param;
2792 cl_int result = getInfo(name, ¶m);
2793 if (err != nullptr) {
2794 *err = result;
2795 }
2796 return param;
2797 }
2798
2799 /*! \brief Gets a list of devices for this platform.
2800 *
2801 * Wraps clGetDeviceIDs().
2802 */
getDevices(cl_device_type type,vector<Device> * devices) const2803 cl_int getDevices(
2804 cl_device_type type,
2805 vector<Device>* devices) const
2806 {
2807 cl_uint n = 0;
2808 if( devices == nullptr ) {
2809 return detail::errHandler(CL_INVALID_ARG_VALUE, __GET_DEVICE_IDS_ERR);
2810 }
2811 cl_int err = ::clGetDeviceIDs(object_, type, 0, nullptr, &n);
2812 if (err != CL_SUCCESS && err != CL_DEVICE_NOT_FOUND) {
2813 return detail::errHandler(err, __GET_DEVICE_IDS_ERR);
2814 }
2815
2816 vector<cl_device_id> ids(n);
2817 if (n>0) {
2818 err = ::clGetDeviceIDs(object_, type, n, ids.data(), nullptr);
2819 if (err != CL_SUCCESS) {
2820 return detail::errHandler(err, __GET_DEVICE_IDS_ERR);
2821 }
2822 }
2823
2824 // Cannot trivially assign because we need to capture intermediates
2825 // with safe construction
2826 // We must retain things we obtain from the API to avoid releasing
2827 // API-owned objects.
2828 if (devices) {
2829 devices->resize(ids.size());
2830
2831 // Assign to param, constructing with retain behaviour
2832 // to correctly capture each underlying CL object
2833 for (size_type i = 0; i < ids.size(); i++) {
2834 (*devices)[i] = Device(ids[i], true);
2835 }
2836 }
2837 return CL_SUCCESS;
2838 }
2839
2840 #if defined(CL_HPP_USE_DX_INTEROP)
2841 /*! \brief Get the list of available D3D10 devices.
2842 *
2843 * \param d3d_device_source.
2844 *
2845 * \param d3d_object.
2846 *
2847 * \param d3d_device_set.
2848 *
2849 * \param devices returns a vector of OpenCL D3D10 devices found. The cl::Device
2850 * values returned in devices can be used to identify a specific OpenCL
2851 * device. If \a devices argument is nullptr, this argument is ignored.
2852 *
2853 * \return One of the following values:
2854 * - CL_SUCCESS if the function is executed successfully.
2855 *
2856 * The application can query specific capabilities of the OpenCL device(s)
2857 * returned by cl::getDevices. This can be used by the application to
2858 * determine which device(s) to use.
2859 *
2860 * \note In the case that exceptions are enabled and a return value
2861 * other than CL_SUCCESS is generated, then cl::Error exception is
2862 * generated.
2863 */
getDevices(cl_d3d10_device_source_khr d3d_device_source,void * d3d_object,cl_d3d10_device_set_khr d3d_device_set,vector<Device> * devices) const2864 cl_int getDevices(
2865 cl_d3d10_device_source_khr d3d_device_source,
2866 void * d3d_object,
2867 cl_d3d10_device_set_khr d3d_device_set,
2868 vector<Device>* devices) const
2869 {
2870 typedef CL_API_ENTRY cl_int (CL_API_CALL *PFN_clGetDeviceIDsFromD3D10KHR)(
2871 cl_platform_id platform,
2872 cl_d3d10_device_source_khr d3d_device_source,
2873 void * d3d_object,
2874 cl_d3d10_device_set_khr d3d_device_set,
2875 cl_uint num_entries,
2876 cl_device_id * devices,
2877 cl_uint* num_devices);
2878
2879 if( devices == nullptr ) {
2880 return detail::errHandler(CL_INVALID_ARG_VALUE, __GET_DEVICE_IDS_ERR);
2881 }
2882
2883 static PFN_clGetDeviceIDsFromD3D10KHR pfn_clGetDeviceIDsFromD3D10KHR = nullptr;
2884 #if CL_HPP_TARGET_OPENCL_VERSION >= 120
2885 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(object_, clGetDeviceIDsFromD3D10KHR);
2886 #endif
2887 #if CL_HPP_MINIMUM_OPENCL_VERSION < 120
2888 CL_HPP_INIT_CL_EXT_FCN_PTR_(clGetDeviceIDsFromD3D10KHR);
2889 #endif
2890
2891 cl_uint n = 0;
2892 cl_int err = pfn_clGetDeviceIDsFromD3D10KHR(
2893 object_,
2894 d3d_device_source,
2895 d3d_object,
2896 d3d_device_set,
2897 0,
2898 nullptr,
2899 &n);
2900 if (err != CL_SUCCESS) {
2901 return detail::errHandler(err, __GET_DEVICE_IDS_ERR);
2902 }
2903
2904 vector<cl_device_id> ids(n);
2905 err = pfn_clGetDeviceIDsFromD3D10KHR(
2906 object_,
2907 d3d_device_source,
2908 d3d_object,
2909 d3d_device_set,
2910 n,
2911 ids.data(),
2912 nullptr);
2913 if (err != CL_SUCCESS) {
2914 return detail::errHandler(err, __GET_DEVICE_IDS_ERR);
2915 }
2916
2917 // Cannot trivially assign because we need to capture intermediates
2918 // with safe construction
2919 // We must retain things we obtain from the API to avoid releasing
2920 // API-owned objects.
2921 if (devices) {
2922 devices->resize(ids.size());
2923
2924 // Assign to param, constructing with retain behaviour
2925 // to correctly capture each underlying CL object
2926 for (size_type i = 0; i < ids.size(); i++) {
2927 (*devices)[i] = Device(ids[i], true);
2928 }
2929 }
2930 return CL_SUCCESS;
2931 }
2932 #endif
2933
2934 /*! \brief Gets a list of available platforms.
2935 *
2936 * Wraps clGetPlatformIDs().
2937 */
get(vector<Platform> * platforms)2938 static cl_int get(
2939 vector<Platform>* platforms)
2940 {
2941 cl_uint n = 0;
2942
2943 if( platforms == nullptr ) {
2944 return detail::errHandler(CL_INVALID_ARG_VALUE, __GET_PLATFORM_IDS_ERR);
2945 }
2946
2947 cl_int err = ::clGetPlatformIDs(0, nullptr, &n);
2948 if (err != CL_SUCCESS) {
2949 return detail::errHandler(err, __GET_PLATFORM_IDS_ERR);
2950 }
2951
2952 vector<cl_platform_id> ids(n);
2953 err = ::clGetPlatformIDs(n, ids.data(), nullptr);
2954 if (err != CL_SUCCESS) {
2955 return detail::errHandler(err, __GET_PLATFORM_IDS_ERR);
2956 }
2957
2958 if (platforms) {
2959 platforms->resize(ids.size());
2960
2961 // Platforms don't reference count
2962 for (size_type i = 0; i < ids.size(); i++) {
2963 (*platforms)[i] = Platform(ids[i]);
2964 }
2965 }
2966 return CL_SUCCESS;
2967 }
2968
2969 /*! \brief Gets the first available platform.
2970 *
2971 * Wraps clGetPlatformIDs(), returning the first result.
2972 */
get(Platform * platform)2973 static cl_int get(
2974 Platform * platform)
2975 {
2976 cl_int err;
2977 Platform default_platform = Platform::getDefault(&err);
2978 if (platform) {
2979 *platform = default_platform;
2980 }
2981 return err;
2982 }
2983
2984 /*! \brief Gets the first available platform, returning it by value.
2985 *
2986 * \return Returns a valid platform if one is available.
2987 * If no platform is available will return a null platform.
2988 * Throws an exception if no platforms are available
2989 * or an error condition occurs.
2990 * Wraps clGetPlatformIDs(), returning the first result.
2991 */
get(cl_int * errResult=nullptr)2992 static Platform get(
2993 cl_int * errResult = nullptr)
2994 {
2995 cl_int err;
2996 Platform default_platform = Platform::getDefault(&err);
2997 if (errResult) {
2998 *errResult = err;
2999 }
3000 return default_platform;
3001 }
3002
3003 #if CL_HPP_TARGET_OPENCL_VERSION >= 120
3004 //! \brief Wrapper for clUnloadCompiler().
3005 cl_int
unloadCompiler()3006 unloadCompiler()
3007 {
3008 return ::clUnloadPlatformCompiler(object_);
3009 }
3010 #endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
3011 }; // class Platform
3012
3013 #if CL_HPP_TARGET_OPENCL_VERSION >= 120
3014 //! \brief Wrapper for clCreateSubDevices().
createSubDevices(const cl_device_partition_property * properties,vector<Device> * devices)3015 inline cl_int Device::createSubDevices(const cl_device_partition_property* properties,
3016 vector<Device>* devices)
3017 {
3018 cl_uint n = 0;
3019 cl_int err = clCreateSubDevices(object_, properties, 0, nullptr, &n);
3020 if (err != CL_SUCCESS)
3021 {
3022 return detail::errHandler(err, __CREATE_SUB_DEVICES_ERR);
3023 }
3024
3025 vector<cl_device_id> ids(n);
3026 err = clCreateSubDevices(object_, properties, n, ids.data(), nullptr);
3027 if (err != CL_SUCCESS)
3028 {
3029 return detail::errHandler(err, __CREATE_SUB_DEVICES_ERR);
3030 }
3031
3032 // Cannot trivially assign because we need to capture intermediates
3033 // with safe construction
3034 if (devices)
3035 {
3036 devices->resize(ids.size());
3037
3038 // Assign to param, constructing with retain behaviour
3039 // to correctly capture each underlying CL object
3040 for (size_type i = 0; i < ids.size(); i++)
3041 {
3042 // We do not need to retain because this device is being created
3043 // by the runtime
3044 (*devices)[i] = Device(ids[i], false);
3045 }
3046 }
3047
3048 return CL_SUCCESS;
3049 }
3050 #endif // defined (CL_HPP_TARGET_OPENCL_VERSION >= 120)
3051
3052 #if defined(cl_ext_device_fission)
3053 //! \brief Wrapper for clCreateSubDevices().
createSubDevices(const cl_device_partition_property_ext * properties,vector<Device> * devices)3054 inline cl_int Device::createSubDevices(const cl_device_partition_property_ext* properties,
3055 vector<Device>* devices)
3056 {
3057 #if CL_HPP_TARGET_OPENCL_VERSION >= 120
3058 cl::Device device(object_);
3059 cl_platform_id platform = device.getInfo<CL_DEVICE_PLATFORM>()();
3060 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clCreateSubDevicesEXT);
3061 #endif
3062 #if CL_HPP_MINIMUM_OPENCL_VERSION < 120
3063 CL_HPP_INIT_CL_EXT_FCN_PTR_(clCreateSubDevicesEXT);
3064 #endif
3065
3066 cl_uint n = 0;
3067 cl_int err = pfn_clCreateSubDevicesEXT(object_, properties, 0, nullptr, &n);
3068 if (err != CL_SUCCESS)
3069 {
3070 return detail::errHandler(err, __CREATE_SUB_DEVICES_ERR);
3071 }
3072
3073 vector<cl_device_id> ids(n);
3074 err =
3075 pfn_clCreateSubDevicesEXT(object_, properties, n, ids.data(), nullptr);
3076 if (err != CL_SUCCESS)
3077 {
3078 return detail::errHandler(err, __CREATE_SUB_DEVICES_ERR);
3079 }
3080 // Cannot trivially assign because we need to capture intermediates
3081 // with safe construction
3082 if (devices)
3083 {
3084 devices->resize(ids.size());
3085
3086 // Assign to param, constructing with retain behaviour
3087 // to correctly capture each underlying CL object
3088 for (size_type i = 0; i < ids.size(); i++)
3089 {
3090 // We do not need to retain because this device is being created
3091 // by the runtime
3092 (*devices)[i] = Device(ids[i], false);
3093 }
3094 }
3095
3096 return CL_SUCCESS;
3097 }
3098 #endif // defined(cl_ext_device_fission)
3099
3100 CL_HPP_DEFINE_STATIC_MEMBER_ std::once_flag Platform::default_initialized_;
3101 CL_HPP_DEFINE_STATIC_MEMBER_ Platform Platform::default_;
3102 CL_HPP_DEFINE_STATIC_MEMBER_ cl_int Platform::default_error_ = CL_SUCCESS;
3103
3104
3105 /**
3106 * Deprecated APIs for 1.2
3107 */
3108 #if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
3109 /**
3110 * Unload the OpenCL compiler.
3111 * \note Deprecated for OpenCL 1.2. Use Platform::unloadCompiler instead.
3112 */
3113 inline CL_API_PREFIX__VERSION_1_1_DEPRECATED cl_int
3114 UnloadCompiler() CL_API_SUFFIX__VERSION_1_1_DEPRECATED;
3115 inline cl_int
UnloadCompiler()3116 UnloadCompiler()
3117 {
3118 return ::clUnloadCompiler();
3119 }
3120 #endif // #if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
3121
3122
3123 #if defined(cl_ext_image_requirements_info)
3124 enum ImageRequirementsInfoExt : cl_image_requirements_info_ext
3125 {
3126 RowPitchAlign = CL_IMAGE_REQUIREMENTS_ROW_PITCH_ALIGNMENT_EXT,
3127 BaseAddAlign = CL_IMAGE_REQUIREMENTS_BASE_ADDRESS_ALIGNMENT_EXT,
3128 Size = CL_IMAGE_REQUIREMENTS_SIZE_EXT,
3129 MaxWidth = CL_IMAGE_REQUIREMENTS_MAX_WIDTH_EXT,
3130 MaxHeight = CL_IMAGE_REQUIREMENTS_MAX_HEIGHT_EXT,
3131 MaxDepth = CL_IMAGE_REQUIREMENTS_MAX_DEPTH_EXT,
3132 MaxArraySize = CL_IMAGE_REQUIREMENTS_MAX_ARRAY_SIZE_EXT,
3133 #if defined(cl_ext_image_from_buffer)
3134 SlicePitchAlign = CL_IMAGE_REQUIREMENTS_SLICE_PITCH_ALIGNMENT_EXT,
3135 #endif
3136 };
3137
3138 #endif // cl_ext_image_requirements_info
3139
3140
3141 /*! \brief Class interface for cl_context.
3142 *
3143 * \note Copies of these objects are shallow, meaning that the copy will refer
3144 * to the same underlying cl_context as the original. For details, see
3145 * clRetainContext() and clReleaseContext().
3146 *
3147 * \see cl_context
3148 */
3149 class Context
3150 : public detail::Wrapper<cl_context>
3151 {
3152 private:
3153 static std::once_flag default_initialized_;
3154 static Context default_;
3155 static cl_int default_error_;
3156
3157 /*! \brief Create the default context from the default device type in the default platform.
3158 *
3159 * This sets @c default_ and @c default_error_. It does not throw
3160 * @c cl::Error.
3161 */
makeDefault()3162 static void makeDefault() {
3163 /* Throwing an exception from a call_once invocation does not do
3164 * what we wish, so we catch it and save the error.
3165 */
3166 #if defined(CL_HPP_ENABLE_EXCEPTIONS)
3167 try
3168 #endif
3169 {
3170 #if !defined(__APPLE__) && !defined(__MACOS)
3171 const Platform &p = Platform::getDefault();
3172 cl_platform_id defaultPlatform = p();
3173 cl_context_properties properties[3] = {
3174 CL_CONTEXT_PLATFORM, (cl_context_properties)defaultPlatform, 0
3175 };
3176 #else // #if !defined(__APPLE__) && !defined(__MACOS)
3177 cl_context_properties *properties = nullptr;
3178 #endif // #if !defined(__APPLE__) && !defined(__MACOS)
3179
3180 default_ = Context(
3181 CL_DEVICE_TYPE_DEFAULT,
3182 properties,
3183 nullptr,
3184 nullptr,
3185 &default_error_);
3186 }
3187 #if defined(CL_HPP_ENABLE_EXCEPTIONS)
3188 catch (cl::Error &e) {
3189 default_error_ = e.err();
3190 }
3191 #endif
3192 }
3193
3194
3195 /*! \brief Create the default context from a provided Context.
3196 *
3197 * This sets @c default_. It does not throw
3198 * @c cl::Error.
3199 */
makeDefaultProvided(const Context & c)3200 static void makeDefaultProvided(const Context &c) {
3201 default_ = c;
3202 }
3203
3204 #if defined(cl_ext_image_requirements_info)
3205 struct ImageRequirementsInfo {
3206
ImageRequirementsInfocl::Context::ImageRequirementsInfo3207 ImageRequirementsInfo(cl_mem_flags f, const cl_mem_properties* properties, const ImageFormat* format, const cl_image_desc* desc)
3208 {
3209 flags = f;
3210 properties = properties;
3211 image_format = format;
3212 image_desc = desc;
3213 }
3214
3215 cl_mem_flags flags = 0;
3216 const cl_mem_properties* properties;
3217 const ImageFormat* image_format;
3218 const cl_image_desc* image_desc;
3219 };
3220
getImageRequirementsInfoExtHelper(const Context & context,const ImageRequirementsInfo & info,cl_image_requirements_info_ext param_name,size_type param_value_size,void * param_value,size_type * param_value_size_ret)3221 static cl_int getImageRequirementsInfoExtHelper(const Context &context,
3222 const ImageRequirementsInfo &info,
3223 cl_image_requirements_info_ext param_name,
3224 size_type param_value_size,
3225 void* param_value,
3226 size_type* param_value_size_ret)
3227 {
3228
3229 #if CL_HPP_TARGET_OPENCL_VERSION >= 120
3230 Device device = context.getInfo<CL_CONTEXT_DEVICES>().at(0);
3231 cl_platform_id platform = device.getInfo<CL_DEVICE_PLATFORM>()();
3232 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clGetImageRequirementsInfoEXT);
3233 #else
3234 CL_HPP_INIT_CL_EXT_FCN_PTR_(clGetImageRequirementsInfoEXT);
3235 #endif
3236
3237 if (pfn_clGetImageRequirementsInfoEXT == nullptr) {
3238 return detail::errHandler(CL_INVALID_OPERATION, __GET_IMAGE_REQUIREMENT_INFO_EXT_ERR);
3239 }
3240
3241 return detail::errHandler(
3242 pfn_clGetImageRequirementsInfoEXT(context(), info.properties,
3243 info.flags, info.image_format, info.image_desc, param_name,
3244 param_value_size, param_value, param_value_size_ret),
3245 __GET_IMAGE_REQUIREMENT_INFO_EXT_ERR);
3246 }
3247 #endif // cl_ext_image_requirements_info
3248
3249 public:
3250 #ifdef CL_HPP_UNIT_TEST_ENABLE
3251 /*! \brief Reset the default.
3252 *
3253 * This sets @c default_ to an empty value to support cleanup in
3254 * the unit test framework.
3255 * This function is not thread safe.
3256 */
unitTestClearDefault()3257 static void unitTestClearDefault() {
3258 default_ = Context();
3259 }
3260 #endif // #ifdef CL_HPP_UNIT_TEST_ENABLE
3261
3262 /*! \brief Constructs a context including a list of specified devices.
3263 *
3264 * Wraps clCreateContext().
3265 */
Context(const vector<Device> & devices,const cl_context_properties * properties=nullptr,void (CL_CALLBACK * notifyFptr)(const char *,const void *,size_type,void *)=nullptr,void * data=nullptr,cl_int * err=nullptr)3266 Context(
3267 const vector<Device>& devices,
3268 const cl_context_properties* properties = nullptr,
3269 void (CL_CALLBACK * notifyFptr)(
3270 const char *,
3271 const void *,
3272 size_type,
3273 void *) = nullptr,
3274 void* data = nullptr,
3275 cl_int* err = nullptr)
3276 {
3277 cl_int error;
3278
3279 size_type numDevices = devices.size();
3280 vector<cl_device_id> deviceIDs(numDevices);
3281
3282 for( size_type deviceIndex = 0; deviceIndex < numDevices; ++deviceIndex ) {
3283 deviceIDs[deviceIndex] = (devices[deviceIndex])();
3284 }
3285
3286 object_ = ::clCreateContext(
3287 properties, (cl_uint) numDevices,
3288 deviceIDs.data(),
3289 notifyFptr, data, &error);
3290
3291 detail::errHandler(error, __CREATE_CONTEXT_ERR);
3292 if (err != nullptr) {
3293 *err = error;
3294 }
3295 }
3296
3297 /*! \brief Constructs a context including a specific device.
3298 *
3299 * Wraps clCreateContext().
3300 */
Context(const Device & device,const cl_context_properties * properties=nullptr,void (CL_CALLBACK * notifyFptr)(const char *,const void *,size_type,void *)=nullptr,void * data=nullptr,cl_int * err=nullptr)3301 Context(
3302 const Device& device,
3303 const cl_context_properties* properties = nullptr,
3304 void (CL_CALLBACK * notifyFptr)(
3305 const char *,
3306 const void *,
3307 size_type,
3308 void *) = nullptr,
3309 void* data = nullptr,
3310 cl_int* err = nullptr)
3311 {
3312 cl_int error;
3313
3314 cl_device_id deviceID = device();
3315
3316 object_ = ::clCreateContext(
3317 properties, 1,
3318 &deviceID,
3319 notifyFptr, data, &error);
3320
3321 detail::errHandler(error, __CREATE_CONTEXT_ERR);
3322 if (err != nullptr) {
3323 *err = error;
3324 }
3325 }
3326
3327 /*! \brief Constructs a context including all or a subset of devices of a specified type.
3328 *
3329 * Wraps clCreateContextFromType().
3330 */
Context(cl_device_type type,const cl_context_properties * properties=nullptr,void (CL_CALLBACK * notifyFptr)(const char *,const void *,size_type,void *)=nullptr,void * data=nullptr,cl_int * err=nullptr)3331 Context(
3332 cl_device_type type,
3333 const cl_context_properties* properties = nullptr,
3334 void (CL_CALLBACK * notifyFptr)(
3335 const char *,
3336 const void *,
3337 size_type,
3338 void *) = nullptr,
3339 void* data = nullptr,
3340 cl_int* err = nullptr)
3341 {
3342 cl_int error;
3343
3344 #if !defined(__APPLE__) && !defined(__MACOS)
3345 cl_context_properties prop[4] = {CL_CONTEXT_PLATFORM, 0, 0, 0 };
3346
3347 if (properties == nullptr) {
3348 // Get a valid platform ID as we cannot send in a blank one
3349 vector<Platform> platforms;
3350 error = Platform::get(&platforms);
3351 if (error != CL_SUCCESS) {
3352 detail::errHandler(error, __CREATE_CONTEXT_FROM_TYPE_ERR);
3353 if (err != nullptr) {
3354 *err = error;
3355 }
3356 return;
3357 }
3358
3359 // Check the platforms we found for a device of our specified type
3360 cl_context_properties platform_id = 0;
3361 for (unsigned int i = 0; i < platforms.size(); i++) {
3362
3363 vector<Device> devices;
3364
3365 #if defined(CL_HPP_ENABLE_EXCEPTIONS)
3366 try {
3367 #endif
3368
3369 error = platforms[i].getDevices(type, &devices);
3370
3371 #if defined(CL_HPP_ENABLE_EXCEPTIONS)
3372 } catch (cl::Error& e) {
3373 error = e.err();
3374 }
3375 // Catch if exceptions are enabled as we don't want to exit if first platform has no devices of type
3376 // We do error checking next anyway, and can throw there if needed
3377 #endif
3378
3379 // Only squash CL_SUCCESS and CL_DEVICE_NOT_FOUND
3380 if (error != CL_SUCCESS && error != CL_DEVICE_NOT_FOUND) {
3381 detail::errHandler(error, __CREATE_CONTEXT_FROM_TYPE_ERR);
3382 if (err != nullptr) {
3383 *err = error;
3384 }
3385 }
3386
3387 if (devices.size() > 0) {
3388 platform_id = (cl_context_properties)platforms[i]();
3389 break;
3390 }
3391 }
3392
3393 if (platform_id == 0) {
3394 detail::errHandler(CL_DEVICE_NOT_FOUND, __CREATE_CONTEXT_FROM_TYPE_ERR);
3395 if (err != nullptr) {
3396 *err = CL_DEVICE_NOT_FOUND;
3397 }
3398 return;
3399 }
3400
3401 prop[1] = platform_id;
3402 properties = &prop[0];
3403 }
3404 #endif
3405 object_ = ::clCreateContextFromType(
3406 properties, type, notifyFptr, data, &error);
3407
3408 detail::errHandler(error, __CREATE_CONTEXT_FROM_TYPE_ERR);
3409 if (err != nullptr) {
3410 *err = error;
3411 }
3412 }
3413
3414
3415 /*! \brief Returns a singleton context including all devices of CL_DEVICE_TYPE_DEFAULT.
3416 *
3417 * \note All calls to this function return the same cl_context as the first.
3418 */
getDefault(cl_int * err=nullptr)3419 static Context getDefault(cl_int * err = nullptr)
3420 {
3421 std::call_once(default_initialized_, makeDefault);
3422 detail::errHandler(default_error_);
3423 if (err != nullptr) {
3424 *err = default_error_;
3425 }
3426 return default_;
3427 }
3428
3429 /**
3430 * Modify the default context to be used by
3431 * subsequent operations.
3432 * Will only set the default if no default was previously created.
3433 * @return updated default context.
3434 * Should be compared to the passed value to ensure that it was updated.
3435 */
setDefault(const Context & default_context)3436 static Context setDefault(const Context &default_context)
3437 {
3438 std::call_once(default_initialized_, makeDefaultProvided, std::cref(default_context));
3439 detail::errHandler(default_error_);
3440 return default_;
3441 }
3442
3443 //! \brief Default constructor - initializes to nullptr.
Context()3444 Context() : detail::Wrapper<cl_type>() { }
3445
3446 /*! \brief Constructor from cl_context - takes ownership.
3447 *
3448 * This effectively transfers ownership of a refcount on the cl_context
3449 * into the new Context object.
3450 */
Context(const cl_context & context,bool retainObject=false)3451 explicit Context(const cl_context& context, bool retainObject = false) :
3452 detail::Wrapper<cl_type>(context, retainObject) { }
3453
3454 /*! \brief Assignment operator from cl_context - takes ownership.
3455 *
3456 * This effectively transfers ownership of a refcount on the rhs and calls
3457 * clReleaseContext() on the value previously held by this instance.
3458 */
operator =(const cl_context & rhs)3459 Context& operator = (const cl_context& rhs)
3460 {
3461 detail::Wrapper<cl_type>::operator=(rhs);
3462 return *this;
3463 }
3464
3465 //! \brief Wrapper for clGetContextInfo().
3466 template <typename T>
getInfo(cl_context_info name,T * param) const3467 cl_int getInfo(cl_context_info name, T* param) const
3468 {
3469 return detail::errHandler(
3470 detail::getInfo(&::clGetContextInfo, object_, name, param),
3471 __GET_CONTEXT_INFO_ERR);
3472 }
3473
3474 //! \brief Wrapper for clGetContextInfo() that returns by value.
3475 template <cl_context_info name> typename
3476 detail::param_traits<detail::cl_context_info, name>::param_type
getInfo(cl_int * err=nullptr) const3477 getInfo(cl_int* err = nullptr) const
3478 {
3479 typename detail::param_traits<
3480 detail::cl_context_info, name>::param_type param;
3481 cl_int result = getInfo(name, ¶m);
3482 if (err != nullptr) {
3483 *err = result;
3484 }
3485 return param;
3486 }
3487
3488 /*! \brief Gets a list of supported image formats.
3489 *
3490 * Wraps clGetSupportedImageFormats().
3491 */
getSupportedImageFormats(cl_mem_flags flags,cl_mem_object_type type,vector<ImageFormat> * formats) const3492 cl_int getSupportedImageFormats(
3493 cl_mem_flags flags,
3494 cl_mem_object_type type,
3495 vector<ImageFormat>* formats) const
3496 {
3497 cl_uint numEntries;
3498
3499 if (!formats) {
3500 return CL_SUCCESS;
3501 }
3502
3503 cl_int err = ::clGetSupportedImageFormats(
3504 object_,
3505 flags,
3506 type,
3507 0,
3508 nullptr,
3509 &numEntries);
3510 if (err != CL_SUCCESS) {
3511 return detail::errHandler(err, __GET_SUPPORTED_IMAGE_FORMATS_ERR);
3512 }
3513
3514 if (numEntries > 0) {
3515 vector<ImageFormat> value(numEntries);
3516 err = ::clGetSupportedImageFormats(
3517 object_,
3518 flags,
3519 type,
3520 numEntries,
3521 (cl_image_format*)value.data(),
3522 nullptr);
3523 if (err != CL_SUCCESS) {
3524 return detail::errHandler(err, __GET_SUPPORTED_IMAGE_FORMATS_ERR);
3525 }
3526
3527 formats->assign(value.begin(), value.end());
3528 }
3529 else {
3530 // If no values are being returned, ensure an empty vector comes back
3531 formats->clear();
3532 }
3533
3534 return CL_SUCCESS;
3535 }
3536
3537 #if defined(cl_ext_image_requirements_info)
3538 template <typename T>
getImageRequirementsInfoExt(cl_image_requirements_info_ext name,T * param,cl_mem_flags flags=0,const cl_mem_properties * properties=nullptr,const ImageFormat * image_format=nullptr,const cl_image_desc * image_desc=nullptr) const3539 cl_int getImageRequirementsInfoExt(cl_image_requirements_info_ext name,
3540 T* param,
3541 cl_mem_flags flags = 0,
3542 const cl_mem_properties* properties = nullptr,
3543 const ImageFormat* image_format = nullptr,
3544 const cl_image_desc* image_desc = nullptr) const
3545 {
3546 ImageRequirementsInfo imageInfo = {flags, properties, image_format, image_desc};
3547
3548 return detail::errHandler(
3549 detail::getInfo(
3550 Context::getImageRequirementsInfoExtHelper, *this, imageInfo, name, param),
3551 __GET_IMAGE_REQUIREMENT_INFO_EXT_ERR);
3552 }
3553
3554 template <cl_image_requirements_info_ext type> typename
3555 detail::param_traits<detail::cl_image_requirements_info_ext, type>::param_type
getImageRequirementsInfoExt(cl_mem_flags flags=0,const cl_mem_properties * properties=nullptr,const ImageFormat * image_format=nullptr,const cl_image_desc * image_desc=nullptr,cl_int * err=nullptr) const3556 getImageRequirementsInfoExt(cl_mem_flags flags = 0,
3557 const cl_mem_properties* properties = nullptr,
3558 const ImageFormat* image_format = nullptr,
3559 const cl_image_desc* image_desc = nullptr,
3560 cl_int* err = nullptr) const
3561 {
3562 typename detail::param_traits<
3563 detail::cl_image_requirements_info_ext, type>::param_type param;
3564 cl_int result = getImageRequirementsInfoExt(type, ¶m, flags, properties, image_format, image_desc);
3565 if (err != nullptr) {
3566 *err = result;
3567 }
3568 return param;
3569 }
3570 #endif // cl_ext_image_requirements_info
3571
3572 #if CL_HPP_TARGET_OPENCL_VERSION >= 300
3573 /*! \brief Registers a destructor callback function with a context.
3574 *
3575 * Wraps clSetContextDestructorCallback().
3576 *
3577 * Each call to this function registers the specified callback function on
3578 * a destructor callback stack associated with context. The registered
3579 * callback functions are called in the reverse order in which they were registered.
3580 * If a context callback function was specified when context was created,
3581 * it will not be called after any context destructor callback is called.
3582 */
setDestructorCallback(void (CL_CALLBACK * pfn_notify)(cl_context,void *),void * user_data=nullptr)3583 cl_int setDestructorCallback(
3584 void (CL_CALLBACK * pfn_notify)(cl_context, void *),
3585 void * user_data = nullptr)
3586 {
3587 return detail::errHandler(
3588 ::clSetContextDestructorCallback(
3589 object_,
3590 pfn_notify,
3591 user_data),
3592 __SET_CONTEXT_DESCTRUCTOR_CALLBACK_ERR);
3593 }
3594 #endif // CL_HPP_TARGET_OPENCL_VERSION >= 300
3595 };
3596
makeDefault()3597 inline void Device::makeDefault()
3598 {
3599 /* Throwing an exception from a call_once invocation does not do
3600 * what we wish, so we catch it and save the error.
3601 */
3602 #if defined(CL_HPP_ENABLE_EXCEPTIONS)
3603 try
3604 #endif
3605 {
3606 cl_int error = 0;
3607
3608 Context context = Context::getDefault(&error);
3609 detail::errHandler(error, __CREATE_CONTEXT_ERR);
3610
3611 if (error != CL_SUCCESS) {
3612 default_error_ = error;
3613 }
3614 else {
3615 default_ = context.getInfo<CL_CONTEXT_DEVICES>()[0];
3616 default_error_ = CL_SUCCESS;
3617 }
3618 }
3619 #if defined(CL_HPP_ENABLE_EXCEPTIONS)
3620 catch (cl::Error &e) {
3621 default_error_ = e.err();
3622 }
3623 #endif
3624 }
3625
3626 CL_HPP_DEFINE_STATIC_MEMBER_ std::once_flag Context::default_initialized_;
3627 CL_HPP_DEFINE_STATIC_MEMBER_ Context Context::default_;
3628 CL_HPP_DEFINE_STATIC_MEMBER_ cl_int Context::default_error_ = CL_SUCCESS;
3629
3630 /*! \brief Class interface for cl_event.
3631 *
3632 * \note Copies of these objects are shallow, meaning that the copy will refer
3633 * to the same underlying cl_event as the original. For details, see
3634 * clRetainEvent() and clReleaseEvent().
3635 *
3636 * \see cl_event
3637 */
3638 class Event : public detail::Wrapper<cl_event>
3639 {
3640 public:
3641 //! \brief Default constructor - initializes to nullptr.
Event()3642 Event() : detail::Wrapper<cl_type>() { }
3643
3644 /*! \brief Constructor from cl_event - takes ownership.
3645 *
3646 * \param retainObject will cause the constructor to retain its cl object.
3647 * Defaults to false to maintain compatibility with
3648 * earlier versions.
3649 * This effectively transfers ownership of a refcount on the cl_event
3650 * into the new Event object.
3651 */
Event(const cl_event & event,bool retainObject=false)3652 explicit Event(const cl_event& event, bool retainObject = false) :
3653 detail::Wrapper<cl_type>(event, retainObject) { }
3654
3655 /*! \brief Assignment operator from cl_event - takes ownership.
3656 *
3657 * This effectively transfers ownership of a refcount on the rhs and calls
3658 * clReleaseEvent() on the value previously held by this instance.
3659 */
operator =(const cl_event & rhs)3660 Event& operator = (const cl_event& rhs)
3661 {
3662 detail::Wrapper<cl_type>::operator=(rhs);
3663 return *this;
3664 }
3665
3666 //! \brief Wrapper for clGetEventInfo().
3667 template <typename T>
getInfo(cl_event_info name,T * param) const3668 cl_int getInfo(cl_event_info name, T* param) const
3669 {
3670 return detail::errHandler(
3671 detail::getInfo(&::clGetEventInfo, object_, name, param),
3672 __GET_EVENT_INFO_ERR);
3673 }
3674
3675 //! \brief Wrapper for clGetEventInfo() that returns by value.
3676 template <cl_event_info name> typename
3677 detail::param_traits<detail::cl_event_info, name>::param_type
getInfo(cl_int * err=nullptr) const3678 getInfo(cl_int* err = nullptr) const
3679 {
3680 typename detail::param_traits<
3681 detail::cl_event_info, name>::param_type param;
3682 cl_int result = getInfo(name, ¶m);
3683 if (err != nullptr) {
3684 *err = result;
3685 }
3686 return param;
3687 }
3688
3689 //! \brief Wrapper for clGetEventProfilingInfo().
3690 template <typename T>
getProfilingInfo(cl_profiling_info name,T * param) const3691 cl_int getProfilingInfo(cl_profiling_info name, T* param) const
3692 {
3693 return detail::errHandler(detail::getInfo(
3694 &::clGetEventProfilingInfo, object_, name, param),
3695 __GET_EVENT_PROFILE_INFO_ERR);
3696 }
3697
3698 //! \brief Wrapper for clGetEventProfilingInfo() that returns by value.
3699 template <cl_profiling_info name> typename
3700 detail::param_traits<detail::cl_profiling_info, name>::param_type
getProfilingInfo(cl_int * err=nullptr) const3701 getProfilingInfo(cl_int* err = nullptr) const
3702 {
3703 typename detail::param_traits<
3704 detail::cl_profiling_info, name>::param_type param;
3705 cl_int result = getProfilingInfo(name, ¶m);
3706 if (err != nullptr) {
3707 *err = result;
3708 }
3709 return param;
3710 }
3711
3712 /*! \brief Blocks the calling thread until this event completes.
3713 *
3714 * Wraps clWaitForEvents().
3715 */
wait() const3716 cl_int wait() const
3717 {
3718 return detail::errHandler(
3719 ::clWaitForEvents(1, &object_),
3720 __WAIT_FOR_EVENTS_ERR);
3721 }
3722
3723 #if CL_HPP_TARGET_OPENCL_VERSION >= 110
3724 /*! \brief Registers a user callback function for a specific command execution status.
3725 *
3726 * Wraps clSetEventCallback().
3727 */
setCallback(cl_int type,void (CL_CALLBACK * pfn_notify)(cl_event,cl_int,void *),void * user_data=nullptr)3728 cl_int setCallback(
3729 cl_int type,
3730 void (CL_CALLBACK * pfn_notify)(cl_event, cl_int, void *),
3731 void * user_data = nullptr)
3732 {
3733 return detail::errHandler(
3734 ::clSetEventCallback(
3735 object_,
3736 type,
3737 pfn_notify,
3738 user_data),
3739 __SET_EVENT_CALLBACK_ERR);
3740 }
3741 #endif // CL_HPP_TARGET_OPENCL_VERSION >= 110
3742
3743 /*! \brief Blocks the calling thread until every event specified is complete.
3744 *
3745 * Wraps clWaitForEvents().
3746 */
3747 static cl_int
waitForEvents(const vector<Event> & events)3748 waitForEvents(const vector<Event>& events)
3749 {
3750 static_assert(sizeof(cl::Event) == sizeof(cl_event),
3751 "Size of cl::Event must be equal to size of cl_event");
3752
3753 return detail::errHandler(
3754 ::clWaitForEvents(
3755 (cl_uint) events.size(), (events.size() > 0) ? (cl_event*)&events.front() : nullptr),
3756 __WAIT_FOR_EVENTS_ERR);
3757 }
3758 };
3759
3760 #if CL_HPP_TARGET_OPENCL_VERSION >= 110
3761 /*! \brief Class interface for user events (a subset of cl_event's).
3762 *
3763 * See Event for details about copy semantics, etc.
3764 */
3765 class UserEvent : public Event
3766 {
3767 public:
3768 /*! \brief Constructs a user event on a given context.
3769 *
3770 * Wraps clCreateUserEvent().
3771 */
UserEvent(const Context & context,cl_int * err=nullptr)3772 UserEvent(
3773 const Context& context,
3774 cl_int * err = nullptr)
3775 {
3776 cl_int error;
3777 object_ = ::clCreateUserEvent(
3778 context(),
3779 &error);
3780
3781 detail::errHandler(error, __CREATE_USER_EVENT_ERR);
3782 if (err != nullptr) {
3783 *err = error;
3784 }
3785 }
3786
3787 //! \brief Default constructor - initializes to nullptr.
UserEvent()3788 UserEvent() : Event() { }
3789
3790 /*! \brief Sets the execution status of a user event object.
3791 *
3792 * Wraps clSetUserEventStatus().
3793 */
setStatus(cl_int status)3794 cl_int setStatus(cl_int status)
3795 {
3796 return detail::errHandler(
3797 ::clSetUserEventStatus(object_,status),
3798 __SET_USER_EVENT_STATUS_ERR);
3799 }
3800 };
3801 #endif // CL_HPP_TARGET_OPENCL_VERSION >= 110
3802
3803 /*! \brief Blocks the calling thread until every event specified is complete.
3804 *
3805 * Wraps clWaitForEvents().
3806 */
3807 inline static cl_int
WaitForEvents(const vector<Event> & events)3808 WaitForEvents(const vector<Event>& events)
3809 {
3810 return detail::errHandler(
3811 ::clWaitForEvents(
3812 (cl_uint) events.size(), (events.size() > 0) ? (cl_event*)&events.front() : nullptr),
3813 __WAIT_FOR_EVENTS_ERR);
3814 }
3815
3816 /*! \brief Class interface for cl_mem.
3817 *
3818 * \note Copies of these objects are shallow, meaning that the copy will refer
3819 * to the same underlying cl_mem as the original. For details, see
3820 * clRetainMemObject() and clReleaseMemObject().
3821 *
3822 * \see cl_mem
3823 */
3824 class Memory : public detail::Wrapper<cl_mem>
3825 {
3826 public:
3827 //! \brief Default constructor - initializes to nullptr.
Memory()3828 Memory() : detail::Wrapper<cl_type>() { }
3829
3830 /*! \brief Constructor from cl_mem - takes ownership.
3831 *
3832 * Optionally transfer ownership of a refcount on the cl_mem
3833 * into the new Memory object.
3834 *
3835 * \param retainObject will cause the constructor to retain its cl object.
3836 * Defaults to false to maintain compatibility with
3837 * earlier versions.
3838 *
3839 * See Memory for further details.
3840 */
Memory(const cl_mem & memory,bool retainObject)3841 explicit Memory(const cl_mem& memory, bool retainObject) :
3842 detail::Wrapper<cl_type>(memory, retainObject) { }
3843
3844 /*! \brief Assignment operator from cl_mem - takes ownership.
3845 *
3846 * This effectively transfers ownership of a refcount on the rhs and calls
3847 * clReleaseMemObject() on the value previously held by this instance.
3848 */
operator =(const cl_mem & rhs)3849 Memory& operator = (const cl_mem& rhs)
3850 {
3851 detail::Wrapper<cl_type>::operator=(rhs);
3852 return *this;
3853 }
3854
3855 //! \brief Wrapper for clGetMemObjectInfo().
3856 template <typename T>
getInfo(cl_mem_info name,T * param) const3857 cl_int getInfo(cl_mem_info name, T* param) const
3858 {
3859 return detail::errHandler(
3860 detail::getInfo(&::clGetMemObjectInfo, object_, name, param),
3861 __GET_MEM_OBJECT_INFO_ERR);
3862 }
3863
3864 //! \brief Wrapper for clGetMemObjectInfo() that returns by value.
3865 template <cl_mem_info name> typename
3866 detail::param_traits<detail::cl_mem_info, name>::param_type
getInfo(cl_int * err=nullptr) const3867 getInfo(cl_int* err = nullptr) const
3868 {
3869 typename detail::param_traits<
3870 detail::cl_mem_info, name>::param_type param;
3871 cl_int result = getInfo(name, ¶m);
3872 if (err != nullptr) {
3873 *err = result;
3874 }
3875 return param;
3876 }
3877
3878 #if CL_HPP_TARGET_OPENCL_VERSION >= 110
3879 /*! \brief Registers a callback function to be called when the memory object
3880 * is no longer needed.
3881 *
3882 * Wraps clSetMemObjectDestructorCallback().
3883 *
3884 * Repeated calls to this function, for a given cl_mem value, will append
3885 * to the list of functions called (in reverse order) when memory object's
3886 * resources are freed and the memory object is deleted.
3887 *
3888 * \note
3889 * The registered callbacks are associated with the underlying cl_mem
3890 * value - not the Memory class instance.
3891 */
setDestructorCallback(void (CL_CALLBACK * pfn_notify)(cl_mem,void *),void * user_data=nullptr)3892 cl_int setDestructorCallback(
3893 void (CL_CALLBACK * pfn_notify)(cl_mem, void *),
3894 void * user_data = nullptr)
3895 {
3896 return detail::errHandler(
3897 ::clSetMemObjectDestructorCallback(
3898 object_,
3899 pfn_notify,
3900 user_data),
3901 __SET_MEM_OBJECT_DESTRUCTOR_CALLBACK_ERR);
3902 }
3903 #endif // CL_HPP_TARGET_OPENCL_VERSION >= 110
3904
3905 };
3906
3907 // Pre-declare copy functions
3908 class Buffer;
3909 template< typename IteratorType >
3910 cl_int copy( IteratorType startIterator, IteratorType endIterator, cl::Buffer &buffer );
3911 template< typename IteratorType >
3912 cl_int copy( const cl::Buffer &buffer, IteratorType startIterator, IteratorType endIterator );
3913 template< typename IteratorType >
3914 cl_int copy( const CommandQueue &queue, IteratorType startIterator, IteratorType endIterator, cl::Buffer &buffer );
3915 template< typename IteratorType >
3916 cl_int copy( const CommandQueue &queue, const cl::Buffer &buffer, IteratorType startIterator, IteratorType endIterator );
3917
3918
3919 #if CL_HPP_TARGET_OPENCL_VERSION >= 200
3920 namespace detail
3921 {
3922 class SVMTraitNull
3923 {
3924 public:
getSVMMemFlags()3925 static cl_svm_mem_flags getSVMMemFlags()
3926 {
3927 return 0;
3928 }
3929 };
3930 } // namespace detail
3931
3932 template<class Trait = detail::SVMTraitNull>
3933 class SVMTraitReadWrite
3934 {
3935 public:
getSVMMemFlags()3936 static cl_svm_mem_flags getSVMMemFlags()
3937 {
3938 return CL_MEM_READ_WRITE |
3939 Trait::getSVMMemFlags();
3940 }
3941 };
3942
3943 template<class Trait = detail::SVMTraitNull>
3944 class SVMTraitReadOnly
3945 {
3946 public:
getSVMMemFlags()3947 static cl_svm_mem_flags getSVMMemFlags()
3948 {
3949 return CL_MEM_READ_ONLY |
3950 Trait::getSVMMemFlags();
3951 }
3952 };
3953
3954 template<class Trait = detail::SVMTraitNull>
3955 class SVMTraitWriteOnly
3956 {
3957 public:
getSVMMemFlags()3958 static cl_svm_mem_flags getSVMMemFlags()
3959 {
3960 return CL_MEM_WRITE_ONLY |
3961 Trait::getSVMMemFlags();
3962 }
3963 };
3964
3965 template<class Trait = SVMTraitReadWrite<>>
3966 class SVMTraitCoarse
3967 {
3968 public:
getSVMMemFlags()3969 static cl_svm_mem_flags getSVMMemFlags()
3970 {
3971 return Trait::getSVMMemFlags();
3972 }
3973 };
3974
3975 template<class Trait = SVMTraitReadWrite<>>
3976 class SVMTraitFine
3977 {
3978 public:
getSVMMemFlags()3979 static cl_svm_mem_flags getSVMMemFlags()
3980 {
3981 return CL_MEM_SVM_FINE_GRAIN_BUFFER |
3982 Trait::getSVMMemFlags();
3983 }
3984 };
3985
3986 template<class Trait = SVMTraitReadWrite<>>
3987 class SVMTraitAtomic
3988 {
3989 public:
getSVMMemFlags()3990 static cl_svm_mem_flags getSVMMemFlags()
3991 {
3992 return
3993 CL_MEM_SVM_FINE_GRAIN_BUFFER |
3994 CL_MEM_SVM_ATOMICS |
3995 Trait::getSVMMemFlags();
3996 }
3997 };
3998
3999 // Pre-declare SVM map function
4000 template<typename T>
4001 inline cl_int enqueueMapSVM(
4002 T* ptr,
4003 cl_bool blocking,
4004 cl_map_flags flags,
4005 size_type size,
4006 const vector<Event>* events = nullptr,
4007 Event* event = nullptr);
4008
4009 /**
4010 * STL-like allocator class for managing SVM objects provided for convenience.
4011 *
4012 * Note that while this behaves like an allocator for the purposes of constructing vectors and similar objects,
4013 * care must be taken when using with smart pointers.
4014 * The allocator should not be used to construct a unique_ptr if we are using coarse-grained SVM mode because
4015 * the coarse-grained management behaviour would behave incorrectly with respect to reference counting.
4016 *
4017 * Instead the allocator embeds a Deleter which may be used with unique_ptr and is used
4018 * with the allocate_shared and allocate_ptr supplied operations.
4019 */
4020 template<typename T, class SVMTrait>
4021 class SVMAllocator {
4022 private:
4023 Context context_;
4024
4025 public:
4026 typedef T value_type;
4027 typedef value_type* pointer;
4028 typedef const value_type* const_pointer;
4029 typedef value_type& reference;
4030 typedef const value_type& const_reference;
4031 typedef std::size_t size_type;
4032 typedef std::ptrdiff_t difference_type;
4033
4034 template<typename U>
4035 struct rebind
4036 {
4037 typedef SVMAllocator<U, SVMTrait> other;
4038 };
4039
4040 template<typename U, typename V>
4041 friend class SVMAllocator;
4042
SVMAllocator()4043 SVMAllocator() :
4044 context_(Context::getDefault())
4045 {
4046 }
4047
SVMAllocator(cl::Context context)4048 explicit SVMAllocator(cl::Context context) :
4049 context_(context)
4050 {
4051 }
4052
4053
SVMAllocator(const SVMAllocator & other)4054 SVMAllocator(const SVMAllocator &other) :
4055 context_(other.context_)
4056 {
4057 }
4058
4059 template<typename U>
SVMAllocator(const SVMAllocator<U,SVMTrait> & other)4060 SVMAllocator(const SVMAllocator<U, SVMTrait> &other) :
4061 context_(other.context_)
4062 {
4063 }
4064
~SVMAllocator()4065 ~SVMAllocator()
4066 {
4067 }
4068
address(reference r)4069 pointer address(reference r) noexcept
4070 {
4071 return std::addressof(r);
4072 }
4073
address(const_reference r)4074 const_pointer address(const_reference r) noexcept
4075 {
4076 return std::addressof(r);
4077 }
4078
4079 /**
4080 * Allocate an SVM pointer.
4081 *
4082 * If the allocator is coarse-grained, this will take ownership to allow
4083 * containers to correctly construct data in place.
4084 */
allocate(size_type size,typename cl::SVMAllocator<void,SVMTrait>::const_pointer=0,bool map=true)4085 pointer allocate(
4086 size_type size,
4087 typename cl::SVMAllocator<void, SVMTrait>::const_pointer = 0,
4088 bool map = true)
4089 {
4090 // Allocate memory with default alignment matching the size of the type
4091 void* voidPointer =
4092 clSVMAlloc(
4093 context_(),
4094 SVMTrait::getSVMMemFlags(),
4095 size*sizeof(T),
4096 0);
4097 pointer retValue = reinterpret_cast<pointer>(
4098 voidPointer);
4099 #if defined(CL_HPP_ENABLE_EXCEPTIONS)
4100 if (!retValue) {
4101 std::bad_alloc excep;
4102 throw excep;
4103 }
4104 #endif // #if defined(CL_HPP_ENABLE_EXCEPTIONS)
4105
4106 // If allocation was coarse-grained then map it
4107 if (map && !(SVMTrait::getSVMMemFlags() & CL_MEM_SVM_FINE_GRAIN_BUFFER)) {
4108 cl_int err = enqueueMapSVM(retValue, CL_TRUE, CL_MAP_READ | CL_MAP_WRITE, size*sizeof(T));
4109 if (err != CL_SUCCESS) {
4110 clSVMFree(context_(), retValue);
4111 retValue = nullptr;
4112 #if defined(CL_HPP_ENABLE_EXCEPTIONS)
4113 std::bad_alloc excep;
4114 throw excep;
4115 #endif
4116 }
4117 }
4118
4119 // If exceptions disabled, return null pointer from allocator
4120 return retValue;
4121 }
4122
deallocate(pointer p,size_type)4123 void deallocate(pointer p, size_type)
4124 {
4125 clSVMFree(context_(), p);
4126 }
4127
4128 /**
4129 * Return the maximum possible allocation size.
4130 * This is the minimum of the maximum sizes of all devices in the context.
4131 */
max_size() const4132 size_type max_size() const noexcept
4133 {
4134 size_type maxSize = std::numeric_limits<size_type>::max() / sizeof(T);
4135
4136 for (const Device &d : context_.getInfo<CL_CONTEXT_DEVICES>()) {
4137 maxSize = std::min(
4138 maxSize,
4139 static_cast<size_type>(d.getInfo<CL_DEVICE_MAX_MEM_ALLOC_SIZE>()));
4140 }
4141
4142 return maxSize;
4143 }
4144
4145 template< class U, class... Args >
construct(U * p,Args &&...args)4146 void construct(U* p, Args&&... args)
4147 {
4148 new(p)T(args...);
4149 }
4150
4151 template< class U >
destroy(U * p)4152 void destroy(U* p)
4153 {
4154 p->~U();
4155 }
4156
4157 /**
4158 * Returns true if the contexts match.
4159 */
operator ==(SVMAllocator const & rhs)4160 inline bool operator==(SVMAllocator const& rhs)
4161 {
4162 return (context_==rhs.context_);
4163 }
4164
operator !=(SVMAllocator const & a)4165 inline bool operator!=(SVMAllocator const& a)
4166 {
4167 return !operator==(a);
4168 }
4169 }; // class SVMAllocator return cl::pointer<T>(tmp, detail::Deleter<T, Alloc>{alloc, copies});
4170
4171
4172 template<class SVMTrait>
4173 class SVMAllocator<void, SVMTrait> {
4174 public:
4175 typedef void value_type;
4176 typedef value_type* pointer;
4177 typedef const value_type* const_pointer;
4178
4179 template<typename U>
4180 struct rebind
4181 {
4182 typedef SVMAllocator<U, SVMTrait> other;
4183 };
4184
4185 template<typename U, typename V>
4186 friend class SVMAllocator;
4187 };
4188
4189 #if !defined(CL_HPP_NO_STD_UNIQUE_PTR)
4190 namespace detail
4191 {
4192 template<class Alloc>
4193 class Deleter {
4194 private:
4195 Alloc alloc_;
4196 size_type copies_;
4197
4198 public:
4199 typedef typename std::allocator_traits<Alloc>::pointer pointer;
4200
Deleter(const Alloc & alloc,size_type copies)4201 Deleter(const Alloc &alloc, size_type copies) : alloc_{ alloc }, copies_{ copies }
4202 {
4203 }
4204
operator ()(pointer ptr) const4205 void operator()(pointer ptr) const {
4206 Alloc tmpAlloc{ alloc_ };
4207 std::allocator_traits<Alloc>::destroy(tmpAlloc, std::addressof(*ptr));
4208 std::allocator_traits<Alloc>::deallocate(tmpAlloc, ptr, copies_);
4209 }
4210 };
4211 } // namespace detail
4212
4213 /**
4214 * Allocation operation compatible with std::allocate_ptr.
4215 * Creates a unique_ptr<T> by default.
4216 * This requirement is to ensure that the control block is not
4217 * allocated in memory inaccessible to the host.
4218 */
4219 template <class T, class Alloc, class... Args>
allocate_pointer(const Alloc & alloc_,Args &&...args)4220 cl::pointer<T, detail::Deleter<Alloc>> allocate_pointer(const Alloc &alloc_, Args&&... args)
4221 {
4222 Alloc alloc(alloc_);
4223 static const size_type copies = 1;
4224
4225 // Ensure that creation of the management block and the
4226 // object are dealt with separately such that we only provide a deleter
4227
4228 T* tmp = std::allocator_traits<Alloc>::allocate(alloc, copies);
4229 if (!tmp) {
4230 std::bad_alloc excep;
4231 throw excep;
4232 }
4233 try {
4234 std::allocator_traits<Alloc>::construct(
4235 alloc,
4236 std::addressof(*tmp),
4237 std::forward<Args>(args)...);
4238
4239 return cl::pointer<T, detail::Deleter<Alloc>>(tmp, detail::Deleter<Alloc>{alloc, copies});
4240 }
4241 catch (std::bad_alloc&)
4242 {
4243 std::allocator_traits<Alloc>::deallocate(alloc, tmp, copies);
4244 throw;
4245 }
4246 }
4247
4248 template< class T, class SVMTrait, class... Args >
allocate_svm(Args...args)4249 cl::pointer<T, detail::Deleter<SVMAllocator<T, SVMTrait>>> allocate_svm(Args... args)
4250 {
4251 SVMAllocator<T, SVMTrait> alloc;
4252 return cl::allocate_pointer<T>(alloc, args...);
4253 }
4254
4255 template< class T, class SVMTrait, class... Args >
allocate_svm(const cl::Context & c,Args...args)4256 cl::pointer<T, detail::Deleter<SVMAllocator<T, SVMTrait>>> allocate_svm(const cl::Context &c, Args... args)
4257 {
4258 SVMAllocator<T, SVMTrait> alloc(c);
4259 return cl::allocate_pointer<T>(alloc, args...);
4260 }
4261 #endif // #if !defined(CL_HPP_NO_STD_UNIQUE_PTR)
4262
4263 /*! \brief Vector alias to simplify contruction of coarse-grained SVM containers.
4264 *
4265 */
4266 template < class T >
4267 using coarse_svm_vector = vector<T, cl::SVMAllocator<int, cl::SVMTraitCoarse<>>>;
4268
4269 /*! \brief Vector alias to simplify contruction of fine-grained SVM containers.
4270 *
4271 */
4272 template < class T >
4273 using fine_svm_vector = vector<T, cl::SVMAllocator<int, cl::SVMTraitFine<>>>;
4274
4275 /*! \brief Vector alias to simplify contruction of fine-grained SVM containers that support platform atomics.
4276 *
4277 */
4278 template < class T >
4279 using atomic_svm_vector = vector<T, cl::SVMAllocator<int, cl::SVMTraitAtomic<>>>;
4280
4281 #endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 200
4282
4283
4284 /*! \brief Class interface for Buffer Memory Objects.
4285 *
4286 * See Memory for details about copy semantics, etc.
4287 *
4288 * \see Memory
4289 */
4290 class Buffer : public Memory
4291 {
4292 public:
4293
4294 /*! \brief Constructs a Buffer in a specified context.
4295 *
4296 * Wraps clCreateBuffer().
4297 *
4298 * \param host_ptr Storage to be used if the CL_MEM_USE_HOST_PTR flag was
4299 * specified. Note alignment & exclusivity requirements.
4300 */
Buffer(const Context & context,cl_mem_flags flags,size_type size,void * host_ptr=nullptr,cl_int * err=nullptr)4301 Buffer(
4302 const Context& context,
4303 cl_mem_flags flags,
4304 size_type size,
4305 void* host_ptr = nullptr,
4306 cl_int* err = nullptr)
4307 {
4308 cl_int error;
4309 object_ = ::clCreateBuffer(context(), flags, size, host_ptr, &error);
4310
4311 detail::errHandler(error, __CREATE_BUFFER_ERR);
4312 if (err != nullptr) {
4313 *err = error;
4314 }
4315 }
4316
4317 #if CL_HPP_TARGET_OPENCL_VERSION >= 300
4318 /*! \brief Constructs a Buffer in a specified context and with specified properties.
4319 *
4320 * Wraps clCreateBufferWithProperties().
4321 *
4322 * \param properties Optional list of properties for the buffer object and
4323 * their corresponding values. The non-empty list must
4324 * end with 0.
4325 * \param host_ptr Storage to be used if the CL_MEM_USE_HOST_PTR flag was
4326 * specified. Note alignment & exclusivity requirements.
4327 */
Buffer(const Context & context,const vector<cl_mem_properties> & properties,cl_mem_flags flags,size_type size,void * host_ptr=nullptr,cl_int * err=nullptr)4328 Buffer(
4329 const Context& context,
4330 const vector<cl_mem_properties>& properties,
4331 cl_mem_flags flags,
4332 size_type size,
4333 void* host_ptr = nullptr,
4334 cl_int* err = nullptr)
4335 {
4336 cl_int error;
4337
4338 if (properties.empty()) {
4339 object_ = ::clCreateBufferWithProperties(context(), nullptr, flags,
4340 size, host_ptr, &error);
4341 }
4342 else {
4343 object_ = ::clCreateBufferWithProperties(
4344 context(), properties.data(), flags, size, host_ptr, &error);
4345 }
4346
4347 detail::errHandler(error, __CREATE_BUFFER_ERR);
4348 if (err != nullptr) {
4349 *err = error;
4350 }
4351 }
4352 #endif
4353
4354 /*! \brief Constructs a Buffer in the default context.
4355 *
4356 * Wraps clCreateBuffer().
4357 *
4358 * \param host_ptr Storage to be used if the CL_MEM_USE_HOST_PTR flag was
4359 * specified. Note alignment & exclusivity requirements.
4360 *
4361 * \see Context::getDefault()
4362 */
Buffer(cl_mem_flags flags,size_type size,void * host_ptr=nullptr,cl_int * err=nullptr)4363 Buffer(
4364 cl_mem_flags flags,
4365 size_type size,
4366 void* host_ptr = nullptr,
4367 cl_int* err = nullptr) : Buffer(Context::getDefault(err), flags, size, host_ptr, err) { }
4368
4369 #if CL_HPP_TARGET_OPENCL_VERSION >= 300
4370 /*! \brief Constructs a Buffer in the default context and with specified properties.
4371 *
4372 * Wraps clCreateBufferWithProperties().
4373 *
4374 * \param properties Optional list of properties for the buffer object and
4375 * their corresponding values. The non-empty list must
4376 * end with 0.
4377 * \param host_ptr Storage to be used if the CL_MEM_USE_HOST_PTR flag was
4378 * specified. Note alignment & exclusivity requirements.
4379 *
4380 * \see Context::getDefault()
4381 */
Buffer(const vector<cl_mem_properties> & properties,cl_mem_flags flags,size_type size,void * host_ptr=nullptr,cl_int * err=nullptr)4382 Buffer(
4383 const vector<cl_mem_properties>& properties,
4384 cl_mem_flags flags,
4385 size_type size,
4386 void* host_ptr = nullptr,
4387 cl_int* err = nullptr) : Buffer(Context::getDefault(err), properties, flags, size, host_ptr, err) { }
4388 #endif
4389
4390 /*!
4391 * \brief Construct a Buffer from a host container via iterators.
4392 * IteratorType must be random access.
4393 * If useHostPtr is specified iterators must represent contiguous data.
4394 */
4395 template< typename IteratorType >
Buffer(IteratorType startIterator,IteratorType endIterator,bool readOnly,bool useHostPtr=false,cl_int * err=nullptr)4396 Buffer(
4397 IteratorType startIterator,
4398 IteratorType endIterator,
4399 bool readOnly,
4400 bool useHostPtr = false,
4401 cl_int* err = nullptr)
4402 {
4403 typedef typename std::iterator_traits<IteratorType>::value_type DataType;
4404 cl_int error;
4405
4406 cl_mem_flags flags = 0;
4407 if( readOnly ) {
4408 flags |= CL_MEM_READ_ONLY;
4409 }
4410 else {
4411 flags |= CL_MEM_READ_WRITE;
4412 }
4413 if( useHostPtr ) {
4414 flags |= CL_MEM_USE_HOST_PTR;
4415 }
4416
4417 size_type size = sizeof(DataType)*(endIterator - startIterator);
4418
4419 Context context = Context::getDefault(err);
4420
4421 if( useHostPtr ) {
4422 object_ = ::clCreateBuffer(context(), flags, size, const_cast<DataType*>(&*startIterator), &error);
4423 } else {
4424 object_ = ::clCreateBuffer(context(), flags, size, 0, &error);
4425 }
4426
4427 detail::errHandler(error, __CREATE_BUFFER_ERR);
4428 if (err != nullptr) {
4429 *err = error;
4430 }
4431
4432 if( !useHostPtr ) {
4433 error = cl::copy(startIterator, endIterator, *this);
4434 detail::errHandler(error, __CREATE_BUFFER_ERR);
4435 if (err != nullptr) {
4436 *err = error;
4437 }
4438 }
4439 }
4440
4441 /*!
4442 * \brief Construct a Buffer from a host container via iterators using a specified context.
4443 * IteratorType must be random access.
4444 * If useHostPtr is specified iterators must represent contiguous data.
4445 */
4446 template< typename IteratorType >
4447 Buffer(const Context &context, IteratorType startIterator, IteratorType endIterator,
4448 bool readOnly, bool useHostPtr = false, cl_int* err = nullptr);
4449
4450 /*!
4451 * \brief Construct a Buffer from a host container via iterators using a specified queue.
4452 * If useHostPtr is specified iterators must be random access.
4453 */
4454 template< typename IteratorType >
4455 Buffer(const CommandQueue &queue, IteratorType startIterator, IteratorType endIterator,
4456 bool readOnly, bool useHostPtr = false, cl_int* err = nullptr);
4457
4458 //! \brief Default constructor - initializes to nullptr.
Buffer()4459 Buffer() : Memory() { }
4460
4461 /*! \brief Constructor from cl_mem - takes ownership.
4462 *
4463 * \param retainObject will cause the constructor to retain its cl object.
4464 * Defaults to false to maintain compatibility with earlier versions.
4465 *
4466 * See Memory for further details.
4467 */
Buffer(const cl_mem & buffer,bool retainObject=false)4468 explicit Buffer(const cl_mem& buffer, bool retainObject = false) :
4469 Memory(buffer, retainObject) { }
4470
4471 /*! \brief Assignment from cl_mem - performs shallow copy.
4472 *
4473 * See Memory for further details.
4474 */
operator =(const cl_mem & rhs)4475 Buffer& operator = (const cl_mem& rhs)
4476 {
4477 Memory::operator=(rhs);
4478 return *this;
4479 }
4480
4481
4482 #if CL_HPP_TARGET_OPENCL_VERSION >= 110
4483 /*! \brief Creates a new buffer object from this.
4484 *
4485 * Wraps clCreateSubBuffer().
4486 */
createSubBuffer(cl_mem_flags flags,cl_buffer_create_type buffer_create_type,const void * buffer_create_info,cl_int * err=nullptr)4487 Buffer createSubBuffer(
4488 cl_mem_flags flags,
4489 cl_buffer_create_type buffer_create_type,
4490 const void * buffer_create_info,
4491 cl_int * err = nullptr)
4492 {
4493 Buffer result;
4494 cl_int error;
4495 result.object_ = ::clCreateSubBuffer(
4496 object_,
4497 flags,
4498 buffer_create_type,
4499 buffer_create_info,
4500 &error);
4501
4502 detail::errHandler(error, __CREATE_SUBBUFFER_ERR);
4503 if (err != nullptr) {
4504 *err = error;
4505 }
4506
4507 return result;
4508 }
4509 #endif // CL_HPP_TARGET_OPENCL_VERSION >= 110
4510 };
4511
4512 #if defined (CL_HPP_USE_DX_INTEROP)
4513 /*! \brief Class interface for creating OpenCL buffers from ID3D10Buffer's.
4514 *
4515 * This is provided to facilitate interoperability with Direct3D.
4516 *
4517 * See Memory for details about copy semantics, etc.
4518 *
4519 * \see Memory
4520 */
4521 class BufferD3D10 : public Buffer
4522 {
4523 public:
4524
4525
4526 /*! \brief Constructs a BufferD3D10, in a specified context, from a
4527 * given ID3D10Buffer.
4528 *
4529 * Wraps clCreateFromD3D10BufferKHR().
4530 */
BufferD3D10(const Context & context,cl_mem_flags flags,ID3D10Buffer * bufobj,cl_int * err=nullptr)4531 BufferD3D10(
4532 const Context& context,
4533 cl_mem_flags flags,
4534 ID3D10Buffer* bufobj,
4535 cl_int * err = nullptr) : pfn_clCreateFromD3D10BufferKHR(nullptr)
4536 {
4537 typedef CL_API_ENTRY cl_mem (CL_API_CALL *PFN_clCreateFromD3D10BufferKHR)(
4538 cl_context context, cl_mem_flags flags, ID3D10Buffer* buffer,
4539 cl_int* errcode_ret);
4540 PFN_clCreateFromD3D10BufferKHR pfn_clCreateFromD3D10BufferKHR;
4541 #if CL_HPP_TARGET_OPENCL_VERSION >= 120
4542 vector<cl_context_properties> props = context.getInfo<CL_CONTEXT_PROPERTIES>();
4543 cl_platform platform = nullptr;
4544 for( int i = 0; i < props.size(); ++i ) {
4545 if( props[i] == CL_CONTEXT_PLATFORM ) {
4546 platform = props[i+1];
4547 }
4548 }
4549 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clCreateFromD3D10BufferKHR);
4550 #endif
4551 #if CL_HPP_MINIMUM_OPENCL_VERSION < 120
4552 CL_HPP_INIT_CL_EXT_FCN_PTR_(clCreateFromD3D10BufferKHR);
4553 #endif
4554
4555 cl_int error;
4556 object_ = pfn_clCreateFromD3D10BufferKHR(
4557 context(),
4558 flags,
4559 bufobj,
4560 &error);
4561
4562 // TODO: This should really have a D3D10 rerror code!
4563 detail::errHandler(error, __CREATE_GL_BUFFER_ERR);
4564 if (err != nullptr) {
4565 *err = error;
4566 }
4567 }
4568
4569 //! \brief Default constructor - initializes to nullptr.
BufferD3D10()4570 BufferD3D10() : Buffer() { }
4571
4572 /*! \brief Constructor from cl_mem - takes ownership.
4573 *
4574 * \param retainObject will cause the constructor to retain its cl object.
4575 * Defaults to false to maintain compatibility with
4576 * earlier versions.
4577 * See Memory for further details.
4578 */
BufferD3D10(const cl_mem & buffer,bool retainObject=false)4579 explicit BufferD3D10(const cl_mem& buffer, bool retainObject = false) :
4580 Buffer(buffer, retainObject) { }
4581
4582 /*! \brief Assignment from cl_mem - performs shallow copy.
4583 *
4584 * See Memory for further details.
4585 */
operator =(const cl_mem & rhs)4586 BufferD3D10& operator = (const cl_mem& rhs)
4587 {
4588 Buffer::operator=(rhs);
4589 return *this;
4590 }
4591 };
4592 #endif
4593
4594 /*! \brief Class interface for GL Buffer Memory Objects.
4595 *
4596 * This is provided to facilitate interoperability with OpenGL.
4597 *
4598 * See Memory for details about copy semantics, etc.
4599 *
4600 * \see Memory
4601 */
4602 class BufferGL : public Buffer
4603 {
4604 public:
4605 /*! \brief Constructs a BufferGL in a specified context, from a given
4606 * GL buffer.
4607 *
4608 * Wraps clCreateFromGLBuffer().
4609 */
BufferGL(const Context & context,cl_mem_flags flags,cl_GLuint bufobj,cl_int * err=nullptr)4610 BufferGL(
4611 const Context& context,
4612 cl_mem_flags flags,
4613 cl_GLuint bufobj,
4614 cl_int * err = nullptr)
4615 {
4616 cl_int error;
4617 object_ = ::clCreateFromGLBuffer(
4618 context(),
4619 flags,
4620 bufobj,
4621 &error);
4622
4623 detail::errHandler(error, __CREATE_GL_BUFFER_ERR);
4624 if (err != nullptr) {
4625 *err = error;
4626 }
4627 }
4628
4629 //! \brief Default constructor - initializes to nullptr.
BufferGL()4630 BufferGL() : Buffer() { }
4631
4632 /*! \brief Constructor from cl_mem - takes ownership.
4633 *
4634 * \param retainObject will cause the constructor to retain its cl object.
4635 * Defaults to false to maintain compatibility with
4636 * earlier versions.
4637 * See Memory for further details.
4638 */
BufferGL(const cl_mem & buffer,bool retainObject=false)4639 explicit BufferGL(const cl_mem& buffer, bool retainObject = false) :
4640 Buffer(buffer, retainObject) { }
4641
4642 /*! \brief Assignment from cl_mem - performs shallow copy.
4643 *
4644 * See Memory for further details.
4645 */
operator =(const cl_mem & rhs)4646 BufferGL& operator = (const cl_mem& rhs)
4647 {
4648 Buffer::operator=(rhs);
4649 return *this;
4650 }
4651
4652
4653 //! \brief Wrapper for clGetGLObjectInfo().
getObjectInfo(cl_gl_object_type * type,cl_GLuint * gl_object_name)4654 cl_int getObjectInfo(
4655 cl_gl_object_type *type,
4656 cl_GLuint * gl_object_name)
4657 {
4658 return detail::errHandler(
4659 ::clGetGLObjectInfo(object_,type,gl_object_name),
4660 __GET_GL_OBJECT_INFO_ERR);
4661 }
4662 };
4663
4664 /*! \brief Class interface for GL Render Buffer Memory Objects.
4665 *
4666 * This is provided to facilitate interoperability with OpenGL.
4667 *
4668 * See Memory for details about copy semantics, etc.
4669 *
4670 * \see Memory
4671 */
4672 class BufferRenderGL : public Buffer
4673 {
4674 public:
4675 /*! \brief Constructs a BufferRenderGL in a specified context, from a given
4676 * GL Renderbuffer.
4677 *
4678 * Wraps clCreateFromGLRenderbuffer().
4679 */
BufferRenderGL(const Context & context,cl_mem_flags flags,cl_GLuint bufobj,cl_int * err=nullptr)4680 BufferRenderGL(
4681 const Context& context,
4682 cl_mem_flags flags,
4683 cl_GLuint bufobj,
4684 cl_int * err = nullptr)
4685 {
4686 cl_int error;
4687 object_ = ::clCreateFromGLRenderbuffer(
4688 context(),
4689 flags,
4690 bufobj,
4691 &error);
4692
4693 detail::errHandler(error, __CREATE_GL_RENDER_BUFFER_ERR);
4694 if (err != nullptr) {
4695 *err = error;
4696 }
4697 }
4698
4699 //! \brief Default constructor - initializes to nullptr.
BufferRenderGL()4700 BufferRenderGL() : Buffer() { }
4701
4702 /*! \brief Constructor from cl_mem - takes ownership.
4703 *
4704 * \param retainObject will cause the constructor to retain its cl object.
4705 * Defaults to false to maintain compatibility with
4706 * earlier versions.
4707 * See Memory for further details.
4708 */
BufferRenderGL(const cl_mem & buffer,bool retainObject=false)4709 explicit BufferRenderGL(const cl_mem& buffer, bool retainObject = false) :
4710 Buffer(buffer, retainObject) { }
4711
4712 /*! \brief Assignment from cl_mem - performs shallow copy.
4713 *
4714 * See Memory for further details.
4715 */
operator =(const cl_mem & rhs)4716 BufferRenderGL& operator = (const cl_mem& rhs)
4717 {
4718 Buffer::operator=(rhs);
4719 return *this;
4720 }
4721
4722
4723 //! \brief Wrapper for clGetGLObjectInfo().
getObjectInfo(cl_gl_object_type * type,cl_GLuint * gl_object_name)4724 cl_int getObjectInfo(
4725 cl_gl_object_type *type,
4726 cl_GLuint * gl_object_name)
4727 {
4728 return detail::errHandler(
4729 ::clGetGLObjectInfo(object_,type,gl_object_name),
4730 __GET_GL_OBJECT_INFO_ERR);
4731 }
4732 };
4733
4734 /*! \brief C++ base class for Image Memory objects.
4735 *
4736 * See Memory for details about copy semantics, etc.
4737 *
4738 * \see Memory
4739 */
4740 class Image : public Memory
4741 {
4742 protected:
4743 //! \brief Default constructor - initializes to nullptr.
Image()4744 Image() : Memory() { }
4745
4746 /*! \brief Constructor from cl_mem - takes ownership.
4747 *
4748 * \param retainObject will cause the constructor to retain its cl object.
4749 * Defaults to false to maintain compatibility with
4750 * earlier versions.
4751 * See Memory for further details.
4752 */
Image(const cl_mem & image,bool retainObject=false)4753 explicit Image(const cl_mem& image, bool retainObject = false) :
4754 Memory(image, retainObject) { }
4755
4756 /*! \brief Assignment from cl_mem - performs shallow copy.
4757 *
4758 * See Memory for further details.
4759 */
operator =(const cl_mem & rhs)4760 Image& operator = (const cl_mem& rhs)
4761 {
4762 Memory::operator=(rhs);
4763 return *this;
4764 }
4765
4766
4767 public:
4768 //! \brief Wrapper for clGetImageInfo().
4769 template <typename T>
getImageInfo(cl_image_info name,T * param) const4770 cl_int getImageInfo(cl_image_info name, T* param) const
4771 {
4772 return detail::errHandler(
4773 detail::getInfo(&::clGetImageInfo, object_, name, param),
4774 __GET_IMAGE_INFO_ERR);
4775 }
4776
4777 //! \brief Wrapper for clGetImageInfo() that returns by value.
4778 template <cl_image_info name> typename
4779 detail::param_traits<detail::cl_image_info, name>::param_type
getImageInfo(cl_int * err=nullptr) const4780 getImageInfo(cl_int* err = nullptr) const
4781 {
4782 typename detail::param_traits<
4783 detail::cl_image_info, name>::param_type param;
4784 cl_int result = getImageInfo(name, ¶m);
4785 if (err != nullptr) {
4786 *err = result;
4787 }
4788 return param;
4789 }
4790 };
4791
4792 #if CL_HPP_TARGET_OPENCL_VERSION >= 120
4793 /*! \brief Class interface for 1D Image Memory objects.
4794 *
4795 * See Memory for details about copy semantics, etc.
4796 *
4797 * \see Memory
4798 */
4799 class Image1D : public Image
4800 {
4801 public:
4802 /*! \brief Constructs a 1D Image in a specified context.
4803 *
4804 * Wraps clCreateImage().
4805 */
Image1D(const Context & context,cl_mem_flags flags,ImageFormat format,size_type width,void * host_ptr=nullptr,cl_int * err=nullptr)4806 Image1D(
4807 const Context& context,
4808 cl_mem_flags flags,
4809 ImageFormat format,
4810 size_type width,
4811 void* host_ptr = nullptr,
4812 cl_int* err = nullptr)
4813 {
4814 cl_int error;
4815
4816 cl_image_desc desc = {};
4817 desc.image_type = CL_MEM_OBJECT_IMAGE1D;
4818 desc.image_width = width;
4819
4820 object_ = ::clCreateImage(
4821 context(),
4822 flags,
4823 &format,
4824 &desc,
4825 host_ptr,
4826 &error);
4827
4828 detail::errHandler(error, __CREATE_IMAGE_ERR);
4829 if (err != nullptr) {
4830 *err = error;
4831 }
4832 }
4833
4834 //! \brief Default constructor - initializes to nullptr.
Image1D()4835 Image1D() { }
4836
4837 /*! \brief Constructor from cl_mem - takes ownership.
4838 *
4839 * \param retainObject will cause the constructor to retain its cl object.
4840 * Defaults to false to maintain compatibility with
4841 * earlier versions.
4842 * See Memory for further details.
4843 */
Image1D(const cl_mem & image1D,bool retainObject=false)4844 explicit Image1D(const cl_mem& image1D, bool retainObject = false) :
4845 Image(image1D, retainObject) { }
4846
4847 /*! \brief Assignment from cl_mem - performs shallow copy.
4848 *
4849 * See Memory for further details.
4850 */
operator =(const cl_mem & rhs)4851 Image1D& operator = (const cl_mem& rhs)
4852 {
4853 Image::operator=(rhs);
4854 return *this;
4855 }
4856
4857
4858 };
4859
4860 /*! \class Image1DBuffer
4861 * \brief Image interface for 1D buffer images.
4862 */
4863 class Image1DBuffer : public Image
4864 {
4865 public:
Image1DBuffer(const Context & context,cl_mem_flags flags,ImageFormat format,size_type width,const Buffer & buffer,cl_int * err=nullptr)4866 Image1DBuffer(
4867 const Context& context,
4868 cl_mem_flags flags,
4869 ImageFormat format,
4870 size_type width,
4871 const Buffer &buffer,
4872 cl_int* err = nullptr)
4873 {
4874 cl_int error;
4875
4876 cl_image_desc desc = {};
4877 desc.image_type = CL_MEM_OBJECT_IMAGE1D_BUFFER;
4878 desc.image_width = width;
4879 desc.buffer = buffer();
4880
4881 object_ = ::clCreateImage(
4882 context(),
4883 flags,
4884 &format,
4885 &desc,
4886 nullptr,
4887 &error);
4888
4889 detail::errHandler(error, __CREATE_IMAGE_ERR);
4890 if (err != nullptr) {
4891 *err = error;
4892 }
4893 }
4894
Image1DBuffer()4895 Image1DBuffer() { }
4896
4897 /*! \brief Constructor from cl_mem - takes ownership.
4898 *
4899 * \param retainObject will cause the constructor to retain its cl object.
4900 * Defaults to false to maintain compatibility with
4901 * earlier versions.
4902 * See Memory for further details.
4903 */
Image1DBuffer(const cl_mem & image1D,bool retainObject=false)4904 explicit Image1DBuffer(const cl_mem& image1D, bool retainObject = false) :
4905 Image(image1D, retainObject) { }
4906
operator =(const cl_mem & rhs)4907 Image1DBuffer& operator = (const cl_mem& rhs)
4908 {
4909 Image::operator=(rhs);
4910 return *this;
4911 }
4912
4913
4914
4915 };
4916
4917 /*! \class Image1DArray
4918 * \brief Image interface for arrays of 1D images.
4919 */
4920 class Image1DArray : public Image
4921 {
4922 public:
Image1DArray(const Context & context,cl_mem_flags flags,ImageFormat format,size_type arraySize,size_type width,size_type rowPitch,void * host_ptr=nullptr,cl_int * err=nullptr)4923 Image1DArray(
4924 const Context& context,
4925 cl_mem_flags flags,
4926 ImageFormat format,
4927 size_type arraySize,
4928 size_type width,
4929 size_type rowPitch,
4930 void* host_ptr = nullptr,
4931 cl_int* err = nullptr)
4932 {
4933 cl_int error;
4934
4935 cl_image_desc desc = {};
4936 desc.image_type = CL_MEM_OBJECT_IMAGE1D_ARRAY;
4937 desc.image_width = width;
4938 desc.image_array_size = arraySize;
4939 desc.image_row_pitch = rowPitch;
4940
4941 object_ = ::clCreateImage(
4942 context(),
4943 flags,
4944 &format,
4945 &desc,
4946 host_ptr,
4947 &error);
4948
4949 detail::errHandler(error, __CREATE_IMAGE_ERR);
4950 if (err != nullptr) {
4951 *err = error;
4952 }
4953 }
4954
Image1DArray()4955 Image1DArray() { }
4956
4957 /*! \brief Constructor from cl_mem - takes ownership.
4958 *
4959 * \param retainObject will cause the constructor to retain its cl object.
4960 * Defaults to false to maintain compatibility with
4961 * earlier versions.
4962 * See Memory for further details.
4963 */
Image1DArray(const cl_mem & imageArray,bool retainObject=false)4964 explicit Image1DArray(const cl_mem& imageArray, bool retainObject = false) :
4965 Image(imageArray, retainObject) { }
4966
4967
operator =(const cl_mem & rhs)4968 Image1DArray& operator = (const cl_mem& rhs)
4969 {
4970 Image::operator=(rhs);
4971 return *this;
4972 }
4973
4974
4975 };
4976 #endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 120
4977
4978
4979 /*! \brief Class interface for 2D Image Memory objects.
4980 *
4981 * See Memory for details about copy semantics, etc.
4982 *
4983 * \see Memory
4984 */
4985 class Image2D : public Image
4986 {
4987 public:
4988 /*! \brief Constructs a 2D Image in a specified context.
4989 *
4990 * Wraps clCreateImage().
4991 */
Image2D(const Context & context,cl_mem_flags flags,ImageFormat format,size_type width,size_type height,size_type row_pitch=0,void * host_ptr=nullptr,cl_int * err=nullptr)4992 Image2D(
4993 const Context& context,
4994 cl_mem_flags flags,
4995 ImageFormat format,
4996 size_type width,
4997 size_type height,
4998 size_type row_pitch = 0,
4999 void* host_ptr = nullptr,
5000 cl_int* err = nullptr)
5001 {
5002 cl_int error;
5003 bool useCreateImage;
5004
5005 #if CL_HPP_TARGET_OPENCL_VERSION >= 120 && CL_HPP_MINIMUM_OPENCL_VERSION < 120
5006 // Run-time decision based on the actual platform
5007 {
5008 cl_uint version = detail::getContextPlatformVersion(context());
5009 useCreateImage = (version >= 0x10002); // OpenCL 1.2 or above
5010 }
5011 #elif CL_HPP_TARGET_OPENCL_VERSION >= 120
5012 useCreateImage = true;
5013 #else
5014 useCreateImage = false;
5015 #endif
5016
5017 #if CL_HPP_TARGET_OPENCL_VERSION >= 120
5018 if (useCreateImage)
5019 {
5020 cl_image_desc desc = {};
5021 desc.image_type = CL_MEM_OBJECT_IMAGE2D;
5022 desc.image_width = width;
5023 desc.image_height = height;
5024 desc.image_row_pitch = row_pitch;
5025
5026 object_ = ::clCreateImage(
5027 context(),
5028 flags,
5029 &format,
5030 &desc,
5031 host_ptr,
5032 &error);
5033
5034 detail::errHandler(error, __CREATE_IMAGE_ERR);
5035 if (err != nullptr) {
5036 *err = error;
5037 }
5038 }
5039 #endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
5040 #if CL_HPP_MINIMUM_OPENCL_VERSION < 120
5041 if (!useCreateImage)
5042 {
5043 object_ = ::clCreateImage2D(
5044 context(), flags,&format, width, height, row_pitch, host_ptr, &error);
5045
5046 detail::errHandler(error, __CREATE_IMAGE2D_ERR);
5047 if (err != nullptr) {
5048 *err = error;
5049 }
5050 }
5051 #endif // CL_HPP_MINIMUM_OPENCL_VERSION < 120
5052 }
5053
5054 #if CL_HPP_TARGET_OPENCL_VERSION >= 120
5055 /*! \brief Constructs a 2D Image from a buffer.
5056 * \note This will share storage with the underlying buffer.
5057 *
5058 * Requires OpenCL 2.0 or newer or OpenCL 1.2 and the
5059 * cl_khr_image2d_from_buffer extension.
5060 *
5061 * Wraps clCreateImage().
5062 */
Image2D(const Context & context,ImageFormat format,const Buffer & sourceBuffer,size_type width,size_type height,size_type row_pitch=0,cl_int * err=nullptr)5063 Image2D(
5064 const Context& context,
5065 ImageFormat format,
5066 const Buffer &sourceBuffer,
5067 size_type width,
5068 size_type height,
5069 size_type row_pitch = 0,
5070 cl_int* err = nullptr)
5071 {
5072 cl_int error;
5073
5074 cl_image_desc desc = {};
5075 desc.image_type = CL_MEM_OBJECT_IMAGE2D;
5076 desc.image_width = width;
5077 desc.image_height = height;
5078 desc.image_row_pitch = row_pitch;
5079 desc.buffer = sourceBuffer();
5080
5081 object_ = ::clCreateImage(
5082 context(),
5083 0, // flags inherited from buffer
5084 &format,
5085 &desc,
5086 nullptr,
5087 &error);
5088
5089 detail::errHandler(error, __CREATE_IMAGE_ERR);
5090 if (err != nullptr) {
5091 *err = error;
5092 }
5093 }
5094 #endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
5095
5096 #if CL_HPP_TARGET_OPENCL_VERSION >= 200
5097 /*! \brief Constructs a 2D Image from an image.
5098 * \note This will share storage with the underlying image but may
5099 * reinterpret the channel order and type.
5100 *
5101 * The image will be created matching with a descriptor matching the source.
5102 *
5103 * \param order is the channel order to reinterpret the image data as.
5104 * The channel order may differ as described in the OpenCL
5105 * 2.0 API specification.
5106 *
5107 * Wraps clCreateImage().
5108 */
Image2D(const Context & context,cl_channel_order order,const Image & sourceImage,cl_int * err=nullptr)5109 Image2D(
5110 const Context& context,
5111 cl_channel_order order,
5112 const Image &sourceImage,
5113 cl_int* err = nullptr)
5114 {
5115 cl_int error;
5116
5117 // Descriptor fields have to match source image
5118 size_type sourceWidth =
5119 sourceImage.getImageInfo<CL_IMAGE_WIDTH>();
5120 size_type sourceHeight =
5121 sourceImage.getImageInfo<CL_IMAGE_HEIGHT>();
5122 size_type sourceRowPitch =
5123 sourceImage.getImageInfo<CL_IMAGE_ROW_PITCH>();
5124 cl_uint sourceNumMIPLevels =
5125 sourceImage.getImageInfo<CL_IMAGE_NUM_MIP_LEVELS>();
5126 cl_uint sourceNumSamples =
5127 sourceImage.getImageInfo<CL_IMAGE_NUM_SAMPLES>();
5128 cl_image_format sourceFormat =
5129 sourceImage.getImageInfo<CL_IMAGE_FORMAT>();
5130
5131 // Update only the channel order.
5132 // Channel format inherited from source.
5133 sourceFormat.image_channel_order = order;
5134
5135 cl_image_desc desc = {};
5136 desc.image_type = CL_MEM_OBJECT_IMAGE2D;
5137 desc.image_width = sourceWidth;
5138 desc.image_height = sourceHeight;
5139 desc.image_row_pitch = sourceRowPitch;
5140 desc.num_mip_levels = sourceNumMIPLevels;
5141 desc.num_samples = sourceNumSamples;
5142 desc.buffer = sourceImage();
5143
5144 object_ = ::clCreateImage(
5145 context(),
5146 0, // flags should be inherited from mem_object
5147 &sourceFormat,
5148 &desc,
5149 nullptr,
5150 &error);
5151
5152 detail::errHandler(error, __CREATE_IMAGE_ERR);
5153 if (err != nullptr) {
5154 *err = error;
5155 }
5156 }
5157 #endif //#if CL_HPP_TARGET_OPENCL_VERSION >= 200
5158
5159 //! \brief Default constructor - initializes to nullptr.
Image2D()5160 Image2D() { }
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 */
Image2D(const cl_mem & image2D,bool retainObject=false)5169 explicit Image2D(const cl_mem& image2D, bool retainObject = false) :
5170 Image(image2D, retainObject) { }
5171
5172 /*! \brief Assignment from cl_mem - performs shallow copy.
5173 *
5174 * See Memory for further details.
5175 */
operator =(const cl_mem & rhs)5176 Image2D& operator = (const cl_mem& rhs)
5177 {
5178 Image::operator=(rhs);
5179 return *this;
5180 }
5181
5182
5183
5184
5185 };
5186
5187
5188 #if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
5189 /*! \brief Class interface for GL 2D Image Memory objects.
5190 *
5191 * This is provided to facilitate interoperability with OpenGL.
5192 *
5193 * See Memory for details about copy semantics, etc.
5194 *
5195 * \see Memory
5196 * \note Deprecated for OpenCL 1.2. Please use ImageGL instead.
5197 */
5198 class CL_API_PREFIX__VERSION_1_1_DEPRECATED Image2DGL : public Image2D
5199 {
5200 public:
5201 /*! \brief Constructs an Image2DGL in a specified context, from a given
5202 * GL Texture.
5203 *
5204 * Wraps clCreateFromGLTexture2D().
5205 */
Image2DGL(const Context & context,cl_mem_flags flags,cl_GLenum target,cl_GLint miplevel,cl_GLuint texobj,cl_int * err=nullptr)5206 Image2DGL(
5207 const Context& context,
5208 cl_mem_flags flags,
5209 cl_GLenum target,
5210 cl_GLint miplevel,
5211 cl_GLuint texobj,
5212 cl_int * err = nullptr)
5213 {
5214 cl_int error;
5215 object_ = ::clCreateFromGLTexture2D(
5216 context(),
5217 flags,
5218 target,
5219 miplevel,
5220 texobj,
5221 &error);
5222
5223 detail::errHandler(error, __CREATE_GL_TEXTURE_2D_ERR);
5224 if (err != nullptr) {
5225 *err = error;
5226 }
5227
5228 }
5229
5230 //! \brief Default constructor - initializes to nullptr.
Image2DGL()5231 Image2DGL() : Image2D() { }
5232
5233 /*! \brief Constructor from cl_mem - takes ownership.
5234 *
5235 * \param retainObject will cause the constructor to retain its cl object.
5236 * Defaults to false to maintain compatibility with
5237 * earlier versions.
5238 * See Memory for further details.
5239 */
Image2DGL(const cl_mem & image,bool retainObject=false)5240 explicit Image2DGL(const cl_mem& image, bool retainObject = false) :
5241 Image2D(image, retainObject) { }
5242
5243 /*! \brief Assignment from cl_mem - performs shallow copy.
5244 *c
5245 * See Memory for further details.
5246 */
operator =(const cl_mem & rhs)5247 Image2DGL& operator = (const cl_mem& rhs)
5248 {
5249 Image2D::operator=(rhs);
5250 return *this;
5251 }
5252
5253
5254
5255 } CL_API_SUFFIX__VERSION_1_1_DEPRECATED;
5256 #endif // CL_USE_DEPRECATED_OPENCL_1_1_APIS
5257
5258 #if CL_HPP_TARGET_OPENCL_VERSION >= 120
5259 /*! \class Image2DArray
5260 * \brief Image interface for arrays of 2D images.
5261 */
5262 class Image2DArray : public Image
5263 {
5264 public:
Image2DArray(const Context & context,cl_mem_flags flags,ImageFormat format,size_type arraySize,size_type width,size_type height,size_type rowPitch,size_type slicePitch,void * host_ptr=nullptr,cl_int * err=nullptr)5265 Image2DArray(
5266 const Context& context,
5267 cl_mem_flags flags,
5268 ImageFormat format,
5269 size_type arraySize,
5270 size_type width,
5271 size_type height,
5272 size_type rowPitch,
5273 size_type slicePitch,
5274 void* host_ptr = nullptr,
5275 cl_int* err = nullptr)
5276 {
5277 cl_int error;
5278
5279 cl_image_desc desc = {};
5280 desc.image_type = CL_MEM_OBJECT_IMAGE2D_ARRAY;
5281 desc.image_width = width;
5282 desc.image_height = height;
5283 desc.image_array_size = arraySize;
5284 desc.image_row_pitch = rowPitch;
5285 desc.image_slice_pitch = slicePitch;
5286
5287 object_ = ::clCreateImage(
5288 context(),
5289 flags,
5290 &format,
5291 &desc,
5292 host_ptr,
5293 &error);
5294
5295 detail::errHandler(error, __CREATE_IMAGE_ERR);
5296 if (err != nullptr) {
5297 *err = error;
5298 }
5299 }
5300
Image2DArray()5301 Image2DArray() { }
5302
5303 /*! \brief Constructor from cl_mem - takes ownership.
5304 *
5305 * \param retainObject will cause the constructor to retain its cl object.
5306 * Defaults to false to maintain compatibility with
5307 * earlier versions.
5308 * See Memory for further details.
5309 */
Image2DArray(const cl_mem & imageArray,bool retainObject=false)5310 explicit Image2DArray(const cl_mem& imageArray, bool retainObject = false) : Image(imageArray, retainObject) { }
5311
operator =(const cl_mem & rhs)5312 Image2DArray& operator = (const cl_mem& rhs)
5313 {
5314 Image::operator=(rhs);
5315 return *this;
5316 }
5317
5318 };
5319 #endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 120
5320
5321 /*! \brief Class interface for 3D Image Memory objects.
5322 *
5323 * See Memory for details about copy semantics, etc.
5324 *
5325 * \see Memory
5326 */
5327 class Image3D : public Image
5328 {
5329 public:
5330 /*! \brief Constructs a 3D Image in a specified context.
5331 *
5332 * Wraps clCreateImage().
5333 */
Image3D(const Context & context,cl_mem_flags flags,ImageFormat format,size_type width,size_type height,size_type depth,size_type row_pitch=0,size_type slice_pitch=0,void * host_ptr=nullptr,cl_int * err=nullptr)5334 Image3D(
5335 const Context& context,
5336 cl_mem_flags flags,
5337 ImageFormat format,
5338 size_type width,
5339 size_type height,
5340 size_type depth,
5341 size_type row_pitch = 0,
5342 size_type slice_pitch = 0,
5343 void* host_ptr = nullptr,
5344 cl_int* err = nullptr)
5345 {
5346 cl_int error;
5347 bool useCreateImage;
5348
5349 #if CL_HPP_TARGET_OPENCL_VERSION >= 120 && CL_HPP_MINIMUM_OPENCL_VERSION < 120
5350 // Run-time decision based on the actual platform
5351 {
5352 cl_uint version = detail::getContextPlatformVersion(context());
5353 useCreateImage = (version >= 0x10002); // OpenCL 1.2 or above
5354 }
5355 #elif CL_HPP_TARGET_OPENCL_VERSION >= 120
5356 useCreateImage = true;
5357 #else
5358 useCreateImage = false;
5359 #endif
5360
5361 #if CL_HPP_TARGET_OPENCL_VERSION >= 120
5362 if (useCreateImage)
5363 {
5364 cl_image_desc desc = {};
5365 desc.image_type = CL_MEM_OBJECT_IMAGE3D;
5366 desc.image_width = width;
5367 desc.image_height = height;
5368 desc.image_depth = depth;
5369 desc.image_row_pitch = row_pitch;
5370 desc.image_slice_pitch = slice_pitch;
5371
5372 object_ = ::clCreateImage(
5373 context(),
5374 flags,
5375 &format,
5376 &desc,
5377 host_ptr,
5378 &error);
5379
5380 detail::errHandler(error, __CREATE_IMAGE_ERR);
5381 if (err != nullptr) {
5382 *err = error;
5383 }
5384 }
5385 #endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
5386 #if CL_HPP_MINIMUM_OPENCL_VERSION < 120
5387 if (!useCreateImage)
5388 {
5389 object_ = ::clCreateImage3D(
5390 context(), flags, &format, width, height, depth, row_pitch,
5391 slice_pitch, host_ptr, &error);
5392
5393 detail::errHandler(error, __CREATE_IMAGE3D_ERR);
5394 if (err != nullptr) {
5395 *err = error;
5396 }
5397 }
5398 #endif // CL_HPP_MINIMUM_OPENCL_VERSION < 120
5399 }
5400
5401 //! \brief Default constructor - initializes to nullptr.
Image3D()5402 Image3D() : Image() { }
5403
5404 /*! \brief Constructor from cl_mem - takes ownership.
5405 *
5406 * \param retainObject will cause the constructor to retain its cl object.
5407 * Defaults to false to maintain compatibility with
5408 * earlier versions.
5409 * See Memory for further details.
5410 */
Image3D(const cl_mem & image3D,bool retainObject=false)5411 explicit Image3D(const cl_mem& image3D, bool retainObject = false) :
5412 Image(image3D, retainObject) { }
5413
5414 /*! \brief Assignment from cl_mem - performs shallow copy.
5415 *
5416 * See Memory for further details.
5417 */
operator =(const cl_mem & rhs)5418 Image3D& operator = (const cl_mem& rhs)
5419 {
5420 Image::operator=(rhs);
5421 return *this;
5422 }
5423
5424 };
5425
5426 #if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
5427 /*! \brief Class interface for GL 3D Image Memory objects.
5428 *
5429 * This is provided to facilitate interoperability with OpenGL.
5430 *
5431 * See Memory for details about copy semantics, etc.
5432 *
5433 * \see Memory
5434 */
5435 class Image3DGL : public Image3D
5436 {
5437 public:
5438 /*! \brief Constructs an Image3DGL in a specified context, from a given
5439 * GL Texture.
5440 *
5441 * Wraps clCreateFromGLTexture3D().
5442 */
Image3DGL(const Context & context,cl_mem_flags flags,cl_GLenum target,cl_GLint miplevel,cl_GLuint texobj,cl_int * err=nullptr)5443 Image3DGL(
5444 const Context& context,
5445 cl_mem_flags flags,
5446 cl_GLenum target,
5447 cl_GLint miplevel,
5448 cl_GLuint texobj,
5449 cl_int * err = nullptr)
5450 {
5451 cl_int error;
5452 object_ = ::clCreateFromGLTexture3D(
5453 context(),
5454 flags,
5455 target,
5456 miplevel,
5457 texobj,
5458 &error);
5459
5460 detail::errHandler(error, __CREATE_GL_TEXTURE_3D_ERR);
5461 if (err != nullptr) {
5462 *err = error;
5463 }
5464 }
5465
5466 //! \brief Default constructor - initializes to nullptr.
Image3DGL()5467 Image3DGL() : Image3D() { }
5468
5469 /*! \brief Constructor from cl_mem - takes ownership.
5470 *
5471 * \param retainObject will cause the constructor to retain its cl object.
5472 * Defaults to false to maintain compatibility with
5473 * earlier versions.
5474 * See Memory for further details.
5475 */
Image3DGL(const cl_mem & image,bool retainObject=false)5476 explicit Image3DGL(const cl_mem& image, bool retainObject = false) :
5477 Image3D(image, retainObject) { }
5478
5479 /*! \brief Assignment from cl_mem - performs shallow copy.
5480 *
5481 * See Memory for further details.
5482 */
operator =(const cl_mem & rhs)5483 Image3DGL& operator = (const cl_mem& rhs)
5484 {
5485 Image3D::operator=(rhs);
5486 return *this;
5487 }
5488
5489 };
5490 #endif // CL_USE_DEPRECATED_OPENCL_1_1_APIS
5491
5492 #if CL_HPP_TARGET_OPENCL_VERSION >= 120
5493 /*! \class ImageGL
5494 * \brief general image interface for GL interop.
5495 * We abstract the 2D and 3D GL images into a single instance here
5496 * that wraps all GL sourced images on the grounds that setup information
5497 * was performed by OpenCL anyway.
5498 */
5499 class ImageGL : public Image
5500 {
5501 public:
ImageGL(const Context & context,cl_mem_flags flags,cl_GLenum target,cl_GLint miplevel,cl_GLuint texobj,cl_int * err=nullptr)5502 ImageGL(
5503 const Context& context,
5504 cl_mem_flags flags,
5505 cl_GLenum target,
5506 cl_GLint miplevel,
5507 cl_GLuint texobj,
5508 cl_int * err = nullptr)
5509 {
5510 cl_int error;
5511 object_ = ::clCreateFromGLTexture(
5512 context(),
5513 flags,
5514 target,
5515 miplevel,
5516 texobj,
5517 &error);
5518
5519 detail::errHandler(error, __CREATE_GL_TEXTURE_ERR);
5520 if (err != nullptr) {
5521 *err = error;
5522 }
5523 }
5524
ImageGL()5525 ImageGL() : Image() { }
5526
5527 /*! \brief Constructor from cl_mem - takes ownership.
5528 *
5529 * \param retainObject will cause the constructor to retain its cl object.
5530 * Defaults to false to maintain compatibility with
5531 * earlier versions.
5532 * See Memory for further details.
5533 */
ImageGL(const cl_mem & image,bool retainObject=false)5534 explicit ImageGL(const cl_mem& image, bool retainObject = false) :
5535 Image(image, retainObject) { }
5536
operator =(const cl_mem & rhs)5537 ImageGL& operator = (const cl_mem& rhs)
5538 {
5539 Image::operator=(rhs);
5540 return *this;
5541 }
5542
5543 };
5544 #endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
5545
5546
5547
5548 #if CL_HPP_TARGET_OPENCL_VERSION >= 200
5549 /*! \brief Class interface for Pipe Memory Objects.
5550 *
5551 * See Memory for details about copy semantics, etc.
5552 *
5553 * \see Memory
5554 */
5555 class Pipe : public Memory
5556 {
5557 public:
5558
5559 /*! \brief Constructs a Pipe in a specified context.
5560 *
5561 * Wraps clCreatePipe().
5562 * @param context Context in which to create the pipe.
5563 * @param flags Bitfield. Only CL_MEM_READ_WRITE and CL_MEM_HOST_NO_ACCESS are valid.
5564 * @param packet_size Size in bytes of a single packet of the pipe.
5565 * @param max_packets Number of packets that may be stored in the pipe.
5566 *
5567 */
Pipe(const Context & context,cl_uint packet_size,cl_uint max_packets,cl_int * err=nullptr)5568 Pipe(
5569 const Context& context,
5570 cl_uint packet_size,
5571 cl_uint max_packets,
5572 cl_int* err = nullptr)
5573 {
5574 cl_int error;
5575
5576 cl_mem_flags flags = CL_MEM_READ_WRITE | CL_MEM_HOST_NO_ACCESS;
5577 object_ = ::clCreatePipe(context(), flags, packet_size, max_packets, nullptr, &error);
5578
5579 detail::errHandler(error, __CREATE_PIPE_ERR);
5580 if (err != nullptr) {
5581 *err = error;
5582 }
5583 }
5584
5585 /*! \brief Constructs a Pipe in a the default context.
5586 *
5587 * Wraps clCreatePipe().
5588 * @param flags Bitfield. Only CL_MEM_READ_WRITE and CL_MEM_HOST_NO_ACCESS are valid.
5589 * @param packet_size Size in bytes of a single packet of the pipe.
5590 * @param max_packets Number of packets that may be stored in the pipe.
5591 *
5592 */
Pipe(cl_uint packet_size,cl_uint max_packets,cl_int * err=nullptr)5593 Pipe(
5594 cl_uint packet_size,
5595 cl_uint max_packets,
5596 cl_int* err = nullptr)
5597 {
5598 cl_int error;
5599
5600 Context context = Context::getDefault(err);
5601
5602 cl_mem_flags flags = CL_MEM_READ_WRITE | CL_MEM_HOST_NO_ACCESS;
5603 object_ = ::clCreatePipe(context(), flags, packet_size, max_packets, nullptr, &error);
5604
5605 detail::errHandler(error, __CREATE_PIPE_ERR);
5606 if (err != nullptr) {
5607 *err = error;
5608 }
5609 }
5610
5611 //! \brief Default constructor - initializes to nullptr.
Pipe()5612 Pipe() : Memory() { }
5613
5614 /*! \brief Constructor from cl_mem - takes ownership.
5615 *
5616 * \param retainObject will cause the constructor to retain its cl object.
5617 * Defaults to false to maintain compatibility with earlier versions.
5618 *
5619 * See Memory for further details.
5620 */
Pipe(const cl_mem & pipe,bool retainObject=false)5621 explicit Pipe(const cl_mem& pipe, bool retainObject = false) :
5622 Memory(pipe, retainObject) { }
5623
5624 /*! \brief Assignment from cl_mem - performs shallow copy.
5625 *
5626 * See Memory for further details.
5627 */
operator =(const cl_mem & rhs)5628 Pipe& operator = (const cl_mem& rhs)
5629 {
5630 Memory::operator=(rhs);
5631 return *this;
5632 }
5633
5634
5635
5636 //! \brief Wrapper for clGetMemObjectInfo().
5637 template <typename T>
getInfo(cl_pipe_info name,T * param) const5638 cl_int getInfo(cl_pipe_info name, T* param) const
5639 {
5640 return detail::errHandler(
5641 detail::getInfo(&::clGetPipeInfo, object_, name, param),
5642 __GET_PIPE_INFO_ERR);
5643 }
5644
5645 //! \brief Wrapper for clGetMemObjectInfo() that returns by value.
5646 template <cl_pipe_info name> typename
5647 detail::param_traits<detail::cl_pipe_info, name>::param_type
getInfo(cl_int * err=nullptr) const5648 getInfo(cl_int* err = nullptr) const
5649 {
5650 typename detail::param_traits<
5651 detail::cl_pipe_info, name>::param_type param;
5652 cl_int result = getInfo(name, ¶m);
5653 if (err != nullptr) {
5654 *err = result;
5655 }
5656 return param;
5657 }
5658 }; // class Pipe
5659 #endif // CL_HPP_TARGET_OPENCL_VERSION >= 200
5660
5661
5662 /*! \brief Class interface for cl_sampler.
5663 *
5664 * \note Copies of these objects are shallow, meaning that the copy will refer
5665 * to the same underlying cl_sampler as the original. For details, see
5666 * clRetainSampler() and clReleaseSampler().
5667 *
5668 * \see cl_sampler
5669 */
5670 class Sampler : public detail::Wrapper<cl_sampler>
5671 {
5672 public:
5673 //! \brief Default constructor - initializes to nullptr.
Sampler()5674 Sampler() { }
5675
5676 /*! \brief Constructs a Sampler in a specified context.
5677 *
5678 * Wraps clCreateSampler().
5679 */
Sampler(const Context & context,cl_bool normalized_coords,cl_addressing_mode addressing_mode,cl_filter_mode filter_mode,cl_int * err=nullptr)5680 Sampler(
5681 const Context& context,
5682 cl_bool normalized_coords,
5683 cl_addressing_mode addressing_mode,
5684 cl_filter_mode filter_mode,
5685 cl_int* err = nullptr)
5686 {
5687 cl_int error;
5688
5689 #if CL_HPP_TARGET_OPENCL_VERSION >= 200
5690 cl_sampler_properties sampler_properties[] = {
5691 CL_SAMPLER_NORMALIZED_COORDS, normalized_coords,
5692 CL_SAMPLER_ADDRESSING_MODE, addressing_mode,
5693 CL_SAMPLER_FILTER_MODE, filter_mode,
5694 0 };
5695 object_ = ::clCreateSamplerWithProperties(
5696 context(),
5697 sampler_properties,
5698 &error);
5699
5700 detail::errHandler(error, __CREATE_SAMPLER_WITH_PROPERTIES_ERR);
5701 if (err != nullptr) {
5702 *err = error;
5703 }
5704 #else
5705 object_ = ::clCreateSampler(
5706 context(),
5707 normalized_coords,
5708 addressing_mode,
5709 filter_mode,
5710 &error);
5711
5712 detail::errHandler(error, __CREATE_SAMPLER_ERR);
5713 if (err != nullptr) {
5714 *err = error;
5715 }
5716 #endif
5717 }
5718
5719 /*! \brief Constructor from cl_sampler - takes ownership.
5720 *
5721 * \param retainObject will cause the constructor to retain its cl object.
5722 * Defaults to false to maintain compatibility with
5723 * earlier versions.
5724 * This effectively transfers ownership of a refcount on the cl_sampler
5725 * into the new Sampler object.
5726 */
Sampler(const cl_sampler & sampler,bool retainObject=false)5727 explicit Sampler(const cl_sampler& sampler, bool retainObject = false) :
5728 detail::Wrapper<cl_type>(sampler, retainObject) { }
5729
5730 /*! \brief Assignment operator from cl_sampler - takes ownership.
5731 *
5732 * This effectively transfers ownership of a refcount on the rhs and calls
5733 * clReleaseSampler() on the value previously held by this instance.
5734 */
operator =(const cl_sampler & rhs)5735 Sampler& operator = (const cl_sampler& rhs)
5736 {
5737 detail::Wrapper<cl_type>::operator=(rhs);
5738 return *this;
5739 }
5740
5741
5742
5743 //! \brief Wrapper for clGetSamplerInfo().
5744 template <typename T>
getInfo(cl_sampler_info name,T * param) const5745 cl_int getInfo(cl_sampler_info name, T* param) const
5746 {
5747 return detail::errHandler(
5748 detail::getInfo(&::clGetSamplerInfo, object_, name, param),
5749 __GET_SAMPLER_INFO_ERR);
5750 }
5751
5752 //! \brief Wrapper for clGetSamplerInfo() that returns by value.
5753 template <cl_sampler_info name> typename
5754 detail::param_traits<detail::cl_sampler_info, name>::param_type
getInfo(cl_int * err=nullptr) const5755 getInfo(cl_int* err = nullptr) const
5756 {
5757 typename detail::param_traits<
5758 detail::cl_sampler_info, name>::param_type param;
5759 cl_int result = getInfo(name, ¶m);
5760 if (err != nullptr) {
5761 *err = result;
5762 }
5763 return param;
5764 }
5765 };
5766
5767 class Program;
5768 class CommandQueue;
5769 class DeviceCommandQueue;
5770 class Kernel;
5771
5772 //! \brief Class interface for specifying NDRange values.
5773 class NDRange
5774 {
5775 private:
5776 size_type sizes_[3];
5777 cl_uint dimensions_;
5778
5779 public:
5780 //! \brief Default constructor - resulting range has zero dimensions.
NDRange()5781 NDRange()
5782 : dimensions_(0)
5783 {
5784 sizes_[0] = 0;
5785 sizes_[1] = 0;
5786 sizes_[2] = 0;
5787 }
5788
5789 //! \brief Constructs one-dimensional range.
NDRange(size_type size0)5790 NDRange(size_type size0)
5791 : dimensions_(1)
5792 {
5793 sizes_[0] = size0;
5794 sizes_[1] = 1;
5795 sizes_[2] = 1;
5796 }
5797
5798 //! \brief Constructs two-dimensional range.
NDRange(size_type size0,size_type size1)5799 NDRange(size_type size0, size_type size1)
5800 : dimensions_(2)
5801 {
5802 sizes_[0] = size0;
5803 sizes_[1] = size1;
5804 sizes_[2] = 1;
5805 }
5806
5807 //! \brief Constructs three-dimensional range.
NDRange(size_type size0,size_type size1,size_type size2)5808 NDRange(size_type size0, size_type size1, size_type size2)
5809 : dimensions_(3)
5810 {
5811 sizes_[0] = size0;
5812 sizes_[1] = size1;
5813 sizes_[2] = size2;
5814 }
5815
5816 //! \brief Constructs one-dimensional range.
NDRange(array<size_type,1> a)5817 NDRange(array<size_type, 1> a) : NDRange(a[0]){}
5818
5819 //! \brief Constructs two-dimensional range.
NDRange(array<size_type,2> a)5820 NDRange(array<size_type, 2> a) : NDRange(a[0], a[1]){}
5821
5822 //! \brief Constructs three-dimensional range.
NDRange(array<size_type,3> a)5823 NDRange(array<size_type, 3> a) : NDRange(a[0], a[1], a[2]){}
5824
5825 /*! \brief Conversion operator to const size_type *.
5826 *
5827 * \returns a pointer to the size of the first dimension.
5828 */
operator const size_type*() const5829 operator const size_type*() const {
5830 return sizes_;
5831 }
5832
5833 //! \brief Queries the number of dimensions in the range.
dimensions() const5834 size_type dimensions() const
5835 {
5836 return dimensions_;
5837 }
5838
5839 //! \brief Returns the size of the object in bytes based on the
5840 // runtime number of dimensions
size() const5841 size_type size() const
5842 {
5843 return dimensions_*sizeof(size_type);
5844 }
5845
get()5846 size_type* get()
5847 {
5848 return sizes_;
5849 }
5850
get() const5851 const size_type* get() const
5852 {
5853 return sizes_;
5854 }
5855 };
5856
5857 //! \brief A zero-dimensional range.
5858 static const NDRange NullRange;
5859
5860 //! \brief Local address wrapper for use with Kernel::setArg
5861 struct LocalSpaceArg
5862 {
5863 size_type size_;
5864 };
5865
5866 namespace detail {
5867
5868 template <typename T, class Enable = void>
5869 struct KernelArgumentHandler;
5870
5871 // Enable for objects that are not subclasses of memory
5872 // Pointers, constants etc
5873 template <typename T>
5874 struct KernelArgumentHandler<T, typename std::enable_if<!std::is_base_of<cl::Memory, T>::value>::type>
5875 {
sizecl::detail::KernelArgumentHandler5876 static size_type size(const T&) { return sizeof(T); }
ptrcl::detail::KernelArgumentHandler5877 static const T* ptr(const T& value) { return &value; }
5878 };
5879
5880 // Enable for subclasses of memory where we want to get a reference to the cl_mem out
5881 // and pass that in for safety
5882 template <typename T>
5883 struct KernelArgumentHandler<T, typename std::enable_if<std::is_base_of<cl::Memory, T>::value>::type>
5884 {
sizecl::detail::KernelArgumentHandler5885 static size_type size(const T&) { return sizeof(cl_mem); }
ptrcl::detail::KernelArgumentHandler5886 static const cl_mem* ptr(const T& value) { return &(value()); }
5887 };
5888
5889 // Specialization for DeviceCommandQueue defined later
5890
5891 template <>
5892 struct KernelArgumentHandler<LocalSpaceArg, void>
5893 {
sizecl::detail::KernelArgumentHandler5894 static size_type size(const LocalSpaceArg& value) { return value.size_; }
ptrcl::detail::KernelArgumentHandler5895 static const void* ptr(const LocalSpaceArg&) { return nullptr; }
5896 };
5897
5898 }
5899 //! \endcond
5900
5901 /*! Local
5902 * \brief Helper function for generating LocalSpaceArg objects.
5903 */
5904 inline LocalSpaceArg
Local(size_type size)5905 Local(size_type size)
5906 {
5907 LocalSpaceArg ret = { size };
5908 return ret;
5909 }
5910
5911 /*! \brief Class interface for cl_kernel.
5912 *
5913 * \note Copies of these objects are shallow, meaning that the copy will refer
5914 * to the same underlying cl_kernel as the original. For details, see
5915 * clRetainKernel() and clReleaseKernel().
5916 *
5917 * \see cl_kernel
5918 */
5919 class Kernel : public detail::Wrapper<cl_kernel>
5920 {
5921 public:
5922 inline Kernel(const Program& program, const char* name, cl_int* err = nullptr);
5923
5924 //! \brief Default constructor - initializes to nullptr.
Kernel()5925 Kernel() { }
5926
5927 /*! \brief Constructor from cl_kernel - takes ownership.
5928 *
5929 * \param retainObject will cause the constructor to retain its cl object.
5930 * Defaults to false to maintain compatibility with
5931 * earlier versions.
5932 * This effectively transfers ownership of a refcount on the cl_kernel
5933 * into the new Kernel object.
5934 */
Kernel(const cl_kernel & kernel,bool retainObject=false)5935 explicit Kernel(const cl_kernel& kernel, bool retainObject = false) :
5936 detail::Wrapper<cl_type>(kernel, retainObject) { }
5937
5938 /*! \brief Assignment operator from cl_kernel - takes ownership.
5939 *
5940 * This effectively transfers ownership of a refcount on the rhs and calls
5941 * clReleaseKernel() on the value previously held by this instance.
5942 */
operator =(const cl_kernel & rhs)5943 Kernel& operator = (const cl_kernel& rhs)
5944 {
5945 detail::Wrapper<cl_type>::operator=(rhs);
5946 return *this;
5947 }
5948
5949
5950
5951
5952 template <typename T>
getInfo(cl_kernel_info name,T * param) const5953 cl_int getInfo(cl_kernel_info name, T* param) const
5954 {
5955 return detail::errHandler(
5956 detail::getInfo(&::clGetKernelInfo, object_, name, param),
5957 __GET_KERNEL_INFO_ERR);
5958 }
5959
5960 template <cl_kernel_info name> typename
5961 detail::param_traits<detail::cl_kernel_info, name>::param_type
getInfo(cl_int * err=nullptr) const5962 getInfo(cl_int* err = nullptr) const
5963 {
5964 typename detail::param_traits<
5965 detail::cl_kernel_info, name>::param_type param;
5966 cl_int result = getInfo(name, ¶m);
5967 if (err != nullptr) {
5968 *err = result;
5969 }
5970 return param;
5971 }
5972
5973 #if CL_HPP_TARGET_OPENCL_VERSION >= 120
5974 template <typename T>
getArgInfo(cl_uint argIndex,cl_kernel_arg_info name,T * param) const5975 cl_int getArgInfo(cl_uint argIndex, cl_kernel_arg_info name, T* param) const
5976 {
5977 return detail::errHandler(
5978 detail::getInfo(&::clGetKernelArgInfo, object_, argIndex, name, param),
5979 __GET_KERNEL_ARG_INFO_ERR);
5980 }
5981
5982 template <cl_kernel_arg_info name> typename
5983 detail::param_traits<detail::cl_kernel_arg_info, name>::param_type
getArgInfo(cl_uint argIndex,cl_int * err=nullptr) const5984 getArgInfo(cl_uint argIndex, cl_int* err = nullptr) const
5985 {
5986 typename detail::param_traits<
5987 detail::cl_kernel_arg_info, name>::param_type param;
5988 cl_int result = getArgInfo(argIndex, name, ¶m);
5989 if (err != nullptr) {
5990 *err = result;
5991 }
5992 return param;
5993 }
5994 #endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
5995
5996 template <typename T>
getWorkGroupInfo(const Device & device,cl_kernel_work_group_info name,T * param) const5997 cl_int getWorkGroupInfo(
5998 const Device& device, cl_kernel_work_group_info name, T* param) const
5999 {
6000 return detail::errHandler(
6001 detail::getInfo(
6002 &::clGetKernelWorkGroupInfo, object_, device(), name, param),
6003 __GET_KERNEL_WORK_GROUP_INFO_ERR);
6004 }
6005
6006 template <cl_kernel_work_group_info name> typename
6007 detail::param_traits<detail::cl_kernel_work_group_info, name>::param_type
getWorkGroupInfo(const Device & device,cl_int * err=nullptr) const6008 getWorkGroupInfo(const Device& device, cl_int* err = nullptr) const
6009 {
6010 typename detail::param_traits<
6011 detail::cl_kernel_work_group_info, name>::param_type param;
6012 cl_int result = getWorkGroupInfo(device, name, ¶m);
6013 if (err != nullptr) {
6014 *err = result;
6015 }
6016 return param;
6017 }
6018
6019 #if defined(CL_HPP_USE_CL_SUB_GROUPS_KHR) || CL_HPP_TARGET_OPENCL_VERSION >= 210
getSubGroupInfo(const cl::Device & dev,cl_kernel_sub_group_info name,const cl::NDRange & range,size_type * param) const6020 cl_int getSubGroupInfo(const cl::Device &dev, cl_kernel_sub_group_info name, const cl::NDRange &range, size_type* param) const
6021 {
6022 #if CL_HPP_TARGET_OPENCL_VERSION >= 210
6023
6024 return detail::errHandler(
6025 clGetKernelSubGroupInfo(object_, dev(), name, range.size(), range.get(), sizeof(size_type), param, nullptr),
6026 __GET_KERNEL_SUB_GROUP_INFO_ERR);
6027
6028 #else // #if CL_HPP_TARGET_OPENCL_VERSION >= 210
6029
6030 typedef clGetKernelSubGroupInfoKHR_fn PFN_clGetKernelSubGroupInfoKHR;
6031 static PFN_clGetKernelSubGroupInfoKHR pfn_clGetKernelSubGroupInfoKHR = nullptr;
6032 CL_HPP_INIT_CL_EXT_FCN_PTR_(clGetKernelSubGroupInfoKHR);
6033
6034 return detail::errHandler(
6035 pfn_clGetKernelSubGroupInfoKHR(object_, dev(), name, range.size(), range.get(), sizeof(size_type), param, nullptr),
6036 __GET_KERNEL_SUB_GROUP_INFO_ERR);
6037
6038 #endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 210
6039 }
6040
6041 template <cl_kernel_sub_group_info name>
getSubGroupInfo(const cl::Device & dev,const cl::NDRange & range,cl_int * err=nullptr) const6042 size_type getSubGroupInfo(const cl::Device &dev, const cl::NDRange &range, cl_int* err = nullptr) const
6043 {
6044 size_type param;
6045 cl_int result = getSubGroupInfo(dev, name, range, ¶m);
6046 if (err != nullptr) {
6047 *err = result;
6048 }
6049 return param;
6050 }
6051 #endif // defined(CL_HPP_USE_CL_SUB_GROUPS_KHR) || CL_HPP_TARGET_OPENCL_VERSION >= 210
6052
6053 #if CL_HPP_TARGET_OPENCL_VERSION >= 200
6054 /*! \brief setArg overload taking a shared_ptr type
6055 */
6056 template<typename T, class D>
setArg(cl_uint index,const cl::pointer<T,D> & argPtr)6057 cl_int setArg(cl_uint index, const cl::pointer<T, D> &argPtr)
6058 {
6059 return detail::errHandler(
6060 ::clSetKernelArgSVMPointer(object_, index, argPtr.get()),
6061 __SET_KERNEL_ARGS_ERR);
6062 }
6063
6064 /*! \brief setArg overload taking a vector type.
6065 */
6066 template<typename T, class Alloc>
setArg(cl_uint index,const cl::vector<T,Alloc> & argPtr)6067 cl_int setArg(cl_uint index, const cl::vector<T, Alloc> &argPtr)
6068 {
6069 return detail::errHandler(
6070 ::clSetKernelArgSVMPointer(object_, index, argPtr.data()),
6071 __SET_KERNEL_ARGS_ERR);
6072 }
6073
6074 /*! \brief setArg overload taking a pointer type
6075 */
6076 template<typename T>
6077 typename std::enable_if<std::is_pointer<T>::value, cl_int>::type
setArg(cl_uint index,const T argPtr)6078 setArg(cl_uint index, const T argPtr)
6079 {
6080 return detail::errHandler(
6081 ::clSetKernelArgSVMPointer(object_, index, argPtr),
6082 __SET_KERNEL_ARGS_ERR);
6083 }
6084 #endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 200
6085
6086 /*! \brief setArg overload taking a POD type
6087 */
6088 template <typename T>
6089 typename std::enable_if<!std::is_pointer<T>::value, cl_int>::type
setArg(cl_uint index,const T & value)6090 setArg(cl_uint index, const T &value)
6091 {
6092 return detail::errHandler(
6093 ::clSetKernelArg(
6094 object_,
6095 index,
6096 detail::KernelArgumentHandler<T>::size(value),
6097 detail::KernelArgumentHandler<T>::ptr(value)),
6098 __SET_KERNEL_ARGS_ERR);
6099 }
6100
setArg(cl_uint index,size_type size,const void * argPtr)6101 cl_int setArg(cl_uint index, size_type size, const void* argPtr)
6102 {
6103 return detail::errHandler(
6104 ::clSetKernelArg(object_, index, size, argPtr),
6105 __SET_KERNEL_ARGS_ERR);
6106 }
6107
6108 #if CL_HPP_TARGET_OPENCL_VERSION >= 200
6109 /*!
6110 * Specify a vector of SVM pointers that the kernel may access in
6111 * addition to its arguments.
6112 */
setSVMPointers(const vector<void * > & pointerList)6113 cl_int setSVMPointers(const vector<void*> &pointerList)
6114 {
6115 return detail::errHandler(
6116 ::clSetKernelExecInfo(
6117 object_,
6118 CL_KERNEL_EXEC_INFO_SVM_PTRS,
6119 sizeof(void*)*pointerList.size(),
6120 pointerList.data()));
6121 }
6122
6123 /*!
6124 * Specify a std::array of SVM pointers that the kernel may access in
6125 * addition to its arguments.
6126 */
6127 template<int ArrayLength>
setSVMPointers(const std::array<void *,ArrayLength> & pointerList)6128 cl_int setSVMPointers(const std::array<void*, ArrayLength> &pointerList)
6129 {
6130 return detail::errHandler(
6131 ::clSetKernelExecInfo(
6132 object_,
6133 CL_KERNEL_EXEC_INFO_SVM_PTRS,
6134 sizeof(void*)*pointerList.size(),
6135 pointerList.data()));
6136 }
6137
6138 /*! \brief Enable fine-grained system SVM.
6139 *
6140 * \note It is only possible to enable fine-grained system SVM if all devices
6141 * in the context associated with kernel support it.
6142 *
6143 * \param svmEnabled True if fine-grained system SVM is requested. False otherwise.
6144 * \return CL_SUCCESS if the function was executed succesfully. CL_INVALID_OPERATION
6145 * if no devices in the context support fine-grained system SVM.
6146 *
6147 * \see clSetKernelExecInfo
6148 */
enableFineGrainedSystemSVM(bool svmEnabled)6149 cl_int enableFineGrainedSystemSVM(bool svmEnabled)
6150 {
6151 cl_bool svmEnabled_ = svmEnabled ? CL_TRUE : CL_FALSE;
6152 return detail::errHandler(
6153 ::clSetKernelExecInfo(
6154 object_,
6155 CL_KERNEL_EXEC_INFO_SVM_FINE_GRAIN_SYSTEM,
6156 sizeof(cl_bool),
6157 &svmEnabled_
6158 )
6159 );
6160 }
6161
6162 template<int index, int ArrayLength, class D, typename T0, typename T1, typename... Ts>
setSVMPointersHelper(std::array<void *,ArrayLength> & pointerList,const pointer<T0,D> & t0,const pointer<T1,D> & t1,Ts &...ts)6163 void setSVMPointersHelper(std::array<void*, ArrayLength> &pointerList, const pointer<T0, D> &t0, const pointer<T1, D> &t1, Ts & ... ts)
6164 {
6165 pointerList[index] = static_cast<void*>(t0.get());
6166 setSVMPointersHelper<index + 1, ArrayLength>(pointerList, t1, ts...);
6167 }
6168
6169 template<int index, int ArrayLength, typename T0, typename T1, typename... Ts>
6170 typename std::enable_if<std::is_pointer<T0>::value, void>::type
setSVMPointersHelper(std::array<void *,ArrayLength> & pointerList,T0 t0,T1 t1,Ts...ts)6171 setSVMPointersHelper(std::array<void*, ArrayLength> &pointerList, T0 t0, T1 t1, Ts... ts)
6172 {
6173 pointerList[index] = static_cast<void*>(t0);
6174 setSVMPointersHelper<index + 1, ArrayLength>(pointerList, t1, ts...);
6175 }
6176
6177 template<int index, int ArrayLength, typename T0, class D>
setSVMPointersHelper(std::array<void *,ArrayLength> & pointerList,const pointer<T0,D> & t0)6178 void setSVMPointersHelper(std::array<void*, ArrayLength> &pointerList, const pointer<T0, D> &t0)
6179 {
6180 pointerList[index] = static_cast<void*>(t0.get());
6181 }
6182
6183
6184 template<int index, int ArrayLength, typename T0>
6185 typename std::enable_if<std::is_pointer<T0>::value, void>::type
setSVMPointersHelper(std::array<void *,ArrayLength> & pointerList,T0 t0)6186 setSVMPointersHelper(std::array<void*, ArrayLength> &pointerList, T0 t0)
6187 {
6188 pointerList[index] = static_cast<void*>(t0);
6189 }
6190
6191 template<typename T0, typename... Ts>
setSVMPointers(const T0 & t0,Ts &...ts)6192 cl_int setSVMPointers(const T0 &t0, Ts & ... ts)
6193 {
6194 std::array<void*, 1 + sizeof...(Ts)> pointerList;
6195
6196 setSVMPointersHelper<0, 1 + sizeof...(Ts)>(pointerList, t0, ts...);
6197 return detail::errHandler(
6198 ::clSetKernelExecInfo(
6199 object_,
6200 CL_KERNEL_EXEC_INFO_SVM_PTRS,
6201 sizeof(void*)*(1 + sizeof...(Ts)),
6202 pointerList.data()));
6203 }
6204
6205 template<typename T>
setExecInfo(cl_kernel_exec_info param_name,const T & val)6206 cl_int setExecInfo(cl_kernel_exec_info param_name, const T& val)
6207 {
6208 return detail::errHandler(
6209 ::clSetKernelExecInfo(
6210 object_,
6211 param_name,
6212 sizeof(T),
6213 &val));
6214 }
6215
6216 template<cl_kernel_exec_info name>
setExecInfo(typename detail::param_traits<detail::cl_kernel_exec_info,name>::param_type & val)6217 cl_int setExecInfo(typename detail::param_traits<detail::cl_kernel_exec_info, name>::param_type& val)
6218 {
6219 return setExecInfo(name, val);
6220 }
6221 #endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 200
6222
6223 #if CL_HPP_TARGET_OPENCL_VERSION >= 210
6224 /**
6225 * Make a deep copy of the kernel object including its arguments.
6226 * @return A new kernel object with internal state entirely separate from that
6227 * of the original but with any arguments set on the original intact.
6228 */
clone()6229 Kernel clone()
6230 {
6231 cl_int error;
6232 Kernel retValue(clCloneKernel(this->get(), &error));
6233
6234 detail::errHandler(error, __CLONE_KERNEL_ERR);
6235 return retValue;
6236 }
6237 #endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 210
6238 };
6239
6240 /*! \class Program
6241 * \brief Program interface that implements cl_program.
6242 */
6243 class Program : public detail::Wrapper<cl_program>
6244 {
6245 public:
6246 #if !defined(CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY)
6247 typedef vector<vector<unsigned char>> Binaries;
6248 typedef vector<string> Sources;
6249 #else // #if !defined(CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY)
6250 typedef vector<std::pair<const void*, size_type> > Binaries;
6251 typedef vector<std::pair<const char*, size_type> > Sources;
6252 #endif // #if !defined(CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY)
6253
Program(const string & source,bool build=false,cl_int * err=nullptr)6254 Program(
6255 const string& source,
6256 bool build = false,
6257 cl_int* err = nullptr)
6258 {
6259 cl_int error;
6260
6261 const char * strings = source.c_str();
6262 const size_type length = source.size();
6263
6264 Context context = Context::getDefault(err);
6265
6266 object_ = ::clCreateProgramWithSource(
6267 context(), (cl_uint)1, &strings, &length, &error);
6268
6269 detail::errHandler(error, __CREATE_PROGRAM_WITH_SOURCE_ERR);
6270
6271 if (error == CL_SUCCESS && build) {
6272
6273 error = ::clBuildProgram(
6274 object_,
6275 0,
6276 nullptr,
6277 #if !defined(CL_HPP_CL_1_2_DEFAULT_BUILD)
6278 "-cl-std=CL2.0",
6279 #else
6280 "",
6281 #endif // #if !defined(CL_HPP_CL_1_2_DEFAULT_BUILD)
6282 nullptr,
6283 nullptr);
6284
6285 detail::buildErrHandler(error, __BUILD_PROGRAM_ERR, getBuildInfo<CL_PROGRAM_BUILD_LOG>());
6286 }
6287
6288 if (err != nullptr) {
6289 *err = error;
6290 }
6291 }
6292
Program(const Context & context,const string & source,bool build=false,cl_int * err=nullptr)6293 Program(
6294 const Context& context,
6295 const string& source,
6296 bool build = false,
6297 cl_int* err = nullptr)
6298 {
6299 cl_int error;
6300
6301 const char * strings = source.c_str();
6302 const size_type length = source.size();
6303
6304 object_ = ::clCreateProgramWithSource(
6305 context(), (cl_uint)1, &strings, &length, &error);
6306
6307 detail::errHandler(error, __CREATE_PROGRAM_WITH_SOURCE_ERR);
6308
6309 if (error == CL_SUCCESS && build) {
6310 error = ::clBuildProgram(
6311 object_,
6312 0,
6313 nullptr,
6314 #if !defined(CL_HPP_CL_1_2_DEFAULT_BUILD)
6315 "-cl-std=CL2.0",
6316 #else
6317 "",
6318 #endif // #if !defined(CL_HPP_CL_1_2_DEFAULT_BUILD)
6319 nullptr,
6320 nullptr);
6321
6322 detail::buildErrHandler(error, __BUILD_PROGRAM_ERR, getBuildInfo<CL_PROGRAM_BUILD_LOG>());
6323 }
6324
6325 if (err != nullptr) {
6326 *err = error;
6327 }
6328 }
6329
6330 /**
6331 * Create a program from a vector of source strings and the default context.
6332 * Does not compile or link the program.
6333 */
Program(const Sources & sources,cl_int * err=nullptr)6334 Program(
6335 const Sources& sources,
6336 cl_int* err = nullptr)
6337 {
6338 cl_int error;
6339 Context context = Context::getDefault(err);
6340
6341 const size_type n = (size_type)sources.size();
6342
6343 vector<size_type> lengths(n);
6344 vector<const char*> strings(n);
6345
6346 for (size_type i = 0; i < n; ++i) {
6347 #if !defined(CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY)
6348 strings[i] = sources[(int)i].data();
6349 lengths[i] = sources[(int)i].length();
6350 #else // #if !defined(CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY)
6351 strings[i] = sources[(int)i].first;
6352 lengths[i] = sources[(int)i].second;
6353 #endif // #if !defined(CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY)
6354 }
6355
6356 object_ = ::clCreateProgramWithSource(
6357 context(), (cl_uint)n, strings.data(), lengths.data(), &error);
6358
6359 detail::errHandler(error, __CREATE_PROGRAM_WITH_SOURCE_ERR);
6360 if (err != nullptr) {
6361 *err = error;
6362 }
6363 }
6364
6365 /**
6366 * Create a program from a vector of source strings and a provided context.
6367 * Does not compile or link the program.
6368 */
Program(const Context & context,const Sources & sources,cl_int * err=nullptr)6369 Program(
6370 const Context& context,
6371 const Sources& sources,
6372 cl_int* err = nullptr)
6373 {
6374 cl_int error;
6375
6376 const size_type n = (size_type)sources.size();
6377
6378 vector<size_type> lengths(n);
6379 vector<const char*> strings(n);
6380
6381 for (size_type i = 0; i < n; ++i) {
6382 #if !defined(CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY)
6383 strings[i] = sources[(int)i].data();
6384 lengths[i] = sources[(int)i].length();
6385 #else // #if !defined(CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY)
6386 strings[i] = sources[(int)i].first;
6387 lengths[i] = sources[(int)i].second;
6388 #endif // #if !defined(CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY)
6389 }
6390
6391 object_ = ::clCreateProgramWithSource(
6392 context(), (cl_uint)n, strings.data(), lengths.data(), &error);
6393
6394 detail::errHandler(error, __CREATE_PROGRAM_WITH_SOURCE_ERR);
6395 if (err != nullptr) {
6396 *err = error;
6397 }
6398 }
6399
6400
6401 #if defined(CL_HPP_USE_IL_KHR) || CL_HPP_TARGET_OPENCL_VERSION >= 210
6402 /**
6403 * Program constructor to allow construction of program from SPIR-V or another IL.
6404 *
6405 * Requires OpenCL 2.1 or newer or the cl_khr_il_program extension.
6406 */
Program(const vector<char> & IL,bool build=false,cl_int * err=nullptr)6407 Program(
6408 const vector<char>& IL,
6409 bool build = false,
6410 cl_int* err = nullptr)
6411 {
6412 cl_int error;
6413
6414 Context context = Context::getDefault(err);
6415
6416 #if CL_HPP_TARGET_OPENCL_VERSION >= 210
6417
6418 object_ = ::clCreateProgramWithIL(
6419 context(), static_cast<const void*>(IL.data()), IL.size(), &error);
6420
6421 #else // #if CL_HPP_TARGET_OPENCL_VERSION >= 210
6422
6423 typedef clCreateProgramWithILKHR_fn PFN_clCreateProgramWithILKHR;
6424 static PFN_clCreateProgramWithILKHR pfn_clCreateProgramWithILKHR = nullptr;
6425 CL_HPP_INIT_CL_EXT_FCN_PTR_(clCreateProgramWithILKHR);
6426
6427 object_ = pfn_clCreateProgramWithILKHR(
6428 context(), static_cast<const void*>(IL.data()), IL.size(), &error);
6429
6430 #endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 210
6431
6432 detail::errHandler(error, __CREATE_PROGRAM_WITH_IL_ERR);
6433
6434 if (error == CL_SUCCESS && build) {
6435
6436 error = ::clBuildProgram(
6437 object_,
6438 0,
6439 nullptr,
6440 #if !defined(CL_HPP_CL_1_2_DEFAULT_BUILD)
6441 "-cl-std=CL2.0",
6442 #else
6443 "",
6444 #endif // #if !defined(CL_HPP_CL_1_2_DEFAULT_BUILD)
6445 nullptr,
6446 nullptr);
6447
6448 detail::buildErrHandler(error, __BUILD_PROGRAM_ERR, getBuildInfo<CL_PROGRAM_BUILD_LOG>());
6449 }
6450
6451 if (err != nullptr) {
6452 *err = error;
6453 }
6454 }
6455
6456 /**
6457 * Program constructor to allow construction of program from SPIR-V or another IL
6458 * for a specific context.
6459 *
6460 * Requires OpenCL 2.1 or newer or the cl_khr_il_program extension.
6461 */
Program(const Context & context,const vector<char> & IL,bool build=false,cl_int * err=nullptr)6462 Program(
6463 const Context& context,
6464 const vector<char>& IL,
6465 bool build = false,
6466 cl_int* err = nullptr)
6467 {
6468 cl_int error;
6469
6470 #if CL_HPP_TARGET_OPENCL_VERSION >= 210
6471
6472 object_ = ::clCreateProgramWithIL(
6473 context(), static_cast<const void*>(IL.data()), IL.size(), &error);
6474
6475 #else // #if CL_HPP_TARGET_OPENCL_VERSION >= 210
6476
6477 typedef clCreateProgramWithILKHR_fn PFN_clCreateProgramWithILKHR;
6478 static PFN_clCreateProgramWithILKHR pfn_clCreateProgramWithILKHR = nullptr;
6479 CL_HPP_INIT_CL_EXT_FCN_PTR_(clCreateProgramWithILKHR);
6480
6481 object_ = pfn_clCreateProgramWithILKHR(
6482 context(), static_cast<const void*>(IL.data()), IL.size(), &error);
6483
6484 #endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 210
6485
6486 detail::errHandler(error, __CREATE_PROGRAM_WITH_IL_ERR);
6487
6488 if (error == CL_SUCCESS && build) {
6489 error = ::clBuildProgram(
6490 object_,
6491 0,
6492 nullptr,
6493 #if !defined(CL_HPP_CL_1_2_DEFAULT_BUILD)
6494 "-cl-std=CL2.0",
6495 #else
6496 "",
6497 #endif // #if !defined(CL_HPP_CL_1_2_DEFAULT_BUILD)
6498 nullptr,
6499 nullptr);
6500
6501 detail::buildErrHandler(error, __BUILD_PROGRAM_ERR, getBuildInfo<CL_PROGRAM_BUILD_LOG>());
6502 }
6503
6504 if (err != nullptr) {
6505 *err = error;
6506 }
6507 }
6508 #endif // defined(CL_HPP_USE_IL_KHR) || CL_HPP_TARGET_OPENCL_VERSION >= 210
6509
6510 /**
6511 * Construct a program object from a list of devices and a per-device list of binaries.
6512 * \param context A valid OpenCL context in which to construct the program.
6513 * \param devices A vector of OpenCL device objects for which the program will be created.
6514 * \param binaries A vector of pairs of a pointer to a binary object and its length.
6515 * \param binaryStatus An optional vector that on completion will be resized to
6516 * match the size of binaries and filled with values to specify if each binary
6517 * was successfully loaded.
6518 * Set to CL_SUCCESS if the binary was successfully loaded.
6519 * Set to CL_INVALID_VALUE if the length is 0 or the binary pointer is nullptr.
6520 * Set to CL_INVALID_BINARY if the binary provided is not valid for the matching device.
6521 * \param err if non-nullptr will be set to CL_SUCCESS on successful operation or one of the following errors:
6522 * CL_INVALID_CONTEXT if context is not a valid context.
6523 * CL_INVALID_VALUE if the length of devices is zero; or if the length of binaries does not match the length of devices;
6524 * or if any entry in binaries is nullptr or has length 0.
6525 * CL_INVALID_DEVICE if OpenCL devices listed in devices are not in the list of devices associated with context.
6526 * CL_INVALID_BINARY if an invalid program binary was encountered for any device. binaryStatus will return specific status for each device.
6527 * CL_OUT_OF_HOST_MEMORY if there is a failure to allocate resources required by the OpenCL implementation on the host.
6528 */
Program(const Context & context,const vector<Device> & devices,const Binaries & binaries,vector<cl_int> * binaryStatus=nullptr,cl_int * err=nullptr)6529 Program(
6530 const Context& context,
6531 const vector<Device>& devices,
6532 const Binaries& binaries,
6533 vector<cl_int>* binaryStatus = nullptr,
6534 cl_int* err = nullptr)
6535 {
6536 cl_int error;
6537
6538 const size_type numDevices = devices.size();
6539
6540 // Catch size mismatch early and return
6541 if(binaries.size() != numDevices) {
6542 error = CL_INVALID_VALUE;
6543 detail::errHandler(error, __CREATE_PROGRAM_WITH_BINARY_ERR);
6544 if (err != nullptr) {
6545 *err = error;
6546 }
6547 return;
6548 }
6549
6550
6551 vector<size_type> lengths(numDevices);
6552 vector<const unsigned char*> images(numDevices);
6553 #if !defined(CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY)
6554 for (size_type i = 0; i < numDevices; ++i) {
6555 images[i] = binaries[i].data();
6556 lengths[i] = binaries[(int)i].size();
6557 }
6558 #else // #if !defined(CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY)
6559 for (size_type i = 0; i < numDevices; ++i) {
6560 images[i] = (const unsigned char*)binaries[i].first;
6561 lengths[i] = binaries[(int)i].second;
6562 }
6563 #endif // #if !defined(CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY)
6564
6565 vector<cl_device_id> deviceIDs(numDevices);
6566 for( size_type deviceIndex = 0; deviceIndex < numDevices; ++deviceIndex ) {
6567 deviceIDs[deviceIndex] = (devices[deviceIndex])();
6568 }
6569
6570 if(binaryStatus) {
6571 binaryStatus->resize(numDevices);
6572 }
6573
6574 object_ = ::clCreateProgramWithBinary(
6575 context(), (cl_uint) devices.size(),
6576 deviceIDs.data(),
6577 lengths.data(), images.data(), (binaryStatus != nullptr && numDevices > 0)
6578 ? &binaryStatus->front()
6579 : nullptr, &error);
6580
6581 detail::errHandler(error, __CREATE_PROGRAM_WITH_BINARY_ERR);
6582 if (err != nullptr) {
6583 *err = error;
6584 }
6585 }
6586
6587
6588 #if CL_HPP_TARGET_OPENCL_VERSION >= 120
6589 /**
6590 * Create program using builtin kernels.
6591 * \param kernelNames Semi-colon separated list of builtin kernel names
6592 */
Program(const Context & context,const vector<Device> & devices,const string & kernelNames,cl_int * err=nullptr)6593 Program(
6594 const Context& context,
6595 const vector<Device>& devices,
6596 const string& kernelNames,
6597 cl_int* err = nullptr)
6598 {
6599 cl_int error;
6600
6601
6602 size_type numDevices = devices.size();
6603 vector<cl_device_id> deviceIDs(numDevices);
6604 for( size_type deviceIndex = 0; deviceIndex < numDevices; ++deviceIndex ) {
6605 deviceIDs[deviceIndex] = (devices[deviceIndex])();
6606 }
6607
6608 object_ = ::clCreateProgramWithBuiltInKernels(
6609 context(),
6610 (cl_uint) devices.size(),
6611 deviceIDs.data(),
6612 kernelNames.c_str(),
6613 &error);
6614
6615 detail::errHandler(error, __CREATE_PROGRAM_WITH_BUILT_IN_KERNELS_ERR);
6616 if (err != nullptr) {
6617 *err = error;
6618 }
6619 }
6620 #endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
6621
Program()6622 Program() { }
6623
6624
6625 /*! \brief Constructor from cl_program - takes ownership.
6626 *
6627 * \param retainObject will cause the constructor to retain its cl object.
6628 * Defaults to false to maintain compatibility with
6629 * earlier versions.
6630 */
Program(const cl_program & program,bool retainObject=false)6631 explicit Program(const cl_program& program, bool retainObject = false) :
6632 detail::Wrapper<cl_type>(program, retainObject) { }
6633
operator =(const cl_program & rhs)6634 Program& operator = (const cl_program& rhs)
6635 {
6636 detail::Wrapper<cl_type>::operator=(rhs);
6637 return *this;
6638 }
6639
6640
build(const vector<Device> & devices,const char * options=nullptr,void (CL_CALLBACK * notifyFptr)(cl_program,void *)=nullptr,void * data=nullptr) const6641 cl_int build(
6642 const vector<Device>& devices,
6643 const char* options = nullptr,
6644 void (CL_CALLBACK * notifyFptr)(cl_program, void *) = nullptr,
6645 void* data = nullptr) const
6646 {
6647 size_type numDevices = devices.size();
6648 vector<cl_device_id> deviceIDs(numDevices);
6649
6650 for( size_type deviceIndex = 0; deviceIndex < numDevices; ++deviceIndex ) {
6651 deviceIDs[deviceIndex] = (devices[deviceIndex])();
6652 }
6653
6654 cl_int buildError = ::clBuildProgram(
6655 object_,
6656 (cl_uint)
6657 devices.size(),
6658 deviceIDs.data(),
6659 options,
6660 notifyFptr,
6661 data);
6662
6663 return detail::buildErrHandler(buildError, __BUILD_PROGRAM_ERR, getBuildInfo<CL_PROGRAM_BUILD_LOG>());
6664 }
6665
build(const Device & device,const char * options=nullptr,void (CL_CALLBACK * notifyFptr)(cl_program,void *)=nullptr,void * data=nullptr) const6666 cl_int build(
6667 const Device& device,
6668 const char* options = nullptr,
6669 void (CL_CALLBACK * notifyFptr)(cl_program, void *) = nullptr,
6670 void* data = nullptr) const
6671 {
6672 cl_device_id deviceID = device();
6673
6674 cl_int buildError = ::clBuildProgram(
6675 object_,
6676 1,
6677 &deviceID,
6678 options,
6679 notifyFptr,
6680 data);
6681
6682 BuildLogType buildLog(0);
6683 buildLog.push_back(std::make_pair(device, getBuildInfo<CL_PROGRAM_BUILD_LOG>(device)));
6684 return detail::buildErrHandler(buildError, __BUILD_PROGRAM_ERR, buildLog);
6685 }
6686
build(const char * options=nullptr,void (CL_CALLBACK * notifyFptr)(cl_program,void *)=nullptr,void * data=nullptr) const6687 cl_int build(
6688 const char* options = nullptr,
6689 void (CL_CALLBACK * notifyFptr)(cl_program, void *) = nullptr,
6690 void* data = nullptr) const
6691 {
6692 cl_int buildError = ::clBuildProgram(
6693 object_,
6694 0,
6695 nullptr,
6696 options,
6697 notifyFptr,
6698 data);
6699
6700 return detail::buildErrHandler(buildError, __BUILD_PROGRAM_ERR, getBuildInfo<CL_PROGRAM_BUILD_LOG>());
6701 }
6702
6703 #if CL_HPP_TARGET_OPENCL_VERSION >= 120
compile(const char * options=nullptr,void (CL_CALLBACK * notifyFptr)(cl_program,void *)=nullptr,void * data=nullptr) const6704 cl_int compile(
6705 const char* options = nullptr,
6706 void (CL_CALLBACK * notifyFptr)(cl_program, void *) = nullptr,
6707 void* data = nullptr) const
6708 {
6709 cl_int error = ::clCompileProgram(
6710 object_,
6711 0,
6712 nullptr,
6713 options,
6714 0,
6715 nullptr,
6716 nullptr,
6717 notifyFptr,
6718 data);
6719 return detail::buildErrHandler(error, __COMPILE_PROGRAM_ERR, getBuildInfo<CL_PROGRAM_BUILD_LOG>());
6720 }
6721 #endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
6722
6723 template <typename T>
getInfo(cl_program_info name,T * param) const6724 cl_int getInfo(cl_program_info name, T* param) const
6725 {
6726 return detail::errHandler(
6727 detail::getInfo(&::clGetProgramInfo, object_, name, param),
6728 __GET_PROGRAM_INFO_ERR);
6729 }
6730
6731 template <cl_program_info name> typename
6732 detail::param_traits<detail::cl_program_info, name>::param_type
getInfo(cl_int * err=nullptr) const6733 getInfo(cl_int* err = nullptr) const
6734 {
6735 typename detail::param_traits<
6736 detail::cl_program_info, name>::param_type param;
6737 cl_int result = getInfo(name, ¶m);
6738 if (err != nullptr) {
6739 *err = result;
6740 }
6741 return param;
6742 }
6743
6744 template <typename T>
getBuildInfo(const Device & device,cl_program_build_info name,T * param) const6745 cl_int getBuildInfo(
6746 const Device& device, cl_program_build_info name, T* param) const
6747 {
6748 return detail::errHandler(
6749 detail::getInfo(
6750 &::clGetProgramBuildInfo, object_, device(), name, param),
6751 __GET_PROGRAM_BUILD_INFO_ERR);
6752 }
6753
6754 template <cl_program_build_info name> typename
6755 detail::param_traits<detail::cl_program_build_info, name>::param_type
getBuildInfo(const Device & device,cl_int * err=nullptr) const6756 getBuildInfo(const Device& device, cl_int* err = nullptr) const
6757 {
6758 typename detail::param_traits<
6759 detail::cl_program_build_info, name>::param_type param;
6760 cl_int result = getBuildInfo(device, name, ¶m);
6761 if (err != nullptr) {
6762 *err = result;
6763 }
6764 return param;
6765 }
6766
6767 /**
6768 * Build info function that returns a vector of device/info pairs for the specified
6769 * info type and for all devices in the program.
6770 * On an error reading the info for any device, an empty vector of info will be returned.
6771 */
6772 template <cl_program_build_info name>
6773 vector<std::pair<cl::Device, typename detail::param_traits<detail::cl_program_build_info, name>::param_type>>
getBuildInfo(cl_int * err=nullptr) const6774 getBuildInfo(cl_int *err = nullptr) const
6775 {
6776 cl_int result = CL_SUCCESS;
6777
6778 auto devs = getInfo<CL_PROGRAM_DEVICES>(&result);
6779 vector<std::pair<cl::Device, typename detail::param_traits<detail::cl_program_build_info, name>::param_type>>
6780 devInfo;
6781
6782 // If there was an initial error from getInfo return the error
6783 if (result != CL_SUCCESS) {
6784 if (err != nullptr) {
6785 *err = result;
6786 }
6787 return devInfo;
6788 }
6789
6790 for (const cl::Device &d : devs) {
6791 typename detail::param_traits<
6792 detail::cl_program_build_info, name>::param_type param;
6793 result = getBuildInfo(d, name, ¶m);
6794 devInfo.push_back(
6795 std::pair<cl::Device, typename detail::param_traits<detail::cl_program_build_info, name>::param_type>
6796 (d, param));
6797 if (result != CL_SUCCESS) {
6798 // On error, leave the loop and return the error code
6799 break;
6800 }
6801 }
6802 if (err != nullptr) {
6803 *err = result;
6804 }
6805 if (result != CL_SUCCESS) {
6806 devInfo.clear();
6807 }
6808 return devInfo;
6809 }
6810
createKernels(vector<Kernel> * kernels)6811 cl_int createKernels(vector<Kernel>* kernels)
6812 {
6813 cl_uint numKernels;
6814 cl_int err = ::clCreateKernelsInProgram(object_, 0, nullptr, &numKernels);
6815 if (err != CL_SUCCESS) {
6816 return detail::errHandler(err, __CREATE_KERNELS_IN_PROGRAM_ERR);
6817 }
6818
6819 vector<cl_kernel> value(numKernels);
6820
6821 err = ::clCreateKernelsInProgram(
6822 object_, numKernels, value.data(), nullptr);
6823 if (err != CL_SUCCESS) {
6824 return detail::errHandler(err, __CREATE_KERNELS_IN_PROGRAM_ERR);
6825 }
6826
6827 if (kernels) {
6828 kernels->resize(value.size());
6829
6830 // Assign to param, constructing with retain behaviour
6831 // to correctly capture each underlying CL object
6832 for (size_type i = 0; i < value.size(); i++) {
6833 // We do not need to retain because this kernel is being created
6834 // by the runtime
6835 (*kernels)[i] = Kernel(value[i], false);
6836 }
6837 }
6838 return CL_SUCCESS;
6839 }
6840
6841 #if CL_HPP_TARGET_OPENCL_VERSION >= 220
6842 #if defined(CL_USE_DEPRECATED_OPENCL_2_2_APIS)
6843 /*! \brief Registers a callback function to be called when destructors for
6844 * program scope global variables are complete and before the
6845 * program is released.
6846 *
6847 * Wraps clSetProgramReleaseCallback().
6848 *
6849 * Each call to this function registers the specified user callback function
6850 * on a callback stack associated with program. The registered user callback
6851 * functions are called in the reverse order in which they were registered.
6852 */
setReleaseCallback(void (CL_CALLBACK * pfn_notify)(cl_program program,void * user_data),void * user_data=nullptr)6853 CL_API_PREFIX__VERSION_2_2_DEPRECATED cl_int setReleaseCallback(
6854 void (CL_CALLBACK * pfn_notify)(cl_program program, void * user_data),
6855 void * user_data = nullptr) CL_API_SUFFIX__VERSION_2_2_DEPRECATED
6856 {
6857 return detail::errHandler(
6858 ::clSetProgramReleaseCallback(
6859 object_,
6860 pfn_notify,
6861 user_data),
6862 __SET_PROGRAM_RELEASE_CALLBACK_ERR);
6863 }
6864 #endif // #if defined(CL_USE_DEPRECATED_OPENCL_2_2_APIS)
6865
6866 /*! \brief Sets a SPIR-V specialization constant.
6867 *
6868 * Wraps clSetProgramSpecializationConstant().
6869 */
6870 template <typename T>
6871 typename std::enable_if<!std::is_pointer<T>::value, cl_int>::type
setSpecializationConstant(cl_uint index,const T & value)6872 setSpecializationConstant(cl_uint index, const T &value)
6873 {
6874 return detail::errHandler(
6875 ::clSetProgramSpecializationConstant(
6876 object_,
6877 index,
6878 sizeof(value),
6879 &value),
6880 __SET_PROGRAM_SPECIALIZATION_CONSTANT_ERR);
6881 }
6882
6883 /*! \brief Sets a SPIR-V specialization constant.
6884 *
6885 * Wraps clSetProgramSpecializationConstant().
6886 */
setSpecializationConstant(cl_uint index,size_type size,const void * value)6887 cl_int setSpecializationConstant(cl_uint index, size_type size, const void* value)
6888 {
6889 return detail::errHandler(
6890 ::clSetProgramSpecializationConstant(
6891 object_,
6892 index,
6893 size,
6894 value),
6895 __SET_PROGRAM_SPECIALIZATION_CONSTANT_ERR);
6896 }
6897 #endif // CL_HPP_TARGET_OPENCL_VERSION >= 220
6898 };
6899
6900 #if CL_HPP_TARGET_OPENCL_VERSION >= 120
linkProgram(const Program & input1,const Program & input2,const char * options=nullptr,void (CL_CALLBACK * notifyFptr)(cl_program,void *)=nullptr,void * data=nullptr,cl_int * err=nullptr)6901 inline Program linkProgram(
6902 const Program& input1,
6903 const Program& input2,
6904 const char* options = nullptr,
6905 void (CL_CALLBACK * notifyFptr)(cl_program, void *) = nullptr,
6906 void* data = nullptr,
6907 cl_int* err = nullptr)
6908 {
6909 cl_int error_local = CL_SUCCESS;
6910 cl_program programs[2] = { input1(), input2() };
6911
6912 Context ctx = input1.getInfo<CL_PROGRAM_CONTEXT>(&error_local);
6913 if(error_local!=CL_SUCCESS) {
6914 detail::errHandler(error_local, __LINK_PROGRAM_ERR);
6915 }
6916
6917 cl_program prog = ::clLinkProgram(
6918 ctx(),
6919 0,
6920 nullptr,
6921 options,
6922 2,
6923 programs,
6924 notifyFptr,
6925 data,
6926 &error_local);
6927
6928 detail::errHandler(error_local,__COMPILE_PROGRAM_ERR);
6929 if (err != nullptr) {
6930 *err = error_local;
6931 }
6932
6933 return Program(prog);
6934 }
6935
linkProgram(const vector<Program> & inputPrograms,const char * options=nullptr,void (CL_CALLBACK * notifyFptr)(cl_program,void *)=nullptr,void * data=nullptr,cl_int * err=nullptr)6936 inline Program linkProgram(
6937 const vector<Program>& inputPrograms,
6938 const char* options = nullptr,
6939 void (CL_CALLBACK * notifyFptr)(cl_program, void *) = nullptr,
6940 void* data = nullptr,
6941 cl_int* err = nullptr)
6942 {
6943 cl_int error_local = CL_SUCCESS;
6944 Context ctx;
6945
6946 static_assert(sizeof(cl::Program) == sizeof(cl_program),
6947 "Size of cl::Program must be equal to size of cl_program");
6948
6949 if(inputPrograms.size() > 0) {
6950 ctx = inputPrograms[0].getInfo<CL_PROGRAM_CONTEXT>(&error_local);
6951 if(error_local!=CL_SUCCESS) {
6952 detail::errHandler(error_local, __LINK_PROGRAM_ERR);
6953 }
6954 }
6955
6956 cl_program prog = ::clLinkProgram(
6957 ctx(),
6958 0,
6959 nullptr,
6960 options,
6961 static_cast<cl_uint>(inputPrograms.size()),
6962 reinterpret_cast<const cl_program *>(inputPrograms.data()),
6963 notifyFptr,
6964 data,
6965 &error_local);
6966
6967 detail::errHandler(error_local,__COMPILE_PROGRAM_ERR);
6968 if (err != nullptr) {
6969 *err = error_local;
6970 }
6971
6972 return Program(prog);
6973 }
6974 #endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
6975
6976 // Template specialization for CL_PROGRAM_BINARIES
6977 template <>
getInfo(cl_program_info name,vector<vector<unsigned char>> * param) const6978 inline cl_int cl::Program::getInfo(cl_program_info name, vector<vector<unsigned char>>* param) const
6979 {
6980 if (name != CL_PROGRAM_BINARIES) {
6981 return CL_INVALID_VALUE;
6982 }
6983 if (param) {
6984 // Resize the parameter array appropriately for each allocation
6985 // and pass down to the helper
6986
6987 vector<size_type> sizes = getInfo<CL_PROGRAM_BINARY_SIZES>();
6988 size_type numBinaries = sizes.size();
6989
6990 // Resize the parameter array and constituent arrays
6991 param->resize(numBinaries);
6992 for (size_type i = 0; i < numBinaries; ++i) {
6993 (*param)[i].resize(sizes[i]);
6994 }
6995
6996 return detail::errHandler(
6997 detail::getInfo(&::clGetProgramInfo, object_, name, param),
6998 __GET_PROGRAM_INFO_ERR);
6999 }
7000
7001 return CL_SUCCESS;
7002 }
7003
7004 template<>
getInfo(cl_int * err) const7005 inline vector<vector<unsigned char>> cl::Program::getInfo<CL_PROGRAM_BINARIES>(cl_int* err) const
7006 {
7007 vector<vector<unsigned char>> binariesVectors;
7008
7009 cl_int result = getInfo(CL_PROGRAM_BINARIES, &binariesVectors);
7010 if (err != nullptr) {
7011 *err = result;
7012 }
7013 return binariesVectors;
7014 }
7015
7016 #if CL_HPP_TARGET_OPENCL_VERSION >= 220
7017 // Template specialization for clSetProgramSpecializationConstant
7018 template <>
setSpecializationConstant(cl_uint index,const bool & value)7019 inline cl_int cl::Program::setSpecializationConstant(cl_uint index, const bool &value)
7020 {
7021 cl_uchar ucValue = value ? CL_UCHAR_MAX : 0;
7022 return detail::errHandler(
7023 ::clSetProgramSpecializationConstant(
7024 object_,
7025 index,
7026 sizeof(ucValue),
7027 &ucValue),
7028 __SET_PROGRAM_SPECIALIZATION_CONSTANT_ERR);
7029 }
7030 #endif // CL_HPP_TARGET_OPENCL_VERSION >= 220
7031
Kernel(const Program & program,const char * name,cl_int * err)7032 inline Kernel::Kernel(const Program& program, const char* name, cl_int* err)
7033 {
7034 cl_int error;
7035
7036 object_ = ::clCreateKernel(program(), name, &error);
7037 detail::errHandler(error, __CREATE_KERNEL_ERR);
7038
7039 if (err != nullptr) {
7040 *err = error;
7041 }
7042
7043 }
7044
7045 #ifdef cl_khr_external_memory
7046 enum class ExternalMemoryType : cl_external_memory_handle_type_khr
7047 {
7048 None = 0,
7049
7050 OpaqueFd = CL_EXTERNAL_MEMORY_HANDLE_OPAQUE_FD_KHR,
7051 OpaqueWin32 = CL_EXTERNAL_MEMORY_HANDLE_OPAQUE_WIN32_KHR,
7052 OpaqueWin32Kmt = CL_EXTERNAL_MEMORY_HANDLE_OPAQUE_WIN32_KMT_KHR,
7053
7054 D3D11Texture = CL_EXTERNAL_MEMORY_HANDLE_D3D11_TEXTURE_KHR,
7055 D3D11TextureKmt = CL_EXTERNAL_MEMORY_HANDLE_D3D11_TEXTURE_KMT_KHR,
7056
7057 D3D12Heap = CL_EXTERNAL_MEMORY_HANDLE_D3D12_HEAP_KHR,
7058 D3D12Resource = CL_EXTERNAL_MEMORY_HANDLE_D3D12_RESOURCE_KHR,
7059
7060 DmaBuf = CL_EXTERNAL_MEMORY_HANDLE_DMA_BUF_KHR,
7061 };
7062 #endif
7063
7064 enum class QueueProperties : cl_command_queue_properties
7065 {
7066 None = 0,
7067 Profiling = CL_QUEUE_PROFILING_ENABLE,
7068 OutOfOrder = CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE,
7069 };
7070
operator |(QueueProperties lhs,QueueProperties rhs)7071 inline QueueProperties operator|(QueueProperties lhs, QueueProperties rhs)
7072 {
7073 return static_cast<QueueProperties>(static_cast<cl_command_queue_properties>(lhs) | static_cast<cl_command_queue_properties>(rhs));
7074 }
7075
operator &(QueueProperties lhs,QueueProperties rhs)7076 inline QueueProperties operator&(QueueProperties lhs, QueueProperties rhs)
7077 {
7078 return static_cast<QueueProperties>(static_cast<cl_command_queue_properties>(lhs) & static_cast<cl_command_queue_properties>(rhs));
7079 }
7080
7081 /*! \class CommandQueue
7082 * \brief CommandQueue interface for cl_command_queue.
7083 */
7084 class CommandQueue : public detail::Wrapper<cl_command_queue>
7085 {
7086 private:
7087 static std::once_flag default_initialized_;
7088 static CommandQueue default_;
7089 static cl_int default_error_;
7090
7091 /*! \brief Create the default command queue returned by @ref getDefault.
7092 *
7093 * It sets default_error_ to indicate success or failure. It does not throw
7094 * @c cl::Error.
7095 */
makeDefault()7096 static void makeDefault()
7097 {
7098 /* We don't want to throw an error from this function, so we have to
7099 * catch and set the error flag.
7100 */
7101 #if defined(CL_HPP_ENABLE_EXCEPTIONS)
7102 try
7103 #endif
7104 {
7105 int error;
7106 Context context = Context::getDefault(&error);
7107
7108 if (error != CL_SUCCESS) {
7109 default_error_ = error;
7110 }
7111 else {
7112 Device device = Device::getDefault();
7113 default_ = CommandQueue(context, device, 0, &default_error_);
7114 }
7115 }
7116 #if defined(CL_HPP_ENABLE_EXCEPTIONS)
7117 catch (cl::Error &e) {
7118 default_error_ = e.err();
7119 }
7120 #endif
7121 }
7122
7123 /*! \brief Create the default command queue.
7124 *
7125 * This sets @c default_. It does not throw
7126 * @c cl::Error.
7127 */
makeDefaultProvided(const CommandQueue & c)7128 static void makeDefaultProvided(const CommandQueue &c) {
7129 default_ = c;
7130 }
7131
7132 #ifdef cl_khr_external_memory
7133 static std::once_flag ext_memory_initialized_;
7134
initMemoryExtension(const cl::Device & device)7135 static void initMemoryExtension(const cl::Device& device)
7136 {
7137 auto platform = device.getInfo<CL_DEVICE_PLATFORM>()();
7138
7139 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clEnqueueAcquireExternalMemObjectsKHR);
7140 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clEnqueueReleaseExternalMemObjectsKHR);
7141
7142 if ((pfn_clEnqueueAcquireExternalMemObjectsKHR == nullptr)
7143 && (pfn_clEnqueueReleaseExternalMemObjectsKHR == nullptr))
7144 {
7145 detail::errHandler(CL_INVALID_VALUE, __ENQUEUE_ACQUIRE_EXTERNAL_MEMORY_ERR);
7146 }
7147 }
7148 #endif // cl_khr_external_memory
7149
7150 public:
7151 #ifdef CL_HPP_UNIT_TEST_ENABLE
7152 /*! \brief Reset the default.
7153 *
7154 * This sets @c default_ to an empty value to support cleanup in
7155 * the unit test framework.
7156 * This function is not thread safe.
7157 */
unitTestClearDefault()7158 static void unitTestClearDefault() {
7159 default_ = CommandQueue();
7160 }
7161 #endif // #ifdef CL_HPP_UNIT_TEST_ENABLE
7162
7163
7164 /*!
7165 * \brief Constructs a CommandQueue based on passed properties.
7166 * Will return an CL_INVALID_QUEUE_PROPERTIES error if CL_QUEUE_ON_DEVICE is specified.
7167 */
CommandQueue(cl_command_queue_properties properties,cl_int * err=nullptr)7168 CommandQueue(
7169 cl_command_queue_properties properties,
7170 cl_int* err = nullptr)
7171 {
7172 cl_int error;
7173
7174 Context context = Context::getDefault(&error);
7175 detail::errHandler(error, __CREATE_CONTEXT_ERR);
7176
7177 if (error != CL_SUCCESS) {
7178 if (err != nullptr) {
7179 *err = error;
7180 }
7181 }
7182 else {
7183 Device device = context.getInfo<CL_CONTEXT_DEVICES>()[0];
7184 bool useWithProperties;
7185
7186 #if CL_HPP_TARGET_OPENCL_VERSION >= 200 && CL_HPP_MINIMUM_OPENCL_VERSION < 200
7187 // Run-time decision based on the actual platform
7188 {
7189 cl_uint version = detail::getContextPlatformVersion(context());
7190 useWithProperties = (version >= 0x20000); // OpenCL 2.0 or above
7191 }
7192 #elif CL_HPP_TARGET_OPENCL_VERSION >= 200
7193 useWithProperties = true;
7194 #else
7195 useWithProperties = false;
7196 #endif
7197
7198 #if CL_HPP_TARGET_OPENCL_VERSION >= 200
7199 if (useWithProperties) {
7200 cl_queue_properties queue_properties[] = {
7201 CL_QUEUE_PROPERTIES, properties, 0 };
7202 if ((properties & CL_QUEUE_ON_DEVICE) == 0) {
7203 object_ = ::clCreateCommandQueueWithProperties(
7204 context(), device(), queue_properties, &error);
7205 }
7206 else {
7207 error = CL_INVALID_QUEUE_PROPERTIES;
7208 }
7209
7210 detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR);
7211 if (err != nullptr) {
7212 *err = error;
7213 }
7214 }
7215 #endif // CL_HPP_TARGET_OPENCL_VERSION >= 200
7216 #if CL_HPP_MINIMUM_OPENCL_VERSION < 200
7217 if (!useWithProperties) {
7218 object_ = ::clCreateCommandQueue(
7219 context(), device(), properties, &error);
7220
7221 detail::errHandler(error, __CREATE_COMMAND_QUEUE_ERR);
7222 if (err != nullptr) {
7223 *err = error;
7224 }
7225 }
7226 #endif // CL_HPP_MINIMUM_OPENCL_VERSION < 200
7227 }
7228 }
7229
7230 /*!
7231 * \brief Constructs a CommandQueue based on passed properties.
7232 * Will return an CL_INVALID_QUEUE_PROPERTIES error if CL_QUEUE_ON_DEVICE is specified.
7233 */
CommandQueue(QueueProperties properties,cl_int * err=nullptr)7234 CommandQueue(
7235 QueueProperties properties,
7236 cl_int* err = nullptr)
7237 {
7238 cl_int error;
7239
7240 Context context = Context::getDefault(&error);
7241 detail::errHandler(error, __CREATE_CONTEXT_ERR);
7242
7243 if (error != CL_SUCCESS) {
7244 if (err != nullptr) {
7245 *err = error;
7246 }
7247 }
7248 else {
7249 Device device = context.getInfo<CL_CONTEXT_DEVICES>()[0];
7250 bool useWithProperties;
7251
7252 #if CL_HPP_TARGET_OPENCL_VERSION >= 200 && CL_HPP_MINIMUM_OPENCL_VERSION < 200
7253 // Run-time decision based on the actual platform
7254 {
7255 cl_uint version = detail::getContextPlatformVersion(context());
7256 useWithProperties = (version >= 0x20000); // OpenCL 2.0 or above
7257 }
7258 #elif CL_HPP_TARGET_OPENCL_VERSION >= 200
7259 useWithProperties = true;
7260 #else
7261 useWithProperties = false;
7262 #endif
7263
7264 #if CL_HPP_TARGET_OPENCL_VERSION >= 200
7265 if (useWithProperties) {
7266 cl_queue_properties queue_properties[] = {
7267 CL_QUEUE_PROPERTIES, static_cast<cl_queue_properties>(properties), 0 };
7268
7269 object_ = ::clCreateCommandQueueWithProperties(
7270 context(), device(), queue_properties, &error);
7271
7272 detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR);
7273 if (err != nullptr) {
7274 *err = error;
7275 }
7276 }
7277 #endif // CL_HPP_TARGET_OPENCL_VERSION >= 200
7278 #if CL_HPP_MINIMUM_OPENCL_VERSION < 200
7279 if (!useWithProperties) {
7280 object_ = ::clCreateCommandQueue(
7281 context(), device(), static_cast<cl_command_queue_properties>(properties), &error);
7282
7283 detail::errHandler(error, __CREATE_COMMAND_QUEUE_ERR);
7284 if (err != nullptr) {
7285 *err = error;
7286 }
7287 }
7288 #endif // CL_HPP_MINIMUM_OPENCL_VERSION < 200
7289
7290 }
7291 }
7292
7293 /*!
7294 * \brief Constructs a CommandQueue for an implementation defined device in the given context
7295 * Will return an CL_INVALID_QUEUE_PROPERTIES error if CL_QUEUE_ON_DEVICE is specified.
7296 */
CommandQueue(const Context & context,cl_command_queue_properties properties=0,cl_int * err=nullptr)7297 explicit CommandQueue(
7298 const Context& context,
7299 cl_command_queue_properties properties = 0,
7300 cl_int* err = nullptr)
7301 {
7302 cl_int error;
7303 bool useWithProperties;
7304 vector<cl::Device> devices;
7305 error = context.getInfo(CL_CONTEXT_DEVICES, &devices);
7306
7307 detail::errHandler(error, __CREATE_CONTEXT_ERR);
7308
7309 if (error != CL_SUCCESS)
7310 {
7311 if (err != nullptr) {
7312 *err = error;
7313 }
7314 return;
7315 }
7316
7317 #if CL_HPP_TARGET_OPENCL_VERSION >= 200 && CL_HPP_MINIMUM_OPENCL_VERSION < 200
7318 // Run-time decision based on the actual platform
7319 {
7320 cl_uint version = detail::getContextPlatformVersion(context());
7321 useWithProperties = (version >= 0x20000); // OpenCL 2.0 or above
7322 }
7323 #elif CL_HPP_TARGET_OPENCL_VERSION >= 200
7324 useWithProperties = true;
7325 #else
7326 useWithProperties = false;
7327 #endif
7328
7329 #if CL_HPP_TARGET_OPENCL_VERSION >= 200
7330 if (useWithProperties) {
7331 cl_queue_properties queue_properties[] = {
7332 CL_QUEUE_PROPERTIES, properties, 0 };
7333 if ((properties & CL_QUEUE_ON_DEVICE) == 0) {
7334 object_ = ::clCreateCommandQueueWithProperties(
7335 context(), devices[0](), queue_properties, &error);
7336 }
7337 else {
7338 error = CL_INVALID_QUEUE_PROPERTIES;
7339 }
7340
7341 detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR);
7342 if (err != nullptr) {
7343 *err = error;
7344 }
7345 }
7346 #endif // CL_HPP_TARGET_OPENCL_VERSION >= 200
7347 #if CL_HPP_MINIMUM_OPENCL_VERSION < 200
7348 if (!useWithProperties) {
7349 object_ = ::clCreateCommandQueue(
7350 context(), devices[0](), properties, &error);
7351
7352 detail::errHandler(error, __CREATE_COMMAND_QUEUE_ERR);
7353 if (err != nullptr) {
7354 *err = error;
7355 }
7356 }
7357 #endif // CL_HPP_MINIMUM_OPENCL_VERSION < 200
7358 }
7359
7360 /*!
7361 * \brief Constructs a CommandQueue for an implementation defined device in the given context
7362 * Will return an CL_INVALID_QUEUE_PROPERTIES error if CL_QUEUE_ON_DEVICE is specified.
7363 */
CommandQueue(const Context & context,QueueProperties properties,cl_int * err=nullptr)7364 explicit CommandQueue(
7365 const Context& context,
7366 QueueProperties properties,
7367 cl_int* err = nullptr)
7368 {
7369 cl_int error;
7370 bool useWithProperties;
7371 vector<cl::Device> devices;
7372 error = context.getInfo(CL_CONTEXT_DEVICES, &devices);
7373
7374 detail::errHandler(error, __CREATE_CONTEXT_ERR);
7375
7376 if (error != CL_SUCCESS)
7377 {
7378 if (err != nullptr) {
7379 *err = error;
7380 }
7381 return;
7382 }
7383
7384 #if CL_HPP_TARGET_OPENCL_VERSION >= 200 && CL_HPP_MINIMUM_OPENCL_VERSION < 200
7385 // Run-time decision based on the actual platform
7386 {
7387 cl_uint version = detail::getContextPlatformVersion(context());
7388 useWithProperties = (version >= 0x20000); // OpenCL 2.0 or above
7389 }
7390 #elif CL_HPP_TARGET_OPENCL_VERSION >= 200
7391 useWithProperties = true;
7392 #else
7393 useWithProperties = false;
7394 #endif
7395
7396 #if CL_HPP_TARGET_OPENCL_VERSION >= 200
7397 if (useWithProperties) {
7398 cl_queue_properties queue_properties[] = {
7399 CL_QUEUE_PROPERTIES, static_cast<cl_queue_properties>(properties), 0 };
7400 object_ = ::clCreateCommandQueueWithProperties(
7401 context(), devices[0](), queue_properties, &error);
7402
7403 detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR);
7404 if (err != nullptr) {
7405 *err = error;
7406 }
7407 }
7408 #endif // CL_HPP_TARGET_OPENCL_VERSION >= 200
7409 #if CL_HPP_MINIMUM_OPENCL_VERSION < 200
7410 if (!useWithProperties) {
7411 object_ = ::clCreateCommandQueue(
7412 context(), devices[0](), static_cast<cl_command_queue_properties>(properties), &error);
7413
7414 detail::errHandler(error, __CREATE_COMMAND_QUEUE_ERR);
7415 if (err != nullptr) {
7416 *err = error;
7417 }
7418 }
7419 #endif // CL_HPP_MINIMUM_OPENCL_VERSION < 200
7420 }
7421
7422 /*!
7423 * \brief Constructs a CommandQueue for a passed device and context
7424 * Will return an CL_INVALID_QUEUE_PROPERTIES error if CL_QUEUE_ON_DEVICE is specified.
7425 */
CommandQueue(const Context & context,const Device & device,cl_command_queue_properties properties=0,cl_int * err=nullptr)7426 CommandQueue(
7427 const Context& context,
7428 const Device& device,
7429 cl_command_queue_properties properties = 0,
7430 cl_int* err = nullptr)
7431 {
7432 cl_int error;
7433 bool useWithProperties;
7434
7435 #if CL_HPP_TARGET_OPENCL_VERSION >= 200 && CL_HPP_MINIMUM_OPENCL_VERSION < 200
7436 // Run-time decision based on the actual platform
7437 {
7438 cl_uint version = detail::getContextPlatformVersion(context());
7439 useWithProperties = (version >= 0x20000); // OpenCL 2.0 or above
7440 }
7441 #elif CL_HPP_TARGET_OPENCL_VERSION >= 200
7442 useWithProperties = true;
7443 #else
7444 useWithProperties = false;
7445 #endif
7446
7447 #if CL_HPP_TARGET_OPENCL_VERSION >= 200
7448 if (useWithProperties) {
7449 cl_queue_properties queue_properties[] = {
7450 CL_QUEUE_PROPERTIES, properties, 0 };
7451 object_ = ::clCreateCommandQueueWithProperties(
7452 context(), device(), queue_properties, &error);
7453
7454 detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR);
7455 if (err != nullptr) {
7456 *err = error;
7457 }
7458 }
7459 #endif // CL_HPP_TARGET_OPENCL_VERSION >= 200
7460 #if CL_HPP_MINIMUM_OPENCL_VERSION < 200
7461 if (!useWithProperties) {
7462 object_ = ::clCreateCommandQueue(
7463 context(), device(), properties, &error);
7464
7465 detail::errHandler(error, __CREATE_COMMAND_QUEUE_ERR);
7466 if (err != nullptr) {
7467 *err = error;
7468 }
7469 }
7470 #endif // CL_HPP_MINIMUM_OPENCL_VERSION < 200
7471 }
7472
7473 /*!
7474 * \brief Constructs a CommandQueue for a passed device and context
7475 * Will return an CL_INVALID_QUEUE_PROPERTIES error if CL_QUEUE_ON_DEVICE is specified.
7476 */
CommandQueue(const Context & context,const Device & device,QueueProperties properties,cl_int * err=nullptr)7477 CommandQueue(
7478 const Context& context,
7479 const Device& device,
7480 QueueProperties properties,
7481 cl_int* err = nullptr)
7482 {
7483 cl_int error;
7484 bool useWithProperties;
7485
7486 #if CL_HPP_TARGET_OPENCL_VERSION >= 200 && CL_HPP_MINIMUM_OPENCL_VERSION < 200
7487 // Run-time decision based on the actual platform
7488 {
7489 cl_uint version = detail::getContextPlatformVersion(context());
7490 useWithProperties = (version >= 0x20000); // OpenCL 2.0 or above
7491 }
7492 #elif CL_HPP_TARGET_OPENCL_VERSION >= 200
7493 useWithProperties = true;
7494 #else
7495 useWithProperties = false;
7496 #endif
7497
7498 #if CL_HPP_TARGET_OPENCL_VERSION >= 200
7499 if (useWithProperties) {
7500 cl_queue_properties queue_properties[] = {
7501 CL_QUEUE_PROPERTIES, static_cast<cl_queue_properties>(properties), 0 };
7502 object_ = ::clCreateCommandQueueWithProperties(
7503 context(), device(), queue_properties, &error);
7504
7505 detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR);
7506 if (err != nullptr) {
7507 *err = error;
7508 }
7509 }
7510 #endif // CL_HPP_TARGET_OPENCL_VERSION >= 200
7511 #if CL_HPP_MINIMUM_OPENCL_VERSION < 200
7512 if (!useWithProperties) {
7513 object_ = ::clCreateCommandQueue(
7514 context(), device(), static_cast<cl_command_queue_properties>(properties), &error);
7515
7516 detail::errHandler(error, __CREATE_COMMAND_QUEUE_ERR);
7517 if (err != nullptr) {
7518 *err = error;
7519 }
7520 }
7521 #endif // CL_HPP_MINIMUM_OPENCL_VERSION < 200
7522 }
7523
getDefault(cl_int * err=nullptr)7524 static CommandQueue getDefault(cl_int * err = nullptr)
7525 {
7526 std::call_once(default_initialized_, makeDefault);
7527 #if CL_HPP_TARGET_OPENCL_VERSION >= 200
7528 detail::errHandler(default_error_, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR);
7529 #else // CL_HPP_TARGET_OPENCL_VERSION >= 200
7530 detail::errHandler(default_error_, __CREATE_COMMAND_QUEUE_ERR);
7531 #endif // CL_HPP_TARGET_OPENCL_VERSION >= 200
7532 if (err != nullptr) {
7533 *err = default_error_;
7534 }
7535 return default_;
7536 }
7537
7538 /**
7539 * Modify the default command queue to be used by
7540 * subsequent operations.
7541 * Will only set the default if no default was previously created.
7542 * @return updated default command queue.
7543 * Should be compared to the passed value to ensure that it was updated.
7544 */
setDefault(const CommandQueue & default_queue)7545 static CommandQueue setDefault(const CommandQueue &default_queue)
7546 {
7547 std::call_once(default_initialized_, makeDefaultProvided, std::cref(default_queue));
7548 detail::errHandler(default_error_);
7549 return default_;
7550 }
7551
CommandQueue()7552 CommandQueue() { }
7553
7554
7555 /*! \brief Constructor from cl_command_queue - takes ownership.
7556 *
7557 * \param retainObject will cause the constructor to retain its cl object.
7558 * Defaults to false to maintain compatibility with
7559 * earlier versions.
7560 */
CommandQueue(const cl_command_queue & commandQueue,bool retainObject=false)7561 explicit CommandQueue(const cl_command_queue& commandQueue, bool retainObject = false) :
7562 detail::Wrapper<cl_type>(commandQueue, retainObject) { }
7563
operator =(const cl_command_queue & rhs)7564 CommandQueue& operator = (const cl_command_queue& rhs)
7565 {
7566 detail::Wrapper<cl_type>::operator=(rhs);
7567 return *this;
7568 }
7569
7570 template <typename T>
getInfo(cl_command_queue_info name,T * param) const7571 cl_int getInfo(cl_command_queue_info name, T* param) const
7572 {
7573 return detail::errHandler(
7574 detail::getInfo(
7575 &::clGetCommandQueueInfo, object_, name, param),
7576 __GET_COMMAND_QUEUE_INFO_ERR);
7577 }
7578
7579 template <cl_command_queue_info name> typename
7580 detail::param_traits<detail::cl_command_queue_info, name>::param_type
getInfo(cl_int * err=nullptr) const7581 getInfo(cl_int* err = nullptr) const
7582 {
7583 typename detail::param_traits<
7584 detail::cl_command_queue_info, name>::param_type param;
7585 cl_int result = getInfo(name, ¶m);
7586 if (err != nullptr) {
7587 *err = result;
7588 }
7589 return param;
7590 }
7591
enqueueReadBuffer(const Buffer & buffer,cl_bool blocking,size_type offset,size_type size,void * ptr,const vector<Event> * events=nullptr,Event * event=nullptr) const7592 cl_int enqueueReadBuffer(
7593 const Buffer& buffer,
7594 cl_bool blocking,
7595 size_type offset,
7596 size_type size,
7597 void* ptr,
7598 const vector<Event>* events = nullptr,
7599 Event* event = nullptr) const
7600 {
7601 cl_event tmp;
7602 cl_int err = detail::errHandler(
7603 ::clEnqueueReadBuffer(
7604 object_, buffer(), blocking, offset, size,
7605 ptr,
7606 (events != nullptr) ? (cl_uint) events->size() : 0,
7607 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
7608 (event != nullptr) ? &tmp : nullptr),
7609 __ENQUEUE_READ_BUFFER_ERR);
7610
7611 if (event != nullptr && err == CL_SUCCESS)
7612 *event = tmp;
7613
7614 return err;
7615 }
7616
enqueueWriteBuffer(const Buffer & buffer,cl_bool blocking,size_type offset,size_type size,const void * ptr,const vector<Event> * events=nullptr,Event * event=nullptr) const7617 cl_int enqueueWriteBuffer(
7618 const Buffer& buffer,
7619 cl_bool blocking,
7620 size_type offset,
7621 size_type size,
7622 const void* ptr,
7623 const vector<Event>* events = nullptr,
7624 Event* event = nullptr) const
7625 {
7626 cl_event tmp;
7627 cl_int err = detail::errHandler(
7628 ::clEnqueueWriteBuffer(
7629 object_, buffer(), blocking, offset, size,
7630 ptr,
7631 (events != nullptr) ? (cl_uint) events->size() : 0,
7632 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
7633 (event != nullptr) ? &tmp : nullptr),
7634 __ENQUEUE_WRITE_BUFFER_ERR);
7635
7636 if (event != nullptr && err == CL_SUCCESS)
7637 *event = tmp;
7638
7639 return err;
7640 }
7641
enqueueCopyBuffer(const Buffer & src,const Buffer & dst,size_type src_offset,size_type dst_offset,size_type size,const vector<Event> * events=nullptr,Event * event=nullptr) const7642 cl_int enqueueCopyBuffer(
7643 const Buffer& src,
7644 const Buffer& dst,
7645 size_type src_offset,
7646 size_type dst_offset,
7647 size_type size,
7648 const vector<Event>* events = nullptr,
7649 Event* event = nullptr) const
7650 {
7651 cl_event tmp;
7652 cl_int err = detail::errHandler(
7653 ::clEnqueueCopyBuffer(
7654 object_, src(), dst(), src_offset, dst_offset, size,
7655 (events != nullptr) ? (cl_uint) events->size() : 0,
7656 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
7657 (event != nullptr) ? &tmp : nullptr),
7658 __ENQEUE_COPY_BUFFER_ERR);
7659
7660 if (event != nullptr && err == CL_SUCCESS)
7661 *event = tmp;
7662
7663 return err;
7664 }
7665 #if CL_HPP_TARGET_OPENCL_VERSION >= 110
enqueueReadBufferRect(const Buffer & buffer,cl_bool blocking,const array<size_type,3> & buffer_offset,const array<size_type,3> & host_offset,const array<size_type,3> & region,size_type buffer_row_pitch,size_type buffer_slice_pitch,size_type host_row_pitch,size_type host_slice_pitch,void * ptr,const vector<Event> * events=nullptr,Event * event=nullptr) const7666 cl_int enqueueReadBufferRect(
7667 const Buffer& buffer,
7668 cl_bool blocking,
7669 const array<size_type, 3>& buffer_offset,
7670 const array<size_type, 3>& host_offset,
7671 const array<size_type, 3>& region,
7672 size_type buffer_row_pitch,
7673 size_type buffer_slice_pitch,
7674 size_type host_row_pitch,
7675 size_type host_slice_pitch,
7676 void *ptr,
7677 const vector<Event>* events = nullptr,
7678 Event* event = nullptr) const
7679 {
7680 cl_event tmp;
7681 cl_int err = detail::errHandler(
7682 ::clEnqueueReadBufferRect(
7683 object_,
7684 buffer(),
7685 blocking,
7686 buffer_offset.data(),
7687 host_offset.data(),
7688 region.data(),
7689 buffer_row_pitch,
7690 buffer_slice_pitch,
7691 host_row_pitch,
7692 host_slice_pitch,
7693 ptr,
7694 (events != nullptr) ? (cl_uint) events->size() : 0,
7695 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
7696 (event != nullptr) ? &tmp : nullptr),
7697 __ENQUEUE_READ_BUFFER_RECT_ERR);
7698
7699 if (event != nullptr && err == CL_SUCCESS)
7700 *event = tmp;
7701
7702 return err;
7703 }
7704
enqueueReadBufferRect(const Buffer & buffer,cl_bool blocking,const array<size_type,2> & buffer_offset,const array<size_type,2> & host_offset,const array<size_type,2> & region,size_type buffer_row_pitch,size_type buffer_slice_pitch,size_type host_row_pitch,size_type host_slice_pitch,void * ptr,const vector<Event> * events=nullptr,Event * event=nullptr) const7705 cl_int enqueueReadBufferRect(
7706 const Buffer& buffer,
7707 cl_bool blocking,
7708 const array<size_type, 2>& buffer_offset,
7709 const array<size_type, 2>& host_offset,
7710 const array<size_type, 2>& region,
7711 size_type buffer_row_pitch,
7712 size_type buffer_slice_pitch,
7713 size_type host_row_pitch,
7714 size_type host_slice_pitch,
7715 void* ptr,
7716 const vector<Event>* events = nullptr,
7717 Event* event = nullptr) const
7718 {
7719 return enqueueReadBufferRect(
7720 buffer,
7721 blocking,
7722 { buffer_offset[0], buffer_offset[1], 0 },
7723 { host_offset[0], host_offset[1], 0 },
7724 { region[0], region[1], 1 },
7725 buffer_row_pitch,
7726 buffer_slice_pitch,
7727 host_row_pitch,
7728 host_slice_pitch,
7729 ptr,
7730 events,
7731 event);
7732 }
7733
enqueueWriteBufferRect(const Buffer & buffer,cl_bool blocking,const array<size_type,3> & buffer_offset,const array<size_type,3> & host_offset,const array<size_type,3> & region,size_type buffer_row_pitch,size_type buffer_slice_pitch,size_type host_row_pitch,size_type host_slice_pitch,const void * ptr,const vector<Event> * events=nullptr,Event * event=nullptr) const7734 cl_int enqueueWriteBufferRect(
7735 const Buffer& buffer,
7736 cl_bool blocking,
7737 const array<size_type, 3>& buffer_offset,
7738 const array<size_type, 3>& host_offset,
7739 const array<size_type, 3>& region,
7740 size_type buffer_row_pitch,
7741 size_type buffer_slice_pitch,
7742 size_type host_row_pitch,
7743 size_type host_slice_pitch,
7744 const void *ptr,
7745 const vector<Event>* events = nullptr,
7746 Event* event = nullptr) const
7747 {
7748 cl_event tmp;
7749 cl_int err = detail::errHandler(
7750 ::clEnqueueWriteBufferRect(
7751 object_,
7752 buffer(),
7753 blocking,
7754 buffer_offset.data(),
7755 host_offset.data(),
7756 region.data(),
7757 buffer_row_pitch,
7758 buffer_slice_pitch,
7759 host_row_pitch,
7760 host_slice_pitch,
7761 ptr,
7762 (events != nullptr) ? (cl_uint) events->size() : 0,
7763 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
7764 (event != nullptr) ? &tmp : nullptr),
7765 __ENQUEUE_WRITE_BUFFER_RECT_ERR);
7766
7767 if (event != nullptr && err == CL_SUCCESS)
7768 *event = tmp;
7769
7770 return err;
7771 }
7772
enqueueWriteBufferRect(const Buffer & buffer,cl_bool blocking,const array<size_type,2> & buffer_offset,const array<size_type,2> & host_offset,const array<size_type,2> & region,size_type buffer_row_pitch,size_type buffer_slice_pitch,size_type host_row_pitch,size_type host_slice_pitch,const void * ptr,const vector<Event> * events=nullptr,Event * event=nullptr) const7773 cl_int enqueueWriteBufferRect(
7774 const Buffer& buffer,
7775 cl_bool blocking,
7776 const array<size_type, 2>& buffer_offset,
7777 const array<size_type, 2>& host_offset,
7778 const array<size_type, 2>& region,
7779 size_type buffer_row_pitch,
7780 size_type buffer_slice_pitch,
7781 size_type host_row_pitch,
7782 size_type host_slice_pitch,
7783 const void* ptr,
7784 const vector<Event>* events = nullptr,
7785 Event* event = nullptr) const
7786 {
7787 return enqueueWriteBufferRect(
7788 buffer,
7789 blocking,
7790 { buffer_offset[0], buffer_offset[1], 0 },
7791 { host_offset[0], host_offset[1], 0 },
7792 { region[0], region[1], 1 },
7793 buffer_row_pitch,
7794 buffer_slice_pitch,
7795 host_row_pitch,
7796 host_slice_pitch,
7797 ptr,
7798 events,
7799 event);
7800 }
7801
enqueueCopyBufferRect(const Buffer & src,const Buffer & dst,const array<size_type,3> & src_origin,const array<size_type,3> & dst_origin,const array<size_type,3> & region,size_type src_row_pitch,size_type src_slice_pitch,size_type dst_row_pitch,size_type dst_slice_pitch,const vector<Event> * events=nullptr,Event * event=nullptr) const7802 cl_int enqueueCopyBufferRect(
7803 const Buffer& src,
7804 const Buffer& dst,
7805 const array<size_type, 3>& src_origin,
7806 const array<size_type, 3>& dst_origin,
7807 const array<size_type, 3>& region,
7808 size_type src_row_pitch,
7809 size_type src_slice_pitch,
7810 size_type dst_row_pitch,
7811 size_type dst_slice_pitch,
7812 const vector<Event>* events = nullptr,
7813 Event* event = nullptr) const
7814 {
7815 cl_event tmp;
7816 cl_int err = detail::errHandler(
7817 ::clEnqueueCopyBufferRect(
7818 object_,
7819 src(),
7820 dst(),
7821 src_origin.data(),
7822 dst_origin.data(),
7823 region.data(),
7824 src_row_pitch,
7825 src_slice_pitch,
7826 dst_row_pitch,
7827 dst_slice_pitch,
7828 (events != nullptr) ? (cl_uint) events->size() : 0,
7829 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
7830 (event != nullptr) ? &tmp : nullptr),
7831 __ENQEUE_COPY_BUFFER_RECT_ERR);
7832
7833 if (event != nullptr && err == CL_SUCCESS)
7834 *event = tmp;
7835
7836 return err;
7837 }
7838
enqueueCopyBufferRect(const Buffer & src,const Buffer & dst,const array<size_type,2> & src_origin,const array<size_type,2> & dst_origin,const array<size_type,2> & region,size_type src_row_pitch,size_type src_slice_pitch,size_type dst_row_pitch,size_type dst_slice_pitch,const vector<Event> * events=nullptr,Event * event=nullptr) const7839 cl_int enqueueCopyBufferRect(
7840 const Buffer& src,
7841 const Buffer& dst,
7842 const array<size_type, 2>& src_origin,
7843 const array<size_type, 2>& dst_origin,
7844 const array<size_type, 2>& region,
7845 size_type src_row_pitch,
7846 size_type src_slice_pitch,
7847 size_type dst_row_pitch,
7848 size_type dst_slice_pitch,
7849 const vector<Event>* events = nullptr,
7850 Event* event = nullptr) const
7851 {
7852 return enqueueCopyBufferRect(
7853 src,
7854 dst,
7855 { src_origin[0], src_origin[1], 0 },
7856 { dst_origin[0], dst_origin[1], 0 },
7857 { region[0], region[1], 1 },
7858 src_row_pitch,
7859 src_slice_pitch,
7860 dst_row_pitch,
7861 dst_slice_pitch,
7862 events,
7863 event);
7864 }
7865
7866 #endif // CL_HPP_TARGET_OPENCL_VERSION >= 110
7867 #if CL_HPP_TARGET_OPENCL_VERSION >= 120
7868 /**
7869 * Enqueue a command to fill a buffer object with a pattern
7870 * of a given size. The pattern is specified as a vector type.
7871 * \tparam PatternType The datatype of the pattern field.
7872 * The pattern type must be an accepted OpenCL data type.
7873 * \tparam offset Is the offset in bytes into the buffer at
7874 * which to start filling. This must be a multiple of
7875 * the pattern size.
7876 * \tparam size Is the size in bytes of the region to fill.
7877 * This must be a multiple of the pattern size.
7878 */
7879 template<typename PatternType>
enqueueFillBuffer(const Buffer & buffer,PatternType pattern,size_type offset,size_type size,const vector<Event> * events=nullptr,Event * event=nullptr) const7880 cl_int enqueueFillBuffer(
7881 const Buffer& buffer,
7882 PatternType pattern,
7883 size_type offset,
7884 size_type size,
7885 const vector<Event>* events = nullptr,
7886 Event* event = nullptr) const
7887 {
7888 cl_event tmp;
7889 cl_int err = detail::errHandler(
7890 ::clEnqueueFillBuffer(
7891 object_,
7892 buffer(),
7893 static_cast<void*>(&pattern),
7894 sizeof(PatternType),
7895 offset,
7896 size,
7897 (events != nullptr) ? (cl_uint) events->size() : 0,
7898 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
7899 (event != nullptr) ? &tmp : nullptr),
7900 __ENQUEUE_FILL_BUFFER_ERR);
7901
7902 if (event != nullptr && err == CL_SUCCESS)
7903 *event = tmp;
7904
7905 return err;
7906 }
7907 #endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
7908
enqueueReadImage(const Image & image,cl_bool blocking,const array<size_type,3> & origin,const array<size_type,3> & region,size_type row_pitch,size_type slice_pitch,void * ptr,const vector<Event> * events=nullptr,Event * event=nullptr) const7909 cl_int enqueueReadImage(
7910 const Image& image,
7911 cl_bool blocking,
7912 const array<size_type, 3>& origin,
7913 const array<size_type, 3>& region,
7914 size_type row_pitch,
7915 size_type slice_pitch,
7916 void* ptr,
7917 const vector<Event>* events = nullptr,
7918 Event* event = nullptr) const
7919 {
7920 cl_event tmp;
7921 cl_int err = detail::errHandler(
7922 ::clEnqueueReadImage(
7923 object_,
7924 image(),
7925 blocking,
7926 origin.data(),
7927 region.data(),
7928 row_pitch,
7929 slice_pitch,
7930 ptr,
7931 (events != nullptr) ? (cl_uint) events->size() : 0,
7932 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
7933 (event != nullptr) ? &tmp : nullptr),
7934 __ENQUEUE_READ_IMAGE_ERR);
7935
7936 if (event != nullptr && err == CL_SUCCESS)
7937 *event = tmp;
7938
7939 return err;
7940 }
7941
enqueueReadImage(const Image & image,cl_bool blocking,const array<size_type,2> & origin,const array<size_type,2> & region,size_type row_pitch,size_type slice_pitch,void * ptr,const vector<Event> * events=nullptr,Event * event=nullptr) const7942 cl_int enqueueReadImage(
7943 const Image& image,
7944 cl_bool blocking,
7945 const array<size_type, 2>& origin,
7946 const array<size_type, 2>& region,
7947 size_type row_pitch,
7948 size_type slice_pitch,
7949 void* ptr,
7950 const vector<Event>* events = nullptr,
7951 Event* event = nullptr) const
7952 {
7953 return enqueueReadImage(
7954 image,
7955 blocking,
7956 { origin[0], origin[1], 0 },
7957 { region[0], region[1], 1 },
7958 row_pitch,
7959 slice_pitch,
7960 ptr,
7961 events,
7962 event);
7963 }
7964
enqueueWriteImage(const Image & image,cl_bool blocking,const array<size_type,3> & origin,const array<size_type,3> & region,size_type row_pitch,size_type slice_pitch,const void * ptr,const vector<Event> * events=nullptr,Event * event=nullptr) const7965 cl_int enqueueWriteImage(
7966 const Image& image,
7967 cl_bool blocking,
7968 const array<size_type, 3>& origin,
7969 const array<size_type, 3>& region,
7970 size_type row_pitch,
7971 size_type slice_pitch,
7972 const void* ptr,
7973 const vector<Event>* events = nullptr,
7974 Event* event = nullptr) const
7975 {
7976 cl_event tmp;
7977 cl_int err = detail::errHandler(
7978 ::clEnqueueWriteImage(
7979 object_,
7980 image(),
7981 blocking,
7982 origin.data(),
7983 region.data(),
7984 row_pitch,
7985 slice_pitch,
7986 ptr,
7987 (events != nullptr) ? (cl_uint) events->size() : 0,
7988 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
7989 (event != nullptr) ? &tmp : nullptr),
7990 __ENQUEUE_WRITE_IMAGE_ERR);
7991
7992 if (event != nullptr && err == CL_SUCCESS)
7993 *event = tmp;
7994
7995 return err;
7996 }
7997
enqueueWriteImage(const Image & image,cl_bool blocking,const array<size_type,2> & origin,const array<size_type,2> & region,size_type row_pitch,size_type slice_pitch,const void * ptr,const vector<Event> * events=nullptr,Event * event=nullptr) const7998 cl_int enqueueWriteImage(
7999 const Image& image,
8000 cl_bool blocking,
8001 const array<size_type, 2>& origin,
8002 const array<size_type, 2>& region,
8003 size_type row_pitch,
8004 size_type slice_pitch,
8005 const void* ptr,
8006 const vector<Event>* events = nullptr,
8007 Event* event = nullptr) const
8008 {
8009 return enqueueWriteImage(
8010 image,
8011 blocking,
8012 { origin[0], origin[1], 0 },
8013 { region[0], region[1], 1 },
8014 row_pitch,
8015 slice_pitch,
8016 ptr,
8017 events,
8018 event);
8019 }
8020
enqueueCopyImage(const Image & src,const Image & dst,const array<size_type,3> & src_origin,const array<size_type,3> & dst_origin,const array<size_type,3> & region,const vector<Event> * events=nullptr,Event * event=nullptr) const8021 cl_int enqueueCopyImage(
8022 const Image& src,
8023 const Image& dst,
8024 const array<size_type, 3>& src_origin,
8025 const array<size_type, 3>& dst_origin,
8026 const array<size_type, 3>& region,
8027 const vector<Event>* events = nullptr,
8028 Event* event = nullptr) const
8029 {
8030 cl_event tmp;
8031 cl_int err = detail::errHandler(
8032 ::clEnqueueCopyImage(
8033 object_,
8034 src(),
8035 dst(),
8036 src_origin.data(),
8037 dst_origin.data(),
8038 region.data(),
8039 (events != nullptr) ? (cl_uint) events->size() : 0,
8040 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
8041 (event != nullptr) ? &tmp : nullptr),
8042 __ENQUEUE_COPY_IMAGE_ERR);
8043
8044 if (event != nullptr && err == CL_SUCCESS)
8045 *event = tmp;
8046
8047 return err;
8048 }
8049
enqueueCopyImage(const Image & src,const Image & dst,const array<size_type,2> & src_origin,const array<size_type,2> & dst_origin,const array<size_type,2> & region,const vector<Event> * events=nullptr,Event * event=nullptr) const8050 cl_int enqueueCopyImage(
8051 const Image& src,
8052 const Image& dst,
8053 const array<size_type, 2>& src_origin,
8054 const array<size_type, 2>& dst_origin,
8055 const array<size_type, 2>& region,
8056 const vector<Event>* events = nullptr,
8057 Event* event = nullptr) const
8058 {
8059 return enqueueCopyImage(
8060 src,
8061 dst,
8062 { src_origin[0], src_origin[1], 0 },
8063 { dst_origin[0], dst_origin[1], 0 },
8064 { region[0], region[1], 1 },
8065 events,
8066 event);
8067 }
8068
8069 #if CL_HPP_TARGET_OPENCL_VERSION >= 120
8070 /**
8071 * Enqueue a command to fill an image object with a specified color.
8072 * \param fillColor is the color to use to fill the image.
8073 * This is a four component RGBA floating-point, signed integer
8074 * or unsigned integer color value if the image channel data
8075 * type is an unnormalized signed integer type.
8076 */
8077 template <typename T>
8078 typename std::enable_if<std::is_same<T, cl_float4>::value ||
8079 std::is_same<T, cl_int4 >::value ||
8080 std::is_same<T, cl_uint4 >::value,
8081 cl_int>::type
enqueueFillImage(const Image & image,T fillColor,const array<size_type,3> & origin,const array<size_type,3> & region,const vector<Event> * events=nullptr,Event * event=nullptr) const8082 enqueueFillImage(
8083 const Image& image,
8084 T fillColor,
8085 const array<size_type, 3>& origin,
8086 const array<size_type, 3>& region,
8087 const vector<Event>* events = nullptr,
8088 Event* event = nullptr) const
8089 {
8090 cl_event tmp;
8091 cl_int err = detail::errHandler(
8092 ::clEnqueueFillImage(
8093 object_,
8094 image(),
8095 static_cast<void*>(&fillColor),
8096 origin.data(),
8097 region.data(),
8098 (events != nullptr) ? (cl_uint)events->size() : 0,
8099 (events != nullptr && events->size() > 0) ? (cl_event*)&events->front() : NULL,
8100 (event != NULL) ? &tmp : nullptr),
8101 __ENQUEUE_FILL_IMAGE_ERR);
8102
8103 if (event != nullptr && err == CL_SUCCESS) *event = tmp;
8104
8105 return err;
8106 }
8107
8108 /**
8109 * Enqueue a command to fill an image object with a specified color.
8110 * \param fillColor is the color to use to fill the image.
8111 * This is a four component RGBA floating-point, signed integer
8112 * or unsigned integer color value if the image channel data
8113 * type is an unnormalized signed integer type.
8114 */
8115 template <typename T>
8116 typename std::enable_if<std::is_same<T, cl_float4>::value ||
8117 std::is_same<T, cl_int4 >::value ||
8118 std::is_same<T, cl_uint4 >::value, cl_int>::type
enqueueFillImage(const Image & image,T fillColor,const array<size_type,2> & origin,const array<size_type,2> & region,const vector<Event> * events=nullptr,Event * event=nullptr) const8119 enqueueFillImage(
8120 const Image& image,
8121 T fillColor,
8122 const array<size_type, 2>& origin,
8123 const array<size_type, 2>& region,
8124 const vector<Event>* events = nullptr,
8125 Event* event = nullptr) const
8126 {
8127 return enqueueFillImage(
8128 image,
8129 fillColor,
8130 { origin[0], origin[1], 0 },
8131 { region[0], region[1], 1 },
8132 events,
8133 event
8134 );
8135 }
8136 #endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
8137
enqueueCopyImageToBuffer(const Image & src,const Buffer & dst,const array<size_type,3> & src_origin,const array<size_type,3> & region,size_type dst_offset,const vector<Event> * events=nullptr,Event * event=nullptr) const8138 cl_int enqueueCopyImageToBuffer(
8139 const Image& src,
8140 const Buffer& dst,
8141 const array<size_type, 3>& src_origin,
8142 const array<size_type, 3>& region,
8143 size_type dst_offset,
8144 const vector<Event>* events = nullptr,
8145 Event* event = nullptr) const
8146 {
8147 cl_event tmp;
8148 cl_int err = detail::errHandler(
8149 ::clEnqueueCopyImageToBuffer(
8150 object_,
8151 src(),
8152 dst(),
8153 src_origin.data(),
8154 region.data(),
8155 dst_offset,
8156 (events != nullptr) ? (cl_uint) events->size() : 0,
8157 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
8158 (event != nullptr) ? &tmp : nullptr),
8159 __ENQUEUE_COPY_IMAGE_TO_BUFFER_ERR);
8160
8161 if (event != nullptr && err == CL_SUCCESS)
8162 *event = tmp;
8163
8164 return err;
8165 }
8166
enqueueCopyImageToBuffer(const Image & src,const Buffer & dst,const array<size_type,2> & src_origin,const array<size_type,2> & region,size_type dst_offset,const vector<Event> * events=nullptr,Event * event=nullptr) const8167 cl_int enqueueCopyImageToBuffer(
8168 const Image& src,
8169 const Buffer& dst,
8170 const array<size_type, 2>& src_origin,
8171 const array<size_type, 2>& region,
8172 size_type dst_offset,
8173 const vector<Event>* events = nullptr,
8174 Event* event = nullptr) const
8175 {
8176 return enqueueCopyImageToBuffer(
8177 src,
8178 dst,
8179 { src_origin[0], src_origin[1], 0 },
8180 { region[0], region[1], 1 },
8181 dst_offset,
8182 events,
8183 event);
8184 }
8185
enqueueCopyBufferToImage(const Buffer & src,const Image & dst,size_type src_offset,const array<size_type,3> & dst_origin,const array<size_type,3> & region,const vector<Event> * events=nullptr,Event * event=nullptr) const8186 cl_int enqueueCopyBufferToImage(
8187 const Buffer& src,
8188 const Image& dst,
8189 size_type src_offset,
8190 const array<size_type, 3>& dst_origin,
8191 const array<size_type, 3>& region,
8192 const vector<Event>* events = nullptr,
8193 Event* event = nullptr) const
8194 {
8195 cl_event tmp;
8196 cl_int err = detail::errHandler(
8197 ::clEnqueueCopyBufferToImage(
8198 object_,
8199 src(),
8200 dst(),
8201 src_offset,
8202 dst_origin.data(),
8203 region.data(),
8204 (events != nullptr) ? (cl_uint) events->size() : 0,
8205 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
8206 (event != nullptr) ? &tmp : nullptr),
8207 __ENQUEUE_COPY_BUFFER_TO_IMAGE_ERR);
8208
8209 if (event != nullptr && err == CL_SUCCESS)
8210 *event = tmp;
8211
8212 return err;
8213 }
8214
enqueueCopyBufferToImage(const Buffer & src,const Image & dst,size_type src_offset,const array<size_type,2> & dst_origin,const array<size_type,2> & region,const vector<Event> * events=nullptr,Event * event=nullptr) const8215 cl_int enqueueCopyBufferToImage(
8216 const Buffer& src,
8217 const Image& dst,
8218 size_type src_offset,
8219 const array<size_type, 2>& dst_origin,
8220 const array<size_type, 2>& region,
8221 const vector<Event>* events = nullptr,
8222 Event* event = nullptr) const
8223 {
8224 return enqueueCopyBufferToImage(
8225 src,
8226 dst,
8227 src_offset,
8228 { dst_origin[0], dst_origin[1], 0 },
8229 { region[0], region[1], 1 },
8230 events,
8231 event);
8232 }
8233
enqueueMapBuffer(const Buffer & buffer,cl_bool blocking,cl_map_flags flags,size_type offset,size_type size,const vector<Event> * events=nullptr,Event * event=nullptr,cl_int * err=nullptr) const8234 void* enqueueMapBuffer(
8235 const Buffer& buffer,
8236 cl_bool blocking,
8237 cl_map_flags flags,
8238 size_type offset,
8239 size_type size,
8240 const vector<Event>* events = nullptr,
8241 Event* event = nullptr,
8242 cl_int* err = nullptr) const
8243 {
8244 cl_event tmp;
8245 cl_int error;
8246 void * result = ::clEnqueueMapBuffer(
8247 object_, buffer(), blocking, flags, offset, size,
8248 (events != nullptr) ? (cl_uint) events->size() : 0,
8249 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
8250 (event != nullptr) ? &tmp : nullptr,
8251 &error);
8252
8253 detail::errHandler(error, __ENQUEUE_MAP_BUFFER_ERR);
8254 if (err != nullptr) {
8255 *err = error;
8256 }
8257 if (event != nullptr && error == CL_SUCCESS)
8258 *event = tmp;
8259
8260 return result;
8261 }
8262
enqueueMapImage(const Image & image,cl_bool blocking,cl_map_flags flags,const array<size_type,3> & origin,const array<size_type,3> & region,size_type * row_pitch,size_type * slice_pitch,const vector<Event> * events=nullptr,Event * event=nullptr,cl_int * err=nullptr) const8263 void* enqueueMapImage(
8264 const Image& image,
8265 cl_bool blocking,
8266 cl_map_flags flags,
8267 const array<size_type, 3>& origin,
8268 const array<size_type, 3>& region,
8269 size_type * row_pitch,
8270 size_type * slice_pitch,
8271 const vector<Event>* events = nullptr,
8272 Event* event = nullptr,
8273 cl_int* err = nullptr) const
8274 {
8275 cl_event tmp;
8276 cl_int error;
8277 void * result = ::clEnqueueMapImage(
8278 object_, image(), blocking, flags,
8279 origin.data(),
8280 region.data(),
8281 row_pitch, slice_pitch,
8282 (events != nullptr) ? (cl_uint) events->size() : 0,
8283 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
8284 (event != nullptr) ? &tmp : nullptr,
8285 &error);
8286
8287 detail::errHandler(error, __ENQUEUE_MAP_IMAGE_ERR);
8288 if (err != nullptr) {
8289 *err = error;
8290 }
8291 if (event != nullptr && error == CL_SUCCESS)
8292 *event = tmp;
8293 return result;
8294 }
8295
enqueueMapImage(const Image & image,cl_bool blocking,cl_map_flags flags,const array<size_type,2> & origin,const array<size_type,2> & region,size_type * row_pitch,size_type * slice_pitch,const vector<Event> * events=nullptr,Event * event=nullptr,cl_int * err=nullptr) const8296 void* enqueueMapImage(
8297 const Image& image,
8298 cl_bool blocking,
8299 cl_map_flags flags,
8300 const array<size_type, 2>& origin,
8301 const array<size_type, 2>& region,
8302 size_type* row_pitch,
8303 size_type* slice_pitch,
8304 const vector<Event>* events = nullptr,
8305 Event* event = nullptr,
8306 cl_int* err = nullptr) const
8307 {
8308 return enqueueMapImage(image, blocking, flags,
8309 { origin[0], origin[1], 0 },
8310 { region[0], region[1], 1 }, row_pitch,
8311 slice_pitch, events, event, err);
8312 }
8313
8314 #if CL_HPP_TARGET_OPENCL_VERSION >= 200
8315
8316 /**
8317 * Enqueues a command that copies a region of memory from the source pointer to the destination pointer.
8318 * This function is specifically for transferring data between the host and a coarse-grained SVM buffer.
8319 */
8320 template<typename T>
enqueueMemcpySVM(T * dst_ptr,const T * src_ptr,cl_bool blocking,size_type size,const vector<Event> * events=nullptr,Event * event=nullptr) const8321 cl_int enqueueMemcpySVM(
8322 T *dst_ptr,
8323 const T *src_ptr,
8324 cl_bool blocking,
8325 size_type size,
8326 const vector<Event> *events = nullptr,
8327 Event *event = nullptr) const {
8328 cl_event tmp;
8329 cl_int err = detail::errHandler(::clEnqueueSVMMemcpy(
8330 object_, blocking, static_cast<void *>(dst_ptr), static_cast<const void *>(src_ptr), size,
8331 (events != nullptr) ? (cl_uint) events->size() : 0,
8332 (events != nullptr && events->size() > 0) ? (cl_event *) &events->front() : nullptr,
8333 (event != nullptr) ? &tmp : nullptr), __ENQUEUE_COPY_SVM_ERR);
8334
8335 if (event != nullptr && err == CL_SUCCESS)
8336 *event = tmp;
8337
8338 return err;
8339 }
8340
8341 /**
8342 *Enqueues a command that will copy data from one coarse-grained SVM buffer to another.
8343 *This function takes two cl::pointer instances representing the destination and source buffers.
8344 */
8345 template<typename T, class D>
enqueueMemcpySVM(cl::pointer<T,D> & dst_ptr,const cl::pointer<T,D> & src_ptr,cl_bool blocking,size_type size,const vector<Event> * events=nullptr,Event * event=nullptr) const8346 cl_int enqueueMemcpySVM(
8347 cl::pointer<T, D> &dst_ptr,
8348 const cl::pointer<T, D> &src_ptr,
8349 cl_bool blocking,
8350 size_type size,
8351 const vector<Event> *events = nullptr,
8352 Event *event = nullptr) const {
8353 cl_event tmp;
8354 cl_int err = detail::errHandler(::clEnqueueSVMMemcpy(
8355 object_, blocking, static_cast<void *>(dst_ptr.get()), static_cast<const void *>(src_ptr.get()),
8356 size,
8357 (events != nullptr) ? (cl_uint) events->size() : 0,
8358 (events != nullptr && events->size() > 0) ? (cl_event *) &events->front() : nullptr,
8359 (event != nullptr) ? &tmp : nullptr), __ENQUEUE_COPY_SVM_ERR);
8360
8361 if (event != nullptr && err == CL_SUCCESS)
8362 *event = tmp;
8363
8364 return err;
8365 }
8366
8367 /**
8368 * Enqueues a command that will allow the host to update a region of a coarse-grained SVM buffer.
8369 * This variant takes a cl::vector instance.
8370 */
8371 template<typename T, class Alloc>
enqueueMemcpySVM(cl::vector<T,Alloc> & dst_container,const cl::vector<T,Alloc> & src_container,cl_bool blocking,const vector<Event> * events=nullptr,Event * event=nullptr) const8372 cl_int enqueueMemcpySVM(
8373 cl::vector<T, Alloc> &dst_container,
8374 const cl::vector<T, Alloc> &src_container,
8375 cl_bool blocking,
8376 const vector<Event> *events = nullptr,
8377 Event *event = nullptr) const {
8378 cl_event tmp;
8379 if(src_container.size() != dst_container.size()){
8380 return detail::errHandler(CL_INVALID_VALUE,__ENQUEUE_COPY_SVM_ERR);
8381 }
8382 cl_int err = detail::errHandler(::clEnqueueSVMMemcpy(
8383 object_, blocking, static_cast<void *>(dst_container.data()),
8384 static_cast<const void *>(src_container.data()),
8385 dst_container.size() * sizeof(T),
8386 (events != nullptr) ? (cl_uint) events->size() : 0,
8387 (events != nullptr && events->size() > 0) ? (cl_event *) &events->front() : nullptr,
8388 (event != NULL) ? &tmp : nullptr), __ENQUEUE_COPY_SVM_ERR);
8389
8390 if (event != nullptr && err == CL_SUCCESS)
8391 *event = tmp;
8392
8393 return err;
8394 }
8395
8396 /**
8397 * Enqueues a command to fill a SVM buffer with a pattern.
8398 *
8399 */
8400 template<typename T, typename PatternType>
enqueueMemFillSVM(T * ptr,PatternType pattern,size_type size,const vector<Event> * events=nullptr,Event * event=nullptr) const8401 cl_int enqueueMemFillSVM(
8402 T *ptr,
8403 PatternType pattern,
8404 size_type size,
8405 const vector<Event> *events = nullptr,
8406 Event *event = nullptr) const {
8407 cl_event tmp;
8408 cl_int err = detail::errHandler(::clEnqueueSVMMemFill(
8409 object_, static_cast<void *>(ptr), static_cast<void *>(&pattern),
8410 sizeof(PatternType), size,
8411 (events != nullptr) ? (cl_uint) events->size() : 0,
8412 (events != nullptr && events->size() > 0) ? (cl_event *) &events->front() : nullptr,
8413 (event != nullptr) ? &tmp : nullptr), __ENQUEUE_FILL_SVM_ERR);
8414
8415 if (event != nullptr && err == CL_SUCCESS)
8416 *event = tmp;
8417
8418 return err;
8419 }
8420
8421 /**
8422 * Enqueues a command that fills a region of a coarse-grained SVM buffer with a specified pattern.
8423 * This variant takes a cl::pointer instance.
8424 */
8425 template<typename T, class D, typename PatternType>
enqueueMemFillSVM(cl::pointer<T,D> & ptr,PatternType pattern,size_type size,const vector<Event> * events=nullptr,Event * event=nullptr) const8426 cl_int enqueueMemFillSVM(
8427 cl::pointer<T, D> &ptr,
8428 PatternType pattern,
8429 size_type size,
8430 const vector<Event> *events = nullptr,
8431 Event *event = nullptr) const {
8432 cl_event tmp;
8433 cl_int err = detail::errHandler(::clEnqueueSVMMemFill(
8434 object_, static_cast<void *>(ptr.get()), static_cast<void *>(&pattern),
8435 sizeof(PatternType), size,
8436 (events != nullptr) ? (cl_uint) events->size() : 0,
8437 (events != nullptr && events->size() > 0) ? (cl_event *) &events->front() : nullptr,
8438 (event != nullptr) ? &tmp : nullptr), __ENQUEUE_FILL_SVM_ERR);
8439
8440 if (event != nullptr && err == CL_SUCCESS)
8441 *event = tmp;
8442
8443 return err;
8444 }
8445
8446 /**
8447 * Enqueues a command that will allow the host to fill a region of a coarse-grained SVM buffer with a specified pattern.
8448 * This variant takes a cl::vector instance.
8449 */
8450 template<typename T, class Alloc, typename PatternType>
enqueueMemFillSVM(cl::vector<T,Alloc> & container,PatternType pattern,const vector<Event> * events=nullptr,Event * event=nullptr) const8451 cl_int enqueueMemFillSVM(
8452 cl::vector<T, Alloc> &container,
8453 PatternType pattern,
8454 const vector<Event> *events = nullptr,
8455 Event* event = nullptr) const
8456 {
8457 cl_event tmp;
8458 cl_int err = detail::errHandler(::clEnqueueSVMMemFill(
8459 object_, static_cast<void *>(container.data()), static_cast<void *>(&pattern),
8460 sizeof(PatternType), container.size() * sizeof(T),
8461 (events != nullptr) ? (cl_uint) events->size() : 0,
8462 (events != nullptr && events->size() > 0) ? (cl_event *) &events->front() : nullptr,
8463 (event != nullptr) ? &tmp : NULL), __ENQUEUE_FILL_SVM_ERR);
8464
8465 if (event != nullptr && err == CL_SUCCESS)
8466 *event = tmp;
8467
8468 return err;
8469 }
8470
8471 /**
8472 * Enqueues a command that will allow the host to update a region of a coarse-grained SVM buffer.
8473 * This variant takes a raw SVM pointer.
8474 */
8475 template<typename T>
enqueueMapSVM(T * ptr,cl_bool blocking,cl_map_flags flags,size_type size,const vector<Event> * events=nullptr,Event * event=nullptr) const8476 cl_int enqueueMapSVM(
8477 T* ptr,
8478 cl_bool blocking,
8479 cl_map_flags flags,
8480 size_type size,
8481 const vector<Event>* events = nullptr,
8482 Event* event = nullptr) const
8483 {
8484 cl_event tmp;
8485 cl_int err = detail::errHandler(::clEnqueueSVMMap(
8486 object_, blocking, flags, static_cast<void*>(ptr), size,
8487 (events != nullptr) ? (cl_uint)events->size() : 0,
8488 (events != nullptr && events->size() > 0) ? (cl_event*)&events->front() : nullptr,
8489 (event != nullptr) ? &tmp : nullptr),
8490 __ENQUEUE_MAP_SVM_ERR);
8491
8492 if (event != nullptr && err == CL_SUCCESS)
8493 *event = tmp;
8494
8495 return err;
8496 }
8497
8498
8499 /**
8500 * Enqueues a command that will allow the host to update a region of a coarse-grained SVM buffer.
8501 * This variant takes a cl::pointer instance.
8502 */
8503 template<typename T, class D>
enqueueMapSVM(cl::pointer<T,D> & ptr,cl_bool blocking,cl_map_flags flags,size_type size,const vector<Event> * events=nullptr,Event * event=nullptr) const8504 cl_int enqueueMapSVM(
8505 cl::pointer<T, D> &ptr,
8506 cl_bool blocking,
8507 cl_map_flags flags,
8508 size_type size,
8509 const vector<Event>* events = nullptr,
8510 Event* event = nullptr) const
8511 {
8512 cl_event tmp;
8513 cl_int err = detail::errHandler(::clEnqueueSVMMap(
8514 object_, blocking, flags, static_cast<void*>(ptr.get()), size,
8515 (events != nullptr) ? (cl_uint)events->size() : 0,
8516 (events != nullptr && events->size() > 0) ? (cl_event*)&events->front() : nullptr,
8517 (event != nullptr) ? &tmp : nullptr),
8518 __ENQUEUE_MAP_SVM_ERR);
8519
8520 if (event != nullptr && err == CL_SUCCESS)
8521 *event = tmp;
8522
8523 return err;
8524 }
8525
8526 /**
8527 * Enqueues a command that will allow the host to update a region of a coarse-grained SVM buffer.
8528 * This variant takes a cl::vector instance.
8529 */
8530 template<typename T, class Alloc>
enqueueMapSVM(cl::vector<T,Alloc> & container,cl_bool blocking,cl_map_flags flags,const vector<Event> * events=nullptr,Event * event=nullptr) const8531 cl_int enqueueMapSVM(
8532 cl::vector<T, Alloc> &container,
8533 cl_bool blocking,
8534 cl_map_flags flags,
8535 const vector<Event>* events = nullptr,
8536 Event* event = nullptr) const
8537 {
8538 cl_event tmp;
8539 cl_int err = detail::errHandler(::clEnqueueSVMMap(
8540 object_, blocking, flags, static_cast<void*>(container.data()), container.size()*sizeof(T),
8541 (events != nullptr) ? (cl_uint)events->size() : 0,
8542 (events != nullptr && events->size() > 0) ? (cl_event*)&events->front() : nullptr,
8543 (event != nullptr) ? &tmp : nullptr),
8544 __ENQUEUE_MAP_SVM_ERR);
8545
8546 if (event != nullptr && err == CL_SUCCESS)
8547 *event = tmp;
8548
8549 return err;
8550 }
8551 #endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 200
8552
enqueueUnmapMemObject(const Memory & memory,void * mapped_ptr,const vector<Event> * events=nullptr,Event * event=nullptr) const8553 cl_int enqueueUnmapMemObject(
8554 const Memory& memory,
8555 void* mapped_ptr,
8556 const vector<Event>* events = nullptr,
8557 Event* event = nullptr) const
8558 {
8559 cl_event tmp;
8560 cl_int err = detail::errHandler(
8561 ::clEnqueueUnmapMemObject(
8562 object_, memory(), mapped_ptr,
8563 (events != nullptr) ? (cl_uint) events->size() : 0,
8564 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
8565 (event != nullptr) ? &tmp : nullptr),
8566 __ENQUEUE_UNMAP_MEM_OBJECT_ERR);
8567
8568 if (event != nullptr && err == CL_SUCCESS)
8569 *event = tmp;
8570
8571 return err;
8572 }
8573
8574
8575 #if CL_HPP_TARGET_OPENCL_VERSION >= 200
8576 /**
8577 * Enqueues a command that will release a coarse-grained SVM buffer back to the OpenCL runtime.
8578 * This variant takes a raw SVM pointer.
8579 */
8580 template<typename T>
enqueueUnmapSVM(T * ptr,const vector<Event> * events=nullptr,Event * event=nullptr) const8581 cl_int enqueueUnmapSVM(
8582 T* ptr,
8583 const vector<Event>* events = nullptr,
8584 Event* event = nullptr) const
8585 {
8586 cl_event tmp;
8587 cl_int err = detail::errHandler(
8588 ::clEnqueueSVMUnmap(
8589 object_, static_cast<void*>(ptr),
8590 (events != nullptr) ? (cl_uint)events->size() : 0,
8591 (events != nullptr && events->size() > 0) ? (cl_event*)&events->front() : nullptr,
8592 (event != nullptr) ? &tmp : nullptr),
8593 __ENQUEUE_UNMAP_SVM_ERR);
8594
8595 if (event != nullptr && err == CL_SUCCESS)
8596 *event = tmp;
8597
8598 return err;
8599 }
8600
8601 /**
8602 * Enqueues a command that will release a coarse-grained SVM buffer back to the OpenCL runtime.
8603 * This variant takes a cl::pointer instance.
8604 */
8605 template<typename T, class D>
enqueueUnmapSVM(cl::pointer<T,D> & ptr,const vector<Event> * events=nullptr,Event * event=nullptr) const8606 cl_int enqueueUnmapSVM(
8607 cl::pointer<T, D> &ptr,
8608 const vector<Event>* events = nullptr,
8609 Event* event = nullptr) const
8610 {
8611 cl_event tmp;
8612 cl_int err = detail::errHandler(
8613 ::clEnqueueSVMUnmap(
8614 object_, static_cast<void*>(ptr.get()),
8615 (events != nullptr) ? (cl_uint)events->size() : 0,
8616 (events != nullptr && events->size() > 0) ? (cl_event*)&events->front() : nullptr,
8617 (event != nullptr) ? &tmp : nullptr),
8618 __ENQUEUE_UNMAP_SVM_ERR);
8619
8620 if (event != nullptr && err == CL_SUCCESS)
8621 *event = tmp;
8622
8623 return err;
8624 }
8625
8626 /**
8627 * Enqueues a command that will release a coarse-grained SVM buffer back to the OpenCL runtime.
8628 * This variant takes a cl::vector instance.
8629 */
8630 template<typename T, class Alloc>
enqueueUnmapSVM(cl::vector<T,Alloc> & container,const vector<Event> * events=nullptr,Event * event=nullptr) const8631 cl_int enqueueUnmapSVM(
8632 cl::vector<T, Alloc> &container,
8633 const vector<Event>* events = nullptr,
8634 Event* event = nullptr) const
8635 {
8636 cl_event tmp;
8637 cl_int err = detail::errHandler(
8638 ::clEnqueueSVMUnmap(
8639 object_, static_cast<void*>(container.data()),
8640 (events != nullptr) ? (cl_uint)events->size() : 0,
8641 (events != nullptr && events->size() > 0) ? (cl_event*)&events->front() : nullptr,
8642 (event != nullptr) ? &tmp : nullptr),
8643 __ENQUEUE_UNMAP_SVM_ERR);
8644
8645 if (event != nullptr && err == CL_SUCCESS)
8646 *event = tmp;
8647
8648 return err;
8649 }
8650 #endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 200
8651
8652 #if CL_HPP_TARGET_OPENCL_VERSION >= 120
8653 /**
8654 * Enqueues a marker command which waits for either a list of events to complete,
8655 * or all previously enqueued commands to complete.
8656 *
8657 * Enqueues a marker command which waits for either a list of events to complete,
8658 * or if the list is empty it waits for all commands previously enqueued in command_queue
8659 * to complete before it completes. This command returns an event which can be waited on,
8660 * i.e. this event can be waited on to insure that all events either in the event_wait_list
8661 * or all previously enqueued commands, queued before this command to command_queue,
8662 * have completed.
8663 */
enqueueMarkerWithWaitList(const vector<Event> * events=nullptr,Event * event=nullptr) const8664 cl_int enqueueMarkerWithWaitList(
8665 const vector<Event> *events = nullptr,
8666 Event *event = nullptr) const
8667 {
8668 cl_event tmp;
8669 cl_int err = detail::errHandler(
8670 ::clEnqueueMarkerWithWaitList(
8671 object_,
8672 (events != nullptr) ? (cl_uint) events->size() : 0,
8673 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
8674 (event != nullptr) ? &tmp : nullptr),
8675 __ENQUEUE_MARKER_WAIT_LIST_ERR);
8676
8677 if (event != nullptr && err == CL_SUCCESS)
8678 *event = tmp;
8679
8680 return err;
8681 }
8682
8683 /**
8684 * A synchronization point that enqueues a barrier operation.
8685 *
8686 * Enqueues a barrier command which waits for either a list of events to complete,
8687 * or if the list is empty it waits for all commands previously enqueued in command_queue
8688 * to complete before it completes. This command blocks command execution, that is, any
8689 * following commands enqueued after it do not execute until it completes. This command
8690 * returns an event which can be waited on, i.e. this event can be waited on to insure that
8691 * all events either in the event_wait_list or all previously enqueued commands, queued
8692 * before this command to command_queue, have completed.
8693 */
enqueueBarrierWithWaitList(const vector<Event> * events=nullptr,Event * event=nullptr) const8694 cl_int enqueueBarrierWithWaitList(
8695 const vector<Event> *events = nullptr,
8696 Event *event = nullptr) const
8697 {
8698 cl_event tmp;
8699 cl_int err = detail::errHandler(
8700 ::clEnqueueBarrierWithWaitList(
8701 object_,
8702 (events != nullptr) ? (cl_uint) events->size() : 0,
8703 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
8704 (event != nullptr) ? &tmp : nullptr),
8705 __ENQUEUE_BARRIER_WAIT_LIST_ERR);
8706
8707 if (event != nullptr && err == CL_SUCCESS)
8708 *event = tmp;
8709
8710 return err;
8711 }
8712
8713 /**
8714 * Enqueues a command to indicate with which device a set of memory objects
8715 * should be associated.
8716 */
enqueueMigrateMemObjects(const vector<Memory> & memObjects,cl_mem_migration_flags flags,const vector<Event> * events=nullptr,Event * event=nullptr) const8717 cl_int enqueueMigrateMemObjects(
8718 const vector<Memory> &memObjects,
8719 cl_mem_migration_flags flags,
8720 const vector<Event>* events = nullptr,
8721 Event* event = nullptr
8722 ) const
8723 {
8724 cl_event tmp;
8725
8726 vector<cl_mem> localMemObjects(memObjects.size());
8727
8728 for( int i = 0; i < (int)memObjects.size(); ++i ) {
8729 localMemObjects[i] = memObjects[i]();
8730 }
8731
8732 cl_int err = detail::errHandler(
8733 ::clEnqueueMigrateMemObjects(
8734 object_,
8735 (cl_uint)memObjects.size(),
8736 localMemObjects.data(),
8737 flags,
8738 (events != nullptr) ? (cl_uint) events->size() : 0,
8739 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
8740 (event != nullptr) ? &tmp : nullptr),
8741 __ENQUEUE_UNMAP_MEM_OBJECT_ERR);
8742
8743 if (event != nullptr && err == CL_SUCCESS)
8744 *event = tmp;
8745
8746 return err;
8747 }
8748 #endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
8749
8750
8751 #if CL_HPP_TARGET_OPENCL_VERSION >= 210
8752 /**
8753 * Enqueues a command that will allow the host associate ranges within a set of
8754 * SVM allocations with a device.
8755 * @param sizes - The length from each pointer to migrate.
8756 */
8757 template<typename T>
enqueueMigrateSVM(const cl::vector<T * > & svmRawPointers,const cl::vector<size_type> & sizes,cl_mem_migration_flags flags=0,const vector<Event> * events=nullptr,Event * event=nullptr) const8758 cl_int enqueueMigrateSVM(
8759 const cl::vector<T*> &svmRawPointers,
8760 const cl::vector<size_type> &sizes,
8761 cl_mem_migration_flags flags = 0,
8762 const vector<Event>* events = nullptr,
8763 Event* event = nullptr) const
8764 {
8765 cl_event tmp;
8766 cl_int err = detail::errHandler(::clEnqueueSVMMigrateMem(
8767 object_,
8768 svmRawPointers.size(), static_cast<void**>(svmRawPointers.data()),
8769 sizes.data(), // array of sizes not passed
8770 flags,
8771 (events != nullptr) ? (cl_uint)events->size() : 0,
8772 (events != nullptr && events->size() > 0) ? (cl_event*)&events->front() : nullptr,
8773 (event != nullptr) ? &tmp : nullptr),
8774 __ENQUEUE_MIGRATE_SVM_ERR);
8775
8776 if (event != nullptr && err == CL_SUCCESS)
8777 *event = tmp;
8778
8779 return err;
8780 }
8781
8782 /**
8783 * Enqueues a command that will allow the host associate a set of SVM allocations with
8784 * a device.
8785 */
8786 template<typename T>
enqueueMigrateSVM(const cl::vector<T * > & svmRawPointers,cl_mem_migration_flags flags=0,const vector<Event> * events=nullptr,Event * event=nullptr) const8787 cl_int enqueueMigrateSVM(
8788 const cl::vector<T*> &svmRawPointers,
8789 cl_mem_migration_flags flags = 0,
8790 const vector<Event>* events = nullptr,
8791 Event* event = nullptr) const
8792 {
8793 return enqueueMigrateSVM(svmRawPointers, cl::vector<size_type>(svmRawPointers.size()), flags, events, event);
8794 }
8795
8796
8797 /**
8798 * Enqueues a command that will allow the host associate ranges within a set of
8799 * SVM allocations with a device.
8800 * @param sizes - The length from each pointer to migrate.
8801 */
8802 template<typename T, class D>
enqueueMigrateSVM(const cl::vector<cl::pointer<T,D>> & svmPointers,const cl::vector<size_type> & sizes,cl_mem_migration_flags flags=0,const vector<Event> * events=nullptr,Event * event=nullptr) const8803 cl_int enqueueMigrateSVM(
8804 const cl::vector<cl::pointer<T, D>> &svmPointers,
8805 const cl::vector<size_type> &sizes,
8806 cl_mem_migration_flags flags = 0,
8807 const vector<Event>* events = nullptr,
8808 Event* event = nullptr) const
8809 {
8810 cl::vector<void*> svmRawPointers;
8811 svmRawPointers.reserve(svmPointers.size());
8812 for (auto p : svmPointers) {
8813 svmRawPointers.push_back(static_cast<void*>(p.get()));
8814 }
8815
8816 return enqueueMigrateSVM(svmRawPointers, sizes, flags, events, event);
8817 }
8818
8819
8820 /**
8821 * Enqueues a command that will allow the host associate a set of SVM allocations with
8822 * a device.
8823 */
8824 template<typename T, class D>
enqueueMigrateSVM(const cl::vector<cl::pointer<T,D>> & svmPointers,cl_mem_migration_flags flags=0,const vector<Event> * events=nullptr,Event * event=nullptr) const8825 cl_int enqueueMigrateSVM(
8826 const cl::vector<cl::pointer<T, D>> &svmPointers,
8827 cl_mem_migration_flags flags = 0,
8828 const vector<Event>* events = nullptr,
8829 Event* event = nullptr) const
8830 {
8831 return enqueueMigrateSVM(svmPointers, cl::vector<size_type>(svmPointers.size()), flags, events, event);
8832 }
8833
8834 /**
8835 * Enqueues a command that will allow the host associate ranges within a set of
8836 * SVM allocations with a device.
8837 * @param sizes - The length from the beginning of each container to migrate.
8838 */
8839 template<typename T, class Alloc>
enqueueMigrateSVM(const cl::vector<cl::vector<T,Alloc>> & svmContainers,const cl::vector<size_type> & sizes,cl_mem_migration_flags flags=0,const vector<Event> * events=nullptr,Event * event=nullptr) const8840 cl_int enqueueMigrateSVM(
8841 const cl::vector<cl::vector<T, Alloc>> &svmContainers,
8842 const cl::vector<size_type> &sizes,
8843 cl_mem_migration_flags flags = 0,
8844 const vector<Event>* events = nullptr,
8845 Event* event = nullptr) const
8846 {
8847 cl::vector<void*> svmRawPointers;
8848 svmRawPointers.reserve(svmContainers.size());
8849 for (auto p : svmContainers) {
8850 svmRawPointers.push_back(static_cast<void*>(p.data()));
8851 }
8852
8853 return enqueueMigrateSVM(svmRawPointers, sizes, flags, events, event);
8854 }
8855
8856 /**
8857 * Enqueues a command that will allow the host associate a set of SVM allocations with
8858 * a device.
8859 */
8860 template<typename T, class Alloc>
enqueueMigrateSVM(const cl::vector<cl::vector<T,Alloc>> & svmContainers,cl_mem_migration_flags flags=0,const vector<Event> * events=nullptr,Event * event=nullptr) const8861 cl_int enqueueMigrateSVM(
8862 const cl::vector<cl::vector<T, Alloc>> &svmContainers,
8863 cl_mem_migration_flags flags = 0,
8864 const vector<Event>* events = nullptr,
8865 Event* event = nullptr) const
8866 {
8867 return enqueueMigrateSVM(svmContainers, cl::vector<size_type>(svmContainers.size()), flags, events, event);
8868 }
8869
8870 #endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 210
8871
enqueueNDRangeKernel(const Kernel & kernel,const NDRange & offset,const NDRange & global,const NDRange & local=NullRange,const vector<Event> * events=nullptr,Event * event=nullptr) const8872 cl_int enqueueNDRangeKernel(
8873 const Kernel& kernel,
8874 const NDRange& offset,
8875 const NDRange& global,
8876 const NDRange& local = NullRange,
8877 const vector<Event>* events = nullptr,
8878 Event* event = nullptr) const
8879 {
8880 cl_event tmp;
8881 cl_int err = detail::errHandler(
8882 ::clEnqueueNDRangeKernel(
8883 object_, kernel(), (cl_uint) global.dimensions(),
8884 offset.dimensions() != 0 ? (const size_type*) offset : nullptr,
8885 (const size_type*) global,
8886 local.dimensions() != 0 ? (const size_type*) local : nullptr,
8887 (events != nullptr) ? (cl_uint) events->size() : 0,
8888 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
8889 (event != nullptr) ? &tmp : nullptr),
8890 __ENQUEUE_NDRANGE_KERNEL_ERR);
8891
8892 if (event != nullptr && err == CL_SUCCESS)
8893 *event = tmp;
8894
8895 return err;
8896 }
8897
8898 #if defined(CL_USE_DEPRECATED_OPENCL_1_2_APIS)
enqueueTask(const Kernel & kernel,const vector<Event> * events=nullptr,Event * event=nullptr) const8899 CL_API_PREFIX__VERSION_1_2_DEPRECATED cl_int enqueueTask(
8900 const Kernel& kernel,
8901 const vector<Event>* events = nullptr,
8902 Event* event = nullptr) const CL_API_SUFFIX__VERSION_1_2_DEPRECATED
8903 {
8904 cl_event tmp;
8905 cl_int err = detail::errHandler(
8906 ::clEnqueueTask(
8907 object_, kernel(),
8908 (events != nullptr) ? (cl_uint) events->size() : 0,
8909 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
8910 (event != nullptr) ? &tmp : nullptr),
8911 __ENQUEUE_TASK_ERR);
8912
8913 if (event != nullptr && err == CL_SUCCESS)
8914 *event = tmp;
8915
8916 return err;
8917 }
8918 #endif // #if defined(CL_USE_DEPRECATED_OPENCL_1_2_APIS)
8919
enqueueNativeKernel(void (CL_CALLBACK * userFptr)(void *),std::pair<void *,size_type> args,const vector<Memory> * mem_objects=nullptr,const vector<const void * > * mem_locs=nullptr,const vector<Event> * events=nullptr,Event * event=nullptr) const8920 cl_int enqueueNativeKernel(
8921 void (CL_CALLBACK *userFptr)(void *),
8922 std::pair<void*, size_type> args,
8923 const vector<Memory>* mem_objects = nullptr,
8924 const vector<const void*>* mem_locs = nullptr,
8925 const vector<Event>* events = nullptr,
8926 Event* event = nullptr) const
8927 {
8928 cl_event tmp;
8929 cl_int err = detail::errHandler(
8930 ::clEnqueueNativeKernel(
8931 object_, userFptr, args.first, args.second,
8932 (mem_objects != nullptr) ? (cl_uint) mem_objects->size() : 0,
8933 (mem_objects->size() > 0 ) ? reinterpret_cast<const cl_mem *>(mem_objects->data()) : nullptr,
8934 (mem_locs != nullptr && mem_locs->size() > 0) ? (const void **) &mem_locs->front() : nullptr,
8935 (events != nullptr) ? (cl_uint) events->size() : 0,
8936 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
8937 (event != nullptr) ? &tmp : nullptr),
8938 __ENQUEUE_NATIVE_KERNEL);
8939
8940 if (event != nullptr && err == CL_SUCCESS)
8941 *event = tmp;
8942
8943 return err;
8944 }
8945
8946 /**
8947 * Deprecated APIs for 1.2
8948 */
8949 #if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
8950 CL_API_PREFIX__VERSION_1_1_DEPRECATED
enqueueMarker(Event * event=nullptr) const8951 cl_int enqueueMarker(Event* event = nullptr) const CL_API_SUFFIX__VERSION_1_1_DEPRECATED
8952 {
8953 cl_event tmp;
8954 cl_int err = detail::errHandler(
8955 ::clEnqueueMarker(
8956 object_,
8957 (event != nullptr) ? &tmp : nullptr),
8958 __ENQUEUE_MARKER_ERR);
8959
8960 if (event != nullptr && err == CL_SUCCESS)
8961 *event = tmp;
8962
8963 return err;
8964 }
8965
8966 CL_API_PREFIX__VERSION_1_1_DEPRECATED
enqueueWaitForEvents(const vector<Event> & events) const8967 cl_int enqueueWaitForEvents(const vector<Event>& events) const CL_API_SUFFIX__VERSION_1_1_DEPRECATED
8968 {
8969 return detail::errHandler(
8970 ::clEnqueueWaitForEvents(
8971 object_,
8972 (cl_uint) events.size(),
8973 events.size() > 0 ? (const cl_event*) &events.front() : nullptr),
8974 __ENQUEUE_WAIT_FOR_EVENTS_ERR);
8975 }
8976 #endif // defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
8977
enqueueAcquireGLObjects(const vector<Memory> * mem_objects=nullptr,const vector<Event> * events=nullptr,Event * event=nullptr) const8978 cl_int enqueueAcquireGLObjects(
8979 const vector<Memory>* mem_objects = nullptr,
8980 const vector<Event>* events = nullptr,
8981 Event* event = nullptr) const
8982 {
8983 cl_event tmp;
8984 cl_int err = detail::errHandler(
8985 ::clEnqueueAcquireGLObjects(
8986 object_,
8987 (mem_objects != nullptr) ? (cl_uint) mem_objects->size() : 0,
8988 (mem_objects != nullptr && mem_objects->size() > 0) ? (const cl_mem *) &mem_objects->front(): nullptr,
8989 (events != nullptr) ? (cl_uint) events->size() : 0,
8990 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
8991 (event != nullptr) ? &tmp : nullptr),
8992 __ENQUEUE_ACQUIRE_GL_ERR);
8993
8994 if (event != nullptr && err == CL_SUCCESS)
8995 *event = tmp;
8996
8997 return err;
8998 }
8999
enqueueReleaseGLObjects(const vector<Memory> * mem_objects=nullptr,const vector<Event> * events=nullptr,Event * event=nullptr) const9000 cl_int enqueueReleaseGLObjects(
9001 const vector<Memory>* mem_objects = nullptr,
9002 const vector<Event>* events = nullptr,
9003 Event* event = nullptr) const
9004 {
9005 cl_event tmp;
9006 cl_int err = detail::errHandler(
9007 ::clEnqueueReleaseGLObjects(
9008 object_,
9009 (mem_objects != nullptr) ? (cl_uint) mem_objects->size() : 0,
9010 (mem_objects != nullptr && mem_objects->size() > 0) ? (const cl_mem *) &mem_objects->front(): nullptr,
9011 (events != nullptr) ? (cl_uint) events->size() : 0,
9012 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
9013 (event != nullptr) ? &tmp : nullptr),
9014 __ENQUEUE_RELEASE_GL_ERR);
9015
9016 if (event != nullptr && err == CL_SUCCESS)
9017 *event = tmp;
9018
9019 return err;
9020 }
9021
9022 #if defined (CL_HPP_USE_DX_INTEROP)
9023 typedef CL_API_ENTRY cl_int (CL_API_CALL *PFN_clEnqueueAcquireD3D10ObjectsKHR)(
9024 cl_command_queue command_queue, cl_uint num_objects,
9025 const cl_mem* mem_objects, cl_uint num_events_in_wait_list,
9026 const cl_event* event_wait_list, cl_event* event);
9027 typedef CL_API_ENTRY cl_int (CL_API_CALL *PFN_clEnqueueReleaseD3D10ObjectsKHR)(
9028 cl_command_queue command_queue, cl_uint num_objects,
9029 const cl_mem* mem_objects, cl_uint num_events_in_wait_list,
9030 const cl_event* event_wait_list, cl_event* event);
9031
enqueueAcquireD3D10Objects(const vector<Memory> * mem_objects=nullptr,const vector<Event> * events=nullptr,Event * event=nullptr) const9032 cl_int enqueueAcquireD3D10Objects(
9033 const vector<Memory>* mem_objects = nullptr,
9034 const vector<Event>* events = nullptr,
9035 Event* event = nullptr) const
9036 {
9037 static PFN_clEnqueueAcquireD3D10ObjectsKHR pfn_clEnqueueAcquireD3D10ObjectsKHR = nullptr;
9038 #if CL_HPP_TARGET_OPENCL_VERSION >= 120
9039 cl_context context = getInfo<CL_QUEUE_CONTEXT>();
9040 cl::Device device(getInfo<CL_QUEUE_DEVICE>());
9041 cl_platform_id platform = device.getInfo<CL_DEVICE_PLATFORM>();
9042 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clEnqueueAcquireD3D10ObjectsKHR);
9043 #endif
9044 #if CL_HPP_MINIMUM_OPENCL_VERSION < 120
9045 CL_HPP_INIT_CL_EXT_FCN_PTR_(clEnqueueAcquireD3D10ObjectsKHR);
9046 #endif
9047
9048 cl_event tmp;
9049 cl_int err = detail::errHandler(
9050 pfn_clEnqueueAcquireD3D10ObjectsKHR(
9051 object_,
9052 (mem_objects != nullptr) ? (cl_uint) mem_objects->size() : 0,
9053 (mem_objects != nullptr && mem_objects->size() > 0) ? (const cl_mem *) &mem_objects->front(): nullptr,
9054 (events != nullptr) ? (cl_uint) events->size() : 0,
9055 (events != nullptr) ? (cl_event*) &events->front() : nullptr,
9056 (event != nullptr) ? &tmp : nullptr),
9057 __ENQUEUE_ACQUIRE_GL_ERR);
9058
9059 if (event != nullptr && err == CL_SUCCESS)
9060 *event = tmp;
9061
9062 return err;
9063 }
9064
enqueueReleaseD3D10Objects(const vector<Memory> * mem_objects=nullptr,const vector<Event> * events=nullptr,Event * event=nullptr) const9065 cl_int enqueueReleaseD3D10Objects(
9066 const vector<Memory>* mem_objects = nullptr,
9067 const vector<Event>* events = nullptr,
9068 Event* event = nullptr) const
9069 {
9070 static PFN_clEnqueueReleaseD3D10ObjectsKHR pfn_clEnqueueReleaseD3D10ObjectsKHR = nullptr;
9071 #if CL_HPP_TARGET_OPENCL_VERSION >= 120
9072 cl_context context = getInfo<CL_QUEUE_CONTEXT>();
9073 cl::Device device(getInfo<CL_QUEUE_DEVICE>());
9074 cl_platform_id platform = device.getInfo<CL_DEVICE_PLATFORM>();
9075 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clEnqueueReleaseD3D10ObjectsKHR);
9076 #endif
9077 #if CL_HPP_MINIMUM_OPENCL_VERSION < 120
9078 CL_HPP_INIT_CL_EXT_FCN_PTR_(clEnqueueReleaseD3D10ObjectsKHR);
9079 #endif
9080
9081 cl_event tmp;
9082 cl_int err = detail::errHandler(
9083 pfn_clEnqueueReleaseD3D10ObjectsKHR(
9084 object_,
9085 (mem_objects != nullptr) ? (cl_uint) mem_objects->size() : 0,
9086 (mem_objects != nullptr && mem_objects->size() > 0) ? (const cl_mem *) &mem_objects->front(): nullptr,
9087 (events != nullptr) ? (cl_uint) events->size() : 0,
9088 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
9089 (event != nullptr) ? &tmp : nullptr),
9090 __ENQUEUE_RELEASE_GL_ERR);
9091
9092 if (event != nullptr && err == CL_SUCCESS)
9093 *event = tmp;
9094
9095 return err;
9096 }
9097 #endif
9098
9099 /**
9100 * Deprecated APIs for 1.2
9101 */
9102 #if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
9103 CL_API_PREFIX__VERSION_1_1_DEPRECATED
enqueueBarrier() const9104 cl_int enqueueBarrier() const CL_API_SUFFIX__VERSION_1_1_DEPRECATED
9105 {
9106 return detail::errHandler(
9107 ::clEnqueueBarrier(object_),
9108 __ENQUEUE_BARRIER_ERR);
9109 }
9110 #endif // CL_USE_DEPRECATED_OPENCL_1_1_APIS
9111
flush() const9112 cl_int flush() const
9113 {
9114 return detail::errHandler(::clFlush(object_), __FLUSH_ERR);
9115 }
9116
finish() const9117 cl_int finish() const
9118 {
9119 return detail::errHandler(::clFinish(object_), __FINISH_ERR);
9120 }
9121
9122 #ifdef cl_khr_external_memory
enqueueAcquireExternalMemObjects(const vector<Memory> & mem_objects,const vector<Event> * events_wait=nullptr,Event * event=nullptr)9123 cl_int enqueueAcquireExternalMemObjects(
9124 const vector<Memory>& mem_objects,
9125 const vector<Event>* events_wait = nullptr,
9126 Event *event = nullptr)
9127 {
9128 cl_int err = CL_INVALID_OPERATION;
9129 cl_event tmp;
9130
9131 std::call_once(ext_memory_initialized_, initMemoryExtension, this->getInfo<CL_QUEUE_DEVICE>());
9132
9133 if (pfn_clEnqueueAcquireExternalMemObjectsKHR)
9134 {
9135 err = pfn_clEnqueueAcquireExternalMemObjectsKHR(
9136 object_,
9137 static_cast<cl_uint>(mem_objects.size()),
9138 (mem_objects.size() > 0) ? reinterpret_cast<const cl_mem *>(mem_objects.data()) : nullptr,
9139 (events_wait != nullptr) ? static_cast<cl_uint>(events_wait->size()) : 0,
9140 (events_wait != nullptr && events_wait->size() > 0) ? reinterpret_cast<const cl_event*>(events_wait->data()) : nullptr,
9141 &tmp);
9142 }
9143
9144 detail::errHandler(err, __ENQUEUE_ACQUIRE_EXTERNAL_MEMORY_ERR);
9145
9146 if (event != nullptr && err == CL_SUCCESS)
9147 *event = tmp;
9148
9149 return err;
9150 }
9151
enqueueReleaseExternalMemObjects(const vector<Memory> & mem_objects,const vector<Event> * events_wait=nullptr,Event * event=nullptr)9152 cl_int enqueueReleaseExternalMemObjects(
9153 const vector<Memory>& mem_objects,
9154 const vector<Event>* events_wait = nullptr,
9155 Event *event = nullptr)
9156 {
9157 cl_int err = CL_INVALID_OPERATION;
9158 cl_event tmp;
9159
9160 std::call_once(ext_memory_initialized_, initMemoryExtension, this->getInfo<CL_QUEUE_DEVICE>());
9161
9162 if (pfn_clEnqueueReleaseExternalMemObjectsKHR)
9163 {
9164 err = pfn_clEnqueueReleaseExternalMemObjectsKHR(
9165 object_,
9166 static_cast<cl_uint>(mem_objects.size()),
9167 (mem_objects.size() > 0) ? reinterpret_cast<const cl_mem *>(mem_objects.data()) : nullptr,
9168 (events_wait != nullptr) ? static_cast<cl_uint>(events_wait->size()) : 0,
9169 (events_wait != nullptr && events_wait->size() > 0) ? reinterpret_cast<const cl_event*>(events_wait->data()) : nullptr,
9170 &tmp);
9171 }
9172
9173 detail::errHandler(err, __ENQUEUE_RELEASE_EXTERNAL_MEMORY_ERR);
9174
9175 if (event != nullptr && err == CL_SUCCESS)
9176 *event = tmp;
9177
9178 return err;
9179 }
9180 #endif // cl_khr_external_memory && CL_HPP_TARGET_OPENCL_VERSION >= 300
9181
9182 #ifdef cl_khr_semaphore
9183 cl_int enqueueWaitSemaphores(
9184 const vector<Semaphore> &sema_objects,
9185 const vector<cl_semaphore_payload_khr> &sema_payloads = {},
9186 const vector<Event>* events_wait_list = nullptr,
9187 Event *event = nullptr) const;
9188
9189 cl_int enqueueSignalSemaphores(
9190 const vector<Semaphore> &sema_objects,
9191 const vector<cl_semaphore_payload_khr>& sema_payloads = {},
9192 const vector<Event>* events_wait_list = nullptr,
9193 Event* event = nullptr);
9194 #endif // cl_khr_semaphore
9195 }; // CommandQueue
9196
9197 #ifdef cl_khr_external_memory
9198 CL_HPP_DEFINE_STATIC_MEMBER_ std::once_flag CommandQueue::ext_memory_initialized_;
9199 #endif
9200
9201 CL_HPP_DEFINE_STATIC_MEMBER_ std::once_flag CommandQueue::default_initialized_;
9202 CL_HPP_DEFINE_STATIC_MEMBER_ CommandQueue CommandQueue::default_;
9203 CL_HPP_DEFINE_STATIC_MEMBER_ cl_int CommandQueue::default_error_ = CL_SUCCESS;
9204
9205
9206 #if CL_HPP_TARGET_OPENCL_VERSION >= 200
9207 enum class DeviceQueueProperties : cl_command_queue_properties
9208 {
9209 None = 0,
9210 Profiling = CL_QUEUE_PROFILING_ENABLE,
9211 };
9212
operator |(DeviceQueueProperties lhs,DeviceQueueProperties rhs)9213 inline DeviceQueueProperties operator|(DeviceQueueProperties lhs, DeviceQueueProperties rhs)
9214 {
9215 return static_cast<DeviceQueueProperties>(static_cast<cl_command_queue_properties>(lhs) | static_cast<cl_command_queue_properties>(rhs));
9216 }
9217
9218 /*! \class DeviceCommandQueue
9219 * \brief DeviceCommandQueue interface for device cl_command_queues.
9220 */
9221 class DeviceCommandQueue : public detail::Wrapper<cl_command_queue>
9222 {
9223 public:
9224
9225 /*!
9226 * Trivial empty constructor to create a null queue.
9227 */
DeviceCommandQueue()9228 DeviceCommandQueue() { }
9229
9230 /*!
9231 * Default construct device command queue on default context and device
9232 */
DeviceCommandQueue(DeviceQueueProperties properties,cl_int * err=nullptr)9233 DeviceCommandQueue(DeviceQueueProperties properties, cl_int* err = nullptr)
9234 {
9235 cl_int error;
9236 cl::Context context = cl::Context::getDefault();
9237 cl::Device device = cl::Device::getDefault();
9238
9239 cl_command_queue_properties mergedProperties =
9240 CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE | CL_QUEUE_ON_DEVICE | static_cast<cl_command_queue_properties>(properties);
9241
9242 cl_queue_properties queue_properties[] = {
9243 CL_QUEUE_PROPERTIES, mergedProperties, 0 };
9244 object_ = ::clCreateCommandQueueWithProperties(
9245 context(), device(), queue_properties, &error);
9246
9247 detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR);
9248 if (err != nullptr) {
9249 *err = error;
9250 }
9251 }
9252
9253 /*!
9254 * Create a device command queue for a specified device in the passed context.
9255 */
DeviceCommandQueue(const Context & context,const Device & device,DeviceQueueProperties properties=DeviceQueueProperties::None,cl_int * err=nullptr)9256 DeviceCommandQueue(
9257 const Context& context,
9258 const Device& device,
9259 DeviceQueueProperties properties = DeviceQueueProperties::None,
9260 cl_int* err = nullptr)
9261 {
9262 cl_int error;
9263
9264 cl_command_queue_properties mergedProperties =
9265 CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE | CL_QUEUE_ON_DEVICE | static_cast<cl_command_queue_properties>(properties);
9266 cl_queue_properties queue_properties[] = {
9267 CL_QUEUE_PROPERTIES, mergedProperties, 0 };
9268 object_ = ::clCreateCommandQueueWithProperties(
9269 context(), device(), queue_properties, &error);
9270
9271 detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR);
9272 if (err != nullptr) {
9273 *err = error;
9274 }
9275 }
9276
9277 /*!
9278 * Create a device command queue for a specified device in the passed context.
9279 */
DeviceCommandQueue(const Context & context,const Device & device,cl_uint queueSize,DeviceQueueProperties properties=DeviceQueueProperties::None,cl_int * err=nullptr)9280 DeviceCommandQueue(
9281 const Context& context,
9282 const Device& device,
9283 cl_uint queueSize,
9284 DeviceQueueProperties properties = DeviceQueueProperties::None,
9285 cl_int* err = nullptr)
9286 {
9287 cl_int error;
9288
9289 cl_command_queue_properties mergedProperties =
9290 CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE | CL_QUEUE_ON_DEVICE | static_cast<cl_command_queue_properties>(properties);
9291 cl_queue_properties queue_properties[] = {
9292 CL_QUEUE_PROPERTIES, mergedProperties,
9293 CL_QUEUE_SIZE, queueSize,
9294 0 };
9295 object_ = ::clCreateCommandQueueWithProperties(
9296 context(), device(), queue_properties, &error);
9297
9298 detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR);
9299 if (err != nullptr) {
9300 *err = error;
9301 }
9302 }
9303
9304 /*! \brief Constructor from cl_command_queue - takes ownership.
9305 *
9306 * \param retainObject will cause the constructor to retain its cl object.
9307 * Defaults to false to maintain compatibility with
9308 * earlier versions.
9309 */
DeviceCommandQueue(const cl_command_queue & commandQueue,bool retainObject=false)9310 explicit DeviceCommandQueue(const cl_command_queue& commandQueue, bool retainObject = false) :
9311 detail::Wrapper<cl_type>(commandQueue, retainObject) { }
9312
operator =(const cl_command_queue & rhs)9313 DeviceCommandQueue& operator = (const cl_command_queue& rhs)
9314 {
9315 detail::Wrapper<cl_type>::operator=(rhs);
9316 return *this;
9317 }
9318
9319 template <typename T>
getInfo(cl_command_queue_info name,T * param) const9320 cl_int getInfo(cl_command_queue_info name, T* param) const
9321 {
9322 return detail::errHandler(
9323 detail::getInfo(
9324 &::clGetCommandQueueInfo, object_, name, param),
9325 __GET_COMMAND_QUEUE_INFO_ERR);
9326 }
9327
9328 template <cl_command_queue_info name> typename
9329 detail::param_traits<detail::cl_command_queue_info, name>::param_type
getInfo(cl_int * err=nullptr) const9330 getInfo(cl_int* err = nullptr) const
9331 {
9332 typename detail::param_traits<
9333 detail::cl_command_queue_info, name>::param_type param;
9334 cl_int result = getInfo(name, ¶m);
9335 if (err != nullptr) {
9336 *err = result;
9337 }
9338 return param;
9339 }
9340
9341 /*!
9342 * Create a new default device command queue for the default device,
9343 * in the default context and of the default size.
9344 * If there is already a default queue for the specified device this
9345 * function will return the pre-existing queue.
9346 */
makeDefault(cl_int * err=nullptr)9347 static DeviceCommandQueue makeDefault(
9348 cl_int *err = nullptr)
9349 {
9350 cl_int error;
9351 cl::Context context = cl::Context::getDefault();
9352 cl::Device device = cl::Device::getDefault();
9353
9354 cl_command_queue_properties properties =
9355 CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE | CL_QUEUE_ON_DEVICE | CL_QUEUE_ON_DEVICE_DEFAULT;
9356 cl_queue_properties queue_properties[] = {
9357 CL_QUEUE_PROPERTIES, properties,
9358 0 };
9359 DeviceCommandQueue deviceQueue(
9360 ::clCreateCommandQueueWithProperties(
9361 context(), device(), queue_properties, &error));
9362
9363 detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR);
9364 if (err != nullptr) {
9365 *err = error;
9366 }
9367
9368 return deviceQueue;
9369 }
9370
9371 /*!
9372 * Create a new default device command queue for the specified device
9373 * and of the default size.
9374 * If there is already a default queue for the specified device this
9375 * function will return the pre-existing queue.
9376 */
makeDefault(const Context & context,const Device & device,cl_int * err=nullptr)9377 static DeviceCommandQueue makeDefault(
9378 const Context &context, const Device &device, cl_int *err = nullptr)
9379 {
9380 cl_int error;
9381
9382 cl_command_queue_properties properties =
9383 CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE | CL_QUEUE_ON_DEVICE | CL_QUEUE_ON_DEVICE_DEFAULT;
9384 cl_queue_properties queue_properties[] = {
9385 CL_QUEUE_PROPERTIES, properties,
9386 0 };
9387 DeviceCommandQueue deviceQueue(
9388 ::clCreateCommandQueueWithProperties(
9389 context(), device(), queue_properties, &error));
9390
9391 detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR);
9392 if (err != nullptr) {
9393 *err = error;
9394 }
9395
9396 return deviceQueue;
9397 }
9398
9399 /*!
9400 * Create a new default device command queue for the specified device
9401 * and of the requested size in bytes.
9402 * If there is already a default queue for the specified device this
9403 * function will return the pre-existing queue.
9404 */
makeDefault(const Context & context,const Device & device,cl_uint queueSize,cl_int * err=nullptr)9405 static DeviceCommandQueue makeDefault(
9406 const Context &context, const Device &device, cl_uint queueSize, cl_int *err = nullptr)
9407 {
9408 cl_int error;
9409
9410 cl_command_queue_properties properties =
9411 CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE | CL_QUEUE_ON_DEVICE | CL_QUEUE_ON_DEVICE_DEFAULT;
9412 cl_queue_properties queue_properties[] = {
9413 CL_QUEUE_PROPERTIES, properties,
9414 CL_QUEUE_SIZE, queueSize,
9415 0 };
9416 DeviceCommandQueue deviceQueue(
9417 ::clCreateCommandQueueWithProperties(
9418 context(), device(), queue_properties, &error));
9419
9420 detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR);
9421 if (err != nullptr) {
9422 *err = error;
9423 }
9424
9425 return deviceQueue;
9426 }
9427
9428
9429
9430 #if CL_HPP_TARGET_OPENCL_VERSION >= 210
9431 /*!
9432 * Modify the default device command queue to be used for subsequent kernels.
9433 * This can update the default command queue for a device repeatedly to account
9434 * for kernels that rely on the default.
9435 * @return updated default device command queue.
9436 */
updateDefault(const Context & context,const Device & device,const DeviceCommandQueue & default_queue,cl_int * err=nullptr)9437 static DeviceCommandQueue updateDefault(const Context &context, const Device &device, const DeviceCommandQueue &default_queue, cl_int *err = nullptr)
9438 {
9439 cl_int error;
9440 error = clSetDefaultDeviceCommandQueue(context.get(), device.get(), default_queue.get());
9441
9442 detail::errHandler(error, __SET_DEFAULT_DEVICE_COMMAND_QUEUE_ERR);
9443 if (err != nullptr) {
9444 *err = error;
9445 }
9446 return default_queue;
9447 }
9448
9449 /*!
9450 * Return the current default command queue for the specified command queue
9451 */
getDefault(const CommandQueue & queue,cl_int * err=nullptr)9452 static DeviceCommandQueue getDefault(const CommandQueue &queue, cl_int * err = nullptr)
9453 {
9454 return queue.getInfo<CL_QUEUE_DEVICE_DEFAULT>(err);
9455 }
9456
9457 #endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 210
9458 }; // DeviceCommandQueue
9459
9460 namespace detail
9461 {
9462 // Specialization for device command queue
9463 template <>
9464 struct KernelArgumentHandler<cl::DeviceCommandQueue, void>
9465 {
sizecl::detail::KernelArgumentHandler9466 static size_type size(const cl::DeviceCommandQueue&) { return sizeof(cl_command_queue); }
ptrcl::detail::KernelArgumentHandler9467 static const cl_command_queue* ptr(const cl::DeviceCommandQueue& value) { return &(value()); }
9468 };
9469 } // namespace detail
9470
9471 #endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 200
9472
9473
9474 template< typename IteratorType >
Buffer(const Context & context,IteratorType startIterator,IteratorType endIterator,bool readOnly,bool useHostPtr,cl_int * err)9475 Buffer::Buffer(
9476 const Context &context,
9477 IteratorType startIterator,
9478 IteratorType endIterator,
9479 bool readOnly,
9480 bool useHostPtr,
9481 cl_int* err)
9482 {
9483 typedef typename std::iterator_traits<IteratorType>::value_type DataType;
9484 cl_int error;
9485
9486 cl_mem_flags flags = 0;
9487 if( readOnly ) {
9488 flags |= CL_MEM_READ_ONLY;
9489 }
9490 else {
9491 flags |= CL_MEM_READ_WRITE;
9492 }
9493 if( useHostPtr ) {
9494 flags |= CL_MEM_USE_HOST_PTR;
9495 }
9496
9497 size_type size = sizeof(DataType)*(endIterator - startIterator);
9498
9499 if( useHostPtr ) {
9500 object_ = ::clCreateBuffer(context(), flags, size, const_cast<DataType*>(&*startIterator), &error);
9501 } else {
9502 object_ = ::clCreateBuffer(context(), flags, size, 0, &error);
9503 }
9504
9505 detail::errHandler(error, __CREATE_BUFFER_ERR);
9506 if (err != nullptr) {
9507 *err = error;
9508 }
9509
9510 if( !useHostPtr ) {
9511 CommandQueue queue(context, 0, &error);
9512 detail::errHandler(error, __CREATE_BUFFER_ERR);
9513 if (err != nullptr) {
9514 *err = error;
9515 }
9516
9517 error = cl::copy(queue, startIterator, endIterator, *this);
9518 detail::errHandler(error, __CREATE_BUFFER_ERR);
9519 if (err != nullptr) {
9520 *err = error;
9521 }
9522 }
9523 }
9524
9525 template< typename IteratorType >
Buffer(const CommandQueue & queue,IteratorType startIterator,IteratorType endIterator,bool readOnly,bool useHostPtr,cl_int * err)9526 Buffer::Buffer(
9527 const CommandQueue &queue,
9528 IteratorType startIterator,
9529 IteratorType endIterator,
9530 bool readOnly,
9531 bool useHostPtr,
9532 cl_int* err)
9533 {
9534 typedef typename std::iterator_traits<IteratorType>::value_type DataType;
9535 cl_int error;
9536
9537 cl_mem_flags flags = 0;
9538 if (readOnly) {
9539 flags |= CL_MEM_READ_ONLY;
9540 }
9541 else {
9542 flags |= CL_MEM_READ_WRITE;
9543 }
9544 if (useHostPtr) {
9545 flags |= CL_MEM_USE_HOST_PTR;
9546 }
9547
9548 size_type size = sizeof(DataType)*(endIterator - startIterator);
9549
9550 Context context = queue.getInfo<CL_QUEUE_CONTEXT>();
9551
9552 if (useHostPtr) {
9553 object_ = ::clCreateBuffer(context(), flags, size, const_cast<DataType*>(&*startIterator), &error);
9554 }
9555 else {
9556 object_ = ::clCreateBuffer(context(), flags, size, 0, &error);
9557 }
9558
9559 detail::errHandler(error, __CREATE_BUFFER_ERR);
9560 if (err != nullptr) {
9561 *err = error;
9562 }
9563
9564 if (!useHostPtr) {
9565 error = cl::copy(queue, startIterator, endIterator, *this);
9566 detail::errHandler(error, __CREATE_BUFFER_ERR);
9567 if (err != nullptr) {
9568 *err = error;
9569 }
9570 }
9571 }
9572
enqueueReadBuffer(const Buffer & buffer,cl_bool blocking,size_type offset,size_type size,void * ptr,const vector<Event> * events=nullptr,Event * event=nullptr)9573 inline cl_int enqueueReadBuffer(
9574 const Buffer& buffer,
9575 cl_bool blocking,
9576 size_type offset,
9577 size_type size,
9578 void* ptr,
9579 const vector<Event>* events = nullptr,
9580 Event* event = nullptr)
9581 {
9582 cl_int error;
9583 CommandQueue queue = CommandQueue::getDefault(&error);
9584
9585 if (error != CL_SUCCESS) {
9586 return error;
9587 }
9588
9589 return queue.enqueueReadBuffer(buffer, blocking, offset, size, ptr, events, event);
9590 }
9591
enqueueWriteBuffer(const Buffer & buffer,cl_bool blocking,size_type offset,size_type size,const void * ptr,const vector<Event> * events=nullptr,Event * event=nullptr)9592 inline cl_int enqueueWriteBuffer(
9593 const Buffer& buffer,
9594 cl_bool blocking,
9595 size_type offset,
9596 size_type size,
9597 const void* ptr,
9598 const vector<Event>* events = nullptr,
9599 Event* event = nullptr)
9600 {
9601 cl_int error;
9602 CommandQueue queue = CommandQueue::getDefault(&error);
9603
9604 if (error != CL_SUCCESS) {
9605 return error;
9606 }
9607
9608 return queue.enqueueWriteBuffer(buffer, blocking, offset, size, ptr, events, event);
9609 }
9610
enqueueMapBuffer(const Buffer & buffer,cl_bool blocking,cl_map_flags flags,size_type offset,size_type size,const vector<Event> * events=nullptr,Event * event=nullptr,cl_int * err=nullptr)9611 inline void* enqueueMapBuffer(
9612 const Buffer& buffer,
9613 cl_bool blocking,
9614 cl_map_flags flags,
9615 size_type offset,
9616 size_type size,
9617 const vector<Event>* events = nullptr,
9618 Event* event = nullptr,
9619 cl_int* err = nullptr)
9620 {
9621 cl_int error;
9622 CommandQueue queue = CommandQueue::getDefault(&error);
9623 detail::errHandler(error, __ENQUEUE_MAP_BUFFER_ERR);
9624 if (err != nullptr) {
9625 *err = error;
9626 }
9627
9628 void * result = ::clEnqueueMapBuffer(
9629 queue(), buffer(), blocking, flags, offset, size,
9630 (events != nullptr) ? (cl_uint) events->size() : 0,
9631 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
9632 (cl_event*) event,
9633 &error);
9634
9635 detail::errHandler(error, __ENQUEUE_MAP_BUFFER_ERR);
9636 if (err != nullptr) {
9637 *err = error;
9638 }
9639 return result;
9640 }
9641
9642
9643 #if CL_HPP_TARGET_OPENCL_VERSION >= 200
9644 /**
9645 * Enqueues to the default queue a command that will allow the host to
9646 * update a region of a coarse-grained SVM buffer.
9647 * This variant takes a raw SVM pointer.
9648 */
9649 template<typename T>
enqueueMapSVM(T * ptr,cl_bool blocking,cl_map_flags flags,size_type size,const vector<Event> * events,Event * event)9650 inline cl_int enqueueMapSVM(
9651 T* ptr,
9652 cl_bool blocking,
9653 cl_map_flags flags,
9654 size_type size,
9655 const vector<Event>* events,
9656 Event* event)
9657 {
9658 cl_int error;
9659 CommandQueue queue = CommandQueue::getDefault(&error);
9660 if (error != CL_SUCCESS) {
9661 return detail::errHandler(error, __ENQUEUE_MAP_SVM_ERR);
9662 }
9663
9664 return queue.enqueueMapSVM(
9665 ptr, blocking, flags, size, events, event);
9666 }
9667
9668 /**
9669 * Enqueues to the default queue a command that will allow the host to
9670 * update a region of a coarse-grained SVM buffer.
9671 * This variant takes a cl::pointer instance.
9672 */
9673 template<typename T, class D>
enqueueMapSVM(cl::pointer<T,D> & ptr,cl_bool blocking,cl_map_flags flags,size_type size,const vector<Event> * events=nullptr,Event * event=nullptr)9674 inline cl_int enqueueMapSVM(
9675 cl::pointer<T, D> &ptr,
9676 cl_bool blocking,
9677 cl_map_flags flags,
9678 size_type size,
9679 const vector<Event>* events = nullptr,
9680 Event* event = nullptr)
9681 {
9682 cl_int error;
9683 CommandQueue queue = CommandQueue::getDefault(&error);
9684 if (error != CL_SUCCESS) {
9685 return detail::errHandler(error, __ENQUEUE_MAP_BUFFER_ERR);
9686 }
9687
9688 return queue.enqueueMapSVM(
9689 ptr, blocking, flags, size, events, event);
9690 }
9691
9692 /**
9693 * Enqueues to the default queue a command that will allow the host to
9694 * update a region of a coarse-grained SVM buffer.
9695 * This variant takes a cl::vector instance.
9696 */
9697 template<typename T, class Alloc>
enqueueMapSVM(cl::vector<T,Alloc> & container,cl_bool blocking,cl_map_flags flags,const vector<Event> * events=nullptr,Event * event=nullptr)9698 inline cl_int enqueueMapSVM(
9699 cl::vector<T, Alloc> &container,
9700 cl_bool blocking,
9701 cl_map_flags flags,
9702 const vector<Event>* events = nullptr,
9703 Event* event = nullptr)
9704 {
9705 cl_int error;
9706 CommandQueue queue = CommandQueue::getDefault(&error);
9707 if (error != CL_SUCCESS) {
9708 return detail::errHandler(error, __ENQUEUE_MAP_SVM_ERR);
9709 }
9710
9711 return queue.enqueueMapSVM(
9712 container, blocking, flags, events, event);
9713 }
9714
9715 #endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 200
9716
enqueueUnmapMemObject(const Memory & memory,void * mapped_ptr,const vector<Event> * events=nullptr,Event * event=nullptr)9717 inline cl_int enqueueUnmapMemObject(
9718 const Memory& memory,
9719 void* mapped_ptr,
9720 const vector<Event>* events = nullptr,
9721 Event* event = nullptr)
9722 {
9723 cl_int error;
9724 CommandQueue queue = CommandQueue::getDefault(&error);
9725 detail::errHandler(error, __ENQUEUE_MAP_BUFFER_ERR);
9726 if (error != CL_SUCCESS) {
9727 return error;
9728 }
9729
9730 cl_event tmp;
9731 cl_int err = detail::errHandler(
9732 ::clEnqueueUnmapMemObject(
9733 queue(), memory(), mapped_ptr,
9734 (events != nullptr) ? (cl_uint)events->size() : 0,
9735 (events != nullptr && events->size() > 0) ? (cl_event*)&events->front() : nullptr,
9736 (event != nullptr) ? &tmp : nullptr),
9737 __ENQUEUE_UNMAP_MEM_OBJECT_ERR);
9738
9739 if (event != nullptr && err == CL_SUCCESS)
9740 *event = tmp;
9741
9742 return err;
9743 }
9744
9745 #if CL_HPP_TARGET_OPENCL_VERSION >= 200
9746 /**
9747 * Enqueues to the default queue a command that will release a coarse-grained
9748 * SVM buffer back to the OpenCL runtime.
9749 * This variant takes a raw SVM pointer.
9750 */
9751 template<typename T>
enqueueUnmapSVM(T * ptr,const vector<Event> * events=nullptr,Event * event=nullptr)9752 inline cl_int enqueueUnmapSVM(
9753 T* ptr,
9754 const vector<Event>* events = nullptr,
9755 Event* event = nullptr)
9756 {
9757 cl_int error;
9758 CommandQueue queue = CommandQueue::getDefault(&error);
9759 if (error != CL_SUCCESS) {
9760 return detail::errHandler(error, __ENQUEUE_UNMAP_SVM_ERR);
9761 }
9762
9763 return detail::errHandler(queue.enqueueUnmapSVM(ptr, events, event),
9764 __ENQUEUE_UNMAP_SVM_ERR);
9765
9766 }
9767
9768 /**
9769 * Enqueues to the default queue a command that will release a coarse-grained
9770 * SVM buffer back to the OpenCL runtime.
9771 * This variant takes a cl::pointer instance.
9772 */
9773 template<typename T, class D>
enqueueUnmapSVM(cl::pointer<T,D> & ptr,const vector<Event> * events=nullptr,Event * event=nullptr)9774 inline cl_int enqueueUnmapSVM(
9775 cl::pointer<T, D> &ptr,
9776 const vector<Event>* events = nullptr,
9777 Event* event = nullptr)
9778 {
9779 cl_int error;
9780 CommandQueue queue = CommandQueue::getDefault(&error);
9781 if (error != CL_SUCCESS) {
9782 return detail::errHandler(error, __ENQUEUE_UNMAP_SVM_ERR);
9783 }
9784
9785 return detail::errHandler(queue.enqueueUnmapSVM(ptr, events, event),
9786 __ENQUEUE_UNMAP_SVM_ERR);
9787 }
9788
9789 /**
9790 * Enqueues to the default queue a command that will release a coarse-grained
9791 * SVM buffer back to the OpenCL runtime.
9792 * This variant takes a cl::vector instance.
9793 */
9794 template<typename T, class Alloc>
enqueueUnmapSVM(cl::vector<T,Alloc> & container,const vector<Event> * events=nullptr,Event * event=nullptr)9795 inline cl_int enqueueUnmapSVM(
9796 cl::vector<T, Alloc> &container,
9797 const vector<Event>* events = nullptr,
9798 Event* event = nullptr)
9799 {
9800 cl_int error;
9801 CommandQueue queue = CommandQueue::getDefault(&error);
9802 if (error != CL_SUCCESS) {
9803 return detail::errHandler(error, __ENQUEUE_UNMAP_SVM_ERR);
9804 }
9805
9806 return detail::errHandler(queue.enqueueUnmapSVM(container, events, event),
9807 __ENQUEUE_UNMAP_SVM_ERR);
9808 }
9809
9810 #endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 200
9811
enqueueCopyBuffer(const Buffer & src,const Buffer & dst,size_type src_offset,size_type dst_offset,size_type size,const vector<Event> * events=nullptr,Event * event=nullptr)9812 inline cl_int enqueueCopyBuffer(
9813 const Buffer& src,
9814 const Buffer& dst,
9815 size_type src_offset,
9816 size_type dst_offset,
9817 size_type size,
9818 const vector<Event>* events = nullptr,
9819 Event* event = nullptr)
9820 {
9821 cl_int error;
9822 CommandQueue queue = CommandQueue::getDefault(&error);
9823
9824 if (error != CL_SUCCESS) {
9825 return error;
9826 }
9827
9828 return queue.enqueueCopyBuffer(src, dst, src_offset, dst_offset, size, events, event);
9829 }
9830
9831 /**
9832 * Blocking copy operation between iterators and a buffer.
9833 * Host to Device.
9834 * Uses default command queue.
9835 */
9836 template< typename IteratorType >
copy(IteratorType startIterator,IteratorType endIterator,cl::Buffer & buffer)9837 inline cl_int copy( IteratorType startIterator, IteratorType endIterator, cl::Buffer &buffer )
9838 {
9839 cl_int error;
9840 CommandQueue queue = CommandQueue::getDefault(&error);
9841 if (error != CL_SUCCESS)
9842 return error;
9843
9844 return cl::copy(queue, startIterator, endIterator, buffer);
9845 }
9846
9847 /**
9848 * Blocking copy operation between iterators and a buffer.
9849 * Device to Host.
9850 * Uses default command queue.
9851 */
9852 template< typename IteratorType >
copy(const cl::Buffer & buffer,IteratorType startIterator,IteratorType endIterator)9853 inline cl_int copy( const cl::Buffer &buffer, IteratorType startIterator, IteratorType endIterator )
9854 {
9855 cl_int error;
9856 CommandQueue queue = CommandQueue::getDefault(&error);
9857 if (error != CL_SUCCESS)
9858 return error;
9859
9860 return cl::copy(queue, buffer, startIterator, endIterator);
9861 }
9862
9863 /**
9864 * Blocking copy operation between iterators and a buffer.
9865 * Host to Device.
9866 * Uses specified queue.
9867 */
9868 template< typename IteratorType >
copy(const CommandQueue & queue,IteratorType startIterator,IteratorType endIterator,cl::Buffer & buffer)9869 inline cl_int copy( const CommandQueue &queue, IteratorType startIterator, IteratorType endIterator, cl::Buffer &buffer )
9870 {
9871 typedef typename std::iterator_traits<IteratorType>::value_type DataType;
9872 cl_int error;
9873
9874 size_type length = endIterator-startIterator;
9875 size_type byteLength = length*sizeof(DataType);
9876
9877 DataType *pointer =
9878 static_cast<DataType*>(queue.enqueueMapBuffer(buffer, CL_TRUE, CL_MAP_WRITE, 0, byteLength, 0, 0, &error));
9879 // if exceptions enabled, enqueueMapBuffer will throw
9880 if( error != CL_SUCCESS ) {
9881 return error;
9882 }
9883 #if defined(_MSC_VER)
9884 std::copy(
9885 startIterator,
9886 endIterator,
9887 stdext::checked_array_iterator<DataType*>(
9888 pointer, length));
9889 #else
9890 std::copy(startIterator, endIterator, pointer);
9891 #endif
9892 Event endEvent;
9893 error = queue.enqueueUnmapMemObject(buffer, pointer, 0, &endEvent);
9894 // if exceptions enabled, enqueueUnmapMemObject will throw
9895 if( error != CL_SUCCESS ) {
9896 return error;
9897 }
9898 endEvent.wait();
9899 return CL_SUCCESS;
9900 }
9901
9902 /**
9903 * Blocking copy operation between iterators and a buffer.
9904 * Device to Host.
9905 * Uses specified queue.
9906 */
9907 template< typename IteratorType >
copy(const CommandQueue & queue,const cl::Buffer & buffer,IteratorType startIterator,IteratorType endIterator)9908 inline cl_int copy( const CommandQueue &queue, const cl::Buffer &buffer, IteratorType startIterator, IteratorType endIterator )
9909 {
9910 typedef typename std::iterator_traits<IteratorType>::value_type DataType;
9911 cl_int error;
9912
9913 size_type length = endIterator-startIterator;
9914 size_type byteLength = length*sizeof(DataType);
9915
9916 DataType *pointer =
9917 static_cast<DataType*>(queue.enqueueMapBuffer(buffer, CL_TRUE, CL_MAP_READ, 0, byteLength, 0, 0, &error));
9918 // if exceptions enabled, enqueueMapBuffer will throw
9919 if( error != CL_SUCCESS ) {
9920 return error;
9921 }
9922 std::copy(pointer, pointer + length, startIterator);
9923 Event endEvent;
9924 error = queue.enqueueUnmapMemObject(buffer, pointer, 0, &endEvent);
9925 // if exceptions enabled, enqueueUnmapMemObject will throw
9926 if( error != CL_SUCCESS ) {
9927 return error;
9928 }
9929 endEvent.wait();
9930 return CL_SUCCESS;
9931 }
9932
9933
9934 #if CL_HPP_TARGET_OPENCL_VERSION >= 200
9935 /**
9936 * Blocking SVM map operation - performs a blocking map underneath.
9937 */
9938 template<typename T, class Alloc>
mapSVM(cl::vector<T,Alloc> & container)9939 inline cl_int mapSVM(cl::vector<T, Alloc> &container)
9940 {
9941 return enqueueMapSVM(container, CL_TRUE, CL_MAP_READ | CL_MAP_WRITE);
9942 }
9943
9944 /**
9945 * Blocking SVM map operation - performs a blocking map underneath.
9946 */
9947 template<typename T, class Alloc>
unmapSVM(cl::vector<T,Alloc> & container)9948 inline cl_int unmapSVM(cl::vector<T, Alloc> &container)
9949 {
9950 return enqueueUnmapSVM(container);
9951 }
9952
9953 #endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 200
9954
9955 #if CL_HPP_TARGET_OPENCL_VERSION >= 110
enqueueReadBufferRect(const Buffer & buffer,cl_bool blocking,const array<size_type,3> & buffer_offset,const array<size_type,3> & host_offset,const array<size_type,3> & region,size_type buffer_row_pitch,size_type buffer_slice_pitch,size_type host_row_pitch,size_type host_slice_pitch,void * ptr,const vector<Event> * events=nullptr,Event * event=nullptr)9956 inline cl_int enqueueReadBufferRect(
9957 const Buffer& buffer,
9958 cl_bool blocking,
9959 const array<size_type, 3>& buffer_offset,
9960 const array<size_type, 3>& host_offset,
9961 const array<size_type, 3>& region,
9962 size_type buffer_row_pitch,
9963 size_type buffer_slice_pitch,
9964 size_type host_row_pitch,
9965 size_type host_slice_pitch,
9966 void *ptr,
9967 const vector<Event>* events = nullptr,
9968 Event* event = nullptr)
9969 {
9970 cl_int error;
9971 CommandQueue queue = CommandQueue::getDefault(&error);
9972
9973 if (error != CL_SUCCESS) {
9974 return error;
9975 }
9976
9977 return queue.enqueueReadBufferRect(
9978 buffer,
9979 blocking,
9980 buffer_offset,
9981 host_offset,
9982 region,
9983 buffer_row_pitch,
9984 buffer_slice_pitch,
9985 host_row_pitch,
9986 host_slice_pitch,
9987 ptr,
9988 events,
9989 event);
9990 }
9991
enqueueReadBufferRect(const Buffer & buffer,cl_bool blocking,const array<size_type,2> & buffer_offset,const array<size_type,2> & host_offset,const array<size_type,2> & region,size_type buffer_row_pitch,size_type buffer_slice_pitch,size_type host_row_pitch,size_type host_slice_pitch,void * ptr,const vector<Event> * events=nullptr,Event * event=nullptr)9992 inline cl_int enqueueReadBufferRect(
9993 const Buffer& buffer,
9994 cl_bool blocking,
9995 const array<size_type, 2>& buffer_offset,
9996 const array<size_type, 2>& host_offset,
9997 const array<size_type, 2>& region,
9998 size_type buffer_row_pitch,
9999 size_type buffer_slice_pitch,
10000 size_type host_row_pitch,
10001 size_type host_slice_pitch,
10002 void* ptr,
10003 const vector<Event>* events = nullptr,
10004 Event* event = nullptr)
10005 {
10006 return enqueueReadBufferRect(
10007 buffer,
10008 blocking,
10009 { buffer_offset[0], buffer_offset[1], 0 },
10010 { host_offset[0], host_offset[1], 0 },
10011 { region[0], region[1], 1 },
10012 buffer_row_pitch,
10013 buffer_slice_pitch,
10014 host_row_pitch,
10015 host_slice_pitch,
10016 ptr,
10017 events,
10018 event);
10019 }
10020
enqueueWriteBufferRect(const Buffer & buffer,cl_bool blocking,const array<size_type,3> & buffer_offset,const array<size_type,3> & host_offset,const array<size_type,3> & region,size_type buffer_row_pitch,size_type buffer_slice_pitch,size_type host_row_pitch,size_type host_slice_pitch,const void * ptr,const vector<Event> * events=nullptr,Event * event=nullptr)10021 inline cl_int enqueueWriteBufferRect(
10022 const Buffer& buffer,
10023 cl_bool blocking,
10024 const array<size_type, 3>& buffer_offset,
10025 const array<size_type, 3>& host_offset,
10026 const array<size_type, 3>& region,
10027 size_type buffer_row_pitch,
10028 size_type buffer_slice_pitch,
10029 size_type host_row_pitch,
10030 size_type host_slice_pitch,
10031 const void *ptr,
10032 const vector<Event>* events = nullptr,
10033 Event* event = nullptr)
10034 {
10035 cl_int error;
10036 CommandQueue queue = CommandQueue::getDefault(&error);
10037
10038 if (error != CL_SUCCESS) {
10039 return error;
10040 }
10041
10042 return queue.enqueueWriteBufferRect(
10043 buffer,
10044 blocking,
10045 buffer_offset,
10046 host_offset,
10047 region,
10048 buffer_row_pitch,
10049 buffer_slice_pitch,
10050 host_row_pitch,
10051 host_slice_pitch,
10052 ptr,
10053 events,
10054 event);
10055 }
10056
enqueueWriteBufferRect(const Buffer & buffer,cl_bool blocking,const array<size_type,2> & buffer_offset,const array<size_type,2> & host_offset,const array<size_type,2> & region,size_type buffer_row_pitch,size_type buffer_slice_pitch,size_type host_row_pitch,size_type host_slice_pitch,const void * ptr,const vector<Event> * events=nullptr,Event * event=nullptr)10057 inline cl_int enqueueWriteBufferRect(
10058 const Buffer& buffer,
10059 cl_bool blocking,
10060 const array<size_type, 2>& buffer_offset,
10061 const array<size_type, 2>& host_offset,
10062 const array<size_type, 2>& region,
10063 size_type buffer_row_pitch,
10064 size_type buffer_slice_pitch,
10065 size_type host_row_pitch,
10066 size_type host_slice_pitch,
10067 const void* ptr,
10068 const vector<Event>* events = nullptr,
10069 Event* event = nullptr)
10070 {
10071 return enqueueWriteBufferRect(
10072 buffer,
10073 blocking,
10074 { buffer_offset[0], buffer_offset[1], 0 },
10075 { host_offset[0], host_offset[1], 0 },
10076 { region[0], region[1], 1 },
10077 buffer_row_pitch,
10078 buffer_slice_pitch,
10079 host_row_pitch,
10080 host_slice_pitch,
10081 ptr,
10082 events,
10083 event);
10084 }
10085
enqueueCopyBufferRect(const Buffer & src,const Buffer & dst,const array<size_type,3> & src_origin,const array<size_type,3> & dst_origin,const array<size_type,3> & region,size_type src_row_pitch,size_type src_slice_pitch,size_type dst_row_pitch,size_type dst_slice_pitch,const vector<Event> * events=nullptr,Event * event=nullptr)10086 inline cl_int enqueueCopyBufferRect(
10087 const Buffer& src,
10088 const Buffer& dst,
10089 const array<size_type, 3>& src_origin,
10090 const array<size_type, 3>& dst_origin,
10091 const array<size_type, 3>& region,
10092 size_type src_row_pitch,
10093 size_type src_slice_pitch,
10094 size_type dst_row_pitch,
10095 size_type dst_slice_pitch,
10096 const vector<Event>* events = nullptr,
10097 Event* event = nullptr)
10098 {
10099 cl_int error;
10100 CommandQueue queue = CommandQueue::getDefault(&error);
10101
10102 if (error != CL_SUCCESS) {
10103 return error;
10104 }
10105
10106 return queue.enqueueCopyBufferRect(
10107 src,
10108 dst,
10109 src_origin,
10110 dst_origin,
10111 region,
10112 src_row_pitch,
10113 src_slice_pitch,
10114 dst_row_pitch,
10115 dst_slice_pitch,
10116 events,
10117 event);
10118 }
10119
enqueueCopyBufferRect(const Buffer & src,const Buffer & dst,const array<size_type,2> & src_origin,const array<size_type,2> & dst_origin,const array<size_type,2> & region,size_type src_row_pitch,size_type src_slice_pitch,size_type dst_row_pitch,size_type dst_slice_pitch,const vector<Event> * events=nullptr,Event * event=nullptr)10120 inline cl_int enqueueCopyBufferRect(
10121 const Buffer& src,
10122 const Buffer& dst,
10123 const array<size_type, 2>& src_origin,
10124 const array<size_type, 2>& dst_origin,
10125 const array<size_type, 2>& region,
10126 size_type src_row_pitch,
10127 size_type src_slice_pitch,
10128 size_type dst_row_pitch,
10129 size_type dst_slice_pitch,
10130 const vector<Event>* events = nullptr,
10131 Event* event = nullptr)
10132 {
10133 return enqueueCopyBufferRect(
10134 src,
10135 dst,
10136 { src_origin[0], src_origin[1], 0 },
10137 { dst_origin[0], dst_origin[1], 0 },
10138 { region[0], region[1], 1 },
10139 src_row_pitch,
10140 src_slice_pitch,
10141 dst_row_pitch,
10142 dst_slice_pitch,
10143 events,
10144 event);
10145 }
10146 #endif // CL_HPP_TARGET_OPENCL_VERSION >= 110
10147
enqueueReadImage(const Image & image,cl_bool blocking,const array<size_type,3> & origin,const array<size_type,3> & region,size_type row_pitch,size_type slice_pitch,void * ptr,const vector<Event> * events=nullptr,Event * event=nullptr)10148 inline cl_int enqueueReadImage(
10149 const Image& image,
10150 cl_bool blocking,
10151 const array<size_type, 3>& origin,
10152 const array<size_type, 3>& region,
10153 size_type row_pitch,
10154 size_type slice_pitch,
10155 void* ptr,
10156 const vector<Event>* events = nullptr,
10157 Event* event = nullptr)
10158 {
10159 cl_int error;
10160 CommandQueue queue = CommandQueue::getDefault(&error);
10161
10162 if (error != CL_SUCCESS) {
10163 return error;
10164 }
10165
10166 return queue.enqueueReadImage(
10167 image,
10168 blocking,
10169 origin,
10170 region,
10171 row_pitch,
10172 slice_pitch,
10173 ptr,
10174 events,
10175 event);
10176 }
10177
enqueueReadImage(const Image & image,cl_bool blocking,const array<size_type,2> & origin,const array<size_type,2> & region,size_type row_pitch,size_type slice_pitch,void * ptr,const vector<Event> * events=nullptr,Event * event=nullptr)10178 inline cl_int enqueueReadImage(
10179 const Image& image,
10180 cl_bool blocking,
10181 const array<size_type, 2>& origin,
10182 const array<size_type, 2>& region,
10183 size_type row_pitch,
10184 size_type slice_pitch,
10185 void* ptr,
10186 const vector<Event>* events = nullptr,
10187 Event* event = nullptr)
10188 {
10189 return enqueueReadImage(
10190 image,
10191 blocking,
10192 { origin[0], origin[1], 0 },
10193 { region[0], region[1], 1 },
10194 row_pitch,
10195 slice_pitch,
10196 ptr,
10197 events,
10198 event);
10199 }
10200
enqueueWriteImage(const Image & image,cl_bool blocking,const array<size_type,3> & origin,const array<size_type,3> & region,size_type row_pitch,size_type slice_pitch,const void * ptr,const vector<Event> * events=nullptr,Event * event=nullptr)10201 inline cl_int enqueueWriteImage(
10202 const Image& image,
10203 cl_bool blocking,
10204 const array<size_type, 3>& origin,
10205 const array<size_type, 3>& region,
10206 size_type row_pitch,
10207 size_type slice_pitch,
10208 const void* ptr,
10209 const vector<Event>* events = nullptr,
10210 Event* event = nullptr)
10211 {
10212 cl_int error;
10213 CommandQueue queue = CommandQueue::getDefault(&error);
10214
10215 if (error != CL_SUCCESS) {
10216 return error;
10217 }
10218
10219 return queue.enqueueWriteImage(
10220 image,
10221 blocking,
10222 origin,
10223 region,
10224 row_pitch,
10225 slice_pitch,
10226 ptr,
10227 events,
10228 event);
10229 }
10230
enqueueWriteImage(const Image & image,cl_bool blocking,const array<size_type,2> & origin,const array<size_type,2> & region,size_type row_pitch,size_type slice_pitch,const void * ptr,const vector<Event> * events=nullptr,Event * event=nullptr)10231 inline cl_int enqueueWriteImage(
10232 const Image& image,
10233 cl_bool blocking,
10234 const array<size_type, 2>& origin,
10235 const array<size_type, 2>& region,
10236 size_type row_pitch,
10237 size_type slice_pitch,
10238 const void* ptr,
10239 const vector<Event>* events = nullptr,
10240 Event* event = nullptr)
10241 {
10242 return enqueueWriteImage(
10243 image,
10244 blocking,
10245 { origin[0], origin[1], 0 },
10246 { region[0], region[1], 1 },
10247 row_pitch,
10248 slice_pitch,
10249 ptr,
10250 events,
10251 event);
10252 }
10253
enqueueCopyImage(const Image & src,const Image & dst,const array<size_type,3> & src_origin,const array<size_type,3> & dst_origin,const array<size_type,3> & region,const vector<Event> * events=nullptr,Event * event=nullptr)10254 inline cl_int enqueueCopyImage(
10255 const Image& src,
10256 const Image& dst,
10257 const array<size_type, 3>& src_origin,
10258 const array<size_type, 3>& dst_origin,
10259 const array<size_type, 3>& region,
10260 const vector<Event>* events = nullptr,
10261 Event* event = nullptr)
10262 {
10263 cl_int error;
10264 CommandQueue queue = CommandQueue::getDefault(&error);
10265
10266 if (error != CL_SUCCESS) {
10267 return error;
10268 }
10269
10270 return queue.enqueueCopyImage(
10271 src,
10272 dst,
10273 src_origin,
10274 dst_origin,
10275 region,
10276 events,
10277 event);
10278 }
10279
enqueueCopyImage(const Image & src,const Image & dst,const array<size_type,2> & src_origin,const array<size_type,2> & dst_origin,const array<size_type,2> & region,const vector<Event> * events=nullptr,Event * event=nullptr)10280 inline cl_int enqueueCopyImage(
10281 const Image& src,
10282 const Image& dst,
10283 const array<size_type, 2>& src_origin,
10284 const array<size_type, 2>& dst_origin,
10285 const array<size_type, 2>& region,
10286 const vector<Event>* events = nullptr,
10287 Event* event = nullptr)
10288 {
10289 return enqueueCopyImage(
10290 src,
10291 dst,
10292 { src_origin[0], src_origin[1], 0 },
10293 { dst_origin[0], dst_origin[1], 0 },
10294 { region[0], region[1], 1 },
10295 events,
10296 event);
10297 }
10298
enqueueCopyImageToBuffer(const Image & src,const Buffer & dst,const array<size_type,3> & src_origin,const array<size_type,3> & region,size_type dst_offset,const vector<Event> * events=nullptr,Event * event=nullptr)10299 inline cl_int enqueueCopyImageToBuffer(
10300 const Image& src,
10301 const Buffer& dst,
10302 const array<size_type, 3>& src_origin,
10303 const array<size_type, 3>& region,
10304 size_type dst_offset,
10305 const vector<Event>* events = nullptr,
10306 Event* event = nullptr)
10307 {
10308 cl_int error;
10309 CommandQueue queue = CommandQueue::getDefault(&error);
10310
10311 if (error != CL_SUCCESS) {
10312 return error;
10313 }
10314
10315 return queue.enqueueCopyImageToBuffer(
10316 src,
10317 dst,
10318 src_origin,
10319 region,
10320 dst_offset,
10321 events,
10322 event);
10323 }
10324
enqueueCopyImageToBuffer(const Image & src,const Buffer & dst,const array<size_type,2> & src_origin,const array<size_type,2> & region,size_type dst_offset,const vector<Event> * events=nullptr,Event * event=nullptr)10325 inline cl_int enqueueCopyImageToBuffer(
10326 const Image& src,
10327 const Buffer& dst,
10328 const array<size_type, 2>& src_origin,
10329 const array<size_type, 2>& region,
10330 size_type dst_offset,
10331 const vector<Event>* events = nullptr,
10332 Event* event = nullptr)
10333 {
10334 return enqueueCopyImageToBuffer(
10335 src,
10336 dst,
10337 { src_origin[0], src_origin[1], 0 },
10338 { region[0], region[1], 1 },
10339 dst_offset,
10340 events,
10341 event);
10342 }
10343
enqueueCopyBufferToImage(const Buffer & src,const Image & dst,size_type src_offset,const array<size_type,3> & dst_origin,const array<size_type,3> & region,const vector<Event> * events=nullptr,Event * event=nullptr)10344 inline cl_int enqueueCopyBufferToImage(
10345 const Buffer& src,
10346 const Image& dst,
10347 size_type src_offset,
10348 const array<size_type, 3>& dst_origin,
10349 const array<size_type, 3>& region,
10350 const vector<Event>* events = nullptr,
10351 Event* event = nullptr)
10352 {
10353 cl_int error;
10354 CommandQueue queue = CommandQueue::getDefault(&error);
10355
10356 if (error != CL_SUCCESS) {
10357 return error;
10358 }
10359
10360 return queue.enqueueCopyBufferToImage(
10361 src,
10362 dst,
10363 src_offset,
10364 dst_origin,
10365 region,
10366 events,
10367 event);
10368 }
10369
enqueueCopyBufferToImage(const Buffer & src,const Image & dst,size_type src_offset,const array<size_type,2> & dst_origin,const array<size_type,2> & region,const vector<Event> * events=nullptr,Event * event=nullptr)10370 inline cl_int enqueueCopyBufferToImage(
10371 const Buffer& src,
10372 const Image& dst,
10373 size_type src_offset,
10374 const array<size_type, 2>& dst_origin,
10375 const array<size_type, 2>& region,
10376 const vector<Event>* events = nullptr,
10377 Event* event = nullptr)
10378 {
10379 cl_int error;
10380 CommandQueue queue = CommandQueue::getDefault(&error);
10381
10382 if (error != CL_SUCCESS) {
10383 return error;
10384 }
10385
10386 return enqueueCopyBufferToImage(
10387 src,
10388 dst,
10389 src_offset,
10390 { dst_origin[0], dst_origin[1], 0 },
10391 { region[0], region[1], 1 },
10392 events,
10393 event);
10394 }
10395
flush(void)10396 inline cl_int flush(void)
10397 {
10398 cl_int error;
10399 CommandQueue queue = CommandQueue::getDefault(&error);
10400
10401 if (error != CL_SUCCESS) {
10402 return error;
10403 }
10404
10405 return queue.flush();
10406 }
10407
finish(void)10408 inline cl_int finish(void)
10409 {
10410 cl_int error;
10411 CommandQueue queue = CommandQueue::getDefault(&error);
10412
10413 if (error != CL_SUCCESS) {
10414 return error;
10415 }
10416
10417
10418 return queue.finish();
10419 }
10420
10421 class EnqueueArgs
10422 {
10423 private:
10424 CommandQueue queue_;
10425 const NDRange offset_;
10426 const NDRange global_;
10427 const NDRange local_;
10428 vector<Event> events_;
10429
10430 template<typename... Ts>
10431 friend class KernelFunctor;
10432
10433 public:
EnqueueArgs(NDRange global)10434 EnqueueArgs(NDRange global) :
10435 queue_(CommandQueue::getDefault()),
10436 offset_(NullRange),
10437 global_(global),
10438 local_(NullRange)
10439 {
10440
10441 }
10442
EnqueueArgs(NDRange global,NDRange local)10443 EnqueueArgs(NDRange global, NDRange local) :
10444 queue_(CommandQueue::getDefault()),
10445 offset_(NullRange),
10446 global_(global),
10447 local_(local)
10448 {
10449
10450 }
10451
EnqueueArgs(NDRange offset,NDRange global,NDRange local)10452 EnqueueArgs(NDRange offset, NDRange global, NDRange local) :
10453 queue_(CommandQueue::getDefault()),
10454 offset_(offset),
10455 global_(global),
10456 local_(local)
10457 {
10458
10459 }
10460
EnqueueArgs(Event e,NDRange global)10461 EnqueueArgs(Event e, NDRange global) :
10462 queue_(CommandQueue::getDefault()),
10463 offset_(NullRange),
10464 global_(global),
10465 local_(NullRange)
10466 {
10467 events_.push_back(e);
10468 }
10469
EnqueueArgs(Event e,NDRange global,NDRange local)10470 EnqueueArgs(Event e, NDRange global, NDRange local) :
10471 queue_(CommandQueue::getDefault()),
10472 offset_(NullRange),
10473 global_(global),
10474 local_(local)
10475 {
10476 events_.push_back(e);
10477 }
10478
EnqueueArgs(Event e,NDRange offset,NDRange global,NDRange local)10479 EnqueueArgs(Event e, NDRange offset, NDRange global, NDRange local) :
10480 queue_(CommandQueue::getDefault()),
10481 offset_(offset),
10482 global_(global),
10483 local_(local)
10484 {
10485 events_.push_back(e);
10486 }
10487
EnqueueArgs(const vector<Event> & events,NDRange global)10488 EnqueueArgs(const vector<Event> &events, NDRange global) :
10489 queue_(CommandQueue::getDefault()),
10490 offset_(NullRange),
10491 global_(global),
10492 local_(NullRange),
10493 events_(events)
10494 {
10495
10496 }
10497
EnqueueArgs(const vector<Event> & events,NDRange global,NDRange local)10498 EnqueueArgs(const vector<Event> &events, NDRange global, NDRange local) :
10499 queue_(CommandQueue::getDefault()),
10500 offset_(NullRange),
10501 global_(global),
10502 local_(local),
10503 events_(events)
10504 {
10505
10506 }
10507
EnqueueArgs(const vector<Event> & events,NDRange offset,NDRange global,NDRange local)10508 EnqueueArgs(const vector<Event> &events, NDRange offset, NDRange global, NDRange local) :
10509 queue_(CommandQueue::getDefault()),
10510 offset_(offset),
10511 global_(global),
10512 local_(local),
10513 events_(events)
10514 {
10515
10516 }
10517
EnqueueArgs(CommandQueue & queue,NDRange global)10518 EnqueueArgs(CommandQueue &queue, NDRange global) :
10519 queue_(queue),
10520 offset_(NullRange),
10521 global_(global),
10522 local_(NullRange)
10523 {
10524
10525 }
10526
EnqueueArgs(CommandQueue & queue,NDRange global,NDRange local)10527 EnqueueArgs(CommandQueue &queue, NDRange global, NDRange local) :
10528 queue_(queue),
10529 offset_(NullRange),
10530 global_(global),
10531 local_(local)
10532 {
10533
10534 }
10535
EnqueueArgs(CommandQueue & queue,NDRange offset,NDRange global,NDRange local)10536 EnqueueArgs(CommandQueue &queue, NDRange offset, NDRange global, NDRange local) :
10537 queue_(queue),
10538 offset_(offset),
10539 global_(global),
10540 local_(local)
10541 {
10542
10543 }
10544
EnqueueArgs(CommandQueue & queue,Event e,NDRange global)10545 EnqueueArgs(CommandQueue &queue, Event e, NDRange global) :
10546 queue_(queue),
10547 offset_(NullRange),
10548 global_(global),
10549 local_(NullRange)
10550 {
10551 events_.push_back(e);
10552 }
10553
EnqueueArgs(CommandQueue & queue,Event e,NDRange global,NDRange local)10554 EnqueueArgs(CommandQueue &queue, Event e, NDRange global, NDRange local) :
10555 queue_(queue),
10556 offset_(NullRange),
10557 global_(global),
10558 local_(local)
10559 {
10560 events_.push_back(e);
10561 }
10562
EnqueueArgs(CommandQueue & queue,Event e,NDRange offset,NDRange global,NDRange local)10563 EnqueueArgs(CommandQueue &queue, Event e, NDRange offset, NDRange global, NDRange local) :
10564 queue_(queue),
10565 offset_(offset),
10566 global_(global),
10567 local_(local)
10568 {
10569 events_.push_back(e);
10570 }
10571
EnqueueArgs(CommandQueue & queue,const vector<Event> & events,NDRange global)10572 EnqueueArgs(CommandQueue &queue, const vector<Event> &events, NDRange global) :
10573 queue_(queue),
10574 offset_(NullRange),
10575 global_(global),
10576 local_(NullRange),
10577 events_(events)
10578 {
10579
10580 }
10581
EnqueueArgs(CommandQueue & queue,const vector<Event> & events,NDRange global,NDRange local)10582 EnqueueArgs(CommandQueue &queue, const vector<Event> &events, NDRange global, NDRange local) :
10583 queue_(queue),
10584 offset_(NullRange),
10585 global_(global),
10586 local_(local),
10587 events_(events)
10588 {
10589
10590 }
10591
EnqueueArgs(CommandQueue & queue,const vector<Event> & events,NDRange offset,NDRange global,NDRange local)10592 EnqueueArgs(CommandQueue &queue, const vector<Event> &events, NDRange offset, NDRange global, NDRange local) :
10593 queue_(queue),
10594 offset_(offset),
10595 global_(global),
10596 local_(local),
10597 events_(events)
10598 {
10599
10600 }
10601 };
10602
10603
10604 //----------------------------------------------------------------------------------------------
10605
10606
10607 /**
10608 * Type safe kernel functor.
10609 *
10610 */
10611 template<typename... Ts>
10612 class KernelFunctor
10613 {
10614 private:
10615 Kernel kernel_;
10616
10617 template<int index, typename T0, typename... T1s>
setArgs(T0 && t0,T1s &&...t1s)10618 void setArgs(T0&& t0, T1s&&... t1s)
10619 {
10620 kernel_.setArg(index, t0);
10621 setArgs<index + 1, T1s...>(std::forward<T1s>(t1s)...);
10622 }
10623
10624 template<int index, typename T0>
setArgs(T0 && t0)10625 void setArgs(T0&& t0)
10626 {
10627 kernel_.setArg(index, t0);
10628 }
10629
10630 template<int index>
setArgs()10631 void setArgs()
10632 {
10633 }
10634
10635
10636 public:
KernelFunctor(Kernel kernel)10637 KernelFunctor(Kernel kernel) : kernel_(kernel)
10638 {}
10639
KernelFunctor(const Program & program,const string name,cl_int * err=nullptr)10640 KernelFunctor(
10641 const Program& program,
10642 const string name,
10643 cl_int * err = nullptr) :
10644 kernel_(program, name.c_str(), err)
10645 {}
10646
10647 //! \brief Return type of the functor
10648 typedef Event result_type;
10649
10650 /**
10651 * Enqueue kernel.
10652 * @param args Launch parameters of the kernel.
10653 * @param t0... List of kernel arguments based on the template type of the functor.
10654 */
operator ()(const EnqueueArgs & args,Ts...ts)10655 Event operator() (
10656 const EnqueueArgs& args,
10657 Ts... ts)
10658 {
10659 Event event;
10660 setArgs<0>(std::forward<Ts>(ts)...);
10661
10662 args.queue_.enqueueNDRangeKernel(
10663 kernel_,
10664 args.offset_,
10665 args.global_,
10666 args.local_,
10667 &args.events_,
10668 &event);
10669
10670 return event;
10671 }
10672
10673 /**
10674 * Enqueue kernel with support for error code.
10675 * @param args Launch parameters of the kernel.
10676 * @param t0... List of kernel arguments based on the template type of the functor.
10677 * @param error Out parameter returning the error code from the execution.
10678 */
operator ()(const EnqueueArgs & args,Ts...ts,cl_int & error)10679 Event operator() (
10680 const EnqueueArgs& args,
10681 Ts... ts,
10682 cl_int &error)
10683 {
10684 Event event;
10685 setArgs<0>(std::forward<Ts>(ts)...);
10686
10687 error = args.queue_.enqueueNDRangeKernel(
10688 kernel_,
10689 args.offset_,
10690 args.global_,
10691 args.local_,
10692 &args.events_,
10693 &event);
10694
10695 return event;
10696 }
10697
10698 #if CL_HPP_TARGET_OPENCL_VERSION >= 200
setSVMPointers(const vector<void * > & pointerList)10699 cl_int setSVMPointers(const vector<void*> &pointerList)
10700 {
10701 return kernel_.setSVMPointers(pointerList);
10702 }
10703
10704 template<typename T0, typename... T1s>
setSVMPointers(const T0 & t0,T1s &...ts)10705 cl_int setSVMPointers(const T0 &t0, T1s &... ts)
10706 {
10707 return kernel_.setSVMPointers(t0, ts...);
10708 }
10709 #endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 200
10710
getKernel()10711 Kernel getKernel()
10712 {
10713 return kernel_;
10714 }
10715 };
10716
10717 namespace compatibility {
10718 /**
10719 * Backward compatibility class to ensure that cl.hpp code works with opencl.hpp.
10720 * Please use KernelFunctor directly.
10721 */
10722 template<typename... Ts>
10723 struct make_kernel
10724 {
10725 typedef KernelFunctor<Ts...> FunctorType;
10726
10727 FunctorType functor_;
10728
make_kernelcl::compatibility::make_kernel10729 make_kernel(
10730 const Program& program,
10731 const string name,
10732 cl_int * err = nullptr) :
10733 functor_(FunctorType(program, name, err))
10734 {}
10735
make_kernelcl::compatibility::make_kernel10736 make_kernel(
10737 const Kernel kernel) :
10738 functor_(FunctorType(kernel))
10739 {}
10740
10741 //! \brief Return type of the functor
10742 typedef Event result_type;
10743
10744 //! \brief Function signature of kernel functor with no event dependency.
10745 typedef Event type_(
10746 const EnqueueArgs&,
10747 Ts...);
10748
operator ()cl::compatibility::make_kernel10749 Event operator()(
10750 const EnqueueArgs& enqueueArgs,
10751 Ts... args)
10752 {
10753 return functor_(
10754 enqueueArgs, args...);
10755 }
10756 };
10757 } // namespace compatibility
10758
10759 #ifdef cl_khr_semaphore
10760
10761 #ifdef cl_khr_external_semaphore
10762 enum ExternalSemaphoreType : cl_external_semaphore_handle_type_khr
10763 {
10764 None = 0,
10765 #ifdef cl_khr_external_semaphore_dx_fence
10766 D3D12Fence = CL_SEMAPHORE_HANDLE_D3D12_FENCE_KHR,
10767 #endif
10768 #ifdef cl_khr_external_semaphore_opaque_fd
10769 OpaqueFd = CL_SEMAPHORE_HANDLE_OPAQUE_FD_KHR,
10770 #endif
10771 #ifdef cl_khr_external_semaphore_sync_fd
10772 SyncFd = CL_SEMAPHORE_HANDLE_SYNC_FD_KHR,
10773 #endif
10774 #ifdef cl_khr_external_semaphore_win32
10775 OpaqueWin32 = CL_SEMAPHORE_HANDLE_OPAQUE_WIN32_KHR,
10776 OpaqueWin32Kmt = CL_SEMAPHORE_HANDLE_OPAQUE_WIN32_KMT_KHR,
10777 #endif // cl_khr_external_semaphore_win32
10778 };
10779 #endif // cl_khr_external_semaphore
10780
10781 class Semaphore : public detail::Wrapper<cl_semaphore_khr>
10782 {
10783 public:
Semaphore()10784 Semaphore() : detail::Wrapper<cl_type>() {}
Semaphore(const Context & context,const vector<cl_semaphore_properties_khr> & sema_props,cl_int * err=nullptr)10785 Semaphore(
10786 const Context &context,
10787 const vector<cl_semaphore_properties_khr>& sema_props,
10788 cl_int *err = nullptr)
10789 {
10790 /* initialization of addresses to extension functions (it is done only once) */
10791 std::call_once(ext_init_, initExtensions, context);
10792
10793 cl_int error = CL_INVALID_OPERATION;
10794
10795 if (pfn_clCreateSemaphoreWithPropertiesKHR)
10796 {
10797 object_ = pfn_clCreateSemaphoreWithPropertiesKHR(
10798 context(),
10799 sema_props.data(),
10800 &error);
10801 }
10802
10803 detail::errHandler(error, __CREATE_SEMAPHORE_KHR_WITH_PROPERTIES_ERR);
10804
10805 if (err != nullptr) {
10806 *err = error;
10807 }
10808 }
Semaphore(const vector<cl_semaphore_properties_khr> & sema_props,cl_int * err=nullptr)10809 Semaphore(
10810 const vector<cl_semaphore_properties_khr>& sema_props,
10811 cl_int* err = nullptr):Semaphore(Context::getDefault(err), sema_props, err) {}
10812
Semaphore(const cl_semaphore_khr & semaphore,bool retainObject=false)10813 explicit Semaphore(const cl_semaphore_khr& semaphore, bool retainObject = false) :
10814 detail::Wrapper<cl_type>(semaphore, retainObject) {}
operator =(const cl_semaphore_khr & rhs)10815 Semaphore& operator = (const cl_semaphore_khr& rhs) {
10816 detail::Wrapper<cl_type>::operator=(rhs);
10817 return *this;
10818 }
10819 template <typename T>
getInfo(cl_semaphore_info_khr name,T * param) const10820 cl_int getInfo(cl_semaphore_info_khr name, T* param) const
10821 {
10822 if (pfn_clGetSemaphoreInfoKHR == nullptr) {
10823 return detail::errHandler(CL_INVALID_OPERATION,
10824 __GET_SEMAPHORE_KHR_INFO_ERR);
10825 }
10826
10827 return detail::errHandler(
10828 detail::getInfo(pfn_clGetSemaphoreInfoKHR, object_, name, param),
10829 __GET_SEMAPHORE_KHR_INFO_ERR);
10830 }
10831 template <cl_semaphore_info_khr name> typename
10832 detail::param_traits<detail::cl_semaphore_info_khr, name>::param_type
getInfo(cl_int * err=nullptr) const10833 getInfo(cl_int* err = nullptr) const
10834 {
10835 typename detail::param_traits<
10836 detail::cl_semaphore_info_khr, name>::param_type param;
10837 cl_int result = getInfo(name, ¶m);
10838 if (err != nullptr) {
10839 *err = result;
10840 }
10841 return param;
10842 }
10843
10844 #ifdef cl_khr_external_semaphore
10845 template <typename T>
getHandleForTypeKHR(const Device & device,cl_external_semaphore_handle_type_khr name,T * param) const10846 cl_int getHandleForTypeKHR(
10847 const Device& device, cl_external_semaphore_handle_type_khr name, T* param) const
10848 {
10849 if (pfn_clGetSemaphoreHandleForTypeKHR == nullptr) {
10850 return detail::errHandler(CL_INVALID_OPERATION,
10851 __GET_SEMAPHORE_HANDLE_FOR_TYPE_KHR_ERR);
10852 }
10853
10854 return detail::errHandler(
10855 detail::getInfo(
10856 pfn_clGetSemaphoreHandleForTypeKHR, object_, device(), name, param),
10857 __GET_SEMAPHORE_HANDLE_FOR_TYPE_KHR_ERR);
10858 }
10859
10860 template <cl_external_semaphore_handle_type_khr type> typename
10861 detail::param_traits<detail::cl_external_semaphore_handle_type_khr, type>::param_type
getHandleForTypeKHR(const Device & device,cl_int * err=nullptr) const10862 getHandleForTypeKHR(const Device& device, cl_int* err = nullptr) const
10863 {
10864 typename detail::param_traits<
10865 detail::cl_external_semaphore_handle_type_khr, type>::param_type param;
10866 cl_int result = getHandleForTypeKHR(device, type, ¶m);
10867 if (err != nullptr) {
10868 *err = result;
10869 }
10870 return param;
10871 }
10872 #endif // cl_khr_external_semaphore
10873
retain()10874 cl_int retain()
10875 {
10876 if (pfn_clRetainSemaphoreKHR == nullptr) {
10877 return detail::errHandler(CL_INVALID_OPERATION,
10878 __RETAIN_SEMAPHORE_KHR_ERR);
10879 }
10880 return pfn_clRetainSemaphoreKHR(object_);
10881 }
10882
release()10883 cl_int release()
10884 {
10885 if (pfn_clReleaseSemaphoreKHR == nullptr) {
10886 return detail::errHandler(CL_INVALID_OPERATION,
10887 __RELEASE_SEMAPHORE_KHR_ERR);
10888 }
10889 return pfn_clReleaseSemaphoreKHR(object_);
10890 }
10891
10892 private:
10893 static std::once_flag ext_init_;
10894
initExtensions(const Context & context)10895 static void initExtensions(const Context& context)
10896 {
10897 #if CL_HPP_TARGET_OPENCL_VERSION >= 120
10898 Device device = context.getInfo<CL_CONTEXT_DEVICES>().at(0);
10899 cl_platform_id platform = device.getInfo<CL_DEVICE_PLATFORM>()();
10900 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clCreateSemaphoreWithPropertiesKHR);
10901 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clReleaseSemaphoreKHR);
10902 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clRetainSemaphoreKHR);
10903 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clEnqueueWaitSemaphoresKHR);
10904 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clEnqueueSignalSemaphoresKHR);
10905 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clGetSemaphoreInfoKHR);
10906 #ifdef cl_khr_external_semaphore
10907 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clGetSemaphoreHandleForTypeKHR);
10908 #endif // cl_khr_external_semaphore
10909
10910 #else
10911 CL_HPP_INIT_CL_EXT_FCN_PTR_(clCreateSemaphoreWithPropertiesKHR);
10912 CL_HPP_INIT_CL_EXT_FCN_PTR_(clReleaseSemaphoreKHR);
10913 CL_HPP_INIT_CL_EXT_FCN_PTR_(clRetainSemaphoreKHR);
10914 CL_HPP_INIT_CL_EXT_FCN_PTR_(clEnqueueWaitSemaphoresKHR);
10915 CL_HPP_INIT_CL_EXT_FCN_PTR_(clEnqueueSignalSemaphoresKHR);
10916 CL_HPP_INIT_CL_EXT_FCN_PTR_(clGetSemaphoreInfoKHR);
10917 #ifdef cl_khr_external_semaphore
10918 CL_HPP_INIT_CL_EXT_FCN_PTR_(clGetSemaphoreHandleForTypeKHR);
10919 #endif // cl_khr_external_semaphore
10920
10921 #endif
10922 if ((pfn_clCreateSemaphoreWithPropertiesKHR == nullptr) &&
10923 (pfn_clReleaseSemaphoreKHR == nullptr) &&
10924 (pfn_clRetainSemaphoreKHR == nullptr) &&
10925 (pfn_clEnqueueWaitSemaphoresKHR == nullptr) &&
10926 (pfn_clEnqueueSignalSemaphoresKHR == nullptr) &&
10927 #ifdef cl_khr_external_semaphore
10928 (pfn_clGetSemaphoreHandleForTypeKHR == nullptr) &&
10929 #endif // cl_khr_external_semaphore
10930 (pfn_clGetSemaphoreInfoKHR == nullptr))
10931 {
10932 detail::errHandler(CL_INVALID_VALUE, __CREATE_SEMAPHORE_KHR_WITH_PROPERTIES_ERR);
10933 }
10934 }
10935
10936 };
10937
10938 CL_HPP_DEFINE_STATIC_MEMBER_ std::once_flag Semaphore::ext_init_;
10939
enqueueWaitSemaphores(const vector<Semaphore> & sema_objects,const vector<cl_semaphore_payload_khr> & sema_payloads,const vector<Event> * events_wait_list,Event * event) const10940 inline cl_int CommandQueue::enqueueWaitSemaphores(
10941 const vector<Semaphore> &sema_objects,
10942 const vector<cl_semaphore_payload_khr> &sema_payloads,
10943 const vector<Event>* events_wait_list,
10944 Event *event) const
10945 {
10946 cl_event tmp;
10947 cl_int err = CL_INVALID_OPERATION;
10948
10949 if (pfn_clEnqueueWaitSemaphoresKHR != nullptr) {
10950 err = pfn_clEnqueueWaitSemaphoresKHR(
10951 object_,
10952 (cl_uint)sema_objects.size(),
10953 (const cl_semaphore_khr *) &sema_objects.front(),
10954 (sema_payloads.size() > 0) ? &sema_payloads.front() : nullptr,
10955 (events_wait_list != nullptr) ? (cl_uint) events_wait_list->size() : 0,
10956 (events_wait_list != nullptr && events_wait_list->size() > 0) ? (cl_event*) &events_wait_list->front() : nullptr,
10957 (event != nullptr) ? &tmp : nullptr);
10958 }
10959
10960 detail::errHandler(err, __ENQUEUE_WAIT_SEMAPHORE_KHR_ERR);
10961
10962 if (event != nullptr && err == CL_SUCCESS)
10963 *event = tmp;
10964
10965 return err;
10966 }
10967
enqueueSignalSemaphores(const vector<Semaphore> & sema_objects,const vector<cl_semaphore_payload_khr> & sema_payloads,const vector<Event> * events_wait_list,Event * event)10968 inline cl_int CommandQueue::enqueueSignalSemaphores(
10969 const vector<Semaphore> &sema_objects,
10970 const vector<cl_semaphore_payload_khr>& sema_payloads,
10971 const vector<Event>* events_wait_list,
10972 Event* event)
10973 {
10974 cl_event tmp;
10975 cl_int err = CL_INVALID_OPERATION;
10976
10977 if (pfn_clEnqueueSignalSemaphoresKHR != nullptr) {
10978 err = pfn_clEnqueueSignalSemaphoresKHR(
10979 object_,
10980 (cl_uint)sema_objects.size(),
10981 (const cl_semaphore_khr*) &sema_objects.front(),
10982 (sema_payloads.size() > 0) ? &sema_payloads.front() : nullptr,
10983 (events_wait_list != nullptr) ? (cl_uint) events_wait_list->size() : 0,
10984 (events_wait_list != nullptr && events_wait_list->size() > 0) ? (cl_event*) &events_wait_list->front() : nullptr,
10985 (event != nullptr) ? &tmp : nullptr);
10986 }
10987
10988 detail::errHandler(err, __ENQUEUE_SIGNAL_SEMAPHORE_KHR_ERR);
10989
10990 if (event != nullptr && err == CL_SUCCESS)
10991 *event = tmp;
10992
10993 return err;
10994 }
10995
10996 #endif // cl_khr_semaphore
10997
10998 #if defined(cl_khr_command_buffer)
10999 /*! \class CommandBufferKhr
11000 * \brief CommandBufferKhr interface for cl_command_buffer_khr.
11001 */
11002 class CommandBufferKhr : public detail::Wrapper<cl_command_buffer_khr>
11003 {
11004 public:
11005 //! \brief Default constructor - initializes to nullptr.
CommandBufferKhr()11006 CommandBufferKhr() : detail::Wrapper<cl_type>() { }
11007
CommandBufferKhr(const vector<CommandQueue> & queues,cl_command_buffer_properties_khr properties=0,cl_int * errcode_ret=nullptr)11008 explicit CommandBufferKhr(const vector<CommandQueue> &queues,
11009 cl_command_buffer_properties_khr properties = 0,
11010 cl_int* errcode_ret = nullptr)
11011 {
11012 cl_command_buffer_properties_khr command_buffer_properties[] = {
11013 CL_COMMAND_BUFFER_FLAGS_KHR, properties, 0
11014 };
11015
11016 /* initialization of addresses to extension functions (it is done only once) */
11017 std::call_once(ext_init_, [&] { initExtensions(queues[0].getInfo<CL_QUEUE_DEVICE>()); });
11018 cl_int error = CL_INVALID_OPERATION;
11019
11020 static_assert(sizeof(cl::CommandQueue) == sizeof(cl_command_queue),
11021 "Size of cl::CommandQueue must be equal to size of cl_command_queue");
11022
11023 if (pfn_clCreateCommandBufferKHR)
11024 {
11025 object_ = pfn_clCreateCommandBufferKHR((cl_uint) queues.size(),
11026 (cl_command_queue *) &queues.front(),
11027 command_buffer_properties,
11028 &error);
11029 }
11030
11031 detail::errHandler(error, __CREATE_COMMAND_BUFFER_KHR_ERR);
11032 if (errcode_ret != nullptr) {
11033 *errcode_ret = error;
11034 }
11035 }
11036
CommandBufferKhr(const cl_command_buffer_khr & commandBufferKhr,bool retainObject=false)11037 explicit CommandBufferKhr(const cl_command_buffer_khr& commandBufferKhr, bool retainObject = false) :
11038 detail::Wrapper<cl_type>(commandBufferKhr, retainObject) { }
11039
operator =(const cl_command_buffer_khr & rhs)11040 CommandBufferKhr& operator=(const cl_command_buffer_khr& rhs)
11041 {
11042 detail::Wrapper<cl_type>::operator=(rhs);
11043 return *this;
11044 }
11045
11046 template <typename T>
getInfo(cl_command_buffer_info_khr name,T * param) const11047 cl_int getInfo(cl_command_buffer_info_khr name, T* param) const
11048 {
11049 if (pfn_clGetCommandBufferInfoKHR == nullptr) {
11050 return detail::errHandler(CL_INVALID_OPERATION,
11051 __GET_COMMAND_BUFFER_INFO_KHR_ERR);
11052 }
11053 return detail::errHandler(
11054 detail::getInfo(pfn_clGetCommandBufferInfoKHR, object_, name, param),
11055 __GET_COMMAND_BUFFER_INFO_KHR_ERR);
11056 }
11057
11058 template <cl_command_buffer_info_khr name> typename
11059 detail::param_traits<detail::cl_command_buffer_info_khr, name>::param_type
getInfo(cl_int * err=nullptr) const11060 getInfo(cl_int* err = nullptr) const
11061 {
11062 typename detail::param_traits<
11063 detail::cl_command_buffer_info_khr, name>::param_type param;
11064 cl_int result = getInfo(name, ¶m);
11065 if (err != nullptr) {
11066 *err = result;
11067 }
11068 return param;
11069 }
11070
finalizeCommandBuffer() const11071 cl_int finalizeCommandBuffer() const
11072 {
11073 return detail::errHandler(::clFinalizeCommandBufferKHR(object_), __FINALIZE_COMMAND_BUFFER_KHR_ERR);
11074 }
11075
enqueueCommandBuffer(vector<CommandQueue> & queues,const vector<Event> * events=nullptr,Event * event=nullptr)11076 cl_int enqueueCommandBuffer(vector<CommandQueue> &queues,
11077 const vector<Event>* events = nullptr,
11078 Event* event = nullptr)
11079 {
11080 if (pfn_clEnqueueCommandBufferKHR == nullptr) {
11081 return detail::errHandler(CL_INVALID_OPERATION,
11082 __ENQUEUE_COMMAND_BUFFER_KHR_ERR);
11083 }
11084
11085 static_assert(sizeof(cl::CommandQueue) == sizeof(cl_command_queue),
11086 "Size of cl::CommandQueue must be equal to size of cl_command_queue");
11087
11088 return detail::errHandler(pfn_clEnqueueCommandBufferKHR((cl_uint) queues.size(),
11089 (cl_command_queue *) &queues.front(),
11090 object_,
11091 (events != nullptr) ? (cl_uint) events->size() : 0,
11092 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
11093 (cl_event*) event),
11094 __ENQUEUE_COMMAND_BUFFER_KHR_ERR);
11095 }
11096
commandBarrierWithWaitList(const vector<cl_sync_point_khr> * sync_points_vec=nullptr,cl_sync_point_khr * sync_point=nullptr,MutableCommandKhr * mutable_handle=nullptr,const CommandQueue * command_queue=nullptr)11097 cl_int commandBarrierWithWaitList(const vector<cl_sync_point_khr>* sync_points_vec = nullptr,
11098 cl_sync_point_khr* sync_point = nullptr,
11099 MutableCommandKhr* mutable_handle = nullptr,
11100 const CommandQueue* command_queue = nullptr)
11101 {
11102 if (pfn_clCommandBarrierWithWaitListKHR == nullptr) {
11103 return detail::errHandler(CL_INVALID_OPERATION,
11104 __COMMAND_BARRIER_WITH_WAIT_LIST_KHR_ERR);
11105 }
11106
11107 cl_sync_point_khr tmp_sync_point;
11108 cl_int error = detail::errHandler(
11109 pfn_clCommandBarrierWithWaitListKHR(object_,
11110 (command_queue != nullptr) ? (*command_queue)() : nullptr,
11111 (sync_points_vec != nullptr) ? (cl_uint) sync_points_vec->size() : 0,
11112 (sync_points_vec != nullptr && sync_points_vec->size() > 0) ? &sync_points_vec->front() : nullptr,
11113 (sync_point != nullptr) ? &tmp_sync_point : nullptr,
11114 (cl_mutable_command_khr*) mutable_handle),
11115 __COMMAND_BARRIER_WITH_WAIT_LIST_KHR_ERR);
11116
11117 if (sync_point != nullptr && error == CL_SUCCESS)
11118 *sync_point = tmp_sync_point;
11119
11120 return error;
11121 }
11122
commandCopyBuffer(const Buffer & src,const Buffer & dst,size_type src_offset,size_type dst_offset,size_type size,const vector<cl_sync_point_khr> * sync_points_vec=nullptr,cl_sync_point_khr * sync_point=nullptr,MutableCommandKhr * mutable_handle=nullptr,const CommandQueue * command_queue=nullptr)11123 cl_int commandCopyBuffer(const Buffer& src,
11124 const Buffer& dst,
11125 size_type src_offset,
11126 size_type dst_offset,
11127 size_type size,
11128 const vector<cl_sync_point_khr>* sync_points_vec = nullptr,
11129 cl_sync_point_khr* sync_point = nullptr,
11130 MutableCommandKhr* mutable_handle = nullptr,
11131 const CommandQueue* command_queue = nullptr)
11132 {
11133 if (pfn_clCommandCopyBufferKHR == nullptr) {
11134 return detail::errHandler(CL_INVALID_OPERATION,
11135 __COMMAND_COPY_BUFFER_KHR_ERR);
11136 }
11137
11138 cl_sync_point_khr tmp_sync_point;
11139 cl_int error = detail::errHandler(
11140 pfn_clCommandCopyBufferKHR(object_,
11141 (command_queue != nullptr) ? (*command_queue)() : nullptr,
11142 src(),
11143 dst(),
11144 src_offset,
11145 dst_offset,
11146 size,
11147 (sync_points_vec != nullptr) ? (cl_uint) sync_points_vec->size() : 0,
11148 (sync_points_vec != nullptr && sync_points_vec->size() > 0) ? &sync_points_vec->front() : nullptr,
11149 (sync_point != nullptr) ? &tmp_sync_point : nullptr,
11150 (cl_mutable_command_khr*) mutable_handle),
11151 __COMMAND_COPY_BUFFER_KHR_ERR);
11152
11153 if (sync_point != nullptr && error == CL_SUCCESS)
11154 *sync_point = tmp_sync_point;
11155
11156 return error;
11157 }
11158
commandCopyBufferRect(const Buffer & src,const Buffer & dst,const array<size_type,3> & src_origin,const array<size_type,3> & dst_origin,const array<size_type,3> & region,size_type src_row_pitch,size_type src_slice_pitch,size_type dst_row_pitch,size_type dst_slice_pitch,const vector<cl_sync_point_khr> * sync_points_vec=nullptr,cl_sync_point_khr * sync_point=nullptr,MutableCommandKhr * mutable_handle=nullptr,const CommandQueue * command_queue=nullptr)11159 cl_int commandCopyBufferRect(const Buffer& src,
11160 const Buffer& dst,
11161 const array<size_type, 3>& src_origin,
11162 const array<size_type, 3>& dst_origin,
11163 const array<size_type, 3>& region,
11164 size_type src_row_pitch,
11165 size_type src_slice_pitch,
11166 size_type dst_row_pitch,
11167 size_type dst_slice_pitch,
11168 const vector<cl_sync_point_khr>* sync_points_vec = nullptr,
11169 cl_sync_point_khr* sync_point = nullptr,
11170 MutableCommandKhr* mutable_handle = nullptr,
11171 const CommandQueue* command_queue = nullptr)
11172 {
11173 if (pfn_clCommandCopyBufferRectKHR == nullptr) {
11174 return detail::errHandler(CL_INVALID_OPERATION,
11175 __COMMAND_COPY_BUFFER_RECT_KHR_ERR);
11176 }
11177
11178 cl_sync_point_khr tmp_sync_point;
11179 cl_int error = detail::errHandler(
11180 pfn_clCommandCopyBufferRectKHR(object_,
11181 (command_queue != nullptr) ? (*command_queue)() : nullptr,
11182 src(),
11183 dst(),
11184 src_origin.data(),
11185 dst_origin.data(),
11186 region.data(),
11187 src_row_pitch,
11188 src_slice_pitch,
11189 dst_row_pitch,
11190 dst_slice_pitch,
11191 (sync_points_vec != nullptr) ? (cl_uint) sync_points_vec->size() : 0,
11192 (sync_points_vec != nullptr && sync_points_vec->size() > 0) ? &sync_points_vec->front() : nullptr,
11193 (sync_point != nullptr) ? &tmp_sync_point : nullptr,
11194 (cl_mutable_command_khr*) mutable_handle),
11195 __COMMAND_COPY_BUFFER_RECT_KHR_ERR);
11196
11197 if (sync_point != nullptr && error == CL_SUCCESS)
11198 *sync_point = tmp_sync_point;
11199
11200 return error;
11201 }
11202
commandCopyBufferToImage(const Buffer & src,const Image & dst,size_type src_offset,const array<size_type,3> & dst_origin,const array<size_type,3> & region,const vector<cl_sync_point_khr> * sync_points_vec=nullptr,cl_sync_point_khr * sync_point=nullptr,MutableCommandKhr * mutable_handle=nullptr,const CommandQueue * command_queue=nullptr)11203 cl_int commandCopyBufferToImage(const Buffer& src,
11204 const Image& dst,
11205 size_type src_offset,
11206 const array<size_type, 3>& dst_origin,
11207 const array<size_type, 3>& region,
11208 const vector<cl_sync_point_khr>* sync_points_vec = nullptr,
11209 cl_sync_point_khr* sync_point = nullptr,
11210 MutableCommandKhr* mutable_handle = nullptr,
11211 const CommandQueue* command_queue = nullptr)
11212 {
11213 if (pfn_clCommandCopyBufferToImageKHR == nullptr) {
11214 return detail::errHandler(CL_INVALID_OPERATION,
11215 __COMMAND_COPY_BUFFER_TO_IMAGE_KHR_ERR);
11216 }
11217
11218 cl_sync_point_khr tmp_sync_point;
11219 cl_int error = detail::errHandler(
11220 pfn_clCommandCopyBufferToImageKHR(object_,
11221 (command_queue != nullptr) ? (*command_queue)() : nullptr,
11222 src(),
11223 dst(),
11224 src_offset,
11225 dst_origin.data(),
11226 region.data(),
11227 (sync_points_vec != nullptr) ? (cl_uint) sync_points_vec->size() : 0,
11228 (sync_points_vec != nullptr && sync_points_vec->size() > 0) ? &sync_points_vec->front() : nullptr,
11229 (sync_point != nullptr) ? &tmp_sync_point : nullptr,
11230 (cl_mutable_command_khr*) mutable_handle),
11231 __COMMAND_COPY_BUFFER_TO_IMAGE_KHR_ERR);
11232
11233 if (sync_point != nullptr && error == CL_SUCCESS)
11234 *sync_point = tmp_sync_point;
11235
11236 return error;
11237 }
11238
commandCopyImage(const Image & src,const Image & dst,const array<size_type,3> & src_origin,const array<size_type,3> & dst_origin,const array<size_type,3> & region,const vector<cl_sync_point_khr> * sync_points_vec=nullptr,cl_sync_point_khr * sync_point=nullptr,MutableCommandKhr * mutable_handle=nullptr,const CommandQueue * command_queue=nullptr)11239 cl_int commandCopyImage(const Image& src,
11240 const Image& dst,
11241 const array<size_type, 3>& src_origin,
11242 const array<size_type, 3>& dst_origin,
11243 const array<size_type, 3>& region,
11244 const vector<cl_sync_point_khr>* sync_points_vec = nullptr,
11245 cl_sync_point_khr* sync_point = nullptr,
11246 MutableCommandKhr* mutable_handle = nullptr,
11247 const CommandQueue* command_queue = nullptr)
11248 {
11249 if (pfn_clCommandCopyImageKHR == nullptr) {
11250 return detail::errHandler(CL_INVALID_OPERATION,
11251 __COMMAND_COPY_IMAGE_KHR_ERR);
11252 }
11253
11254 cl_sync_point_khr tmp_sync_point;
11255 cl_int error = detail::errHandler(
11256 pfn_clCommandCopyImageKHR(object_,
11257 (command_queue != nullptr) ? (*command_queue)() : nullptr,
11258 src(),
11259 dst(),
11260 src_origin.data(),
11261 dst_origin.data(),
11262 region.data(),
11263 (sync_points_vec != nullptr) ? (cl_uint) sync_points_vec->size() : 0,
11264 (sync_points_vec != nullptr && sync_points_vec->size() > 0) ? &sync_points_vec->front() : nullptr,
11265 (sync_point != nullptr) ? &tmp_sync_point : nullptr,
11266 (cl_mutable_command_khr*) mutable_handle),
11267 __COMMAND_COPY_IMAGE_KHR_ERR);
11268
11269 if (sync_point != nullptr && error == CL_SUCCESS)
11270 *sync_point = tmp_sync_point;
11271
11272 return error;
11273 }
11274
commandCopyImageToBuffer(const Image & src,const Buffer & dst,const array<size_type,3> & src_origin,const array<size_type,3> & region,size_type dst_offset,const vector<cl_sync_point_khr> * sync_points_vec=nullptr,cl_sync_point_khr * sync_point=nullptr,MutableCommandKhr * mutable_handle=nullptr,const CommandQueue * command_queue=nullptr)11275 cl_int commandCopyImageToBuffer(const Image& src,
11276 const Buffer& dst,
11277 const array<size_type, 3>& src_origin,
11278 const array<size_type, 3>& region,
11279 size_type dst_offset,
11280 const vector<cl_sync_point_khr>* sync_points_vec = nullptr,
11281 cl_sync_point_khr* sync_point = nullptr,
11282 MutableCommandKhr* mutable_handle = nullptr,
11283 const CommandQueue* command_queue = nullptr)
11284 {
11285 if (pfn_clCommandCopyImageToBufferKHR == nullptr) {
11286 return detail::errHandler(CL_INVALID_OPERATION,
11287 __COMMAND_COPY_IMAGE_TO_BUFFER_KHR_ERR);
11288 }
11289
11290 cl_sync_point_khr tmp_sync_point;
11291 cl_int error = detail::errHandler(
11292 pfn_clCommandCopyImageToBufferKHR(object_,
11293 (command_queue != nullptr) ? (*command_queue)() : nullptr,
11294 src(),
11295 dst(),
11296 src_origin.data(),
11297 region.data(),
11298 dst_offset,
11299 (sync_points_vec != nullptr) ? (cl_uint) sync_points_vec->size() : 0,
11300 (sync_points_vec != nullptr && sync_points_vec->size() > 0) ? &sync_points_vec->front() : nullptr,
11301 (sync_point != nullptr) ? &tmp_sync_point : nullptr,
11302 (cl_mutable_command_khr*) mutable_handle),
11303 __COMMAND_COPY_IMAGE_TO_BUFFER_KHR_ERR);
11304
11305 if (sync_point != nullptr && error == CL_SUCCESS)
11306 *sync_point = tmp_sync_point;
11307
11308 return error;
11309 }
11310
11311 template<typename PatternType>
commandFillBuffer(const Buffer & buffer,PatternType pattern,size_type offset,size_type size,const vector<cl_sync_point_khr> * sync_points_vec=nullptr,cl_sync_point_khr * sync_point=nullptr,MutableCommandKhr * mutable_handle=nullptr,const CommandQueue * command_queue=nullptr)11312 cl_int commandFillBuffer(const Buffer& buffer,
11313 PatternType pattern,
11314 size_type offset,
11315 size_type size,
11316 const vector<cl_sync_point_khr>* sync_points_vec = nullptr,
11317 cl_sync_point_khr* sync_point = nullptr,
11318 MutableCommandKhr* mutable_handle = nullptr,
11319 const CommandQueue* command_queue = nullptr)
11320 {
11321 if (pfn_clCommandFillBufferKHR == nullptr) {
11322 return detail::errHandler(CL_INVALID_OPERATION,
11323 __COMMAND_FILL_BUFFER_KHR_ERR);
11324 }
11325
11326 cl_sync_point_khr tmp_sync_point;
11327 cl_int error = detail::errHandler(
11328 pfn_clCommandFillBufferKHR(object_,
11329 (command_queue != nullptr) ? (*command_queue)() : nullptr,
11330 buffer(),
11331 static_cast<void*>(&pattern),
11332 sizeof(PatternType),
11333 offset,
11334 size,
11335 (sync_points_vec != nullptr) ? (cl_uint) sync_points_vec->size() : 0,
11336 (sync_points_vec != nullptr && sync_points_vec->size() > 0) ? &sync_points_vec->front() : nullptr,
11337 (sync_point != nullptr) ? &tmp_sync_point : nullptr,
11338 (cl_mutable_command_khr*) mutable_handle),
11339 __COMMAND_FILL_BUFFER_KHR_ERR);
11340
11341 if (sync_point != nullptr && error == CL_SUCCESS)
11342 *sync_point = tmp_sync_point;
11343
11344 return error;
11345 }
11346
commandFillImage(const Image & image,cl_float4 fillColor,const array<size_type,3> & origin,const array<size_type,3> & region,const vector<cl_sync_point_khr> * sync_points_vec=nullptr,cl_sync_point_khr * sync_point=nullptr,MutableCommandKhr * mutable_handle=nullptr,const CommandQueue * command_queue=nullptr)11347 cl_int commandFillImage(const Image& image,
11348 cl_float4 fillColor,
11349 const array<size_type, 3>& origin,
11350 const array<size_type, 3>& region,
11351 const vector<cl_sync_point_khr>* sync_points_vec = nullptr,
11352 cl_sync_point_khr* sync_point = nullptr,
11353 MutableCommandKhr* mutable_handle = nullptr,
11354 const CommandQueue* command_queue = nullptr)
11355 {
11356 if (pfn_clCommandFillImageKHR == nullptr) {
11357 return detail::errHandler(CL_INVALID_OPERATION,
11358 __COMMAND_FILL_IMAGE_KHR_ERR);
11359 }
11360
11361 cl_sync_point_khr tmp_sync_point;
11362 cl_int error = detail::errHandler(
11363 pfn_clCommandFillImageKHR(object_,
11364 (command_queue != nullptr) ? (*command_queue)() : nullptr,
11365 image(),
11366 static_cast<void*>(&fillColor),
11367 origin.data(),
11368 region.data(),
11369 (sync_points_vec != nullptr) ? (cl_uint) sync_points_vec->size() : 0,
11370 (sync_points_vec != nullptr && sync_points_vec->size() > 0) ? &sync_points_vec->front() : nullptr,
11371 (sync_point != nullptr) ? &tmp_sync_point : nullptr,
11372 (cl_mutable_command_khr*) mutable_handle),
11373 __COMMAND_FILL_IMAGE_KHR_ERR);
11374
11375 if (sync_point != nullptr && error == CL_SUCCESS)
11376 *sync_point = tmp_sync_point;
11377
11378 return error;
11379 }
11380
commandNDRangeKernel(const cl::vector<cl_ndrange_kernel_command_properties_khr> & properties,const Kernel & kernel,const NDRange & offset,const NDRange & global,const NDRange & local=NullRange,const vector<cl_sync_point_khr> * sync_points_vec=nullptr,cl_sync_point_khr * sync_point=nullptr,MutableCommandKhr * mutable_handle=nullptr,const CommandQueue * command_queue=nullptr)11381 cl_int commandNDRangeKernel(const cl::vector<cl_ndrange_kernel_command_properties_khr> &properties,
11382 const Kernel& kernel,
11383 const NDRange& offset,
11384 const NDRange& global,
11385 const NDRange& local = NullRange,
11386 const vector<cl_sync_point_khr>* sync_points_vec = nullptr,
11387 cl_sync_point_khr* sync_point = nullptr,
11388 MutableCommandKhr* mutable_handle = nullptr,
11389 const CommandQueue* command_queue = nullptr)
11390 {
11391 if (pfn_clCommandNDRangeKernelKHR == nullptr) {
11392 return detail::errHandler(CL_INVALID_OPERATION,
11393 __COMMAND_NDRANGE_KERNEL_KHR_ERR);
11394 }
11395
11396 cl_sync_point_khr tmp_sync_point;
11397 cl_int error = detail::errHandler(
11398 pfn_clCommandNDRangeKernelKHR(object_,
11399 (command_queue != nullptr) ? (*command_queue)() : nullptr,
11400 &properties[0],
11401 kernel(),
11402 (cl_uint) global.dimensions(),
11403 offset.dimensions() != 0 ? (const size_type*) offset : nullptr,
11404 (const size_type*) global,
11405 local.dimensions() != 0 ? (const size_type*) local : nullptr,
11406 (sync_points_vec != nullptr) ? (cl_uint) sync_points_vec->size() : 0,
11407 (sync_points_vec != nullptr && sync_points_vec->size() > 0) ? &sync_points_vec->front() : nullptr,
11408 (sync_point != nullptr) ? &tmp_sync_point : nullptr,
11409 (cl_mutable_command_khr*) mutable_handle),
11410 __COMMAND_NDRANGE_KERNEL_KHR_ERR);
11411
11412 if (sync_point != nullptr && error == CL_SUCCESS)
11413 *sync_point = tmp_sync_point;
11414
11415 return error;
11416 }
11417
11418 #if defined(cl_khr_command_buffer_mutable_dispatch)
updateMutableCommands(const cl_mutable_base_config_khr * mutable_config)11419 cl_int updateMutableCommands(const cl_mutable_base_config_khr* mutable_config)
11420 {
11421 if (pfn_clUpdateMutableCommandsKHR == nullptr) {
11422 return detail::errHandler(CL_INVALID_OPERATION,
11423 __UPDATE_MUTABLE_COMMANDS_KHR_ERR);
11424 }
11425 return detail::errHandler(pfn_clUpdateMutableCommandsKHR(object_, mutable_config),
11426 __UPDATE_MUTABLE_COMMANDS_KHR_ERR);
11427 }
11428 #endif /* cl_khr_command_buffer_mutable_dispatch */
11429
11430 private:
11431 static std::once_flag ext_init_;
11432
initExtensions(const cl::Device & device)11433 static void initExtensions(const cl::Device& device)
11434 {
11435 #if CL_HPP_TARGET_OPENCL_VERSION >= 120
11436 cl_platform_id platform = device.getInfo<CL_DEVICE_PLATFORM>()();
11437 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clCreateCommandBufferKHR);
11438 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clFinalizeCommandBufferKHR);
11439 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clRetainCommandBufferKHR);
11440 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clReleaseCommandBufferKHR);
11441 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clGetCommandBufferInfoKHR);
11442 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clEnqueueCommandBufferKHR);
11443 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clCommandBarrierWithWaitListKHR);
11444 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clCommandCopyBufferKHR);
11445 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clCommandCopyBufferRectKHR);
11446 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clCommandCopyBufferToImageKHR);
11447 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clCommandCopyImageKHR);
11448 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clCommandCopyImageToBufferKHR);
11449 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clCommandFillBufferKHR);
11450 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clCommandFillImageKHR);
11451 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clCommandNDRangeKernelKHR);
11452 #if defined(cl_khr_command_buffer_mutable_dispatch)
11453 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clUpdateMutableCommandsKHR);
11454 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clGetMutableCommandInfoKHR);
11455 #endif /* cl_khr_command_buffer_mutable_dispatch */
11456 #elif CL_HPP_TARGET_OPENCL_VERSION >= 110
11457 CL_HPP_INIT_CL_EXT_FCN_PTR_(clCreateCommandBufferKHR);
11458 CL_HPP_INIT_CL_EXT_FCN_PTR_(clFinalizeCommandBufferKHR);
11459 CL_HPP_INIT_CL_EXT_FCN_PTR_(clRetainCommandBufferKHR);
11460 CL_HPP_INIT_CL_EXT_FCN_PTR_(clReleaseCommandBufferKHR);
11461 CL_HPP_INIT_CL_EXT_FCN_PTR_(clGetCommandBufferInfoKHR);
11462 CL_HPP_INIT_CL_EXT_FCN_PTR_(clEnqueueCommandBufferKHR);
11463 CL_HPP_INIT_CL_EXT_FCN_PTR_(clCommandBarrierWithWaitListKHR);
11464 CL_HPP_INIT_CL_EXT_FCN_PTR_(clCommandCopyBufferKHR);
11465 CL_HPP_INIT_CL_EXT_FCN_PTR_(clCommandCopyBufferRectKHR);
11466 CL_HPP_INIT_CL_EXT_FCN_PTR_(clCommandCopyBufferToImageKHR);
11467 CL_HPP_INIT_CL_EXT_FCN_PTR_(clCommandCopyImageKHR);
11468 CL_HPP_INIT_CL_EXT_FCN_PTR_(clCommandCopyImageToBufferKHR);
11469 CL_HPP_INIT_CL_EXT_FCN_PTR_(clCommandFillBufferKHR);
11470 CL_HPP_INIT_CL_EXT_FCN_PTR_(clCommandFillImageKHR);
11471 CL_HPP_INIT_CL_EXT_FCN_PTR_(clCommandNDRangeKernelKHR);
11472 #if defined(cl_khr_command_buffer_mutable_dispatch)
11473 CL_HPP_INIT_CL_EXT_FCN_PTR_(clUpdateMutableCommandsKHR);
11474 CL_HPP_INIT_CL_EXT_FCN_PTR_(clGetMutableCommandInfoKHR);
11475 #endif /* cl_khr_command_buffer_mutable_dispatch */
11476 #endif
11477 if ((pfn_clCreateCommandBufferKHR == nullptr) &&
11478 (pfn_clFinalizeCommandBufferKHR == nullptr) &&
11479 (pfn_clRetainCommandBufferKHR == nullptr) &&
11480 (pfn_clReleaseCommandBufferKHR == nullptr) &&
11481 (pfn_clGetCommandBufferInfoKHR == nullptr) &&
11482 (pfn_clEnqueueCommandBufferKHR == nullptr) &&
11483 (pfn_clCommandBarrierWithWaitListKHR == nullptr) &&
11484 (pfn_clCommandCopyBufferKHR == nullptr) &&
11485 (pfn_clCommandCopyBufferRectKHR == nullptr) &&
11486 (pfn_clCommandCopyBufferToImageKHR == nullptr) &&
11487 (pfn_clCommandCopyImageKHR == nullptr) &&
11488 (pfn_clCommandCopyImageToBufferKHR == nullptr) &&
11489 (pfn_clCommandFillBufferKHR == nullptr) &&
11490 (pfn_clCommandFillImageKHR == nullptr) &&
11491 (pfn_clCommandNDRangeKernelKHR == nullptr)
11492 #if defined(cl_khr_command_buffer_mutable_dispatch)
11493 && (pfn_clUpdateMutableCommandsKHR == nullptr)
11494 && (pfn_clGetMutableCommandInfoKHR == nullptr)
11495 #endif /* cl_khr_command_buffer_mutable_dispatch */
11496 )
11497 {
11498 detail::errHandler(CL_INVALID_VALUE, __CREATE_COMMAND_BUFFER_KHR_ERR);
11499 }
11500 }
11501 }; // CommandBufferKhr
11502
11503 CL_HPP_DEFINE_STATIC_MEMBER_ std::once_flag CommandBufferKhr::ext_init_;
11504
11505 #if defined(cl_khr_command_buffer_mutable_dispatch)
11506 /*! \class MutableCommandKhr
11507 * \brief MutableCommandKhr interface for cl_mutable_command_khr.
11508 */
11509 class MutableCommandKhr : public detail::Wrapper<cl_mutable_command_khr>
11510 {
11511 public:
11512 //! \brief Default constructor - initializes to nullptr.
MutableCommandKhr()11513 MutableCommandKhr() : detail::Wrapper<cl_type>() { }
11514
MutableCommandKhr(const cl_mutable_command_khr & mutableCommandKhr,bool retainObject=false)11515 explicit MutableCommandKhr(const cl_mutable_command_khr& mutableCommandKhr, bool retainObject = false) :
11516 detail::Wrapper<cl_type>(mutableCommandKhr, retainObject) { }
11517
operator =(const cl_mutable_command_khr & rhs)11518 MutableCommandKhr& operator=(const cl_mutable_command_khr& rhs)
11519 {
11520 detail::Wrapper<cl_type>::operator=(rhs);
11521 return *this;
11522 }
11523
11524 template <typename T>
getInfo(cl_mutable_command_info_khr name,T * param) const11525 cl_int getInfo(cl_mutable_command_info_khr name, T* param) const
11526 {
11527 if (pfn_clGetMutableCommandInfoKHR == nullptr) {
11528 return detail::errHandler(CL_INVALID_OPERATION,
11529 __GET_MUTABLE_COMMAND_INFO_KHR_ERR);
11530 }
11531 return detail::errHandler(
11532 detail::getInfo(pfn_clGetMutableCommandInfoKHR, object_, name, param),
11533 __GET_MUTABLE_COMMAND_INFO_KHR_ERR);
11534 }
11535
11536 template <cl_mutable_command_info_khr name> typename
11537 detail::param_traits<detail::cl_mutable_command_info_khr, name>::param_type
getInfo(cl_int * err=nullptr) const11538 getInfo(cl_int* err = nullptr) const
11539 {
11540 typename detail::param_traits<
11541 detail::cl_mutable_command_info_khr, name>::param_type param;
11542 cl_int result = getInfo(name, ¶m);
11543 if (err != nullptr) {
11544 *err = result;
11545 }
11546 return param;
11547 }
11548 }; // MutableCommandKhr
11549 #endif /* cl_khr_command_buffer_mutable_dispatch */
11550
11551 #endif // cl_khr_command_buffer
11552 //----------------------------------------------------------------------------------------------------------------------
11553
11554 #undef CL_HPP_ERR_STR_
11555 #if !defined(CL_HPP_USER_OVERRIDE_ERROR_STRINGS)
11556 #undef __GET_DEVICE_INFO_ERR
11557 #undef __GET_PLATFORM_INFO_ERR
11558 #undef __GET_DEVICE_IDS_ERR
11559 #undef __GET_PLATFORM_IDS_ERR
11560 #undef __GET_CONTEXT_INFO_ERR
11561 #undef __GET_EVENT_INFO_ERR
11562 #undef __GET_EVENT_PROFILE_INFO_ERR
11563 #undef __GET_MEM_OBJECT_INFO_ERR
11564 #undef __GET_IMAGE_INFO_ERR
11565 #undef __GET_SAMPLER_INFO_ERR
11566 #undef __GET_KERNEL_INFO_ERR
11567 #undef __GET_KERNEL_ARG_INFO_ERR
11568 #undef __GET_KERNEL_SUB_GROUP_INFO_ERR
11569 #undef __GET_KERNEL_WORK_GROUP_INFO_ERR
11570 #undef __GET_PROGRAM_INFO_ERR
11571 #undef __GET_PROGRAM_BUILD_INFO_ERR
11572 #undef __GET_COMMAND_QUEUE_INFO_ERR
11573 #undef __CREATE_CONTEXT_ERR
11574 #undef __CREATE_CONTEXT_FROM_TYPE_ERR
11575 #undef __CREATE_COMMAND_BUFFER_KHR_ERR
11576 #undef __GET_COMMAND_BUFFER_INFO_KHR_ERR
11577 #undef __FINALIZE_COMMAND_BUFFER_KHR_ERR
11578 #undef __ENQUEUE_COMMAND_BUFFER_KHR_ERR
11579 #undef __COMMAND_BARRIER_WITH_WAIT_LIST_KHR_ERR
11580 #undef __COMMAND_COPY_BUFFER_KHR_ERR
11581 #undef __COMMAND_COPY_BUFFER_RECT_KHR_ERR
11582 #undef __COMMAND_COPY_BUFFER_TO_IMAGE_KHR_ERR
11583 #undef __COMMAND_COPY_IMAGE_KHR_ERR
11584 #undef __COMMAND_COPY_IMAGE_TO_BUFFER_KHR_ERR
11585 #undef __COMMAND_FILL_BUFFER_KHR_ERR
11586 #undef __COMMAND_FILL_IMAGE_KHR_ERR
11587 #undef __COMMAND_NDRANGE_KERNEL_KHR_ERR
11588 #undef __UPDATE_MUTABLE_COMMANDS_KHR_ERR
11589 #undef __GET_MUTABLE_COMMAND_INFO_KHR_ERR
11590 #undef __RETAIN_COMMAND_BUFFER_KHR_ERR
11591 #undef __RELEASE_COMMAND_BUFFER_KHR_ERR
11592 #undef __GET_SUPPORTED_IMAGE_FORMATS_ERR
11593 #undef __SET_CONTEXT_DESCTRUCTOR_CALLBACK_ERR
11594 #undef __CREATE_BUFFER_ERR
11595 #undef __COPY_ERR
11596 #undef __CREATE_SUBBUFFER_ERR
11597 #undef __CREATE_GL_BUFFER_ERR
11598 #undef __CREATE_GL_RENDER_BUFFER_ERR
11599 #undef __GET_GL_OBJECT_INFO_ERR
11600 #undef __CREATE_IMAGE_ERR
11601 #undef __CREATE_GL_TEXTURE_ERR
11602 #undef __IMAGE_DIMENSION_ERR
11603 #undef __SET_MEM_OBJECT_DESTRUCTOR_CALLBACK_ERR
11604 #undef __CREATE_USER_EVENT_ERR
11605 #undef __SET_USER_EVENT_STATUS_ERR
11606 #undef __SET_EVENT_CALLBACK_ERR
11607 #undef __WAIT_FOR_EVENTS_ERR
11608 #undef __CREATE_KERNEL_ERR
11609 #undef __SET_KERNEL_ARGS_ERR
11610 #undef __CREATE_PROGRAM_WITH_SOURCE_ERR
11611 #undef __CREATE_PROGRAM_WITH_BINARY_ERR
11612 #undef __CREATE_PROGRAM_WITH_IL_ERR
11613 #undef __CREATE_PROGRAM_WITH_BUILT_IN_KERNELS_ERR
11614 #undef __BUILD_PROGRAM_ERR
11615 #undef __COMPILE_PROGRAM_ERR
11616 #undef __LINK_PROGRAM_ERR
11617 #undef __CREATE_KERNELS_IN_PROGRAM_ERR
11618 #undef __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR
11619 #undef __CREATE_SAMPLER_WITH_PROPERTIES_ERR
11620 #undef __SET_COMMAND_QUEUE_PROPERTY_ERR
11621 #undef __ENQUEUE_READ_BUFFER_ERR
11622 #undef __ENQUEUE_READ_BUFFER_RECT_ERR
11623 #undef __ENQUEUE_WRITE_BUFFER_ERR
11624 #undef __ENQUEUE_WRITE_BUFFER_RECT_ERR
11625 #undef __ENQEUE_COPY_BUFFER_ERR
11626 #undef __ENQEUE_COPY_BUFFER_RECT_ERR
11627 #undef __ENQUEUE_FILL_BUFFER_ERR
11628 #undef __ENQUEUE_READ_IMAGE_ERR
11629 #undef __ENQUEUE_WRITE_IMAGE_ERR
11630 #undef __ENQUEUE_COPY_IMAGE_ERR
11631 #undef __ENQUEUE_FILL_IMAGE_ERR
11632 #undef __ENQUEUE_COPY_IMAGE_TO_BUFFER_ERR
11633 #undef __ENQUEUE_COPY_BUFFER_TO_IMAGE_ERR
11634 #undef __ENQUEUE_MAP_BUFFER_ERR
11635 #undef __ENQUEUE_MAP_IMAGE_ERR
11636 #undef __ENQUEUE_MAP_SVM_ERR
11637 #undef __ENQUEUE_FILL_SVM_ERR
11638 #undef __ENQUEUE_COPY_SVM_ERR
11639 #undef __ENQUEUE_UNMAP_SVM_ERR
11640 #undef __ENQUEUE_MAP_IMAGE_ERR
11641 #undef __ENQUEUE_UNMAP_MEM_OBJECT_ERR
11642 #undef __ENQUEUE_NDRANGE_KERNEL_ERR
11643 #undef __ENQUEUE_NATIVE_KERNEL
11644 #undef __ENQUEUE_MIGRATE_MEM_OBJECTS_ERR
11645 #undef __ENQUEUE_MIGRATE_SVM_ERR
11646 #undef __ENQUEUE_ACQUIRE_GL_ERR
11647 #undef __ENQUEUE_RELEASE_GL_ERR
11648 #undef __CREATE_PIPE_ERR
11649 #undef __GET_PIPE_INFO_ERR
11650 #undef __RETAIN_ERR
11651 #undef __RELEASE_ERR
11652 #undef __FLUSH_ERR
11653 #undef __FINISH_ERR
11654 #undef __VECTOR_CAPACITY_ERR
11655 #undef __CREATE_SUB_DEVICES_ERR
11656 #undef __ENQUEUE_ACQUIRE_EXTERNAL_MEMORY_ERR
11657 #undef __ENQUEUE_RELEASE_EXTERNAL_MEMORY_ERR
11658 #undef __ENQUEUE_MARKER_ERR
11659 #undef __ENQUEUE_WAIT_FOR_EVENTS_ERR
11660 #undef __ENQUEUE_BARRIER_ERR
11661 #undef __UNLOAD_COMPILER_ERR
11662 #undef __CREATE_GL_TEXTURE_2D_ERR
11663 #undef __CREATE_GL_TEXTURE_3D_ERR
11664 #undef __CREATE_IMAGE2D_ERR
11665 #undef __CREATE_IMAGE3D_ERR
11666 #undef __CREATE_COMMAND_QUEUE_ERR
11667 #undef __ENQUEUE_TASK_ERR
11668 #undef __CREATE_SAMPLER_ERR
11669 #undef __ENQUEUE_MARKER_WAIT_LIST_ERR
11670 #undef __ENQUEUE_BARRIER_WAIT_LIST_ERR
11671 #undef __CLONE_KERNEL_ERR
11672 #undef __GET_HOST_TIMER_ERR
11673 #undef __GET_DEVICE_AND_HOST_TIMER_ERR
11674 #undef __GET_SEMAPHORE_KHR_INFO_ERR
11675 #undef __CREATE_SEMAPHORE_KHR_WITH_PROPERTIES_ERR
11676 #undef __GET_IMAGE_REQUIREMENT_INFO_EXT_ERR
11677 #undef __ENQUEUE_WAIT_SEMAPHORE_KHR_ERR
11678 #undef __ENQUEUE_SIGNAL_SEMAPHORE_KHR_ERR
11679 #undef __RETAIN_SEMAPHORE_KHR_ERR
11680 #undef __RELEASE_SEMAPHORE_KHR_ERR
11681 #undef __GET_SEMAPHORE_HANDLE_FOR_TYPE_KHR_ERR
11682
11683 #endif //CL_HPP_USER_OVERRIDE_ERROR_STRINGS
11684
11685 // Extensions
11686 #undef CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_
11687 #undef CL_HPP_INIT_CL_EXT_FCN_PTR_
11688 #undef CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_
11689
11690 #undef CL_HPP_DEFINE_STATIC_MEMBER_
11691
11692 } // namespace cl
11693
11694 #endif // CL_HPP_
11695