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