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