blob: d8d227e1b2d6c86343651ca54dfebe4c133424b6 [file] [log] [blame]
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00001//
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01002// Copyright (c) 2008-2023 The Khronos Group Inc.
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00003//
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//
Anthony Barbier6ff3b192017-09-04 18:44:23 +010016
17/*! \file
18 *
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +000019 * \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.
Anthony Barbier6ff3b192017-09-04 18:44:23 +010021 * \author Lee Howes and Bruce Merry
Anthony Barbier8b2fdc92018-08-09 11:42:38 +010022 *
23 * Derived from the OpenCL 1.x C++ bindings written by
Anthony Barbier6ff3b192017-09-04 18:44:23 +010024 * 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
Anthony Barbier8b2fdc92018-08-09 11:42:38 +010030 * James Price, 2015-
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +000031 * \version 2.2.0
32 * \date 2019-09-18
Anthony Barbier6ff3b192017-09-04 18:44:23 +010033 *
34 * Optional extension support
35 *
Anthony Barbier6ff3b192017-09-04 18:44:23 +010036 * cl_khr_d3d10_sharing
37 * #define CL_HPP_USE_DX_INTEROP
Viet-Hoa Do633ebd12023-08-11 12:27:59 +010038 * cl_khr_il_program
39 * #define CL_HPP_USE_IL_KHR
Anthony Barbier6ff3b192017-09-04 18:44:23 +010040 * cl_khr_sub_groups
41 * #define CL_HPP_USE_CL_SUB_GROUPS_KHR
Anthony Barbier8b2fdc92018-08-09 11:42:38 +010042 *
43 * Doxygen documentation for this header is available here:
44 *
45 * http://khronosgroup.github.io/OpenCL-CLHPP/
46 *
47 * The latest version of this header can be found on the GitHub releases page:
48 *
49 * https://github.com/KhronosGroup/OpenCL-CLHPP/releases
50 *
51 * Bugs and patches can be submitted to the GitHub repository:
52 *
53 * https://github.com/KhronosGroup/OpenCL-CLHPP
Anthony Barbier6ff3b192017-09-04 18:44:23 +010054 */
55
56/*! \mainpage
57 * \section intro Introduction
58 * For many large applications C++ is the language of choice and so it seems
59 * reasonable to define C++ bindings for OpenCL.
60 *
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +000061 * The interface is contained with a single C++ header file \em opencl.hpp and all
Anthony Barbier6ff3b192017-09-04 18:44:23 +010062 * definitions are contained within the namespace \em cl. There is no additional
63 * requirement to include \em cl.h and to use either the C++ or original C
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +000064 * bindings; it is enough to simply include \em opencl.hpp.
Anthony Barbier6ff3b192017-09-04 18:44:23 +010065 *
66 * The bindings themselves are lightweight and correspond closely to the
67 * underlying C API. Using the C++ bindings introduces no additional execution
68 * overhead.
69 *
70 * There are numerous compatibility, portability and memory management
71 * fixes in the new header as well as additional OpenCL 2.0 features.
72 * As a result the header is not directly backward compatible and for this
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +000073 * reason we release it as opencl.hpp rather than a new version of cl.hpp.
Anthony Barbier6ff3b192017-09-04 18:44:23 +010074 *
75 *
76 * \section compatibility Compatibility
77 * Due to the evolution of the underlying OpenCL API the 2.0 C++ bindings
78 * include an updated approach to defining supported feature versions
79 * and the range of valid underlying OpenCL runtime versions supported.
80 *
81 * The combination of preprocessor macros CL_HPP_TARGET_OPENCL_VERSION and
82 * CL_HPP_MINIMUM_OPENCL_VERSION control this range. These are three digit
Viet-Hoa Do633ebd12023-08-11 12:27:59 +010083 * decimal values representing OpenCL runtime versions. The default for
84 * the target is 300, representing OpenCL 3.0. The minimum is defined as 200.
85 * These settings would use 2.0 and newer API calls only.
Anthony Barbier6ff3b192017-09-04 18:44:23 +010086 * If backward compatibility with a 1.2 runtime is required, the minimum
87 * version may be set to 120.
88 *
89 * Note that this is a compile-time setting, and so affects linking against
90 * a particular SDK version rather than the versioning of the loaded runtime.
91 *
92 * The earlier versions of the header included basic vector and string
93 * classes based loosely on STL versions. These were difficult to
94 * maintain and very rarely used. For the 2.0 header we now assume
95 * the presence of the standard library unless requested otherwise.
96 * We use std::array, std::vector, std::shared_ptr and std::string
97 * throughout to safely manage memory and reduce the chance of a
98 * recurrance of earlier memory management bugs.
99 *
100 * These classes are used through typedefs in the cl namespace:
101 * cl::array, cl::vector, cl::pointer and cl::string.
102 * In addition cl::allocate_pointer forwards to std::allocate_shared
103 * by default.
104 * In all cases these standard library classes can be replaced with
105 * custom interface-compatible versions using the CL_HPP_NO_STD_ARRAY,
106 * CL_HPP_NO_STD_VECTOR, CL_HPP_NO_STD_UNIQUE_PTR and
107 * CL_HPP_NO_STD_STRING macros.
108 *
109 * The OpenCL 1.x versions of the C++ bindings included a size_t wrapper
110 * class to interface with kernel enqueue. This caused unpleasant interactions
111 * with the standard size_t declaration and led to namespacing bugs.
112 * In the 2.0 version we have replaced this with a std::array-based interface.
113 * However, the old behaviour can be regained for backward compatibility
114 * using the CL_HPP_ENABLE_SIZE_T_COMPATIBILITY macro.
115 *
116 * Finally, the program construction interface used a clumsy vector-of-pairs
117 * design in the earlier versions. We have replaced that with a cleaner
118 * vector-of-vectors and vector-of-strings design. However, for backward
119 * compatibility old behaviour can be regained with the
120 * CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY macro.
121 *
122 * In OpenCL 2.0 OpenCL C is not entirely backward compatibility with
123 * earlier versions. As a result a flag must be passed to the OpenCL C
124 * compiled to request OpenCL 2.0 compilation of kernels with 1.2 as
125 * the default in the absence of the flag.
126 * In some cases the C++ bindings automatically compile code for ease.
127 * For those cases the compilation defaults to OpenCL C 2.0.
128 * If this is not wanted, the CL_HPP_CL_1_2_DEFAULT_BUILD macro may
129 * be specified to assume 1.2 compilation.
130 * If more fine-grained decisions on a per-kernel bases are required
131 * then explicit build operations that take the flag should be used.
132 *
133 *
134 * \section parameterization Parameters
135 * This header may be parameterized by a set of preprocessor macros.
Anthony Barbier8b2fdc92018-08-09 11:42:38 +0100136 *
137 * - CL_HPP_TARGET_OPENCL_VERSION
138 *
139 * Defines the target OpenCL runtime version to build the header
Viet-Hoa Do633ebd12023-08-11 12:27:59 +0100140 * against. Defaults to 300, representing OpenCL 3.0.
141 *
142 * - CL_HPP_MINIMUM_OPENCL_VERSION
143 *
144 * Defines the minimum OpenCL runtime version to build the header
Anthony Barbier8b2fdc92018-08-09 11:42:38 +0100145 * against. Defaults to 200, representing OpenCL 2.0.
146 *
147 * - CL_HPP_NO_STD_STRING
148 *
149 * Do not use the standard library string class. cl::string is not
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +0000150 * defined and may be defined by the user before opencl.hpp is
Anthony Barbier8b2fdc92018-08-09 11:42:38 +0100151 * included.
152 *
153 * - CL_HPP_NO_STD_VECTOR
154 *
155 * Do not use the standard library vector class. cl::vector is not
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +0000156 * defined and may be defined by the user before opencl.hpp is
Anthony Barbier8b2fdc92018-08-09 11:42:38 +0100157 * included.
158 *
159 * - CL_HPP_NO_STD_ARRAY
160 *
161 * Do not use the standard library array class. cl::array is not
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +0000162 * defined and may be defined by the user before opencl.hpp is
Anthony Barbier8b2fdc92018-08-09 11:42:38 +0100163 * included.
164 *
165 * - CL_HPP_NO_STD_UNIQUE_PTR
166 *
167 * Do not use the standard library unique_ptr class. cl::pointer and
168 * the cl::allocate_pointer functions are not defined and may be
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +0000169 * defined by the user before opencl.hpp is included.
Anthony Barbier8b2fdc92018-08-09 11:42:38 +0100170 *
Anthony Barbier8b2fdc92018-08-09 11:42:38 +0100171 * - CL_HPP_ENABLE_EXCEPTIONS
172 *
173 * Enable exceptions for use in the C++ bindings header. This is the
174 * preferred error handling mechanism but is not required.
175 *
176 * - CL_HPP_ENABLE_SIZE_T_COMPATIBILITY
177 *
178 * Backward compatibility option to support cl.hpp-style size_t
179 * class. Replaces the updated std::array derived version and
180 * removal of size_t from the namespace. Note that in this case the
181 * new size_t class is placed in the cl::compatibility namespace and
182 * thus requires an additional using declaration for direct backward
183 * compatibility.
184 *
185 * - CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY
186 *
187 * Enable older vector of pairs interface for construction of
188 * programs.
189 *
190 * - CL_HPP_CL_1_2_DEFAULT_BUILD
191 *
192 * Default to OpenCL C 1.2 compilation rather than OpenCL C 2.0
193 * applies to use of cl::Program construction and other program
194 * build variants.
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100195 *
Viet-Hoa Do633ebd12023-08-11 12:27:59 +0100196 *
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +0000197 * - CL_HPP_USE_CL_SUB_GROUPS_KHR
198 *
199 * Enable the cl_khr_subgroups extension.
200 *
Viet-Hoa Do633ebd12023-08-11 12:27:59 +0100201 * - CL_HPP_USE_DX_INTEROP
202 *
203 * Enable the cl_khr_d3d10_sharing extension.
204 *
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +0000205 * - CL_HPP_USE_IL_KHR
206 *
207 * Enable the cl_khr_il_program extension.
208 *
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100209 *
210 * \section example Example
211 *
212 * The following example shows a general use case for the C++
213 * bindings, including support for the optional exception feature and
214 * also the supplied vector and string classes, see following sections for
215 * decriptions of these features.
Viet-Hoa Do633ebd12023-08-11 12:27:59 +0100216 *
217 * Note: the C++ bindings use std::call_once and therefore may need to be
218 * compiled using special command-line options (such as "-pthread") on some
219 * platforms!
Anthony Barbier8b2fdc92018-08-09 11:42:38 +0100220 *
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100221 * \code
222 #define CL_HPP_ENABLE_EXCEPTIONS
223 #define CL_HPP_TARGET_OPENCL_VERSION 200
Anthony Barbier8b2fdc92018-08-09 11:42:38 +0100224
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +0000225 #include <CL/opencl.hpp>
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100226 #include <iostream>
227 #include <vector>
228 #include <memory>
229 #include <algorithm>
Anthony Barbier8b2fdc92018-08-09 11:42:38 +0100230
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100231 const int numElements = 32;
Anthony Barbier8b2fdc92018-08-09 11:42:38 +0100232
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100233 int main(void)
234 {
Viet-Hoa Do633ebd12023-08-11 12:27:59 +0100235 // Filter for a 2.0 or newer platform and set it as the default
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100236 std::vector<cl::Platform> platforms;
237 cl::Platform::get(&platforms);
238 cl::Platform plat;
239 for (auto &p : platforms) {
240 std::string platver = p.getInfo<CL_PLATFORM_VERSION>();
Viet-Hoa Do633ebd12023-08-11 12:27:59 +0100241 if (platver.find("OpenCL 2.") != std::string::npos ||
242 platver.find("OpenCL 3.") != std::string::npos) {
243 // Note: an OpenCL 3.x platform may not support all required features!
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100244 plat = p;
245 }
246 }
Viet-Hoa Do633ebd12023-08-11 12:27:59 +0100247 if (plat() == 0) {
248 std::cout << "No OpenCL 2.0 or newer platform found.\n";
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100249 return -1;
250 }
251
252 cl::Platform newP = cl::Platform::setDefault(plat);
253 if (newP != plat) {
Viet-Hoa Do633ebd12023-08-11 12:27:59 +0100254 std::cout << "Error setting default platform.\n";
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100255 return -1;
256 }
Anthony Barbier8b2fdc92018-08-09 11:42:38 +0100257
Viet-Hoa Do633ebd12023-08-11 12:27:59 +0100258 // C++11 raw string literal for the first kernel
Anthony Barbier8b2fdc92018-08-09 11:42:38 +0100259 std::string kernel1{R"CLC(
260 global int globalA;
261 kernel void updateGlobal()
262 {
263 globalA = 75;
264 }
265 )CLC"};
Viet-Hoa Do633ebd12023-08-11 12:27:59 +0100266
267 // Raw string literal for the second kernel
Anthony Barbier8b2fdc92018-08-09 11:42:38 +0100268 std::string kernel2{R"CLC(
269 typedef struct { global int *bar; } Foo;
270 kernel void vectorAdd(global const Foo* aNum, global const int *inputA, global const int *inputB,
271 global int *output, int val, write_only pipe int outPipe, queue_t childQueue)
272 {
273 output[get_global_id(0)] = inputA[get_global_id(0)] + inputB[get_global_id(0)] + val + *(aNum->bar);
274 write_pipe(outPipe, &val);
275 queue_t default_queue = get_default_queue();
276 ndrange_t ndrange = ndrange_1D(get_global_size(0)/2, get_global_size(0)/2);
277
278 // Have a child kernel write into third quarter of output
279 enqueue_kernel(default_queue, CLK_ENQUEUE_FLAGS_WAIT_KERNEL, ndrange,
280 ^{
281 output[get_global_size(0)*2 + get_global_id(0)] =
282 inputA[get_global_size(0)*2 + get_global_id(0)] + inputB[get_global_size(0)*2 + get_global_id(0)] + globalA;
283 });
284
285 // Have a child kernel write into last quarter of output
286 enqueue_kernel(childQueue, CLK_ENQUEUE_FLAGS_WAIT_KERNEL, ndrange,
287 ^{
288 output[get_global_size(0)*3 + get_global_id(0)] =
289 inputA[get_global_size(0)*3 + get_global_id(0)] + inputB[get_global_size(0)*3 + get_global_id(0)] + globalA + 2;
290 });
291 }
292 )CLC"};
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100293
Viet-Hoa Do633ebd12023-08-11 12:27:59 +0100294 std::vector<std::string> programStrings;
295 programStrings.push_back(kernel1);
296 programStrings.push_back(kernel2);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100297
Anthony Barbier8b2fdc92018-08-09 11:42:38 +0100298 cl::Program vectorAddProgram(programStrings);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100299 try {
300 vectorAddProgram.build("-cl-std=CL2.0");
301 }
302 catch (...) {
303 // Print build info for all devices
304 cl_int buildErr = CL_SUCCESS;
305 auto buildInfo = vectorAddProgram.getBuildInfo<CL_PROGRAM_BUILD_LOG>(&buildErr);
306 for (auto &pair : buildInfo) {
307 std::cerr << pair.second << std::endl << std::endl;
308 }
Anthony Barbier8b2fdc92018-08-09 11:42:38 +0100309
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100310 return 1;
311 }
312
313 typedef struct { int *bar; } Foo;
314
315 // Get and run kernel that initializes the program-scope global
316 // A test for kernels that take no arguments
317 auto program2Kernel =
318 cl::KernelFunctor<>(vectorAddProgram, "updateGlobal");
319 program2Kernel(
320 cl::EnqueueArgs(
321 cl::NDRange(1)));
Anthony Barbier8b2fdc92018-08-09 11:42:38 +0100322
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100323 //////////////////
324 // SVM allocations
Anthony Barbier8b2fdc92018-08-09 11:42:38 +0100325
326 auto anSVMInt = cl::allocate_svm<int, cl::SVMTraitCoarse<>>();
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100327 *anSVMInt = 5;
Anthony Barbier8b2fdc92018-08-09 11:42:38 +0100328 cl::SVMAllocator<Foo, cl::SVMTraitCoarse<cl::SVMTraitReadOnly<>>> svmAllocReadOnly;
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100329 auto fooPointer = cl::allocate_pointer<Foo>(svmAllocReadOnly);
330 fooPointer->bar = anSVMInt.get();
331 cl::SVMAllocator<int, cl::SVMTraitCoarse<>> svmAlloc;
Anthony Barbier8b2fdc92018-08-09 11:42:38 +0100332 std::vector<int, cl::SVMAllocator<int, cl::SVMTraitCoarse<>>> inputA(numElements, 1, svmAlloc);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100333 cl::coarse_svm_vector<int> inputB(numElements, 2, svmAlloc);
334
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100335 //////////////
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100336 // Traditional cl_mem allocations
Viet-Hoa Do633ebd12023-08-11 12:27:59 +0100337
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100338 std::vector<int> output(numElements, 0xdeadbeef);
339 cl::Buffer outputBuffer(begin(output), end(output), false);
340 cl::Pipe aPipe(sizeof(cl_int), numElements / 2);
Anthony Barbier8b2fdc92018-08-09 11:42:38 +0100341
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100342 // Default command queue, also passed in as a parameter
343 cl::DeviceCommandQueue defaultDeviceQueue = cl::DeviceCommandQueue::makeDefault(
344 cl::Context::getDefault(), cl::Device::getDefault());
345
346 auto vectorAddKernel =
347 cl::KernelFunctor<
348 decltype(fooPointer)&,
349 int*,
350 cl::coarse_svm_vector<int>&,
351 cl::Buffer,
352 int,
353 cl::Pipe&,
354 cl::DeviceCommandQueue
355 >(vectorAddProgram, "vectorAdd");
356
357 // Ensure that the additional SVM pointer is available to the kernel
358 // This one was not passed as a parameter
359 vectorAddKernel.setSVMPointers(anSVMInt);
360
Viet-Hoa Do633ebd12023-08-11 12:27:59 +0100361 cl_int error;
362 vectorAddKernel(
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100363 cl::EnqueueArgs(
364 cl::NDRange(numElements/2),
365 cl::NDRange(numElements/2)),
366 fooPointer,
367 inputA.data(),
368 inputB,
369 outputBuffer,
370 3,
371 aPipe,
372 defaultDeviceQueue,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +0100373 error
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100374 );
375
376 cl::copy(outputBuffer, begin(output), end(output));
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100377
378 cl::Device d = cl::Device::getDefault();
379
380 std::cout << "Output:\n";
381 for (int i = 1; i < numElements; ++i) {
382 std::cout << "\t" << output[i] << "\n";
383 }
384 std::cout << "\n\n";
385
386 return 0;
387 }
Anthony Barbier8b2fdc92018-08-09 11:42:38 +0100388 *
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100389 * \endcode
390 *
391 */
392#ifndef CL_HPP_
393#define CL_HPP_
394
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100395/* Handle deprecated preprocessor definitions. In each case, we only check for
396 * the old name if the new name is not defined, so that user code can define
397 * both and hence work with either version of the bindings.
398 */
399#if !defined(CL_HPP_USE_DX_INTEROP) && defined(USE_DX_INTEROP)
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +0000400# pragma message("opencl.hpp: USE_DX_INTEROP is deprecated. Define CL_HPP_USE_DX_INTEROP instead")
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100401# define CL_HPP_USE_DX_INTEROP
402#endif
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100403#if !defined(CL_HPP_ENABLE_EXCEPTIONS) && defined(__CL_ENABLE_EXCEPTIONS)
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +0000404# pragma message("opencl.hpp: __CL_ENABLE_EXCEPTIONS is deprecated. Define CL_HPP_ENABLE_EXCEPTIONS instead")
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100405# define CL_HPP_ENABLE_EXCEPTIONS
406#endif
407#if !defined(CL_HPP_NO_STD_VECTOR) && defined(__NO_STD_VECTOR)
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +0000408# pragma message("opencl.hpp: __NO_STD_VECTOR is deprecated. Define CL_HPP_NO_STD_VECTOR instead")
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100409# define CL_HPP_NO_STD_VECTOR
410#endif
411#if !defined(CL_HPP_NO_STD_STRING) && defined(__NO_STD_STRING)
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +0000412# pragma message("opencl.hpp: __NO_STD_STRING is deprecated. Define CL_HPP_NO_STD_STRING instead")
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100413# define CL_HPP_NO_STD_STRING
414#endif
415#if defined(VECTOR_CLASS)
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +0000416# pragma message("opencl.hpp: VECTOR_CLASS is deprecated. Alias cl::vector instead")
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100417#endif
418#if defined(STRING_CLASS)
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +0000419# pragma message("opencl.hpp: STRING_CLASS is deprecated. Alias cl::string instead.")
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100420#endif
421#if !defined(CL_HPP_USER_OVERRIDE_ERROR_STRINGS) && defined(__CL_USER_OVERRIDE_ERROR_STRINGS)
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +0000422# pragma message("opencl.hpp: __CL_USER_OVERRIDE_ERROR_STRINGS is deprecated. Define CL_HPP_USER_OVERRIDE_ERROR_STRINGS instead")
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100423# define CL_HPP_USER_OVERRIDE_ERROR_STRINGS
424#endif
425
426/* Warn about features that are no longer supported
427 */
428#if defined(__USE_DEV_VECTOR)
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +0000429# pragma message("opencl.hpp: __USE_DEV_VECTOR is no longer supported. Expect compilation errors")
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100430#endif
431#if defined(__USE_DEV_STRING)
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +0000432# pragma message("opencl.hpp: __USE_DEV_STRING is no longer supported. Expect compilation errors")
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100433#endif
434
435/* Detect which version to target */
436#if !defined(CL_HPP_TARGET_OPENCL_VERSION)
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +0000437# pragma message("opencl.hpp: CL_HPP_TARGET_OPENCL_VERSION is not defined. It will default to 300 (OpenCL 3.0)")
438# define CL_HPP_TARGET_OPENCL_VERSION 300
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100439#endif
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +0000440#if CL_HPP_TARGET_OPENCL_VERSION != 100 && \
441 CL_HPP_TARGET_OPENCL_VERSION != 110 && \
442 CL_HPP_TARGET_OPENCL_VERSION != 120 && \
443 CL_HPP_TARGET_OPENCL_VERSION != 200 && \
444 CL_HPP_TARGET_OPENCL_VERSION != 210 && \
445 CL_HPP_TARGET_OPENCL_VERSION != 220 && \
446 CL_HPP_TARGET_OPENCL_VERSION != 300
447# pragma message("opencl.hpp: CL_HPP_TARGET_OPENCL_VERSION is not a valid value (100, 110, 120, 200, 210, 220 or 300). It will be set to 300 (OpenCL 3.0).")
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100448# undef CL_HPP_TARGET_OPENCL_VERSION
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +0000449# define CL_HPP_TARGET_OPENCL_VERSION 300
450#endif
451
452/* Forward target OpenCL version to C headers if necessary */
453#if defined(CL_TARGET_OPENCL_VERSION)
454/* Warn if prior definition of CL_TARGET_OPENCL_VERSION is lower than
455 * requested C++ bindings version */
456#if CL_TARGET_OPENCL_VERSION < CL_HPP_TARGET_OPENCL_VERSION
457# pragma message("CL_TARGET_OPENCL_VERSION is already defined as is lower than CL_HPP_TARGET_OPENCL_VERSION")
458#endif
459#else
460# define CL_TARGET_OPENCL_VERSION CL_HPP_TARGET_OPENCL_VERSION
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100461#endif
462
463#if !defined(CL_HPP_MINIMUM_OPENCL_VERSION)
464# define CL_HPP_MINIMUM_OPENCL_VERSION 200
465#endif
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +0000466#if CL_HPP_MINIMUM_OPENCL_VERSION != 100 && \
467 CL_HPP_MINIMUM_OPENCL_VERSION != 110 && \
468 CL_HPP_MINIMUM_OPENCL_VERSION != 120 && \
469 CL_HPP_MINIMUM_OPENCL_VERSION != 200 && \
470 CL_HPP_MINIMUM_OPENCL_VERSION != 210 && \
471 CL_HPP_MINIMUM_OPENCL_VERSION != 220 && \
472 CL_HPP_MINIMUM_OPENCL_VERSION != 300
473# pragma message("opencl.hpp: CL_HPP_MINIMUM_OPENCL_VERSION is not a valid value (100, 110, 120, 200, 210, 220 or 300). It will be set to 100")
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100474# undef CL_HPP_MINIMUM_OPENCL_VERSION
475# define CL_HPP_MINIMUM_OPENCL_VERSION 100
476#endif
477#if CL_HPP_MINIMUM_OPENCL_VERSION > CL_HPP_TARGET_OPENCL_VERSION
478# error "CL_HPP_MINIMUM_OPENCL_VERSION must not be greater than CL_HPP_TARGET_OPENCL_VERSION"
479#endif
480
481#if CL_HPP_MINIMUM_OPENCL_VERSION <= 100 && !defined(CL_USE_DEPRECATED_OPENCL_1_0_APIS)
482# define CL_USE_DEPRECATED_OPENCL_1_0_APIS
483#endif
484#if CL_HPP_MINIMUM_OPENCL_VERSION <= 110 && !defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
485# define CL_USE_DEPRECATED_OPENCL_1_1_APIS
486#endif
487#if CL_HPP_MINIMUM_OPENCL_VERSION <= 120 && !defined(CL_USE_DEPRECATED_OPENCL_1_2_APIS)
488# define CL_USE_DEPRECATED_OPENCL_1_2_APIS
489#endif
490#if CL_HPP_MINIMUM_OPENCL_VERSION <= 200 && !defined(CL_USE_DEPRECATED_OPENCL_2_0_APIS)
491# define CL_USE_DEPRECATED_OPENCL_2_0_APIS
492#endif
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +0000493#if CL_HPP_MINIMUM_OPENCL_VERSION <= 210 && !defined(CL_USE_DEPRECATED_OPENCL_2_1_APIS)
494# define CL_USE_DEPRECATED_OPENCL_2_1_APIS
495#endif
496#if CL_HPP_MINIMUM_OPENCL_VERSION <= 220 && !defined(CL_USE_DEPRECATED_OPENCL_2_2_APIS)
497# define CL_USE_DEPRECATED_OPENCL_2_2_APIS
498#endif
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100499
500#ifdef _WIN32
501
502#include <malloc.h>
503
504#if defined(CL_HPP_USE_DX_INTEROP)
505#include <CL/cl_d3d10.h>
506#include <CL/cl_dx9_media_sharing.h>
507#endif
508#endif // _WIN32
509
510#if defined(_MSC_VER)
511#include <intrin.h>
512#endif // _MSC_VER
513
514 // Check for a valid C++ version
515
516// Need to do both tests here because for some reason __cplusplus is not
517// updated in visual studio
518#if (!defined(_MSC_VER) && __cplusplus < 201103L) || (defined(_MSC_VER) && _MSC_VER < 1700)
519#error Visual studio 2013 or another C++11-supporting compiler required
520#endif
521
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100522#if defined(__APPLE__) || defined(__MACOSX)
523#include <OpenCL/opencl.h>
524#else
525#include <CL/opencl.h>
526#endif // !__APPLE__
527
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +0000528#if (__cplusplus >= 201103L || _MSVC_LANG >= 201103L )
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100529#define CL_HPP_NOEXCEPT_ noexcept
530#else
531#define CL_HPP_NOEXCEPT_
532#endif
533
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +0000534#if __cplusplus >= 201703L
535# define CL_HPP_DEFINE_STATIC_MEMBER_ inline
536#elif defined(_MSC_VER)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100537# define CL_HPP_DEFINE_STATIC_MEMBER_ __declspec(selectany)
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +0000538#elif defined(__MINGW32__)
539# define CL_HPP_DEFINE_STATIC_MEMBER_ __attribute__((selectany))
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100540#else
541# define CL_HPP_DEFINE_STATIC_MEMBER_ __attribute__((weak))
542#endif // !_MSC_VER
543
544// Define deprecated prefixes and suffixes to ensure compilation
545// in case they are not pre-defined
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +0000546#if !defined(CL_API_PREFIX__VERSION_1_1_DEPRECATED)
Viet-Hoa Do633ebd12023-08-11 12:27:59 +0100547#define CL_API_PREFIX__VERSION_1_1_DEPRECATED
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +0000548#endif // #if !defined(CL_API_PREFIX__VERSION_1_1_DEPRECATED)
549#if !defined(CL_API_SUFFIX__VERSION_1_1_DEPRECATED)
550#define CL_API_SUFFIX__VERSION_1_1_DEPRECATED
Viet-Hoa Do633ebd12023-08-11 12:27:59 +0100551#endif // #if !defined(CL_API_SUFFIX__VERSION_1_1_DEPRECATED)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100552
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +0000553#if !defined(CL_API_PREFIX__VERSION_1_2_DEPRECATED)
Viet-Hoa Do633ebd12023-08-11 12:27:59 +0100554#define CL_API_PREFIX__VERSION_1_2_DEPRECATED
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +0000555#endif // #if !defined(CL_API_PREFIX__VERSION_1_2_DEPRECATED)
556#if !defined(CL_API_SUFFIX__VERSION_1_2_DEPRECATED)
557#define CL_API_SUFFIX__VERSION_1_2_DEPRECATED
Viet-Hoa Do633ebd12023-08-11 12:27:59 +0100558#endif // #if !defined(CL_API_SUFFIX__VERSION_1_2_DEPRECATED)
559
560#if !defined(CL_API_PREFIX__VERSION_2_2_DEPRECATED)
561#define CL_API_PREFIX__VERSION_2_2_DEPRECATED
562#endif // #if !defined(CL_API_PREFIX__VERSION_2_2_DEPRECATED)
563#if !defined(CL_API_SUFFIX__VERSION_2_2_DEPRECATED)
564#define CL_API_SUFFIX__VERSION_2_2_DEPRECATED
565#endif // #if !defined(CL_API_SUFFIX__VERSION_2_2_DEPRECATED)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100566
567#if !defined(CL_CALLBACK)
568#define CL_CALLBACK
569#endif //CL_CALLBACK
570
571#include <utility>
572#include <limits>
573#include <iterator>
574#include <mutex>
575#include <cstring>
576#include <functional>
577
578
579// Define a size_type to represent a correctly resolved size_t
580#if defined(CL_HPP_ENABLE_SIZE_T_COMPATIBILITY)
581namespace cl {
582 using size_type = ::size_t;
583} // namespace cl
584#else // #if defined(CL_HPP_ENABLE_SIZE_T_COMPATIBILITY)
585namespace cl {
586 using size_type = size_t;
587} // namespace cl
588#endif // #if defined(CL_HPP_ENABLE_SIZE_T_COMPATIBILITY)
589
590
591#if defined(CL_HPP_ENABLE_EXCEPTIONS)
592#include <exception>
593#endif // #if defined(CL_HPP_ENABLE_EXCEPTIONS)
594
595#if !defined(CL_HPP_NO_STD_VECTOR)
596#include <vector>
597namespace cl {
598 template < class T, class Alloc = std::allocator<T> >
599 using vector = std::vector<T, Alloc>;
600} // namespace cl
601#endif // #if !defined(CL_HPP_NO_STD_VECTOR)
602
603#if !defined(CL_HPP_NO_STD_STRING)
604#include <string>
605namespace cl {
606 using string = std::string;
607} // namespace cl
608#endif // #if !defined(CL_HPP_NO_STD_STRING)
609
610#if CL_HPP_TARGET_OPENCL_VERSION >= 200
611
612#if !defined(CL_HPP_NO_STD_UNIQUE_PTR)
613#include <memory>
614namespace cl {
615 // Replace unique_ptr and allocate_pointer for internal use
616 // to allow user to replace them
617 template<class T, class D>
618 using pointer = std::unique_ptr<T, D>;
619} // namespace cl
620#endif
621#endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 200
622#if !defined(CL_HPP_NO_STD_ARRAY)
623#include <array>
624namespace cl {
625 template < class T, size_type N >
626 using array = std::array<T, N>;
627} // namespace cl
628#endif // #if !defined(CL_HPP_NO_STD_ARRAY)
629
630// Define size_type appropriately to allow backward-compatibility
631// use of the old size_t interface class
632#if defined(CL_HPP_ENABLE_SIZE_T_COMPATIBILITY)
633namespace cl {
634 namespace compatibility {
635 /*! \brief class used to interface between C++ and
636 * OpenCL C calls that require arrays of size_t values, whose
637 * size is known statically.
638 */
639 template <int N>
640 class size_t
641 {
642 private:
643 size_type data_[N];
644
645 public:
646 //! \brief Initialize size_t to all 0s
647 size_t()
648 {
649 for (int i = 0; i < N; ++i) {
650 data_[i] = 0;
651 }
652 }
653
654 size_t(const array<size_type, N> &rhs)
655 {
656 for (int i = 0; i < N; ++i) {
657 data_[i] = rhs[i];
658 }
659 }
660
661 size_type& operator[](int index)
662 {
663 return data_[index];
664 }
665
666 const size_type& operator[](int index) const
667 {
668 return data_[index];
669 }
670
671 //! \brief Conversion operator to T*.
672 operator size_type* () { return data_; }
673
674 //! \brief Conversion operator to const T*.
675 operator const size_type* () const { return data_; }
676
677 operator array<size_type, N>() const
678 {
679 array<size_type, N> ret;
680
681 for (int i = 0; i < N; ++i) {
682 ret[i] = data_[i];
683 }
684 return ret;
685 }
686 };
687 } // namespace compatibility
688
689 template<int N>
690 using size_t = compatibility::size_t<N>;
691} // namespace cl
692#endif // #if defined(CL_HPP_ENABLE_SIZE_T_COMPATIBILITY)
693
694// Helper alias to avoid confusing the macros
695namespace cl {
696 namespace detail {
697 using size_t_array = array<size_type, 3>;
698 } // namespace detail
699} // namespace cl
700
701
702/*! \namespace cl
703 *
704 * \brief The OpenCL C++ bindings are defined within this namespace.
705 *
706 */
707namespace cl {
Viet-Hoa Do633ebd12023-08-11 12:27:59 +0100708
709#define CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(name) \
710 using PFN_##name = name##_fn
711
712#define CL_HPP_INIT_CL_EXT_FCN_PTR_(name) \
713 if (!pfn_##name) { \
714 pfn_##name = (PFN_##name)clGetExtensionFunctionAddress(#name); \
715 }
716
717#define CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, name) \
718 if (!pfn_##name) { \
719 pfn_##name = (PFN_##name) \
720 clGetExtensionFunctionAddressForPlatform(platform, #name); \
721 }
722
723#ifdef cl_khr_external_memory
724 enum class ExternalMemoryType : cl_external_memory_handle_type_khr;
725#endif
726
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100727 class Memory;
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100728 class Program;
729 class Device;
730 class Context;
731 class CommandQueue;
732 class DeviceCommandQueue;
733 class Memory;
734 class Buffer;
735 class Pipe;
Viet-Hoa Do633ebd12023-08-11 12:27:59 +0100736#ifdef cl_khr_semaphore
737 class Semaphore;
738#endif
739#if defined(cl_khr_command_buffer)
740 class CommandBufferKhr;
741 class MutableCommandKhr;
742#endif // cl_khr_command_buffer
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100743
744#if defined(CL_HPP_ENABLE_EXCEPTIONS)
745 /*! \brief Exception class
746 *
747 * This may be thrown by API functions when CL_HPP_ENABLE_EXCEPTIONS is defined.
748 */
749 class Error : public std::exception
750 {
751 private:
752 cl_int err_;
753 const char * errStr_;
754 public:
755 /*! \brief Create a new CL error exception for a given error code
756 * and corresponding message.
757 *
758 * \param err error code value.
759 *
760 * \param errStr a descriptive string that must remain in scope until
761 * handling of the exception has concluded. If set, it
762 * will be returned by what().
763 */
Viet-Hoa Do633ebd12023-08-11 12:27:59 +0100764 Error(cl_int err, const char * errStr = nullptr) : err_(err), errStr_(errStr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100765 {}
766
767 ~Error() throw() {}
768
769 /*! \brief Get error string associated with exception
770 *
771 * \return A memory pointer to the error message string.
772 */
773 virtual const char * what() const throw ()
774 {
Viet-Hoa Do633ebd12023-08-11 12:27:59 +0100775 if (errStr_ == nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100776 return "empty";
777 }
778 else {
779 return errStr_;
780 }
781 }
782
783 /*! \brief Get error code associated with exception
784 *
785 * \return The error code.
786 */
787 cl_int err(void) const { return err_; }
788 };
789#define CL_HPP_ERR_STR_(x) #x
790#else
Viet-Hoa Do633ebd12023-08-11 12:27:59 +0100791#define CL_HPP_ERR_STR_(x) nullptr
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100792#endif // CL_HPP_ENABLE_EXCEPTIONS
793
794
795namespace detail
796{
797#if defined(CL_HPP_ENABLE_EXCEPTIONS)
798static inline cl_int errHandler (
799 cl_int err,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +0100800 const char * errStr = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100801{
802 if (err != CL_SUCCESS) {
803 throw Error(err, errStr);
804 }
805 return err;
806}
807#else
Viet-Hoa Do633ebd12023-08-11 12:27:59 +0100808static inline cl_int errHandler (cl_int err, const char * errStr = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100809{
810 (void) errStr; // suppress unused variable warning
811 return err;
812}
813#endif // CL_HPP_ENABLE_EXCEPTIONS
814}
815
816
817
818//! \cond DOXYGEN_DETAIL
819#if !defined(CL_HPP_USER_OVERRIDE_ERROR_STRINGS)
820#define __GET_DEVICE_INFO_ERR CL_HPP_ERR_STR_(clGetDeviceInfo)
821#define __GET_PLATFORM_INFO_ERR CL_HPP_ERR_STR_(clGetPlatformInfo)
822#define __GET_DEVICE_IDS_ERR CL_HPP_ERR_STR_(clGetDeviceIDs)
823#define __GET_PLATFORM_IDS_ERR CL_HPP_ERR_STR_(clGetPlatformIDs)
824#define __GET_CONTEXT_INFO_ERR CL_HPP_ERR_STR_(clGetContextInfo)
825#define __GET_EVENT_INFO_ERR CL_HPP_ERR_STR_(clGetEventInfo)
826#define __GET_EVENT_PROFILE_INFO_ERR CL_HPP_ERR_STR_(clGetEventProfileInfo)
827#define __GET_MEM_OBJECT_INFO_ERR CL_HPP_ERR_STR_(clGetMemObjectInfo)
828#define __GET_IMAGE_INFO_ERR CL_HPP_ERR_STR_(clGetImageInfo)
829#define __GET_SAMPLER_INFO_ERR CL_HPP_ERR_STR_(clGetSamplerInfo)
830#define __GET_KERNEL_INFO_ERR CL_HPP_ERR_STR_(clGetKernelInfo)
831#if CL_HPP_TARGET_OPENCL_VERSION >= 120
832#define __GET_KERNEL_ARG_INFO_ERR CL_HPP_ERR_STR_(clGetKernelArgInfo)
833#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
Viet-Hoa Do633ebd12023-08-11 12:27:59 +0100834#if CL_HPP_TARGET_OPENCL_VERSION >= 210
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +0000835#define __GET_KERNEL_SUB_GROUP_INFO_ERR CL_HPP_ERR_STR_(clGetKernelSubGroupInfo)
Viet-Hoa Do633ebd12023-08-11 12:27:59 +0100836#else
837#define __GET_KERNEL_SUB_GROUP_INFO_ERR CL_HPP_ERR_STR_(clGetKernelSubGroupInfoKHR)
838#endif // CL_HPP_TARGET_OPENCL_VERSION >= 210
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100839#define __GET_KERNEL_WORK_GROUP_INFO_ERR CL_HPP_ERR_STR_(clGetKernelWorkGroupInfo)
840#define __GET_PROGRAM_INFO_ERR CL_HPP_ERR_STR_(clGetProgramInfo)
841#define __GET_PROGRAM_BUILD_INFO_ERR CL_HPP_ERR_STR_(clGetProgramBuildInfo)
842#define __GET_COMMAND_QUEUE_INFO_ERR CL_HPP_ERR_STR_(clGetCommandQueueInfo)
843
844#define __CREATE_CONTEXT_ERR CL_HPP_ERR_STR_(clCreateContext)
845#define __CREATE_CONTEXT_FROM_TYPE_ERR CL_HPP_ERR_STR_(clCreateContextFromType)
846#define __GET_SUPPORTED_IMAGE_FORMATS_ERR CL_HPP_ERR_STR_(clGetSupportedImageFormats)
Viet-Hoa Do633ebd12023-08-11 12:27:59 +0100847#if CL_HPP_TARGET_OPENCL_VERSION >= 300
848#define __SET_CONTEXT_DESCTRUCTOR_CALLBACK_ERR CL_HPP_ERR_STR_(clSetContextDestructorCallback)
849#endif // CL_HPP_TARGET_OPENCL_VERSION >= 300
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100850
851#define __CREATE_BUFFER_ERR CL_HPP_ERR_STR_(clCreateBuffer)
852#define __COPY_ERR CL_HPP_ERR_STR_(cl::copy)
853#define __CREATE_SUBBUFFER_ERR CL_HPP_ERR_STR_(clCreateSubBuffer)
854#define __CREATE_GL_BUFFER_ERR CL_HPP_ERR_STR_(clCreateFromGLBuffer)
855#define __CREATE_GL_RENDER_BUFFER_ERR CL_HPP_ERR_STR_(clCreateFromGLBuffer)
856#define __GET_GL_OBJECT_INFO_ERR CL_HPP_ERR_STR_(clGetGLObjectInfo)
857#if CL_HPP_TARGET_OPENCL_VERSION >= 120
858#define __CREATE_IMAGE_ERR CL_HPP_ERR_STR_(clCreateImage)
859#define __CREATE_GL_TEXTURE_ERR CL_HPP_ERR_STR_(clCreateFromGLTexture)
860#define __IMAGE_DIMENSION_ERR CL_HPP_ERR_STR_(Incorrect image dimensions)
861#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
862#define __SET_MEM_OBJECT_DESTRUCTOR_CALLBACK_ERR CL_HPP_ERR_STR_(clSetMemObjectDestructorCallback)
863
864#define __CREATE_USER_EVENT_ERR CL_HPP_ERR_STR_(clCreateUserEvent)
865#define __SET_USER_EVENT_STATUS_ERR CL_HPP_ERR_STR_(clSetUserEventStatus)
866#define __SET_EVENT_CALLBACK_ERR CL_HPP_ERR_STR_(clSetEventCallback)
867#define __WAIT_FOR_EVENTS_ERR CL_HPP_ERR_STR_(clWaitForEvents)
868
869#define __CREATE_KERNEL_ERR CL_HPP_ERR_STR_(clCreateKernel)
870#define __SET_KERNEL_ARGS_ERR CL_HPP_ERR_STR_(clSetKernelArg)
871#define __CREATE_PROGRAM_WITH_SOURCE_ERR CL_HPP_ERR_STR_(clCreateProgramWithSource)
872#define __CREATE_PROGRAM_WITH_BINARY_ERR CL_HPP_ERR_STR_(clCreateProgramWithBinary)
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +0000873#if CL_HPP_TARGET_OPENCL_VERSION >= 210
874#define __CREATE_PROGRAM_WITH_IL_ERR CL_HPP_ERR_STR_(clCreateProgramWithIL)
Viet-Hoa Do633ebd12023-08-11 12:27:59 +0100875#else
876#define __CREATE_PROGRAM_WITH_IL_ERR CL_HPP_ERR_STR_(clCreateProgramWithILKHR)
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +0000877#endif // CL_HPP_TARGET_OPENCL_VERSION >= 210
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100878#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
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +0000914#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
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100919
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
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100926#define __RETAIN_ERR CL_HPP_ERR_STR_(Retain Object)
927#define __RELEASE_ERR CL_HPP_ERR_STR_(Release Object)
928#define __FLUSH_ERR CL_HPP_ERR_STR_(clFlush)
929#define __FINISH_ERR CL_HPP_ERR_STR_(clFinish)
930#define __VECTOR_CAPACITY_ERR CL_HPP_ERR_STR_(Vector capacity error)
931
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +0000932#if CL_HPP_TARGET_OPENCL_VERSION >= 210
933#define __GET_HOST_TIMER_ERR CL_HPP_ERR_STR_(clGetHostTimer)
934#define __GET_DEVICE_AND_HOST_TIMER_ERR CL_HPP_ERR_STR_(clGetDeviceAndHostTimer)
935#endif
936#if CL_HPP_TARGET_OPENCL_VERSION >= 220
937#define __SET_PROGRAM_RELEASE_CALLBACK_ERR CL_HPP_ERR_STR_(clSetProgramReleaseCallback)
938#define __SET_PROGRAM_SPECIALIZATION_CONSTANT_ERR CL_HPP_ERR_STR_(clSetProgramSpecializationConstant)
939#endif
940
Viet-Hoa Do633ebd12023-08-11 12:27:59 +0100941#ifdef cl_khr_external_memory
942#define __ENQUEUE_ACQUIRE_EXTERNAL_MEMORY_ERR CL_HPP_ERR_STR_(clEnqueueAcquireExternalMemObjectsKHR)
943#define __ENQUEUE_RELEASE_EXTERNAL_MEMORY_ERR CL_HPP_ERR_STR_(clEnqueueReleaseExternalMemObjectsKHR)
944#endif
945
946#ifdef cl_khr_semaphore
947#define __GET_SEMAPHORE_KHR_INFO_ERR CL_HPP_ERR_STR_(clGetSemaphoreInfoKHR)
948#define __CREATE_SEMAPHORE_KHR_WITH_PROPERTIES_ERR CL_HPP_ERR_STR_(clCreateSemaphoreWithPropertiesKHR)
949#define __ENQUEUE_WAIT_SEMAPHORE_KHR_ERR CL_HPP_ERR_STR_(clEnqueueWaitSemaphoresKHR)
950#define __ENQUEUE_SIGNAL_SEMAPHORE_KHR_ERR CL_HPP_ERR_STR_(clEnqueueSignalSemaphoresKHR)
951#define __RETAIN_SEMAPHORE_KHR_ERR CL_HPP_ERR_STR_(clRetainSemaphoreKHR)
952#define __RELEASE_SEMAPHORE_KHR_ERR CL_HPP_ERR_STR_(clReleaseSemaphoreKHR)
953#endif
954#if defined(cl_khr_command_buffer)
955#define __CREATE_COMMAND_BUFFER_KHR_ERR CL_HPP_ERR_STR_(clCreateCommandBufferKHR)
956#define __GET_COMMAND_BUFFER_INFO_KHR_ERR CL_HPP_ERR_STR_(clGetCommandBufferInfoKHR)
957#define __FINALIZE_COMMAND_BUFFER_KHR_ERR CL_HPP_ERR_STR_(clFinalizeCommandBufferKHR)
958#define __ENQUEUE_COMMAND_BUFFER_KHR_ERR CL_HPP_ERR_STR_(clEnqueueCommandBufferKHR)
959#define __COMMAND_BARRIER_WITH_WAIT_LIST_KHR_ERR CL_HPP_ERR_STR_(clCommandBarrierWithWaitListKHR)
960#define __COMMAND_COPY_BUFFER_KHR_ERR CL_HPP_ERR_STR_(clCommandCopyBufferKHR)
961#define __COMMAND_COPY_BUFFER_RECT_KHR_ERR CL_HPP_ERR_STR_(clCommandCopyBufferRectKHR)
962#define __COMMAND_COPY_BUFFER_TO_IMAGE_KHR_ERR CL_HPP_ERR_STR_(clCommandCopyBufferToImageKHR)
963#define __COMMAND_COPY_IMAGE_KHR_ERR CL_HPP_ERR_STR_(clCommandCopyImageKHR)
964#define __COMMAND_COPY_IMAGE_TO_BUFFER_KHR_ERR CL_HPP_ERR_STR_(clCommandCopyImageToBufferKHR)
965#define __COMMAND_FILL_BUFFER_KHR_ERR CL_HPP_ERR_STR_(clCommandFillBufferKHR)
966#define __COMMAND_FILL_IMAGE_KHR_ERR CL_HPP_ERR_STR_(clCommandFillImageKHR)
967#define __COMMAND_NDRANGE_KERNEL_KHR_ERR CL_HPP_ERR_STR_(clCommandNDRangeKernelKHR)
968#define __UPDATE_MUTABLE_COMMANDS_KHR_ERR CL_HPP_ERR_STR_(clUpdateMutableCommandsKHR)
969#define __GET_MUTABLE_COMMAND_INFO_KHR_ERR CL_HPP_ERR_STR_(clGetMutableCommandInfoKHR)
970#define __RETAIN_COMMAND_BUFFER_KHR_ERR CL_HPP_ERR_STR_(clRetainCommandBufferKHR)
971#define __RELEASE_COMMAND_BUFFER_KHR_ERR CL_HPP_ERR_STR_(clReleaseCommandBufferKHR)
972#endif // cl_khr_command_buffer
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +0000973
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100974/**
975 * CL 1.2 version that uses device fission.
976 */
977#if CL_HPP_TARGET_OPENCL_VERSION >= 120
978#define __CREATE_SUB_DEVICES_ERR CL_HPP_ERR_STR_(clCreateSubDevices)
979#else
980#define __CREATE_SUB_DEVICES_ERR CL_HPP_ERR_STR_(clCreateSubDevicesEXT)
981#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
982
983/**
984 * Deprecated APIs for 1.2
985 */
986#if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
987#define __ENQUEUE_MARKER_ERR CL_HPP_ERR_STR_(clEnqueueMarker)
988#define __ENQUEUE_WAIT_FOR_EVENTS_ERR CL_HPP_ERR_STR_(clEnqueueWaitForEvents)
989#define __ENQUEUE_BARRIER_ERR CL_HPP_ERR_STR_(clEnqueueBarrier)
990#define __UNLOAD_COMPILER_ERR CL_HPP_ERR_STR_(clUnloadCompiler)
991#define __CREATE_GL_TEXTURE_2D_ERR CL_HPP_ERR_STR_(clCreateFromGLTexture2D)
992#define __CREATE_GL_TEXTURE_3D_ERR CL_HPP_ERR_STR_(clCreateFromGLTexture3D)
993#define __CREATE_IMAGE2D_ERR CL_HPP_ERR_STR_(clCreateImage2D)
994#define __CREATE_IMAGE3D_ERR CL_HPP_ERR_STR_(clCreateImage3D)
995#endif // #if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
996
997/**
998 * Deprecated APIs for 2.0
999 */
1000#if defined(CL_USE_DEPRECATED_OPENCL_1_2_APIS)
1001#define __CREATE_COMMAND_QUEUE_ERR CL_HPP_ERR_STR_(clCreateCommandQueue)
1002#define __ENQUEUE_TASK_ERR CL_HPP_ERR_STR_(clEnqueueTask)
1003#define __CREATE_SAMPLER_ERR CL_HPP_ERR_STR_(clCreateSampler)
1004#endif // #if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
1005
1006/**
1007 * CL 1.2 marker and barrier commands
1008 */
1009#if CL_HPP_TARGET_OPENCL_VERSION >= 120
1010#define __ENQUEUE_MARKER_WAIT_LIST_ERR CL_HPP_ERR_STR_(clEnqueueMarkerWithWaitList)
1011#define __ENQUEUE_BARRIER_WAIT_LIST_ERR CL_HPP_ERR_STR_(clEnqueueBarrierWithWaitList)
1012#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
1013
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00001014#if CL_HPP_TARGET_OPENCL_VERSION >= 210
1015#define __CLONE_KERNEL_ERR CL_HPP_ERR_STR_(clCloneKernel)
1016#endif // CL_HPP_TARGET_OPENCL_VERSION >= 210
1017
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001018#endif // CL_HPP_USER_OVERRIDE_ERROR_STRINGS
1019//! \endcond
1020
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01001021#ifdef cl_khr_external_memory
1022CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clEnqueueAcquireExternalMemObjectsKHR);
1023CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clEnqueueReleaseExternalMemObjectsKHR);
1024
1025CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clEnqueueAcquireExternalMemObjectsKHR pfn_clEnqueueAcquireExternalMemObjectsKHR = nullptr;
1026CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clEnqueueReleaseExternalMemObjectsKHR pfn_clEnqueueReleaseExternalMemObjectsKHR = nullptr;
1027#endif // cl_khr_external_memory
1028
1029#ifdef cl_khr_semaphore
1030CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCreateSemaphoreWithPropertiesKHR);
1031CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clReleaseSemaphoreKHR);
1032CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clRetainSemaphoreKHR);
1033CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clEnqueueWaitSemaphoresKHR);
1034CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clEnqueueSignalSemaphoresKHR);
1035CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clGetSemaphoreInfoKHR);
1036
1037CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCreateSemaphoreWithPropertiesKHR pfn_clCreateSemaphoreWithPropertiesKHR = nullptr;
1038CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clReleaseSemaphoreKHR pfn_clReleaseSemaphoreKHR = nullptr;
1039CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clRetainSemaphoreKHR pfn_clRetainSemaphoreKHR = nullptr;
1040CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clEnqueueWaitSemaphoresKHR pfn_clEnqueueWaitSemaphoresKHR = nullptr;
1041CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clEnqueueSignalSemaphoresKHR pfn_clEnqueueSignalSemaphoresKHR = nullptr;
1042CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clGetSemaphoreInfoKHR pfn_clGetSemaphoreInfoKHR = nullptr;
1043#endif // cl_khr_semaphore
1044
1045#if defined(cl_khr_command_buffer)
1046CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCreateCommandBufferKHR);
1047CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clFinalizeCommandBufferKHR);
1048CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clRetainCommandBufferKHR);
1049CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clReleaseCommandBufferKHR);
1050CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clGetCommandBufferInfoKHR);
1051CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clEnqueueCommandBufferKHR);
1052CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCommandBarrierWithWaitListKHR);
1053CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCommandCopyBufferKHR);
1054CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCommandCopyBufferRectKHR);
1055CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCommandCopyBufferToImageKHR);
1056CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCommandCopyImageKHR);
1057CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCommandCopyImageToBufferKHR);
1058CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCommandFillBufferKHR);
1059CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCommandFillImageKHR);
1060CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCommandNDRangeKernelKHR);
1061
1062CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCreateCommandBufferKHR pfn_clCreateCommandBufferKHR = nullptr;
1063CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clFinalizeCommandBufferKHR pfn_clFinalizeCommandBufferKHR = nullptr;
1064CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clRetainCommandBufferKHR pfn_clRetainCommandBufferKHR = nullptr;
1065CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clReleaseCommandBufferKHR pfn_clReleaseCommandBufferKHR = nullptr;
1066CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clGetCommandBufferInfoKHR pfn_clGetCommandBufferInfoKHR = nullptr;
1067CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clEnqueueCommandBufferKHR pfn_clEnqueueCommandBufferKHR = nullptr;
1068CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCommandBarrierWithWaitListKHR pfn_clCommandBarrierWithWaitListKHR = nullptr;
1069CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCommandCopyBufferKHR pfn_clCommandCopyBufferKHR = nullptr;
1070CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCommandCopyBufferRectKHR pfn_clCommandCopyBufferRectKHR = nullptr;
1071CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCommandCopyBufferToImageKHR pfn_clCommandCopyBufferToImageKHR = nullptr;
1072CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCommandCopyImageKHR pfn_clCommandCopyImageKHR = nullptr;
1073CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCommandCopyImageToBufferKHR pfn_clCommandCopyImageToBufferKHR = nullptr;
1074CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCommandFillBufferKHR pfn_clCommandFillBufferKHR = nullptr;
1075CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCommandFillImageKHR pfn_clCommandFillImageKHR = nullptr;
1076CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCommandNDRangeKernelKHR pfn_clCommandNDRangeKernelKHR = nullptr;
1077#endif /* cl_khr_command_buffer */
1078
1079#if defined(cl_khr_command_buffer_mutable_dispatch)
1080CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clUpdateMutableCommandsKHR);
1081CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clGetMutableCommandInfoKHR);
1082
1083CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clUpdateMutableCommandsKHR pfn_clUpdateMutableCommandsKHR = nullptr;
1084CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clGetMutableCommandInfoKHR pfn_clGetMutableCommandInfoKHR = nullptr;
1085#endif /* cl_khr_command_buffer_mutable_dispatch */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001086
1087namespace detail {
1088
1089// Generic getInfoHelper. The final parameter is used to guide overload
1090// resolution: the actual parameter passed is an int, which makes this
1091// a worse conversion sequence than a specialization that declares the
1092// parameter as an int.
1093template<typename Functor, typename T>
1094inline cl_int getInfoHelper(Functor f, cl_uint name, T* param, long)
1095{
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01001096 return f(name, sizeof(T), param, nullptr);
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001097}
1098
1099// Specialized for getInfo<CL_PROGRAM_BINARIES>
1100// Assumes that the output vector was correctly resized on the way in
1101template <typename Func>
1102inline cl_int getInfoHelper(Func f, cl_uint name, vector<vector<unsigned char>>* param, int)
1103{
1104 if (name != CL_PROGRAM_BINARIES) {
1105 return CL_INVALID_VALUE;
1106 }
1107 if (param) {
1108 // Create array of pointers, calculate total size and pass pointer array in
1109 size_type numBinaries = param->size();
1110 vector<unsigned char*> binariesPointers(numBinaries);
1111
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001112 for (size_type i = 0; i < numBinaries; ++i)
1113 {
1114 binariesPointers[i] = (*param)[i].data();
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001115 }
1116
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01001117 cl_int err = f(name, numBinaries * sizeof(unsigned char*), binariesPointers.data(), nullptr);
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001118
1119 if (err != CL_SUCCESS) {
1120 return err;
1121 }
1122 }
1123
1124
1125 return CL_SUCCESS;
1126}
1127
1128// Specialized getInfoHelper for vector params
1129template <typename Func, typename T>
1130inline cl_int getInfoHelper(Func f, cl_uint name, vector<T>* param, long)
1131{
1132 size_type required;
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01001133 cl_int err = f(name, 0, nullptr, &required);
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001134 if (err != CL_SUCCESS) {
1135 return err;
1136 }
1137 const size_type elements = required / sizeof(T);
1138
1139 // Temporary to avoid changing param on an error
1140 vector<T> localData(elements);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01001141 err = f(name, required, localData.data(), nullptr);
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001142 if (err != CL_SUCCESS) {
1143 return err;
1144 }
1145 if (param) {
1146 *param = std::move(localData);
1147 }
1148
1149 return CL_SUCCESS;
1150}
1151
1152/* Specialization for reference-counted types. This depends on the
1153 * existence of Wrapper<T>::cl_type, and none of the other types having the
1154 * cl_type member. Note that simplify specifying the parameter as Wrapper<T>
1155 * does not work, because when using a derived type (e.g. Context) the generic
1156 * template will provide a better match.
1157 */
1158template <typename Func, typename T>
1159inline cl_int getInfoHelper(
1160 Func f, cl_uint name, vector<T>* param, int, typename T::cl_type = 0)
1161{
1162 size_type required;
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01001163 cl_int err = f(name, 0, nullptr, &required);
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001164 if (err != CL_SUCCESS) {
1165 return err;
1166 }
1167
1168 const size_type elements = required / sizeof(typename T::cl_type);
1169
1170 vector<typename T::cl_type> value(elements);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01001171 err = f(name, required, value.data(), nullptr);
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001172 if (err != CL_SUCCESS) {
1173 return err;
1174 }
1175
1176 if (param) {
1177 // Assign to convert CL type to T for each element
1178 param->resize(elements);
1179
1180 // Assign to param, constructing with retain behaviour
1181 // to correctly capture each underlying CL object
1182 for (size_type i = 0; i < elements; i++) {
1183 (*param)[i] = T(value[i], true);
1184 }
1185 }
1186 return CL_SUCCESS;
1187}
1188
1189// Specialized GetInfoHelper for string params
1190template <typename Func>
1191inline cl_int getInfoHelper(Func f, cl_uint name, string* param, long)
1192{
1193 size_type required;
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01001194 cl_int err = f(name, 0, nullptr, &required);
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001195 if (err != CL_SUCCESS) {
1196 return err;
1197 }
1198
1199 // std::string has a constant data member
1200 // a char vector does not
1201 if (required > 0) {
1202 vector<char> value(required);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01001203 err = f(name, required, value.data(), nullptr);
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001204 if (err != CL_SUCCESS) {
1205 return err;
1206 }
1207 if (param) {
1208 param->assign(begin(value), prev(end(value)));
1209 }
1210 }
1211 else if (param) {
1212 param->assign("");
1213 }
1214 return CL_SUCCESS;
1215}
1216
1217// Specialized GetInfoHelper for clsize_t params
1218template <typename Func, size_type N>
1219inline cl_int getInfoHelper(Func f, cl_uint name, array<size_type, N>* param, long)
1220{
1221 size_type required;
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01001222 cl_int err = f(name, 0, nullptr, &required);
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001223 if (err != CL_SUCCESS) {
1224 return err;
1225 }
1226
1227 size_type elements = required / sizeof(size_type);
1228 vector<size_type> value(elements, 0);
1229
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01001230 err = f(name, required, value.data(), nullptr);
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001231 if (err != CL_SUCCESS) {
1232 return err;
1233 }
1234
1235 // Bound the copy with N to prevent overruns
1236 // if passed N > than the amount copied
1237 if (elements > N) {
1238 elements = N;
1239 }
1240 for (size_type i = 0; i < elements; ++i) {
1241 (*param)[i] = value[i];
1242 }
1243
1244 return CL_SUCCESS;
1245}
1246
1247template<typename T> struct ReferenceHandler;
1248
1249/* Specialization for reference-counted types. This depends on the
1250 * existence of Wrapper<T>::cl_type, and none of the other types having the
1251 * cl_type member. Note that simplify specifying the parameter as Wrapper<T>
1252 * does not work, because when using a derived type (e.g. Context) the generic
1253 * template will provide a better match.
1254 */
1255template<typename Func, typename T>
1256inline cl_int getInfoHelper(Func f, cl_uint name, T* param, int, typename T::cl_type = 0)
1257{
1258 typename T::cl_type value;
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01001259 cl_int err = f(name, sizeof(value), &value, nullptr);
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001260 if (err != CL_SUCCESS) {
1261 return err;
1262 }
1263 *param = value;
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01001264 if (value != nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001265 {
1266 err = param->retain();
1267 if (err != CL_SUCCESS) {
1268 return err;
1269 }
1270 }
1271 return CL_SUCCESS;
1272}
1273
1274#define CL_HPP_PARAM_NAME_INFO_1_0_(F) \
1275 F(cl_platform_info, CL_PLATFORM_PROFILE, string) \
1276 F(cl_platform_info, CL_PLATFORM_VERSION, string) \
1277 F(cl_platform_info, CL_PLATFORM_NAME, string) \
1278 F(cl_platform_info, CL_PLATFORM_VENDOR, string) \
1279 F(cl_platform_info, CL_PLATFORM_EXTENSIONS, string) \
1280 \
1281 F(cl_device_info, CL_DEVICE_TYPE, cl_device_type) \
1282 F(cl_device_info, CL_DEVICE_VENDOR_ID, cl_uint) \
1283 F(cl_device_info, CL_DEVICE_MAX_COMPUTE_UNITS, cl_uint) \
1284 F(cl_device_info, CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS, cl_uint) \
1285 F(cl_device_info, CL_DEVICE_MAX_WORK_GROUP_SIZE, size_type) \
1286 F(cl_device_info, CL_DEVICE_MAX_WORK_ITEM_SIZES, cl::vector<size_type>) \
1287 F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR, cl_uint) \
1288 F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT, cl_uint) \
1289 F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT, cl_uint) \
1290 F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG, cl_uint) \
1291 F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT, cl_uint) \
1292 F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE, cl_uint) \
1293 F(cl_device_info, CL_DEVICE_MAX_CLOCK_FREQUENCY, cl_uint) \
1294 F(cl_device_info, CL_DEVICE_ADDRESS_BITS, cl_uint) \
1295 F(cl_device_info, CL_DEVICE_MAX_READ_IMAGE_ARGS, cl_uint) \
1296 F(cl_device_info, CL_DEVICE_MAX_WRITE_IMAGE_ARGS, cl_uint) \
1297 F(cl_device_info, CL_DEVICE_MAX_MEM_ALLOC_SIZE, cl_ulong) \
1298 F(cl_device_info, CL_DEVICE_IMAGE2D_MAX_WIDTH, size_type) \
1299 F(cl_device_info, CL_DEVICE_IMAGE2D_MAX_HEIGHT, size_type) \
1300 F(cl_device_info, CL_DEVICE_IMAGE3D_MAX_WIDTH, size_type) \
1301 F(cl_device_info, CL_DEVICE_IMAGE3D_MAX_HEIGHT, size_type) \
1302 F(cl_device_info, CL_DEVICE_IMAGE3D_MAX_DEPTH, size_type) \
1303 F(cl_device_info, CL_DEVICE_IMAGE_SUPPORT, cl_bool) \
1304 F(cl_device_info, CL_DEVICE_MAX_PARAMETER_SIZE, size_type) \
1305 F(cl_device_info, CL_DEVICE_MAX_SAMPLERS, cl_uint) \
1306 F(cl_device_info, CL_DEVICE_MEM_BASE_ADDR_ALIGN, cl_uint) \
1307 F(cl_device_info, CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE, cl_uint) \
1308 F(cl_device_info, CL_DEVICE_SINGLE_FP_CONFIG, cl_device_fp_config) \
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00001309 F(cl_device_info, CL_DEVICE_DOUBLE_FP_CONFIG, cl_device_fp_config) \
1310 F(cl_device_info, CL_DEVICE_HALF_FP_CONFIG, cl_device_fp_config) \
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001311 F(cl_device_info, CL_DEVICE_GLOBAL_MEM_CACHE_TYPE, cl_device_mem_cache_type) \
1312 F(cl_device_info, CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE, cl_uint)\
1313 F(cl_device_info, CL_DEVICE_GLOBAL_MEM_CACHE_SIZE, cl_ulong) \
1314 F(cl_device_info, CL_DEVICE_GLOBAL_MEM_SIZE, cl_ulong) \
1315 F(cl_device_info, CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE, cl_ulong) \
1316 F(cl_device_info, CL_DEVICE_MAX_CONSTANT_ARGS, cl_uint) \
1317 F(cl_device_info, CL_DEVICE_LOCAL_MEM_TYPE, cl_device_local_mem_type) \
1318 F(cl_device_info, CL_DEVICE_LOCAL_MEM_SIZE, cl_ulong) \
1319 F(cl_device_info, CL_DEVICE_ERROR_CORRECTION_SUPPORT, cl_bool) \
1320 F(cl_device_info, CL_DEVICE_PROFILING_TIMER_RESOLUTION, size_type) \
1321 F(cl_device_info, CL_DEVICE_ENDIAN_LITTLE, cl_bool) \
1322 F(cl_device_info, CL_DEVICE_AVAILABLE, cl_bool) \
1323 F(cl_device_info, CL_DEVICE_COMPILER_AVAILABLE, cl_bool) \
1324 F(cl_device_info, CL_DEVICE_EXECUTION_CAPABILITIES, cl_device_exec_capabilities) \
1325 F(cl_device_info, CL_DEVICE_PLATFORM, cl_platform_id) \
1326 F(cl_device_info, CL_DEVICE_NAME, string) \
1327 F(cl_device_info, CL_DEVICE_VENDOR, string) \
1328 F(cl_device_info, CL_DRIVER_VERSION, string) \
1329 F(cl_device_info, CL_DEVICE_PROFILE, string) \
1330 F(cl_device_info, CL_DEVICE_VERSION, string) \
1331 F(cl_device_info, CL_DEVICE_EXTENSIONS, string) \
1332 \
1333 F(cl_context_info, CL_CONTEXT_REFERENCE_COUNT, cl_uint) \
1334 F(cl_context_info, CL_CONTEXT_DEVICES, cl::vector<Device>) \
1335 F(cl_context_info, CL_CONTEXT_PROPERTIES, cl::vector<cl_context_properties>) \
1336 \
1337 F(cl_event_info, CL_EVENT_COMMAND_QUEUE, cl::CommandQueue) \
1338 F(cl_event_info, CL_EVENT_COMMAND_TYPE, cl_command_type) \
1339 F(cl_event_info, CL_EVENT_REFERENCE_COUNT, cl_uint) \
1340 F(cl_event_info, CL_EVENT_COMMAND_EXECUTION_STATUS, cl_int) \
1341 \
1342 F(cl_profiling_info, CL_PROFILING_COMMAND_QUEUED, cl_ulong) \
1343 F(cl_profiling_info, CL_PROFILING_COMMAND_SUBMIT, cl_ulong) \
1344 F(cl_profiling_info, CL_PROFILING_COMMAND_START, cl_ulong) \
1345 F(cl_profiling_info, CL_PROFILING_COMMAND_END, cl_ulong) \
1346 \
1347 F(cl_mem_info, CL_MEM_TYPE, cl_mem_object_type) \
1348 F(cl_mem_info, CL_MEM_FLAGS, cl_mem_flags) \
1349 F(cl_mem_info, CL_MEM_SIZE, size_type) \
1350 F(cl_mem_info, CL_MEM_HOST_PTR, void*) \
1351 F(cl_mem_info, CL_MEM_MAP_COUNT, cl_uint) \
1352 F(cl_mem_info, CL_MEM_REFERENCE_COUNT, cl_uint) \
1353 F(cl_mem_info, CL_MEM_CONTEXT, cl::Context) \
1354 \
1355 F(cl_image_info, CL_IMAGE_FORMAT, cl_image_format) \
1356 F(cl_image_info, CL_IMAGE_ELEMENT_SIZE, size_type) \
1357 F(cl_image_info, CL_IMAGE_ROW_PITCH, size_type) \
1358 F(cl_image_info, CL_IMAGE_SLICE_PITCH, size_type) \
1359 F(cl_image_info, CL_IMAGE_WIDTH, size_type) \
1360 F(cl_image_info, CL_IMAGE_HEIGHT, size_type) \
1361 F(cl_image_info, CL_IMAGE_DEPTH, size_type) \
1362 \
1363 F(cl_sampler_info, CL_SAMPLER_REFERENCE_COUNT, cl_uint) \
1364 F(cl_sampler_info, CL_SAMPLER_CONTEXT, cl::Context) \
1365 F(cl_sampler_info, CL_SAMPLER_NORMALIZED_COORDS, cl_bool) \
1366 F(cl_sampler_info, CL_SAMPLER_ADDRESSING_MODE, cl_addressing_mode) \
1367 F(cl_sampler_info, CL_SAMPLER_FILTER_MODE, cl_filter_mode) \
1368 \
1369 F(cl_program_info, CL_PROGRAM_REFERENCE_COUNT, cl_uint) \
1370 F(cl_program_info, CL_PROGRAM_CONTEXT, cl::Context) \
1371 F(cl_program_info, CL_PROGRAM_NUM_DEVICES, cl_uint) \
1372 F(cl_program_info, CL_PROGRAM_DEVICES, cl::vector<Device>) \
1373 F(cl_program_info, CL_PROGRAM_SOURCE, string) \
1374 F(cl_program_info, CL_PROGRAM_BINARY_SIZES, cl::vector<size_type>) \
1375 F(cl_program_info, CL_PROGRAM_BINARIES, cl::vector<cl::vector<unsigned char>>) \
1376 \
1377 F(cl_program_build_info, CL_PROGRAM_BUILD_STATUS, cl_build_status) \
1378 F(cl_program_build_info, CL_PROGRAM_BUILD_OPTIONS, string) \
1379 F(cl_program_build_info, CL_PROGRAM_BUILD_LOG, string) \
1380 \
1381 F(cl_kernel_info, CL_KERNEL_FUNCTION_NAME, string) \
1382 F(cl_kernel_info, CL_KERNEL_NUM_ARGS, cl_uint) \
1383 F(cl_kernel_info, CL_KERNEL_REFERENCE_COUNT, cl_uint) \
1384 F(cl_kernel_info, CL_KERNEL_CONTEXT, cl::Context) \
1385 F(cl_kernel_info, CL_KERNEL_PROGRAM, cl::Program) \
1386 \
1387 F(cl_kernel_work_group_info, CL_KERNEL_WORK_GROUP_SIZE, size_type) \
1388 F(cl_kernel_work_group_info, CL_KERNEL_COMPILE_WORK_GROUP_SIZE, cl::detail::size_t_array) \
1389 F(cl_kernel_work_group_info, CL_KERNEL_LOCAL_MEM_SIZE, cl_ulong) \
1390 \
1391 F(cl_command_queue_info, CL_QUEUE_CONTEXT, cl::Context) \
1392 F(cl_command_queue_info, CL_QUEUE_DEVICE, cl::Device) \
1393 F(cl_command_queue_info, CL_QUEUE_REFERENCE_COUNT, cl_uint) \
1394 F(cl_command_queue_info, CL_QUEUE_PROPERTIES, cl_command_queue_properties)
1395
1396
1397#define CL_HPP_PARAM_NAME_INFO_1_1_(F) \
1398 F(cl_context_info, CL_CONTEXT_NUM_DEVICES, cl_uint)\
1399 F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF, cl_uint) \
1400 F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR, cl_uint) \
1401 F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT, cl_uint) \
1402 F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_INT, cl_uint) \
1403 F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG, cl_uint) \
1404 F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT, cl_uint) \
1405 F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE, cl_uint) \
1406 F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF, cl_uint) \
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001407 F(cl_device_info, CL_DEVICE_OPENCL_C_VERSION, string) \
1408 \
1409 F(cl_mem_info, CL_MEM_ASSOCIATED_MEMOBJECT, cl::Memory) \
1410 F(cl_mem_info, CL_MEM_OFFSET, size_type) \
1411 \
1412 F(cl_kernel_work_group_info, CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE, size_type) \
1413 F(cl_kernel_work_group_info, CL_KERNEL_PRIVATE_MEM_SIZE, cl_ulong) \
1414 \
1415 F(cl_event_info, CL_EVENT_CONTEXT, cl::Context)
1416
1417#define CL_HPP_PARAM_NAME_INFO_1_2_(F) \
1418 F(cl_program_info, CL_PROGRAM_NUM_KERNELS, size_type) \
1419 F(cl_program_info, CL_PROGRAM_KERNEL_NAMES, string) \
1420 \
1421 F(cl_program_build_info, CL_PROGRAM_BINARY_TYPE, cl_program_binary_type) \
1422 \
1423 F(cl_kernel_info, CL_KERNEL_ATTRIBUTES, string) \
1424 \
1425 F(cl_kernel_arg_info, CL_KERNEL_ARG_ADDRESS_QUALIFIER, cl_kernel_arg_address_qualifier) \
1426 F(cl_kernel_arg_info, CL_KERNEL_ARG_ACCESS_QUALIFIER, cl_kernel_arg_access_qualifier) \
1427 F(cl_kernel_arg_info, CL_KERNEL_ARG_TYPE_NAME, string) \
1428 F(cl_kernel_arg_info, CL_KERNEL_ARG_NAME, string) \
1429 F(cl_kernel_arg_info, CL_KERNEL_ARG_TYPE_QUALIFIER, cl_kernel_arg_type_qualifier) \
1430 \
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00001431 F(cl_kernel_work_group_info, CL_KERNEL_GLOBAL_WORK_SIZE, cl::detail::size_t_array) \
1432 \
1433 F(cl_device_info, CL_DEVICE_LINKER_AVAILABLE, cl_bool) \
1434 F(cl_device_info, CL_DEVICE_IMAGE_MAX_BUFFER_SIZE, size_type) \
1435 F(cl_device_info, CL_DEVICE_IMAGE_MAX_ARRAY_SIZE, size_type) \
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001436 F(cl_device_info, CL_DEVICE_PARENT_DEVICE, cl::Device) \
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00001437 F(cl_device_info, CL_DEVICE_PARTITION_MAX_SUB_DEVICES, cl_uint) \
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001438 F(cl_device_info, CL_DEVICE_PARTITION_PROPERTIES, cl::vector<cl_device_partition_property>) \
1439 F(cl_device_info, CL_DEVICE_PARTITION_TYPE, cl::vector<cl_device_partition_property>) \
1440 F(cl_device_info, CL_DEVICE_REFERENCE_COUNT, cl_uint) \
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00001441 F(cl_device_info, CL_DEVICE_PREFERRED_INTEROP_USER_SYNC, cl_bool) \
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001442 F(cl_device_info, CL_DEVICE_PARTITION_AFFINITY_DOMAIN, cl_device_affinity_domain) \
1443 F(cl_device_info, CL_DEVICE_BUILT_IN_KERNELS, string) \
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00001444 F(cl_device_info, CL_DEVICE_PRINTF_BUFFER_SIZE, size_type) \
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001445 \
1446 F(cl_image_info, CL_IMAGE_ARRAY_SIZE, size_type) \
1447 F(cl_image_info, CL_IMAGE_NUM_MIP_LEVELS, cl_uint) \
1448 F(cl_image_info, CL_IMAGE_NUM_SAMPLES, cl_uint)
1449
1450#define CL_HPP_PARAM_NAME_INFO_2_0_(F) \
1451 F(cl_device_info, CL_DEVICE_QUEUE_ON_HOST_PROPERTIES, cl_command_queue_properties) \
1452 F(cl_device_info, CL_DEVICE_QUEUE_ON_DEVICE_PROPERTIES, cl_command_queue_properties) \
1453 F(cl_device_info, CL_DEVICE_QUEUE_ON_DEVICE_PREFERRED_SIZE, cl_uint) \
1454 F(cl_device_info, CL_DEVICE_QUEUE_ON_DEVICE_MAX_SIZE, cl_uint) \
1455 F(cl_device_info, CL_DEVICE_MAX_ON_DEVICE_QUEUES, cl_uint) \
1456 F(cl_device_info, CL_DEVICE_MAX_ON_DEVICE_EVENTS, cl_uint) \
1457 F(cl_device_info, CL_DEVICE_MAX_PIPE_ARGS, cl_uint) \
1458 F(cl_device_info, CL_DEVICE_PIPE_MAX_ACTIVE_RESERVATIONS, cl_uint) \
1459 F(cl_device_info, CL_DEVICE_PIPE_MAX_PACKET_SIZE, cl_uint) \
1460 F(cl_device_info, CL_DEVICE_SVM_CAPABILITIES, cl_device_svm_capabilities) \
1461 F(cl_device_info, CL_DEVICE_PREFERRED_PLATFORM_ATOMIC_ALIGNMENT, cl_uint) \
1462 F(cl_device_info, CL_DEVICE_PREFERRED_GLOBAL_ATOMIC_ALIGNMENT, cl_uint) \
1463 F(cl_device_info, CL_DEVICE_PREFERRED_LOCAL_ATOMIC_ALIGNMENT, cl_uint) \
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00001464 F(cl_device_info, CL_DEVICE_IMAGE_PITCH_ALIGNMENT, cl_uint) \
1465 F(cl_device_info, CL_DEVICE_IMAGE_BASE_ADDRESS_ALIGNMENT, cl_uint) \
1466 F(cl_device_info, CL_DEVICE_MAX_READ_WRITE_IMAGE_ARGS, cl_uint ) \
1467 F(cl_device_info, CL_DEVICE_MAX_GLOBAL_VARIABLE_SIZE, size_type ) \
1468 F(cl_device_info, CL_DEVICE_GLOBAL_VARIABLE_PREFERRED_TOTAL_SIZE, size_type ) \
1469 F(cl_profiling_info, CL_PROFILING_COMMAND_COMPLETE, cl_ulong) \
1470 F(cl_kernel_exec_info, CL_KERNEL_EXEC_INFO_SVM_FINE_GRAIN_SYSTEM, cl_bool) \
1471 F(cl_kernel_exec_info, CL_KERNEL_EXEC_INFO_SVM_PTRS, void**) \
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001472 F(cl_command_queue_info, CL_QUEUE_SIZE, cl_uint) \
1473 F(cl_mem_info, CL_MEM_USES_SVM_POINTER, cl_bool) \
1474 F(cl_program_build_info, CL_PROGRAM_BUILD_GLOBAL_VARIABLE_TOTAL_SIZE, size_type) \
1475 F(cl_pipe_info, CL_PIPE_PACKET_SIZE, cl_uint) \
1476 F(cl_pipe_info, CL_PIPE_MAX_PACKETS, cl_uint)
1477
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00001478#define CL_HPP_PARAM_NAME_INFO_SUBGROUP_KHR_(F) \
1479 F(cl_kernel_sub_group_info, CL_KERNEL_MAX_SUB_GROUP_SIZE_FOR_NDRANGE_KHR, size_type) \
1480 F(cl_kernel_sub_group_info, CL_KERNEL_SUB_GROUP_COUNT_FOR_NDRANGE_KHR, size_type)
1481
1482#define CL_HPP_PARAM_NAME_INFO_IL_KHR_(F) \
1483 F(cl_device_info, CL_DEVICE_IL_VERSION_KHR, string) \
1484 F(cl_program_info, CL_PROGRAM_IL_KHR, cl::vector<unsigned char>)
1485
1486#define CL_HPP_PARAM_NAME_INFO_2_1_(F) \
1487 F(cl_platform_info, CL_PLATFORM_HOST_TIMER_RESOLUTION, cl_ulong) \
1488 F(cl_program_info, CL_PROGRAM_IL, cl::vector<unsigned char>) \
1489 F(cl_device_info, CL_DEVICE_MAX_NUM_SUB_GROUPS, cl_uint) \
1490 F(cl_device_info, CL_DEVICE_IL_VERSION, string) \
1491 F(cl_device_info, CL_DEVICE_SUB_GROUP_INDEPENDENT_FORWARD_PROGRESS, cl_bool) \
1492 F(cl_command_queue_info, CL_QUEUE_DEVICE_DEFAULT, cl::DeviceCommandQueue) \
1493 F(cl_kernel_sub_group_info, CL_KERNEL_MAX_SUB_GROUP_SIZE_FOR_NDRANGE, size_type) \
1494 F(cl_kernel_sub_group_info, CL_KERNEL_SUB_GROUP_COUNT_FOR_NDRANGE, size_type) \
1495 F(cl_kernel_sub_group_info, CL_KERNEL_LOCAL_SIZE_FOR_SUB_GROUP_COUNT, cl::detail::size_t_array) \
1496 F(cl_kernel_sub_group_info, CL_KERNEL_MAX_NUM_SUB_GROUPS, size_type) \
1497 F(cl_kernel_sub_group_info, CL_KERNEL_COMPILE_NUM_SUB_GROUPS, size_type)
1498
1499#define CL_HPP_PARAM_NAME_INFO_2_2_(F) \
1500 F(cl_program_info, CL_PROGRAM_SCOPE_GLOBAL_CTORS_PRESENT, cl_bool) \
1501 F(cl_program_info, CL_PROGRAM_SCOPE_GLOBAL_DTORS_PRESENT, cl_bool)
1502
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01001503#define CL_HPP_PARAM_NAME_DEVICE_FISSION_EXT_(F) \
1504 F(cl_device_info, CL_DEVICE_PARENT_DEVICE_EXT, cl::Device) \
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001505 F(cl_device_info, CL_DEVICE_PARTITION_TYPES_EXT, cl::vector<cl_device_partition_property_ext>) \
1506 F(cl_device_info, CL_DEVICE_AFFINITY_DOMAINS_EXT, cl::vector<cl_device_partition_property_ext>) \
1507 F(cl_device_info, CL_DEVICE_REFERENCE_COUNT_EXT , cl_uint) \
1508 F(cl_device_info, CL_DEVICE_PARTITION_STYLE_EXT, cl::vector<cl_device_partition_property_ext>)
1509
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00001510#define CL_HPP_PARAM_NAME_CL_KHR_EXTENDED_VERSIONING_CL3_SHARED_(F) \
1511 F(cl_platform_info, CL_PLATFORM_NUMERIC_VERSION_KHR, cl_version_khr) \
1512 F(cl_platform_info, CL_PLATFORM_EXTENSIONS_WITH_VERSION_KHR, cl::vector<cl_name_version_khr>) \
1513 \
1514 F(cl_device_info, CL_DEVICE_NUMERIC_VERSION_KHR, cl_version_khr) \
1515 F(cl_device_info, CL_DEVICE_EXTENSIONS_WITH_VERSION_KHR, cl::vector<cl_name_version_khr>) \
1516 F(cl_device_info, CL_DEVICE_ILS_WITH_VERSION_KHR, cl::vector<cl_name_version_khr>) \
1517 F(cl_device_info, CL_DEVICE_BUILT_IN_KERNELS_WITH_VERSION_KHR, cl::vector<cl_name_version_khr>)
1518
1519#define CL_HPP_PARAM_NAME_CL_KHR_EXTENDED_VERSIONING_KHRONLY_(F) \
1520 F(cl_device_info, CL_DEVICE_OPENCL_C_NUMERIC_VERSION_KHR, cl_version_khr)
1521
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01001522#define CL_HPP_PARAM_NAME_CL_KHR_SEMAPHORE_(F) \
1523 F(cl_semaphore_info_khr, CL_SEMAPHORE_PROPERTIES_KHR, cl::vector<cl_semaphore_properties_khr>) \
1524 F(cl_platform_info, CL_PLATFORM_SEMAPHORE_TYPES_KHR, cl::vector<cl_semaphore_type_khr>) \
1525 F(cl_device_info, CL_DEVICE_SEMAPHORE_TYPES_KHR, cl::vector<cl_semaphore_type_khr>) \
1526
1527#define CL_HPP_PARAM_NAME_CL_KHR_EXTERNAL_MEMORY_(F) \
1528 F(cl_device_info, CL_DEVICE_EXTERNAL_MEMORY_IMPORT_HANDLE_TYPES_KHR, cl::vector<cl::ExternalMemoryType>) \
1529 F(cl_platform_info, CL_PLATFORM_EXTERNAL_MEMORY_IMPORT_HANDLE_TYPES_KHR, cl::vector<cl::ExternalMemoryType>)
1530
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00001531#define CL_HPP_PARAM_NAME_INFO_3_0_(F) \
1532 F(cl_platform_info, CL_PLATFORM_NUMERIC_VERSION, cl_version) \
1533 F(cl_platform_info, CL_PLATFORM_EXTENSIONS_WITH_VERSION, cl::vector<cl_name_version>) \
1534 \
1535 F(cl_device_info, CL_DEVICE_NUMERIC_VERSION, cl_version) \
1536 F(cl_device_info, CL_DEVICE_EXTENSIONS_WITH_VERSION, cl::vector<cl_name_version>) \
1537 F(cl_device_info, CL_DEVICE_ILS_WITH_VERSION, cl::vector<cl_name_version>) \
1538 F(cl_device_info, CL_DEVICE_BUILT_IN_KERNELS_WITH_VERSION, cl::vector<cl_name_version>) \
1539 F(cl_device_info, CL_DEVICE_ATOMIC_MEMORY_CAPABILITIES, cl_device_atomic_capabilities) \
1540 F(cl_device_info, CL_DEVICE_ATOMIC_FENCE_CAPABILITIES, cl_device_atomic_capabilities) \
1541 F(cl_device_info, CL_DEVICE_NON_UNIFORM_WORK_GROUP_SUPPORT, cl_bool) \
1542 F(cl_device_info, CL_DEVICE_OPENCL_C_ALL_VERSIONS, cl::vector<cl_name_version>) \
1543 F(cl_device_info, CL_DEVICE_PREFERRED_WORK_GROUP_SIZE_MULTIPLE, size_type) \
1544 F(cl_device_info, CL_DEVICE_WORK_GROUP_COLLECTIVE_FUNCTIONS_SUPPORT, cl_bool) \
1545 F(cl_device_info, CL_DEVICE_GENERIC_ADDRESS_SPACE_SUPPORT, cl_bool) \
1546 F(cl_device_info, CL_DEVICE_OPENCL_C_FEATURES, cl::vector<cl_name_version>) \
1547 F(cl_device_info, CL_DEVICE_DEVICE_ENQUEUE_CAPABILITIES, cl_device_device_enqueue_capabilities) \
1548 F(cl_device_info, CL_DEVICE_PIPE_SUPPORT, cl_bool) \
1549 F(cl_device_info, CL_DEVICE_LATEST_CONFORMANCE_VERSION_PASSED, string) \
1550 \
1551 F(cl_command_queue_info, CL_QUEUE_PROPERTIES_ARRAY, cl::vector<cl_queue_properties>) \
1552 F(cl_mem_info, CL_MEM_PROPERTIES, cl::vector<cl_mem_properties>) \
1553 F(cl_pipe_info, CL_PIPE_PROPERTIES, cl::vector<cl_pipe_properties>) \
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01001554 F(cl_sampler_info, CL_SAMPLER_PROPERTIES, cl::vector<cl_sampler_properties>) \
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00001555
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001556template <typename enum_type, cl_int Name>
1557struct param_traits {};
1558
1559#define CL_HPP_DECLARE_PARAM_TRAITS_(token, param_name, T) \
1560struct token; \
1561template<> \
1562struct param_traits<detail:: token,param_name> \
1563{ \
1564 enum { value = param_name }; \
1565 typedef T param_type; \
1566};
1567
1568CL_HPP_PARAM_NAME_INFO_1_0_(CL_HPP_DECLARE_PARAM_TRAITS_)
1569#if CL_HPP_TARGET_OPENCL_VERSION >= 110
1570CL_HPP_PARAM_NAME_INFO_1_1_(CL_HPP_DECLARE_PARAM_TRAITS_)
1571#endif // CL_HPP_TARGET_OPENCL_VERSION >= 110
1572#if CL_HPP_TARGET_OPENCL_VERSION >= 120
1573CL_HPP_PARAM_NAME_INFO_1_2_(CL_HPP_DECLARE_PARAM_TRAITS_)
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00001574#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001575#if CL_HPP_TARGET_OPENCL_VERSION >= 200
1576CL_HPP_PARAM_NAME_INFO_2_0_(CL_HPP_DECLARE_PARAM_TRAITS_)
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00001577#endif // CL_HPP_TARGET_OPENCL_VERSION >= 200
1578#if CL_HPP_TARGET_OPENCL_VERSION >= 210
1579CL_HPP_PARAM_NAME_INFO_2_1_(CL_HPP_DECLARE_PARAM_TRAITS_)
1580#endif // CL_HPP_TARGET_OPENCL_VERSION >= 210
1581#if CL_HPP_TARGET_OPENCL_VERSION >= 220
1582CL_HPP_PARAM_NAME_INFO_2_2_(CL_HPP_DECLARE_PARAM_TRAITS_)
1583#endif // CL_HPP_TARGET_OPENCL_VERSION >= 220
1584#if CL_HPP_TARGET_OPENCL_VERSION >= 300
1585CL_HPP_PARAM_NAME_INFO_3_0_(CL_HPP_DECLARE_PARAM_TRAITS_)
1586#endif // CL_HPP_TARGET_OPENCL_VERSION >= 300
1587
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01001588#if defined(cl_khr_subgroups) && CL_HPP_TARGET_OPENCL_VERSION < 210
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00001589CL_HPP_PARAM_NAME_INFO_SUBGROUP_KHR_(CL_HPP_DECLARE_PARAM_TRAITS_)
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01001590#endif // #if defined(cl_khr_subgroups) && CL_HPP_TARGET_OPENCL_VERSION < 210
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00001591
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01001592#if defined(cl_khr_il_program) && CL_HPP_TARGET_OPENCL_VERSION < 210
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00001593CL_HPP_PARAM_NAME_INFO_IL_KHR_(CL_HPP_DECLARE_PARAM_TRAITS_)
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01001594#endif // #if defined(cl_khr_il_program) && CL_HPP_TARGET_OPENCL_VERSION < 210
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001595
1596
1597// Flags deprecated in OpenCL 2.0
1598#define CL_HPP_PARAM_NAME_INFO_1_0_DEPRECATED_IN_2_0_(F) \
1599 F(cl_device_info, CL_DEVICE_QUEUE_PROPERTIES, cl_command_queue_properties)
1600
1601#define CL_HPP_PARAM_NAME_INFO_1_1_DEPRECATED_IN_2_0_(F) \
1602 F(cl_device_info, CL_DEVICE_HOST_UNIFIED_MEMORY, cl_bool)
1603
1604#define CL_HPP_PARAM_NAME_INFO_1_2_DEPRECATED_IN_2_0_(F) \
1605 F(cl_image_info, CL_IMAGE_BUFFER, cl::Buffer)
1606
1607// Include deprecated query flags based on versions
1608// Only include deprecated 1.0 flags if 2.0 not active as there is an enum clash
1609#if CL_HPP_TARGET_OPENCL_VERSION > 100 && CL_HPP_MINIMUM_OPENCL_VERSION < 200 && CL_HPP_TARGET_OPENCL_VERSION < 200
1610CL_HPP_PARAM_NAME_INFO_1_0_DEPRECATED_IN_2_0_(CL_HPP_DECLARE_PARAM_TRAITS_)
1611#endif // CL_HPP_MINIMUM_OPENCL_VERSION < 110
1612#if CL_HPP_TARGET_OPENCL_VERSION > 110 && CL_HPP_MINIMUM_OPENCL_VERSION < 200
1613CL_HPP_PARAM_NAME_INFO_1_1_DEPRECATED_IN_2_0_(CL_HPP_DECLARE_PARAM_TRAITS_)
1614#endif // CL_HPP_MINIMUM_OPENCL_VERSION < 120
1615#if CL_HPP_TARGET_OPENCL_VERSION > 120 && CL_HPP_MINIMUM_OPENCL_VERSION < 200
1616CL_HPP_PARAM_NAME_INFO_1_2_DEPRECATED_IN_2_0_(CL_HPP_DECLARE_PARAM_TRAITS_)
1617#endif // CL_HPP_MINIMUM_OPENCL_VERSION < 200
1618
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01001619#if defined(cl_ext_device_fission)
1620CL_HPP_PARAM_NAME_DEVICE_FISSION_EXT_(CL_HPP_DECLARE_PARAM_TRAITS_)
1621#endif // cl_ext_device_fission
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001622
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00001623#if defined(cl_khr_extended_versioning)
1624#if CL_HPP_TARGET_OPENCL_VERSION < 300
1625CL_HPP_PARAM_NAME_CL_KHR_EXTENDED_VERSIONING_CL3_SHARED_(CL_HPP_DECLARE_PARAM_TRAITS_)
1626#endif // CL_HPP_TARGET_OPENCL_VERSION < 300
1627CL_HPP_PARAM_NAME_CL_KHR_EXTENDED_VERSIONING_KHRONLY_(CL_HPP_DECLARE_PARAM_TRAITS_)
1628#endif // cl_khr_extended_versioning
1629
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01001630#if defined(cl_khr_semaphore)
1631CL_HPP_PARAM_NAME_CL_KHR_SEMAPHORE_(CL_HPP_DECLARE_PARAM_TRAITS_)
1632#endif // cl_khr_semaphore
1633
1634#ifdef cl_khr_external_memory
1635CL_HPP_PARAM_NAME_CL_KHR_EXTERNAL_MEMORY_(CL_HPP_DECLARE_PARAM_TRAITS_)
1636#endif // cl_khr_external_memory
1637
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00001638#if defined(cl_khr_device_uuid)
1639using uuid_array = array<cl_uchar, CL_UUID_SIZE_KHR>;
1640using luid_array = array<cl_uchar, CL_LUID_SIZE_KHR>;
1641CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_UUID_KHR, uuid_array)
1642CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DRIVER_UUID_KHR, uuid_array)
1643CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_LUID_VALID_KHR, cl_bool)
1644CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_LUID_KHR, luid_array)
1645CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_NODE_MASK_KHR, cl_uint)
1646#endif
1647
1648#if defined(cl_khr_pci_bus_info)
1649CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_PCI_BUS_INFO_KHR, cl_device_pci_bus_info_khr)
1650#endif
1651
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01001652// Note: some headers do not define cl_khr_image2d_from_buffer
1653#if CL_HPP_TARGET_OPENCL_VERSION < 200
1654#if defined(CL_DEVICE_IMAGE_PITCH_ALIGNMENT_KHR)
1655CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_IMAGE_PITCH_ALIGNMENT_KHR, cl_uint)
1656#endif
1657#if defined(CL_DEVICE_IMAGE_BASE_ADDRESS_ALIGNMENT_KHR)
1658CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_IMAGE_BASE_ADDRESS_ALIGNMENT_KHR, cl_uint)
1659#endif
1660#endif // CL_HPP_TARGET_OPENCL_VERSION < 200
1661
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00001662#if defined(cl_khr_integer_dot_product)
1663CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_INTEGER_DOT_PRODUCT_CAPABILITIES_KHR, cl_device_integer_dot_product_capabilities_khr)
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01001664#if defined(CL_DEVICE_INTEGER_DOT_PRODUCT_ACCELERATION_PROPERTIES_8BIT_KHR)
1665CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_INTEGER_DOT_PRODUCT_ACCELERATION_PROPERTIES_8BIT_KHR, cl_device_integer_dot_product_acceleration_properties_khr)
1666CL_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)
1667#endif // defined(CL_DEVICE_INTEGER_DOT_PRODUCT_ACCELERATION_PROPERTIES_8BIT_KHR)
1668#endif // defined(cl_khr_integer_dot_product)
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00001669
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001670#ifdef CL_PLATFORM_ICD_SUFFIX_KHR
1671CL_HPP_DECLARE_PARAM_TRAITS_(cl_platform_info, CL_PLATFORM_ICD_SUFFIX_KHR, string)
1672#endif
1673
1674#ifdef CL_DEVICE_PROFILING_TIMER_OFFSET_AMD
1675CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_PROFILING_TIMER_OFFSET_AMD, cl_ulong)
1676#endif
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001677#ifdef CL_DEVICE_GLOBAL_FREE_MEMORY_AMD
1678CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_GLOBAL_FREE_MEMORY_AMD, vector<size_type>)
1679#endif
1680#ifdef CL_DEVICE_SIMD_PER_COMPUTE_UNIT_AMD
1681CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_SIMD_PER_COMPUTE_UNIT_AMD, cl_uint)
1682#endif
1683#ifdef CL_DEVICE_SIMD_WIDTH_AMD
1684CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_SIMD_WIDTH_AMD, cl_uint)
1685#endif
1686#ifdef CL_DEVICE_SIMD_INSTRUCTION_WIDTH_AMD
1687CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_SIMD_INSTRUCTION_WIDTH_AMD, cl_uint)
1688#endif
1689#ifdef CL_DEVICE_WAVEFRONT_WIDTH_AMD
1690CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_WAVEFRONT_WIDTH_AMD, cl_uint)
1691#endif
1692#ifdef CL_DEVICE_GLOBAL_MEM_CHANNELS_AMD
1693CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_GLOBAL_MEM_CHANNELS_AMD, cl_uint)
1694#endif
1695#ifdef CL_DEVICE_GLOBAL_MEM_CHANNEL_BANKS_AMD
1696CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_GLOBAL_MEM_CHANNEL_BANKS_AMD, cl_uint)
1697#endif
1698#ifdef CL_DEVICE_GLOBAL_MEM_CHANNEL_BANK_WIDTH_AMD
1699CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_GLOBAL_MEM_CHANNEL_BANK_WIDTH_AMD, cl_uint)
1700#endif
1701#ifdef CL_DEVICE_LOCAL_MEM_SIZE_PER_COMPUTE_UNIT_AMD
1702CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_LOCAL_MEM_SIZE_PER_COMPUTE_UNIT_AMD, cl_uint)
1703#endif
1704#ifdef CL_DEVICE_LOCAL_MEM_BANKS_AMD
1705CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_LOCAL_MEM_BANKS_AMD, cl_uint)
1706#endif
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01001707#ifdef CL_DEVICE_BOARD_NAME_AMD
1708CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_BOARD_NAME_AMD, string)
1709#endif
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001710
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00001711#ifdef CL_DEVICE_COMPUTE_UNITS_BITFIELD_ARM
1712CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_COMPUTE_UNITS_BITFIELD_ARM, cl_ulong)
1713#endif
1714#ifdef CL_DEVICE_JOB_SLOTS_ARM
1715CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_JOB_SLOTS_ARM, cl_uint)
1716#endif
1717#ifdef CL_DEVICE_SCHEDULING_CONTROLS_CAPABILITIES_ARM
1718CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_SCHEDULING_CONTROLS_CAPABILITIES_ARM, cl_bitfield)
1719#endif
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01001720#ifdef CL_DEVICE_SUPPORTED_REGISTER_ALLOCATIONS_ARM
1721CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_SUPPORTED_REGISTER_ALLOCATIONS_ARM, vector<cl_uint>)
1722#endif
1723#ifdef CL_DEVICE_MAX_WARP_COUNT_ARM
1724CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_MAX_WARP_COUNT_ARM, cl_uint)
1725#endif
1726#ifdef CL_KERNEL_MAX_WARP_COUNT_ARM
1727CL_HPP_DECLARE_PARAM_TRAITS_(cl_kernel_info, CL_KERNEL_MAX_WARP_COUNT_ARM, cl_uint)
1728#endif
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00001729#ifdef CL_KERNEL_EXEC_INFO_WORKGROUP_BATCH_SIZE_ARM
1730CL_HPP_DECLARE_PARAM_TRAITS_(cl_kernel_exec_info, CL_KERNEL_EXEC_INFO_WORKGROUP_BATCH_SIZE_ARM, cl_uint)
1731#endif
1732#ifdef CL_KERNEL_EXEC_INFO_WORKGROUP_BATCH_SIZE_MODIFIER_ARM
1733CL_HPP_DECLARE_PARAM_TRAITS_(cl_kernel_exec_info, CL_KERNEL_EXEC_INFO_WORKGROUP_BATCH_SIZE_MODIFIER_ARM, cl_int)
1734#endif
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01001735#ifdef CL_KERNEL_EXEC_INFO_WARP_COUNT_LIMIT_ARM
1736CL_HPP_DECLARE_PARAM_TRAITS_(cl_kernel_exec_info, CL_KERNEL_EXEC_INFO_WARP_COUNT_LIMIT_ARM, cl_uint)
1737#endif
1738#ifdef CL_KERNEL_EXEC_INFO_COMPUTE_UNIT_MAX_QUEUED_BATCHES_ARM
1739CL_HPP_DECLARE_PARAM_TRAITS_(cl_kernel_exec_info, CL_KERNEL_EXEC_INFO_COMPUTE_UNIT_MAX_QUEUED_BATCHES_ARM, cl_uint)
1740#endif
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00001741
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001742#ifdef CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV
1743CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV, cl_uint)
1744#endif
1745#ifdef CL_DEVICE_COMPUTE_CAPABILITY_MINOR_NV
1746CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_COMPUTE_CAPABILITY_MINOR_NV, cl_uint)
1747#endif
1748#ifdef CL_DEVICE_REGISTERS_PER_BLOCK_NV
1749CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_REGISTERS_PER_BLOCK_NV, cl_uint)
1750#endif
1751#ifdef CL_DEVICE_WARP_SIZE_NV
1752CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_WARP_SIZE_NV, cl_uint)
1753#endif
1754#ifdef CL_DEVICE_GPU_OVERLAP_NV
1755CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_GPU_OVERLAP_NV, cl_bool)
1756#endif
1757#ifdef CL_DEVICE_KERNEL_EXEC_TIMEOUT_NV
1758CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_KERNEL_EXEC_TIMEOUT_NV, cl_bool)
1759#endif
1760#ifdef CL_DEVICE_INTEGRATED_MEMORY_NV
1761CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_INTEGRATED_MEMORY_NV, cl_bool)
1762#endif
1763
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01001764#if defined(cl_khr_command_buffer)
1765CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_COMMAND_BUFFER_CAPABILITIES_KHR, cl_device_command_buffer_capabilities_khr)
1766CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_COMMAND_BUFFER_REQUIRED_QUEUE_PROPERTIES_KHR, cl_command_buffer_properties_khr)
1767CL_HPP_DECLARE_PARAM_TRAITS_(cl_command_buffer_info_khr, CL_COMMAND_BUFFER_QUEUES_KHR, cl::vector<CommandQueue>)
1768CL_HPP_DECLARE_PARAM_TRAITS_(cl_command_buffer_info_khr, CL_COMMAND_BUFFER_NUM_QUEUES_KHR, cl_uint)
1769CL_HPP_DECLARE_PARAM_TRAITS_(cl_command_buffer_info_khr, CL_COMMAND_BUFFER_REFERENCE_COUNT_KHR, cl_uint)
1770CL_HPP_DECLARE_PARAM_TRAITS_(cl_command_buffer_info_khr, CL_COMMAND_BUFFER_STATE_KHR, cl_command_buffer_state_khr)
1771CL_HPP_DECLARE_PARAM_TRAITS_(cl_command_buffer_info_khr, CL_COMMAND_BUFFER_PROPERTIES_ARRAY_KHR, cl::vector<cl_command_buffer_properties_khr>)
1772#endif /* cl_khr_command_buffer */
1773
1774#if defined(cl_khr_command_buffer_mutable_dispatch)
1775CL_HPP_DECLARE_PARAM_TRAITS_(cl_mutable_command_info_khr, CL_MUTABLE_COMMAND_COMMAND_QUEUE_KHR, CommandQueue)
1776CL_HPP_DECLARE_PARAM_TRAITS_(cl_mutable_command_info_khr, CL_MUTABLE_COMMAND_COMMAND_BUFFER_KHR, CommandBufferKhr)
1777CL_HPP_DECLARE_PARAM_TRAITS_(cl_mutable_command_info_khr, CL_MUTABLE_COMMAND_COMMAND_TYPE_KHR, cl_command_type)
1778CL_HPP_DECLARE_PARAM_TRAITS_(cl_mutable_command_info_khr, CL_MUTABLE_DISPATCH_PROPERTIES_ARRAY_KHR, cl::vector<cl_ndrange_kernel_command_properties_khr>)
1779CL_HPP_DECLARE_PARAM_TRAITS_(cl_mutable_command_info_khr, CL_MUTABLE_DISPATCH_KERNEL_KHR, cl_kernel)
1780CL_HPP_DECLARE_PARAM_TRAITS_(cl_mutable_command_info_khr, CL_MUTABLE_DISPATCH_DIMENSIONS_KHR, cl_uint)
1781CL_HPP_DECLARE_PARAM_TRAITS_(cl_mutable_command_info_khr, CL_MUTABLE_DISPATCH_GLOBAL_WORK_OFFSET_KHR, cl::vector<size_type>)
1782CL_HPP_DECLARE_PARAM_TRAITS_(cl_mutable_command_info_khr, CL_MUTABLE_DISPATCH_GLOBAL_WORK_SIZE_KHR, cl::vector<size_type>)
1783CL_HPP_DECLARE_PARAM_TRAITS_(cl_mutable_command_info_khr, CL_MUTABLE_DISPATCH_LOCAL_WORK_SIZE_KHR, cl::vector<size_type>)
1784#endif /* cl_khr_command_buffer_mutable_dispatch */
1785
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001786// Convenience functions
1787
1788template <typename Func, typename T>
1789inline cl_int
1790getInfo(Func f, cl_uint name, T* param)
1791{
1792 return getInfoHelper(f, name, param, 0);
1793}
1794
1795template <typename Func, typename Arg0>
1796struct GetInfoFunctor0
1797{
1798 Func f_; const Arg0& arg0_;
1799 cl_int operator ()(
1800 cl_uint param, size_type size, void* value, size_type* size_ret)
1801 { return f_(arg0_, param, size, value, size_ret); }
1802};
1803
1804template <typename Func, typename Arg0, typename Arg1>
1805struct GetInfoFunctor1
1806{
1807 Func f_; const Arg0& arg0_; const Arg1& arg1_;
1808 cl_int operator ()(
1809 cl_uint param, size_type size, void* value, size_type* size_ret)
1810 { return f_(arg0_, arg1_, param, size, value, size_ret); }
1811};
1812
1813template <typename Func, typename Arg0, typename T>
1814inline cl_int
1815getInfo(Func f, const Arg0& arg0, cl_uint name, T* param)
1816{
1817 GetInfoFunctor0<Func, Arg0> f0 = { f, arg0 };
1818 return getInfoHelper(f0, name, param, 0);
1819}
1820
1821template <typename Func, typename Arg0, typename Arg1, typename T>
1822inline cl_int
1823getInfo(Func f, const Arg0& arg0, const Arg1& arg1, cl_uint name, T* param)
1824{
1825 GetInfoFunctor1<Func, Arg0, Arg1> f0 = { f, arg0, arg1 };
1826 return getInfoHelper(f0, name, param, 0);
1827}
1828
1829
1830template<typename T>
1831struct ReferenceHandler
1832{ };
1833
1834#if CL_HPP_TARGET_OPENCL_VERSION >= 120
1835/**
1836 * OpenCL 1.2 devices do have retain/release.
1837 */
1838template <>
1839struct ReferenceHandler<cl_device_id>
1840{
1841 /**
1842 * Retain the device.
1843 * \param device A valid device created using createSubDevices
1844 * \return
1845 * CL_SUCCESS if the function executed successfully.
1846 * CL_INVALID_DEVICE if device was not a valid subdevice
1847 * CL_OUT_OF_RESOURCES
1848 * CL_OUT_OF_HOST_MEMORY
1849 */
1850 static cl_int retain(cl_device_id device)
1851 { return ::clRetainDevice(device); }
1852 /**
1853 * Retain the device.
1854 * \param device A valid device created using createSubDevices
1855 * \return
1856 * CL_SUCCESS if the function executed successfully.
1857 * CL_INVALID_DEVICE if device was not a valid subdevice
1858 * CL_OUT_OF_RESOURCES
1859 * CL_OUT_OF_HOST_MEMORY
1860 */
1861 static cl_int release(cl_device_id device)
1862 { return ::clReleaseDevice(device); }
1863};
1864#else // CL_HPP_TARGET_OPENCL_VERSION >= 120
1865/**
1866 * OpenCL 1.1 devices do not have retain/release.
1867 */
1868template <>
1869struct ReferenceHandler<cl_device_id>
1870{
1871 // cl_device_id does not have retain().
1872 static cl_int retain(cl_device_id)
1873 { return CL_SUCCESS; }
1874 // cl_device_id does not have release().
1875 static cl_int release(cl_device_id)
1876 { return CL_SUCCESS; }
1877};
1878#endif // ! (CL_HPP_TARGET_OPENCL_VERSION >= 120)
1879
1880template <>
1881struct ReferenceHandler<cl_platform_id>
1882{
1883 // cl_platform_id does not have retain().
1884 static cl_int retain(cl_platform_id)
1885 { return CL_SUCCESS; }
1886 // cl_platform_id does not have release().
1887 static cl_int release(cl_platform_id)
1888 { return CL_SUCCESS; }
1889};
1890
1891template <>
1892struct ReferenceHandler<cl_context>
1893{
1894 static cl_int retain(cl_context context)
1895 { return ::clRetainContext(context); }
1896 static cl_int release(cl_context context)
1897 { return ::clReleaseContext(context); }
1898};
1899
1900template <>
1901struct ReferenceHandler<cl_command_queue>
1902{
1903 static cl_int retain(cl_command_queue queue)
1904 { return ::clRetainCommandQueue(queue); }
1905 static cl_int release(cl_command_queue queue)
1906 { return ::clReleaseCommandQueue(queue); }
1907};
1908
1909template <>
1910struct ReferenceHandler<cl_mem>
1911{
1912 static cl_int retain(cl_mem memory)
1913 { return ::clRetainMemObject(memory); }
1914 static cl_int release(cl_mem memory)
1915 { return ::clReleaseMemObject(memory); }
1916};
1917
1918template <>
1919struct ReferenceHandler<cl_sampler>
1920{
1921 static cl_int retain(cl_sampler sampler)
1922 { return ::clRetainSampler(sampler); }
1923 static cl_int release(cl_sampler sampler)
1924 { return ::clReleaseSampler(sampler); }
1925};
1926
1927template <>
1928struct ReferenceHandler<cl_program>
1929{
1930 static cl_int retain(cl_program program)
1931 { return ::clRetainProgram(program); }
1932 static cl_int release(cl_program program)
1933 { return ::clReleaseProgram(program); }
1934};
1935
1936template <>
1937struct ReferenceHandler<cl_kernel>
1938{
1939 static cl_int retain(cl_kernel kernel)
1940 { return ::clRetainKernel(kernel); }
1941 static cl_int release(cl_kernel kernel)
1942 { return ::clReleaseKernel(kernel); }
1943};
1944
1945template <>
1946struct ReferenceHandler<cl_event>
1947{
1948 static cl_int retain(cl_event event)
1949 { return ::clRetainEvent(event); }
1950 static cl_int release(cl_event event)
1951 { return ::clReleaseEvent(event); }
1952};
1953
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01001954#ifdef cl_khr_semaphore
1955template <>
1956struct ReferenceHandler<cl_semaphore_khr>
1957{
1958 static cl_int retain(cl_semaphore_khr semaphore)
1959 {
1960 if (pfn_clRetainSemaphoreKHR != nullptr) {
1961 return pfn_clRetainSemaphoreKHR(semaphore);
1962 }
1963
1964 return CL_INVALID_OPERATION;
1965 }
1966
1967 static cl_int release(cl_semaphore_khr semaphore)
1968 {
1969 if (pfn_clReleaseSemaphoreKHR != nullptr) {
1970 return pfn_clReleaseSemaphoreKHR(semaphore);
1971 }
1972
1973 return CL_INVALID_OPERATION;
1974 }
1975};
1976#endif // cl_khr_semaphore
1977#if defined(cl_khr_command_buffer)
1978template <>
1979struct ReferenceHandler<cl_command_buffer_khr>
1980{
1981 static cl_int retain(cl_command_buffer_khr cmdBufferKhr)
1982 {
1983 if (pfn_clRetainCommandBufferKHR == nullptr) {
1984 return detail::errHandler(CL_INVALID_OPERATION, __RETAIN_COMMAND_BUFFER_KHR_ERR);
1985 }
1986 return pfn_clRetainCommandBufferKHR(cmdBufferKhr);
1987 }
1988
1989 static cl_int release(cl_command_buffer_khr cmdBufferKhr)
1990 {
1991 if (pfn_clReleaseCommandBufferKHR == nullptr) {
1992 return detail::errHandler(CL_INVALID_OPERATION, __RELEASE_COMMAND_BUFFER_KHR_ERR);
1993 }
1994 return pfn_clReleaseCommandBufferKHR(cmdBufferKhr);
1995 }
1996};
1997
1998template <>
1999struct ReferenceHandler<cl_mutable_command_khr>
2000{
2001 // cl_mutable_command_khr does not have retain().
2002 static cl_int retain(cl_mutable_command_khr)
2003 { return CL_SUCCESS; }
2004 // cl_mutable_command_khr does not have release().
2005 static cl_int release(cl_mutable_command_khr)
2006 { return CL_SUCCESS; }
2007};
2008#endif // cl_khr_command_buffer
2009
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002010
Anthony Barbier8b2fdc92018-08-09 11:42:38 +01002011#if CL_HPP_TARGET_OPENCL_VERSION >= 120 && CL_HPP_MINIMUM_OPENCL_VERSION < 120
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002012// Extracts version number with major in the upper 16 bits, minor in the lower 16
2013static cl_uint getVersion(const vector<char> &versionInfo)
2014{
2015 int highVersion = 0;
2016 int lowVersion = 0;
2017 int index = 7;
2018 while(versionInfo[index] != '.' ) {
2019 highVersion *= 10;
2020 highVersion += versionInfo[index]-'0';
2021 ++index;
2022 }
2023 ++index;
2024 while(versionInfo[index] != ' ' && versionInfo[index] != '\0') {
2025 lowVersion *= 10;
2026 lowVersion += versionInfo[index]-'0';
2027 ++index;
2028 }
2029 return (highVersion << 16) | lowVersion;
2030}
2031
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002032static cl_uint getPlatformVersion(cl_platform_id platform)
2033{
2034 size_type size = 0;
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01002035 clGetPlatformInfo(platform, CL_PLATFORM_VERSION, 0, nullptr, &size);
Anthony Barbier8b2fdc92018-08-09 11:42:38 +01002036
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002037 vector<char> versionInfo(size);
2038 clGetPlatformInfo(platform, CL_PLATFORM_VERSION, size, versionInfo.data(), &size);
2039 return getVersion(versionInfo);
2040}
2041
2042static cl_uint getDevicePlatformVersion(cl_device_id device)
2043{
2044 cl_platform_id platform;
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01002045 clGetDeviceInfo(device, CL_DEVICE_PLATFORM, sizeof(platform), &platform, nullptr);
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002046 return getPlatformVersion(platform);
2047}
2048
2049static cl_uint getContextPlatformVersion(cl_context context)
2050{
2051 // The platform cannot be queried directly, so we first have to grab a
2052 // device and obtain its context
2053 size_type size = 0;
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01002054 clGetContextInfo(context, CL_CONTEXT_DEVICES, 0, nullptr, &size);
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002055 if (size == 0)
2056 return 0;
2057 vector<cl_device_id> devices(size/sizeof(cl_device_id));
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01002058 clGetContextInfo(context, CL_CONTEXT_DEVICES, size, devices.data(), nullptr);
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002059 return getDevicePlatformVersion(devices[0]);
2060}
2061#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120 && CL_HPP_MINIMUM_OPENCL_VERSION < 120
2062
2063template <typename T>
2064class Wrapper
2065{
2066public:
2067 typedef T cl_type;
2068
2069protected:
2070 cl_type object_;
2071
2072public:
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01002073 Wrapper() : object_(nullptr) { }
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002074
2075 Wrapper(const cl_type &obj, bool retainObject) : object_(obj)
2076 {
2077 if (retainObject) {
2078 detail::errHandler(retain(), __RETAIN_ERR);
2079 }
2080 }
2081
2082 ~Wrapper()
2083 {
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01002084 if (object_ != nullptr) { release(); }
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002085 }
2086
2087 Wrapper(const Wrapper<cl_type>& rhs)
2088 {
2089 object_ = rhs.object_;
2090 detail::errHandler(retain(), __RETAIN_ERR);
2091 }
2092
2093 Wrapper(Wrapper<cl_type>&& rhs) CL_HPP_NOEXCEPT_
2094 {
2095 object_ = rhs.object_;
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01002096 rhs.object_ = nullptr;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002097 }
2098
2099 Wrapper<cl_type>& operator = (const Wrapper<cl_type>& rhs)
2100 {
2101 if (this != &rhs) {
2102 detail::errHandler(release(), __RELEASE_ERR);
2103 object_ = rhs.object_;
2104 detail::errHandler(retain(), __RETAIN_ERR);
2105 }
2106 return *this;
2107 }
2108
2109 Wrapper<cl_type>& operator = (Wrapper<cl_type>&& rhs)
2110 {
2111 if (this != &rhs) {
2112 detail::errHandler(release(), __RELEASE_ERR);
2113 object_ = rhs.object_;
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01002114 rhs.object_ = nullptr;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002115 }
2116 return *this;
2117 }
2118
2119 Wrapper<cl_type>& operator = (const cl_type &rhs)
2120 {
2121 detail::errHandler(release(), __RELEASE_ERR);
2122 object_ = rhs;
2123 return *this;
2124 }
2125
2126 const cl_type& operator ()() const { return object_; }
2127
2128 cl_type& operator ()() { return object_; }
2129
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00002130 cl_type get() const { return object_; }
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002131
2132protected:
2133 template<typename Func, typename U>
2134 friend inline cl_int getInfoHelper(Func, cl_uint, U*, int, typename U::cl_type);
2135
2136 cl_int retain() const
2137 {
2138 if (object_ != nullptr) {
2139 return ReferenceHandler<cl_type>::retain(object_);
2140 }
2141 else {
2142 return CL_SUCCESS;
2143 }
2144 }
2145
2146 cl_int release() const
2147 {
2148 if (object_ != nullptr) {
2149 return ReferenceHandler<cl_type>::release(object_);
2150 }
2151 else {
2152 return CL_SUCCESS;
2153 }
2154 }
2155};
2156
2157template <>
2158class Wrapper<cl_device_id>
2159{
2160public:
2161 typedef cl_device_id cl_type;
2162
2163protected:
2164 cl_type object_;
2165 bool referenceCountable_;
2166
2167 static bool isReferenceCountable(cl_device_id device)
2168 {
2169 bool retVal = false;
2170#if CL_HPP_TARGET_OPENCL_VERSION >= 120
2171#if CL_HPP_MINIMUM_OPENCL_VERSION < 120
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01002172 if (device != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002173 int version = getDevicePlatformVersion(device);
2174 if(version > ((1 << 16) + 1)) {
2175 retVal = true;
2176 }
2177 }
2178#else // CL_HPP_MINIMUM_OPENCL_VERSION < 120
2179 retVal = true;
2180#endif // CL_HPP_MINIMUM_OPENCL_VERSION < 120
2181#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01002182 (void)device;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002183 return retVal;
2184 }
2185
2186public:
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01002187 Wrapper() : object_(nullptr), referenceCountable_(false)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002188 {
2189 }
2190
2191 Wrapper(const cl_type &obj, bool retainObject) :
2192 object_(obj),
2193 referenceCountable_(false)
2194 {
2195 referenceCountable_ = isReferenceCountable(obj);
2196
2197 if (retainObject) {
2198 detail::errHandler(retain(), __RETAIN_ERR);
2199 }
2200 }
2201
2202 ~Wrapper()
2203 {
2204 release();
2205 }
2206
2207 Wrapper(const Wrapper<cl_type>& rhs)
2208 {
2209 object_ = rhs.object_;
2210 referenceCountable_ = isReferenceCountable(object_);
2211 detail::errHandler(retain(), __RETAIN_ERR);
2212 }
2213
2214 Wrapper(Wrapper<cl_type>&& rhs) CL_HPP_NOEXCEPT_
2215 {
2216 object_ = rhs.object_;
2217 referenceCountable_ = rhs.referenceCountable_;
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01002218 rhs.object_ = nullptr;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002219 rhs.referenceCountable_ = false;
2220 }
2221
2222 Wrapper<cl_type>& operator = (const Wrapper<cl_type>& rhs)
2223 {
2224 if (this != &rhs) {
2225 detail::errHandler(release(), __RELEASE_ERR);
2226 object_ = rhs.object_;
2227 referenceCountable_ = rhs.referenceCountable_;
2228 detail::errHandler(retain(), __RETAIN_ERR);
2229 }
2230 return *this;
2231 }
2232
2233 Wrapper<cl_type>& operator = (Wrapper<cl_type>&& rhs)
2234 {
2235 if (this != &rhs) {
2236 detail::errHandler(release(), __RELEASE_ERR);
2237 object_ = rhs.object_;
2238 referenceCountable_ = rhs.referenceCountable_;
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01002239 rhs.object_ = nullptr;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002240 rhs.referenceCountable_ = false;
2241 }
2242 return *this;
2243 }
2244
2245 Wrapper<cl_type>& operator = (const cl_type &rhs)
2246 {
2247 detail::errHandler(release(), __RELEASE_ERR);
2248 object_ = rhs;
2249 referenceCountable_ = isReferenceCountable(object_);
2250 return *this;
2251 }
2252
2253 const cl_type& operator ()() const { return object_; }
2254
2255 cl_type& operator ()() { return object_; }
2256
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00002257 cl_type get() const { return object_; }
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002258
2259protected:
2260 template<typename Func, typename U>
2261 friend inline cl_int getInfoHelper(Func, cl_uint, U*, int, typename U::cl_type);
2262
2263 template<typename Func, typename U>
2264 friend inline cl_int getInfoHelper(Func, cl_uint, vector<U>*, int, typename U::cl_type);
2265
2266 cl_int retain() const
2267 {
2268 if( object_ != nullptr && referenceCountable_ ) {
2269 return ReferenceHandler<cl_type>::retain(object_);
2270 }
2271 else {
2272 return CL_SUCCESS;
2273 }
2274 }
2275
2276 cl_int release() const
2277 {
2278 if (object_ != nullptr && referenceCountable_) {
2279 return ReferenceHandler<cl_type>::release(object_);
2280 }
2281 else {
2282 return CL_SUCCESS;
2283 }
2284 }
2285};
2286
2287template <typename T>
2288inline bool operator==(const Wrapper<T> &lhs, const Wrapper<T> &rhs)
2289{
2290 return lhs() == rhs();
2291}
2292
2293template <typename T>
2294inline bool operator!=(const Wrapper<T> &lhs, const Wrapper<T> &rhs)
2295{
2296 return !operator==(lhs, rhs);
2297}
2298
2299} // namespace detail
2300//! \endcond
2301
2302
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002303
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002304
2305
2306/*! \stuct ImageFormat
2307 * \brief Adds constructors and member functions for cl_image_format.
2308 *
2309 * \see cl_image_format
2310 */
2311struct ImageFormat : public cl_image_format
2312{
2313 //! \brief Default constructor - performs no initialization.
2314 ImageFormat(){}
2315
2316 //! \brief Initializing constructor.
2317 ImageFormat(cl_channel_order order, cl_channel_type type)
2318 {
2319 image_channel_order = order;
2320 image_channel_data_type = type;
2321 }
2322
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00002323 //! \brief Copy constructor.
2324 ImageFormat(const ImageFormat &other) { *this = other; }
2325
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002326 //! \brief Assignment operator.
2327 ImageFormat& operator = (const ImageFormat& rhs)
2328 {
2329 if (this != &rhs) {
2330 this->image_channel_data_type = rhs.image_channel_data_type;
2331 this->image_channel_order = rhs.image_channel_order;
2332 }
2333 return *this;
2334 }
2335};
2336
2337/*! \brief Class interface for cl_device_id.
2338 *
2339 * \note Copies of these objects are inexpensive, since they don't 'own'
2340 * any underlying resources or data structures.
2341 *
2342 * \see cl_device_id
2343 */
2344class Device : public detail::Wrapper<cl_device_id>
2345{
2346private:
2347 static std::once_flag default_initialized_;
2348 static Device default_;
2349 static cl_int default_error_;
2350
2351 /*! \brief Create the default context.
2352 *
2353 * This sets @c default_ and @c default_error_. It does not throw
2354 * @c cl::Error.
2355 */
2356 static void makeDefault();
2357
2358 /*! \brief Create the default platform from a provided platform.
2359 *
2360 * This sets @c default_. It does not throw
2361 * @c cl::Error.
2362 */
2363 static void makeDefaultProvided(const Device &p) {
2364 default_ = p;
2365 }
2366
2367public:
2368#ifdef CL_HPP_UNIT_TEST_ENABLE
2369 /*! \brief Reset the default.
2370 *
2371 * This sets @c default_ to an empty value to support cleanup in
2372 * the unit test framework.
2373 * This function is not thread safe.
2374 */
2375 static void unitTestClearDefault() {
2376 default_ = Device();
2377 }
2378#endif // #ifdef CL_HPP_UNIT_TEST_ENABLE
2379
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01002380 //! \brief Default constructor - initializes to nullptr.
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002381 Device() : detail::Wrapper<cl_type>() { }
2382
2383 /*! \brief Constructor from cl_device_id.
2384 *
2385 * This simply copies the device ID value, which is an inexpensive operation.
2386 */
2387 explicit Device(const cl_device_id &device, bool retainObject = false) :
2388 detail::Wrapper<cl_type>(device, retainObject) { }
2389
2390 /*! \brief Returns the first device on the default context.
2391 *
2392 * \see Context::getDefault()
2393 */
2394 static Device getDefault(
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01002395 cl_int *errResult = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002396 {
2397 std::call_once(default_initialized_, makeDefault);
2398 detail::errHandler(default_error_);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01002399 if (errResult != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002400 *errResult = default_error_;
2401 }
2402 return default_;
2403 }
2404
2405 /**
2406 * Modify the default device to be used by
2407 * subsequent operations.
2408 * Will only set the default if no default was previously created.
2409 * @return updated default device.
2410 * Should be compared to the passed value to ensure that it was updated.
2411 */
2412 static Device setDefault(const Device &default_device)
2413 {
2414 std::call_once(default_initialized_, makeDefaultProvided, std::cref(default_device));
2415 detail::errHandler(default_error_);
2416 return default_;
2417 }
2418
2419 /*! \brief Assignment operator from cl_device_id.
2420 *
2421 * This simply copies the device ID value, which is an inexpensive operation.
2422 */
2423 Device& operator = (const cl_device_id& rhs)
2424 {
2425 detail::Wrapper<cl_type>::operator=(rhs);
2426 return *this;
2427 }
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01002428
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002429
2430 //! \brief Wrapper for clGetDeviceInfo().
2431 template <typename T>
2432 cl_int getInfo(cl_device_info name, T* param) const
2433 {
2434 return detail::errHandler(
2435 detail::getInfo(&::clGetDeviceInfo, object_, name, param),
2436 __GET_DEVICE_INFO_ERR);
2437 }
2438
2439 //! \brief Wrapper for clGetDeviceInfo() that returns by value.
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00002440 template <cl_device_info name> typename
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002441 detail::param_traits<detail::cl_device_info, name>::param_type
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01002442 getInfo(cl_int* err = nullptr) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002443 {
2444 typename detail::param_traits<
2445 detail::cl_device_info, name>::param_type param;
2446 cl_int result = getInfo(name, &param);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01002447 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002448 *err = result;
2449 }
2450 return param;
2451 }
2452
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00002453#if CL_HPP_TARGET_OPENCL_VERSION >= 210
2454 /**
2455 * Return the current value of the host clock as seen by the device.
2456 * The resolution of the device timer may be queried with the
2457 * CL_DEVICE_PROFILING_TIMER_RESOLUTION query.
2458 * @return The host timer value.
2459 */
2460 cl_ulong getHostTimer(cl_int *error = nullptr)
2461 {
2462 cl_ulong retVal = 0;
2463 cl_int err =
2464 clGetHostTimer(this->get(), &retVal);
2465 detail::errHandler(
2466 err,
2467 __GET_HOST_TIMER_ERR);
2468 if (error) {
2469 *error = err;
2470 }
2471 return retVal;
2472 }
2473
2474 /**
2475 * Return a synchronized pair of host and device timestamps as seen by device.
2476 * Use to correlate the clocks and get the host timer only using getHostTimer
2477 * as a lower cost mechanism in between calls.
2478 * The resolution of the host timer may be queried with the
2479 * CL_PLATFORM_HOST_TIMER_RESOLUTION query.
2480 * The resolution of the device timer may be queried with the
2481 * CL_DEVICE_PROFILING_TIMER_RESOLUTION query.
2482 * @return A pair of (device timer, host timer) timer values.
2483 */
2484 std::pair<cl_ulong, cl_ulong> getDeviceAndHostTimer(cl_int *error = nullptr)
2485 {
2486 std::pair<cl_ulong, cl_ulong> retVal;
2487 cl_int err =
2488 clGetDeviceAndHostTimer(this->get(), &(retVal.first), &(retVal.second));
2489 detail::errHandler(
2490 err,
2491 __GET_DEVICE_AND_HOST_TIMER_ERR);
2492 if (error) {
2493 *error = err;
2494 }
2495 return retVal;
2496 }
2497#endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 210
2498
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002499#if CL_HPP_TARGET_OPENCL_VERSION >= 120
2500 //! \brief Wrapper for clCreateSubDevices().
2501 cl_int createSubDevices(
2502 const cl_device_partition_property * properties,
2503 vector<Device>* devices)
2504 {
2505 cl_uint n = 0;
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01002506 cl_int err = clCreateSubDevices(object_, properties, 0, nullptr, &n);
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002507 if (err != CL_SUCCESS) {
2508 return detail::errHandler(err, __CREATE_SUB_DEVICES_ERR);
2509 }
2510
2511 vector<cl_device_id> ids(n);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01002512 err = clCreateSubDevices(object_, properties, n, ids.data(), nullptr);
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002513 if (err != CL_SUCCESS) {
2514 return detail::errHandler(err, __CREATE_SUB_DEVICES_ERR);
2515 }
2516
2517 // Cannot trivially assign because we need to capture intermediates
2518 // with safe construction
2519 if (devices) {
2520 devices->resize(ids.size());
2521
2522 // Assign to param, constructing with retain behaviour
2523 // to correctly capture each underlying CL object
2524 for (size_type i = 0; i < ids.size(); i++) {
2525 // We do not need to retain because this device is being created
2526 // by the runtime
2527 (*devices)[i] = Device(ids[i], false);
2528 }
2529 }
2530
2531 return CL_SUCCESS;
2532 }
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01002533#endif
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002534
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01002535#if defined(cl_ext_device_fission)
2536 //! \brief Wrapper for clCreateSubDevices().
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002537 cl_int createSubDevices(
2538 const cl_device_partition_property_ext * properties,
2539 vector<Device>* devices)
2540 {
2541 typedef CL_API_ENTRY cl_int
2542 ( CL_API_CALL * PFN_clCreateSubDevicesEXT)(
2543 cl_device_id /*in_device*/,
2544 const cl_device_partition_property_ext * /* properties */,
2545 cl_uint /*num_entries*/,
2546 cl_device_id * /*out_devices*/,
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00002547 cl_uint * /*num_devices*/ ) CL_API_SUFFIX__VERSION_1_1;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002548
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01002549 static PFN_clCreateSubDevicesEXT pfn_clCreateSubDevicesEXT = nullptr;
2550#if CL_HPP_TARGET_OPENCL_VERSION >= 120
2551 cl::Device device(object_);
2552 cl_platform_id platform = device.getInfo<CL_DEVICE_PLATFORM>();
2553 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clCreateSubDevicesEXT);
2554#endif
2555#if CL_HPP_MINIMUM_OPENCL_VERSION < 120
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002556 CL_HPP_INIT_CL_EXT_FCN_PTR_(clCreateSubDevicesEXT);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01002557#endif
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002558
2559 cl_uint n = 0;
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01002560 cl_int err = pfn_clCreateSubDevicesEXT(object_, properties, 0, nullptr, &n);
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002561 if (err != CL_SUCCESS) {
2562 return detail::errHandler(err, __CREATE_SUB_DEVICES_ERR);
2563 }
2564
2565 vector<cl_device_id> ids(n);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01002566 err = pfn_clCreateSubDevicesEXT(object_, properties, n, ids.data(), nullptr);
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002567 if (err != CL_SUCCESS) {
2568 return detail::errHandler(err, __CREATE_SUB_DEVICES_ERR);
2569 }
2570 // Cannot trivially assign because we need to capture intermediates
2571 // with safe construction
2572 if (devices) {
2573 devices->resize(ids.size());
2574
2575 // Assign to param, constructing with retain behaviour
2576 // to correctly capture each underlying CL object
2577 for (size_type i = 0; i < ids.size(); i++) {
2578 // We do not need to retain because this device is being created
2579 // by the runtime
2580 (*devices)[i] = Device(ids[i], false);
2581 }
2582 }
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01002583
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002584 return CL_SUCCESS;
2585 }
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01002586#endif // defined(cl_ext_device_fission)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002587};
2588
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01002589using BuildLogType = vector<std::pair<cl::Device, typename detail::param_traits<detail::cl_program_build_info, CL_PROGRAM_BUILD_LOG>::param_type>>;
2590#if defined(CL_HPP_ENABLE_EXCEPTIONS)
2591/**
2592* Exception class for build errors to carry build info
2593*/
2594class BuildError : public Error
2595{
2596private:
2597 BuildLogType buildLogs;
2598public:
2599 BuildError(cl_int err, const char * errStr, const BuildLogType &vec) : Error(err, errStr), buildLogs(vec)
2600 {
2601 }
2602
2603 BuildLogType getBuildLog() const
2604 {
2605 return buildLogs;
2606 }
2607};
2608namespace detail {
2609 static inline cl_int buildErrHandler(
2610 cl_int err,
2611 const char * errStr,
2612 const BuildLogType &buildLogs)
2613 {
2614 if (err != CL_SUCCESS) {
2615 throw BuildError(err, errStr, buildLogs);
2616 }
2617 return err;
2618 }
2619} // namespace detail
2620
2621#else
2622namespace detail {
2623 static inline cl_int buildErrHandler(
2624 cl_int err,
2625 const char * errStr,
2626 const BuildLogType &buildLogs)
2627 {
2628 (void)buildLogs; // suppress unused variable warning
2629 (void)errStr;
2630 return err;
2631 }
2632} // namespace detail
2633#endif // #if defined(CL_HPP_ENABLE_EXCEPTIONS)
2634
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002635CL_HPP_DEFINE_STATIC_MEMBER_ std::once_flag Device::default_initialized_;
2636CL_HPP_DEFINE_STATIC_MEMBER_ Device Device::default_;
2637CL_HPP_DEFINE_STATIC_MEMBER_ cl_int Device::default_error_ = CL_SUCCESS;
2638
2639/*! \brief Class interface for cl_platform_id.
2640 *
2641 * \note Copies of these objects are inexpensive, since they don't 'own'
2642 * any underlying resources or data structures.
2643 *
2644 * \see cl_platform_id
2645 */
2646class Platform : public detail::Wrapper<cl_platform_id>
2647{
2648private:
2649 static std::once_flag default_initialized_;
2650 static Platform default_;
2651 static cl_int default_error_;
2652
2653 /*! \brief Create the default context.
2654 *
2655 * This sets @c default_ and @c default_error_. It does not throw
2656 * @c cl::Error.
2657 */
2658 static void makeDefault() {
2659 /* Throwing an exception from a call_once invocation does not do
2660 * what we wish, so we catch it and save the error.
2661 */
2662#if defined(CL_HPP_ENABLE_EXCEPTIONS)
2663 try
2664#endif
2665 {
2666 // If default wasn't passed ,generate one
2667 // Otherwise set it
2668 cl_uint n = 0;
2669
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01002670 cl_int err = ::clGetPlatformIDs(0, nullptr, &n);
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002671 if (err != CL_SUCCESS) {
2672 default_error_ = err;
2673 return;
2674 }
2675 if (n == 0) {
2676 default_error_ = CL_INVALID_PLATFORM;
2677 return;
2678 }
2679
2680 vector<cl_platform_id> ids(n);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01002681 err = ::clGetPlatformIDs(n, ids.data(), nullptr);
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002682 if (err != CL_SUCCESS) {
2683 default_error_ = err;
2684 return;
2685 }
2686
2687 default_ = Platform(ids[0]);
2688 }
2689#if defined(CL_HPP_ENABLE_EXCEPTIONS)
2690 catch (cl::Error &e) {
2691 default_error_ = e.err();
2692 }
2693#endif
2694 }
2695
2696 /*! \brief Create the default platform from a provided platform.
2697 *
2698 * This sets @c default_. It does not throw
2699 * @c cl::Error.
2700 */
2701 static void makeDefaultProvided(const Platform &p) {
2702 default_ = p;
2703 }
2704
2705public:
2706#ifdef CL_HPP_UNIT_TEST_ENABLE
2707 /*! \brief Reset the default.
2708 *
2709 * This sets @c default_ to an empty value to support cleanup in
2710 * the unit test framework.
2711 * This function is not thread safe.
2712 */
2713 static void unitTestClearDefault() {
2714 default_ = Platform();
2715 }
2716#endif // #ifdef CL_HPP_UNIT_TEST_ENABLE
2717
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01002718 //! \brief Default constructor - initializes to nullptr.
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002719 Platform() : detail::Wrapper<cl_type>() { }
2720
2721 /*! \brief Constructor from cl_platform_id.
2722 *
2723 * \param retainObject will cause the constructor to retain its cl object.
2724 * Defaults to false to maintain compatibility with
2725 * earlier versions.
2726 * This simply copies the platform ID value, which is an inexpensive operation.
2727 */
2728 explicit Platform(const cl_platform_id &platform, bool retainObject = false) :
2729 detail::Wrapper<cl_type>(platform, retainObject) { }
2730
2731 /*! \brief Assignment operator from cl_platform_id.
2732 *
2733 * This simply copies the platform ID value, which is an inexpensive operation.
2734 */
2735 Platform& operator = (const cl_platform_id& rhs)
2736 {
2737 detail::Wrapper<cl_type>::operator=(rhs);
2738 return *this;
2739 }
2740
2741 static Platform getDefault(
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01002742 cl_int *errResult = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002743 {
2744 std::call_once(default_initialized_, makeDefault);
2745 detail::errHandler(default_error_);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01002746 if (errResult != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002747 *errResult = default_error_;
2748 }
2749 return default_;
2750 }
2751
2752 /**
2753 * Modify the default platform to be used by
2754 * subsequent operations.
2755 * Will only set the default if no default was previously created.
2756 * @return updated default platform.
2757 * Should be compared to the passed value to ensure that it was updated.
2758 */
2759 static Platform setDefault(const Platform &default_platform)
2760 {
2761 std::call_once(default_initialized_, makeDefaultProvided, std::cref(default_platform));
2762 detail::errHandler(default_error_);
2763 return default_;
2764 }
2765
2766 //! \brief Wrapper for clGetPlatformInfo().
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00002767 template <typename T>
2768 cl_int getInfo(cl_platform_info name, T* param) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002769 {
2770 return detail::errHandler(
2771 detail::getInfo(&::clGetPlatformInfo, object_, name, param),
2772 __GET_PLATFORM_INFO_ERR);
2773 }
2774
2775 //! \brief Wrapper for clGetPlatformInfo() that returns by value.
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00002776 template <cl_platform_info name> typename
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002777 detail::param_traits<detail::cl_platform_info, name>::param_type
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01002778 getInfo(cl_int* err = nullptr) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002779 {
2780 typename detail::param_traits<
2781 detail::cl_platform_info, name>::param_type param;
2782 cl_int result = getInfo(name, &param);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01002783 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002784 *err = result;
2785 }
2786 return param;
2787 }
2788
2789 /*! \brief Gets a list of devices for this platform.
2790 *
2791 * Wraps clGetDeviceIDs().
2792 */
2793 cl_int getDevices(
2794 cl_device_type type,
2795 vector<Device>* devices) const
2796 {
2797 cl_uint n = 0;
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01002798 if( devices == nullptr ) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002799 return detail::errHandler(CL_INVALID_ARG_VALUE, __GET_DEVICE_IDS_ERR);
2800 }
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01002801 cl_int err = ::clGetDeviceIDs(object_, type, 0, nullptr, &n);
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00002802 if (err != CL_SUCCESS && err != CL_DEVICE_NOT_FOUND) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002803 return detail::errHandler(err, __GET_DEVICE_IDS_ERR);
2804 }
2805
2806 vector<cl_device_id> ids(n);
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00002807 if (n>0) {
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01002808 err = ::clGetDeviceIDs(object_, type, n, ids.data(), nullptr);
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00002809 if (err != CL_SUCCESS) {
2810 return detail::errHandler(err, __GET_DEVICE_IDS_ERR);
2811 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002812 }
2813
2814 // Cannot trivially assign because we need to capture intermediates
2815 // with safe construction
2816 // We must retain things we obtain from the API to avoid releasing
2817 // API-owned objects.
2818 if (devices) {
2819 devices->resize(ids.size());
2820
2821 // Assign to param, constructing with retain behaviour
2822 // to correctly capture each underlying CL object
2823 for (size_type i = 0; i < ids.size(); i++) {
2824 (*devices)[i] = Device(ids[i], true);
2825 }
2826 }
2827 return CL_SUCCESS;
2828 }
2829
2830#if defined(CL_HPP_USE_DX_INTEROP)
2831 /*! \brief Get the list of available D3D10 devices.
2832 *
2833 * \param d3d_device_source.
2834 *
2835 * \param d3d_object.
2836 *
2837 * \param d3d_device_set.
2838 *
2839 * \param devices returns a vector of OpenCL D3D10 devices found. The cl::Device
2840 * values returned in devices can be used to identify a specific OpenCL
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01002841 * device. If \a devices argument is nullptr, this argument is ignored.
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002842 *
2843 * \return One of the following values:
2844 * - CL_SUCCESS if the function is executed successfully.
2845 *
2846 * The application can query specific capabilities of the OpenCL device(s)
2847 * returned by cl::getDevices. This can be used by the application to
2848 * determine which device(s) to use.
2849 *
2850 * \note In the case that exceptions are enabled and a return value
2851 * other than CL_SUCCESS is generated, then cl::Error exception is
2852 * generated.
2853 */
2854 cl_int getDevices(
2855 cl_d3d10_device_source_khr d3d_device_source,
2856 void * d3d_object,
2857 cl_d3d10_device_set_khr d3d_device_set,
2858 vector<Device>* devices) const
2859 {
2860 typedef CL_API_ENTRY cl_int (CL_API_CALL *PFN_clGetDeviceIDsFromD3D10KHR)(
2861 cl_platform_id platform,
2862 cl_d3d10_device_source_khr d3d_device_source,
2863 void * d3d_object,
2864 cl_d3d10_device_set_khr d3d_device_set,
2865 cl_uint num_entries,
2866 cl_device_id * devices,
2867 cl_uint* num_devices);
2868
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01002869 if( devices == nullptr ) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002870 return detail::errHandler(CL_INVALID_ARG_VALUE, __GET_DEVICE_IDS_ERR);
2871 }
2872
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01002873 static PFN_clGetDeviceIDsFromD3D10KHR pfn_clGetDeviceIDsFromD3D10KHR = nullptr;
2874#if CL_HPP_TARGET_OPENCL_VERSION >= 120
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002875 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(object_, clGetDeviceIDsFromD3D10KHR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01002876#endif
2877#if CL_HPP_MINIMUM_OPENCL_VERSION < 120
2878 CL_HPP_INIT_CL_EXT_FCN_PTR_(clGetDeviceIDsFromD3D10KHR);
2879#endif
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002880
2881 cl_uint n = 0;
2882 cl_int err = pfn_clGetDeviceIDsFromD3D10KHR(
2883 object_,
2884 d3d_device_source,
2885 d3d_object,
2886 d3d_device_set,
2887 0,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01002888 nullptr,
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002889 &n);
2890 if (err != CL_SUCCESS) {
2891 return detail::errHandler(err, __GET_DEVICE_IDS_ERR);
2892 }
2893
2894 vector<cl_device_id> ids(n);
2895 err = pfn_clGetDeviceIDsFromD3D10KHR(
2896 object_,
2897 d3d_device_source,
2898 d3d_object,
2899 d3d_device_set,
2900 n,
2901 ids.data(),
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01002902 nullptr);
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002903 if (err != CL_SUCCESS) {
2904 return detail::errHandler(err, __GET_DEVICE_IDS_ERR);
2905 }
2906
2907 // Cannot trivially assign because we need to capture intermediates
2908 // with safe construction
2909 // We must retain things we obtain from the API to avoid releasing
2910 // API-owned objects.
2911 if (devices) {
2912 devices->resize(ids.size());
2913
2914 // Assign to param, constructing with retain behaviour
2915 // to correctly capture each underlying CL object
2916 for (size_type i = 0; i < ids.size(); i++) {
2917 (*devices)[i] = Device(ids[i], true);
2918 }
2919 }
2920 return CL_SUCCESS;
2921 }
2922#endif
2923
2924 /*! \brief Gets a list of available platforms.
2925 *
2926 * Wraps clGetPlatformIDs().
2927 */
2928 static cl_int get(
2929 vector<Platform>* platforms)
2930 {
2931 cl_uint n = 0;
2932
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01002933 if( platforms == nullptr ) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002934 return detail::errHandler(CL_INVALID_ARG_VALUE, __GET_PLATFORM_IDS_ERR);
2935 }
2936
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01002937 cl_int err = ::clGetPlatformIDs(0, nullptr, &n);
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002938 if (err != CL_SUCCESS) {
2939 return detail::errHandler(err, __GET_PLATFORM_IDS_ERR);
2940 }
2941
2942 vector<cl_platform_id> ids(n);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01002943 err = ::clGetPlatformIDs(n, ids.data(), nullptr);
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002944 if (err != CL_SUCCESS) {
2945 return detail::errHandler(err, __GET_PLATFORM_IDS_ERR);
2946 }
2947
2948 if (platforms) {
2949 platforms->resize(ids.size());
2950
2951 // Platforms don't reference count
2952 for (size_type i = 0; i < ids.size(); i++) {
2953 (*platforms)[i] = Platform(ids[i]);
2954 }
2955 }
2956 return CL_SUCCESS;
2957 }
2958
2959 /*! \brief Gets the first available platform.
2960 *
2961 * Wraps clGetPlatformIDs(), returning the first result.
2962 */
2963 static cl_int get(
2964 Platform * platform)
2965 {
2966 cl_int err;
2967 Platform default_platform = Platform::getDefault(&err);
2968 if (platform) {
2969 *platform = default_platform;
2970 }
2971 return err;
2972 }
2973
2974 /*! \brief Gets the first available platform, returning it by value.
2975 *
2976 * \return Returns a valid platform if one is available.
2977 * If no platform is available will return a null platform.
2978 * Throws an exception if no platforms are available
2979 * or an error condition occurs.
2980 * Wraps clGetPlatformIDs(), returning the first result.
2981 */
2982 static Platform get(
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01002983 cl_int * errResult = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002984 {
2985 cl_int err;
2986 Platform default_platform = Platform::getDefault(&err);
2987 if (errResult) {
2988 *errResult = err;
2989 }
2990 return default_platform;
2991 }
2992
2993#if CL_HPP_TARGET_OPENCL_VERSION >= 120
2994 //! \brief Wrapper for clUnloadCompiler().
2995 cl_int
2996 unloadCompiler()
2997 {
2998 return ::clUnloadPlatformCompiler(object_);
2999 }
3000#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
3001}; // class Platform
3002
3003CL_HPP_DEFINE_STATIC_MEMBER_ std::once_flag Platform::default_initialized_;
3004CL_HPP_DEFINE_STATIC_MEMBER_ Platform Platform::default_;
3005CL_HPP_DEFINE_STATIC_MEMBER_ cl_int Platform::default_error_ = CL_SUCCESS;
3006
3007
3008/**
3009 * Deprecated APIs for 1.2
3010 */
3011#if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
3012/**
3013 * Unload the OpenCL compiler.
3014 * \note Deprecated for OpenCL 1.2. Use Platform::unloadCompiler instead.
3015 */
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00003016inline CL_API_PREFIX__VERSION_1_1_DEPRECATED cl_int
3017UnloadCompiler() CL_API_SUFFIX__VERSION_1_1_DEPRECATED;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003018inline cl_int
3019UnloadCompiler()
3020{
3021 return ::clUnloadCompiler();
3022}
3023#endif // #if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
3024
3025/*! \brief Class interface for cl_context.
3026 *
3027 * \note Copies of these objects are shallow, meaning that the copy will refer
3028 * to the same underlying cl_context as the original. For details, see
3029 * clRetainContext() and clReleaseContext().
3030 *
3031 * \see cl_context
3032 */
3033class Context
3034 : public detail::Wrapper<cl_context>
3035{
3036private:
3037 static std::once_flag default_initialized_;
3038 static Context default_;
3039 static cl_int default_error_;
3040
3041 /*! \brief Create the default context from the default device type in the default platform.
3042 *
3043 * This sets @c default_ and @c default_error_. It does not throw
3044 * @c cl::Error.
3045 */
3046 static void makeDefault() {
3047 /* Throwing an exception from a call_once invocation does not do
3048 * what we wish, so we catch it and save the error.
3049 */
3050#if defined(CL_HPP_ENABLE_EXCEPTIONS)
3051 try
3052#endif
3053 {
3054#if !defined(__APPLE__) && !defined(__MACOS)
3055 const Platform &p = Platform::getDefault();
3056 cl_platform_id defaultPlatform = p();
3057 cl_context_properties properties[3] = {
3058 CL_CONTEXT_PLATFORM, (cl_context_properties)defaultPlatform, 0
3059 };
3060#else // #if !defined(__APPLE__) && !defined(__MACOS)
3061 cl_context_properties *properties = nullptr;
3062#endif // #if !defined(__APPLE__) && !defined(__MACOS)
3063
3064 default_ = Context(
3065 CL_DEVICE_TYPE_DEFAULT,
3066 properties,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01003067 nullptr,
3068 nullptr,
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003069 &default_error_);
3070 }
3071#if defined(CL_HPP_ENABLE_EXCEPTIONS)
3072 catch (cl::Error &e) {
3073 default_error_ = e.err();
3074 }
3075#endif
3076 }
3077
3078
3079 /*! \brief Create the default context from a provided Context.
3080 *
3081 * This sets @c default_. It does not throw
3082 * @c cl::Error.
3083 */
3084 static void makeDefaultProvided(const Context &c) {
3085 default_ = c;
3086 }
3087
3088public:
3089#ifdef CL_HPP_UNIT_TEST_ENABLE
3090 /*! \brief Reset the default.
3091 *
3092 * This sets @c default_ to an empty value to support cleanup in
3093 * the unit test framework.
3094 * This function is not thread safe.
3095 */
3096 static void unitTestClearDefault() {
3097 default_ = Context();
3098 }
3099#endif // #ifdef CL_HPP_UNIT_TEST_ENABLE
3100
3101 /*! \brief Constructs a context including a list of specified devices.
3102 *
3103 * Wraps clCreateContext().
3104 */
3105 Context(
3106 const vector<Device>& devices,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01003107 const cl_context_properties* properties = nullptr,
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003108 void (CL_CALLBACK * notifyFptr)(
3109 const char *,
3110 const void *,
3111 size_type,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01003112 void *) = nullptr,
3113 void* data = nullptr,
3114 cl_int* err = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003115 {
3116 cl_int error;
3117
3118 size_type numDevices = devices.size();
3119 vector<cl_device_id> deviceIDs(numDevices);
3120
3121 for( size_type deviceIndex = 0; deviceIndex < numDevices; ++deviceIndex ) {
3122 deviceIDs[deviceIndex] = (devices[deviceIndex])();
3123 }
3124
3125 object_ = ::clCreateContext(
3126 properties, (cl_uint) numDevices,
3127 deviceIDs.data(),
3128 notifyFptr, data, &error);
3129
3130 detail::errHandler(error, __CREATE_CONTEXT_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01003131 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003132 *err = error;
3133 }
3134 }
3135
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00003136 /*! \brief Constructs a context including a specific device.
3137 *
3138 * Wraps clCreateContext().
3139 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003140 Context(
3141 const Device& device,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01003142 const cl_context_properties* properties = nullptr,
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003143 void (CL_CALLBACK * notifyFptr)(
3144 const char *,
3145 const void *,
3146 size_type,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01003147 void *) = nullptr,
3148 void* data = nullptr,
3149 cl_int* err = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003150 {
3151 cl_int error;
3152
3153 cl_device_id deviceID = device();
3154
3155 object_ = ::clCreateContext(
3156 properties, 1,
3157 &deviceID,
3158 notifyFptr, data, &error);
3159
3160 detail::errHandler(error, __CREATE_CONTEXT_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01003161 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003162 *err = error;
3163 }
3164 }
3165
3166 /*! \brief Constructs a context including all or a subset of devices of a specified type.
3167 *
3168 * Wraps clCreateContextFromType().
3169 */
3170 Context(
3171 cl_device_type type,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01003172 const cl_context_properties* properties = nullptr,
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003173 void (CL_CALLBACK * notifyFptr)(
3174 const char *,
3175 const void *,
3176 size_type,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01003177 void *) = nullptr,
3178 void* data = nullptr,
3179 cl_int* err = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003180 {
3181 cl_int error;
3182
3183#if !defined(__APPLE__) && !defined(__MACOS)
3184 cl_context_properties prop[4] = {CL_CONTEXT_PLATFORM, 0, 0, 0 };
3185
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01003186 if (properties == nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003187 // Get a valid platform ID as we cannot send in a blank one
3188 vector<Platform> platforms;
3189 error = Platform::get(&platforms);
3190 if (error != CL_SUCCESS) {
3191 detail::errHandler(error, __CREATE_CONTEXT_FROM_TYPE_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01003192 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003193 *err = error;
3194 }
3195 return;
3196 }
3197
3198 // Check the platforms we found for a device of our specified type
3199 cl_context_properties platform_id = 0;
3200 for (unsigned int i = 0; i < platforms.size(); i++) {
3201
3202 vector<Device> devices;
3203
3204#if defined(CL_HPP_ENABLE_EXCEPTIONS)
3205 try {
3206#endif
3207
3208 error = platforms[i].getDevices(type, &devices);
3209
3210#if defined(CL_HPP_ENABLE_EXCEPTIONS)
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00003211 } catch (cl::Error& e) {
3212 error = e.err();
3213 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003214 // Catch if exceptions are enabled as we don't want to exit if first platform has no devices of type
3215 // We do error checking next anyway, and can throw there if needed
3216#endif
3217
3218 // Only squash CL_SUCCESS and CL_DEVICE_NOT_FOUND
3219 if (error != CL_SUCCESS && error != CL_DEVICE_NOT_FOUND) {
3220 detail::errHandler(error, __CREATE_CONTEXT_FROM_TYPE_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01003221 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003222 *err = error;
3223 }
3224 }
3225
3226 if (devices.size() > 0) {
3227 platform_id = (cl_context_properties)platforms[i]();
3228 break;
3229 }
3230 }
3231
3232 if (platform_id == 0) {
3233 detail::errHandler(CL_DEVICE_NOT_FOUND, __CREATE_CONTEXT_FROM_TYPE_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01003234 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003235 *err = CL_DEVICE_NOT_FOUND;
3236 }
3237 return;
3238 }
3239
3240 prop[1] = platform_id;
3241 properties = &prop[0];
3242 }
3243#endif
3244 object_ = ::clCreateContextFromType(
3245 properties, type, notifyFptr, data, &error);
3246
3247 detail::errHandler(error, __CREATE_CONTEXT_FROM_TYPE_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01003248 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003249 *err = error;
3250 }
3251 }
3252
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003253
3254 /*! \brief Returns a singleton context including all devices of CL_DEVICE_TYPE_DEFAULT.
3255 *
3256 * \note All calls to this function return the same cl_context as the first.
3257 */
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01003258 static Context getDefault(cl_int * err = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003259 {
3260 std::call_once(default_initialized_, makeDefault);
3261 detail::errHandler(default_error_);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01003262 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003263 *err = default_error_;
3264 }
3265 return default_;
3266 }
3267
3268 /**
3269 * Modify the default context to be used by
3270 * subsequent operations.
3271 * Will only set the default if no default was previously created.
3272 * @return updated default context.
3273 * Should be compared to the passed value to ensure that it was updated.
3274 */
3275 static Context setDefault(const Context &default_context)
3276 {
3277 std::call_once(default_initialized_, makeDefaultProvided, std::cref(default_context));
3278 detail::errHandler(default_error_);
3279 return default_;
3280 }
3281
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01003282 //! \brief Default constructor - initializes to nullptr.
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003283 Context() : detail::Wrapper<cl_type>() { }
3284
3285 /*! \brief Constructor from cl_context - takes ownership.
3286 *
3287 * This effectively transfers ownership of a refcount on the cl_context
3288 * into the new Context object.
3289 */
3290 explicit Context(const cl_context& context, bool retainObject = false) :
3291 detail::Wrapper<cl_type>(context, retainObject) { }
3292
3293 /*! \brief Assignment operator from cl_context - takes ownership.
3294 *
3295 * This effectively transfers ownership of a refcount on the rhs and calls
3296 * clReleaseContext() on the value previously held by this instance.
3297 */
3298 Context& operator = (const cl_context& rhs)
3299 {
3300 detail::Wrapper<cl_type>::operator=(rhs);
3301 return *this;
3302 }
3303
3304 //! \brief Wrapper for clGetContextInfo().
3305 template <typename T>
3306 cl_int getInfo(cl_context_info name, T* param) const
3307 {
3308 return detail::errHandler(
3309 detail::getInfo(&::clGetContextInfo, object_, name, param),
3310 __GET_CONTEXT_INFO_ERR);
3311 }
3312
3313 //! \brief Wrapper for clGetContextInfo() that returns by value.
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00003314 template <cl_context_info name> typename
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003315 detail::param_traits<detail::cl_context_info, name>::param_type
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01003316 getInfo(cl_int* err = nullptr) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003317 {
3318 typename detail::param_traits<
3319 detail::cl_context_info, name>::param_type param;
3320 cl_int result = getInfo(name, &param);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01003321 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003322 *err = result;
3323 }
3324 return param;
3325 }
3326
3327 /*! \brief Gets a list of supported image formats.
3328 *
3329 * Wraps clGetSupportedImageFormats().
3330 */
3331 cl_int getSupportedImageFormats(
3332 cl_mem_flags flags,
3333 cl_mem_object_type type,
3334 vector<ImageFormat>* formats) const
3335 {
3336 cl_uint numEntries;
3337
3338 if (!formats) {
3339 return CL_SUCCESS;
3340 }
3341
3342 cl_int err = ::clGetSupportedImageFormats(
3343 object_,
3344 flags,
3345 type,
3346 0,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01003347 nullptr,
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003348 &numEntries);
3349 if (err != CL_SUCCESS) {
3350 return detail::errHandler(err, __GET_SUPPORTED_IMAGE_FORMATS_ERR);
3351 }
3352
3353 if (numEntries > 0) {
3354 vector<ImageFormat> value(numEntries);
3355 err = ::clGetSupportedImageFormats(
3356 object_,
3357 flags,
3358 type,
3359 numEntries,
3360 (cl_image_format*)value.data(),
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01003361 nullptr);
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003362 if (err != CL_SUCCESS) {
3363 return detail::errHandler(err, __GET_SUPPORTED_IMAGE_FORMATS_ERR);
3364 }
3365
3366 formats->assign(begin(value), end(value));
3367 }
3368 else {
3369 // If no values are being returned, ensure an empty vector comes back
3370 formats->clear();
3371 }
3372
3373 return CL_SUCCESS;
3374 }
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01003375
3376#if CL_HPP_TARGET_OPENCL_VERSION >= 300
3377 /*! \brief Registers a destructor callback function with a context.
3378 *
3379 * Wraps clSetContextDestructorCallback().
3380 *
3381 * Each call to this function registers the specified callback function on
3382 * a destructor callback stack associated with context. The registered
3383 * callback functions are called in the reverse order in which they were registered.
3384 * If a context callback function was specified when context was created,
3385 * it will not be called after any context destructor callback is called.
3386 */
3387 cl_int setDestructorCallback(
3388 void (CL_CALLBACK * pfn_notify)(cl_context, void *),
3389 void * user_data = nullptr)
3390 {
3391 return detail::errHandler(
3392 ::clSetContextDestructorCallback(
3393 object_,
3394 pfn_notify,
3395 user_data),
3396 __SET_CONTEXT_DESCTRUCTOR_CALLBACK_ERR);
3397 }
3398#endif // CL_HPP_TARGET_OPENCL_VERSION >= 300
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003399};
3400
3401inline void Device::makeDefault()
3402{
3403 /* Throwing an exception from a call_once invocation does not do
3404 * what we wish, so we catch it and save the error.
3405 */
3406#if defined(CL_HPP_ENABLE_EXCEPTIONS)
3407 try
3408#endif
3409 {
3410 cl_int error = 0;
3411
3412 Context context = Context::getDefault(&error);
3413 detail::errHandler(error, __CREATE_CONTEXT_ERR);
3414
3415 if (error != CL_SUCCESS) {
3416 default_error_ = error;
3417 }
3418 else {
3419 default_ = context.getInfo<CL_CONTEXT_DEVICES>()[0];
3420 default_error_ = CL_SUCCESS;
3421 }
3422 }
3423#if defined(CL_HPP_ENABLE_EXCEPTIONS)
3424 catch (cl::Error &e) {
3425 default_error_ = e.err();
3426 }
3427#endif
3428}
3429
3430CL_HPP_DEFINE_STATIC_MEMBER_ std::once_flag Context::default_initialized_;
3431CL_HPP_DEFINE_STATIC_MEMBER_ Context Context::default_;
3432CL_HPP_DEFINE_STATIC_MEMBER_ cl_int Context::default_error_ = CL_SUCCESS;
3433
3434/*! \brief Class interface for cl_event.
3435 *
3436 * \note Copies of these objects are shallow, meaning that the copy will refer
3437 * to the same underlying cl_event as the original. For details, see
3438 * clRetainEvent() and clReleaseEvent().
3439 *
3440 * \see cl_event
3441 */
3442class Event : public detail::Wrapper<cl_event>
3443{
3444public:
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01003445 //! \brief Default constructor - initializes to nullptr.
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003446 Event() : detail::Wrapper<cl_type>() { }
3447
3448 /*! \brief Constructor from cl_event - takes ownership.
3449 *
3450 * \param retainObject will cause the constructor to retain its cl object.
3451 * Defaults to false to maintain compatibility with
3452 * earlier versions.
3453 * This effectively transfers ownership of a refcount on the cl_event
3454 * into the new Event object.
3455 */
3456 explicit Event(const cl_event& event, bool retainObject = false) :
3457 detail::Wrapper<cl_type>(event, retainObject) { }
3458
3459 /*! \brief Assignment operator from cl_event - takes ownership.
3460 *
3461 * This effectively transfers ownership of a refcount on the rhs and calls
3462 * clReleaseEvent() on the value previously held by this instance.
3463 */
3464 Event& operator = (const cl_event& rhs)
3465 {
3466 detail::Wrapper<cl_type>::operator=(rhs);
3467 return *this;
3468 }
3469
3470 //! \brief Wrapper for clGetEventInfo().
3471 template <typename T>
3472 cl_int getInfo(cl_event_info name, T* param) const
3473 {
3474 return detail::errHandler(
3475 detail::getInfo(&::clGetEventInfo, object_, name, param),
3476 __GET_EVENT_INFO_ERR);
3477 }
3478
3479 //! \brief Wrapper for clGetEventInfo() that returns by value.
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00003480 template <cl_event_info name> typename
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003481 detail::param_traits<detail::cl_event_info, name>::param_type
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01003482 getInfo(cl_int* err = nullptr) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003483 {
3484 typename detail::param_traits<
3485 detail::cl_event_info, name>::param_type param;
3486 cl_int result = getInfo(name, &param);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01003487 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003488 *err = result;
3489 }
3490 return param;
3491 }
3492
3493 //! \brief Wrapper for clGetEventProfilingInfo().
3494 template <typename T>
3495 cl_int getProfilingInfo(cl_profiling_info name, T* param) const
3496 {
3497 return detail::errHandler(detail::getInfo(
3498 &::clGetEventProfilingInfo, object_, name, param),
3499 __GET_EVENT_PROFILE_INFO_ERR);
3500 }
3501
3502 //! \brief Wrapper for clGetEventProfilingInfo() that returns by value.
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00003503 template <cl_profiling_info name> typename
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003504 detail::param_traits<detail::cl_profiling_info, name>::param_type
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01003505 getProfilingInfo(cl_int* err = nullptr) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003506 {
3507 typename detail::param_traits<
3508 detail::cl_profiling_info, name>::param_type param;
3509 cl_int result = getProfilingInfo(name, &param);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01003510 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003511 *err = result;
3512 }
3513 return param;
3514 }
3515
3516 /*! \brief Blocks the calling thread until this event completes.
3517 *
3518 * Wraps clWaitForEvents().
3519 */
3520 cl_int wait() const
3521 {
3522 return detail::errHandler(
3523 ::clWaitForEvents(1, &object_),
3524 __WAIT_FOR_EVENTS_ERR);
3525 }
3526
3527#if CL_HPP_TARGET_OPENCL_VERSION >= 110
3528 /*! \brief Registers a user callback function for a specific command execution status.
3529 *
3530 * Wraps clSetEventCallback().
3531 */
3532 cl_int setCallback(
3533 cl_int type,
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00003534 void (CL_CALLBACK * pfn_notify)(cl_event, cl_int, void *),
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01003535 void * user_data = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003536 {
3537 return detail::errHandler(
3538 ::clSetEventCallback(
3539 object_,
3540 type,
3541 pfn_notify,
3542 user_data),
3543 __SET_EVENT_CALLBACK_ERR);
3544 }
3545#endif // CL_HPP_TARGET_OPENCL_VERSION >= 110
3546
3547 /*! \brief Blocks the calling thread until every event specified is complete.
3548 *
3549 * Wraps clWaitForEvents().
3550 */
3551 static cl_int
3552 waitForEvents(const vector<Event>& events)
3553 {
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01003554 static_assert(sizeof(cl::Event) == sizeof(cl_event),
3555 "Size of cl::Event must be equal to size of cl_event");
3556
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003557 return detail::errHandler(
3558 ::clWaitForEvents(
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01003559 (cl_uint) events.size(), (events.size() > 0) ? (cl_event*)&events.front() : nullptr),
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003560 __WAIT_FOR_EVENTS_ERR);
3561 }
3562};
3563
3564#if CL_HPP_TARGET_OPENCL_VERSION >= 110
3565/*! \brief Class interface for user events (a subset of cl_event's).
3566 *
3567 * See Event for details about copy semantics, etc.
3568 */
3569class UserEvent : public Event
3570{
3571public:
3572 /*! \brief Constructs a user event on a given context.
3573 *
3574 * Wraps clCreateUserEvent().
3575 */
3576 UserEvent(
3577 const Context& context,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01003578 cl_int * err = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003579 {
3580 cl_int error;
3581 object_ = ::clCreateUserEvent(
3582 context(),
3583 &error);
3584
3585 detail::errHandler(error, __CREATE_USER_EVENT_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01003586 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003587 *err = error;
3588 }
3589 }
3590
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01003591 //! \brief Default constructor - initializes to nullptr.
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003592 UserEvent() : Event() { }
3593
3594 /*! \brief Sets the execution status of a user event object.
3595 *
3596 * Wraps clSetUserEventStatus().
3597 */
3598 cl_int setStatus(cl_int status)
3599 {
3600 return detail::errHandler(
3601 ::clSetUserEventStatus(object_,status),
3602 __SET_USER_EVENT_STATUS_ERR);
3603 }
3604};
3605#endif // CL_HPP_TARGET_OPENCL_VERSION >= 110
3606
3607/*! \brief Blocks the calling thread until every event specified is complete.
3608 *
3609 * Wraps clWaitForEvents().
3610 */
3611inline static cl_int
3612WaitForEvents(const vector<Event>& events)
3613{
3614 return detail::errHandler(
3615 ::clWaitForEvents(
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01003616 (cl_uint) events.size(), (events.size() > 0) ? (cl_event*)&events.front() : nullptr),
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003617 __WAIT_FOR_EVENTS_ERR);
3618}
3619
3620/*! \brief Class interface for cl_mem.
3621 *
3622 * \note Copies of these objects are shallow, meaning that the copy will refer
3623 * to the same underlying cl_mem as the original. For details, see
3624 * clRetainMemObject() and clReleaseMemObject().
3625 *
3626 * \see cl_mem
3627 */
3628class Memory : public detail::Wrapper<cl_mem>
3629{
3630public:
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01003631 //! \brief Default constructor - initializes to nullptr.
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003632 Memory() : detail::Wrapper<cl_type>() { }
3633
3634 /*! \brief Constructor from cl_mem - takes ownership.
3635 *
3636 * Optionally transfer ownership of a refcount on the cl_mem
3637 * into the new Memory object.
3638 *
3639 * \param retainObject will cause the constructor to retain its cl object.
3640 * Defaults to false to maintain compatibility with
3641 * earlier versions.
3642 *
3643 * See Memory for further details.
3644 */
3645 explicit Memory(const cl_mem& memory, bool retainObject) :
3646 detail::Wrapper<cl_type>(memory, retainObject) { }
3647
3648 /*! \brief Assignment operator from cl_mem - takes ownership.
3649 *
3650 * This effectively transfers ownership of a refcount on the rhs and calls
3651 * clReleaseMemObject() on the value previously held by this instance.
3652 */
3653 Memory& operator = (const cl_mem& rhs)
3654 {
3655 detail::Wrapper<cl_type>::operator=(rhs);
3656 return *this;
3657 }
3658
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003659 //! \brief Wrapper for clGetMemObjectInfo().
3660 template <typename T>
3661 cl_int getInfo(cl_mem_info name, T* param) const
3662 {
3663 return detail::errHandler(
3664 detail::getInfo(&::clGetMemObjectInfo, object_, name, param),
3665 __GET_MEM_OBJECT_INFO_ERR);
3666 }
3667
3668 //! \brief Wrapper for clGetMemObjectInfo() that returns by value.
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00003669 template <cl_mem_info name> typename
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003670 detail::param_traits<detail::cl_mem_info, name>::param_type
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01003671 getInfo(cl_int* err = nullptr) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003672 {
3673 typename detail::param_traits<
3674 detail::cl_mem_info, name>::param_type param;
3675 cl_int result = getInfo(name, &param);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01003676 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003677 *err = result;
3678 }
3679 return param;
3680 }
3681
3682#if CL_HPP_TARGET_OPENCL_VERSION >= 110
3683 /*! \brief Registers a callback function to be called when the memory object
3684 * is no longer needed.
3685 *
3686 * Wraps clSetMemObjectDestructorCallback().
3687 *
3688 * Repeated calls to this function, for a given cl_mem value, will append
3689 * to the list of functions called (in reverse order) when memory object's
3690 * resources are freed and the memory object is deleted.
3691 *
3692 * \note
3693 * The registered callbacks are associated with the underlying cl_mem
3694 * value - not the Memory class instance.
3695 */
3696 cl_int setDestructorCallback(
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00003697 void (CL_CALLBACK * pfn_notify)(cl_mem, void *),
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01003698 void * user_data = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003699 {
3700 return detail::errHandler(
3701 ::clSetMemObjectDestructorCallback(
3702 object_,
3703 pfn_notify,
3704 user_data),
3705 __SET_MEM_OBJECT_DESTRUCTOR_CALLBACK_ERR);
3706 }
3707#endif // CL_HPP_TARGET_OPENCL_VERSION >= 110
3708
3709};
3710
3711// Pre-declare copy functions
3712class Buffer;
3713template< typename IteratorType >
3714cl_int copy( IteratorType startIterator, IteratorType endIterator, cl::Buffer &buffer );
3715template< typename IteratorType >
3716cl_int copy( const cl::Buffer &buffer, IteratorType startIterator, IteratorType endIterator );
3717template< typename IteratorType >
3718cl_int copy( const CommandQueue &queue, IteratorType startIterator, IteratorType endIterator, cl::Buffer &buffer );
3719template< typename IteratorType >
3720cl_int copy( const CommandQueue &queue, const cl::Buffer &buffer, IteratorType startIterator, IteratorType endIterator );
3721
3722
3723#if CL_HPP_TARGET_OPENCL_VERSION >= 200
3724namespace detail
3725{
3726 class SVMTraitNull
3727 {
3728 public:
3729 static cl_svm_mem_flags getSVMMemFlags()
3730 {
3731 return 0;
3732 }
3733 };
3734} // namespace detail
3735
3736template<class Trait = detail::SVMTraitNull>
3737class SVMTraitReadWrite
3738{
3739public:
3740 static cl_svm_mem_flags getSVMMemFlags()
3741 {
3742 return CL_MEM_READ_WRITE |
3743 Trait::getSVMMemFlags();
3744 }
3745};
3746
3747template<class Trait = detail::SVMTraitNull>
3748class SVMTraitReadOnly
3749{
3750public:
3751 static cl_svm_mem_flags getSVMMemFlags()
3752 {
3753 return CL_MEM_READ_ONLY |
3754 Trait::getSVMMemFlags();
3755 }
3756};
3757
3758template<class Trait = detail::SVMTraitNull>
3759class SVMTraitWriteOnly
3760{
3761public:
3762 static cl_svm_mem_flags getSVMMemFlags()
3763 {
3764 return CL_MEM_WRITE_ONLY |
3765 Trait::getSVMMemFlags();
3766 }
3767};
3768
3769template<class Trait = SVMTraitReadWrite<>>
3770class SVMTraitCoarse
3771{
3772public:
3773 static cl_svm_mem_flags getSVMMemFlags()
3774 {
3775 return Trait::getSVMMemFlags();
3776 }
3777};
3778
3779template<class Trait = SVMTraitReadWrite<>>
3780class SVMTraitFine
3781{
3782public:
3783 static cl_svm_mem_flags getSVMMemFlags()
3784 {
3785 return CL_MEM_SVM_FINE_GRAIN_BUFFER |
3786 Trait::getSVMMemFlags();
3787 }
3788};
3789
3790template<class Trait = SVMTraitReadWrite<>>
3791class SVMTraitAtomic
3792{
3793public:
3794 static cl_svm_mem_flags getSVMMemFlags()
3795 {
3796 return
3797 CL_MEM_SVM_FINE_GRAIN_BUFFER |
3798 CL_MEM_SVM_ATOMICS |
3799 Trait::getSVMMemFlags();
3800 }
3801};
3802
3803// Pre-declare SVM map function
3804template<typename T>
3805inline cl_int enqueueMapSVM(
3806 T* ptr,
3807 cl_bool blocking,
3808 cl_map_flags flags,
3809 size_type size,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01003810 const vector<Event>* events = nullptr,
3811 Event* event = nullptr);
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003812
3813/**
3814 * STL-like allocator class for managing SVM objects provided for convenience.
3815 *
3816 * Note that while this behaves like an allocator for the purposes of constructing vectors and similar objects,
3817 * care must be taken when using with smart pointers.
3818 * The allocator should not be used to construct a unique_ptr if we are using coarse-grained SVM mode because
3819 * the coarse-grained management behaviour would behave incorrectly with respect to reference counting.
3820 *
3821 * Instead the allocator embeds a Deleter which may be used with unique_ptr and is used
3822 * with the allocate_shared and allocate_ptr supplied operations.
3823 */
3824template<typename T, class SVMTrait>
3825class SVMAllocator {
3826private:
3827 Context context_;
3828
3829public:
3830 typedef T value_type;
3831 typedef value_type* pointer;
3832 typedef const value_type* const_pointer;
3833 typedef value_type& reference;
3834 typedef const value_type& const_reference;
3835 typedef std::size_t size_type;
3836 typedef std::ptrdiff_t difference_type;
3837
3838 template<typename U>
3839 struct rebind
3840 {
3841 typedef SVMAllocator<U, SVMTrait> other;
3842 };
3843
3844 template<typename U, typename V>
3845 friend class SVMAllocator;
3846
3847 SVMAllocator() :
3848 context_(Context::getDefault())
3849 {
3850 }
3851
3852 explicit SVMAllocator(cl::Context context) :
3853 context_(context)
3854 {
3855 }
3856
3857
3858 SVMAllocator(const SVMAllocator &other) :
3859 context_(other.context_)
3860 {
3861 }
3862
3863 template<typename U>
3864 SVMAllocator(const SVMAllocator<U, SVMTrait> &other) :
3865 context_(other.context_)
3866 {
3867 }
3868
3869 ~SVMAllocator()
3870 {
3871 }
3872
3873 pointer address(reference r) CL_HPP_NOEXCEPT_
3874 {
3875 return std::addressof(r);
3876 }
3877
3878 const_pointer address(const_reference r) CL_HPP_NOEXCEPT_
3879 {
3880 return std::addressof(r);
3881 }
3882
3883 /**
3884 * Allocate an SVM pointer.
3885 *
3886 * If the allocator is coarse-grained, this will take ownership to allow
3887 * containers to correctly construct data in place.
3888 */
3889 pointer allocate(
3890 size_type size,
3891 typename cl::SVMAllocator<void, SVMTrait>::const_pointer = 0)
3892 {
3893 // Allocate memory with default alignment matching the size of the type
3894 void* voidPointer =
3895 clSVMAlloc(
3896 context_(),
3897 SVMTrait::getSVMMemFlags(),
3898 size*sizeof(T),
Anthony Barbier8b2fdc92018-08-09 11:42:38 +01003899 0);
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003900 pointer retValue = reinterpret_cast<pointer>(
3901 voidPointer);
3902#if defined(CL_HPP_ENABLE_EXCEPTIONS)
3903 if (!retValue) {
3904 std::bad_alloc excep;
3905 throw excep;
3906 }
3907#endif // #if defined(CL_HPP_ENABLE_EXCEPTIONS)
3908
3909 // If allocation was coarse-grained then map it
3910 if (!(SVMTrait::getSVMMemFlags() & CL_MEM_SVM_FINE_GRAIN_BUFFER)) {
3911 cl_int err = enqueueMapSVM(retValue, CL_TRUE, CL_MAP_READ | CL_MAP_WRITE, size*sizeof(T));
3912 if (err != CL_SUCCESS) {
3913 std::bad_alloc excep;
3914 throw excep;
3915 }
3916 }
3917
3918 // If exceptions disabled, return null pointer from allocator
3919 return retValue;
3920 }
3921
3922 void deallocate(pointer p, size_type)
3923 {
3924 clSVMFree(context_(), p);
3925 }
3926
3927 /**
3928 * Return the maximum possible allocation size.
3929 * This is the minimum of the maximum sizes of all devices in the context.
3930 */
3931 size_type max_size() const CL_HPP_NOEXCEPT_
3932 {
3933 size_type maxSize = std::numeric_limits<size_type>::max() / sizeof(T);
3934
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00003935 for (const Device &d : context_.getInfo<CL_CONTEXT_DEVICES>()) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003936 maxSize = std::min(
3937 maxSize,
3938 static_cast<size_type>(d.getInfo<CL_DEVICE_MAX_MEM_ALLOC_SIZE>()));
3939 }
3940
3941 return maxSize;
3942 }
3943
3944 template< class U, class... Args >
3945 void construct(U* p, Args&&... args)
3946 {
3947 new(p)T(args...);
3948 }
3949
3950 template< class U >
3951 void destroy(U* p)
3952 {
3953 p->~U();
3954 }
3955
3956 /**
3957 * Returns true if the contexts match.
3958 */
3959 inline bool operator==(SVMAllocator const& rhs)
3960 {
3961 return (context_==rhs.context_);
3962 }
3963
3964 inline bool operator!=(SVMAllocator const& a)
3965 {
3966 return !operator==(a);
3967 }
3968}; // class SVMAllocator return cl::pointer<T>(tmp, detail::Deleter<T, Alloc>{alloc, copies});
3969
3970
3971template<class SVMTrait>
3972class SVMAllocator<void, SVMTrait> {
3973public:
3974 typedef void value_type;
3975 typedef value_type* pointer;
3976 typedef const value_type* const_pointer;
3977
3978 template<typename U>
3979 struct rebind
3980 {
3981 typedef SVMAllocator<U, SVMTrait> other;
3982 };
3983
3984 template<typename U, typename V>
3985 friend class SVMAllocator;
3986};
3987
3988#if !defined(CL_HPP_NO_STD_UNIQUE_PTR)
3989namespace detail
3990{
3991 template<class Alloc>
3992 class Deleter {
3993 private:
3994 Alloc alloc_;
3995 size_type copies_;
3996
3997 public:
3998 typedef typename std::allocator_traits<Alloc>::pointer pointer;
3999
4000 Deleter(const Alloc &alloc, size_type copies) : alloc_{ alloc }, copies_{ copies }
4001 {
4002 }
4003
4004 void operator()(pointer ptr) const {
4005 Alloc tmpAlloc{ alloc_ };
4006 std::allocator_traits<Alloc>::destroy(tmpAlloc, std::addressof(*ptr));
4007 std::allocator_traits<Alloc>::deallocate(tmpAlloc, ptr, copies_);
4008 }
4009 };
4010} // namespace detail
4011
4012/**
4013 * Allocation operation compatible with std::allocate_ptr.
4014 * Creates a unique_ptr<T> by default.
4015 * This requirement is to ensure that the control block is not
4016 * allocated in memory inaccessible to the host.
4017 */
4018template <class T, class Alloc, class... Args>
4019cl::pointer<T, detail::Deleter<Alloc>> allocate_pointer(const Alloc &alloc_, Args&&... args)
4020{
4021 Alloc alloc(alloc_);
Anthony Barbier8b2fdc92018-08-09 11:42:38 +01004022 static const size_type copies = 1;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004023
4024 // Ensure that creation of the management block and the
4025 // object are dealt with separately such that we only provide a deleter
4026
4027 T* tmp = std::allocator_traits<Alloc>::allocate(alloc, copies);
4028 if (!tmp) {
4029 std::bad_alloc excep;
4030 throw excep;
4031 }
4032 try {
4033 std::allocator_traits<Alloc>::construct(
4034 alloc,
4035 std::addressof(*tmp),
4036 std::forward<Args>(args)...);
4037
4038 return cl::pointer<T, detail::Deleter<Alloc>>(tmp, detail::Deleter<Alloc>{alloc, copies});
4039 }
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01004040 catch (std::bad_alloc&)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004041 {
4042 std::allocator_traits<Alloc>::deallocate(alloc, tmp, copies);
4043 throw;
4044 }
4045}
4046
4047template< class T, class SVMTrait, class... Args >
4048cl::pointer<T, detail::Deleter<SVMAllocator<T, SVMTrait>>> allocate_svm(Args... args)
4049{
4050 SVMAllocator<T, SVMTrait> alloc;
4051 return cl::allocate_pointer<T>(alloc, args...);
4052}
4053
4054template< class T, class SVMTrait, class... Args >
4055cl::pointer<T, detail::Deleter<SVMAllocator<T, SVMTrait>>> allocate_svm(const cl::Context &c, Args... args)
4056{
4057 SVMAllocator<T, SVMTrait> alloc(c);
4058 return cl::allocate_pointer<T>(alloc, args...);
4059}
4060#endif // #if !defined(CL_HPP_NO_STD_UNIQUE_PTR)
4061
4062/*! \brief Vector alias to simplify contruction of coarse-grained SVM containers.
4063 *
4064 */
4065template < class T >
4066using coarse_svm_vector = vector<T, cl::SVMAllocator<int, cl::SVMTraitCoarse<>>>;
4067
4068/*! \brief Vector alias to simplify contruction of fine-grained SVM containers.
4069*
4070*/
4071template < class T >
4072using fine_svm_vector = vector<T, cl::SVMAllocator<int, cl::SVMTraitFine<>>>;
4073
4074/*! \brief Vector alias to simplify contruction of fine-grained SVM containers that support platform atomics.
4075*
4076*/
4077template < class T >
4078using atomic_svm_vector = vector<T, cl::SVMAllocator<int, cl::SVMTraitAtomic<>>>;
4079
4080#endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 200
4081
4082
4083/*! \brief Class interface for Buffer Memory Objects.
4084 *
4085 * See Memory for details about copy semantics, etc.
4086 *
4087 * \see Memory
4088 */
4089class Buffer : public Memory
4090{
4091public:
4092
4093 /*! \brief Constructs a Buffer in a specified context.
4094 *
4095 * Wraps clCreateBuffer().
4096 *
4097 * \param host_ptr Storage to be used if the CL_MEM_USE_HOST_PTR flag was
4098 * specified. Note alignment & exclusivity requirements.
4099 */
4100 Buffer(
4101 const Context& context,
4102 cl_mem_flags flags,
4103 size_type size,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01004104 void* host_ptr = nullptr,
4105 cl_int* err = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004106 {
4107 cl_int error;
4108 object_ = ::clCreateBuffer(context(), flags, size, host_ptr, &error);
4109
4110 detail::errHandler(error, __CREATE_BUFFER_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01004111 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004112 *err = error;
4113 }
4114 }
4115
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01004116#if CL_HPP_TARGET_OPENCL_VERSION >= 300
4117 /*! \brief Constructs a Buffer in a specified context and with specified properties.
4118 *
4119 * Wraps clCreateBufferWithProperties().
4120 *
4121 * \param properties Optional list of properties for the buffer object and
4122 * their corresponding values. The non-empty list must
4123 * end with 0.
4124 * \param host_ptr Storage to be used if the CL_MEM_USE_HOST_PTR flag was
4125 * specified. Note alignment & exclusivity requirements.
4126 */
4127 Buffer(
4128 const Context& context,
4129 const vector<cl_mem_properties>& properties,
4130 cl_mem_flags flags,
4131 size_type size,
4132 void* host_ptr = nullptr,
4133 cl_int* err = nullptr)
4134 {
4135 cl_int error;
4136
4137 if (properties.empty()) {
4138 object_ = ::clCreateBufferWithProperties(context(), nullptr, flags,
4139 size, host_ptr, &error);
4140 }
4141 else {
4142 object_ = ::clCreateBufferWithProperties(
4143 context(), properties.data(), flags, size, host_ptr, &error);
4144 }
4145
4146 detail::errHandler(error, __CREATE_BUFFER_ERR);
4147 if (err != nullptr) {
4148 *err = error;
4149 }
4150 }
4151#endif
4152
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004153 /*! \brief Constructs a Buffer in the default context.
4154 *
4155 * Wraps clCreateBuffer().
4156 *
4157 * \param host_ptr Storage to be used if the CL_MEM_USE_HOST_PTR flag was
4158 * specified. Note alignment & exclusivity requirements.
4159 *
4160 * \see Context::getDefault()
4161 */
4162 Buffer(
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01004163 cl_mem_flags flags,
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004164 size_type size,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01004165 void* host_ptr = nullptr,
4166 cl_int* err = nullptr) : Buffer(Context::getDefault(err), flags, size, host_ptr, err) { }
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004167
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01004168#if CL_HPP_TARGET_OPENCL_VERSION >= 300
4169 /*! \brief Constructs a Buffer in the default context and with specified properties.
4170 *
4171 * Wraps clCreateBufferWithProperties().
4172 *
4173 * \param properties Optional list of properties for the buffer object and
4174 * their corresponding values. The non-empty list must
4175 * end with 0.
4176 * \param host_ptr Storage to be used if the CL_MEM_USE_HOST_PTR flag was
4177 * specified. Note alignment & exclusivity requirements.
4178 *
4179 * \see Context::getDefault()
4180 */
4181 Buffer(
4182 const vector<cl_mem_properties>& properties,
4183 cl_mem_flags flags,
4184 size_type size,
4185 void* host_ptr = nullptr,
4186 cl_int* err = nullptr) : Buffer(Context::getDefault(err), properties, flags, size, host_ptr, err) { }
4187#endif
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004188
4189 /*!
4190 * \brief Construct a Buffer from a host container via iterators.
4191 * IteratorType must be random access.
4192 * If useHostPtr is specified iterators must represent contiguous data.
4193 */
4194 template< typename IteratorType >
4195 Buffer(
4196 IteratorType startIterator,
4197 IteratorType endIterator,
4198 bool readOnly,
4199 bool useHostPtr = false,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01004200 cl_int* err = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004201 {
4202 typedef typename std::iterator_traits<IteratorType>::value_type DataType;
4203 cl_int error;
4204
4205 cl_mem_flags flags = 0;
4206 if( readOnly ) {
4207 flags |= CL_MEM_READ_ONLY;
4208 }
4209 else {
4210 flags |= CL_MEM_READ_WRITE;
4211 }
4212 if( useHostPtr ) {
4213 flags |= CL_MEM_USE_HOST_PTR;
4214 }
4215
4216 size_type size = sizeof(DataType)*(endIterator - startIterator);
4217
4218 Context context = Context::getDefault(err);
4219
4220 if( useHostPtr ) {
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01004221 object_ = ::clCreateBuffer(context(), flags, size, const_cast<DataType*>(&*startIterator), &error);
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004222 } else {
4223 object_ = ::clCreateBuffer(context(), flags, size, 0, &error);
4224 }
4225
4226 detail::errHandler(error, __CREATE_BUFFER_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01004227 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004228 *err = error;
4229 }
4230
4231 if( !useHostPtr ) {
4232 error = cl::copy(startIterator, endIterator, *this);
4233 detail::errHandler(error, __CREATE_BUFFER_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01004234 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004235 *err = error;
4236 }
4237 }
4238 }
4239
4240 /*!
4241 * \brief Construct a Buffer from a host container via iterators using a specified context.
4242 * IteratorType must be random access.
4243 * If useHostPtr is specified iterators must represent contiguous data.
4244 */
4245 template< typename IteratorType >
4246 Buffer(const Context &context, IteratorType startIterator, IteratorType endIterator,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01004247 bool readOnly, bool useHostPtr = false, cl_int* err = nullptr);
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004248
4249 /*!
4250 * \brief Construct a Buffer from a host container via iterators using a specified queue.
4251 * If useHostPtr is specified iterators must be random access.
4252 */
4253 template< typename IteratorType >
4254 Buffer(const CommandQueue &queue, IteratorType startIterator, IteratorType endIterator,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01004255 bool readOnly, bool useHostPtr = false, cl_int* err = nullptr);
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004256
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01004257 //! \brief Default constructor - initializes to nullptr.
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004258 Buffer() : Memory() { }
4259
4260 /*! \brief Constructor from cl_mem - takes ownership.
4261 *
4262 * \param retainObject will cause the constructor to retain its cl object.
4263 * Defaults to false to maintain compatibility with earlier versions.
4264 *
4265 * See Memory for further details.
4266 */
4267 explicit Buffer(const cl_mem& buffer, bool retainObject = false) :
4268 Memory(buffer, retainObject) { }
4269
4270 /*! \brief Assignment from cl_mem - performs shallow copy.
4271 *
4272 * See Memory for further details.
4273 */
4274 Buffer& operator = (const cl_mem& rhs)
4275 {
4276 Memory::operator=(rhs);
4277 return *this;
4278 }
4279
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004280
4281#if CL_HPP_TARGET_OPENCL_VERSION >= 110
4282 /*! \brief Creates a new buffer object from this.
4283 *
4284 * Wraps clCreateSubBuffer().
4285 */
4286 Buffer createSubBuffer(
4287 cl_mem_flags flags,
4288 cl_buffer_create_type buffer_create_type,
4289 const void * buffer_create_info,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01004290 cl_int * err = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004291 {
4292 Buffer result;
4293 cl_int error;
4294 result.object_ = ::clCreateSubBuffer(
4295 object_,
4296 flags,
4297 buffer_create_type,
4298 buffer_create_info,
4299 &error);
4300
4301 detail::errHandler(error, __CREATE_SUBBUFFER_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01004302 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004303 *err = error;
4304 }
4305
4306 return result;
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00004307 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004308#endif // CL_HPP_TARGET_OPENCL_VERSION >= 110
4309};
4310
4311#if defined (CL_HPP_USE_DX_INTEROP)
4312/*! \brief Class interface for creating OpenCL buffers from ID3D10Buffer's.
4313 *
4314 * This is provided to facilitate interoperability with Direct3D.
4315 *
4316 * See Memory for details about copy semantics, etc.
4317 *
4318 * \see Memory
4319 */
4320class BufferD3D10 : public Buffer
4321{
4322public:
4323
4324
4325 /*! \brief Constructs a BufferD3D10, in a specified context, from a
4326 * given ID3D10Buffer.
4327 *
4328 * Wraps clCreateFromD3D10BufferKHR().
4329 */
4330 BufferD3D10(
4331 const Context& context,
4332 cl_mem_flags flags,
4333 ID3D10Buffer* bufobj,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01004334 cl_int * err = nullptr) : pfn_clCreateFromD3D10BufferKHR(nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004335 {
4336 typedef CL_API_ENTRY cl_mem (CL_API_CALL *PFN_clCreateFromD3D10BufferKHR)(
4337 cl_context context, cl_mem_flags flags, ID3D10Buffer* buffer,
4338 cl_int* errcode_ret);
4339 PFN_clCreateFromD3D10BufferKHR pfn_clCreateFromD3D10BufferKHR;
4340#if CL_HPP_TARGET_OPENCL_VERSION >= 120
4341 vector<cl_context_properties> props = context.getInfo<CL_CONTEXT_PROPERTIES>();
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01004342 cl_platform platform = nullptr;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004343 for( int i = 0; i < props.size(); ++i ) {
4344 if( props[i] == CL_CONTEXT_PLATFORM ) {
4345 platform = props[i+1];
4346 }
4347 }
4348 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clCreateFromD3D10BufferKHR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01004349#endif
4350#if CL_HPP_MINIMUM_OPENCL_VERSION < 120
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004351 CL_HPP_INIT_CL_EXT_FCN_PTR_(clCreateFromD3D10BufferKHR);
4352#endif
4353
4354 cl_int error;
4355 object_ = pfn_clCreateFromD3D10BufferKHR(
4356 context(),
4357 flags,
4358 bufobj,
4359 &error);
4360
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01004361 // TODO: This should really have a D3D10 rerror code!
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004362 detail::errHandler(error, __CREATE_GL_BUFFER_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01004363 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004364 *err = error;
4365 }
4366 }
4367
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01004368 //! \brief Default constructor - initializes to nullptr.
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004369 BufferD3D10() : Buffer() { }
4370
4371 /*! \brief Constructor from cl_mem - takes ownership.
4372 *
4373 * \param retainObject will cause the constructor to retain its cl object.
4374 * Defaults to false to maintain compatibility with
4375 * earlier versions.
4376 * See Memory for further details.
4377 */
4378 explicit BufferD3D10(const cl_mem& buffer, bool retainObject = false) :
4379 Buffer(buffer, retainObject) { }
4380
4381 /*! \brief Assignment from cl_mem - performs shallow copy.
4382 *
4383 * See Memory for further details.
4384 */
4385 BufferD3D10& operator = (const cl_mem& rhs)
4386 {
4387 Buffer::operator=(rhs);
4388 return *this;
4389 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004390};
4391#endif
4392
4393/*! \brief Class interface for GL Buffer Memory Objects.
4394 *
4395 * This is provided to facilitate interoperability with OpenGL.
4396 *
4397 * See Memory for details about copy semantics, etc.
4398 *
4399 * \see Memory
4400 */
4401class BufferGL : public Buffer
4402{
4403public:
4404 /*! \brief Constructs a BufferGL in a specified context, from a given
4405 * GL buffer.
4406 *
4407 * Wraps clCreateFromGLBuffer().
4408 */
4409 BufferGL(
4410 const Context& context,
4411 cl_mem_flags flags,
4412 cl_GLuint bufobj,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01004413 cl_int * err = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004414 {
4415 cl_int error;
4416 object_ = ::clCreateFromGLBuffer(
4417 context(),
4418 flags,
4419 bufobj,
4420 &error);
4421
4422 detail::errHandler(error, __CREATE_GL_BUFFER_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01004423 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004424 *err = error;
4425 }
4426 }
4427
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01004428 //! \brief Default constructor - initializes to nullptr.
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004429 BufferGL() : Buffer() { }
4430
4431 /*! \brief Constructor from cl_mem - takes ownership.
4432 *
4433 * \param retainObject will cause the constructor to retain its cl object.
4434 * Defaults to false to maintain compatibility with
4435 * earlier versions.
4436 * See Memory for further details.
4437 */
4438 explicit BufferGL(const cl_mem& buffer, bool retainObject = false) :
4439 Buffer(buffer, retainObject) { }
4440
4441 /*! \brief Assignment from cl_mem - performs shallow copy.
4442 *
4443 * See Memory for further details.
4444 */
4445 BufferGL& operator = (const cl_mem& rhs)
4446 {
4447 Buffer::operator=(rhs);
4448 return *this;
4449 }
4450
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004451
4452 //! \brief Wrapper for clGetGLObjectInfo().
4453 cl_int getObjectInfo(
4454 cl_gl_object_type *type,
4455 cl_GLuint * gl_object_name)
4456 {
4457 return detail::errHandler(
4458 ::clGetGLObjectInfo(object_,type,gl_object_name),
4459 __GET_GL_OBJECT_INFO_ERR);
4460 }
4461};
4462
4463/*! \brief Class interface for GL Render Buffer Memory Objects.
4464 *
4465 * This is provided to facilitate interoperability with OpenGL.
4466 *
4467 * See Memory for details about copy semantics, etc.
4468 *
4469 * \see Memory
4470 */
4471class BufferRenderGL : public Buffer
4472{
4473public:
4474 /*! \brief Constructs a BufferRenderGL in a specified context, from a given
4475 * GL Renderbuffer.
4476 *
4477 * Wraps clCreateFromGLRenderbuffer().
4478 */
4479 BufferRenderGL(
4480 const Context& context,
4481 cl_mem_flags flags,
4482 cl_GLuint bufobj,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01004483 cl_int * err = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004484 {
4485 cl_int error;
4486 object_ = ::clCreateFromGLRenderbuffer(
4487 context(),
4488 flags,
4489 bufobj,
4490 &error);
4491
4492 detail::errHandler(error, __CREATE_GL_RENDER_BUFFER_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01004493 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004494 *err = error;
4495 }
4496 }
4497
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01004498 //! \brief Default constructor - initializes to nullptr.
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004499 BufferRenderGL() : Buffer() { }
4500
4501 /*! \brief Constructor from cl_mem - takes ownership.
4502 *
4503 * \param retainObject will cause the constructor to retain its cl object.
4504 * Defaults to false to maintain compatibility with
4505 * earlier versions.
4506 * See Memory for further details.
4507 */
4508 explicit BufferRenderGL(const cl_mem& buffer, bool retainObject = false) :
4509 Buffer(buffer, retainObject) { }
4510
4511 /*! \brief Assignment from cl_mem - performs shallow copy.
4512 *
4513 * See Memory for further details.
4514 */
4515 BufferRenderGL& operator = (const cl_mem& rhs)
4516 {
4517 Buffer::operator=(rhs);
4518 return *this;
4519 }
4520
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004521
4522 //! \brief Wrapper for clGetGLObjectInfo().
4523 cl_int getObjectInfo(
4524 cl_gl_object_type *type,
4525 cl_GLuint * gl_object_name)
4526 {
4527 return detail::errHandler(
4528 ::clGetGLObjectInfo(object_,type,gl_object_name),
4529 __GET_GL_OBJECT_INFO_ERR);
4530 }
4531};
4532
4533/*! \brief C++ base class for Image Memory objects.
4534 *
4535 * See Memory for details about copy semantics, etc.
4536 *
4537 * \see Memory
4538 */
4539class Image : public Memory
4540{
4541protected:
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01004542 //! \brief Default constructor - initializes to nullptr.
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004543 Image() : Memory() { }
4544
4545 /*! \brief Constructor from cl_mem - takes ownership.
4546 *
4547 * \param retainObject will cause the constructor to retain its cl object.
4548 * Defaults to false to maintain compatibility with
4549 * earlier versions.
4550 * See Memory for further details.
4551 */
4552 explicit Image(const cl_mem& image, bool retainObject = false) :
4553 Memory(image, retainObject) { }
4554
4555 /*! \brief Assignment from cl_mem - performs shallow copy.
4556 *
4557 * See Memory for further details.
4558 */
4559 Image& operator = (const cl_mem& rhs)
4560 {
4561 Memory::operator=(rhs);
4562 return *this;
4563 }
4564
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004565
4566public:
4567 //! \brief Wrapper for clGetImageInfo().
4568 template <typename T>
4569 cl_int getImageInfo(cl_image_info name, T* param) const
4570 {
4571 return detail::errHandler(
4572 detail::getInfo(&::clGetImageInfo, object_, name, param),
4573 __GET_IMAGE_INFO_ERR);
4574 }
4575
4576 //! \brief Wrapper for clGetImageInfo() that returns by value.
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00004577 template <cl_image_info name> typename
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004578 detail::param_traits<detail::cl_image_info, name>::param_type
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01004579 getImageInfo(cl_int* err = nullptr) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004580 {
4581 typename detail::param_traits<
4582 detail::cl_image_info, name>::param_type param;
4583 cl_int result = getImageInfo(name, &param);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01004584 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004585 *err = result;
4586 }
4587 return param;
4588 }
4589};
4590
4591#if CL_HPP_TARGET_OPENCL_VERSION >= 120
4592/*! \brief Class interface for 1D Image Memory objects.
4593 *
4594 * See Memory for details about copy semantics, etc.
4595 *
4596 * \see Memory
4597 */
4598class Image1D : public Image
4599{
4600public:
4601 /*! \brief Constructs a 1D Image in a specified context.
4602 *
4603 * Wraps clCreateImage().
4604 */
4605 Image1D(
4606 const Context& context,
4607 cl_mem_flags flags,
4608 ImageFormat format,
4609 size_type width,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01004610 void* host_ptr = nullptr,
4611 cl_int* err = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004612 {
4613 cl_int error;
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00004614
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01004615 cl_image_desc desc = {};
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00004616 desc.image_type = CL_MEM_OBJECT_IMAGE1D;
4617 desc.image_width = width;
4618
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004619 object_ = ::clCreateImage(
4620 context(),
4621 flags,
4622 &format,
4623 &desc,
4624 host_ptr,
4625 &error);
4626
4627 detail::errHandler(error, __CREATE_IMAGE_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01004628 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004629 *err = error;
4630 }
4631 }
4632
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01004633 //! \brief Default constructor - initializes to nullptr.
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004634 Image1D() { }
4635
4636 /*! \brief Constructor from cl_mem - takes ownership.
4637 *
4638 * \param retainObject will cause the constructor to retain its cl object.
4639 * Defaults to false to maintain compatibility with
4640 * earlier versions.
4641 * See Memory for further details.
4642 */
4643 explicit Image1D(const cl_mem& image1D, bool retainObject = false) :
4644 Image(image1D, retainObject) { }
4645
4646 /*! \brief Assignment from cl_mem - performs shallow copy.
4647 *
4648 * See Memory for further details.
4649 */
4650 Image1D& operator = (const cl_mem& rhs)
4651 {
4652 Image::operator=(rhs);
4653 return *this;
4654 }
4655
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004656
4657};
4658
4659/*! \class Image1DBuffer
4660 * \brief Image interface for 1D buffer images.
4661 */
4662class Image1DBuffer : public Image
4663{
4664public:
4665 Image1DBuffer(
4666 const Context& context,
4667 cl_mem_flags flags,
4668 ImageFormat format,
4669 size_type width,
4670 const Buffer &buffer,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01004671 cl_int* err = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004672 {
4673 cl_int error;
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00004674
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01004675 cl_image_desc desc = {};
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00004676 desc.image_type = CL_MEM_OBJECT_IMAGE1D_BUFFER;
4677 desc.image_width = width;
4678 desc.buffer = buffer();
4679
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004680 object_ = ::clCreateImage(
4681 context(),
4682 flags,
4683 &format,
4684 &desc,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01004685 nullptr,
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004686 &error);
4687
4688 detail::errHandler(error, __CREATE_IMAGE_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01004689 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004690 *err = error;
4691 }
4692 }
4693
4694 Image1DBuffer() { }
4695
4696 /*! \brief Constructor from cl_mem - takes ownership.
4697 *
4698 * \param retainObject will cause the constructor to retain its cl object.
4699 * Defaults to false to maintain compatibility with
4700 * earlier versions.
4701 * See Memory for further details.
4702 */
4703 explicit Image1DBuffer(const cl_mem& image1D, bool retainObject = false) :
4704 Image(image1D, retainObject) { }
4705
4706 Image1DBuffer& operator = (const cl_mem& rhs)
4707 {
4708 Image::operator=(rhs);
4709 return *this;
4710 }
4711
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004712
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004713
4714};
4715
4716/*! \class Image1DArray
4717 * \brief Image interface for arrays of 1D images.
4718 */
4719class Image1DArray : public Image
4720{
4721public:
4722 Image1DArray(
4723 const Context& context,
4724 cl_mem_flags flags,
4725 ImageFormat format,
4726 size_type arraySize,
4727 size_type width,
4728 size_type rowPitch,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01004729 void* host_ptr = nullptr,
4730 cl_int* err = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004731 {
4732 cl_int error;
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00004733
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01004734 cl_image_desc desc = {};
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00004735 desc.image_type = CL_MEM_OBJECT_IMAGE1D_ARRAY;
4736 desc.image_width = width;
4737 desc.image_array_size = arraySize;
4738 desc.image_row_pitch = rowPitch;
4739
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004740 object_ = ::clCreateImage(
4741 context(),
4742 flags,
4743 &format,
4744 &desc,
4745 host_ptr,
4746 &error);
4747
4748 detail::errHandler(error, __CREATE_IMAGE_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01004749 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004750 *err = error;
4751 }
4752 }
4753
4754 Image1DArray() { }
4755
4756 /*! \brief Constructor from cl_mem - takes ownership.
4757 *
4758 * \param retainObject will cause the constructor to retain its cl object.
4759 * Defaults to false to maintain compatibility with
4760 * earlier versions.
4761 * See Memory for further details.
4762 */
4763 explicit Image1DArray(const cl_mem& imageArray, bool retainObject = false) :
4764 Image(imageArray, retainObject) { }
4765
4766
4767 Image1DArray& operator = (const cl_mem& rhs)
4768 {
4769 Image::operator=(rhs);
4770 return *this;
4771 }
4772
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004773
4774};
4775#endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 120
4776
4777
4778/*! \brief Class interface for 2D Image Memory objects.
4779 *
4780 * See Memory for details about copy semantics, etc.
4781 *
4782 * \see Memory
4783 */
4784class Image2D : public Image
4785{
4786public:
4787 /*! \brief Constructs a 2D Image in a specified context.
4788 *
4789 * Wraps clCreateImage().
4790 */
4791 Image2D(
4792 const Context& context,
4793 cl_mem_flags flags,
4794 ImageFormat format,
4795 size_type width,
4796 size_type height,
4797 size_type row_pitch = 0,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01004798 void* host_ptr = nullptr,
4799 cl_int* err = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004800 {
4801 cl_int error;
4802 bool useCreateImage;
4803
4804#if CL_HPP_TARGET_OPENCL_VERSION >= 120 && CL_HPP_MINIMUM_OPENCL_VERSION < 120
4805 // Run-time decision based on the actual platform
4806 {
4807 cl_uint version = detail::getContextPlatformVersion(context());
4808 useCreateImage = (version >= 0x10002); // OpenCL 1.2 or above
4809 }
4810#elif CL_HPP_TARGET_OPENCL_VERSION >= 120
4811 useCreateImage = true;
4812#else
4813 useCreateImage = false;
4814#endif
4815
4816#if CL_HPP_TARGET_OPENCL_VERSION >= 120
4817 if (useCreateImage)
4818 {
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01004819 cl_image_desc desc = {};
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00004820 desc.image_type = CL_MEM_OBJECT_IMAGE2D;
4821 desc.image_width = width;
4822 desc.image_height = height;
4823 desc.image_row_pitch = row_pitch;
4824
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004825 object_ = ::clCreateImage(
4826 context(),
4827 flags,
4828 &format,
4829 &desc,
4830 host_ptr,
4831 &error);
4832
4833 detail::errHandler(error, __CREATE_IMAGE_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01004834 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004835 *err = error;
4836 }
4837 }
4838#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
4839#if CL_HPP_MINIMUM_OPENCL_VERSION < 120
4840 if (!useCreateImage)
4841 {
4842 object_ = ::clCreateImage2D(
4843 context(), flags,&format, width, height, row_pitch, host_ptr, &error);
4844
4845 detail::errHandler(error, __CREATE_IMAGE2D_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01004846 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004847 *err = error;
4848 }
4849 }
4850#endif // CL_HPP_MINIMUM_OPENCL_VERSION < 120
4851 }
4852
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01004853#if CL_HPP_TARGET_OPENCL_VERSION >= 120
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004854 /*! \brief Constructs a 2D Image from a buffer.
4855 * \note This will share storage with the underlying buffer.
4856 *
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01004857 * Requires OpenCL 2.0 or newer or OpenCL 1.2 and the
4858 * cl_khr_image2d_from_buffer extension.
4859 *
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004860 * Wraps clCreateImage().
4861 */
4862 Image2D(
4863 const Context& context,
4864 ImageFormat format,
4865 const Buffer &sourceBuffer,
4866 size_type width,
4867 size_type height,
4868 size_type row_pitch = 0,
4869 cl_int* err = nullptr)
4870 {
4871 cl_int error;
4872
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01004873 cl_image_desc desc = {};
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00004874 desc.image_type = CL_MEM_OBJECT_IMAGE2D;
4875 desc.image_width = width;
4876 desc.image_height = height;
4877 desc.image_row_pitch = row_pitch;
4878 desc.buffer = sourceBuffer();
4879
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004880 object_ = ::clCreateImage(
4881 context(),
4882 0, // flags inherited from buffer
4883 &format,
4884 &desc,
4885 nullptr,
4886 &error);
4887
4888 detail::errHandler(error, __CREATE_IMAGE_ERR);
4889 if (err != nullptr) {
4890 *err = error;
4891 }
4892 }
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01004893#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004894
4895#if CL_HPP_TARGET_OPENCL_VERSION >= 200
4896 /*! \brief Constructs a 2D Image from an image.
4897 * \note This will share storage with the underlying image but may
4898 * reinterpret the channel order and type.
4899 *
4900 * The image will be created matching with a descriptor matching the source.
4901 *
4902 * \param order is the channel order to reinterpret the image data as.
4903 * The channel order may differ as described in the OpenCL
4904 * 2.0 API specification.
4905 *
4906 * Wraps clCreateImage().
4907 */
4908 Image2D(
4909 const Context& context,
4910 cl_channel_order order,
4911 const Image &sourceImage,
4912 cl_int* err = nullptr)
4913 {
4914 cl_int error;
4915
4916 // Descriptor fields have to match source image
4917 size_type sourceWidth =
4918 sourceImage.getImageInfo<CL_IMAGE_WIDTH>();
4919 size_type sourceHeight =
4920 sourceImage.getImageInfo<CL_IMAGE_HEIGHT>();
4921 size_type sourceRowPitch =
4922 sourceImage.getImageInfo<CL_IMAGE_ROW_PITCH>();
4923 cl_uint sourceNumMIPLevels =
4924 sourceImage.getImageInfo<CL_IMAGE_NUM_MIP_LEVELS>();
4925 cl_uint sourceNumSamples =
4926 sourceImage.getImageInfo<CL_IMAGE_NUM_SAMPLES>();
4927 cl_image_format sourceFormat =
4928 sourceImage.getImageInfo<CL_IMAGE_FORMAT>();
4929
4930 // Update only the channel order.
4931 // Channel format inherited from source.
4932 sourceFormat.image_channel_order = order;
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00004933
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01004934 cl_image_desc desc = {};
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00004935 desc.image_type = CL_MEM_OBJECT_IMAGE2D;
4936 desc.image_width = sourceWidth;
4937 desc.image_height = sourceHeight;
4938 desc.image_row_pitch = sourceRowPitch;
4939 desc.num_mip_levels = sourceNumMIPLevels;
4940 desc.num_samples = sourceNumSamples;
4941 desc.buffer = sourceImage();
4942
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004943 object_ = ::clCreateImage(
4944 context(),
4945 0, // flags should be inherited from mem_object
4946 &sourceFormat,
4947 &desc,
4948 nullptr,
4949 &error);
4950
4951 detail::errHandler(error, __CREATE_IMAGE_ERR);
4952 if (err != nullptr) {
4953 *err = error;
4954 }
4955 }
4956#endif //#if CL_HPP_TARGET_OPENCL_VERSION >= 200
4957
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01004958 //! \brief Default constructor - initializes to nullptr.
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004959 Image2D() { }
4960
4961 /*! \brief Constructor from cl_mem - takes ownership.
4962 *
4963 * \param retainObject will cause the constructor to retain its cl object.
4964 * Defaults to false to maintain compatibility with
4965 * earlier versions.
4966 * See Memory for further details.
4967 */
4968 explicit Image2D(const cl_mem& image2D, bool retainObject = false) :
4969 Image(image2D, retainObject) { }
4970
4971 /*! \brief Assignment from cl_mem - performs shallow copy.
4972 *
4973 * See Memory for further details.
4974 */
4975 Image2D& operator = (const cl_mem& rhs)
4976 {
4977 Image::operator=(rhs);
4978 return *this;
4979 }
4980
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004981
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004982
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004983
4984};
4985
4986
4987#if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
4988/*! \brief Class interface for GL 2D Image Memory objects.
4989 *
4990 * This is provided to facilitate interoperability with OpenGL.
4991 *
4992 * See Memory for details about copy semantics, etc.
4993 *
4994 * \see Memory
4995 * \note Deprecated for OpenCL 1.2. Please use ImageGL instead.
4996 */
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00004997class CL_API_PREFIX__VERSION_1_1_DEPRECATED Image2DGL : public Image2D
Anthony Barbier6ff3b192017-09-04 18:44:23 +01004998{
4999public:
5000 /*! \brief Constructs an Image2DGL in a specified context, from a given
5001 * GL Texture.
5002 *
5003 * Wraps clCreateFromGLTexture2D().
5004 */
5005 Image2DGL(
5006 const Context& context,
5007 cl_mem_flags flags,
5008 cl_GLenum target,
5009 cl_GLint miplevel,
5010 cl_GLuint texobj,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01005011 cl_int * err = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005012 {
5013 cl_int error;
5014 object_ = ::clCreateFromGLTexture2D(
5015 context(),
5016 flags,
5017 target,
5018 miplevel,
5019 texobj,
5020 &error);
5021
5022 detail::errHandler(error, __CREATE_GL_TEXTURE_2D_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01005023 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005024 *err = error;
5025 }
5026
5027 }
5028
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01005029 //! \brief Default constructor - initializes to nullptr.
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005030 Image2DGL() : Image2D() { }
5031
5032 /*! \brief Constructor from cl_mem - takes ownership.
5033 *
5034 * \param retainObject will cause the constructor to retain its cl object.
5035 * Defaults to false to maintain compatibility with
5036 * earlier versions.
5037 * See Memory for further details.
5038 */
5039 explicit Image2DGL(const cl_mem& image, bool retainObject = false) :
5040 Image2D(image, retainObject) { }
5041
5042 /*! \brief Assignment from cl_mem - performs shallow copy.
5043 *c
5044 * See Memory for further details.
5045 */
5046 Image2DGL& operator = (const cl_mem& rhs)
5047 {
5048 Image2D::operator=(rhs);
5049 return *this;
5050 }
5051
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005052
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005053
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00005054} CL_API_SUFFIX__VERSION_1_1_DEPRECATED;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005055#endif // CL_USE_DEPRECATED_OPENCL_1_1_APIS
5056
5057#if CL_HPP_TARGET_OPENCL_VERSION >= 120
5058/*! \class Image2DArray
5059 * \brief Image interface for arrays of 2D images.
5060 */
5061class Image2DArray : public Image
5062{
5063public:
5064 Image2DArray(
5065 const Context& context,
5066 cl_mem_flags flags,
5067 ImageFormat format,
5068 size_type arraySize,
5069 size_type width,
5070 size_type height,
5071 size_type rowPitch,
5072 size_type slicePitch,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01005073 void* host_ptr = nullptr,
5074 cl_int* err = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005075 {
5076 cl_int error;
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00005077
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01005078 cl_image_desc desc = {};
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00005079 desc.image_type = CL_MEM_OBJECT_IMAGE2D_ARRAY;
5080 desc.image_width = width;
5081 desc.image_height = height;
5082 desc.image_array_size = arraySize;
5083 desc.image_row_pitch = rowPitch;
5084 desc.image_slice_pitch = slicePitch;
5085
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005086 object_ = ::clCreateImage(
5087 context(),
5088 flags,
5089 &format,
5090 &desc,
5091 host_ptr,
5092 &error);
5093
5094 detail::errHandler(error, __CREATE_IMAGE_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01005095 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005096 *err = error;
5097 }
5098 }
5099
5100 Image2DArray() { }
5101
5102 /*! \brief Constructor from cl_mem - takes ownership.
5103 *
5104 * \param retainObject will cause the constructor to retain its cl object.
5105 * Defaults to false to maintain compatibility with
5106 * earlier versions.
5107 * See Memory for further details.
5108 */
5109 explicit Image2DArray(const cl_mem& imageArray, bool retainObject = false) : Image(imageArray, retainObject) { }
5110
5111 Image2DArray& operator = (const cl_mem& rhs)
5112 {
5113 Image::operator=(rhs);
5114 return *this;
5115 }
5116
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005117};
5118#endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 120
5119
5120/*! \brief Class interface for 3D Image Memory objects.
5121 *
5122 * See Memory for details about copy semantics, etc.
5123 *
5124 * \see Memory
5125 */
5126class Image3D : public Image
5127{
5128public:
5129 /*! \brief Constructs a 3D Image in a specified context.
5130 *
5131 * Wraps clCreateImage().
5132 */
5133 Image3D(
5134 const Context& context,
5135 cl_mem_flags flags,
5136 ImageFormat format,
5137 size_type width,
5138 size_type height,
5139 size_type depth,
5140 size_type row_pitch = 0,
5141 size_type slice_pitch = 0,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01005142 void* host_ptr = nullptr,
5143 cl_int* err = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005144 {
5145 cl_int error;
5146 bool useCreateImage;
5147
5148#if CL_HPP_TARGET_OPENCL_VERSION >= 120 && CL_HPP_MINIMUM_OPENCL_VERSION < 120
5149 // Run-time decision based on the actual platform
5150 {
5151 cl_uint version = detail::getContextPlatformVersion(context());
5152 useCreateImage = (version >= 0x10002); // OpenCL 1.2 or above
5153 }
5154#elif CL_HPP_TARGET_OPENCL_VERSION >= 120
5155 useCreateImage = true;
5156#else
5157 useCreateImage = false;
5158#endif
5159
5160#if CL_HPP_TARGET_OPENCL_VERSION >= 120
5161 if (useCreateImage)
5162 {
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01005163 cl_image_desc desc = {};
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00005164 desc.image_type = CL_MEM_OBJECT_IMAGE3D;
5165 desc.image_width = width;
5166 desc.image_height = height;
5167 desc.image_depth = depth;
5168 desc.image_row_pitch = row_pitch;
5169 desc.image_slice_pitch = slice_pitch;
5170
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005171 object_ = ::clCreateImage(
5172 context(),
5173 flags,
5174 &format,
5175 &desc,
5176 host_ptr,
5177 &error);
5178
5179 detail::errHandler(error, __CREATE_IMAGE_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01005180 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005181 *err = error;
5182 }
5183 }
5184#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
5185#if CL_HPP_MINIMUM_OPENCL_VERSION < 120
5186 if (!useCreateImage)
5187 {
5188 object_ = ::clCreateImage3D(
5189 context(), flags, &format, width, height, depth, row_pitch,
5190 slice_pitch, host_ptr, &error);
5191
5192 detail::errHandler(error, __CREATE_IMAGE3D_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01005193 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005194 *err = error;
5195 }
5196 }
5197#endif // CL_HPP_MINIMUM_OPENCL_VERSION < 120
5198 }
5199
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01005200 //! \brief Default constructor - initializes to nullptr.
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005201 Image3D() : Image() { }
5202
5203 /*! \brief Constructor from cl_mem - takes ownership.
5204 *
5205 * \param retainObject will cause the constructor to retain its cl object.
5206 * Defaults to false to maintain compatibility with
5207 * earlier versions.
5208 * See Memory for further details.
5209 */
5210 explicit Image3D(const cl_mem& image3D, bool retainObject = false) :
5211 Image(image3D, retainObject) { }
5212
5213 /*! \brief Assignment from cl_mem - performs shallow copy.
5214 *
5215 * See Memory for further details.
5216 */
5217 Image3D& operator = (const cl_mem& rhs)
5218 {
5219 Image::operator=(rhs);
5220 return *this;
5221 }
5222
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005223};
5224
5225#if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
5226/*! \brief Class interface for GL 3D Image Memory objects.
5227 *
5228 * This is provided to facilitate interoperability with OpenGL.
5229 *
5230 * See Memory for details about copy semantics, etc.
5231 *
5232 * \see Memory
5233 */
5234class Image3DGL : public Image3D
5235{
5236public:
5237 /*! \brief Constructs an Image3DGL in a specified context, from a given
5238 * GL Texture.
5239 *
5240 * Wraps clCreateFromGLTexture3D().
5241 */
5242 Image3DGL(
5243 const Context& context,
5244 cl_mem_flags flags,
5245 cl_GLenum target,
5246 cl_GLint miplevel,
5247 cl_GLuint texobj,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01005248 cl_int * err = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005249 {
5250 cl_int error;
5251 object_ = ::clCreateFromGLTexture3D(
5252 context(),
5253 flags,
5254 target,
5255 miplevel,
5256 texobj,
5257 &error);
5258
5259 detail::errHandler(error, __CREATE_GL_TEXTURE_3D_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01005260 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005261 *err = error;
5262 }
5263 }
5264
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01005265 //! \brief Default constructor - initializes to nullptr.
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005266 Image3DGL() : Image3D() { }
5267
5268 /*! \brief Constructor from cl_mem - takes ownership.
5269 *
5270 * \param retainObject will cause the constructor to retain its cl object.
5271 * Defaults to false to maintain compatibility with
5272 * earlier versions.
5273 * See Memory for further details.
5274 */
5275 explicit Image3DGL(const cl_mem& image, bool retainObject = false) :
5276 Image3D(image, retainObject) { }
5277
5278 /*! \brief Assignment from cl_mem - performs shallow copy.
5279 *
5280 * See Memory for further details.
5281 */
5282 Image3DGL& operator = (const cl_mem& rhs)
5283 {
5284 Image3D::operator=(rhs);
5285 return *this;
5286 }
5287
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005288};
5289#endif // CL_USE_DEPRECATED_OPENCL_1_1_APIS
5290
5291#if CL_HPP_TARGET_OPENCL_VERSION >= 120
5292/*! \class ImageGL
5293 * \brief general image interface for GL interop.
5294 * We abstract the 2D and 3D GL images into a single instance here
5295 * that wraps all GL sourced images on the grounds that setup information
5296 * was performed by OpenCL anyway.
5297 */
5298class ImageGL : public Image
5299{
5300public:
5301 ImageGL(
5302 const Context& context,
5303 cl_mem_flags flags,
5304 cl_GLenum target,
5305 cl_GLint miplevel,
5306 cl_GLuint texobj,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01005307 cl_int * err = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005308 {
5309 cl_int error;
5310 object_ = ::clCreateFromGLTexture(
5311 context(),
5312 flags,
5313 target,
5314 miplevel,
5315 texobj,
5316 &error);
5317
5318 detail::errHandler(error, __CREATE_GL_TEXTURE_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01005319 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005320 *err = error;
5321 }
5322 }
5323
5324 ImageGL() : Image() { }
5325
5326 /*! \brief Constructor from cl_mem - takes ownership.
5327 *
5328 * \param retainObject will cause the constructor to retain its cl object.
5329 * Defaults to false to maintain compatibility with
5330 * earlier versions.
5331 * See Memory for further details.
5332 */
5333 explicit ImageGL(const cl_mem& image, bool retainObject = false) :
5334 Image(image, retainObject) { }
5335
5336 ImageGL& operator = (const cl_mem& rhs)
5337 {
5338 Image::operator=(rhs);
5339 return *this;
5340 }
5341
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005342};
5343#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
5344
5345
5346
5347#if CL_HPP_TARGET_OPENCL_VERSION >= 200
5348/*! \brief Class interface for Pipe Memory Objects.
5349*
5350* See Memory for details about copy semantics, etc.
5351*
5352* \see Memory
5353*/
5354class Pipe : public Memory
5355{
5356public:
5357
5358 /*! \brief Constructs a Pipe in a specified context.
5359 *
5360 * Wraps clCreatePipe().
5361 * @param context Context in which to create the pipe.
5362 * @param flags Bitfield. Only CL_MEM_READ_WRITE and CL_MEM_HOST_NO_ACCESS are valid.
5363 * @param packet_size Size in bytes of a single packet of the pipe.
5364 * @param max_packets Number of packets that may be stored in the pipe.
5365 *
5366 */
5367 Pipe(
5368 const Context& context,
5369 cl_uint packet_size,
5370 cl_uint max_packets,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01005371 cl_int* err = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005372 {
5373 cl_int error;
5374
5375 cl_mem_flags flags = CL_MEM_READ_WRITE | CL_MEM_HOST_NO_ACCESS;
5376 object_ = ::clCreatePipe(context(), flags, packet_size, max_packets, nullptr, &error);
5377
5378 detail::errHandler(error, __CREATE_PIPE_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01005379 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005380 *err = error;
5381 }
5382 }
5383
5384 /*! \brief Constructs a Pipe in a the default context.
5385 *
5386 * Wraps clCreatePipe().
5387 * @param flags Bitfield. Only CL_MEM_READ_WRITE and CL_MEM_HOST_NO_ACCESS are valid.
5388 * @param packet_size Size in bytes of a single packet of the pipe.
5389 * @param max_packets Number of packets that may be stored in the pipe.
5390 *
5391 */
5392 Pipe(
5393 cl_uint packet_size,
5394 cl_uint max_packets,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01005395 cl_int* err = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005396 {
5397 cl_int error;
5398
5399 Context context = Context::getDefault(err);
5400
5401 cl_mem_flags flags = CL_MEM_READ_WRITE | CL_MEM_HOST_NO_ACCESS;
5402 object_ = ::clCreatePipe(context(), flags, packet_size, max_packets, nullptr, &error);
5403
5404 detail::errHandler(error, __CREATE_PIPE_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01005405 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005406 *err = error;
5407 }
5408 }
5409
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01005410 //! \brief Default constructor - initializes to nullptr.
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005411 Pipe() : Memory() { }
5412
5413 /*! \brief Constructor from cl_mem - takes ownership.
5414 *
5415 * \param retainObject will cause the constructor to retain its cl object.
5416 * Defaults to false to maintain compatibility with earlier versions.
5417 *
5418 * See Memory for further details.
5419 */
5420 explicit Pipe(const cl_mem& pipe, bool retainObject = false) :
5421 Memory(pipe, retainObject) { }
5422
5423 /*! \brief Assignment from cl_mem - performs shallow copy.
5424 *
5425 * See Memory for further details.
5426 */
5427 Pipe& operator = (const cl_mem& rhs)
5428 {
5429 Memory::operator=(rhs);
5430 return *this;
5431 }
5432
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005433
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005434
5435 //! \brief Wrapper for clGetMemObjectInfo().
5436 template <typename T>
5437 cl_int getInfo(cl_pipe_info name, T* param) const
5438 {
5439 return detail::errHandler(
5440 detail::getInfo(&::clGetPipeInfo, object_, name, param),
5441 __GET_PIPE_INFO_ERR);
5442 }
5443
5444 //! \brief Wrapper for clGetMemObjectInfo() that returns by value.
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00005445 template <cl_pipe_info name> typename
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005446 detail::param_traits<detail::cl_pipe_info, name>::param_type
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01005447 getInfo(cl_int* err = nullptr) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005448 {
5449 typename detail::param_traits<
5450 detail::cl_pipe_info, name>::param_type param;
5451 cl_int result = getInfo(name, &param);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01005452 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005453 *err = result;
5454 }
5455 return param;
5456 }
5457}; // class Pipe
5458#endif // CL_HPP_TARGET_OPENCL_VERSION >= 200
5459
5460
5461/*! \brief Class interface for cl_sampler.
5462 *
5463 * \note Copies of these objects are shallow, meaning that the copy will refer
5464 * to the same underlying cl_sampler as the original. For details, see
5465 * clRetainSampler() and clReleaseSampler().
5466 *
5467 * \see cl_sampler
5468 */
5469class Sampler : public detail::Wrapper<cl_sampler>
5470{
5471public:
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01005472 //! \brief Default constructor - initializes to nullptr.
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005473 Sampler() { }
5474
5475 /*! \brief Constructs a Sampler in a specified context.
5476 *
5477 * Wraps clCreateSampler().
5478 */
5479 Sampler(
5480 const Context& context,
5481 cl_bool normalized_coords,
5482 cl_addressing_mode addressing_mode,
5483 cl_filter_mode filter_mode,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01005484 cl_int* err = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005485 {
5486 cl_int error;
5487
5488#if CL_HPP_TARGET_OPENCL_VERSION >= 200
5489 cl_sampler_properties sampler_properties[] = {
5490 CL_SAMPLER_NORMALIZED_COORDS, normalized_coords,
5491 CL_SAMPLER_ADDRESSING_MODE, addressing_mode,
5492 CL_SAMPLER_FILTER_MODE, filter_mode,
5493 0 };
5494 object_ = ::clCreateSamplerWithProperties(
5495 context(),
5496 sampler_properties,
5497 &error);
5498
5499 detail::errHandler(error, __CREATE_SAMPLER_WITH_PROPERTIES_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01005500 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005501 *err = error;
5502 }
5503#else
5504 object_ = ::clCreateSampler(
5505 context(),
5506 normalized_coords,
5507 addressing_mode,
5508 filter_mode,
5509 &error);
5510
5511 detail::errHandler(error, __CREATE_SAMPLER_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01005512 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005513 *err = error;
5514 }
5515#endif
5516 }
5517
5518 /*! \brief Constructor from cl_sampler - takes ownership.
5519 *
5520 * \param retainObject will cause the constructor to retain its cl object.
5521 * Defaults to false to maintain compatibility with
5522 * earlier versions.
5523 * This effectively transfers ownership of a refcount on the cl_sampler
5524 * into the new Sampler object.
5525 */
5526 explicit Sampler(const cl_sampler& sampler, bool retainObject = false) :
5527 detail::Wrapper<cl_type>(sampler, retainObject) { }
5528
5529 /*! \brief Assignment operator from cl_sampler - takes ownership.
5530 *
5531 * This effectively transfers ownership of a refcount on the rhs and calls
5532 * clReleaseSampler() on the value previously held by this instance.
5533 */
5534 Sampler& operator = (const cl_sampler& rhs)
5535 {
5536 detail::Wrapper<cl_type>::operator=(rhs);
5537 return *this;
5538 }
5539
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01005540
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005541
5542 //! \brief Wrapper for clGetSamplerInfo().
5543 template <typename T>
5544 cl_int getInfo(cl_sampler_info name, T* param) const
5545 {
5546 return detail::errHandler(
5547 detail::getInfo(&::clGetSamplerInfo, object_, name, param),
5548 __GET_SAMPLER_INFO_ERR);
5549 }
5550
5551 //! \brief Wrapper for clGetSamplerInfo() that returns by value.
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00005552 template <cl_sampler_info name> typename
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005553 detail::param_traits<detail::cl_sampler_info, name>::param_type
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01005554 getInfo(cl_int* err = nullptr) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005555 {
5556 typename detail::param_traits<
5557 detail::cl_sampler_info, name>::param_type param;
5558 cl_int result = getInfo(name, &param);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01005559 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005560 *err = result;
5561 }
5562 return param;
5563 }
5564};
5565
5566class Program;
5567class CommandQueue;
5568class DeviceCommandQueue;
5569class Kernel;
5570
5571//! \brief Class interface for specifying NDRange values.
5572class NDRange
5573{
5574private:
5575 size_type sizes_[3];
5576 cl_uint dimensions_;
5577
5578public:
5579 //! \brief Default constructor - resulting range has zero dimensions.
5580 NDRange()
5581 : dimensions_(0)
5582 {
5583 sizes_[0] = 0;
5584 sizes_[1] = 0;
5585 sizes_[2] = 0;
5586 }
5587
5588 //! \brief Constructs one-dimensional range.
5589 NDRange(size_type size0)
5590 : dimensions_(1)
5591 {
5592 sizes_[0] = size0;
5593 sizes_[1] = 1;
5594 sizes_[2] = 1;
5595 }
5596
5597 //! \brief Constructs two-dimensional range.
5598 NDRange(size_type size0, size_type size1)
5599 : dimensions_(2)
5600 {
5601 sizes_[0] = size0;
5602 sizes_[1] = size1;
5603 sizes_[2] = 1;
5604 }
5605
5606 //! \brief Constructs three-dimensional range.
5607 NDRange(size_type size0, size_type size1, size_type size2)
5608 : dimensions_(3)
5609 {
5610 sizes_[0] = size0;
5611 sizes_[1] = size1;
5612 sizes_[2] = size2;
5613 }
5614
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01005615 //! \brief Constructs one-dimensional range.
5616 NDRange(array<size_type, 1> a) : NDRange(a[0]){}
5617
5618 //! \brief Constructs two-dimensional range.
5619 NDRange(array<size_type, 2> a) : NDRange(a[0], a[1]){}
5620
5621 //! \brief Constructs three-dimensional range.
5622 NDRange(array<size_type, 3> a) : NDRange(a[0], a[1], a[2]){}
5623
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005624 /*! \brief Conversion operator to const size_type *.
5625 *
5626 * \returns a pointer to the size of the first dimension.
5627 */
5628 operator const size_type*() const {
5629 return sizes_;
5630 }
5631
5632 //! \brief Queries the number of dimensions in the range.
5633 size_type dimensions() const
5634 {
5635 return dimensions_;
5636 }
5637
5638 //! \brief Returns the size of the object in bytes based on the
5639 // runtime number of dimensions
5640 size_type size() const
5641 {
5642 return dimensions_*sizeof(size_type);
5643 }
5644
5645 size_type* get()
5646 {
5647 return sizes_;
5648 }
5649
5650 const size_type* get() const
5651 {
5652 return sizes_;
5653 }
5654};
5655
5656//! \brief A zero-dimensional range.
5657static const NDRange NullRange;
5658
5659//! \brief Local address wrapper for use with Kernel::setArg
5660struct LocalSpaceArg
5661{
5662 size_type size_;
5663};
5664
5665namespace detail {
5666
5667template <typename T, class Enable = void>
5668struct KernelArgumentHandler;
5669
5670// Enable for objects that are not subclasses of memory
5671// Pointers, constants etc
5672template <typename T>
5673struct KernelArgumentHandler<T, typename std::enable_if<!std::is_base_of<cl::Memory, T>::value>::type>
5674{
5675 static size_type size(const T&) { return sizeof(T); }
5676 static const T* ptr(const T& value) { return &value; }
5677};
5678
5679// Enable for subclasses of memory where we want to get a reference to the cl_mem out
5680// and pass that in for safety
5681template <typename T>
5682struct KernelArgumentHandler<T, typename std::enable_if<std::is_base_of<cl::Memory, T>::value>::type>
5683{
5684 static size_type size(const T&) { return sizeof(cl_mem); }
5685 static const cl_mem* ptr(const T& value) { return &(value()); }
5686};
5687
5688// Specialization for DeviceCommandQueue defined later
5689
5690template <>
5691struct KernelArgumentHandler<LocalSpaceArg, void>
5692{
5693 static size_type size(const LocalSpaceArg& value) { return value.size_; }
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01005694 static const void* ptr(const LocalSpaceArg&) { return nullptr; }
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005695};
5696
5697}
5698//! \endcond
5699
5700/*! Local
5701 * \brief Helper function for generating LocalSpaceArg objects.
5702 */
5703inline LocalSpaceArg
5704Local(size_type size)
5705{
5706 LocalSpaceArg ret = { size };
5707 return ret;
5708}
5709
5710/*! \brief Class interface for cl_kernel.
5711 *
5712 * \note Copies of these objects are shallow, meaning that the copy will refer
5713 * to the same underlying cl_kernel as the original. For details, see
5714 * clRetainKernel() and clReleaseKernel().
5715 *
5716 * \see cl_kernel
5717 */
5718class Kernel : public detail::Wrapper<cl_kernel>
5719{
5720public:
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01005721 inline Kernel(const Program& program, const char* name, cl_int* err = nullptr);
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005722
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01005723 //! \brief Default constructor - initializes to nullptr.
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005724 Kernel() { }
5725
5726 /*! \brief Constructor from cl_kernel - takes ownership.
5727 *
5728 * \param retainObject will cause the constructor to retain its cl object.
5729 * Defaults to false to maintain compatibility with
5730 * earlier versions.
5731 * This effectively transfers ownership of a refcount on the cl_kernel
5732 * into the new Kernel object.
5733 */
5734 explicit Kernel(const cl_kernel& kernel, bool retainObject = false) :
5735 detail::Wrapper<cl_type>(kernel, retainObject) { }
5736
5737 /*! \brief Assignment operator from cl_kernel - takes ownership.
5738 *
5739 * This effectively transfers ownership of a refcount on the rhs and calls
5740 * clReleaseKernel() on the value previously held by this instance.
5741 */
5742 Kernel& operator = (const cl_kernel& rhs)
5743 {
5744 detail::Wrapper<cl_type>::operator=(rhs);
5745 return *this;
5746 }
5747
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005748
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005749
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005750
5751 template <typename T>
5752 cl_int getInfo(cl_kernel_info name, T* param) const
5753 {
5754 return detail::errHandler(
5755 detail::getInfo(&::clGetKernelInfo, object_, name, param),
5756 __GET_KERNEL_INFO_ERR);
5757 }
5758
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00005759 template <cl_kernel_info name> typename
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005760 detail::param_traits<detail::cl_kernel_info, name>::param_type
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01005761 getInfo(cl_int* err = nullptr) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005762 {
5763 typename detail::param_traits<
5764 detail::cl_kernel_info, name>::param_type param;
5765 cl_int result = getInfo(name, &param);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01005766 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005767 *err = result;
5768 }
5769 return param;
5770 }
5771
5772#if CL_HPP_TARGET_OPENCL_VERSION >= 120
5773 template <typename T>
5774 cl_int getArgInfo(cl_uint argIndex, cl_kernel_arg_info name, T* param) const
5775 {
5776 return detail::errHandler(
5777 detail::getInfo(&::clGetKernelArgInfo, object_, argIndex, name, param),
5778 __GET_KERNEL_ARG_INFO_ERR);
5779 }
5780
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00005781 template <cl_kernel_arg_info name> typename
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005782 detail::param_traits<detail::cl_kernel_arg_info, name>::param_type
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01005783 getArgInfo(cl_uint argIndex, cl_int* err = nullptr) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005784 {
5785 typename detail::param_traits<
5786 detail::cl_kernel_arg_info, name>::param_type param;
5787 cl_int result = getArgInfo(argIndex, name, &param);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01005788 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005789 *err = result;
5790 }
5791 return param;
5792 }
5793#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
5794
5795 template <typename T>
5796 cl_int getWorkGroupInfo(
5797 const Device& device, cl_kernel_work_group_info name, T* param) const
5798 {
5799 return detail::errHandler(
5800 detail::getInfo(
5801 &::clGetKernelWorkGroupInfo, object_, device(), name, param),
5802 __GET_KERNEL_WORK_GROUP_INFO_ERR);
5803 }
5804
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00005805 template <cl_kernel_work_group_info name> typename
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005806 detail::param_traits<detail::cl_kernel_work_group_info, name>::param_type
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01005807 getWorkGroupInfo(const Device& device, cl_int* err = nullptr) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005808 {
5809 typename detail::param_traits<
5810 detail::cl_kernel_work_group_info, name>::param_type param;
5811 cl_int result = getWorkGroupInfo(device, name, &param);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01005812 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005813 *err = result;
5814 }
5815 return param;
5816 }
5817
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01005818#if defined(CL_HPP_USE_CL_SUB_GROUPS_KHR) || CL_HPP_TARGET_OPENCL_VERSION >= 210
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005819 cl_int getSubGroupInfo(const cl::Device &dev, cl_kernel_sub_group_info name, const cl::NDRange &range, size_type* param) const
5820 {
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00005821#if CL_HPP_TARGET_OPENCL_VERSION >= 210
5822
5823 return detail::errHandler(
5824 clGetKernelSubGroupInfo(object_, dev(), name, range.size(), range.get(), sizeof(size_type), param, nullptr),
5825 __GET_KERNEL_SUB_GROUP_INFO_ERR);
5826
5827#else // #if CL_HPP_TARGET_OPENCL_VERSION >= 210
5828
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005829 typedef clGetKernelSubGroupInfoKHR_fn PFN_clGetKernelSubGroupInfoKHR;
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01005830 static PFN_clGetKernelSubGroupInfoKHR pfn_clGetKernelSubGroupInfoKHR = nullptr;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005831 CL_HPP_INIT_CL_EXT_FCN_PTR_(clGetKernelSubGroupInfoKHR);
5832
5833 return detail::errHandler(
5834 pfn_clGetKernelSubGroupInfoKHR(object_, dev(), name, range.size(), range.get(), sizeof(size_type), param, nullptr),
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00005835 __GET_KERNEL_SUB_GROUP_INFO_ERR);
5836
5837#endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 210
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005838 }
5839
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00005840 template <cl_kernel_sub_group_info name>
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01005841 size_type getSubGroupInfo(const cl::Device &dev, const cl::NDRange &range, cl_int* err = nullptr) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005842 {
5843 size_type param;
5844 cl_int result = getSubGroupInfo(dev, name, range, &param);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01005845 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005846 *err = result;
5847 }
5848 return param;
5849 }
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01005850#endif // defined(CL_HPP_USE_CL_SUB_GROUPS_KHR) || CL_HPP_TARGET_OPENCL_VERSION >= 210
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005851
5852#if CL_HPP_TARGET_OPENCL_VERSION >= 200
5853 /*! \brief setArg overload taking a shared_ptr type
5854 */
5855 template<typename T, class D>
5856 cl_int setArg(cl_uint index, const cl::pointer<T, D> &argPtr)
5857 {
5858 return detail::errHandler(
5859 ::clSetKernelArgSVMPointer(object_, index, argPtr.get()),
5860 __SET_KERNEL_ARGS_ERR);
5861 }
5862
5863 /*! \brief setArg overload taking a vector type.
5864 */
5865 template<typename T, class Alloc>
5866 cl_int setArg(cl_uint index, const cl::vector<T, Alloc> &argPtr)
5867 {
5868 return detail::errHandler(
5869 ::clSetKernelArgSVMPointer(object_, index, argPtr.data()),
5870 __SET_KERNEL_ARGS_ERR);
5871 }
5872
5873 /*! \brief setArg overload taking a pointer type
5874 */
5875 template<typename T>
5876 typename std::enable_if<std::is_pointer<T>::value, cl_int>::type
5877 setArg(cl_uint index, const T argPtr)
5878 {
5879 return detail::errHandler(
5880 ::clSetKernelArgSVMPointer(object_, index, argPtr),
5881 __SET_KERNEL_ARGS_ERR);
5882 }
5883#endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 200
5884
5885 /*! \brief setArg overload taking a POD type
5886 */
5887 template <typename T>
5888 typename std::enable_if<!std::is_pointer<T>::value, cl_int>::type
5889 setArg(cl_uint index, const T &value)
5890 {
5891 return detail::errHandler(
5892 ::clSetKernelArg(
5893 object_,
5894 index,
5895 detail::KernelArgumentHandler<T>::size(value),
5896 detail::KernelArgumentHandler<T>::ptr(value)),
5897 __SET_KERNEL_ARGS_ERR);
5898 }
5899
5900 cl_int setArg(cl_uint index, size_type size, const void* argPtr)
5901 {
5902 return detail::errHandler(
5903 ::clSetKernelArg(object_, index, size, argPtr),
5904 __SET_KERNEL_ARGS_ERR);
5905 }
5906
5907#if CL_HPP_TARGET_OPENCL_VERSION >= 200
5908 /*!
5909 * Specify a vector of SVM pointers that the kernel may access in
5910 * addition to its arguments.
5911 */
5912 cl_int setSVMPointers(const vector<void*> &pointerList)
5913 {
5914 return detail::errHandler(
5915 ::clSetKernelExecInfo(
5916 object_,
5917 CL_KERNEL_EXEC_INFO_SVM_PTRS,
5918 sizeof(void*)*pointerList.size(),
5919 pointerList.data()));
5920 }
5921
5922 /*!
5923 * Specify a std::array of SVM pointers that the kernel may access in
5924 * addition to its arguments.
5925 */
5926 template<int ArrayLength>
5927 cl_int setSVMPointers(const std::array<void*, ArrayLength> &pointerList)
5928 {
5929 return detail::errHandler(
5930 ::clSetKernelExecInfo(
5931 object_,
5932 CL_KERNEL_EXEC_INFO_SVM_PTRS,
5933 sizeof(void*)*pointerList.size(),
5934 pointerList.data()));
5935 }
5936
5937 /*! \brief Enable fine-grained system SVM.
5938 *
5939 * \note It is only possible to enable fine-grained system SVM if all devices
5940 * in the context associated with kernel support it.
5941 *
5942 * \param svmEnabled True if fine-grained system SVM is requested. False otherwise.
5943 * \return CL_SUCCESS if the function was executed succesfully. CL_INVALID_OPERATION
5944 * if no devices in the context support fine-grained system SVM.
5945 *
5946 * \see clSetKernelExecInfo
5947 */
5948 cl_int enableFineGrainedSystemSVM(bool svmEnabled)
5949 {
5950 cl_bool svmEnabled_ = svmEnabled ? CL_TRUE : CL_FALSE;
5951 return detail::errHandler(
5952 ::clSetKernelExecInfo(
5953 object_,
5954 CL_KERNEL_EXEC_INFO_SVM_FINE_GRAIN_SYSTEM,
5955 sizeof(cl_bool),
5956 &svmEnabled_
5957 )
5958 );
5959 }
5960
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00005961 template<int index, int ArrayLength, class D, typename T0, typename T1, typename... Ts>
5962 void setSVMPointersHelper(std::array<void*, ArrayLength> &pointerList, const pointer<T0, D> &t0, const pointer<T1, D> &t1, Ts & ... ts)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005963 {
5964 pointerList[index] = static_cast<void*>(t0.get());
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00005965 setSVMPointersHelper<index + 1, ArrayLength>(pointerList, t1, ts...);
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005966 }
5967
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00005968 template<int index, int ArrayLength, typename T0, typename T1, typename... Ts>
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005969 typename std::enable_if<std::is_pointer<T0>::value, void>::type
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00005970 setSVMPointersHelper(std::array<void*, ArrayLength> &pointerList, T0 t0, T1 t1, Ts... ts)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005971 {
5972 pointerList[index] = static_cast<void*>(t0);
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00005973 setSVMPointersHelper<index + 1, ArrayLength>(pointerList, t1, ts...);
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005974 }
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00005975
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005976 template<int index, int ArrayLength, typename T0, class D>
5977 void setSVMPointersHelper(std::array<void*, ArrayLength> &pointerList, const pointer<T0, D> &t0)
5978 {
5979 pointerList[index] = static_cast<void*>(t0.get());
5980 }
5981
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00005982
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005983 template<int index, int ArrayLength, typename T0>
5984 typename std::enable_if<std::is_pointer<T0>::value, void>::type
5985 setSVMPointersHelper(std::array<void*, ArrayLength> &pointerList, T0 t0)
5986 {
5987 pointerList[index] = static_cast<void*>(t0);
5988 }
5989
5990 template<typename T0, typename... Ts>
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00005991 cl_int setSVMPointers(const T0 &t0, Ts & ... ts)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01005992 {
5993 std::array<void*, 1 + sizeof...(Ts)> pointerList;
5994
5995 setSVMPointersHelper<0, 1 + sizeof...(Ts)>(pointerList, t0, ts...);
5996 return detail::errHandler(
5997 ::clSetKernelExecInfo(
5998 object_,
5999 CL_KERNEL_EXEC_INFO_SVM_PTRS,
6000 sizeof(void*)*(1 + sizeof...(Ts)),
6001 pointerList.data()));
6002 }
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00006003
6004 template<typename T>
6005 cl_int setExecInfo(cl_kernel_exec_info param_name, const T& val)
6006 {
6007 return detail::errHandler(
6008 ::clSetKernelExecInfo(
6009 object_,
6010 param_name,
6011 sizeof(T),
6012 &val));
6013 }
6014
6015 template<cl_kernel_exec_info name>
6016 cl_int setExecInfo(typename detail::param_traits<detail::cl_kernel_exec_info, name>::param_type& val)
6017 {
6018 return setExecInfo(name, val);
6019 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006020#endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 200
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00006021
6022#if CL_HPP_TARGET_OPENCL_VERSION >= 210
6023 /**
6024 * Make a deep copy of the kernel object including its arguments.
6025 * @return A new kernel object with internal state entirely separate from that
6026 * of the original but with any arguments set on the original intact.
6027 */
6028 Kernel clone()
6029 {
6030 cl_int error;
6031 Kernel retValue(clCloneKernel(this->get(), &error));
6032
6033 detail::errHandler(error, __CLONE_KERNEL_ERR);
6034 return retValue;
6035 }
6036#endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 210
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006037};
6038
6039/*! \class Program
6040 * \brief Program interface that implements cl_program.
6041 */
6042class Program : public detail::Wrapper<cl_program>
6043{
6044public:
6045#if !defined(CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY)
6046 typedef vector<vector<unsigned char>> Binaries;
6047 typedef vector<string> Sources;
6048#else // #if !defined(CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY)
6049 typedef vector<std::pair<const void*, size_type> > Binaries;
6050 typedef vector<std::pair<const char*, size_type> > Sources;
6051#endif // #if !defined(CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY)
6052
6053 Program(
6054 const string& source,
6055 bool build = false,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006056 cl_int* err = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006057 {
6058 cl_int error;
6059
6060 const char * strings = source.c_str();
6061 const size_type length = source.size();
6062
6063 Context context = Context::getDefault(err);
6064
6065 object_ = ::clCreateProgramWithSource(
6066 context(), (cl_uint)1, &strings, &length, &error);
6067
6068 detail::errHandler(error, __CREATE_PROGRAM_WITH_SOURCE_ERR);
6069
6070 if (error == CL_SUCCESS && build) {
6071
6072 error = ::clBuildProgram(
6073 object_,
6074 0,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006075 nullptr,
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006076#if !defined(CL_HPP_CL_1_2_DEFAULT_BUILD)
6077 "-cl-std=CL2.0",
6078#else
6079 "",
6080#endif // #if !defined(CL_HPP_CL_1_2_DEFAULT_BUILD)
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006081 nullptr,
6082 nullptr);
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006083
6084 detail::buildErrHandler(error, __BUILD_PROGRAM_ERR, getBuildInfo<CL_PROGRAM_BUILD_LOG>());
6085 }
6086
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006087 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006088 *err = error;
6089 }
6090 }
6091
6092 Program(
6093 const Context& context,
6094 const string& source,
6095 bool build = false,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006096 cl_int* err = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006097 {
6098 cl_int error;
6099
6100 const char * strings = source.c_str();
6101 const size_type length = source.size();
6102
6103 object_ = ::clCreateProgramWithSource(
6104 context(), (cl_uint)1, &strings, &length, &error);
6105
6106 detail::errHandler(error, __CREATE_PROGRAM_WITH_SOURCE_ERR);
6107
6108 if (error == CL_SUCCESS && build) {
6109 error = ::clBuildProgram(
6110 object_,
6111 0,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006112 nullptr,
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006113#if !defined(CL_HPP_CL_1_2_DEFAULT_BUILD)
6114 "-cl-std=CL2.0",
6115#else
6116 "",
6117#endif // #if !defined(CL_HPP_CL_1_2_DEFAULT_BUILD)
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006118 nullptr,
6119 nullptr);
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006120
6121 detail::buildErrHandler(error, __BUILD_PROGRAM_ERR, getBuildInfo<CL_PROGRAM_BUILD_LOG>());
6122 }
6123
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006124 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006125 *err = error;
6126 }
6127 }
6128
6129 /**
6130 * Create a program from a vector of source strings and the default context.
6131 * Does not compile or link the program.
6132 */
6133 Program(
6134 const Sources& sources,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006135 cl_int* err = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006136 {
6137 cl_int error;
6138 Context context = Context::getDefault(err);
6139
6140 const size_type n = (size_type)sources.size();
6141
6142 vector<size_type> lengths(n);
6143 vector<const char*> strings(n);
6144
6145 for (size_type i = 0; i < n; ++i) {
6146#if !defined(CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY)
6147 strings[i] = sources[(int)i].data();
6148 lengths[i] = sources[(int)i].length();
6149#else // #if !defined(CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY)
6150 strings[i] = sources[(int)i].first;
6151 lengths[i] = sources[(int)i].second;
6152#endif // #if !defined(CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY)
6153 }
6154
6155 object_ = ::clCreateProgramWithSource(
6156 context(), (cl_uint)n, strings.data(), lengths.data(), &error);
6157
6158 detail::errHandler(error, __CREATE_PROGRAM_WITH_SOURCE_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006159 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006160 *err = error;
6161 }
6162 }
6163
6164 /**
6165 * Create a program from a vector of source strings and a provided context.
6166 * Does not compile or link the program.
6167 */
6168 Program(
6169 const Context& context,
6170 const Sources& sources,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006171 cl_int* err = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006172 {
6173 cl_int error;
6174
6175 const size_type n = (size_type)sources.size();
6176
6177 vector<size_type> lengths(n);
6178 vector<const char*> strings(n);
6179
6180 for (size_type i = 0; i < n; ++i) {
6181#if !defined(CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY)
6182 strings[i] = sources[(int)i].data();
6183 lengths[i] = sources[(int)i].length();
6184#else // #if !defined(CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY)
6185 strings[i] = sources[(int)i].first;
6186 lengths[i] = sources[(int)i].second;
6187#endif // #if !defined(CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY)
6188 }
6189
6190 object_ = ::clCreateProgramWithSource(
6191 context(), (cl_uint)n, strings.data(), lengths.data(), &error);
6192
6193 detail::errHandler(error, __CREATE_PROGRAM_WITH_SOURCE_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006194 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006195 *err = error;
6196 }
6197 }
6198
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00006199
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006200#if defined(CL_HPP_USE_IL_KHR) || CL_HPP_TARGET_OPENCL_VERSION >= 210
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00006201 /**
6202 * Program constructor to allow construction of program from SPIR-V or another IL.
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006203 *
6204 * Requires OpenCL 2.1 or newer or the cl_khr_il_program extension.
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00006205 */
6206 Program(
6207 const vector<char>& IL,
6208 bool build = false,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006209 cl_int* err = nullptr)
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00006210 {
6211 cl_int error;
6212
6213 Context context = Context::getDefault(err);
6214
6215#if CL_HPP_TARGET_OPENCL_VERSION >= 210
6216
6217 object_ = ::clCreateProgramWithIL(
6218 context(), static_cast<const void*>(IL.data()), IL.size(), &error);
6219
6220#else // #if CL_HPP_TARGET_OPENCL_VERSION >= 210
6221
6222 typedef clCreateProgramWithILKHR_fn PFN_clCreateProgramWithILKHR;
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006223 static PFN_clCreateProgramWithILKHR pfn_clCreateProgramWithILKHR = nullptr;
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00006224 CL_HPP_INIT_CL_EXT_FCN_PTR_(clCreateProgramWithILKHR);
6225
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006226 object_ = pfn_clCreateProgramWithILKHR(
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00006227 context(), static_cast<const void*>(IL.data()), IL.size(), &error);
6228
6229#endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 210
6230
6231 detail::errHandler(error, __CREATE_PROGRAM_WITH_IL_ERR);
6232
6233 if (error == CL_SUCCESS && build) {
6234
6235 error = ::clBuildProgram(
6236 object_,
6237 0,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006238 nullptr,
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00006239#if !defined(CL_HPP_CL_1_2_DEFAULT_BUILD)
6240 "-cl-std=CL2.0",
6241#else
6242 "",
6243#endif // #if !defined(CL_HPP_CL_1_2_DEFAULT_BUILD)
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006244 nullptr,
6245 nullptr);
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00006246
6247 detail::buildErrHandler(error, __BUILD_PROGRAM_ERR, getBuildInfo<CL_PROGRAM_BUILD_LOG>());
6248 }
6249
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006250 if (err != nullptr) {
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00006251 *err = error;
6252 }
6253 }
6254
6255 /**
6256 * Program constructor to allow construction of program from SPIR-V or another IL
6257 * for a specific context.
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006258 *
6259 * Requires OpenCL 2.1 or newer or the cl_khr_il_program extension.
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00006260 */
6261 Program(
6262 const Context& context,
6263 const vector<char>& IL,
6264 bool build = false,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006265 cl_int* err = nullptr)
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00006266 {
6267 cl_int error;
6268
6269#if CL_HPP_TARGET_OPENCL_VERSION >= 210
6270
6271 object_ = ::clCreateProgramWithIL(
6272 context(), static_cast<const void*>(IL.data()), IL.size(), &error);
6273
6274#else // #if CL_HPP_TARGET_OPENCL_VERSION >= 210
6275
6276 typedef clCreateProgramWithILKHR_fn PFN_clCreateProgramWithILKHR;
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006277 static PFN_clCreateProgramWithILKHR pfn_clCreateProgramWithILKHR = nullptr;
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00006278 CL_HPP_INIT_CL_EXT_FCN_PTR_(clCreateProgramWithILKHR);
6279
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006280 object_ = pfn_clCreateProgramWithILKHR(
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00006281 context(), static_cast<const void*>(IL.data()), IL.size(), &error);
6282
6283#endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 210
6284
6285 detail::errHandler(error, __CREATE_PROGRAM_WITH_IL_ERR);
6286
6287 if (error == CL_SUCCESS && build) {
6288 error = ::clBuildProgram(
6289 object_,
6290 0,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006291 nullptr,
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00006292#if !defined(CL_HPP_CL_1_2_DEFAULT_BUILD)
6293 "-cl-std=CL2.0",
6294#else
6295 "",
6296#endif // #if !defined(CL_HPP_CL_1_2_DEFAULT_BUILD)
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006297 nullptr,
6298 nullptr);
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00006299
6300 detail::buildErrHandler(error, __BUILD_PROGRAM_ERR, getBuildInfo<CL_PROGRAM_BUILD_LOG>());
6301 }
6302
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006303 if (err != nullptr) {
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00006304 *err = error;
6305 }
6306 }
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006307#endif // defined(CL_HPP_USE_IL_KHR) || CL_HPP_TARGET_OPENCL_VERSION >= 210
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00006308
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006309 /**
6310 * Construct a program object from a list of devices and a per-device list of binaries.
6311 * \param context A valid OpenCL context in which to construct the program.
6312 * \param devices A vector of OpenCL device objects for which the program will be created.
6313 * \param binaries A vector of pairs of a pointer to a binary object and its length.
6314 * \param binaryStatus An optional vector that on completion will be resized to
6315 * match the size of binaries and filled with values to specify if each binary
6316 * was successfully loaded.
6317 * Set to CL_SUCCESS if the binary was successfully loaded.
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006318 * Set to CL_INVALID_VALUE if the length is 0 or the binary pointer is nullptr.
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006319 * Set to CL_INVALID_BINARY if the binary provided is not valid for the matching device.
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006320 * \param err if non-nullptr will be set to CL_SUCCESS on successful operation or one of the following errors:
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006321 * CL_INVALID_CONTEXT if context is not a valid context.
6322 * CL_INVALID_VALUE if the length of devices is zero; or if the length of binaries does not match the length of devices;
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006323 * or if any entry in binaries is nullptr or has length 0.
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006324 * CL_INVALID_DEVICE if OpenCL devices listed in devices are not in the list of devices associated with context.
6325 * CL_INVALID_BINARY if an invalid program binary was encountered for any device. binaryStatus will return specific status for each device.
6326 * CL_OUT_OF_HOST_MEMORY if there is a failure to allocate resources required by the OpenCL implementation on the host.
6327 */
6328 Program(
6329 const Context& context,
6330 const vector<Device>& devices,
6331 const Binaries& binaries,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006332 vector<cl_int>* binaryStatus = nullptr,
6333 cl_int* err = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006334 {
6335 cl_int error;
6336
6337 const size_type numDevices = devices.size();
6338
6339 // Catch size mismatch early and return
6340 if(binaries.size() != numDevices) {
6341 error = CL_INVALID_VALUE;
6342 detail::errHandler(error, __CREATE_PROGRAM_WITH_BINARY_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006343 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006344 *err = error;
6345 }
6346 return;
6347 }
6348
6349
6350 vector<size_type> lengths(numDevices);
6351 vector<const unsigned char*> images(numDevices);
6352#if !defined(CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY)
6353 for (size_type i = 0; i < numDevices; ++i) {
6354 images[i] = binaries[i].data();
6355 lengths[i] = binaries[(int)i].size();
6356 }
6357#else // #if !defined(CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY)
6358 for (size_type i = 0; i < numDevices; ++i) {
6359 images[i] = (const unsigned char*)binaries[i].first;
6360 lengths[i] = binaries[(int)i].second;
6361 }
6362#endif // #if !defined(CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY)
6363
6364 vector<cl_device_id> deviceIDs(numDevices);
6365 for( size_type deviceIndex = 0; deviceIndex < numDevices; ++deviceIndex ) {
6366 deviceIDs[deviceIndex] = (devices[deviceIndex])();
6367 }
6368
6369 if(binaryStatus) {
6370 binaryStatus->resize(numDevices);
6371 }
6372
6373 object_ = ::clCreateProgramWithBinary(
6374 context(), (cl_uint) devices.size(),
6375 deviceIDs.data(),
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006376 lengths.data(), images.data(), (binaryStatus != nullptr && numDevices > 0)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006377 ? &binaryStatus->front()
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006378 : nullptr, &error);
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006379
6380 detail::errHandler(error, __CREATE_PROGRAM_WITH_BINARY_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006381 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006382 *err = error;
6383 }
6384 }
6385
6386
6387#if CL_HPP_TARGET_OPENCL_VERSION >= 120
6388 /**
6389 * Create program using builtin kernels.
6390 * \param kernelNames Semi-colon separated list of builtin kernel names
6391 */
6392 Program(
6393 const Context& context,
6394 const vector<Device>& devices,
6395 const string& kernelNames,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006396 cl_int* err = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006397 {
6398 cl_int error;
6399
6400
6401 size_type numDevices = devices.size();
6402 vector<cl_device_id> deviceIDs(numDevices);
6403 for( size_type deviceIndex = 0; deviceIndex < numDevices; ++deviceIndex ) {
6404 deviceIDs[deviceIndex] = (devices[deviceIndex])();
6405 }
6406
6407 object_ = ::clCreateProgramWithBuiltInKernels(
6408 context(),
6409 (cl_uint) devices.size(),
6410 deviceIDs.data(),
6411 kernelNames.c_str(),
6412 &error);
6413
6414 detail::errHandler(error, __CREATE_PROGRAM_WITH_BUILT_IN_KERNELS_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006415 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006416 *err = error;
6417 }
6418 }
6419#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
6420
6421 Program() { }
6422
6423
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00006424 /*! \brief Constructor from cl_program - takes ownership.
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006425 *
6426 * \param retainObject will cause the constructor to retain its cl object.
6427 * Defaults to false to maintain compatibility with
6428 * earlier versions.
6429 */
6430 explicit Program(const cl_program& program, bool retainObject = false) :
6431 detail::Wrapper<cl_type>(program, retainObject) { }
6432
6433 Program& operator = (const cl_program& rhs)
6434 {
6435 detail::Wrapper<cl_type>::operator=(rhs);
6436 return *this;
6437 }
6438
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006439
6440 cl_int build(
6441 const vector<Device>& devices,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006442 const char* options = nullptr,
6443 void (CL_CALLBACK * notifyFptr)(cl_program, void *) = nullptr,
6444 void* data = nullptr) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006445 {
6446 size_type numDevices = devices.size();
6447 vector<cl_device_id> deviceIDs(numDevices);
6448
6449 for( size_type deviceIndex = 0; deviceIndex < numDevices; ++deviceIndex ) {
6450 deviceIDs[deviceIndex] = (devices[deviceIndex])();
6451 }
6452
6453 cl_int buildError = ::clBuildProgram(
6454 object_,
6455 (cl_uint)
6456 devices.size(),
6457 deviceIDs.data(),
6458 options,
6459 notifyFptr,
6460 data);
6461
6462 return detail::buildErrHandler(buildError, __BUILD_PROGRAM_ERR, getBuildInfo<CL_PROGRAM_BUILD_LOG>());
6463 }
6464
6465 cl_int build(
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00006466 const Device& device,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006467 const char* options = nullptr,
6468 void (CL_CALLBACK * notifyFptr)(cl_program, void *) = nullptr,
6469 void* data = nullptr) const
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00006470 {
6471 cl_device_id deviceID = device();
6472
6473 cl_int buildError = ::clBuildProgram(
6474 object_,
6475 1,
6476 &deviceID,
6477 options,
6478 notifyFptr,
6479 data);
6480
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006481 BuildLogType buildLog(0);
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00006482 buildLog.push_back(std::make_pair(device, getBuildInfo<CL_PROGRAM_BUILD_LOG>(device)));
6483 return detail::buildErrHandler(buildError, __BUILD_PROGRAM_ERR, buildLog);
6484 }
6485
6486 cl_int build(
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006487 const char* options = nullptr,
6488 void (CL_CALLBACK * notifyFptr)(cl_program, void *) = nullptr,
6489 void* data = nullptr) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006490 {
6491 cl_int buildError = ::clBuildProgram(
6492 object_,
6493 0,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006494 nullptr,
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006495 options,
6496 notifyFptr,
6497 data);
6498
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006499 return detail::buildErrHandler(buildError, __BUILD_PROGRAM_ERR, getBuildInfo<CL_PROGRAM_BUILD_LOG>());
6500 }
6501
6502#if CL_HPP_TARGET_OPENCL_VERSION >= 120
6503 cl_int compile(
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006504 const char* options = nullptr,
6505 void (CL_CALLBACK * notifyFptr)(cl_program, void *) = nullptr,
6506 void* data = nullptr) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006507 {
6508 cl_int error = ::clCompileProgram(
6509 object_,
6510 0,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006511 nullptr,
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006512 options,
6513 0,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006514 nullptr,
6515 nullptr,
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006516 notifyFptr,
6517 data);
6518 return detail::buildErrHandler(error, __COMPILE_PROGRAM_ERR, getBuildInfo<CL_PROGRAM_BUILD_LOG>());
6519 }
6520#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
6521
6522 template <typename T>
6523 cl_int getInfo(cl_program_info name, T* param) const
6524 {
6525 return detail::errHandler(
6526 detail::getInfo(&::clGetProgramInfo, object_, name, param),
6527 __GET_PROGRAM_INFO_ERR);
6528 }
6529
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00006530 template <cl_program_info name> typename
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006531 detail::param_traits<detail::cl_program_info, name>::param_type
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006532 getInfo(cl_int* err = nullptr) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006533 {
6534 typename detail::param_traits<
6535 detail::cl_program_info, name>::param_type param;
6536 cl_int result = getInfo(name, &param);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006537 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006538 *err = result;
6539 }
6540 return param;
6541 }
6542
6543 template <typename T>
6544 cl_int getBuildInfo(
6545 const Device& device, cl_program_build_info name, T* param) const
6546 {
6547 return detail::errHandler(
6548 detail::getInfo(
6549 &::clGetProgramBuildInfo, object_, device(), name, param),
6550 __GET_PROGRAM_BUILD_INFO_ERR);
6551 }
6552
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00006553 template <cl_program_build_info name> typename
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006554 detail::param_traits<detail::cl_program_build_info, name>::param_type
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006555 getBuildInfo(const Device& device, cl_int* err = nullptr) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006556 {
6557 typename detail::param_traits<
6558 detail::cl_program_build_info, name>::param_type param;
6559 cl_int result = getBuildInfo(device, name, &param);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006560 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006561 *err = result;
6562 }
6563 return param;
6564 }
6565
6566 /**
6567 * Build info function that returns a vector of device/info pairs for the specified
6568 * info type and for all devices in the program.
6569 * On an error reading the info for any device, an empty vector of info will be returned.
6570 */
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00006571 template <cl_program_build_info name>
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006572 vector<std::pair<cl::Device, typename detail::param_traits<detail::cl_program_build_info, name>::param_type>>
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006573 getBuildInfo(cl_int *err = nullptr) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006574 {
6575 cl_int result = CL_SUCCESS;
6576
6577 auto devs = getInfo<CL_PROGRAM_DEVICES>(&result);
6578 vector<std::pair<cl::Device, typename detail::param_traits<detail::cl_program_build_info, name>::param_type>>
6579 devInfo;
6580
6581 // If there was an initial error from getInfo return the error
6582 if (result != CL_SUCCESS) {
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006583 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006584 *err = result;
6585 }
6586 return devInfo;
6587 }
6588
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00006589 for (const cl::Device &d : devs) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006590 typename detail::param_traits<
6591 detail::cl_program_build_info, name>::param_type param;
6592 result = getBuildInfo(d, name, &param);
6593 devInfo.push_back(
6594 std::pair<cl::Device, typename detail::param_traits<detail::cl_program_build_info, name>::param_type>
6595 (d, param));
6596 if (result != CL_SUCCESS) {
6597 // On error, leave the loop and return the error code
6598 break;
6599 }
6600 }
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006601 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006602 *err = result;
6603 }
6604 if (result != CL_SUCCESS) {
6605 devInfo.clear();
6606 }
6607 return devInfo;
6608 }
6609
6610 cl_int createKernels(vector<Kernel>* kernels)
6611 {
6612 cl_uint numKernels;
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006613 cl_int err = ::clCreateKernelsInProgram(object_, 0, nullptr, &numKernels);
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006614 if (err != CL_SUCCESS) {
6615 return detail::errHandler(err, __CREATE_KERNELS_IN_PROGRAM_ERR);
6616 }
6617
6618 vector<cl_kernel> value(numKernels);
6619
6620 err = ::clCreateKernelsInProgram(
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006621 object_, numKernels, value.data(), nullptr);
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006622 if (err != CL_SUCCESS) {
6623 return detail::errHandler(err, __CREATE_KERNELS_IN_PROGRAM_ERR);
6624 }
6625
6626 if (kernels) {
6627 kernels->resize(value.size());
6628
6629 // Assign to param, constructing with retain behaviour
6630 // to correctly capture each underlying CL object
6631 for (size_type i = 0; i < value.size(); i++) {
6632 // We do not need to retain because this kernel is being created
6633 // by the runtime
6634 (*kernels)[i] = Kernel(value[i], false);
6635 }
6636 }
6637 return CL_SUCCESS;
6638 }
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00006639
6640#if CL_HPP_TARGET_OPENCL_VERSION >= 220
6641#if defined(CL_USE_DEPRECATED_OPENCL_2_2_APIS)
6642 /*! \brief Registers a callback function to be called when destructors for
6643 * program scope global variables are complete and before the
6644 * program is released.
6645 *
6646 * Wraps clSetProgramReleaseCallback().
6647 *
6648 * Each call to this function registers the specified user callback function
6649 * on a callback stack associated with program. The registered user callback
6650 * functions are called in the reverse order in which they were registered.
6651 */
6652 CL_API_PREFIX__VERSION_2_2_DEPRECATED cl_int setReleaseCallback(
6653 void (CL_CALLBACK * pfn_notify)(cl_program program, void * user_data),
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006654 void * user_data = nullptr) CL_API_SUFFIX__VERSION_2_2_DEPRECATED
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00006655 {
6656 return detail::errHandler(
6657 ::clSetProgramReleaseCallback(
6658 object_,
6659 pfn_notify,
6660 user_data),
6661 __SET_PROGRAM_RELEASE_CALLBACK_ERR);
6662 }
6663#endif // #if defined(CL_USE_DEPRECATED_OPENCL_2_2_APIS)
6664
6665 /*! \brief Sets a SPIR-V specialization constant.
6666 *
6667 * Wraps clSetProgramSpecializationConstant().
6668 */
6669 template <typename T>
6670 typename std::enable_if<!std::is_pointer<T>::value, cl_int>::type
6671 setSpecializationConstant(cl_uint index, const T &value)
6672 {
6673 return detail::errHandler(
6674 ::clSetProgramSpecializationConstant(
6675 object_,
6676 index,
6677 sizeof(value),
6678 &value),
6679 __SET_PROGRAM_SPECIALIZATION_CONSTANT_ERR);
6680 }
6681
6682 /*! \brief Sets a SPIR-V specialization constant.
6683 *
6684 * Wraps clSetProgramSpecializationConstant().
6685 */
6686 cl_int setSpecializationConstant(cl_uint index, size_type size, const void* value)
6687 {
6688 return detail::errHandler(
6689 ::clSetProgramSpecializationConstant(
6690 object_,
6691 index,
6692 size,
6693 value),
6694 __SET_PROGRAM_SPECIALIZATION_CONSTANT_ERR);
6695 }
6696#endif // CL_HPP_TARGET_OPENCL_VERSION >= 220
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006697};
6698
6699#if CL_HPP_TARGET_OPENCL_VERSION >= 120
6700inline Program linkProgram(
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006701 const Program& input1,
6702 const Program& input2,
6703 const char* options = nullptr,
6704 void (CL_CALLBACK * notifyFptr)(cl_program, void *) = nullptr,
6705 void* data = nullptr,
6706 cl_int* err = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006707{
6708 cl_int error_local = CL_SUCCESS;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006709 cl_program programs[2] = { input1(), input2() };
6710
6711 Context ctx = input1.getInfo<CL_PROGRAM_CONTEXT>(&error_local);
6712 if(error_local!=CL_SUCCESS) {
6713 detail::errHandler(error_local, __LINK_PROGRAM_ERR);
6714 }
6715
6716 cl_program prog = ::clLinkProgram(
6717 ctx(),
6718 0,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006719 nullptr,
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006720 options,
6721 2,
6722 programs,
6723 notifyFptr,
6724 data,
6725 &error_local);
6726
6727 detail::errHandler(error_local,__COMPILE_PROGRAM_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006728 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006729 *err = error_local;
6730 }
6731
6732 return Program(prog);
6733}
6734
6735inline Program linkProgram(
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006736 const vector<Program>& inputPrograms,
6737 const char* options = nullptr,
6738 void (CL_CALLBACK * notifyFptr)(cl_program, void *) = nullptr,
6739 void* data = nullptr,
6740 cl_int* err = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006741{
6742 cl_int error_local = CL_SUCCESS;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006743 Context ctx;
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006744
6745 static_assert(sizeof(cl::Program) == sizeof(cl_program),
6746 "Size of cl::Program must be equal to size of cl_program");
6747
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006748 if(inputPrograms.size() > 0) {
6749 ctx = inputPrograms[0].getInfo<CL_PROGRAM_CONTEXT>(&error_local);
6750 if(error_local!=CL_SUCCESS) {
6751 detail::errHandler(error_local, __LINK_PROGRAM_ERR);
6752 }
6753 }
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006754
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006755 cl_program prog = ::clLinkProgram(
6756 ctx(),
6757 0,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006758 nullptr,
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006759 options,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006760 static_cast<cl_uint>(inputPrograms.size()),
6761 reinterpret_cast<const cl_program *>(inputPrograms.data()),
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006762 notifyFptr,
6763 data,
6764 &error_local);
6765
6766 detail::errHandler(error_local,__COMPILE_PROGRAM_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006767 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006768 *err = error_local;
6769 }
6770
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006771 return Program(prog);
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006772}
6773#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
6774
6775// Template specialization for CL_PROGRAM_BINARIES
6776template <>
6777inline cl_int cl::Program::getInfo(cl_program_info name, vector<vector<unsigned char>>* param) const
6778{
6779 if (name != CL_PROGRAM_BINARIES) {
6780 return CL_INVALID_VALUE;
6781 }
6782 if (param) {
6783 // Resize the parameter array appropriately for each allocation
6784 // and pass down to the helper
6785
6786 vector<size_type> sizes = getInfo<CL_PROGRAM_BINARY_SIZES>();
6787 size_type numBinaries = sizes.size();
6788
6789 // Resize the parameter array and constituent arrays
6790 param->resize(numBinaries);
Anthony Barbier8b2fdc92018-08-09 11:42:38 +01006791 for (size_type i = 0; i < numBinaries; ++i) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006792 (*param)[i].resize(sizes[i]);
6793 }
6794
6795 return detail::errHandler(
6796 detail::getInfo(&::clGetProgramInfo, object_, name, param),
6797 __GET_PROGRAM_INFO_ERR);
6798 }
6799
6800 return CL_SUCCESS;
6801}
6802
6803template<>
6804inline vector<vector<unsigned char>> cl::Program::getInfo<CL_PROGRAM_BINARIES>(cl_int* err) const
6805{
6806 vector<vector<unsigned char>> binariesVectors;
6807
6808 cl_int result = getInfo(CL_PROGRAM_BINARIES, &binariesVectors);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006809 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006810 *err = result;
6811 }
6812 return binariesVectors;
6813}
6814
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00006815#if CL_HPP_TARGET_OPENCL_VERSION >= 220
6816// Template specialization for clSetProgramSpecializationConstant
6817template <>
6818inline cl_int cl::Program::setSpecializationConstant(cl_uint index, const bool &value)
6819{
6820 cl_uchar ucValue = value ? CL_UCHAR_MAX : 0;
6821 return detail::errHandler(
6822 ::clSetProgramSpecializationConstant(
6823 object_,
6824 index,
6825 sizeof(ucValue),
6826 &ucValue),
6827 __SET_PROGRAM_SPECIALIZATION_CONSTANT_ERR);
6828}
6829#endif // CL_HPP_TARGET_OPENCL_VERSION >= 220
6830
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006831inline Kernel::Kernel(const Program& program, const char* name, cl_int* err)
6832{
6833 cl_int error;
6834
6835 object_ = ::clCreateKernel(program(), name, &error);
6836 detail::errHandler(error, __CREATE_KERNEL_ERR);
6837
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006838 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006839 *err = error;
6840 }
6841
6842}
6843
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006844#ifdef cl_khr_external_memory
6845enum class ExternalMemoryType : cl_external_memory_handle_type_khr
6846{
6847 None = 0,
6848
6849 OpaqueFd = CL_EXTERNAL_MEMORY_HANDLE_OPAQUE_FD_KHR,
6850 OpaqueWin32 = CL_EXTERNAL_MEMORY_HANDLE_OPAQUE_WIN32_KHR,
6851 OpaqueWin32Kmt = CL_EXTERNAL_MEMORY_HANDLE_OPAQUE_WIN32_KMT_KHR,
6852
6853 D3D11Texture = CL_EXTERNAL_MEMORY_HANDLE_D3D11_TEXTURE_KHR,
6854 D3D11TextureKmt = CL_EXTERNAL_MEMORY_HANDLE_D3D11_TEXTURE_KMT_KHR,
6855
6856 D3D12Heap = CL_EXTERNAL_MEMORY_HANDLE_D3D12_HEAP_KHR,
6857 D3D12Resource = CL_EXTERNAL_MEMORY_HANDLE_D3D12_RESOURCE_KHR,
6858
6859 DmaBuf = CL_EXTERNAL_MEMORY_HANDLE_DMA_BUF_KHR,
6860};
6861#endif
6862
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006863enum class QueueProperties : cl_command_queue_properties
6864{
6865 None = 0,
6866 Profiling = CL_QUEUE_PROFILING_ENABLE,
6867 OutOfOrder = CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE,
6868};
6869
6870inline QueueProperties operator|(QueueProperties lhs, QueueProperties rhs)
6871{
6872 return static_cast<QueueProperties>(static_cast<cl_command_queue_properties>(lhs) | static_cast<cl_command_queue_properties>(rhs));
6873}
6874
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006875inline QueueProperties operator&(QueueProperties lhs, QueueProperties rhs)
6876{
6877 return static_cast<QueueProperties>(static_cast<cl_command_queue_properties>(lhs) & static_cast<cl_command_queue_properties>(rhs));
6878}
6879
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006880/*! \class CommandQueue
6881 * \brief CommandQueue interface for cl_command_queue.
6882 */
6883class CommandQueue : public detail::Wrapper<cl_command_queue>
6884{
6885private:
6886 static std::once_flag default_initialized_;
6887 static CommandQueue default_;
6888 static cl_int default_error_;
6889
6890 /*! \brief Create the default command queue returned by @ref getDefault.
6891 *
6892 * It sets default_error_ to indicate success or failure. It does not throw
6893 * @c cl::Error.
6894 */
6895 static void makeDefault()
6896 {
6897 /* We don't want to throw an error from this function, so we have to
6898 * catch and set the error flag.
6899 */
6900#if defined(CL_HPP_ENABLE_EXCEPTIONS)
6901 try
6902#endif
6903 {
6904 int error;
6905 Context context = Context::getDefault(&error);
6906
6907 if (error != CL_SUCCESS) {
6908 default_error_ = error;
6909 }
6910 else {
6911 Device device = Device::getDefault();
6912 default_ = CommandQueue(context, device, 0, &default_error_);
6913 }
6914 }
6915#if defined(CL_HPP_ENABLE_EXCEPTIONS)
6916 catch (cl::Error &e) {
6917 default_error_ = e.err();
6918 }
6919#endif
6920 }
6921
6922 /*! \brief Create the default command queue.
6923 *
6924 * This sets @c default_. It does not throw
6925 * @c cl::Error.
6926 */
6927 static void makeDefaultProvided(const CommandQueue &c) {
6928 default_ = c;
6929 }
6930
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006931#ifdef cl_khr_external_memory
6932 static std::once_flag ext_memory_initialized_;
6933
6934 static void initMemoryExtension(const cl::Device& device)
6935 {
6936 auto platform = device.getInfo<CL_DEVICE_PLATFORM>();
6937
6938 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clEnqueueAcquireExternalMemObjectsKHR);
6939 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clEnqueueReleaseExternalMemObjectsKHR);
6940
6941 if ((pfn_clEnqueueAcquireExternalMemObjectsKHR == nullptr)
6942 && (pfn_clEnqueueReleaseExternalMemObjectsKHR == nullptr))
6943 {
6944 detail::errHandler(CL_INVALID_VALUE, __ENQUEUE_ACQUIRE_EXTERNAL_MEMORY_ERR);
6945 }
6946 }
6947#endif // cl_khr_external_memory
6948
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006949public:
6950#ifdef CL_HPP_UNIT_TEST_ENABLE
6951 /*! \brief Reset the default.
6952 *
6953 * This sets @c default_ to an empty value to support cleanup in
6954 * the unit test framework.
6955 * This function is not thread safe.
6956 */
6957 static void unitTestClearDefault() {
6958 default_ = CommandQueue();
6959 }
6960#endif // #ifdef CL_HPP_UNIT_TEST_ENABLE
6961
6962
6963 /*!
6964 * \brief Constructs a CommandQueue based on passed properties.
6965 * Will return an CL_INVALID_QUEUE_PROPERTIES error if CL_QUEUE_ON_DEVICE is specified.
6966 */
6967 CommandQueue(
6968 cl_command_queue_properties properties,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006969 cl_int* err = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006970 {
6971 cl_int error;
6972
6973 Context context = Context::getDefault(&error);
6974 detail::errHandler(error, __CREATE_CONTEXT_ERR);
6975
6976 if (error != CL_SUCCESS) {
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01006977 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006978 *err = error;
6979 }
6980 }
6981 else {
6982 Device device = context.getInfo<CL_CONTEXT_DEVICES>()[0];
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00006983 bool useWithProperties;
6984
6985#if CL_HPP_TARGET_OPENCL_VERSION >= 200 && CL_HPP_MINIMUM_OPENCL_VERSION < 200
6986 // Run-time decision based on the actual platform
6987 {
6988 cl_uint version = detail::getContextPlatformVersion(context());
6989 useWithProperties = (version >= 0x20000); // OpenCL 2.0 or above
6990 }
6991#elif CL_HPP_TARGET_OPENCL_VERSION >= 200
6992 useWithProperties = true;
6993#else
6994 useWithProperties = false;
6995#endif
Anthony Barbier6ff3b192017-09-04 18:44:23 +01006996
6997#if CL_HPP_TARGET_OPENCL_VERSION >= 200
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00006998 if (useWithProperties) {
6999 cl_queue_properties queue_properties[] = {
7000 CL_QUEUE_PROPERTIES, properties, 0 };
7001 if ((properties & CL_QUEUE_ON_DEVICE) == 0) {
7002 object_ = ::clCreateCommandQueueWithProperties(
7003 context(), device(), queue_properties, &error);
7004 }
7005 else {
7006 error = CL_INVALID_QUEUE_PROPERTIES;
7007 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007008
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00007009 detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007010 if (err != nullptr) {
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00007011 *err = error;
7012 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007013 }
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00007014#endif // CL_HPP_TARGET_OPENCL_VERSION >= 200
7015#if CL_HPP_MINIMUM_OPENCL_VERSION < 200
7016 if (!useWithProperties) {
7017 object_ = ::clCreateCommandQueue(
7018 context(), device(), properties, &error);
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007019
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00007020 detail::errHandler(error, __CREATE_COMMAND_QUEUE_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007021 if (err != nullptr) {
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00007022 *err = error;
7023 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007024 }
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00007025#endif // CL_HPP_MINIMUM_OPENCL_VERSION < 200
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007026 }
7027 }
7028
7029 /*!
7030 * \brief Constructs a CommandQueue based on passed properties.
7031 * Will return an CL_INVALID_QUEUE_PROPERTIES error if CL_QUEUE_ON_DEVICE is specified.
7032 */
7033 CommandQueue(
7034 QueueProperties properties,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007035 cl_int* err = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007036 {
7037 cl_int error;
7038
7039 Context context = Context::getDefault(&error);
7040 detail::errHandler(error, __CREATE_CONTEXT_ERR);
7041
7042 if (error != CL_SUCCESS) {
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007043 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007044 *err = error;
7045 }
7046 }
7047 else {
7048 Device device = context.getInfo<CL_CONTEXT_DEVICES>()[0];
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00007049 bool useWithProperties;
7050
7051#if CL_HPP_TARGET_OPENCL_VERSION >= 200 && CL_HPP_MINIMUM_OPENCL_VERSION < 200
7052 // Run-time decision based on the actual platform
7053 {
7054 cl_uint version = detail::getContextPlatformVersion(context());
7055 useWithProperties = (version >= 0x20000); // OpenCL 2.0 or above
7056 }
7057#elif CL_HPP_TARGET_OPENCL_VERSION >= 200
7058 useWithProperties = true;
7059#else
7060 useWithProperties = false;
7061#endif
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007062
7063#if CL_HPP_TARGET_OPENCL_VERSION >= 200
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00007064 if (useWithProperties) {
7065 cl_queue_properties queue_properties[] = {
7066 CL_QUEUE_PROPERTIES, static_cast<cl_queue_properties>(properties), 0 };
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007067
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00007068 object_ = ::clCreateCommandQueueWithProperties(
7069 context(), device(), queue_properties, &error);
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007070
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00007071 detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007072 if (err != nullptr) {
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00007073 *err = error;
7074 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007075 }
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00007076#endif // CL_HPP_TARGET_OPENCL_VERSION >= 200
7077#if CL_HPP_MINIMUM_OPENCL_VERSION < 200
7078 if (!useWithProperties) {
7079 object_ = ::clCreateCommandQueue(
7080 context(), device(), static_cast<cl_command_queue_properties>(properties), &error);
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007081
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00007082 detail::errHandler(error, __CREATE_COMMAND_QUEUE_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007083 if (err != nullptr) {
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00007084 *err = error;
7085 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007086 }
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00007087#endif // CL_HPP_MINIMUM_OPENCL_VERSION < 200
7088
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007089 }
7090 }
7091
7092 /*!
7093 * \brief Constructs a CommandQueue for an implementation defined device in the given context
7094 * Will return an CL_INVALID_QUEUE_PROPERTIES error if CL_QUEUE_ON_DEVICE is specified.
7095 */
7096 explicit CommandQueue(
7097 const Context& context,
7098 cl_command_queue_properties properties = 0,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007099 cl_int* err = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007100 {
7101 cl_int error;
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00007102 bool useWithProperties;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007103 vector<cl::Device> devices;
7104 error = context.getInfo(CL_CONTEXT_DEVICES, &devices);
7105
7106 detail::errHandler(error, __CREATE_CONTEXT_ERR);
7107
7108 if (error != CL_SUCCESS)
7109 {
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007110 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007111 *err = error;
7112 }
7113 return;
7114 }
7115
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00007116#if CL_HPP_TARGET_OPENCL_VERSION >= 200 && CL_HPP_MINIMUM_OPENCL_VERSION < 200
7117 // Run-time decision based on the actual platform
7118 {
7119 cl_uint version = detail::getContextPlatformVersion(context());
7120 useWithProperties = (version >= 0x20000); // OpenCL 2.0 or above
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007121 }
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00007122#elif CL_HPP_TARGET_OPENCL_VERSION >= 200
7123 useWithProperties = true;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007124#else
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00007125 useWithProperties = false;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007126#endif
7127
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00007128#if CL_HPP_TARGET_OPENCL_VERSION >= 200
7129 if (useWithProperties) {
7130 cl_queue_properties queue_properties[] = {
7131 CL_QUEUE_PROPERTIES, properties, 0 };
7132 if ((properties & CL_QUEUE_ON_DEVICE) == 0) {
7133 object_ = ::clCreateCommandQueueWithProperties(
7134 context(), devices[0](), queue_properties, &error);
7135 }
7136 else {
7137 error = CL_INVALID_QUEUE_PROPERTIES;
7138 }
7139
7140 detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007141 if (err != nullptr) {
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00007142 *err = error;
7143 }
7144 }
7145#endif // CL_HPP_TARGET_OPENCL_VERSION >= 200
7146#if CL_HPP_MINIMUM_OPENCL_VERSION < 200
7147 if (!useWithProperties) {
7148 object_ = ::clCreateCommandQueue(
7149 context(), devices[0](), properties, &error);
7150
7151 detail::errHandler(error, __CREATE_COMMAND_QUEUE_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007152 if (err != nullptr) {
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00007153 *err = error;
7154 }
7155 }
7156#endif // CL_HPP_MINIMUM_OPENCL_VERSION < 200
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007157 }
7158
7159 /*!
7160 * \brief Constructs a CommandQueue for an implementation defined device in the given context
7161 * Will return an CL_INVALID_QUEUE_PROPERTIES error if CL_QUEUE_ON_DEVICE is specified.
7162 */
7163 explicit CommandQueue(
7164 const Context& context,
7165 QueueProperties properties,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007166 cl_int* err = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007167 {
7168 cl_int error;
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00007169 bool useWithProperties;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007170 vector<cl::Device> devices;
7171 error = context.getInfo(CL_CONTEXT_DEVICES, &devices);
7172
7173 detail::errHandler(error, __CREATE_CONTEXT_ERR);
7174
7175 if (error != CL_SUCCESS)
7176 {
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007177 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007178 *err = error;
7179 }
7180 return;
7181 }
7182
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00007183#if CL_HPP_TARGET_OPENCL_VERSION >= 200 && CL_HPP_MINIMUM_OPENCL_VERSION < 200
7184 // Run-time decision based on the actual platform
7185 {
7186 cl_uint version = detail::getContextPlatformVersion(context());
7187 useWithProperties = (version >= 0x20000); // OpenCL 2.0 or above
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007188 }
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00007189#elif CL_HPP_TARGET_OPENCL_VERSION >= 200
7190 useWithProperties = true;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007191#else
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00007192 useWithProperties = false;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007193#endif
7194
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00007195#if CL_HPP_TARGET_OPENCL_VERSION >= 200
7196 if (useWithProperties) {
7197 cl_queue_properties queue_properties[] = {
7198 CL_QUEUE_PROPERTIES, static_cast<cl_queue_properties>(properties), 0 };
7199 object_ = ::clCreateCommandQueueWithProperties(
7200 context(), devices[0](), queue_properties, &error);
7201
7202 detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007203 if (err != nullptr) {
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00007204 *err = error;
7205 }
7206 }
7207#endif // CL_HPP_TARGET_OPENCL_VERSION >= 200
7208#if CL_HPP_MINIMUM_OPENCL_VERSION < 200
7209 if (!useWithProperties) {
7210 object_ = ::clCreateCommandQueue(
7211 context(), devices[0](), static_cast<cl_command_queue_properties>(properties), &error);
7212
7213 detail::errHandler(error, __CREATE_COMMAND_QUEUE_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007214 if (err != nullptr) {
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00007215 *err = error;
7216 }
7217 }
7218#endif // CL_HPP_MINIMUM_OPENCL_VERSION < 200
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007219 }
7220
7221 /*!
7222 * \brief Constructs a CommandQueue for a passed device and context
7223 * Will return an CL_INVALID_QUEUE_PROPERTIES error if CL_QUEUE_ON_DEVICE is specified.
7224 */
7225 CommandQueue(
7226 const Context& context,
7227 const Device& device,
7228 cl_command_queue_properties properties = 0,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007229 cl_int* err = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007230 {
7231 cl_int error;
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00007232 bool useWithProperties;
7233
7234#if CL_HPP_TARGET_OPENCL_VERSION >= 200 && CL_HPP_MINIMUM_OPENCL_VERSION < 200
7235 // Run-time decision based on the actual platform
7236 {
7237 cl_uint version = detail::getContextPlatformVersion(context());
7238 useWithProperties = (version >= 0x20000); // OpenCL 2.0 or above
7239 }
7240#elif CL_HPP_TARGET_OPENCL_VERSION >= 200
7241 useWithProperties = true;
7242#else
7243 useWithProperties = false;
7244#endif
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007245
7246#if CL_HPP_TARGET_OPENCL_VERSION >= 200
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00007247 if (useWithProperties) {
7248 cl_queue_properties queue_properties[] = {
7249 CL_QUEUE_PROPERTIES, properties, 0 };
7250 object_ = ::clCreateCommandQueueWithProperties(
7251 context(), device(), queue_properties, &error);
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007252
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00007253 detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007254 if (err != nullptr) {
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00007255 *err = error;
7256 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007257 }
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00007258#endif // CL_HPP_TARGET_OPENCL_VERSION >= 200
7259#if CL_HPP_MINIMUM_OPENCL_VERSION < 200
7260 if (!useWithProperties) {
7261 object_ = ::clCreateCommandQueue(
7262 context(), device(), properties, &error);
7263
7264 detail::errHandler(error, __CREATE_COMMAND_QUEUE_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007265 if (err != nullptr) {
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00007266 *err = error;
7267 }
7268 }
7269#endif // CL_HPP_MINIMUM_OPENCL_VERSION < 200
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007270 }
7271
7272 /*!
7273 * \brief Constructs a CommandQueue for a passed device and context
7274 * Will return an CL_INVALID_QUEUE_PROPERTIES error if CL_QUEUE_ON_DEVICE is specified.
7275 */
7276 CommandQueue(
7277 const Context& context,
7278 const Device& device,
7279 QueueProperties properties,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007280 cl_int* err = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007281 {
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00007282 cl_int error;
7283 bool useWithProperties;
7284
7285#if CL_HPP_TARGET_OPENCL_VERSION >= 200 && CL_HPP_MINIMUM_OPENCL_VERSION < 200
7286 // Run-time decision based on the actual platform
7287 {
7288 cl_uint version = detail::getContextPlatformVersion(context());
7289 useWithProperties = (version >= 0x20000); // OpenCL 2.0 or above
7290 }
7291#elif CL_HPP_TARGET_OPENCL_VERSION >= 200
7292 useWithProperties = true;
7293#else
7294 useWithProperties = false;
7295#endif
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007296
7297#if CL_HPP_TARGET_OPENCL_VERSION >= 200
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00007298 if (useWithProperties) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007299 cl_queue_properties queue_properties[] = {
7300 CL_QUEUE_PROPERTIES, static_cast<cl_queue_properties>(properties), 0 };
7301 object_ = ::clCreateCommandQueueWithProperties(
7302 context(), device(), queue_properties, &error);
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00007303
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007304 detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007305 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007306 *err = error;
7307 }
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00007308 }
7309#endif // CL_HPP_TARGET_OPENCL_VERSION >= 200
7310#if CL_HPP_MINIMUM_OPENCL_VERSION < 200
7311 if (!useWithProperties) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007312 object_ = ::clCreateCommandQueue(
7313 context(), device(), static_cast<cl_command_queue_properties>(properties), &error);
7314
7315 detail::errHandler(error, __CREATE_COMMAND_QUEUE_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007316 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007317 *err = error;
7318 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007319 }
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00007320#endif // CL_HPP_MINIMUM_OPENCL_VERSION < 200
7321 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007322
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007323 static CommandQueue getDefault(cl_int * err = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007324 {
7325 std::call_once(default_initialized_, makeDefault);
7326#if CL_HPP_TARGET_OPENCL_VERSION >= 200
7327 detail::errHandler(default_error_, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR);
7328#else // CL_HPP_TARGET_OPENCL_VERSION >= 200
7329 detail::errHandler(default_error_, __CREATE_COMMAND_QUEUE_ERR);
7330#endif // CL_HPP_TARGET_OPENCL_VERSION >= 200
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007331 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007332 *err = default_error_;
7333 }
7334 return default_;
7335 }
7336
7337 /**
7338 * Modify the default command queue to be used by
7339 * subsequent operations.
7340 * Will only set the default if no default was previously created.
7341 * @return updated default command queue.
7342 * Should be compared to the passed value to ensure that it was updated.
7343 */
7344 static CommandQueue setDefault(const CommandQueue &default_queue)
7345 {
7346 std::call_once(default_initialized_, makeDefaultProvided, std::cref(default_queue));
7347 detail::errHandler(default_error_);
7348 return default_;
7349 }
7350
7351 CommandQueue() { }
7352
7353
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00007354 /*! \brief Constructor from cl_command_queue - takes ownership.
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007355 *
7356 * \param retainObject will cause the constructor to retain its cl object.
7357 * Defaults to false to maintain compatibility with
7358 * earlier versions.
7359 */
7360 explicit CommandQueue(const cl_command_queue& commandQueue, bool retainObject = false) :
7361 detail::Wrapper<cl_type>(commandQueue, retainObject) { }
7362
7363 CommandQueue& operator = (const cl_command_queue& rhs)
7364 {
7365 detail::Wrapper<cl_type>::operator=(rhs);
7366 return *this;
7367 }
7368
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007369 template <typename T>
7370 cl_int getInfo(cl_command_queue_info name, T* param) const
7371 {
7372 return detail::errHandler(
7373 detail::getInfo(
7374 &::clGetCommandQueueInfo, object_, name, param),
7375 __GET_COMMAND_QUEUE_INFO_ERR);
7376 }
7377
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00007378 template <cl_command_queue_info name> typename
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007379 detail::param_traits<detail::cl_command_queue_info, name>::param_type
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007380 getInfo(cl_int* err = nullptr) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007381 {
7382 typename detail::param_traits<
7383 detail::cl_command_queue_info, name>::param_type param;
7384 cl_int result = getInfo(name, &param);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007385 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007386 *err = result;
7387 }
7388 return param;
7389 }
7390
7391 cl_int enqueueReadBuffer(
7392 const Buffer& buffer,
7393 cl_bool blocking,
7394 size_type offset,
7395 size_type size,
7396 void* ptr,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007397 const vector<Event>* events = nullptr,
7398 Event* event = nullptr) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007399 {
7400 cl_event tmp;
7401 cl_int err = detail::errHandler(
7402 ::clEnqueueReadBuffer(
7403 object_, buffer(), blocking, offset, size,
7404 ptr,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007405 (events != nullptr) ? (cl_uint) events->size() : 0,
7406 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
7407 (event != nullptr) ? &tmp : nullptr),
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007408 __ENQUEUE_READ_BUFFER_ERR);
7409
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007410 if (event != nullptr && err == CL_SUCCESS)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007411 *event = tmp;
7412
7413 return err;
7414 }
7415
7416 cl_int enqueueWriteBuffer(
7417 const Buffer& buffer,
7418 cl_bool blocking,
7419 size_type offset,
7420 size_type size,
7421 const void* ptr,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007422 const vector<Event>* events = nullptr,
7423 Event* event = nullptr) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007424 {
7425 cl_event tmp;
7426 cl_int err = detail::errHandler(
7427 ::clEnqueueWriteBuffer(
7428 object_, buffer(), blocking, offset, size,
7429 ptr,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007430 (events != nullptr) ? (cl_uint) events->size() : 0,
7431 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
7432 (event != nullptr) ? &tmp : nullptr),
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007433 __ENQUEUE_WRITE_BUFFER_ERR);
7434
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007435 if (event != nullptr && err == CL_SUCCESS)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007436 *event = tmp;
7437
7438 return err;
7439 }
7440
7441 cl_int enqueueCopyBuffer(
7442 const Buffer& src,
7443 const Buffer& dst,
7444 size_type src_offset,
7445 size_type dst_offset,
7446 size_type size,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007447 const vector<Event>* events = nullptr,
7448 Event* event = nullptr) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007449 {
7450 cl_event tmp;
7451 cl_int err = detail::errHandler(
7452 ::clEnqueueCopyBuffer(
7453 object_, src(), dst(), src_offset, dst_offset, size,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007454 (events != nullptr) ? (cl_uint) events->size() : 0,
7455 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
7456 (event != nullptr) ? &tmp : nullptr),
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007457 __ENQEUE_COPY_BUFFER_ERR);
7458
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007459 if (event != nullptr && err == CL_SUCCESS)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007460 *event = tmp;
7461
7462 return err;
7463 }
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00007464#if CL_HPP_TARGET_OPENCL_VERSION >= 110
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007465 cl_int enqueueReadBufferRect(
7466 const Buffer& buffer,
7467 cl_bool blocking,
7468 const array<size_type, 3>& buffer_offset,
7469 const array<size_type, 3>& host_offset,
7470 const array<size_type, 3>& region,
7471 size_type buffer_row_pitch,
7472 size_type buffer_slice_pitch,
7473 size_type host_row_pitch,
7474 size_type host_slice_pitch,
7475 void *ptr,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007476 const vector<Event>* events = nullptr,
7477 Event* event = nullptr) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007478 {
7479 cl_event tmp;
7480 cl_int err = detail::errHandler(
7481 ::clEnqueueReadBufferRect(
7482 object_,
7483 buffer(),
7484 blocking,
7485 buffer_offset.data(),
7486 host_offset.data(),
7487 region.data(),
7488 buffer_row_pitch,
7489 buffer_slice_pitch,
7490 host_row_pitch,
7491 host_slice_pitch,
7492 ptr,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007493 (events != nullptr) ? (cl_uint) events->size() : 0,
7494 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
7495 (event != nullptr) ? &tmp : nullptr),
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007496 __ENQUEUE_READ_BUFFER_RECT_ERR);
7497
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007498 if (event != nullptr && err == CL_SUCCESS)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007499 *event = tmp;
7500
7501 return err;
7502 }
7503
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007504 cl_int enqueueReadBufferRect(
7505 const Buffer& buffer,
7506 cl_bool blocking,
7507 const array<size_type, 2>& buffer_offset,
7508 const array<size_type, 2>& host_offset,
7509 const array<size_type, 2>& region,
7510 size_type buffer_row_pitch,
7511 size_type buffer_slice_pitch,
7512 size_type host_row_pitch,
7513 size_type host_slice_pitch,
7514 void* ptr,
7515 const vector<Event>* events = nullptr,
7516 Event* event = nullptr) const
7517 {
7518 return enqueueReadBufferRect(
7519 buffer,
7520 blocking,
7521 { buffer_offset[0], buffer_offset[1], 0 },
7522 { host_offset[0], host_offset[1], 0 },
7523 { region[0], region[1], 1 },
7524 buffer_row_pitch,
7525 buffer_slice_pitch,
7526 host_row_pitch,
7527 host_slice_pitch,
7528 ptr,
7529 events,
7530 event);
7531 }
7532
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007533 cl_int enqueueWriteBufferRect(
7534 const Buffer& buffer,
7535 cl_bool blocking,
7536 const array<size_type, 3>& buffer_offset,
7537 const array<size_type, 3>& host_offset,
7538 const array<size_type, 3>& region,
7539 size_type buffer_row_pitch,
7540 size_type buffer_slice_pitch,
7541 size_type host_row_pitch,
7542 size_type host_slice_pitch,
Anthony Barbier8b2fdc92018-08-09 11:42:38 +01007543 const void *ptr,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007544 const vector<Event>* events = nullptr,
7545 Event* event = nullptr) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007546 {
7547 cl_event tmp;
7548 cl_int err = detail::errHandler(
7549 ::clEnqueueWriteBufferRect(
7550 object_,
7551 buffer(),
7552 blocking,
7553 buffer_offset.data(),
7554 host_offset.data(),
7555 region.data(),
7556 buffer_row_pitch,
7557 buffer_slice_pitch,
7558 host_row_pitch,
7559 host_slice_pitch,
7560 ptr,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007561 (events != nullptr) ? (cl_uint) events->size() : 0,
7562 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
7563 (event != nullptr) ? &tmp : nullptr),
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007564 __ENQUEUE_WRITE_BUFFER_RECT_ERR);
7565
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007566 if (event != nullptr && err == CL_SUCCESS)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007567 *event = tmp;
7568
7569 return err;
7570 }
7571
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007572 cl_int enqueueWriteBufferRect(
7573 const Buffer& buffer,
7574 cl_bool blocking,
7575 const array<size_type, 2>& buffer_offset,
7576 const array<size_type, 2>& host_offset,
7577 const array<size_type, 2>& region,
7578 size_type buffer_row_pitch,
7579 size_type buffer_slice_pitch,
7580 size_type host_row_pitch,
7581 size_type host_slice_pitch,
7582 const void* ptr,
7583 const vector<Event>* events = nullptr,
7584 Event* event = nullptr) const
7585 {
7586 return enqueueWriteBufferRect(
7587 buffer,
7588 blocking,
7589 { buffer_offset[0], buffer_offset[1], 0 },
7590 { host_offset[0], host_offset[1], 0 },
7591 { region[0], region[1], 1 },
7592 buffer_row_pitch,
7593 buffer_slice_pitch,
7594 host_row_pitch,
7595 host_slice_pitch,
7596 ptr,
7597 events,
7598 event);
7599 }
7600
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007601 cl_int enqueueCopyBufferRect(
7602 const Buffer& src,
7603 const Buffer& dst,
7604 const array<size_type, 3>& src_origin,
7605 const array<size_type, 3>& dst_origin,
7606 const array<size_type, 3>& region,
7607 size_type src_row_pitch,
7608 size_type src_slice_pitch,
7609 size_type dst_row_pitch,
7610 size_type dst_slice_pitch,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007611 const vector<Event>* events = nullptr,
7612 Event* event = nullptr) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007613 {
7614 cl_event tmp;
7615 cl_int err = detail::errHandler(
7616 ::clEnqueueCopyBufferRect(
7617 object_,
7618 src(),
7619 dst(),
7620 src_origin.data(),
7621 dst_origin.data(),
7622 region.data(),
7623 src_row_pitch,
7624 src_slice_pitch,
7625 dst_row_pitch,
7626 dst_slice_pitch,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007627 (events != nullptr) ? (cl_uint) events->size() : 0,
7628 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
7629 (event != nullptr) ? &tmp : nullptr),
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007630 __ENQEUE_COPY_BUFFER_RECT_ERR);
7631
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007632 if (event != nullptr && err == CL_SUCCESS)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007633 *event = tmp;
7634
7635 return err;
7636 }
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007637
7638 cl_int enqueueCopyBufferRect(
7639 const Buffer& src,
7640 const Buffer& dst,
7641 const array<size_type, 2>& src_origin,
7642 const array<size_type, 2>& dst_origin,
7643 const array<size_type, 2>& region,
7644 size_type src_row_pitch,
7645 size_type src_slice_pitch,
7646 size_type dst_row_pitch,
7647 size_type dst_slice_pitch,
7648 const vector<Event>* events = nullptr,
7649 Event* event = nullptr) const
7650 {
7651 return enqueueCopyBufferRect(
7652 src,
7653 dst,
7654 { src_origin[0], src_origin[1], 0 },
7655 { dst_origin[0], dst_origin[1], 0 },
7656 { region[0], region[1], 1 },
7657 src_row_pitch,
7658 src_slice_pitch,
7659 dst_row_pitch,
7660 dst_slice_pitch,
7661 events,
7662 event);
7663 }
7664
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00007665#endif // CL_HPP_TARGET_OPENCL_VERSION >= 110
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007666#if CL_HPP_TARGET_OPENCL_VERSION >= 120
7667 /**
7668 * Enqueue a command to fill a buffer object with a pattern
7669 * of a given size. The pattern is specified as a vector type.
7670 * \tparam PatternType The datatype of the pattern field.
7671 * The pattern type must be an accepted OpenCL data type.
7672 * \tparam offset Is the offset in bytes into the buffer at
7673 * which to start filling. This must be a multiple of
7674 * the pattern size.
7675 * \tparam size Is the size in bytes of the region to fill.
7676 * This must be a multiple of the pattern size.
7677 */
7678 template<typename PatternType>
7679 cl_int enqueueFillBuffer(
7680 const Buffer& buffer,
7681 PatternType pattern,
7682 size_type offset,
7683 size_type size,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007684 const vector<Event>* events = nullptr,
7685 Event* event = nullptr) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007686 {
7687 cl_event tmp;
7688 cl_int err = detail::errHandler(
7689 ::clEnqueueFillBuffer(
7690 object_,
7691 buffer(),
7692 static_cast<void*>(&pattern),
7693 sizeof(PatternType),
7694 offset,
7695 size,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007696 (events != nullptr) ? (cl_uint) events->size() : 0,
7697 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
7698 (event != nullptr) ? &tmp : nullptr),
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007699 __ENQUEUE_FILL_BUFFER_ERR);
7700
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007701 if (event != nullptr && err == CL_SUCCESS)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007702 *event = tmp;
7703
7704 return err;
7705 }
7706#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
7707
7708 cl_int enqueueReadImage(
7709 const Image& image,
7710 cl_bool blocking,
7711 const array<size_type, 3>& origin,
7712 const array<size_type, 3>& region,
7713 size_type row_pitch,
7714 size_type slice_pitch,
7715 void* ptr,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007716 const vector<Event>* events = nullptr,
7717 Event* event = nullptr) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007718 {
7719 cl_event tmp;
7720 cl_int err = detail::errHandler(
7721 ::clEnqueueReadImage(
7722 object_,
7723 image(),
7724 blocking,
7725 origin.data(),
7726 region.data(),
7727 row_pitch,
7728 slice_pitch,
7729 ptr,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007730 (events != nullptr) ? (cl_uint) events->size() : 0,
7731 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
7732 (event != nullptr) ? &tmp : nullptr),
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007733 __ENQUEUE_READ_IMAGE_ERR);
7734
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007735 if (event != nullptr && err == CL_SUCCESS)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007736 *event = tmp;
7737
7738 return err;
7739 }
7740
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007741 cl_int enqueueReadImage(
7742 const Image& image,
7743 cl_bool blocking,
7744 const array<size_type, 2>& origin,
7745 const array<size_type, 2>& region,
7746 size_type row_pitch,
7747 size_type slice_pitch,
7748 void* ptr,
7749 const vector<Event>* events = nullptr,
7750 Event* event = nullptr) const
7751 {
7752 return enqueueReadImage(
7753 image,
7754 blocking,
7755 { origin[0], origin[1], 0 },
7756 { region[0], region[1], 1 },
7757 row_pitch,
7758 slice_pitch,
7759 ptr,
7760 events,
7761 event);
7762 }
7763
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007764 cl_int enqueueWriteImage(
7765 const Image& image,
7766 cl_bool blocking,
7767 const array<size_type, 3>& origin,
7768 const array<size_type, 3>& region,
7769 size_type row_pitch,
7770 size_type slice_pitch,
Anthony Barbier8b2fdc92018-08-09 11:42:38 +01007771 const void* ptr,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007772 const vector<Event>* events = nullptr,
7773 Event* event = nullptr) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007774 {
7775 cl_event tmp;
7776 cl_int err = detail::errHandler(
7777 ::clEnqueueWriteImage(
7778 object_,
7779 image(),
7780 blocking,
7781 origin.data(),
7782 region.data(),
7783 row_pitch,
7784 slice_pitch,
7785 ptr,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007786 (events != nullptr) ? (cl_uint) events->size() : 0,
7787 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
7788 (event != nullptr) ? &tmp : nullptr),
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007789 __ENQUEUE_WRITE_IMAGE_ERR);
7790
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007791 if (event != nullptr && err == CL_SUCCESS)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007792 *event = tmp;
7793
7794 return err;
7795 }
7796
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007797 cl_int enqueueWriteImage(
7798 const Image& image,
7799 cl_bool blocking,
7800 const array<size_type, 2>& origin,
7801 const array<size_type, 2>& region,
7802 size_type row_pitch,
7803 size_type slice_pitch,
7804 const void* ptr,
7805 const vector<Event>* events = nullptr,
7806 Event* event = nullptr) const
7807 {
7808 return enqueueWriteImage(
7809 image,
7810 blocking,
7811 { origin[0], origin[1], 0 },
7812 { region[0], region[1], 1 },
7813 row_pitch,
7814 slice_pitch,
7815 ptr,
7816 events,
7817 event);
7818 }
7819
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007820 cl_int enqueueCopyImage(
7821 const Image& src,
7822 const Image& dst,
7823 const array<size_type, 3>& src_origin,
7824 const array<size_type, 3>& dst_origin,
7825 const array<size_type, 3>& region,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007826 const vector<Event>* events = nullptr,
7827 Event* event = nullptr) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007828 {
7829 cl_event tmp;
7830 cl_int err = detail::errHandler(
7831 ::clEnqueueCopyImage(
7832 object_,
7833 src(),
7834 dst(),
7835 src_origin.data(),
7836 dst_origin.data(),
7837 region.data(),
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007838 (events != nullptr) ? (cl_uint) events->size() : 0,
7839 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
7840 (event != nullptr) ? &tmp : nullptr),
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007841 __ENQUEUE_COPY_IMAGE_ERR);
7842
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007843 if (event != nullptr && err == CL_SUCCESS)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007844 *event = tmp;
7845
7846 return err;
7847 }
7848
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007849 cl_int enqueueCopyImage(
7850 const Image& src,
7851 const Image& dst,
7852 const array<size_type, 2>& src_origin,
7853 const array<size_type, 2>& dst_origin,
7854 const array<size_type, 2>& region,
7855 const vector<Event>* events = nullptr,
7856 Event* event = nullptr) const
7857 {
7858 return enqueueCopyImage(
7859 src,
7860 dst,
7861 { src_origin[0], src_origin[1], 0 },
7862 { dst_origin[0], dst_origin[1], 0 },
7863 { region[0], region[1], 1 },
7864 events,
7865 event);
7866 }
7867
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007868#if CL_HPP_TARGET_OPENCL_VERSION >= 120
7869 /**
7870 * Enqueue a command to fill an image object with a specified color.
7871 * \param fillColor is the color to use to fill the image.
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007872 * This is a four component RGBA floating-point, signed integer
7873 * or unsigned integer color value if the image channel data
7874 * type is an unnormalized signed integer type.
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007875 */
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007876 template <typename T>
7877 typename std::enable_if<std::is_same<T, cl_float4>::value ||
7878 std::is_same<T, cl_int4 >::value ||
7879 std::is_same<T, cl_uint4 >::value,
7880 cl_int>::type
7881 enqueueFillImage(
7882 const Image& image,
7883 T fillColor,
7884 const array<size_type, 3>& origin,
7885 const array<size_type, 3>& region,
7886 const vector<Event>* events = nullptr,
7887 Event* event = nullptr) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007888 {
7889 cl_event tmp;
7890 cl_int err = detail::errHandler(
7891 ::clEnqueueFillImage(
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007892 object_,
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007893 image(),
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007894 static_cast<void*>(&fillColor),
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007895 origin.data(),
7896 region.data(),
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007897 (events != nullptr) ? (cl_uint)events->size() : 0,
7898 (events != nullptr && events->size() > 0) ? (cl_event*)&events->front() : NULL,
7899 (event != NULL) ? &tmp : nullptr),
7900 __ENQUEUE_FILL_IMAGE_ERR);
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007901
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007902 if (event != nullptr && err == CL_SUCCESS) *event = tmp;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007903
7904 return err;
7905 }
7906
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007907 /**
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007908 * Enqueue a command to fill an image object with a specified color.
7909 * \param fillColor is the color to use to fill the image.
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007910 * This is a four component RGBA floating-point, signed integer
7911 * or unsigned integer color value if the image channel data
7912 * type is an unnormalized signed integer type.
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007913 */
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007914 template <typename T>
7915 typename std::enable_if<std::is_same<T, cl_float4>::value ||
7916 std::is_same<T, cl_int4 >::value ||
7917 std::is_same<T, cl_uint4 >::value, cl_int>::type
7918 enqueueFillImage(
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007919 const Image& image,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007920 T fillColor,
7921 const array<size_type, 2>& origin,
7922 const array<size_type, 2>& region,
7923 const vector<Event>* events = nullptr,
7924 Event* event = nullptr) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007925 {
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007926 return enqueueFillImage(
7927 image,
7928 fillColor,
7929 { origin[0], origin[1], 0 },
7930 { region[0], region[1], 1 },
7931 events,
7932 event
7933 );
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007934 }
7935#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
7936
7937 cl_int enqueueCopyImageToBuffer(
7938 const Image& src,
7939 const Buffer& dst,
7940 const array<size_type, 3>& src_origin,
7941 const array<size_type, 3>& region,
7942 size_type dst_offset,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007943 const vector<Event>* events = nullptr,
7944 Event* event = nullptr) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007945 {
7946 cl_event tmp;
7947 cl_int err = detail::errHandler(
7948 ::clEnqueueCopyImageToBuffer(
7949 object_,
7950 src(),
7951 dst(),
7952 src_origin.data(),
7953 region.data(),
7954 dst_offset,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007955 (events != nullptr) ? (cl_uint) events->size() : 0,
7956 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
7957 (event != nullptr) ? &tmp : nullptr),
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007958 __ENQUEUE_COPY_IMAGE_TO_BUFFER_ERR);
7959
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007960 if (event != nullptr && err == CL_SUCCESS)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007961 *event = tmp;
7962
7963 return err;
7964 }
7965
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007966 cl_int enqueueCopyImageToBuffer(
7967 const Image& src,
7968 const Buffer& dst,
7969 const array<size_type, 2>& src_origin,
7970 const array<size_type, 2>& region,
7971 size_type dst_offset,
7972 const vector<Event>* events = nullptr,
7973 Event* event = nullptr) const
7974 {
7975 return enqueueCopyImageToBuffer(
7976 src,
7977 dst,
7978 { src_origin[0], src_origin[1], 0 },
7979 { region[0], region[1], 1 },
7980 dst_offset,
7981 events,
7982 event);
7983 }
7984
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007985 cl_int enqueueCopyBufferToImage(
7986 const Buffer& src,
7987 const Image& dst,
7988 size_type src_offset,
7989 const array<size_type, 3>& dst_origin,
7990 const array<size_type, 3>& region,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01007991 const vector<Event>* events = nullptr,
7992 Event* event = nullptr) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01007993 {
7994 cl_event tmp;
7995 cl_int err = detail::errHandler(
7996 ::clEnqueueCopyBufferToImage(
7997 object_,
7998 src(),
7999 dst(),
8000 src_offset,
8001 dst_origin.data(),
8002 region.data(),
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008003 (events != nullptr) ? (cl_uint) events->size() : 0,
8004 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
8005 (event != nullptr) ? &tmp : nullptr),
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008006 __ENQUEUE_COPY_BUFFER_TO_IMAGE_ERR);
8007
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008008 if (event != nullptr && err == CL_SUCCESS)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008009 *event = tmp;
8010
8011 return err;
8012 }
8013
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008014 cl_int enqueueCopyBufferToImage(
8015 const Buffer& src,
8016 const Image& dst,
8017 size_type src_offset,
8018 const array<size_type, 2>& dst_origin,
8019 const array<size_type, 2>& region,
8020 const vector<Event>* events = nullptr,
8021 Event* event = nullptr) const
8022 {
8023 return enqueueCopyBufferToImage(
8024 src,
8025 dst,
8026 src_offset,
8027 { dst_origin[0], dst_origin[1], 0 },
8028 { region[0], region[1], 1 },
8029 events,
8030 event);
8031 }
8032
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008033 void* enqueueMapBuffer(
8034 const Buffer& buffer,
8035 cl_bool blocking,
8036 cl_map_flags flags,
8037 size_type offset,
8038 size_type size,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008039 const vector<Event>* events = nullptr,
8040 Event* event = nullptr,
8041 cl_int* err = nullptr) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008042 {
8043 cl_event tmp;
8044 cl_int error;
8045 void * result = ::clEnqueueMapBuffer(
8046 object_, buffer(), blocking, flags, offset, size,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008047 (events != nullptr) ? (cl_uint) events->size() : 0,
8048 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
8049 (event != nullptr) ? &tmp : nullptr,
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008050 &error);
8051
8052 detail::errHandler(error, __ENQUEUE_MAP_BUFFER_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008053 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008054 *err = error;
8055 }
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008056 if (event != nullptr && error == CL_SUCCESS)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008057 *event = tmp;
8058
8059 return result;
8060 }
8061
8062 void* enqueueMapImage(
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008063 const Image& image,
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008064 cl_bool blocking,
8065 cl_map_flags flags,
8066 const array<size_type, 3>& origin,
8067 const array<size_type, 3>& region,
8068 size_type * row_pitch,
8069 size_type * slice_pitch,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008070 const vector<Event>* events = nullptr,
8071 Event* event = nullptr,
8072 cl_int* err = nullptr) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008073 {
8074 cl_event tmp;
8075 cl_int error;
8076 void * result = ::clEnqueueMapImage(
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008077 object_, image(), blocking, flags,
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008078 origin.data(),
8079 region.data(),
8080 row_pitch, slice_pitch,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008081 (events != nullptr) ? (cl_uint) events->size() : 0,
8082 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
8083 (event != nullptr) ? &tmp : nullptr,
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008084 &error);
8085
8086 detail::errHandler(error, __ENQUEUE_MAP_IMAGE_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008087 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008088 *err = error;
8089 }
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008090 if (event != nullptr && error == CL_SUCCESS)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008091 *event = tmp;
8092 return result;
8093 }
8094
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008095 void* enqueueMapImage(
8096 const Image& image,
8097 cl_bool blocking,
8098 cl_map_flags flags,
8099 const array<size_type, 2>& origin,
8100 const array<size_type, 2>& region,
8101 size_type* row_pitch,
8102 size_type* slice_pitch,
8103 const vector<Event>* events = nullptr,
8104 Event* event = nullptr,
8105 cl_int* err = nullptr) const
8106 {
8107 return enqueueMapImage(image, blocking, flags,
8108 { origin[0], origin[1], 0 },
8109 { region[0], region[1], 1 }, row_pitch,
8110 slice_pitch, events, event, err);
8111 }
8112
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008113#if CL_HPP_TARGET_OPENCL_VERSION >= 200
8114 /**
8115 * Enqueues a command that will allow the host to update a region of a coarse-grained SVM buffer.
8116 * This variant takes a raw SVM pointer.
8117 */
8118 template<typename T>
8119 cl_int enqueueMapSVM(
8120 T* ptr,
8121 cl_bool blocking,
8122 cl_map_flags flags,
8123 size_type size,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008124 const vector<Event>* events = nullptr,
8125 Event* event = nullptr) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008126 {
8127 cl_event tmp;
8128 cl_int err = detail::errHandler(::clEnqueueSVMMap(
8129 object_, blocking, flags, static_cast<void*>(ptr), size,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008130 (events != nullptr) ? (cl_uint)events->size() : 0,
8131 (events != nullptr && events->size() > 0) ? (cl_event*)&events->front() : nullptr,
8132 (event != nullptr) ? &tmp : nullptr),
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008133 __ENQUEUE_MAP_BUFFER_ERR);
8134
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008135 if (event != nullptr && err == CL_SUCCESS)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008136 *event = tmp;
8137
8138 return err;
8139 }
8140
8141
8142 /**
8143 * Enqueues a command that will allow the host to update a region of a coarse-grained SVM buffer.
8144 * This variant takes a cl::pointer instance.
8145 */
8146 template<typename T, class D>
8147 cl_int enqueueMapSVM(
8148 cl::pointer<T, D> &ptr,
8149 cl_bool blocking,
8150 cl_map_flags flags,
8151 size_type size,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008152 const vector<Event>* events = nullptr,
8153 Event* event = nullptr) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008154 {
8155 cl_event tmp;
8156 cl_int err = detail::errHandler(::clEnqueueSVMMap(
8157 object_, blocking, flags, static_cast<void*>(ptr.get()), size,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008158 (events != nullptr) ? (cl_uint)events->size() : 0,
8159 (events != nullptr && events->size() > 0) ? (cl_event*)&events->front() : nullptr,
8160 (event != nullptr) ? &tmp : nullptr),
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008161 __ENQUEUE_MAP_BUFFER_ERR);
8162
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008163 if (event != nullptr && err == CL_SUCCESS)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008164 *event = tmp;
8165
8166 return err;
8167 }
8168
8169 /**
8170 * Enqueues a command that will allow the host to update a region of a coarse-grained SVM buffer.
8171 * This variant takes a cl::vector instance.
8172 */
8173 template<typename T, class Alloc>
8174 cl_int enqueueMapSVM(
8175 cl::vector<T, Alloc> &container,
8176 cl_bool blocking,
8177 cl_map_flags flags,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008178 const vector<Event>* events = nullptr,
8179 Event* event = nullptr) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008180 {
8181 cl_event tmp;
8182 cl_int err = detail::errHandler(::clEnqueueSVMMap(
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00008183 object_, blocking, flags, static_cast<void*>(container.data()), container.size()*sizeof(T),
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008184 (events != nullptr) ? (cl_uint)events->size() : 0,
8185 (events != nullptr && events->size() > 0) ? (cl_event*)&events->front() : nullptr,
8186 (event != nullptr) ? &tmp : nullptr),
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008187 __ENQUEUE_MAP_BUFFER_ERR);
8188
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008189 if (event != nullptr && err == CL_SUCCESS)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008190 *event = tmp;
8191
8192 return err;
8193 }
8194#endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 200
8195
8196 cl_int enqueueUnmapMemObject(
8197 const Memory& memory,
8198 void* mapped_ptr,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008199 const vector<Event>* events = nullptr,
8200 Event* event = nullptr) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008201 {
8202 cl_event tmp;
8203 cl_int err = detail::errHandler(
8204 ::clEnqueueUnmapMemObject(
8205 object_, memory(), mapped_ptr,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008206 (events != nullptr) ? (cl_uint) events->size() : 0,
8207 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
8208 (event != nullptr) ? &tmp : nullptr),
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008209 __ENQUEUE_UNMAP_MEM_OBJECT_ERR);
8210
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008211 if (event != nullptr && err == CL_SUCCESS)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008212 *event = tmp;
8213
8214 return err;
8215 }
8216
8217
8218#if CL_HPP_TARGET_OPENCL_VERSION >= 200
8219 /**
8220 * Enqueues a command that will release a coarse-grained SVM buffer back to the OpenCL runtime.
8221 * This variant takes a raw SVM pointer.
8222 */
8223 template<typename T>
8224 cl_int enqueueUnmapSVM(
8225 T* ptr,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008226 const vector<Event>* events = nullptr,
8227 Event* event = nullptr) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008228 {
8229 cl_event tmp;
8230 cl_int err = detail::errHandler(
8231 ::clEnqueueSVMUnmap(
8232 object_, static_cast<void*>(ptr),
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008233 (events != nullptr) ? (cl_uint)events->size() : 0,
8234 (events != nullptr && events->size() > 0) ? (cl_event*)&events->front() : nullptr,
8235 (event != nullptr) ? &tmp : nullptr),
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008236 __ENQUEUE_UNMAP_MEM_OBJECT_ERR);
8237
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008238 if (event != nullptr && err == CL_SUCCESS)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008239 *event = tmp;
8240
8241 return err;
8242 }
8243
8244 /**
8245 * Enqueues a command that will release a coarse-grained SVM buffer back to the OpenCL runtime.
8246 * This variant takes a cl::pointer instance.
8247 */
8248 template<typename T, class D>
8249 cl_int enqueueUnmapSVM(
8250 cl::pointer<T, D> &ptr,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008251 const vector<Event>* events = nullptr,
8252 Event* event = nullptr) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008253 {
8254 cl_event tmp;
8255 cl_int err = detail::errHandler(
8256 ::clEnqueueSVMUnmap(
8257 object_, static_cast<void*>(ptr.get()),
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008258 (events != nullptr) ? (cl_uint)events->size() : 0,
8259 (events != nullptr && events->size() > 0) ? (cl_event*)&events->front() : nullptr,
8260 (event != nullptr) ? &tmp : nullptr),
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008261 __ENQUEUE_UNMAP_MEM_OBJECT_ERR);
8262
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008263 if (event != nullptr && err == CL_SUCCESS)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008264 *event = tmp;
8265
8266 return err;
8267 }
8268
8269 /**
8270 * Enqueues a command that will release a coarse-grained SVM buffer back to the OpenCL runtime.
8271 * This variant takes a cl::vector instance.
8272 */
8273 template<typename T, class Alloc>
8274 cl_int enqueueUnmapSVM(
8275 cl::vector<T, Alloc> &container,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008276 const vector<Event>* events = nullptr,
8277 Event* event = nullptr) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008278 {
8279 cl_event tmp;
8280 cl_int err = detail::errHandler(
8281 ::clEnqueueSVMUnmap(
8282 object_, static_cast<void*>(container.data()),
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008283 (events != nullptr) ? (cl_uint)events->size() : 0,
8284 (events != nullptr && events->size() > 0) ? (cl_event*)&events->front() : nullptr,
8285 (event != nullptr) ? &tmp : nullptr),
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008286 __ENQUEUE_UNMAP_MEM_OBJECT_ERR);
8287
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008288 if (event != nullptr && err == CL_SUCCESS)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008289 *event = tmp;
8290
8291 return err;
8292 }
8293#endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 200
8294
8295#if CL_HPP_TARGET_OPENCL_VERSION >= 120
8296 /**
8297 * Enqueues a marker command which waits for either a list of events to complete,
8298 * or all previously enqueued commands to complete.
8299 *
8300 * Enqueues a marker command which waits for either a list of events to complete,
8301 * or if the list is empty it waits for all commands previously enqueued in command_queue
8302 * to complete before it completes. This command returns an event which can be waited on,
8303 * i.e. this event can be waited on to insure that all events either in the event_wait_list
8304 * or all previously enqueued commands, queued before this command to command_queue,
8305 * have completed.
8306 */
8307 cl_int enqueueMarkerWithWaitList(
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008308 const vector<Event> *events = nullptr,
8309 Event *event = nullptr) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008310 {
8311 cl_event tmp;
8312 cl_int err = detail::errHandler(
8313 ::clEnqueueMarkerWithWaitList(
8314 object_,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008315 (events != nullptr) ? (cl_uint) events->size() : 0,
8316 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
8317 (event != nullptr) ? &tmp : nullptr),
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008318 __ENQUEUE_MARKER_WAIT_LIST_ERR);
8319
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008320 if (event != nullptr && err == CL_SUCCESS)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008321 *event = tmp;
8322
8323 return err;
8324 }
8325
8326 /**
8327 * A synchronization point that enqueues a barrier operation.
8328 *
8329 * Enqueues a barrier command which waits for either a list of events to complete,
8330 * or if the list is empty it waits for all commands previously enqueued in command_queue
8331 * to complete before it completes. This command blocks command execution, that is, any
8332 * following commands enqueued after it do not execute until it completes. This command
8333 * returns an event which can be waited on, i.e. this event can be waited on to insure that
8334 * all events either in the event_wait_list or all previously enqueued commands, queued
8335 * before this command to command_queue, have completed.
8336 */
8337 cl_int enqueueBarrierWithWaitList(
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008338 const vector<Event> *events = nullptr,
8339 Event *event = nullptr) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008340 {
8341 cl_event tmp;
8342 cl_int err = detail::errHandler(
8343 ::clEnqueueBarrierWithWaitList(
8344 object_,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008345 (events != nullptr) ? (cl_uint) events->size() : 0,
8346 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
8347 (event != nullptr) ? &tmp : nullptr),
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008348 __ENQUEUE_BARRIER_WAIT_LIST_ERR);
8349
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008350 if (event != nullptr && err == CL_SUCCESS)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008351 *event = tmp;
8352
8353 return err;
8354 }
8355
8356 /**
8357 * Enqueues a command to indicate with which device a set of memory objects
8358 * should be associated.
8359 */
8360 cl_int enqueueMigrateMemObjects(
8361 const vector<Memory> &memObjects,
8362 cl_mem_migration_flags flags,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008363 const vector<Event>* events = nullptr,
8364 Event* event = nullptr
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00008365 ) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008366 {
8367 cl_event tmp;
8368
8369 vector<cl_mem> localMemObjects(memObjects.size());
8370
8371 for( int i = 0; i < (int)memObjects.size(); ++i ) {
8372 localMemObjects[i] = memObjects[i]();
8373 }
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00008374
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008375 cl_int err = detail::errHandler(
8376 ::clEnqueueMigrateMemObjects(
8377 object_,
8378 (cl_uint)memObjects.size(),
8379 localMemObjects.data(),
8380 flags,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008381 (events != nullptr) ? (cl_uint) events->size() : 0,
8382 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
8383 (event != nullptr) ? &tmp : nullptr),
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008384 __ENQUEUE_UNMAP_MEM_OBJECT_ERR);
8385
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008386 if (event != nullptr && err == CL_SUCCESS)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008387 *event = tmp;
8388
8389 return err;
8390 }
8391#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
8392
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00008393
8394#if CL_HPP_TARGET_OPENCL_VERSION >= 210
8395 /**
8396 * Enqueues a command that will allow the host associate ranges within a set of
8397 * SVM allocations with a device.
8398 * @param sizes - The length from each pointer to migrate.
8399 */
8400 template<typename T>
8401 cl_int enqueueMigrateSVM(
8402 const cl::vector<T*> &svmRawPointers,
8403 const cl::vector<size_type> &sizes,
8404 cl_mem_migration_flags flags = 0,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008405 const vector<Event>* events = nullptr,
8406 Event* event = nullptr) const
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00008407 {
8408 cl_event tmp;
8409 cl_int err = detail::errHandler(::clEnqueueSVMMigrateMem(
8410 object_,
8411 svmRawPointers.size(), static_cast<void**>(svmRawPointers.data()),
8412 sizes.data(), // array of sizes not passed
8413 flags,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008414 (events != nullptr) ? (cl_uint)events->size() : 0,
8415 (events != nullptr && events->size() > 0) ? (cl_event*)&events->front() : nullptr,
8416 (event != nullptr) ? &tmp : nullptr),
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00008417 __ENQUEUE_MIGRATE_SVM_ERR);
8418
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008419 if (event != nullptr && err == CL_SUCCESS)
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00008420 *event = tmp;
8421
8422 return err;
8423 }
8424
8425 /**
8426 * Enqueues a command that will allow the host associate a set of SVM allocations with
8427 * a device.
8428 */
8429 template<typename T>
8430 cl_int enqueueMigrateSVM(
8431 const cl::vector<T*> &svmRawPointers,
8432 cl_mem_migration_flags flags = 0,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008433 const vector<Event>* events = nullptr,
8434 Event* event = nullptr) const
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00008435 {
8436 return enqueueMigrateSVM(svmRawPointers, cl::vector<size_type>(svmRawPointers.size()), flags, events, event);
8437 }
8438
8439
8440 /**
8441 * Enqueues a command that will allow the host associate ranges within a set of
8442 * SVM allocations with a device.
8443 * @param sizes - The length from each pointer to migrate.
8444 */
8445 template<typename T, class D>
8446 cl_int enqueueMigrateSVM(
8447 const cl::vector<cl::pointer<T, D>> &svmPointers,
8448 const cl::vector<size_type> &sizes,
8449 cl_mem_migration_flags flags = 0,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008450 const vector<Event>* events = nullptr,
8451 Event* event = nullptr) const
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00008452 {
8453 cl::vector<void*> svmRawPointers;
8454 svmRawPointers.reserve(svmPointers.size());
8455 for (auto p : svmPointers) {
8456 svmRawPointers.push_back(static_cast<void*>(p.get()));
8457 }
8458
8459 return enqueueMigrateSVM(svmRawPointers, sizes, flags, events, event);
8460 }
8461
8462
8463 /**
8464 * Enqueues a command that will allow the host associate a set of SVM allocations with
8465 * a device.
8466 */
8467 template<typename T, class D>
8468 cl_int enqueueMigrateSVM(
8469 const cl::vector<cl::pointer<T, D>> &svmPointers,
8470 cl_mem_migration_flags flags = 0,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008471 const vector<Event>* events = nullptr,
8472 Event* event = nullptr) const
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00008473 {
8474 return enqueueMigrateSVM(svmPointers, cl::vector<size_type>(svmPointers.size()), flags, events, event);
8475 }
8476
8477 /**
8478 * Enqueues a command that will allow the host associate ranges within a set of
8479 * SVM allocations with a device.
8480 * @param sizes - The length from the beginning of each container to migrate.
8481 */
8482 template<typename T, class Alloc>
8483 cl_int enqueueMigrateSVM(
8484 const cl::vector<cl::vector<T, Alloc>> &svmContainers,
8485 const cl::vector<size_type> &sizes,
8486 cl_mem_migration_flags flags = 0,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008487 const vector<Event>* events = nullptr,
8488 Event* event = nullptr) const
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00008489 {
8490 cl::vector<void*> svmRawPointers;
8491 svmRawPointers.reserve(svmContainers.size());
8492 for (auto p : svmContainers) {
8493 svmRawPointers.push_back(static_cast<void*>(p.data()));
8494 }
8495
8496 return enqueueMigrateSVM(svmRawPointers, sizes, flags, events, event);
8497 }
8498
8499 /**
8500 * Enqueues a command that will allow the host associate a set of SVM allocations with
8501 * a device.
8502 */
8503 template<typename T, class Alloc>
8504 cl_int enqueueMigrateSVM(
8505 const cl::vector<cl::vector<T, Alloc>> &svmContainers,
8506 cl_mem_migration_flags flags = 0,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008507 const vector<Event>* events = nullptr,
8508 Event* event = nullptr) const
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00008509 {
8510 return enqueueMigrateSVM(svmContainers, cl::vector<size_type>(svmContainers.size()), flags, events, event);
8511 }
8512
8513#endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 210
8514
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008515 cl_int enqueueNDRangeKernel(
8516 const Kernel& kernel,
8517 const NDRange& offset,
8518 const NDRange& global,
8519 const NDRange& local = NullRange,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008520 const vector<Event>* events = nullptr,
8521 Event* event = nullptr) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008522 {
8523 cl_event tmp;
8524 cl_int err = detail::errHandler(
8525 ::clEnqueueNDRangeKernel(
8526 object_, kernel(), (cl_uint) global.dimensions(),
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008527 offset.dimensions() != 0 ? (const size_type*) offset : nullptr,
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008528 (const size_type*) global,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008529 local.dimensions() != 0 ? (const size_type*) local : nullptr,
8530 (events != nullptr) ? (cl_uint) events->size() : 0,
8531 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
8532 (event != nullptr) ? &tmp : nullptr),
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008533 __ENQUEUE_NDRANGE_KERNEL_ERR);
8534
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008535 if (event != nullptr && err == CL_SUCCESS)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008536 *event = tmp;
8537
8538 return err;
8539 }
8540
8541#if defined(CL_USE_DEPRECATED_OPENCL_1_2_APIS)
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00008542 CL_API_PREFIX__VERSION_1_2_DEPRECATED cl_int enqueueTask(
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008543 const Kernel& kernel,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008544 const vector<Event>* events = nullptr,
8545 Event* event = nullptr) const CL_API_SUFFIX__VERSION_1_2_DEPRECATED
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008546 {
8547 cl_event tmp;
8548 cl_int err = detail::errHandler(
8549 ::clEnqueueTask(
8550 object_, kernel(),
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008551 (events != nullptr) ? (cl_uint) events->size() : 0,
8552 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
8553 (event != nullptr) ? &tmp : nullptr),
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008554 __ENQUEUE_TASK_ERR);
8555
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008556 if (event != nullptr && err == CL_SUCCESS)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008557 *event = tmp;
8558
8559 return err;
8560 }
8561#endif // #if defined(CL_USE_DEPRECATED_OPENCL_1_2_APIS)
8562
8563 cl_int enqueueNativeKernel(
8564 void (CL_CALLBACK *userFptr)(void *),
8565 std::pair<void*, size_type> args,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008566 const vector<Memory>* mem_objects = nullptr,
8567 const vector<const void*>* mem_locs = nullptr,
8568 const vector<Event>* events = nullptr,
8569 Event* event = nullptr) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008570 {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008571 cl_event tmp;
8572 cl_int err = detail::errHandler(
8573 ::clEnqueueNativeKernel(
8574 object_, userFptr, args.first, args.second,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008575 (mem_objects != nullptr) ? (cl_uint) mem_objects->size() : 0,
8576 (mem_objects->size() > 0 ) ? reinterpret_cast<const cl_mem *>(mem_objects->data()) : nullptr,
8577 (mem_locs != nullptr && mem_locs->size() > 0) ? (const void **) &mem_locs->front() : nullptr,
8578 (events != nullptr) ? (cl_uint) events->size() : 0,
8579 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
8580 (event != nullptr) ? &tmp : nullptr),
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008581 __ENQUEUE_NATIVE_KERNEL);
8582
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008583 if (event != nullptr && err == CL_SUCCESS)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008584 *event = tmp;
8585
8586 return err;
8587 }
8588
8589/**
8590 * Deprecated APIs for 1.2
8591 */
8592#if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00008593 CL_API_PREFIX__VERSION_1_1_DEPRECATED
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008594 cl_int enqueueMarker(Event* event = nullptr) const CL_API_SUFFIX__VERSION_1_1_DEPRECATED
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008595 {
8596 cl_event tmp;
8597 cl_int err = detail::errHandler(
8598 ::clEnqueueMarker(
8599 object_,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008600 (event != nullptr) ? &tmp : nullptr),
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008601 __ENQUEUE_MARKER_ERR);
8602
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008603 if (event != nullptr && err == CL_SUCCESS)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008604 *event = tmp;
8605
8606 return err;
8607 }
8608
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00008609 CL_API_PREFIX__VERSION_1_1_DEPRECATED
8610 cl_int enqueueWaitForEvents(const vector<Event>& events) const CL_API_SUFFIX__VERSION_1_1_DEPRECATED
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008611 {
8612 return detail::errHandler(
8613 ::clEnqueueWaitForEvents(
8614 object_,
8615 (cl_uint) events.size(),
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008616 events.size() > 0 ? (const cl_event*) &events.front() : nullptr),
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008617 __ENQUEUE_WAIT_FOR_EVENTS_ERR);
8618 }
8619#endif // defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
8620
8621 cl_int enqueueAcquireGLObjects(
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008622 const vector<Memory>* mem_objects = nullptr,
8623 const vector<Event>* events = nullptr,
8624 Event* event = nullptr) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008625 {
8626 cl_event tmp;
8627 cl_int err = detail::errHandler(
8628 ::clEnqueueAcquireGLObjects(
8629 object_,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008630 (mem_objects != nullptr) ? (cl_uint) mem_objects->size() : 0,
8631 (mem_objects != nullptr && mem_objects->size() > 0) ? (const cl_mem *) &mem_objects->front(): nullptr,
8632 (events != nullptr) ? (cl_uint) events->size() : 0,
8633 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
8634 (event != nullptr) ? &tmp : nullptr),
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008635 __ENQUEUE_ACQUIRE_GL_ERR);
8636
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008637 if (event != nullptr && err == CL_SUCCESS)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008638 *event = tmp;
8639
8640 return err;
8641 }
8642
8643 cl_int enqueueReleaseGLObjects(
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008644 const vector<Memory>* mem_objects = nullptr,
8645 const vector<Event>* events = nullptr,
8646 Event* event = nullptr) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008647 {
8648 cl_event tmp;
8649 cl_int err = detail::errHandler(
8650 ::clEnqueueReleaseGLObjects(
8651 object_,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008652 (mem_objects != nullptr) ? (cl_uint) mem_objects->size() : 0,
8653 (mem_objects != nullptr && mem_objects->size() > 0) ? (const cl_mem *) &mem_objects->front(): nullptr,
8654 (events != nullptr) ? (cl_uint) events->size() : 0,
8655 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
8656 (event != nullptr) ? &tmp : nullptr),
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008657 __ENQUEUE_RELEASE_GL_ERR);
8658
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008659 if (event != nullptr && err == CL_SUCCESS)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008660 *event = tmp;
8661
8662 return err;
8663 }
8664
8665#if defined (CL_HPP_USE_DX_INTEROP)
8666typedef CL_API_ENTRY cl_int (CL_API_CALL *PFN_clEnqueueAcquireD3D10ObjectsKHR)(
8667 cl_command_queue command_queue, cl_uint num_objects,
8668 const cl_mem* mem_objects, cl_uint num_events_in_wait_list,
8669 const cl_event* event_wait_list, cl_event* event);
8670typedef CL_API_ENTRY cl_int (CL_API_CALL *PFN_clEnqueueReleaseD3D10ObjectsKHR)(
8671 cl_command_queue command_queue, cl_uint num_objects,
8672 const cl_mem* mem_objects, cl_uint num_events_in_wait_list,
8673 const cl_event* event_wait_list, cl_event* event);
8674
8675 cl_int enqueueAcquireD3D10Objects(
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008676 const vector<Memory>* mem_objects = nullptr,
8677 const vector<Event>* events = nullptr,
8678 Event* event = nullptr) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008679 {
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008680 static PFN_clEnqueueAcquireD3D10ObjectsKHR pfn_clEnqueueAcquireD3D10ObjectsKHR = nullptr;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008681#if CL_HPP_TARGET_OPENCL_VERSION >= 120
8682 cl_context context = getInfo<CL_QUEUE_CONTEXT>();
8683 cl::Device device(getInfo<CL_QUEUE_DEVICE>());
8684 cl_platform_id platform = device.getInfo<CL_DEVICE_PLATFORM>();
8685 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clEnqueueAcquireD3D10ObjectsKHR);
8686#endif
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008687#if CL_HPP_MINIMUM_OPENCL_VERSION < 120
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008688 CL_HPP_INIT_CL_EXT_FCN_PTR_(clEnqueueAcquireD3D10ObjectsKHR);
8689#endif
8690
8691 cl_event tmp;
8692 cl_int err = detail::errHandler(
8693 pfn_clEnqueueAcquireD3D10ObjectsKHR(
8694 object_,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008695 (mem_objects != nullptr) ? (cl_uint) mem_objects->size() : 0,
8696 (mem_objects != nullptr && mem_objects->size() > 0) ? (const cl_mem *) &mem_objects->front(): nullptr,
8697 (events != nullptr) ? (cl_uint) events->size() : 0,
8698 (events != nullptr) ? (cl_event*) &events->front() : nullptr,
8699 (event != nullptr) ? &tmp : nullptr),
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008700 __ENQUEUE_ACQUIRE_GL_ERR);
8701
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008702 if (event != nullptr && err == CL_SUCCESS)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008703 *event = tmp;
8704
8705 return err;
8706 }
8707
8708 cl_int enqueueReleaseD3D10Objects(
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008709 const vector<Memory>* mem_objects = nullptr,
8710 const vector<Event>* events = nullptr,
8711 Event* event = nullptr) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008712 {
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008713 static PFN_clEnqueueReleaseD3D10ObjectsKHR pfn_clEnqueueReleaseD3D10ObjectsKHR = nullptr;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008714#if CL_HPP_TARGET_OPENCL_VERSION >= 120
8715 cl_context context = getInfo<CL_QUEUE_CONTEXT>();
8716 cl::Device device(getInfo<CL_QUEUE_DEVICE>());
8717 cl_platform_id platform = device.getInfo<CL_DEVICE_PLATFORM>();
8718 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clEnqueueReleaseD3D10ObjectsKHR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008719#endif
8720#if CL_HPP_MINIMUM_OPENCL_VERSION < 120
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008721 CL_HPP_INIT_CL_EXT_FCN_PTR_(clEnqueueReleaseD3D10ObjectsKHR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008722#endif
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008723
8724 cl_event tmp;
8725 cl_int err = detail::errHandler(
8726 pfn_clEnqueueReleaseD3D10ObjectsKHR(
8727 object_,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008728 (mem_objects != nullptr) ? (cl_uint) mem_objects->size() : 0,
8729 (mem_objects != nullptr && mem_objects->size() > 0) ? (const cl_mem *) &mem_objects->front(): nullptr,
8730 (events != nullptr) ? (cl_uint) events->size() : 0,
8731 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
8732 (event != nullptr) ? &tmp : nullptr),
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008733 __ENQUEUE_RELEASE_GL_ERR);
8734
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008735 if (event != nullptr && err == CL_SUCCESS)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008736 *event = tmp;
8737
8738 return err;
8739 }
8740#endif
8741
8742/**
8743 * Deprecated APIs for 1.2
8744 */
8745#if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00008746 CL_API_PREFIX__VERSION_1_1_DEPRECATED
8747 cl_int enqueueBarrier() const CL_API_SUFFIX__VERSION_1_1_DEPRECATED
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008748 {
8749 return detail::errHandler(
8750 ::clEnqueueBarrier(object_),
8751 __ENQUEUE_BARRIER_ERR);
8752 }
8753#endif // CL_USE_DEPRECATED_OPENCL_1_1_APIS
8754
8755 cl_int flush() const
8756 {
8757 return detail::errHandler(::clFlush(object_), __FLUSH_ERR);
8758 }
8759
8760 cl_int finish() const
8761 {
8762 return detail::errHandler(::clFinish(object_), __FINISH_ERR);
8763 }
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008764
8765#ifdef cl_khr_external_memory
8766 cl_int enqueueAcquireExternalMemObjects(
8767 const vector<Memory>& mem_objects,
8768 const vector<Event>* events_wait = nullptr,
8769 Event *event = nullptr)
8770 {
8771 cl_int err = CL_INVALID_OPERATION;
8772 cl_event tmp;
8773
8774 std::call_once(ext_memory_initialized_, initMemoryExtension, this->getInfo<CL_QUEUE_DEVICE>());
8775
8776 if (pfn_clEnqueueAcquireExternalMemObjectsKHR)
8777 {
8778 err = pfn_clEnqueueAcquireExternalMemObjectsKHR(
8779 object_,
8780 static_cast<cl_uint>(mem_objects.size()),
8781 (mem_objects.size() > 0) ? reinterpret_cast<const cl_mem *>(mem_objects.data()) : nullptr,
8782 (events_wait != nullptr) ? static_cast<cl_uint>(events_wait->size()) : 0,
8783 (events_wait != nullptr && events_wait->size() > 0) ? reinterpret_cast<const cl_event*>(events_wait->data()) : nullptr,
8784 &tmp);
8785 }
8786
8787 detail::errHandler(err, __ENQUEUE_ACQUIRE_EXTERNAL_MEMORY_ERR);
8788
8789 if (event != nullptr && err == CL_SUCCESS)
8790 *event = tmp;
8791
8792 return err;
8793 }
8794
8795 cl_int enqueueReleaseExternalMemObjects(
8796 const vector<Memory>& mem_objects,
8797 const vector<Event>* events_wait = nullptr,
8798 Event *event = nullptr)
8799 {
8800 cl_int err = CL_INVALID_OPERATION;
8801 cl_event tmp;
8802
8803 std::call_once(ext_memory_initialized_, initMemoryExtension, this->getInfo<CL_QUEUE_DEVICE>());
8804
8805 if (pfn_clEnqueueReleaseExternalMemObjectsKHR)
8806 {
8807 err = pfn_clEnqueueReleaseExternalMemObjectsKHR(
8808 object_,
8809 static_cast<cl_uint>(mem_objects.size()),
8810 (mem_objects.size() > 0) ? reinterpret_cast<const cl_mem *>(mem_objects.data()) : nullptr,
8811 (events_wait != nullptr) ? static_cast<cl_uint>(events_wait->size()) : 0,
8812 (events_wait != nullptr && events_wait->size() > 0) ? reinterpret_cast<const cl_event*>(events_wait->data()) : nullptr,
8813 &tmp);
8814 }
8815
8816 detail::errHandler(err, __ENQUEUE_RELEASE_EXTERNAL_MEMORY_ERR);
8817
8818 if (event != nullptr && err == CL_SUCCESS)
8819 *event = tmp;
8820
8821 return err;
8822 }
8823#endif // cl_khr_external_memory && CL_HPP_TARGET_OPENCL_VERSION >= 300
8824
8825#ifdef cl_khr_semaphore
8826 cl_int enqueueWaitSemaphores(
8827 const vector<Semaphore> &sema_objects,
8828 const vector<cl_semaphore_payload_khr> &sema_payloads = {},
8829 const vector<Event>* events_wait_list = nullptr,
8830 Event *event = nullptr) const;
8831
8832 cl_int enqueueSignalSemaphores(
8833 const vector<Semaphore> &sema_objects,
8834 const vector<cl_semaphore_payload_khr>& sema_payloads = {},
8835 const vector<Event>* events_wait_list = nullptr,
8836 Event* event = nullptr);
8837#endif // cl_khr_semaphore
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008838}; // CommandQueue
8839
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008840#ifdef cl_khr_external_memory
8841CL_HPP_DEFINE_STATIC_MEMBER_ std::once_flag CommandQueue::ext_memory_initialized_;
8842#endif
8843
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008844CL_HPP_DEFINE_STATIC_MEMBER_ std::once_flag CommandQueue::default_initialized_;
8845CL_HPP_DEFINE_STATIC_MEMBER_ CommandQueue CommandQueue::default_;
8846CL_HPP_DEFINE_STATIC_MEMBER_ cl_int CommandQueue::default_error_ = CL_SUCCESS;
8847
8848
8849#if CL_HPP_TARGET_OPENCL_VERSION >= 200
8850enum class DeviceQueueProperties : cl_command_queue_properties
8851{
8852 None = 0,
8853 Profiling = CL_QUEUE_PROFILING_ENABLE,
8854};
8855
8856inline DeviceQueueProperties operator|(DeviceQueueProperties lhs, DeviceQueueProperties rhs)
8857{
8858 return static_cast<DeviceQueueProperties>(static_cast<cl_command_queue_properties>(lhs) | static_cast<cl_command_queue_properties>(rhs));
8859}
8860
8861/*! \class DeviceCommandQueue
8862 * \brief DeviceCommandQueue interface for device cl_command_queues.
8863 */
8864class DeviceCommandQueue : public detail::Wrapper<cl_command_queue>
8865{
8866public:
8867
8868 /*!
8869 * Trivial empty constructor to create a null queue.
8870 */
8871 DeviceCommandQueue() { }
8872
8873 /*!
8874 * Default construct device command queue on default context and device
8875 */
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008876 DeviceCommandQueue(DeviceQueueProperties properties, cl_int* err = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008877 {
8878 cl_int error;
8879 cl::Context context = cl::Context::getDefault();
8880 cl::Device device = cl::Device::getDefault();
8881
8882 cl_command_queue_properties mergedProperties =
8883 CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE | CL_QUEUE_ON_DEVICE | static_cast<cl_command_queue_properties>(properties);
8884
8885 cl_queue_properties queue_properties[] = {
8886 CL_QUEUE_PROPERTIES, mergedProperties, 0 };
8887 object_ = ::clCreateCommandQueueWithProperties(
8888 context(), device(), queue_properties, &error);
8889
8890 detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008891 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008892 *err = error;
8893 }
8894 }
8895
8896 /*!
8897 * Create a device command queue for a specified device in the passed context.
8898 */
8899 DeviceCommandQueue(
8900 const Context& context,
8901 const Device& device,
8902 DeviceQueueProperties properties = DeviceQueueProperties::None,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008903 cl_int* err = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008904 {
8905 cl_int error;
8906
8907 cl_command_queue_properties mergedProperties =
8908 CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE | CL_QUEUE_ON_DEVICE | static_cast<cl_command_queue_properties>(properties);
8909 cl_queue_properties queue_properties[] = {
8910 CL_QUEUE_PROPERTIES, mergedProperties, 0 };
8911 object_ = ::clCreateCommandQueueWithProperties(
8912 context(), device(), queue_properties, &error);
8913
8914 detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008915 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008916 *err = error;
8917 }
8918 }
8919
8920 /*!
8921 * Create a device command queue for a specified device in the passed context.
8922 */
8923 DeviceCommandQueue(
8924 const Context& context,
8925 const Device& device,
8926 cl_uint queueSize,
8927 DeviceQueueProperties properties = DeviceQueueProperties::None,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008928 cl_int* err = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008929 {
8930 cl_int error;
8931
8932 cl_command_queue_properties mergedProperties =
8933 CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE | CL_QUEUE_ON_DEVICE | static_cast<cl_command_queue_properties>(properties);
8934 cl_queue_properties queue_properties[] = {
8935 CL_QUEUE_PROPERTIES, mergedProperties,
8936 CL_QUEUE_SIZE, queueSize,
8937 0 };
8938 object_ = ::clCreateCommandQueueWithProperties(
8939 context(), device(), queue_properties, &error);
8940
8941 detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008942 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008943 *err = error;
8944 }
8945 }
8946
8947 /*! \brief Constructor from cl_command_queue - takes ownership.
8948 *
8949 * \param retainObject will cause the constructor to retain its cl object.
8950 * Defaults to false to maintain compatibility with
8951 * earlier versions.
8952 */
8953 explicit DeviceCommandQueue(const cl_command_queue& commandQueue, bool retainObject = false) :
8954 detail::Wrapper<cl_type>(commandQueue, retainObject) { }
8955
8956 DeviceCommandQueue& operator = (const cl_command_queue& rhs)
8957 {
8958 detail::Wrapper<cl_type>::operator=(rhs);
8959 return *this;
8960 }
8961
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008962 template <typename T>
8963 cl_int getInfo(cl_command_queue_info name, T* param) const
8964 {
8965 return detail::errHandler(
8966 detail::getInfo(
8967 &::clGetCommandQueueInfo, object_, name, param),
8968 __GET_COMMAND_QUEUE_INFO_ERR);
8969 }
8970
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00008971 template <cl_command_queue_info name> typename
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008972 detail::param_traits<detail::cl_command_queue_info, name>::param_type
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008973 getInfo(cl_int* err = nullptr) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008974 {
8975 typename detail::param_traits<
8976 detail::cl_command_queue_info, name>::param_type param;
8977 cl_int result = getInfo(name, &param);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01008978 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008979 *err = result;
8980 }
8981 return param;
8982 }
8983
8984 /*!
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00008985 * Create a new default device command queue for the default device,
8986 * in the default context and of the default size.
8987 * If there is already a default queue for the specified device this
8988 * function will return the pre-existing queue.
8989 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01008990 static DeviceCommandQueue makeDefault(
8991 cl_int *err = nullptr)
8992 {
8993 cl_int error;
8994 cl::Context context = cl::Context::getDefault();
8995 cl::Device device = cl::Device::getDefault();
8996
8997 cl_command_queue_properties properties =
8998 CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE | CL_QUEUE_ON_DEVICE | CL_QUEUE_ON_DEVICE_DEFAULT;
8999 cl_queue_properties queue_properties[] = {
9000 CL_QUEUE_PROPERTIES, properties,
9001 0 };
9002 DeviceCommandQueue deviceQueue(
9003 ::clCreateCommandQueueWithProperties(
9004 context(), device(), queue_properties, &error));
9005
9006 detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01009007 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01009008 *err = error;
9009 }
9010
9011 return deviceQueue;
9012 }
9013
9014 /*!
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00009015 * Create a new default device command queue for the specified device
9016 * and of the default size.
9017 * If there is already a default queue for the specified device this
9018 * function will return the pre-existing queue.
9019 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01009020 static DeviceCommandQueue makeDefault(
9021 const Context &context, const Device &device, cl_int *err = nullptr)
9022 {
9023 cl_int error;
9024
9025 cl_command_queue_properties properties =
9026 CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE | CL_QUEUE_ON_DEVICE | CL_QUEUE_ON_DEVICE_DEFAULT;
9027 cl_queue_properties queue_properties[] = {
9028 CL_QUEUE_PROPERTIES, properties,
9029 0 };
9030 DeviceCommandQueue deviceQueue(
9031 ::clCreateCommandQueueWithProperties(
9032 context(), device(), queue_properties, &error));
9033
9034 detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01009035 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01009036 *err = error;
9037 }
9038
9039 return deviceQueue;
9040 }
9041
9042 /*!
9043 * Create a new default device command queue for the specified device
9044 * and of the requested size in bytes.
9045 * If there is already a default queue for the specified device this
9046 * function will return the pre-existing queue.
9047 */
9048 static DeviceCommandQueue makeDefault(
9049 const Context &context, const Device &device, cl_uint queueSize, cl_int *err = nullptr)
9050 {
9051 cl_int error;
9052
9053 cl_command_queue_properties properties =
9054 CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE | CL_QUEUE_ON_DEVICE | CL_QUEUE_ON_DEVICE_DEFAULT;
9055 cl_queue_properties queue_properties[] = {
9056 CL_QUEUE_PROPERTIES, properties,
9057 CL_QUEUE_SIZE, queueSize,
9058 0 };
9059 DeviceCommandQueue deviceQueue(
9060 ::clCreateCommandQueueWithProperties(
9061 context(), device(), queue_properties, &error));
9062
9063 detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01009064 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01009065 *err = error;
9066 }
9067
9068 return deviceQueue;
9069 }
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00009070
9071
9072
9073#if CL_HPP_TARGET_OPENCL_VERSION >= 210
9074 /*!
9075 * Modify the default device command queue to be used for subsequent kernels.
9076 * This can update the default command queue for a device repeatedly to account
9077 * for kernels that rely on the default.
9078 * @return updated default device command queue.
9079 */
9080 static DeviceCommandQueue updateDefault(const Context &context, const Device &device, const DeviceCommandQueue &default_queue, cl_int *err = nullptr)
9081 {
9082 cl_int error;
9083 error = clSetDefaultDeviceCommandQueue(context.get(), device.get(), default_queue.get());
9084
9085 detail::errHandler(error, __SET_DEFAULT_DEVICE_COMMAND_QUEUE_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01009086 if (err != nullptr) {
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00009087 *err = error;
9088 }
9089 return default_queue;
9090 }
9091
9092 /*!
9093 * Return the current default command queue for the specified command queue
9094 */
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01009095 static DeviceCommandQueue getDefault(const CommandQueue &queue, cl_int * err = nullptr)
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +00009096 {
9097 return queue.getInfo<CL_QUEUE_DEVICE_DEFAULT>(err);
9098 }
9099
9100#endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 210
Anthony Barbier6ff3b192017-09-04 18:44:23 +01009101}; // DeviceCommandQueue
9102
9103namespace detail
9104{
9105 // Specialization for device command queue
9106 template <>
9107 struct KernelArgumentHandler<cl::DeviceCommandQueue, void>
9108 {
9109 static size_type size(const cl::DeviceCommandQueue&) { return sizeof(cl_command_queue); }
9110 static const cl_command_queue* ptr(const cl::DeviceCommandQueue& value) { return &(value()); }
9111 };
9112} // namespace detail
9113
9114#endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 200
9115
9116
9117template< typename IteratorType >
9118Buffer::Buffer(
9119 const Context &context,
9120 IteratorType startIterator,
9121 IteratorType endIterator,
9122 bool readOnly,
9123 bool useHostPtr,
9124 cl_int* err)
9125{
9126 typedef typename std::iterator_traits<IteratorType>::value_type DataType;
9127 cl_int error;
9128
9129 cl_mem_flags flags = 0;
9130 if( readOnly ) {
9131 flags |= CL_MEM_READ_ONLY;
9132 }
9133 else {
9134 flags |= CL_MEM_READ_WRITE;
9135 }
9136 if( useHostPtr ) {
9137 flags |= CL_MEM_USE_HOST_PTR;
9138 }
9139
9140 size_type size = sizeof(DataType)*(endIterator - startIterator);
9141
9142 if( useHostPtr ) {
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01009143 object_ = ::clCreateBuffer(context(), flags, size, const_cast<DataType*>(&*startIterator), &error);
Anthony Barbier6ff3b192017-09-04 18:44:23 +01009144 } else {
9145 object_ = ::clCreateBuffer(context(), flags, size, 0, &error);
9146 }
9147
9148 detail::errHandler(error, __CREATE_BUFFER_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01009149 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01009150 *err = error;
9151 }
9152
9153 if( !useHostPtr ) {
9154 CommandQueue queue(context, 0, &error);
9155 detail::errHandler(error, __CREATE_BUFFER_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01009156 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01009157 *err = error;
9158 }
9159
9160 error = cl::copy(queue, startIterator, endIterator, *this);
9161 detail::errHandler(error, __CREATE_BUFFER_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01009162 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01009163 *err = error;
9164 }
9165 }
9166}
9167
9168template< typename IteratorType >
9169Buffer::Buffer(
9170 const CommandQueue &queue,
9171 IteratorType startIterator,
9172 IteratorType endIterator,
9173 bool readOnly,
9174 bool useHostPtr,
9175 cl_int* err)
9176{
9177 typedef typename std::iterator_traits<IteratorType>::value_type DataType;
9178 cl_int error;
9179
9180 cl_mem_flags flags = 0;
9181 if (readOnly) {
9182 flags |= CL_MEM_READ_ONLY;
9183 }
9184 else {
9185 flags |= CL_MEM_READ_WRITE;
9186 }
9187 if (useHostPtr) {
9188 flags |= CL_MEM_USE_HOST_PTR;
9189 }
9190
9191 size_type size = sizeof(DataType)*(endIterator - startIterator);
9192
9193 Context context = queue.getInfo<CL_QUEUE_CONTEXT>();
9194
9195 if (useHostPtr) {
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01009196 object_ = ::clCreateBuffer(context(), flags, size, const_cast<DataType*>(&*startIterator), &error);
Anthony Barbier6ff3b192017-09-04 18:44:23 +01009197 }
9198 else {
9199 object_ = ::clCreateBuffer(context(), flags, size, 0, &error);
9200 }
9201
9202 detail::errHandler(error, __CREATE_BUFFER_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01009203 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01009204 *err = error;
9205 }
9206
9207 if (!useHostPtr) {
9208 error = cl::copy(queue, startIterator, endIterator, *this);
9209 detail::errHandler(error, __CREATE_BUFFER_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01009210 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01009211 *err = error;
9212 }
9213 }
9214}
9215
9216inline cl_int enqueueReadBuffer(
9217 const Buffer& buffer,
9218 cl_bool blocking,
9219 size_type offset,
9220 size_type size,
9221 void* ptr,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01009222 const vector<Event>* events = nullptr,
9223 Event* event = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01009224{
9225 cl_int error;
9226 CommandQueue queue = CommandQueue::getDefault(&error);
9227
9228 if (error != CL_SUCCESS) {
9229 return error;
9230 }
9231
9232 return queue.enqueueReadBuffer(buffer, blocking, offset, size, ptr, events, event);
9233}
9234
9235inline cl_int enqueueWriteBuffer(
9236 const Buffer& buffer,
9237 cl_bool blocking,
9238 size_type offset,
9239 size_type size,
9240 const void* ptr,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01009241 const vector<Event>* events = nullptr,
9242 Event* event = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01009243{
9244 cl_int error;
9245 CommandQueue queue = CommandQueue::getDefault(&error);
9246
9247 if (error != CL_SUCCESS) {
9248 return error;
9249 }
9250
9251 return queue.enqueueWriteBuffer(buffer, blocking, offset, size, ptr, events, event);
9252}
9253
9254inline void* enqueueMapBuffer(
9255 const Buffer& buffer,
9256 cl_bool blocking,
9257 cl_map_flags flags,
9258 size_type offset,
9259 size_type size,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01009260 const vector<Event>* events = nullptr,
9261 Event* event = nullptr,
9262 cl_int* err = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01009263{
9264 cl_int error;
9265 CommandQueue queue = CommandQueue::getDefault(&error);
9266 detail::errHandler(error, __ENQUEUE_MAP_BUFFER_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01009267 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01009268 *err = error;
9269 }
9270
9271 void * result = ::clEnqueueMapBuffer(
9272 queue(), buffer(), blocking, flags, offset, size,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01009273 (events != nullptr) ? (cl_uint) events->size() : 0,
9274 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
Anthony Barbier6ff3b192017-09-04 18:44:23 +01009275 (cl_event*) event,
9276 &error);
9277
9278 detail::errHandler(error, __ENQUEUE_MAP_BUFFER_ERR);
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01009279 if (err != nullptr) {
Anthony Barbier6ff3b192017-09-04 18:44:23 +01009280 *err = error;
9281 }
9282 return result;
9283}
9284
9285
9286#if CL_HPP_TARGET_OPENCL_VERSION >= 200
9287/**
9288 * Enqueues to the default queue a command that will allow the host to
9289 * update a region of a coarse-grained SVM buffer.
9290 * This variant takes a raw SVM pointer.
9291 */
9292template<typename T>
9293inline cl_int enqueueMapSVM(
9294 T* ptr,
9295 cl_bool blocking,
9296 cl_map_flags flags,
9297 size_type size,
9298 const vector<Event>* events,
9299 Event* event)
9300{
9301 cl_int error;
9302 CommandQueue queue = CommandQueue::getDefault(&error);
9303 if (error != CL_SUCCESS) {
9304 return detail::errHandler(error, __ENQUEUE_MAP_BUFFER_ERR);
9305 }
9306
9307 return queue.enqueueMapSVM(
9308 ptr, blocking, flags, size, events, event);
9309}
9310
9311/**
9312 * Enqueues to the default queue a command that will allow the host to
9313 * update a region of a coarse-grained SVM buffer.
9314 * This variant takes a cl::pointer instance.
9315 */
9316template<typename T, class D>
9317inline cl_int enqueueMapSVM(
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01009318 cl::pointer<T, D> &ptr,
Anthony Barbier6ff3b192017-09-04 18:44:23 +01009319 cl_bool blocking,
9320 cl_map_flags flags,
9321 size_type size,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01009322 const vector<Event>* events = nullptr,
9323 Event* event = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01009324{
9325 cl_int error;
9326 CommandQueue queue = CommandQueue::getDefault(&error);
9327 if (error != CL_SUCCESS) {
9328 return detail::errHandler(error, __ENQUEUE_MAP_BUFFER_ERR);
9329 }
9330
9331 return queue.enqueueMapSVM(
9332 ptr, blocking, flags, size, events, event);
9333}
9334
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 cl::vector instance.
9339 */
9340template<typename T, class Alloc>
9341inline cl_int enqueueMapSVM(
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01009342 cl::vector<T, Alloc> &container,
Anthony Barbier6ff3b192017-09-04 18:44:23 +01009343 cl_bool blocking,
9344 cl_map_flags flags,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01009345 const vector<Event>* events = nullptr,
9346 Event* event = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01009347{
9348 cl_int error;
9349 CommandQueue queue = CommandQueue::getDefault(&error);
9350 if (error != CL_SUCCESS) {
9351 return detail::errHandler(error, __ENQUEUE_MAP_BUFFER_ERR);
9352 }
9353
9354 return queue.enqueueMapSVM(
9355 container, blocking, flags, events, event);
9356}
9357
9358#endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 200
9359
9360inline cl_int enqueueUnmapMemObject(
9361 const Memory& memory,
9362 void* mapped_ptr,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01009363 const vector<Event>* events = nullptr,
9364 Event* event = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01009365{
9366 cl_int error;
9367 CommandQueue queue = CommandQueue::getDefault(&error);
9368 detail::errHandler(error, __ENQUEUE_MAP_BUFFER_ERR);
9369 if (error != CL_SUCCESS) {
9370 return error;
9371 }
9372
9373 cl_event tmp;
9374 cl_int err = detail::errHandler(
9375 ::clEnqueueUnmapMemObject(
9376 queue(), memory(), mapped_ptr,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01009377 (events != nullptr) ? (cl_uint)events->size() : 0,
9378 (events != nullptr && events->size() > 0) ? (cl_event*)&events->front() : nullptr,
9379 (event != nullptr) ? &tmp : nullptr),
Anthony Barbier6ff3b192017-09-04 18:44:23 +01009380 __ENQUEUE_UNMAP_MEM_OBJECT_ERR);
9381
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01009382 if (event != nullptr && err == CL_SUCCESS)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01009383 *event = tmp;
9384
9385 return err;
9386}
9387
9388#if CL_HPP_TARGET_OPENCL_VERSION >= 200
9389/**
9390 * Enqueues to the default queue a command that will release a coarse-grained
9391 * SVM buffer back to the OpenCL runtime.
9392 * This variant takes a raw SVM pointer.
9393 */
9394template<typename T>
9395inline cl_int enqueueUnmapSVM(
9396 T* ptr,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01009397 const vector<Event>* events = nullptr,
9398 Event* event = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01009399{
9400 cl_int error;
9401 CommandQueue queue = CommandQueue::getDefault(&error);
9402 if (error != CL_SUCCESS) {
9403 return detail::errHandler(error, __ENQUEUE_UNMAP_MEM_OBJECT_ERR);
9404 }
9405
9406 return detail::errHandler(queue.enqueueUnmapSVM(ptr, events, event),
9407 __ENQUEUE_UNMAP_MEM_OBJECT_ERR);
9408
9409}
9410
9411/**
9412 * Enqueues to the default queue a command that will release a coarse-grained
9413 * SVM buffer back to the OpenCL runtime.
9414 * This variant takes a cl::pointer instance.
9415 */
9416template<typename T, class D>
9417inline cl_int enqueueUnmapSVM(
9418 cl::pointer<T, D> &ptr,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01009419 const vector<Event>* events = nullptr,
9420 Event* event = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01009421{
9422 cl_int error;
9423 CommandQueue queue = CommandQueue::getDefault(&error);
9424 if (error != CL_SUCCESS) {
9425 return detail::errHandler(error, __ENQUEUE_UNMAP_MEM_OBJECT_ERR);
9426 }
9427
9428 return detail::errHandler(queue.enqueueUnmapSVM(ptr, events, event),
9429 __ENQUEUE_UNMAP_MEM_OBJECT_ERR);
9430}
9431
9432/**
9433 * Enqueues to the default queue a command that will release a coarse-grained
9434 * SVM buffer back to the OpenCL runtime.
9435 * This variant takes a cl::vector instance.
9436 */
9437template<typename T, class Alloc>
9438inline cl_int enqueueUnmapSVM(
9439 cl::vector<T, Alloc> &container,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01009440 const vector<Event>* events = nullptr,
9441 Event* event = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01009442{
9443 cl_int error;
9444 CommandQueue queue = CommandQueue::getDefault(&error);
9445 if (error != CL_SUCCESS) {
9446 return detail::errHandler(error, __ENQUEUE_UNMAP_MEM_OBJECT_ERR);
9447 }
9448
9449 return detail::errHandler(queue.enqueueUnmapSVM(container, events, event),
9450 __ENQUEUE_UNMAP_MEM_OBJECT_ERR);
9451}
9452
9453#endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 200
9454
9455inline cl_int enqueueCopyBuffer(
9456 const Buffer& src,
9457 const Buffer& dst,
9458 size_type src_offset,
9459 size_type dst_offset,
9460 size_type size,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01009461 const vector<Event>* events = nullptr,
9462 Event* event = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01009463{
9464 cl_int error;
9465 CommandQueue queue = CommandQueue::getDefault(&error);
9466
9467 if (error != CL_SUCCESS) {
9468 return error;
9469 }
9470
9471 return queue.enqueueCopyBuffer(src, dst, src_offset, dst_offset, size, events, event);
9472}
9473
9474/**
9475 * Blocking copy operation between iterators and a buffer.
9476 * Host to Device.
9477 * Uses default command queue.
9478 */
9479template< typename IteratorType >
9480inline cl_int copy( IteratorType startIterator, IteratorType endIterator, cl::Buffer &buffer )
9481{
9482 cl_int error;
9483 CommandQueue queue = CommandQueue::getDefault(&error);
9484 if (error != CL_SUCCESS)
9485 return error;
9486
9487 return cl::copy(queue, startIterator, endIterator, buffer);
9488}
9489
9490/**
9491 * Blocking copy operation between iterators and a buffer.
9492 * Device to Host.
9493 * Uses default command queue.
9494 */
9495template< typename IteratorType >
9496inline cl_int copy( const cl::Buffer &buffer, IteratorType startIterator, IteratorType endIterator )
9497{
9498 cl_int error;
9499 CommandQueue queue = CommandQueue::getDefault(&error);
9500 if (error != CL_SUCCESS)
9501 return error;
9502
9503 return cl::copy(queue, buffer, startIterator, endIterator);
9504}
9505
9506/**
9507 * Blocking copy operation between iterators and a buffer.
9508 * Host to Device.
9509 * Uses specified queue.
9510 */
9511template< typename IteratorType >
9512inline cl_int copy( const CommandQueue &queue, IteratorType startIterator, IteratorType endIterator, cl::Buffer &buffer )
9513{
9514 typedef typename std::iterator_traits<IteratorType>::value_type DataType;
9515 cl_int error;
9516
9517 size_type length = endIterator-startIterator;
9518 size_type byteLength = length*sizeof(DataType);
9519
9520 DataType *pointer =
9521 static_cast<DataType*>(queue.enqueueMapBuffer(buffer, CL_TRUE, CL_MAP_WRITE, 0, byteLength, 0, 0, &error));
9522 // if exceptions enabled, enqueueMapBuffer will throw
9523 if( error != CL_SUCCESS ) {
9524 return error;
9525 }
9526#if defined(_MSC_VER)
9527 std::copy(
9528 startIterator,
9529 endIterator,
9530 stdext::checked_array_iterator<DataType*>(
9531 pointer, length));
9532#else
9533 std::copy(startIterator, endIterator, pointer);
9534#endif
9535 Event endEvent;
9536 error = queue.enqueueUnmapMemObject(buffer, pointer, 0, &endEvent);
9537 // if exceptions enabled, enqueueUnmapMemObject will throw
9538 if( error != CL_SUCCESS ) {
9539 return error;
9540 }
9541 endEvent.wait();
9542 return CL_SUCCESS;
9543}
9544
9545/**
9546 * Blocking copy operation between iterators and a buffer.
9547 * Device to Host.
9548 * Uses specified queue.
9549 */
9550template< typename IteratorType >
9551inline cl_int copy( const CommandQueue &queue, const cl::Buffer &buffer, IteratorType startIterator, IteratorType endIterator )
9552{
9553 typedef typename std::iterator_traits<IteratorType>::value_type DataType;
9554 cl_int error;
9555
9556 size_type length = endIterator-startIterator;
9557 size_type byteLength = length*sizeof(DataType);
9558
9559 DataType *pointer =
9560 static_cast<DataType*>(queue.enqueueMapBuffer(buffer, CL_TRUE, CL_MAP_READ, 0, byteLength, 0, 0, &error));
9561 // if exceptions enabled, enqueueMapBuffer will throw
9562 if( error != CL_SUCCESS ) {
9563 return error;
9564 }
9565 std::copy(pointer, pointer + length, startIterator);
9566 Event endEvent;
9567 error = queue.enqueueUnmapMemObject(buffer, pointer, 0, &endEvent);
9568 // if exceptions enabled, enqueueUnmapMemObject will throw
9569 if( error != CL_SUCCESS ) {
9570 return error;
9571 }
9572 endEvent.wait();
9573 return CL_SUCCESS;
9574}
9575
9576
9577#if CL_HPP_TARGET_OPENCL_VERSION >= 200
9578/**
9579 * Blocking SVM map operation - performs a blocking map underneath.
9580 */
9581template<typename T, class Alloc>
9582inline cl_int mapSVM(cl::vector<T, Alloc> &container)
9583{
9584 return enqueueMapSVM(container, CL_TRUE, CL_MAP_READ | CL_MAP_WRITE);
9585}
9586
9587/**
9588* Blocking SVM map operation - performs a blocking map underneath.
9589*/
9590template<typename T, class Alloc>
9591inline cl_int unmapSVM(cl::vector<T, Alloc> &container)
9592{
9593 return enqueueUnmapSVM(container);
9594}
9595
9596#endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 200
9597
9598#if CL_HPP_TARGET_OPENCL_VERSION >= 110
9599inline cl_int enqueueReadBufferRect(
9600 const Buffer& buffer,
9601 cl_bool blocking,
9602 const array<size_type, 3>& buffer_offset,
9603 const array<size_type, 3>& host_offset,
9604 const array<size_type, 3>& region,
9605 size_type buffer_row_pitch,
9606 size_type buffer_slice_pitch,
9607 size_type host_row_pitch,
9608 size_type host_slice_pitch,
9609 void *ptr,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01009610 const vector<Event>* events = nullptr,
9611 Event* event = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01009612{
9613 cl_int error;
9614 CommandQueue queue = CommandQueue::getDefault(&error);
9615
9616 if (error != CL_SUCCESS) {
9617 return error;
9618 }
9619
9620 return queue.enqueueReadBufferRect(
9621 buffer,
9622 blocking,
9623 buffer_offset,
9624 host_offset,
9625 region,
9626 buffer_row_pitch,
9627 buffer_slice_pitch,
9628 host_row_pitch,
9629 host_slice_pitch,
9630 ptr,
9631 events,
9632 event);
9633}
9634
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01009635inline cl_int enqueueReadBufferRect(
9636 const Buffer& buffer,
9637 cl_bool blocking,
9638 const array<size_type, 2>& buffer_offset,
9639 const array<size_type, 2>& host_offset,
9640 const array<size_type, 2>& region,
9641 size_type buffer_row_pitch,
9642 size_type buffer_slice_pitch,
9643 size_type host_row_pitch,
9644 size_type host_slice_pitch,
9645 void* ptr,
9646 const vector<Event>* events = nullptr,
9647 Event* event = nullptr)
9648{
9649 return enqueueReadBufferRect(
9650 buffer,
9651 blocking,
9652 { buffer_offset[0], buffer_offset[1], 0 },
9653 { host_offset[0], host_offset[1], 0 },
9654 { region[0], region[1], 1 },
9655 buffer_row_pitch,
9656 buffer_slice_pitch,
9657 host_row_pitch,
9658 host_slice_pitch,
9659 ptr,
9660 events,
9661 event);
9662}
9663
Anthony Barbier6ff3b192017-09-04 18:44:23 +01009664inline cl_int enqueueWriteBufferRect(
9665 const Buffer& buffer,
9666 cl_bool blocking,
9667 const array<size_type, 3>& buffer_offset,
9668 const array<size_type, 3>& host_offset,
9669 const array<size_type, 3>& region,
9670 size_type buffer_row_pitch,
9671 size_type buffer_slice_pitch,
9672 size_type host_row_pitch,
9673 size_type host_slice_pitch,
Anthony Barbier8b2fdc92018-08-09 11:42:38 +01009674 const void *ptr,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01009675 const vector<Event>* events = nullptr,
9676 Event* event = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01009677{
9678 cl_int error;
9679 CommandQueue queue = CommandQueue::getDefault(&error);
9680
9681 if (error != CL_SUCCESS) {
9682 return error;
9683 }
9684
9685 return queue.enqueueWriteBufferRect(
9686 buffer,
9687 blocking,
9688 buffer_offset,
9689 host_offset,
9690 region,
9691 buffer_row_pitch,
9692 buffer_slice_pitch,
9693 host_row_pitch,
9694 host_slice_pitch,
9695 ptr,
9696 events,
9697 event);
9698}
9699
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01009700inline cl_int enqueueWriteBufferRect(
9701 const Buffer& buffer,
9702 cl_bool blocking,
9703 const array<size_type, 2>& buffer_offset,
9704 const array<size_type, 2>& host_offset,
9705 const array<size_type, 2>& region,
9706 size_type buffer_row_pitch,
9707 size_type buffer_slice_pitch,
9708 size_type host_row_pitch,
9709 size_type host_slice_pitch,
9710 const void* ptr,
9711 const vector<Event>* events = nullptr,
9712 Event* event = nullptr)
9713{
9714 return enqueueWriteBufferRect(
9715 buffer,
9716 blocking,
9717 { buffer_offset[0], buffer_offset[1], 0 },
9718 { host_offset[0], host_offset[1], 0 },
9719 { region[0], region[1], 1 },
9720 buffer_row_pitch,
9721 buffer_slice_pitch,
9722 host_row_pitch,
9723 host_slice_pitch,
9724 ptr,
9725 events,
9726 event);
9727}
9728
Anthony Barbier6ff3b192017-09-04 18:44:23 +01009729inline cl_int enqueueCopyBufferRect(
9730 const Buffer& src,
9731 const Buffer& dst,
9732 const array<size_type, 3>& src_origin,
9733 const array<size_type, 3>& dst_origin,
9734 const array<size_type, 3>& region,
9735 size_type src_row_pitch,
9736 size_type src_slice_pitch,
9737 size_type dst_row_pitch,
9738 size_type dst_slice_pitch,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01009739 const vector<Event>* events = nullptr,
9740 Event* event = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01009741{
9742 cl_int error;
9743 CommandQueue queue = CommandQueue::getDefault(&error);
9744
9745 if (error != CL_SUCCESS) {
9746 return error;
9747 }
9748
9749 return queue.enqueueCopyBufferRect(
9750 src,
9751 dst,
9752 src_origin,
9753 dst_origin,
9754 region,
9755 src_row_pitch,
9756 src_slice_pitch,
9757 dst_row_pitch,
9758 dst_slice_pitch,
9759 events,
9760 event);
9761}
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01009762
9763inline cl_int enqueueCopyBufferRect(
9764 const Buffer& src,
9765 const Buffer& dst,
9766 const array<size_type, 2>& src_origin,
9767 const array<size_type, 2>& dst_origin,
9768 const array<size_type, 2>& region,
9769 size_type src_row_pitch,
9770 size_type src_slice_pitch,
9771 size_type dst_row_pitch,
9772 size_type dst_slice_pitch,
9773 const vector<Event>* events = nullptr,
9774 Event* event = nullptr)
9775{
9776 return enqueueCopyBufferRect(
9777 src,
9778 dst,
9779 { src_origin[0], src_origin[1], 0 },
9780 { dst_origin[0], dst_origin[1], 0 },
9781 { region[0], region[1], 1 },
9782 src_row_pitch,
9783 src_slice_pitch,
9784 dst_row_pitch,
9785 dst_slice_pitch,
9786 events,
9787 event);
9788}
Anthony Barbier6ff3b192017-09-04 18:44:23 +01009789#endif // CL_HPP_TARGET_OPENCL_VERSION >= 110
9790
9791inline cl_int enqueueReadImage(
9792 const Image& image,
9793 cl_bool blocking,
9794 const array<size_type, 3>& origin,
9795 const array<size_type, 3>& region,
9796 size_type row_pitch,
9797 size_type slice_pitch,
9798 void* ptr,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01009799 const vector<Event>* events = nullptr,
9800 Event* event = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01009801{
9802 cl_int error;
9803 CommandQueue queue = CommandQueue::getDefault(&error);
9804
9805 if (error != CL_SUCCESS) {
9806 return error;
9807 }
9808
9809 return queue.enqueueReadImage(
9810 image,
9811 blocking,
9812 origin,
9813 region,
9814 row_pitch,
9815 slice_pitch,
9816 ptr,
9817 events,
9818 event);
9819}
9820
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01009821inline cl_int enqueueReadImage(
9822 const Image& image,
9823 cl_bool blocking,
9824 const array<size_type, 2>& origin,
9825 const array<size_type, 2>& region,
9826 size_type row_pitch,
9827 size_type slice_pitch,
9828 void* ptr,
9829 const vector<Event>* events = nullptr,
9830 Event* event = nullptr)
9831{
9832 return enqueueReadImage(
9833 image,
9834 blocking,
9835 { origin[0], origin[1], 0 },
9836 { region[0], region[1], 1 },
9837 row_pitch,
9838 slice_pitch,
9839 ptr,
9840 events,
9841 event);
9842}
9843
Anthony Barbier6ff3b192017-09-04 18:44:23 +01009844inline cl_int enqueueWriteImage(
9845 const Image& image,
9846 cl_bool blocking,
9847 const array<size_type, 3>& origin,
9848 const array<size_type, 3>& region,
9849 size_type row_pitch,
9850 size_type slice_pitch,
Anthony Barbier8b2fdc92018-08-09 11:42:38 +01009851 const void* ptr,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01009852 const vector<Event>* events = nullptr,
9853 Event* event = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01009854{
9855 cl_int error;
9856 CommandQueue queue = CommandQueue::getDefault(&error);
9857
9858 if (error != CL_SUCCESS) {
9859 return error;
9860 }
9861
9862 return queue.enqueueWriteImage(
9863 image,
9864 blocking,
9865 origin,
9866 region,
9867 row_pitch,
9868 slice_pitch,
9869 ptr,
9870 events,
9871 event);
9872}
9873
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01009874inline cl_int enqueueWriteImage(
9875 const Image& image,
9876 cl_bool blocking,
9877 const array<size_type, 2>& origin,
9878 const array<size_type, 2>& region,
9879 size_type row_pitch,
9880 size_type slice_pitch,
9881 const void* ptr,
9882 const vector<Event>* events = nullptr,
9883 Event* event = nullptr)
9884{
9885 return enqueueWriteImage(
9886 image,
9887 blocking,
9888 { origin[0], origin[1], 0 },
9889 { region[0], region[1], 1 },
9890 row_pitch,
9891 slice_pitch,
9892 ptr,
9893 events,
9894 event);
9895}
9896
Anthony Barbier6ff3b192017-09-04 18:44:23 +01009897inline cl_int enqueueCopyImage(
9898 const Image& src,
9899 const Image& dst,
9900 const array<size_type, 3>& src_origin,
9901 const array<size_type, 3>& dst_origin,
9902 const array<size_type, 3>& region,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01009903 const vector<Event>* events = nullptr,
9904 Event* event = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01009905{
9906 cl_int error;
9907 CommandQueue queue = CommandQueue::getDefault(&error);
9908
9909 if (error != CL_SUCCESS) {
9910 return error;
9911 }
9912
9913 return queue.enqueueCopyImage(
9914 src,
9915 dst,
9916 src_origin,
9917 dst_origin,
9918 region,
9919 events,
9920 event);
9921}
9922
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01009923inline cl_int enqueueCopyImage(
9924 const Image& src,
9925 const Image& dst,
9926 const array<size_type, 2>& src_origin,
9927 const array<size_type, 2>& dst_origin,
9928 const array<size_type, 2>& region,
9929 const vector<Event>* events = nullptr,
9930 Event* event = nullptr)
9931{
9932 return enqueueCopyImage(
9933 src,
9934 dst,
9935 { src_origin[0], src_origin[1], 0 },
9936 { dst_origin[0], dst_origin[1], 0 },
9937 { region[0], region[1], 1 },
9938 events,
9939 event);
9940}
9941
Anthony Barbier6ff3b192017-09-04 18:44:23 +01009942inline cl_int enqueueCopyImageToBuffer(
9943 const Image& src,
9944 const Buffer& dst,
9945 const array<size_type, 3>& src_origin,
9946 const array<size_type, 3>& region,
9947 size_type dst_offset,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01009948 const vector<Event>* events = nullptr,
9949 Event* event = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01009950{
9951 cl_int error;
9952 CommandQueue queue = CommandQueue::getDefault(&error);
9953
9954 if (error != CL_SUCCESS) {
9955 return error;
9956 }
9957
9958 return queue.enqueueCopyImageToBuffer(
9959 src,
9960 dst,
9961 src_origin,
9962 region,
9963 dst_offset,
9964 events,
9965 event);
9966}
9967
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01009968inline cl_int enqueueCopyImageToBuffer(
9969 const Image& src,
9970 const Buffer& dst,
9971 const array<size_type, 2>& src_origin,
9972 const array<size_type, 2>& region,
9973 size_type dst_offset,
9974 const vector<Event>* events = nullptr,
9975 Event* event = nullptr)
9976{
9977 return enqueueCopyImageToBuffer(
9978 src,
9979 dst,
9980 { src_origin[0], src_origin[1], 0 },
9981 { region[0], region[1], 1 },
9982 dst_offset,
9983 events,
9984 event);
9985}
9986
Anthony Barbier6ff3b192017-09-04 18:44:23 +01009987inline cl_int enqueueCopyBufferToImage(
9988 const Buffer& src,
9989 const Image& dst,
9990 size_type src_offset,
9991 const array<size_type, 3>& dst_origin,
9992 const array<size_type, 3>& region,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +01009993 const vector<Event>* events = nullptr,
9994 Event* event = nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01009995{
9996 cl_int error;
9997 CommandQueue queue = CommandQueue::getDefault(&error);
9998
9999 if (error != CL_SUCCESS) {
10000 return error;
10001 }
10002
10003 return queue.enqueueCopyBufferToImage(
10004 src,
10005 dst,
10006 src_offset,
10007 dst_origin,
10008 region,
10009 events,
10010 event);
10011}
10012
Viet-Hoa Do633ebd12023-08-11 12:27:59 +010010013inline cl_int enqueueCopyBufferToImage(
10014 const Buffer& src,
10015 const Image& dst,
10016 size_type src_offset,
10017 const array<size_type, 2>& dst_origin,
10018 const array<size_type, 2>& region,
10019 const vector<Event>* events = nullptr,
10020 Event* event = nullptr)
10021{
10022 cl_int error;
10023 CommandQueue queue = CommandQueue::getDefault(&error);
10024
10025 if (error != CL_SUCCESS) {
10026 return error;
10027 }
10028
10029 return enqueueCopyBufferToImage(
10030 src,
10031 dst,
10032 src_offset,
10033 { dst_origin[0], dst_origin[1], 0 },
10034 { region[0], region[1], 1 },
10035 events,
10036 event);
10037}
Anthony Barbier6ff3b192017-09-04 18:44:23 +010010038
10039inline cl_int flush(void)
10040{
10041 cl_int error;
10042 CommandQueue queue = CommandQueue::getDefault(&error);
10043
10044 if (error != CL_SUCCESS) {
10045 return error;
10046 }
10047
10048 return queue.flush();
10049}
10050
10051inline cl_int finish(void)
10052{
10053 cl_int error;
10054 CommandQueue queue = CommandQueue::getDefault(&error);
10055
10056 if (error != CL_SUCCESS) {
10057 return error;
10058 }
10059
10060
10061 return queue.finish();
10062}
10063
10064class EnqueueArgs
10065{
10066private:
10067 CommandQueue queue_;
10068 const NDRange offset_;
10069 const NDRange global_;
10070 const NDRange local_;
10071 vector<Event> events_;
10072
10073 template<typename... Ts>
10074 friend class KernelFunctor;
10075
10076public:
10077 EnqueueArgs(NDRange global) :
10078 queue_(CommandQueue::getDefault()),
10079 offset_(NullRange),
10080 global_(global),
10081 local_(NullRange)
10082 {
10083
10084 }
10085
10086 EnqueueArgs(NDRange global, NDRange local) :
10087 queue_(CommandQueue::getDefault()),
10088 offset_(NullRange),
10089 global_(global),
10090 local_(local)
10091 {
10092
10093 }
10094
10095 EnqueueArgs(NDRange offset, NDRange global, NDRange local) :
10096 queue_(CommandQueue::getDefault()),
10097 offset_(offset),
10098 global_(global),
10099 local_(local)
10100 {
10101
10102 }
10103
10104 EnqueueArgs(Event e, NDRange global) :
10105 queue_(CommandQueue::getDefault()),
10106 offset_(NullRange),
10107 global_(global),
10108 local_(NullRange)
10109 {
10110 events_.push_back(e);
10111 }
10112
10113 EnqueueArgs(Event e, NDRange global, NDRange local) :
10114 queue_(CommandQueue::getDefault()),
10115 offset_(NullRange),
10116 global_(global),
10117 local_(local)
10118 {
10119 events_.push_back(e);
10120 }
10121
10122 EnqueueArgs(Event e, NDRange offset, NDRange global, NDRange local) :
10123 queue_(CommandQueue::getDefault()),
10124 offset_(offset),
10125 global_(global),
10126 local_(local)
10127 {
10128 events_.push_back(e);
10129 }
10130
10131 EnqueueArgs(const vector<Event> &events, NDRange global) :
10132 queue_(CommandQueue::getDefault()),
10133 offset_(NullRange),
10134 global_(global),
10135 local_(NullRange),
10136 events_(events)
10137 {
10138
10139 }
10140
10141 EnqueueArgs(const vector<Event> &events, NDRange global, NDRange local) :
10142 queue_(CommandQueue::getDefault()),
10143 offset_(NullRange),
10144 global_(global),
10145 local_(local),
10146 events_(events)
10147 {
10148
10149 }
10150
10151 EnqueueArgs(const vector<Event> &events, NDRange offset, NDRange global, NDRange local) :
10152 queue_(CommandQueue::getDefault()),
10153 offset_(offset),
10154 global_(global),
10155 local_(local),
10156 events_(events)
10157 {
10158
10159 }
10160
10161 EnqueueArgs(CommandQueue &queue, NDRange global) :
10162 queue_(queue),
10163 offset_(NullRange),
10164 global_(global),
10165 local_(NullRange)
10166 {
10167
10168 }
10169
10170 EnqueueArgs(CommandQueue &queue, NDRange global, NDRange local) :
10171 queue_(queue),
10172 offset_(NullRange),
10173 global_(global),
10174 local_(local)
10175 {
10176
10177 }
10178
10179 EnqueueArgs(CommandQueue &queue, NDRange offset, NDRange global, NDRange local) :
10180 queue_(queue),
10181 offset_(offset),
10182 global_(global),
10183 local_(local)
10184 {
10185
10186 }
10187
10188 EnqueueArgs(CommandQueue &queue, Event e, NDRange global) :
10189 queue_(queue),
10190 offset_(NullRange),
10191 global_(global),
10192 local_(NullRange)
10193 {
10194 events_.push_back(e);
10195 }
10196
10197 EnqueueArgs(CommandQueue &queue, Event e, NDRange global, NDRange local) :
10198 queue_(queue),
10199 offset_(NullRange),
10200 global_(global),
10201 local_(local)
10202 {
10203 events_.push_back(e);
10204 }
10205
10206 EnqueueArgs(CommandQueue &queue, Event e, NDRange offset, NDRange global, NDRange local) :
10207 queue_(queue),
10208 offset_(offset),
10209 global_(global),
10210 local_(local)
10211 {
10212 events_.push_back(e);
10213 }
10214
10215 EnqueueArgs(CommandQueue &queue, const vector<Event> &events, NDRange global) :
10216 queue_(queue),
10217 offset_(NullRange),
10218 global_(global),
10219 local_(NullRange),
10220 events_(events)
10221 {
10222
10223 }
10224
10225 EnqueueArgs(CommandQueue &queue, const vector<Event> &events, NDRange global, NDRange local) :
10226 queue_(queue),
10227 offset_(NullRange),
10228 global_(global),
10229 local_(local),
10230 events_(events)
10231 {
10232
10233 }
10234
10235 EnqueueArgs(CommandQueue &queue, const vector<Event> &events, NDRange offset, NDRange global, NDRange local) :
10236 queue_(queue),
10237 offset_(offset),
10238 global_(global),
10239 local_(local),
10240 events_(events)
10241 {
10242
10243 }
10244};
10245
10246
10247//----------------------------------------------------------------------------------------------
10248
10249
10250/**
10251 * Type safe kernel functor.
10252 *
10253 */
10254template<typename... Ts>
10255class KernelFunctor
10256{
10257private:
10258 Kernel kernel_;
10259
10260 template<int index, typename T0, typename... T1s>
10261 void setArgs(T0&& t0, T1s&&... t1s)
10262 {
10263 kernel_.setArg(index, t0);
10264 setArgs<index + 1, T1s...>(std::forward<T1s>(t1s)...);
10265 }
10266
10267 template<int index, typename T0>
10268 void setArgs(T0&& t0)
10269 {
10270 kernel_.setArg(index, t0);
10271 }
10272
10273 template<int index>
10274 void setArgs()
10275 {
10276 }
10277
10278
10279public:
10280 KernelFunctor(Kernel kernel) : kernel_(kernel)
10281 {}
10282
10283 KernelFunctor(
10284 const Program& program,
10285 const string name,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +010010286 cl_int * err = nullptr) :
Anthony Barbier6ff3b192017-09-04 18:44:23 +010010287 kernel_(program, name.c_str(), err)
10288 {}
10289
10290 //! \brief Return type of the functor
10291 typedef Event result_type;
10292
10293 /**
10294 * Enqueue kernel.
10295 * @param args Launch parameters of the kernel.
10296 * @param t0... List of kernel arguments based on the template type of the functor.
10297 */
10298 Event operator() (
10299 const EnqueueArgs& args,
10300 Ts... ts)
10301 {
10302 Event event;
10303 setArgs<0>(std::forward<Ts>(ts)...);
10304
10305 args.queue_.enqueueNDRangeKernel(
10306 kernel_,
10307 args.offset_,
10308 args.global_,
10309 args.local_,
10310 &args.events_,
10311 &event);
10312
10313 return event;
10314 }
10315
10316 /**
10317 * Enqueue kernel with support for error code.
10318 * @param args Launch parameters of the kernel.
10319 * @param t0... List of kernel arguments based on the template type of the functor.
10320 * @param error Out parameter returning the error code from the execution.
10321 */
10322 Event operator() (
10323 const EnqueueArgs& args,
10324 Ts... ts,
10325 cl_int &error)
10326 {
10327 Event event;
10328 setArgs<0>(std::forward<Ts>(ts)...);
10329
10330 error = args.queue_.enqueueNDRangeKernel(
10331 kernel_,
10332 args.offset_,
10333 args.global_,
10334 args.local_,
10335 &args.events_,
10336 &event);
10337
10338 return event;
10339 }
10340
10341#if CL_HPP_TARGET_OPENCL_VERSION >= 200
10342 cl_int setSVMPointers(const vector<void*> &pointerList)
10343 {
10344 return kernel_.setSVMPointers(pointerList);
10345 }
10346
10347 template<typename T0, typename... T1s>
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +000010348 cl_int setSVMPointers(const T0 &t0, T1s &... ts)
Anthony Barbier6ff3b192017-09-04 18:44:23 +010010349 {
10350 return kernel_.setSVMPointers(t0, ts...);
10351 }
10352#endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 200
10353
10354 Kernel getKernel()
10355 {
10356 return kernel_;
10357 }
10358};
10359
10360namespace compatibility {
10361 /**
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +000010362 * Backward compatibility class to ensure that cl.hpp code works with opencl.hpp.
Anthony Barbier6ff3b192017-09-04 18:44:23 +010010363 * Please use KernelFunctor directly.
10364 */
10365 template<typename... Ts>
10366 struct make_kernel
10367 {
10368 typedef KernelFunctor<Ts...> FunctorType;
10369
10370 FunctorType functor_;
10371
10372 make_kernel(
10373 const Program& program,
10374 const string name,
Viet-Hoa Do633ebd12023-08-11 12:27:59 +010010375 cl_int * err = nullptr) :
Anthony Barbier6ff3b192017-09-04 18:44:23 +010010376 functor_(FunctorType(program, name, err))
10377 {}
10378
10379 make_kernel(
10380 const Kernel kernel) :
10381 functor_(FunctorType(kernel))
10382 {}
10383
10384 //! \brief Return type of the functor
10385 typedef Event result_type;
10386
10387 //! \brief Function signature of kernel functor with no event dependency.
10388 typedef Event type_(
10389 const EnqueueArgs&,
10390 Ts...);
10391
10392 Event operator()(
10393 const EnqueueArgs& enqueueArgs,
10394 Ts... args)
10395 {
10396 return functor_(
10397 enqueueArgs, args...);
10398 }
10399 };
10400} // namespace compatibility
10401
Viet-Hoa Do633ebd12023-08-11 12:27:59 +010010402#ifdef cl_khr_semaphore
10403class Semaphore : public detail::Wrapper<cl_semaphore_khr>
10404{
10405public:
10406 Semaphore() : detail::Wrapper<cl_type>() {}
10407 Semaphore(
10408 const Context &context,
10409 const vector<cl_semaphore_properties_khr>& sema_props,
10410 cl_int *err = nullptr)
10411 {
10412 /* initialization of addresses to extension functions (it is done only once) */
10413 std::call_once(ext_init_, initExtensions, context);
Anthony Barbier6ff3b192017-09-04 18:44:23 +010010414
Viet-Hoa Do633ebd12023-08-11 12:27:59 +010010415 cl_int error = CL_INVALID_OPERATION;
10416
10417 if (pfn_clCreateSemaphoreWithPropertiesKHR)
10418 {
10419 object_ = pfn_clCreateSemaphoreWithPropertiesKHR(
10420 context(),
10421 sema_props.data(),
10422 &error);
10423 }
10424
10425 detail::errHandler(error, __CREATE_SEMAPHORE_KHR_WITH_PROPERTIES_ERR);
10426
10427 if (err != nullptr) {
10428 *err = error;
10429 }
10430 }
10431 Semaphore(
10432 const vector<cl_semaphore_properties_khr>& sema_props,
10433 cl_int* err = nullptr):Semaphore(Context::getDefault(err), sema_props, err) {}
10434
10435 explicit Semaphore(const cl_semaphore_khr& semaphore, bool retainObject = false) :
10436 detail::Wrapper<cl_type>(semaphore, retainObject) {}
10437 Semaphore& operator = (const cl_semaphore_khr& rhs) {
10438 detail::Wrapper<cl_type>::operator=(rhs);
10439 return *this;
10440 }
10441 template <typename T>
10442 cl_int getInfo(cl_semaphore_info_khr name, T* param) const
10443 {
10444 if (pfn_clGetSemaphoreInfoKHR == nullptr) {
10445 return detail::errHandler(CL_INVALID_OPERATION,
10446 __GET_SEMAPHORE_KHR_INFO_ERR);
10447 }
10448
10449 return detail::errHandler(
10450 detail::getInfo(&pfn_clGetSemaphoreInfoKHR, object_, name, param),
10451 __GET_SEMAPHORE_KHR_INFO_ERR);
10452 }
10453 template <cl_semaphore_info_khr name> typename
10454 detail::param_traits<detail::cl_semaphore_info_khr, name>::param_type
10455 getInfo(cl_int* err = nullptr) const
10456 {
10457 typename detail::param_traits<
10458 detail::cl_semaphore_info_khr, name>::param_type param;
10459 cl_int result = getInfo(name, &param);
10460 if (err != nullptr) {
10461 *err = result;
10462 }
10463 return param;
10464 }
10465
10466 cl_int retain()
10467 {
10468 if (pfn_clRetainSemaphoreKHR == nullptr) {
10469 return detail::errHandler(CL_INVALID_OPERATION,
10470 __RETAIN_SEMAPHORE_KHR_ERR);
10471 }
10472 return pfn_clRetainSemaphoreKHR(object_);
10473 }
10474
10475 cl_int release()
10476 {
10477 if (pfn_clReleaseSemaphoreKHR == nullptr) {
10478 return detail::errHandler(CL_INVALID_OPERATION,
10479 __RELEASE_SEMAPHORE_KHR_ERR);
10480 }
10481 return pfn_clReleaseSemaphoreKHR(object_);
10482 }
10483
10484private:
10485 static std::once_flag ext_init_;
10486
10487 static void initExtensions(const Context& context)
10488 {
10489#if CL_HPP_TARGET_OPENCL_VERSION >= 120
10490 Device device = context.getInfo<CL_CONTEXT_DEVICES>().at(0);
10491 cl_platform_id platform = device.getInfo<CL_DEVICE_PLATFORM>();
10492 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clCreateSemaphoreWithPropertiesKHR);
10493 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clReleaseSemaphoreKHR);
10494 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clRetainSemaphoreKHR);
10495 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clEnqueueWaitSemaphoresKHR);
10496 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clEnqueueSignalSemaphoresKHR);
10497 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clGetSemaphoreInfoKHR);
10498#else
10499 CL_HPP_INIT_CL_EXT_FCN_PTR_(clCreateSemaphoreWithPropertiesKHR);
10500 CL_HPP_INIT_CL_EXT_FCN_PTR_(clReleaseSemaphoreKHR);
10501 CL_HPP_INIT_CL_EXT_FCN_PTR_(clRetainSemaphoreKHR);
10502 CL_HPP_INIT_CL_EXT_FCN_PTR_(clEnqueueWaitSemaphoresKHR);
10503 CL_HPP_INIT_CL_EXT_FCN_PTR_(clEnqueueSignalSemaphoresKHR);
10504 CL_HPP_INIT_CL_EXT_FCN_PTR_(clGetSemaphoreInfoKHR);
10505#endif
10506 if ((pfn_clCreateSemaphoreWithPropertiesKHR == nullptr) &&
10507 (pfn_clReleaseSemaphoreKHR == nullptr) &&
10508 (pfn_clRetainSemaphoreKHR == nullptr) &&
10509 (pfn_clEnqueueWaitSemaphoresKHR == nullptr) &&
10510 (pfn_clEnqueueSignalSemaphoresKHR == nullptr) &&
10511 (pfn_clGetSemaphoreInfoKHR == nullptr))
10512 {
10513 detail::errHandler(CL_INVALID_VALUE, __CREATE_SEMAPHORE_KHR_WITH_PROPERTIES_ERR);
10514 }
10515 }
10516
10517};
10518
10519CL_HPP_DEFINE_STATIC_MEMBER_ std::once_flag Semaphore::ext_init_;
10520
10521inline cl_int CommandQueue::enqueueWaitSemaphores(
10522 const vector<Semaphore> &sema_objects,
10523 const vector<cl_semaphore_payload_khr> &sema_payloads,
10524 const vector<Event>* events_wait_list,
10525 Event *event) const
10526{
10527 cl_event tmp;
10528 cl_int err = CL_INVALID_OPERATION;
10529
10530 if (pfn_clEnqueueWaitSemaphoresKHR != nullptr) {
10531 err = pfn_clEnqueueWaitSemaphoresKHR(
10532 object_,
10533 (cl_uint)sema_objects.size(),
10534 (const cl_semaphore_khr *) &sema_objects.front(),
10535 (sema_payloads.size() > 0) ? &sema_payloads.front() : nullptr,
10536 (events_wait_list != nullptr) ? (cl_uint) events_wait_list->size() : 0,
10537 (events_wait_list != nullptr && events_wait_list->size() > 0) ? (cl_event*) &events_wait_list->front() : nullptr,
10538 (event != nullptr) ? &tmp : nullptr);
10539 }
10540
10541 detail::errHandler(err, __ENQUEUE_WAIT_SEMAPHORE_KHR_ERR);
10542
10543 if (event != nullptr && err == CL_SUCCESS)
10544 *event = tmp;
10545
10546 return err;
10547}
10548
10549inline cl_int CommandQueue::enqueueSignalSemaphores(
10550 const vector<Semaphore> &sema_objects,
10551 const vector<cl_semaphore_payload_khr>& sema_payloads,
10552 const vector<Event>* events_wait_list,
10553 Event* event)
10554{
10555 cl_event tmp;
10556 cl_int err = CL_INVALID_OPERATION;
10557
10558 if (pfn_clEnqueueSignalSemaphoresKHR != nullptr) {
10559 err = pfn_clEnqueueSignalSemaphoresKHR(
10560 object_,
10561 (cl_uint)sema_objects.size(),
10562 (const cl_semaphore_khr*) &sema_objects.front(),
10563 (sema_payloads.size() > 0) ? &sema_payloads.front() : nullptr,
10564 (events_wait_list != nullptr) ? (cl_uint) events_wait_list->size() : 0,
10565 (events_wait_list != nullptr && events_wait_list->size() > 0) ? (cl_event*) &events_wait_list->front() : nullptr,
10566 (event != nullptr) ? &tmp : nullptr);
10567 }
10568
10569 detail::errHandler(err, __ENQUEUE_SIGNAL_SEMAPHORE_KHR_ERR);
10570
10571 if (event != nullptr && err == CL_SUCCESS)
10572 *event = tmp;
10573
10574 return err;
10575}
10576
10577#endif // cl_khr_semaphore
10578
10579#if defined(cl_khr_command_buffer)
10580/*! \class CommandBufferKhr
10581 * \brief CommandBufferKhr interface for cl_command_buffer_khr.
10582 */
10583class CommandBufferKhr : public detail::Wrapper<cl_command_buffer_khr>
10584{
10585public:
10586 //! \brief Default constructor - initializes to nullptr.
10587 CommandBufferKhr() : detail::Wrapper<cl_type>() { }
10588
10589 explicit CommandBufferKhr(const vector<CommandQueue> &queues,
10590 cl_command_buffer_properties_khr properties = 0,
10591 cl_int* errcode_ret = nullptr)
10592 {
10593 cl_command_buffer_properties_khr command_buffer_properties[] = {
10594 CL_COMMAND_BUFFER_FLAGS_KHR, properties, 0
10595 };
10596
10597 /* initialization of addresses to extension functions (it is done only once) */
10598 std::call_once(ext_init_, [&] { initExtensions(queues[0].getInfo<CL_QUEUE_DEVICE>()); });
10599 cl_int error = CL_INVALID_OPERATION;
10600
10601 static_assert(sizeof(cl::CommandQueue) == sizeof(cl_command_queue),
10602 "Size of cl::CommandQueue must be equal to size of cl_command_queue");
10603
10604 if (pfn_clCreateCommandBufferKHR)
10605 {
10606 object_ = pfn_clCreateCommandBufferKHR((cl_uint) queues.size(),
10607 (cl_command_queue *) &queues.front(),
10608 command_buffer_properties,
10609 &error);
10610 }
10611
10612 detail::errHandler(error, __CREATE_COMMAND_BUFFER_KHR_ERR);
10613 if (errcode_ret != nullptr) {
10614 *errcode_ret = error;
10615 }
10616 }
10617
10618 explicit CommandBufferKhr(const cl_command_buffer_khr& commandBufferKhr, bool retainObject = false) :
10619 detail::Wrapper<cl_type>(commandBufferKhr, retainObject) { }
10620
10621 CommandBufferKhr& operator=(const cl_command_buffer_khr& rhs)
10622 {
10623 detail::Wrapper<cl_type>::operator=(rhs);
10624 return *this;
10625 }
10626
10627 template <typename T>
10628 cl_int getInfo(cl_command_buffer_info_khr name, T* param) const
10629 {
10630 if (pfn_clGetCommandBufferInfoKHR == nullptr) {
10631 return detail::errHandler(CL_INVALID_OPERATION,
10632 __GET_COMMAND_BUFFER_INFO_KHR_ERR);
10633 }
10634 return detail::errHandler(
10635 detail::getInfo(pfn_clGetCommandBufferInfoKHR, object_, name, param),
10636 __GET_COMMAND_BUFFER_INFO_KHR_ERR);
10637 }
10638
10639 template <cl_command_buffer_info_khr name> typename
10640 detail::param_traits<detail::cl_command_buffer_info_khr, name>::param_type
10641 getInfo(cl_int* err = nullptr) const
10642 {
10643 typename detail::param_traits<
10644 detail::cl_command_buffer_info_khr, name>::param_type param;
10645 cl_int result = getInfo(name, &param);
10646 if (err != nullptr) {
10647 *err = result;
10648 }
10649 return param;
10650 }
10651
10652 cl_int finalizeCommandBuffer() const
10653 {
10654 return detail::errHandler(::clFinalizeCommandBufferKHR(object_), __FINALIZE_COMMAND_BUFFER_KHR_ERR);
10655 }
10656
10657 cl_int enqueueCommandBuffer(vector<CommandQueue> &queues,
10658 const vector<Event>* events = nullptr,
10659 Event* event = nullptr)
10660 {
10661 if (pfn_clEnqueueCommandBufferKHR == nullptr) {
10662 return detail::errHandler(CL_INVALID_OPERATION,
10663 __ENQUEUE_COMMAND_BUFFER_KHR_ERR);
10664 }
10665
10666 static_assert(sizeof(cl::CommandQueue) == sizeof(cl_command_queue),
10667 "Size of cl::CommandQueue must be equal to size of cl_command_queue");
10668
10669 return detail::errHandler(pfn_clEnqueueCommandBufferKHR((cl_uint) queues.size(),
10670 (cl_command_queue *) &queues.front(),
10671 object_,
10672 (events != nullptr) ? (cl_uint) events->size() : 0,
10673 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
10674 (cl_event*) event),
10675 __ENQUEUE_COMMAND_BUFFER_KHR_ERR);
10676 }
10677
10678 cl_int commandBarrierWithWaitList(const vector<cl_sync_point_khr>* sync_points_vec = nullptr,
10679 cl_sync_point_khr* sync_point = nullptr,
10680 MutableCommandKhr* mutable_handle = nullptr,
10681 const CommandQueue* command_queue = nullptr)
10682 {
10683 if (pfn_clCommandBarrierWithWaitListKHR == nullptr) {
10684 return detail::errHandler(CL_INVALID_OPERATION,
10685 __COMMAND_BARRIER_WITH_WAIT_LIST_KHR_ERR);
10686 }
10687
10688 cl_sync_point_khr tmp_sync_point;
10689 cl_int error = detail::errHandler(
10690 pfn_clCommandBarrierWithWaitListKHR(object_,
10691 (command_queue != nullptr) ? (*command_queue)() : nullptr,
10692 (sync_points_vec != nullptr) ? (cl_uint) sync_points_vec->size() : 0,
10693 (sync_points_vec != nullptr && sync_points_vec->size() > 0) ? &sync_points_vec->front() : nullptr,
10694 (sync_point != nullptr) ? &tmp_sync_point : nullptr,
10695 (cl_mutable_command_khr*) mutable_handle),
10696 __COMMAND_BARRIER_WITH_WAIT_LIST_KHR_ERR);
10697
10698 if (sync_point != nullptr && error == CL_SUCCESS)
10699 *sync_point = tmp_sync_point;
10700
10701 return error;
10702 }
10703
10704 cl_int commandCopyBuffer(const Buffer& src,
10705 const Buffer& dst,
10706 size_type src_offset,
10707 size_type dst_offset,
10708 size_type size,
10709 const vector<cl_sync_point_khr>* sync_points_vec = nullptr,
10710 cl_sync_point_khr* sync_point = nullptr,
10711 MutableCommandKhr* mutable_handle = nullptr,
10712 const CommandQueue* command_queue = nullptr)
10713 {
10714 if (pfn_clCommandCopyBufferKHR == nullptr) {
10715 return detail::errHandler(CL_INVALID_OPERATION,
10716 __COMMAND_COPY_BUFFER_KHR_ERR);
10717 }
10718
10719 cl_sync_point_khr tmp_sync_point;
10720 cl_int error = detail::errHandler(
10721 pfn_clCommandCopyBufferKHR(object_,
10722 (command_queue != nullptr) ? (*command_queue)() : nullptr,
10723 src(),
10724 dst(),
10725 src_offset,
10726 dst_offset,
10727 size,
10728 (sync_points_vec != nullptr) ? (cl_uint) sync_points_vec->size() : 0,
10729 (sync_points_vec != nullptr && sync_points_vec->size() > 0) ? &sync_points_vec->front() : nullptr,
10730 (sync_point != nullptr) ? &tmp_sync_point : nullptr,
10731 (cl_mutable_command_khr*) mutable_handle),
10732 __COMMAND_COPY_BUFFER_KHR_ERR);
10733
10734 if (sync_point != nullptr && error == CL_SUCCESS)
10735 *sync_point = tmp_sync_point;
10736
10737 return error;
10738 }
10739
10740 cl_int commandCopyBufferRect(const Buffer& src,
10741 const Buffer& dst,
10742 const array<size_type, 3>& src_origin,
10743 const array<size_type, 3>& dst_origin,
10744 const array<size_type, 3>& region,
10745 size_type src_row_pitch,
10746 size_type src_slice_pitch,
10747 size_type dst_row_pitch,
10748 size_type dst_slice_pitch,
10749 const vector<cl_sync_point_khr>* sync_points_vec = nullptr,
10750 cl_sync_point_khr* sync_point = nullptr,
10751 MutableCommandKhr* mutable_handle = nullptr,
10752 const CommandQueue* command_queue = nullptr)
10753 {
10754 if (pfn_clCommandCopyBufferRectKHR == nullptr) {
10755 return detail::errHandler(CL_INVALID_OPERATION,
10756 __COMMAND_COPY_BUFFER_RECT_KHR_ERR);
10757 }
10758
10759 cl_sync_point_khr tmp_sync_point;
10760 cl_int error = detail::errHandler(
10761 pfn_clCommandCopyBufferRectKHR(object_,
10762 (command_queue != nullptr) ? (*command_queue)() : nullptr,
10763 src(),
10764 dst(),
10765 src_origin.data(),
10766 dst_origin.data(),
10767 region.data(),
10768 src_row_pitch,
10769 src_slice_pitch,
10770 dst_row_pitch,
10771 dst_slice_pitch,
10772 (sync_points_vec != nullptr) ? (cl_uint) sync_points_vec->size() : 0,
10773 (sync_points_vec != nullptr && sync_points_vec->size() > 0) ? &sync_points_vec->front() : nullptr,
10774 (sync_point != nullptr) ? &tmp_sync_point : nullptr,
10775 (cl_mutable_command_khr*) mutable_handle),
10776 __COMMAND_COPY_BUFFER_RECT_KHR_ERR);
10777
10778 if (sync_point != nullptr && error == CL_SUCCESS)
10779 *sync_point = tmp_sync_point;
10780
10781 return error;
10782 }
10783
10784 cl_int commandCopyBufferToImage(const Buffer& src,
10785 const Image& dst,
10786 size_type src_offset,
10787 const array<size_type, 3>& dst_origin,
10788 const array<size_type, 3>& region,
10789 const vector<cl_sync_point_khr>* sync_points_vec = nullptr,
10790 cl_sync_point_khr* sync_point = nullptr,
10791 MutableCommandKhr* mutable_handle = nullptr,
10792 const CommandQueue* command_queue = nullptr)
10793 {
10794 if (pfn_clCommandCopyBufferToImageKHR == nullptr) {
10795 return detail::errHandler(CL_INVALID_OPERATION,
10796 __COMMAND_COPY_BUFFER_TO_IMAGE_KHR_ERR);
10797 }
10798
10799 cl_sync_point_khr tmp_sync_point;
10800 cl_int error = detail::errHandler(
10801 pfn_clCommandCopyBufferToImageKHR(object_,
10802 (command_queue != nullptr) ? (*command_queue)() : nullptr,
10803 src(),
10804 dst(),
10805 src_offset,
10806 dst_origin.data(),
10807 region.data(),
10808 (sync_points_vec != nullptr) ? (cl_uint) sync_points_vec->size() : 0,
10809 (sync_points_vec != nullptr && sync_points_vec->size() > 0) ? &sync_points_vec->front() : nullptr,
10810 (sync_point != nullptr) ? &tmp_sync_point : nullptr,
10811 (cl_mutable_command_khr*) mutable_handle),
10812 __COMMAND_COPY_BUFFER_TO_IMAGE_KHR_ERR);
10813
10814 if (sync_point != nullptr && error == CL_SUCCESS)
10815 *sync_point = tmp_sync_point;
10816
10817 return error;
10818 }
10819
10820 cl_int commandCopyImage(const Image& src,
10821 const Image& dst,
10822 const array<size_type, 3>& src_origin,
10823 const array<size_type, 3>& dst_origin,
10824 const array<size_type, 3>& region,
10825 const vector<cl_sync_point_khr>* sync_points_vec = nullptr,
10826 cl_sync_point_khr* sync_point = nullptr,
10827 MutableCommandKhr* mutable_handle = nullptr,
10828 const CommandQueue* command_queue = nullptr)
10829 {
10830 if (pfn_clCommandCopyImageKHR == nullptr) {
10831 return detail::errHandler(CL_INVALID_OPERATION,
10832 __COMMAND_COPY_IMAGE_KHR_ERR);
10833 }
10834
10835 cl_sync_point_khr tmp_sync_point;
10836 cl_int error = detail::errHandler(
10837 pfn_clCommandCopyImageKHR(object_,
10838 (command_queue != nullptr) ? (*command_queue)() : nullptr,
10839 src(),
10840 dst(),
10841 src_origin.data(),
10842 dst_origin.data(),
10843 region.data(),
10844 (sync_points_vec != nullptr) ? (cl_uint) sync_points_vec->size() : 0,
10845 (sync_points_vec != nullptr && sync_points_vec->size() > 0) ? &sync_points_vec->front() : nullptr,
10846 (sync_point != nullptr) ? &tmp_sync_point : nullptr,
10847 (cl_mutable_command_khr*) mutable_handle),
10848 __COMMAND_COPY_IMAGE_KHR_ERR);
10849
10850 if (sync_point != nullptr && error == CL_SUCCESS)
10851 *sync_point = tmp_sync_point;
10852
10853 return error;
10854 }
10855
10856 cl_int commandCopyImageToBuffer(const Image& src,
10857 const Buffer& dst,
10858 const array<size_type, 3>& src_origin,
10859 const array<size_type, 3>& region,
10860 size_type dst_offset,
10861 const vector<cl_sync_point_khr>* sync_points_vec = nullptr,
10862 cl_sync_point_khr* sync_point = nullptr,
10863 MutableCommandKhr* mutable_handle = nullptr,
10864 const CommandQueue* command_queue = nullptr)
10865 {
10866 if (pfn_clCommandCopyImageToBufferKHR == nullptr) {
10867 return detail::errHandler(CL_INVALID_OPERATION,
10868 __COMMAND_COPY_IMAGE_TO_BUFFER_KHR_ERR);
10869 }
10870
10871 cl_sync_point_khr tmp_sync_point;
10872 cl_int error = detail::errHandler(
10873 pfn_clCommandCopyImageToBufferKHR(object_,
10874 (command_queue != nullptr) ? (*command_queue)() : nullptr,
10875 src(),
10876 dst(),
10877 src_origin.data(),
10878 region.data(),
10879 dst_offset,
10880 (sync_points_vec != nullptr) ? (cl_uint) sync_points_vec->size() : 0,
10881 (sync_points_vec != nullptr && sync_points_vec->size() > 0) ? &sync_points_vec->front() : nullptr,
10882 (sync_point != nullptr) ? &tmp_sync_point : nullptr,
10883 (cl_mutable_command_khr*) mutable_handle),
10884 __COMMAND_COPY_IMAGE_TO_BUFFER_KHR_ERR);
10885
10886 if (sync_point != nullptr && error == CL_SUCCESS)
10887 *sync_point = tmp_sync_point;
10888
10889 return error;
10890 }
10891
10892 template<typename PatternType>
10893 cl_int commandFillBuffer(const Buffer& buffer,
10894 PatternType pattern,
10895 size_type offset,
10896 size_type size,
10897 const vector<cl_sync_point_khr>* sync_points_vec = nullptr,
10898 cl_sync_point_khr* sync_point = nullptr,
10899 MutableCommandKhr* mutable_handle = nullptr,
10900 const CommandQueue* command_queue = nullptr)
10901 {
10902 if (pfn_clCommandFillBufferKHR == nullptr) {
10903 return detail::errHandler(CL_INVALID_OPERATION,
10904 __COMMAND_FILL_BUFFER_KHR_ERR);
10905 }
10906
10907 cl_sync_point_khr tmp_sync_point;
10908 cl_int error = detail::errHandler(
10909 pfn_clCommandFillBufferKHR(object_,
10910 (command_queue != nullptr) ? (*command_queue)() : nullptr,
10911 buffer(),
10912 static_cast<void*>(&pattern),
10913 sizeof(PatternType),
10914 offset,
10915 size,
10916 (sync_points_vec != nullptr) ? (cl_uint) sync_points_vec->size() : 0,
10917 (sync_points_vec != nullptr && sync_points_vec->size() > 0) ? &sync_points_vec->front() : nullptr,
10918 (sync_point != nullptr) ? &tmp_sync_point : nullptr,
10919 (cl_mutable_command_khr*) mutable_handle),
10920 __COMMAND_FILL_BUFFER_KHR_ERR);
10921
10922 if (sync_point != nullptr && error == CL_SUCCESS)
10923 *sync_point = tmp_sync_point;
10924
10925 return error;
10926 }
10927
10928 cl_int commandFillImage(const Image& image,
10929 cl_float4 fillColor,
10930 const array<size_type, 3>& origin,
10931 const array<size_type, 3>& region,
10932 const vector<cl_sync_point_khr>* sync_points_vec = nullptr,
10933 cl_sync_point_khr* sync_point = nullptr,
10934 MutableCommandKhr* mutable_handle = nullptr,
10935 const CommandQueue* command_queue = nullptr)
10936 {
10937 if (pfn_clCommandFillImageKHR == nullptr) {
10938 return detail::errHandler(CL_INVALID_OPERATION,
10939 __COMMAND_FILL_IMAGE_KHR_ERR);
10940 }
10941
10942 cl_sync_point_khr tmp_sync_point;
10943 cl_int error = detail::errHandler(
10944 pfn_clCommandFillImageKHR(object_,
10945 (command_queue != nullptr) ? (*command_queue)() : nullptr,
10946 image(),
10947 static_cast<void*>(&fillColor),
10948 origin.data(),
10949 region.data(),
10950 (sync_points_vec != nullptr) ? (cl_uint) sync_points_vec->size() : 0,
10951 (sync_points_vec != nullptr && sync_points_vec->size() > 0) ? &sync_points_vec->front() : nullptr,
10952 (sync_point != nullptr) ? &tmp_sync_point : nullptr,
10953 (cl_mutable_command_khr*) mutable_handle),
10954 __COMMAND_FILL_IMAGE_KHR_ERR);
10955
10956 if (sync_point != nullptr && error == CL_SUCCESS)
10957 *sync_point = tmp_sync_point;
10958
10959 return error;
10960 }
10961
10962 cl_int commandNDRangeKernel(const cl::vector<cl_ndrange_kernel_command_properties_khr> &properties,
10963 const Kernel& kernel,
10964 const NDRange& offset,
10965 const NDRange& global,
10966 const NDRange& local = NullRange,
10967 const vector<cl_sync_point_khr>* sync_points_vec = nullptr,
10968 cl_sync_point_khr* sync_point = nullptr,
10969 MutableCommandKhr* mutable_handle = nullptr,
10970 const CommandQueue* command_queue = nullptr)
10971 {
10972 if (pfn_clCommandNDRangeKernelKHR == nullptr) {
10973 return detail::errHandler(CL_INVALID_OPERATION,
10974 __COMMAND_NDRANGE_KERNEL_KHR_ERR);
10975 }
10976
10977 cl_sync_point_khr tmp_sync_point;
10978 cl_int error = detail::errHandler(
10979 pfn_clCommandNDRangeKernelKHR(object_,
10980 (command_queue != nullptr) ? (*command_queue)() : nullptr,
10981 &properties[0],
10982 kernel(),
10983 (cl_uint) global.dimensions(),
10984 offset.dimensions() != 0 ? (const size_type*) offset : nullptr,
10985 (const size_type*) global,
10986 local.dimensions() != 0 ? (const size_type*) local : nullptr,
10987 (sync_points_vec != nullptr) ? (cl_uint) sync_points_vec->size() : 0,
10988 (sync_points_vec != nullptr && sync_points_vec->size() > 0) ? &sync_points_vec->front() : nullptr,
10989 (sync_point != nullptr) ? &tmp_sync_point : nullptr,
10990 (cl_mutable_command_khr*) mutable_handle),
10991 __COMMAND_NDRANGE_KERNEL_KHR_ERR);
10992
10993 if (sync_point != nullptr && error == CL_SUCCESS)
10994 *sync_point = tmp_sync_point;
10995
10996 return error;
10997 }
10998
10999#if defined(cl_khr_command_buffer_mutable_dispatch)
11000 cl_int updateMutableCommands(const cl_mutable_base_config_khr* mutable_config)
11001 {
11002 if (pfn_clUpdateMutableCommandsKHR == nullptr) {
11003 return detail::errHandler(CL_INVALID_OPERATION,
11004 __UPDATE_MUTABLE_COMMANDS_KHR_ERR);
11005 }
11006 return detail::errHandler(pfn_clUpdateMutableCommandsKHR(object_, mutable_config),
11007 __UPDATE_MUTABLE_COMMANDS_KHR_ERR);
11008 }
11009#endif /* cl_khr_command_buffer_mutable_dispatch */
11010
11011private:
11012 static std::once_flag ext_init_;
11013
11014 static void initExtensions(const cl::Device& device)
11015 {
11016#if CL_HPP_TARGET_OPENCL_VERSION >= 120
11017 cl_platform_id platform = device.getInfo<CL_DEVICE_PLATFORM>();
11018 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clCreateCommandBufferKHR);
11019 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clFinalizeCommandBufferKHR);
11020 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clRetainCommandBufferKHR);
11021 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clReleaseCommandBufferKHR);
11022 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clGetCommandBufferInfoKHR);
11023 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clEnqueueCommandBufferKHR);
11024 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clCommandBarrierWithWaitListKHR);
11025 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clCommandCopyBufferKHR);
11026 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clCommandCopyBufferRectKHR);
11027 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clCommandCopyBufferToImageKHR);
11028 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clCommandCopyImageKHR);
11029 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clCommandCopyImageToBufferKHR);
11030 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clCommandFillBufferKHR);
11031 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clCommandFillImageKHR);
11032 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clCommandNDRangeKernelKHR);
11033#if defined(cl_khr_command_buffer_mutable_dispatch)
11034 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clUpdateMutableCommandsKHR);
11035 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clGetMutableCommandInfoKHR);
11036#endif /* cl_khr_command_buffer_mutable_dispatch */
11037#elif CL_HPP_TARGET_OPENCL_VERSION >= 110
11038 CL_HPP_INIT_CL_EXT_FCN_PTR_(clCreateCommandBufferKHR);
11039 CL_HPP_INIT_CL_EXT_FCN_PTR_(clFinalizeCommandBufferKHR);
11040 CL_HPP_INIT_CL_EXT_FCN_PTR_(clRetainCommandBufferKHR);
11041 CL_HPP_INIT_CL_EXT_FCN_PTR_(clReleaseCommandBufferKHR);
11042 CL_HPP_INIT_CL_EXT_FCN_PTR_(clGetCommandBufferInfoKHR);
11043 CL_HPP_INIT_CL_EXT_FCN_PTR_(clEnqueueCommandBufferKHR);
11044 CL_HPP_INIT_CL_EXT_FCN_PTR_(clCommandBarrierWithWaitListKHR);
11045 CL_HPP_INIT_CL_EXT_FCN_PTR_(clCommandCopyBufferKHR);
11046 CL_HPP_INIT_CL_EXT_FCN_PTR_(clCommandCopyBufferRectKHR);
11047 CL_HPP_INIT_CL_EXT_FCN_PTR_(clCommandCopyBufferToImageKHR);
11048 CL_HPP_INIT_CL_EXT_FCN_PTR_(clCommandCopyImageKHR);
11049 CL_HPP_INIT_CL_EXT_FCN_PTR_(clCommandCopyImageToBufferKHR);
11050 CL_HPP_INIT_CL_EXT_FCN_PTR_(clCommandFillBufferKHR);
11051 CL_HPP_INIT_CL_EXT_FCN_PTR_(clCommandFillImageKHR);
11052 CL_HPP_INIT_CL_EXT_FCN_PTR_(clCommandNDRangeKernelKHR);
11053#if defined(cl_khr_command_buffer_mutable_dispatch)
11054 CL_HPP_INIT_CL_EXT_FCN_PTR_(clUpdateMutableCommandsKHR);
11055 CL_HPP_INIT_CL_EXT_FCN_PTR_(clGetMutableCommandInfoKHR);
11056#endif /* cl_khr_command_buffer_mutable_dispatch */
11057#endif
11058 if ((pfn_clCreateCommandBufferKHR == nullptr) &&
11059 (pfn_clFinalizeCommandBufferKHR == nullptr) &&
11060 (pfn_clRetainCommandBufferKHR == nullptr) &&
11061 (pfn_clReleaseCommandBufferKHR == nullptr) &&
11062 (pfn_clGetCommandBufferInfoKHR == nullptr) &&
11063 (pfn_clEnqueueCommandBufferKHR == nullptr) &&
11064 (pfn_clCommandBarrierWithWaitListKHR == nullptr) &&
11065 (pfn_clCommandCopyBufferKHR == nullptr) &&
11066 (pfn_clCommandCopyBufferRectKHR == nullptr) &&
11067 (pfn_clCommandCopyBufferToImageKHR == nullptr) &&
11068 (pfn_clCommandCopyImageKHR == nullptr) &&
11069 (pfn_clCommandCopyImageToBufferKHR == nullptr) &&
11070 (pfn_clCommandFillBufferKHR == nullptr) &&
11071 (pfn_clCommandFillImageKHR == nullptr) &&
11072 (pfn_clCommandNDRangeKernelKHR == nullptr)
11073#if defined(cl_khr_command_buffer_mutable_dispatch)
11074 && (pfn_clUpdateMutableCommandsKHR == nullptr)
11075 && (pfn_clGetMutableCommandInfoKHR == nullptr)
11076#endif /* cl_khr_command_buffer_mutable_dispatch */
11077 )
11078 {
11079 detail::errHandler(CL_INVALID_VALUE, __CREATE_COMMAND_BUFFER_KHR_ERR);
11080 }
11081 }
11082}; // CommandBufferKhr
11083
11084CL_HPP_DEFINE_STATIC_MEMBER_ std::once_flag CommandBufferKhr::ext_init_;
11085
11086#if defined(cl_khr_command_buffer_mutable_dispatch)
11087/*! \class MutableCommandKhr
11088 * \brief MutableCommandKhr interface for cl_mutable_command_khr.
11089 */
11090class MutableCommandKhr : public detail::Wrapper<cl_mutable_command_khr>
11091{
11092public:
11093 //! \brief Default constructor - initializes to nullptr.
11094 MutableCommandKhr() : detail::Wrapper<cl_type>() { }
11095
11096 explicit MutableCommandKhr(const cl_mutable_command_khr& mutableCommandKhr, bool retainObject = false) :
11097 detail::Wrapper<cl_type>(mutableCommandKhr, retainObject) { }
11098
11099 MutableCommandKhr& operator=(const cl_mutable_command_khr& rhs)
11100 {
11101 detail::Wrapper<cl_type>::operator=(rhs);
11102 return *this;
11103 }
11104
11105 template <typename T>
11106 cl_int getInfo(cl_mutable_command_info_khr name, T* param) const
11107 {
11108 if (pfn_clGetMutableCommandInfoKHR == nullptr) {
11109 return detail::errHandler(CL_INVALID_OPERATION,
11110 __GET_MUTABLE_COMMAND_INFO_KHR_ERR);
11111 }
11112 return detail::errHandler(
11113 detail::getInfo(pfn_clGetMutableCommandInfoKHR, object_, name, param),
11114 __GET_MUTABLE_COMMAND_INFO_KHR_ERR);
11115 }
11116
11117 template <cl_mutable_command_info_khr name> typename
11118 detail::param_traits<detail::cl_mutable_command_info_khr, name>::param_type
11119 getInfo(cl_int* err = nullptr) const
11120 {
11121 typename detail::param_traits<
11122 detail::cl_mutable_command_info_khr, name>::param_type param;
11123 cl_int result = getInfo(name, &param);
11124 if (err != nullptr) {
11125 *err = result;
11126 }
11127 return param;
11128 }
11129}; // MutableCommandKhr
11130#endif /* cl_khr_command_buffer_mutable_dispatch */
11131
11132#endif // cl_khr_command_buffer
Anthony Barbier6ff3b192017-09-04 18:44:23 +010011133//----------------------------------------------------------------------------------------------------------------------
11134
11135#undef CL_HPP_ERR_STR_
11136#if !defined(CL_HPP_USER_OVERRIDE_ERROR_STRINGS)
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +000011137#undef __GET_DEVICE_INFO_ERR
11138#undef __GET_PLATFORM_INFO_ERR
11139#undef __GET_DEVICE_IDS_ERR
11140#undef __GET_PLATFORM_IDS_ERR
11141#undef __GET_CONTEXT_INFO_ERR
11142#undef __GET_EVENT_INFO_ERR
11143#undef __GET_EVENT_PROFILE_INFO_ERR
11144#undef __GET_MEM_OBJECT_INFO_ERR
11145#undef __GET_IMAGE_INFO_ERR
11146#undef __GET_SAMPLER_INFO_ERR
11147#undef __GET_KERNEL_INFO_ERR
11148#undef __GET_KERNEL_ARG_INFO_ERR
11149#undef __GET_KERNEL_SUB_GROUP_INFO_ERR
11150#undef __GET_KERNEL_WORK_GROUP_INFO_ERR
11151#undef __GET_PROGRAM_INFO_ERR
11152#undef __GET_PROGRAM_BUILD_INFO_ERR
11153#undef __GET_COMMAND_QUEUE_INFO_ERR
11154#undef __CREATE_CONTEXT_ERR
Viet-Hoa Do633ebd12023-08-11 12:27:59 +010011155#undef __CREATE_CONTEXT_FROM_TYPE_ERR
11156#undef __CREATE_COMMAND_BUFFER_KHR_ERR
11157#undef __GET_COMMAND_BUFFER_INFO_KHR_ERR
11158#undef __FINALIZE_COMMAND_BUFFER_KHR_ERR
11159#undef __ENQUEUE_COMMAND_BUFFER_KHR_ERR
11160#undef __COMMAND_BARRIER_WITH_WAIT_LIST_KHR_ERR
11161#undef __COMMAND_COPY_BUFFER_KHR_ERR
11162#undef __COMMAND_COPY_BUFFER_RECT_KHR_ERR
11163#undef __COMMAND_COPY_BUFFER_TO_IMAGE_KHR_ERR
11164#undef __COMMAND_COPY_IMAGE_KHR_ERR
11165#undef __COMMAND_COPY_IMAGE_TO_BUFFER_KHR_ERR
11166#undef __COMMAND_FILL_BUFFER_KHR_ERR
11167#undef __COMMAND_FILL_IMAGE_KHR_ERR
11168#undef __COMMAND_NDRANGE_KERNEL_KHR_ERR
11169#undef __UPDATE_MUTABLE_COMMANDS_KHR_ERR
11170#undef __GET_MUTABLE_COMMAND_INFO_KHR_ERR
11171#undef __RETAIN_COMMAND_BUFFER_KHR_ERR
11172#undef __RELEASE_COMMAND_BUFFER_KHR_ERR
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +000011173#undef __GET_SUPPORTED_IMAGE_FORMATS_ERR
Viet-Hoa Do633ebd12023-08-11 12:27:59 +010011174#undef __SET_CONTEXT_DESCTRUCTOR_CALLBACK_ERR
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +000011175#undef __CREATE_BUFFER_ERR
11176#undef __COPY_ERR
11177#undef __CREATE_SUBBUFFER_ERR
11178#undef __CREATE_GL_BUFFER_ERR
11179#undef __CREATE_GL_RENDER_BUFFER_ERR
11180#undef __GET_GL_OBJECT_INFO_ERR
11181#undef __CREATE_IMAGE_ERR
11182#undef __CREATE_GL_TEXTURE_ERR
11183#undef __IMAGE_DIMENSION_ERR
11184#undef __SET_MEM_OBJECT_DESTRUCTOR_CALLBACK_ERR
11185#undef __CREATE_USER_EVENT_ERR
11186#undef __SET_USER_EVENT_STATUS_ERR
11187#undef __SET_EVENT_CALLBACK_ERR
11188#undef __WAIT_FOR_EVENTS_ERR
11189#undef __CREATE_KERNEL_ERR
11190#undef __SET_KERNEL_ARGS_ERR
11191#undef __CREATE_PROGRAM_WITH_SOURCE_ERR
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +000011192#undef __CREATE_PROGRAM_WITH_BINARY_ERR
11193#undef __CREATE_PROGRAM_WITH_IL_ERR
11194#undef __CREATE_PROGRAM_WITH_BUILT_IN_KERNELS_ERR
11195#undef __BUILD_PROGRAM_ERR
11196#undef __COMPILE_PROGRAM_ERR
11197#undef __LINK_PROGRAM_ERR
11198#undef __CREATE_KERNELS_IN_PROGRAM_ERR
11199#undef __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR
11200#undef __CREATE_SAMPLER_WITH_PROPERTIES_ERR
11201#undef __SET_COMMAND_QUEUE_PROPERTY_ERR
11202#undef __ENQUEUE_READ_BUFFER_ERR
11203#undef __ENQUEUE_READ_BUFFER_RECT_ERR
11204#undef __ENQUEUE_WRITE_BUFFER_ERR
11205#undef __ENQUEUE_WRITE_BUFFER_RECT_ERR
11206#undef __ENQEUE_COPY_BUFFER_ERR
11207#undef __ENQEUE_COPY_BUFFER_RECT_ERR
11208#undef __ENQUEUE_FILL_BUFFER_ERR
11209#undef __ENQUEUE_READ_IMAGE_ERR
11210#undef __ENQUEUE_WRITE_IMAGE_ERR
11211#undef __ENQUEUE_COPY_IMAGE_ERR
11212#undef __ENQUEUE_FILL_IMAGE_ERR
11213#undef __ENQUEUE_COPY_IMAGE_TO_BUFFER_ERR
11214#undef __ENQUEUE_COPY_BUFFER_TO_IMAGE_ERR
11215#undef __ENQUEUE_MAP_BUFFER_ERR
11216#undef __ENQUEUE_MAP_IMAGE_ERR
11217#undef __ENQUEUE_UNMAP_MEM_OBJECT_ERR
11218#undef __ENQUEUE_NDRANGE_KERNEL_ERR
11219#undef __ENQUEUE_NATIVE_KERNEL
11220#undef __ENQUEUE_MIGRATE_MEM_OBJECTS_ERR
11221#undef __ENQUEUE_MIGRATE_SVM_ERR
11222#undef __ENQUEUE_ACQUIRE_GL_ERR
11223#undef __ENQUEUE_RELEASE_GL_ERR
11224#undef __CREATE_PIPE_ERR
11225#undef __GET_PIPE_INFO_ERR
11226#undef __RETAIN_ERR
11227#undef __RELEASE_ERR
11228#undef __FLUSH_ERR
11229#undef __FINISH_ERR
11230#undef __VECTOR_CAPACITY_ERR
Viet-Hoa Do633ebd12023-08-11 12:27:59 +010011231#undef __CREATE_SUB_DEVICES_ERR
11232#undef __ENQUEUE_ACQUIRE_EXTERNAL_MEMORY_ERR
11233#undef __ENQUEUE_RELEASE_EXTERNAL_MEMORY_ERR
Pablo Marquez Tellodc2282f2021-11-23 15:16:00 +000011234#undef __ENQUEUE_MARKER_ERR
11235#undef __ENQUEUE_WAIT_FOR_EVENTS_ERR
11236#undef __ENQUEUE_BARRIER_ERR
11237#undef __UNLOAD_COMPILER_ERR
11238#undef __CREATE_GL_TEXTURE_2D_ERR
11239#undef __CREATE_GL_TEXTURE_3D_ERR
11240#undef __CREATE_IMAGE2D_ERR
11241#undef __CREATE_IMAGE3D_ERR
11242#undef __CREATE_COMMAND_QUEUE_ERR
11243#undef __ENQUEUE_TASK_ERR
11244#undef __CREATE_SAMPLER_ERR
11245#undef __ENQUEUE_MARKER_WAIT_LIST_ERR
11246#undef __ENQUEUE_BARRIER_WAIT_LIST_ERR
11247#undef __CLONE_KERNEL_ERR
11248#undef __GET_HOST_TIMER_ERR
11249#undef __GET_DEVICE_AND_HOST_TIMER_ERR
Viet-Hoa Do633ebd12023-08-11 12:27:59 +010011250#undef __GET_SEMAPHORE_KHR_INFO_ERR
11251#undef __CREATE_SEMAPHORE_KHR_WITH_PROPERTIES_ERR
11252#undef __ENQUEUE_WAIT_SEMAPHORE_KHR_ERR
11253#undef __ENQUEUE_SIGNAL_SEMAPHORE_KHR_ERR
Anthony Barbier6ff3b192017-09-04 18:44:23 +010011254
11255#endif //CL_HPP_USER_OVERRIDE_ERROR_STRINGS
11256
11257// Extensions
Viet-Hoa Do633ebd12023-08-11 12:27:59 +010011258#undef CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_
Anthony Barbier6ff3b192017-09-04 18:44:23 +010011259#undef CL_HPP_INIT_CL_EXT_FCN_PTR_
11260#undef CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_
11261
Anthony Barbier6ff3b192017-09-04 18:44:23 +010011262#undef CL_HPP_NOEXCEPT_
11263#undef CL_HPP_DEFINE_STATIC_MEMBER_
11264
11265} // namespace cl
11266
11267#endif // CL_HPP_