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