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