diff --git a/CHANGELOG.md b/CHANGELOG.md index 9378d09..6a3a36d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ All notable changes to this project will be documented in this file. ### Changed - Use cl::sycl::id parameters instead of cl::sycl::item. +- Update local copy of OpenCL C++ header file. ### Removed - Pre-building of kernels in SYCL version to ensure compatibility with SYCL 1.2.1. diff --git a/CL/cl2.hpp b/CL/cl2.hpp index e0f55fe..09e295e 100644 --- a/CL/cl2.hpp +++ b/CL/cl2.hpp @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2008-2015 The Khronos Group Inc. + * Copyright (c) 2008-2016 The Khronos Group Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and/or associated documentation files (the @@ -29,7 +29,8 @@ /*! \file * * \brief C++ bindings for OpenCL 1.0 (rev 48), OpenCL 1.1 (rev 33), - * OpenCL 1.2 (rev 15) and OpenCL 2.0 (rev 29) + * OpenCL 1.2 (rev 15), OpenCL 2.0 (rev 29), OpenCL 2.1 (rev 17), + * and OpenCL 2.2 (V2.2-11). * \author Lee Howes and Bruce Merry * * Derived from the OpenCL 1.x C++ bindings written by @@ -39,10 +40,9 @@ * Matt Gruenke, April 2012. * Bruce Merry, February 2013. * Tom Deakin and Simon McIntosh-Smith, July 2013 - * James Price, June-November 2015 - * - * \version 2.0.9 - * \date 2015-12-07 + * James Price, 2015- + * \version 2.2.0 + * \date 2019-09-18 * * Optional extension support * @@ -52,6 +52,8 @@ * #define CL_HPP_USE_DX_INTEROP * cl_khr_sub_groups * #define CL_HPP_USE_CL_SUB_GROUPS_KHR + * cl_khr_image2d_from_buffer + * #define CL_HPP_USE_CL_IMAGE2D_FROM_BUFFER_KHR * * Doxygen documentation for this header is available here: * @@ -205,6 +207,14 @@ * applies to use of cl::Program construction and other program * build variants. * + * - CL_HPP_USE_CL_SUB_GROUPS_KHR + * + * Enable the cl_khr_subgroups extension. + * + * - CL_HPP_USE_IL_KHR + * + * Enable the cl_khr_il_program extension. + * * * \section example Example * @@ -437,20 +447,41 @@ /* Detect which version to target */ #if !defined(CL_HPP_TARGET_OPENCL_VERSION) -# pragma message("cl2.hpp: CL_HPP_TARGET_OPENCL_VERSION is not defined. It will default to 200 (OpenCL 2.0)") -# define CL_HPP_TARGET_OPENCL_VERSION 200 +# pragma message("cl2.hpp: CL_HPP_TARGET_OPENCL_VERSION is not defined. It will default to 220 (OpenCL 2.2)") +# define CL_HPP_TARGET_OPENCL_VERSION 220 #endif -#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 -# 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") +#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 && \ + CL_HPP_TARGET_OPENCL_VERSION != 210 && \ + CL_HPP_TARGET_OPENCL_VERSION != 220 +# pragma message("cl2.hpp: CL_HPP_TARGET_OPENCL_VERSION is not a valid value (100, 110, 120, 200, 210 or 220). It will be set to 220") # undef CL_HPP_TARGET_OPENCL_VERSION -# define CL_HPP_TARGET_OPENCL_VERSION 200 +# define CL_HPP_TARGET_OPENCL_VERSION 220 +#endif + +/* Forward target OpenCL version to C headers if necessary */ +#if defined(CL_TARGET_OPENCL_VERSION) +/* Warn if prior definition of CL_TARGET_OPENCL_VERSION is lower than + * requested C++ bindings version */ +#if CL_TARGET_OPENCL_VERSION < CL_HPP_TARGET_OPENCL_VERSION +# pragma message("CL_TARGET_OPENCL_VERSION is already defined as is lower than CL_HPP_TARGET_OPENCL_VERSION") +#endif +#else +# define CL_TARGET_OPENCL_VERSION CL_HPP_TARGET_OPENCL_VERSION #endif #if !defined(CL_HPP_MINIMUM_OPENCL_VERSION) # define CL_HPP_MINIMUM_OPENCL_VERSION 200 #endif -#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 -# 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") +#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 && \ + CL_HPP_MINIMUM_OPENCL_VERSION != 210 && \ + CL_HPP_MINIMUM_OPENCL_VERSION != 220 +# pragma message("cl2.hpp: CL_HPP_MINIMUM_OPENCL_VERSION is not a valid value (100, 110, 120, 200, 210 or 220). It will be set to 100") # undef CL_HPP_MINIMUM_OPENCL_VERSION # define CL_HPP_MINIMUM_OPENCL_VERSION 100 #endif @@ -470,6 +501,12 @@ #if CL_HPP_MINIMUM_OPENCL_VERSION <= 200 && !defined(CL_USE_DEPRECATED_OPENCL_2_0_APIS) # define CL_USE_DEPRECATED_OPENCL_2_0_APIS #endif +#if CL_HPP_MINIMUM_OPENCL_VERSION <= 210 && !defined(CL_USE_DEPRECATED_OPENCL_2_1_APIS) +# define CL_USE_DEPRECATED_OPENCL_2_1_APIS +#endif +#if CL_HPP_MINIMUM_OPENCL_VERSION <= 220 && !defined(CL_USE_DEPRECATED_OPENCL_2_2_APIS) +# define CL_USE_DEPRECATED_OPENCL_2_2_APIS +#endif #ifdef _WIN32 @@ -512,6 +549,8 @@ #if defined(_MSC_VER) # define CL_HPP_DEFINE_STATIC_MEMBER_ __declspec(selectany) +#elif defined(__MINGW32__) +# define CL_HPP_DEFINE_STATIC_MEMBER_ __attribute__((selectany)) #else # define CL_HPP_DEFINE_STATIC_MEMBER_ __attribute__((weak)) #endif // !_MSC_VER @@ -790,6 +829,9 @@ static inline cl_int errHandler (cl_int err, const char * errStr = NULL) #if CL_HPP_TARGET_OPENCL_VERSION >= 120 #define __GET_KERNEL_ARG_INFO_ERR CL_HPP_ERR_STR_(clGetKernelArgInfo) #endif // CL_HPP_TARGET_OPENCL_VERSION >= 120 +#if CL_HPP_TARGET_OPENCL_VERSION >= 200 +#define __GET_KERNEL_SUB_GROUP_INFO_ERR CL_HPP_ERR_STR_(clGetKernelSubGroupInfo) +#endif // CL_HPP_TARGET_OPENCL_VERSION >= 200 #define __GET_KERNEL_WORK_GROUP_INFO_ERR CL_HPP_ERR_STR_(clGetKernelWorkGroupInfo) #define __GET_PROGRAM_INFO_ERR CL_HPP_ERR_STR_(clGetProgramInfo) #define __GET_PROGRAM_BUILD_INFO_ERR CL_HPP_ERR_STR_(clGetProgramBuildInfo) @@ -820,7 +862,13 @@ static inline cl_int errHandler (cl_int err, const char * errStr = NULL) #define __CREATE_KERNEL_ERR CL_HPP_ERR_STR_(clCreateKernel) #define __SET_KERNEL_ARGS_ERR CL_HPP_ERR_STR_(clSetKernelArg) #define __CREATE_PROGRAM_WITH_SOURCE_ERR CL_HPP_ERR_STR_(clCreateProgramWithSource) +#if CL_HPP_TARGET_OPENCL_VERSION >= 200 +#define __CREATE_PROGRAM_WITH_IL_ERR CL_HPP_ERR_STR_(clCreateProgramWithIL) +#endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 200 #define __CREATE_PROGRAM_WITH_BINARY_ERR CL_HPP_ERR_STR_(clCreateProgramWithBinary) +#if CL_HPP_TARGET_OPENCL_VERSION >= 210 +#define __CREATE_PROGRAM_WITH_IL_ERR CL_HPP_ERR_STR_(clCreateProgramWithIL) +#endif // CL_HPP_TARGET_OPENCL_VERSION >= 210 #if CL_HPP_TARGET_OPENCL_VERSION >= 120 #define __CREATE_PROGRAM_WITH_BUILT_IN_KERNELS_ERR CL_HPP_ERR_STR_(clCreateProgramWithBuiltInKernels) #endif // CL_HPP_TARGET_OPENCL_VERSION >= 120 @@ -857,6 +905,11 @@ static inline cl_int errHandler (cl_int err, const char * errStr = NULL) #if CL_HPP_TARGET_OPENCL_VERSION >= 120 #define __ENQUEUE_MIGRATE_MEM_OBJECTS_ERR CL_HPP_ERR_STR_(clEnqueueMigrateMemObjects) #endif // CL_HPP_TARGET_OPENCL_VERSION >= 120 +#if CL_HPP_TARGET_OPENCL_VERSION >= 210 +#define __ENQUEUE_MIGRATE_SVM_ERR CL_HPP_ERR_STR_(clEnqueueSVMMigrateMem) +#define __SET_DEFAULT_DEVICE_COMMAND_QUEUE_ERR CL_HPP_ERR_STR_(clSetDefaultDeviceCommandQueue) +#endif // CL_HPP_TARGET_OPENCL_VERSION >= 210 + #define __ENQUEUE_ACQUIRE_GL_ERR CL_HPP_ERR_STR_(clEnqueueAcquireGLObjects) #define __ENQUEUE_RELEASE_GL_ERR CL_HPP_ERR_STR_(clEnqueueReleaseGLObjects) @@ -871,6 +924,16 @@ static inline cl_int errHandler (cl_int err, const char * errStr = NULL) #define __FINISH_ERR CL_HPP_ERR_STR_(clFinish) #define __VECTOR_CAPACITY_ERR CL_HPP_ERR_STR_(Vector capacity error) +#if CL_HPP_TARGET_OPENCL_VERSION >= 210 +#define __GET_HOST_TIMER_ERR CL_HPP_ERR_STR_(clGetHostTimer) +#define __GET_DEVICE_AND_HOST_TIMER_ERR CL_HPP_ERR_STR_(clGetDeviceAndHostTimer) +#endif +#if CL_HPP_TARGET_OPENCL_VERSION >= 220 +#define __SET_PROGRAM_RELEASE_CALLBACK_ERR CL_HPP_ERR_STR_(clSetProgramReleaseCallback) +#define __SET_PROGRAM_SPECIALIZATION_CONSTANT_ERR CL_HPP_ERR_STR_(clSetProgramSpecializationConstant) +#endif + + /** * CL 1.2 version that uses device fission. */ @@ -911,6 +974,10 @@ static inline cl_int errHandler (cl_int err, const char * errStr = NULL) #define __ENQUEUE_BARRIER_WAIT_LIST_ERR CL_HPP_ERR_STR_(clEnqueueBarrierWithWaitList) #endif // CL_HPP_TARGET_OPENCL_VERSION >= 120 +#if CL_HPP_TARGET_OPENCL_VERSION >= 210 +#define __CLONE_KERNEL_ERR CL_HPP_ERR_STR_(clCloneKernel) +#endif // CL_HPP_TARGET_OPENCL_VERSION >= 210 + #endif // CL_HPP_USER_OVERRIDE_ERROR_STRINGS //! \endcond @@ -940,14 +1007,12 @@ inline cl_int getInfoHelper(Func f, cl_uint name, vector>* size_type numBinaries = param->size(); vector binariesPointers(numBinaries); - size_type totalSize = 0; for (size_type i = 0; i < numBinaries; ++i) { binariesPointers[i] = (*param)[i].data(); - totalSize += (*param)[i].size(); } - cl_int err = f(name, totalSize, binariesPointers.data(), NULL); + cl_int err = f(name, numBinaries * sizeof(unsigned char*), binariesPointers.data(), NULL); if (err != CL_SUCCESS) { return err; @@ -1139,6 +1204,8 @@ inline cl_int getInfoHelper(Func f, cl_uint name, T* param, int, typename T::cl_ F(cl_device_info, CL_DEVICE_MEM_BASE_ADDR_ALIGN, cl_uint) \ F(cl_device_info, CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE, cl_uint) \ F(cl_device_info, CL_DEVICE_SINGLE_FP_CONFIG, cl_device_fp_config) \ + F(cl_device_info, CL_DEVICE_DOUBLE_FP_CONFIG, cl_device_fp_config) \ + F(cl_device_info, CL_DEVICE_HALF_FP_CONFIG, cl_device_fp_config) \ F(cl_device_info, CL_DEVICE_GLOBAL_MEM_CACHE_TYPE, cl_device_mem_cache_type) \ F(cl_device_info, CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE, cl_uint)\ F(cl_device_info, CL_DEVICE_GLOBAL_MEM_CACHE_SIZE, cl_ulong) \ @@ -1235,8 +1302,6 @@ inline cl_int getInfoHelper(Func f, cl_uint name, T* param, int, typename T::cl_ F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT, cl_uint) \ F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE, cl_uint) \ F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF, cl_uint) \ - F(cl_device_info, CL_DEVICE_DOUBLE_FP_CONFIG, cl_device_fp_config) \ - F(cl_device_info, CL_DEVICE_HALF_FP_CONFIG, cl_device_fp_config) \ F(cl_device_info, CL_DEVICE_OPENCL_C_VERSION, string) \ \ F(cl_mem_info, CL_MEM_ASSOCIATED_MEMOBJECT, cl::Memory) \ @@ -1293,6 +1358,31 @@ inline cl_int getInfoHelper(Func f, cl_uint name, T* param, int, typename T::cl_ F(cl_pipe_info, CL_PIPE_PACKET_SIZE, cl_uint) \ F(cl_pipe_info, CL_PIPE_MAX_PACKETS, cl_uint) +#define CL_HPP_PARAM_NAME_INFO_SUBGROUP_KHR_(F) \ + F(cl_kernel_sub_group_info, CL_KERNEL_MAX_SUB_GROUP_SIZE_FOR_NDRANGE_KHR, size_type) \ + F(cl_kernel_sub_group_info, CL_KERNEL_SUB_GROUP_COUNT_FOR_NDRANGE_KHR, size_type) + +#define CL_HPP_PARAM_NAME_INFO_IL_KHR_(F) \ + F(cl_device_info, CL_DEVICE_IL_VERSION_KHR, string) \ + F(cl_program_info, CL_PROGRAM_IL_KHR, cl::vector) + +#define CL_HPP_PARAM_NAME_INFO_2_1_(F) \ + F(cl_platform_info, CL_PLATFORM_HOST_TIMER_RESOLUTION, size_type) \ + F(cl_program_info, CL_PROGRAM_IL, cl::vector) \ + F(cl_kernel_info, CL_KERNEL_MAX_NUM_SUB_GROUPS, size_type) \ + F(cl_kernel_info, CL_KERNEL_COMPILE_NUM_SUB_GROUPS, size_type) \ + F(cl_device_info, CL_DEVICE_MAX_NUM_SUB_GROUPS, cl_uint) \ + F(cl_device_info, CL_DEVICE_IL_VERSION, string) \ + F(cl_device_info, CL_DEVICE_SUB_GROUP_INDEPENDENT_FORWARD_PROGRESS, cl_bool) \ + F(cl_command_queue_info, CL_QUEUE_DEVICE_DEFAULT, cl::DeviceCommandQueue) \ + F(cl_kernel_sub_group_info, CL_KERNEL_MAX_SUB_GROUP_SIZE_FOR_NDRANGE, size_type) \ + F(cl_kernel_sub_group_info, CL_KERNEL_SUB_GROUP_COUNT_FOR_NDRANGE, size_type) \ + F(cl_kernel_sub_group_info, CL_KERNEL_LOCAL_SIZE_FOR_SUB_GROUP_COUNT, cl::detail::size_t_array) + +#define CL_HPP_PARAM_NAME_INFO_2_2_(F) \ + F(cl_program_info, CL_PROGRAM_SCOPE_GLOBAL_CTORS_PRESENT, cl_bool) \ + F(cl_program_info, CL_PROGRAM_SCOPE_GLOBAL_DTORS_PRESENT, cl_bool) + #define CL_HPP_PARAM_NAME_DEVICE_FISSION_(F) \ F(cl_device_info, CL_DEVICE_PARENT_DEVICE_EXT, cl_device_id) \ F(cl_device_info, CL_DEVICE_PARTITION_TYPES_EXT, cl::vector) \ @@ -1318,10 +1408,24 @@ CL_HPP_PARAM_NAME_INFO_1_1_(CL_HPP_DECLARE_PARAM_TRAITS_) #endif // CL_HPP_TARGET_OPENCL_VERSION >= 110 #if CL_HPP_TARGET_OPENCL_VERSION >= 120 CL_HPP_PARAM_NAME_INFO_1_2_(CL_HPP_DECLARE_PARAM_TRAITS_) -#endif // CL_HPP_TARGET_OPENCL_VERSION >= 110 +#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120 #if CL_HPP_TARGET_OPENCL_VERSION >= 200 CL_HPP_PARAM_NAME_INFO_2_0_(CL_HPP_DECLARE_PARAM_TRAITS_) -#endif // CL_HPP_TARGET_OPENCL_VERSION >= 110 +#endif // CL_HPP_TARGET_OPENCL_VERSION >= 200 +#if CL_HPP_TARGET_OPENCL_VERSION >= 210 +CL_HPP_PARAM_NAME_INFO_2_1_(CL_HPP_DECLARE_PARAM_TRAITS_) +#endif // CL_HPP_TARGET_OPENCL_VERSION >= 210 +#if CL_HPP_TARGET_OPENCL_VERSION >= 220 +CL_HPP_PARAM_NAME_INFO_2_2_(CL_HPP_DECLARE_PARAM_TRAITS_) +#endif // CL_HPP_TARGET_OPENCL_VERSION >= 220 + +#if defined(CL_HPP_USE_CL_SUB_GROUPS_KHR) && CL_HPP_TARGET_OPENCL_VERSION < 210 +CL_HPP_PARAM_NAME_INFO_SUBGROUP_KHR_(CL_HPP_DECLARE_PARAM_TRAITS_) +#endif // #if defined(CL_HPP_USE_CL_SUB_GROUPS_KHR) && CL_HPP_TARGET_OPENCL_VERSION < 210 + +#if defined(CL_HPP_USE_IL_KHR) +CL_HPP_PARAM_NAME_INFO_IL_KHR_(CL_HPP_DECLARE_PARAM_TRAITS_) +#endif // #if defined(CL_HPP_USE_IL_KHR) // Flags deprecated in OpenCL 2.0 @@ -1389,6 +1493,13 @@ CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_LOCAL_MEM_SIZE_PER_COMPUT CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_LOCAL_MEM_BANKS_AMD, cl_uint) #endif +#ifdef CL_DEVICE_COMPUTE_UNITS_BITFIELD_ARM +CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_COMPUTE_UNITS_BITFIELD_ARM, cl_ulong) +#endif +#ifdef CL_DEVICE_JOB_SLOTS_ARM +CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_JOB_SLOTS_ARM, cl_uint) +#endif + #ifdef CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV, cl_uint) #endif @@ -1580,6 +1691,7 @@ struct ReferenceHandler }; +#if CL_HPP_TARGET_OPENCL_VERSION >= 120 && CL_HPP_MINIMUM_OPENCL_VERSION < 120 // Extracts version number with major in the upper 16 bits, minor in the lower 16 static cl_uint getVersion(const vector &versionInfo) { @@ -1600,12 +1712,11 @@ static cl_uint getVersion(const vector &versionInfo) return (highVersion << 16) | lowVersion; } -#if CL_HPP_TARGET_OPENCL_VERSION >= 120 && CL_HPP_MINIMUM_OPENCL_VERSION < 120 static cl_uint getPlatformVersion(cl_platform_id platform) { size_type size = 0; clGetPlatformInfo(platform, CL_PLATFORM_VERSION, 0, NULL, &size); - + vector versionInfo(size); clGetPlatformInfo(platform, CL_PLATFORM_VERSION, size, versionInfo.data(), &size); return getVersion(versionInfo); @@ -1699,10 +1810,7 @@ public: cl_type& operator ()() { return object_; } - const cl_type get() const { return object_; } - - cl_type get() { return object_; } - + cl_type get() const { return object_; } protected: template @@ -1828,9 +1936,7 @@ public: cl_type& operator ()() { return object_; } - const cl_type get() const { return object_; } - - cl_type get() { return object_; } + cl_type get() const { return object_; } protected: template @@ -2094,6 +2200,53 @@ public: return param; } + +#if CL_HPP_TARGET_OPENCL_VERSION >= 210 + /** + * Return the current value of the host clock as seen by the device. + * The resolution of the device timer may be queried with the + * CL_DEVICE_PROFILING_TIMER_RESOLUTION query. + * @return The host timer value. + */ + cl_ulong getHostTimer(cl_int *error = nullptr) + { + cl_ulong retVal = 0; + cl_int err = + clGetHostTimer(this->get(), &retVal); + detail::errHandler( + err, + __GET_HOST_TIMER_ERR); + if (error) { + *error = err; + } + return retVal; + } + + /** + * Return a synchronized pair of host and device timestamps as seen by device. + * Use to correlate the clocks and get the host timer only using getHostTimer + * as a lower cost mechanism in between calls. + * The resolution of the host timer may be queried with the + * CL_PLATFORM_HOST_TIMER_RESOLUTION query. + * The resolution of the device timer may be queried with the + * CL_DEVICE_PROFILING_TIMER_RESOLUTION query. + * @return A pair of (device timer, host timer) timer values. + */ + std::pair getDeviceAndHostTimer(cl_int *error = nullptr) + { + std::pair retVal; + cl_int err = + clGetDeviceAndHostTimer(this->get(), &(retVal.first), &(retVal.second)); + detail::errHandler( + err, + __GET_DEVICE_AND_HOST_TIMER_ERR); + if (error) { + *error = err; + } + return retVal; + } +#endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 210 + /** * CL 1.2 version */ @@ -2346,14 +2499,16 @@ public: return detail::errHandler(CL_INVALID_ARG_VALUE, __GET_DEVICE_IDS_ERR); } cl_int err = ::clGetDeviceIDs(object_, type, 0, NULL, &n); - if (err != CL_SUCCESS) { + if (err != CL_SUCCESS && err != CL_DEVICE_NOT_FOUND) { return detail::errHandler(err, __GET_DEVICE_IDS_ERR); } vector ids(n); - err = ::clGetDeviceIDs(object_, type, n, ids.data(), NULL); - if (err != CL_SUCCESS) { - return detail::errHandler(err, __GET_DEVICE_IDS_ERR); + if (n>0) { + err = ::clGetDeviceIDs(object_, type, n, ids.data(), NULL); + if (err != CL_SUCCESS) { + return detail::errHandler(err, __GET_DEVICE_IDS_ERR); + } } // Cannot trivially assign because we need to capture intermediates @@ -2744,7 +2899,9 @@ public: error = platforms[i].getDevices(type, &devices); #if defined(CL_HPP_ENABLE_EXCEPTIONS) - } catch (Error) {} + } catch (cl::Error& e) { + error = e.err(); + } // Catch if exceptions are enabled as we don't want to exit if first platform has no devices of type // We do error checking next anyway, and can throw there if needed #endif @@ -3460,7 +3617,7 @@ public: context_(), SVMTrait::getSVMMemFlags(), size*sizeof(T), - sizeof(T)); + 0); pointer retValue = reinterpret_cast( voidPointer); #if defined(CL_HPP_ENABLE_EXCEPTIONS) @@ -3496,7 +3653,7 @@ public: { size_type maxSize = std::numeric_limits::max() / sizeof(T); - for (Device &d : context_.getInfo()) { + for (const Device &d : context_.getInfo()) { maxSize = std::min( maxSize, static_cast(d.getInfo())); @@ -3601,7 +3758,7 @@ cl::pointer> allocate_pointer(const Alloc &alloc_, Arg return cl::pointer>(tmp, detail::Deleter{alloc, copies}); } - catch (std::bad_alloc b) + catch (std::bad_alloc& b) { std::allocator_traits::deallocate(alloc, tmp, copies); throw; @@ -4591,7 +4748,7 @@ public: #endif // CL_HPP_MINIMUM_OPENCL_VERSION < 120 } -#if CL_HPP_TARGET_OPENCL_VERSION >= 200 +#if CL_HPP_TARGET_OPENCL_VERSION >= 200 || defined(CL_HPP_USE_CL_IMAGE2D_FROM_BUFFER_KHR) /*! \brief Constructs a 2D Image from a buffer. * \note This will share storage with the underlying buffer. * @@ -4632,7 +4789,7 @@ public: *err = error; } } -#endif //#if CL_HPP_TARGET_OPENCL_VERSION >= 200 +#endif //#if CL_HPP_TARGET_OPENCL_VERSION >= 200 || defined(CL_HPP_USE_CL_IMAGE2D_FROM_BUFFER_KHR) #if CL_HPP_TARGET_OPENCL_VERSION >= 200 /*! \brief Constructs a 2D Image from an image. @@ -5792,17 +5949,26 @@ public: return param; } -#if CL_HPP_TARGET_OPENCL_VERSION >= 200 -#if defined(CL_HPP_USE_CL_SUB_GROUPS_KHR) +#if (CL_HPP_TARGET_OPENCL_VERSION >= 200 && defined(CL_HPP_USE_CL_SUB_GROUPS_KHR)) || CL_HPP_TARGET_OPENCL_VERSION >= 210 cl_int getSubGroupInfo(const cl::Device &dev, cl_kernel_sub_group_info name, const cl::NDRange &range, size_type* param) const { +#if CL_HPP_TARGET_OPENCL_VERSION >= 210 + + return detail::errHandler( + clGetKernelSubGroupInfo(object_, dev(), name, range.size(), range.get(), sizeof(size_type), param, nullptr), + __GET_KERNEL_SUB_GROUP_INFO_ERR); + +#else // #if CL_HPP_TARGET_OPENCL_VERSION >= 210 + typedef clGetKernelSubGroupInfoKHR_fn PFN_clGetKernelSubGroupInfoKHR; static PFN_clGetKernelSubGroupInfoKHR pfn_clGetKernelSubGroupInfoKHR = NULL; CL_HPP_INIT_CL_EXT_FCN_PTR_(clGetKernelSubGroupInfoKHR); return detail::errHandler( pfn_clGetKernelSubGroupInfoKHR(object_, dev(), name, range.size(), range.get(), sizeof(size_type), param, nullptr), - __GET_KERNEL_ARG_INFO_ERR); + __GET_KERNEL_SUB_GROUP_INFO_ERR); + +#endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 210 } template @@ -5815,7 +5981,6 @@ public: } return param; } -#endif // #if defined(CL_HPP_USE_CL_SUB_GROUPS_KHR) #endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 200 #if CL_HPP_TARGET_OPENCL_VERSION >= 200 @@ -5927,27 +6092,28 @@ public: ); } - template - void setSVMPointersHelper(std::array &pointerList, const pointer &t0, Ts... ts) + template + void setSVMPointersHelper(std::array &pointerList, const pointer &t0, const pointer &t1, Ts & ... ts) { pointerList[index] = static_cast(t0.get()); - setSVMPointersHelper(ts...); + setSVMPointersHelper(pointerList, t1, ts...); } - template + template typename std::enable_if::value, void>::type - setSVMPointersHelper(std::array &pointerList, T0 t0, Ts... ts) + setSVMPointersHelper(std::array &pointerList, T0 t0, T1 t1, Ts... ts) { pointerList[index] = static_cast(t0); - setSVMPointersHelper(ts...); + setSVMPointersHelper(pointerList, t1, ts...); } - + template void setSVMPointersHelper(std::array &pointerList, const pointer &t0) { pointerList[index] = static_cast(t0.get()); } + template typename std::enable_if::value, void>::type setSVMPointersHelper(std::array &pointerList, T0 t0) @@ -5956,7 +6122,7 @@ public: } template - cl_int setSVMPointers(const T0 &t0, Ts... ts) + cl_int setSVMPointers(const T0 &t0, Ts & ... ts) { std::array pointerList; @@ -5969,6 +6135,22 @@ public: pointerList.data())); } #endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 200 + +#if CL_HPP_TARGET_OPENCL_VERSION >= 210 + /** + * Make a deep copy of the kernel object including its arguments. + * @return A new kernel object with internal state entirely separate from that + * of the original but with any arguments set on the original intact. + */ + Kernel clone() + { + cl_int error; + Kernel retValue(clCloneKernel(this->get(), &error)); + + detail::errHandler(error, __CLONE_KERNEL_ERR); + return retValue; + } +#endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 210 }; /*! \class Program @@ -6131,6 +6313,116 @@ public: } } + +#if CL_HPP_TARGET_OPENCL_VERSION >= 210 || (CL_HPP_TARGET_OPENCL_VERSION==200 && defined(CL_HPP_USE_IL_KHR)) + /** + * Program constructor to allow construction of program from SPIR-V or another IL. + * Valid for either OpenCL >= 2.1 or when CL_HPP_USE_IL_KHR is defined. + */ + Program( + const vector& IL, + bool build = false, + cl_int* err = NULL) + { + cl_int error; + + Context context = Context::getDefault(err); + +#if CL_HPP_TARGET_OPENCL_VERSION >= 210 + + object_ = ::clCreateProgramWithIL( + context(), static_cast(IL.data()), IL.size(), &error); + +#else // #if CL_HPP_TARGET_OPENCL_VERSION >= 210 + + typedef clCreateProgramWithILKHR_fn PFN_clCreateProgramWithILKHR; + static PFN_clCreateProgramWithILKHR pfn_clCreateProgramWithILKHR = NULL; + CL_HPP_INIT_CL_EXT_FCN_PTR_(clCreateProgramWithILKHR); + + return detail::errHandler( + pfn_clCreateProgramWithILKHR( + context(), static_cast(IL.data()), IL.size(), &error); + +#endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 210 + + detail::errHandler(error, __CREATE_PROGRAM_WITH_IL_ERR); + + if (error == CL_SUCCESS && build) { + + error = ::clBuildProgram( + object_, + 0, + NULL, +#if !defined(CL_HPP_CL_1_2_DEFAULT_BUILD) + "-cl-std=CL2.0", +#else + "", +#endif // #if !defined(CL_HPP_CL_1_2_DEFAULT_BUILD) + NULL, + NULL); + + detail::buildErrHandler(error, __BUILD_PROGRAM_ERR, getBuildInfo()); + } + + if (err != NULL) { + *err = error; + } + } + + /** + * Program constructor to allow construction of program from SPIR-V or another IL + * for a specific context. + * Valid for either OpenCL >= 2.1 or when CL_HPP_USE_IL_KHR is defined. + */ + Program( + const Context& context, + const vector& IL, + bool build = false, + cl_int* err = NULL) + { + cl_int error; + +#if CL_HPP_TARGET_OPENCL_VERSION >= 210 + + object_ = ::clCreateProgramWithIL( + context(), static_cast(IL.data()), IL.size(), &error); + +#else // #if CL_HPP_TARGET_OPENCL_VERSION >= 210 + + typedef clCreateProgramWithILKHR_fn PFN_clCreateProgramWithILKHR; + static PFN_clCreateProgramWithILKHR pfn_clCreateProgramWithILKHR = NULL; + CL_HPP_INIT_CL_EXT_FCN_PTR_(clCreateProgramWithILKHR); + + return detail::errHandler( + pfn_clCreateProgramWithILKHR( + context(), static_cast(IL.data()), IL.size(), &error); + +#endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 210 + + detail::errHandler(error, __CREATE_PROGRAM_WITH_IL_ERR); + + if (error == CL_SUCCESS && build) { + error = ::clBuildProgram( + object_, + 0, + NULL, +#if !defined(CL_HPP_CL_1_2_DEFAULT_BUILD) + "-cl-std=CL2.0", +#else + "", +#endif // #if !defined(CL_HPP_CL_1_2_DEFAULT_BUILD) + NULL, + NULL); + + detail::buildErrHandler(error, __BUILD_PROGRAM_ERR, getBuildInfo()); + } + + if (err != NULL) { + *err = error; + } + } +#endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 210 + /** * Construct a program object from a list of devices and a per-device list of binaries. * \param context A valid OpenCL context in which to construct the program. @@ -6418,7 +6710,7 @@ public: return devInfo; } - for (cl::Device d : devs) { + for (const cl::Device &d : devs) { typename detail::param_traits< detail::cl_program_build_info, name>::param_type param; result = getBuildInfo(d, name, ¶m); @@ -6468,6 +6760,62 @@ public: } return CL_SUCCESS; } + +#if CL_HPP_TARGET_OPENCL_VERSION >= 220 + /*! \brief Registers a callback function to be called when destructors for + * program scope global variables are complete and before the + * program is released. + * + * Wraps clSetProgramReleaseCallback(). + * + * Each call to this function registers the specified user callback function + * on a callback stack associated with program. The registered user callback + * functions are called in the reverse order in which they were registered. + */ + cl_int setReleaseCallback( + void (CL_CALLBACK * pfn_notify)(cl_program program, void * user_data), + void * user_data = NULL) + { + return detail::errHandler( + ::clSetProgramReleaseCallback( + object_, + pfn_notify, + user_data), + __SET_PROGRAM_RELEASE_CALLBACK_ERR); + } + + /*! \brief Sets a SPIR-V specialization constant. + * + * Wraps clSetProgramSpecializationConstant(). + */ + template + typename std::enable_if::value, cl_int>::type + setSpecializationConstant(cl_uint index, const T &value) + { + return detail::errHandler( + ::clSetProgramSpecializationConstant( + object_, + index, + sizeof(value), + &value), + __SET_PROGRAM_SPECIALIZATION_CONSTANT_ERR); + } + + /*! \brief Sets a SPIR-V specialization constant. + * + * Wraps clSetProgramSpecializationConstant(). + */ + cl_int setSpecializationConstant(cl_uint index, size_type size, const void* value) + { + return detail::errHandler( + ::clSetProgramSpecializationConstant( + object_, + index, + size, + value), + __SET_PROGRAM_SPECIALIZATION_CONSTANT_ERR); + } +#endif // CL_HPP_TARGET_OPENCL_VERSION >= 220 }; #if CL_HPP_TARGET_OPENCL_VERSION >= 120 @@ -6589,6 +6937,22 @@ inline vector> cl::Program::getInfo(c return binariesVectors; } +#if CL_HPP_TARGET_OPENCL_VERSION >= 220 +// Template specialization for clSetProgramSpecializationConstant +template <> +inline cl_int cl::Program::setSpecializationConstant(cl_uint index, const bool &value) +{ + cl_uchar ucValue = value ? CL_UCHAR_MAX : 0; + return detail::errHandler( + ::clSetProgramSpecializationConstant( + object_, + index, + sizeof(ucValue), + &ucValue), + __SET_PROGRAM_SPECIALIZATION_CONSTANT_ERR); +} +#endif // CL_HPP_TARGET_OPENCL_VERSION >= 220 + inline Kernel::Kernel(const Program& program, const char* name, cl_int* err) { cl_int error; @@ -6699,31 +7063,49 @@ public: } else { Device device = context.getInfo()[0]; + bool useWithProperties; + +#if CL_HPP_TARGET_OPENCL_VERSION >= 200 && CL_HPP_MINIMUM_OPENCL_VERSION < 200 + // Run-time decision based on the actual platform + { + cl_uint version = detail::getContextPlatformVersion(context()); + useWithProperties = (version >= 0x20000); // OpenCL 2.0 or above + } +#elif CL_HPP_TARGET_OPENCL_VERSION >= 200 + useWithProperties = true; +#else + useWithProperties = false; +#endif #if CL_HPP_TARGET_OPENCL_VERSION >= 200 - cl_queue_properties queue_properties[] = { - CL_QUEUE_PROPERTIES, properties, 0 }; - if ((properties & CL_QUEUE_ON_DEVICE) == 0) { - object_ = ::clCreateCommandQueueWithProperties( - context(), device(), queue_properties, &error); - } - else { - error = CL_INVALID_QUEUE_PROPERTIES; - } + if (useWithProperties) { + cl_queue_properties queue_properties[] = { + CL_QUEUE_PROPERTIES, properties, 0 }; + if ((properties & CL_QUEUE_ON_DEVICE) == 0) { + object_ = ::clCreateCommandQueueWithProperties( + context(), device(), queue_properties, &error); + } + else { + error = CL_INVALID_QUEUE_PROPERTIES; + } - detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR); - if (err != NULL) { - *err = error; + detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR); + if (err != NULL) { + *err = error; + } } -#else - object_ = ::clCreateCommandQueue( - context(), device(), properties, &error); +#endif // CL_HPP_TARGET_OPENCL_VERSION >= 200 +#if CL_HPP_MINIMUM_OPENCL_VERSION < 200 + if (!useWithProperties) { + object_ = ::clCreateCommandQueue( + context(), device(), properties, &error); - detail::errHandler(error, __CREATE_COMMAND_QUEUE_ERR); - if (err != NULL) { - *err = error; + detail::errHandler(error, __CREATE_COMMAND_QUEUE_ERR); + if (err != NULL) { + *err = error; + } } -#endif +#endif // CL_HPP_MINIMUM_OPENCL_VERSION < 200 } } @@ -6747,28 +7129,46 @@ public: } else { Device device = context.getInfo()[0]; + bool useWithProperties; + +#if CL_HPP_TARGET_OPENCL_VERSION >= 200 && CL_HPP_MINIMUM_OPENCL_VERSION < 200 + // Run-time decision based on the actual platform + { + cl_uint version = detail::getContextPlatformVersion(context()); + useWithProperties = (version >= 0x20000); // OpenCL 2.0 or above + } +#elif CL_HPP_TARGET_OPENCL_VERSION >= 200 + useWithProperties = true; +#else + useWithProperties = false; +#endif #if CL_HPP_TARGET_OPENCL_VERSION >= 200 - cl_queue_properties queue_properties[] = { - CL_QUEUE_PROPERTIES, static_cast(properties), 0 }; + if (useWithProperties) { + cl_queue_properties queue_properties[] = { + CL_QUEUE_PROPERTIES, static_cast(properties), 0 }; - object_ = ::clCreateCommandQueueWithProperties( - context(), device(), queue_properties, &error); + object_ = ::clCreateCommandQueueWithProperties( + context(), device(), queue_properties, &error); - - detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR); - if (err != NULL) { - *err = error; + detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR); + if (err != NULL) { + *err = error; + } } -#else - object_ = ::clCreateCommandQueue( - context(), device(), static_cast(properties), &error); +#endif // CL_HPP_TARGET_OPENCL_VERSION >= 200 +#if CL_HPP_MINIMUM_OPENCL_VERSION < 200 + if (!useWithProperties) { + object_ = ::clCreateCommandQueue( + context(), device(), static_cast(properties), &error); - detail::errHandler(error, __CREATE_COMMAND_QUEUE_ERR); - if (err != NULL) { - *err = error; + detail::errHandler(error, __CREATE_COMMAND_QUEUE_ERR); + if (err != NULL) { + *err = error; + } } -#endif +#endif // CL_HPP_MINIMUM_OPENCL_VERSION < 200 + } } @@ -6782,6 +7182,7 @@ public: cl_int* err = NULL) { cl_int error; + bool useWithProperties; vector devices; error = context.getInfo(CL_CONTEXT_DEVICES, &devices); @@ -6795,31 +7196,47 @@ public: return; } -#if CL_HPP_TARGET_OPENCL_VERSION >= 200 - cl_queue_properties queue_properties[] = { - CL_QUEUE_PROPERTIES, properties, 0 }; - if ((properties & CL_QUEUE_ON_DEVICE) == 0) { - object_ = ::clCreateCommandQueueWithProperties( - context(), devices[0](), queue_properties, &error); - } - else { - error = CL_INVALID_QUEUE_PROPERTIES; - } - - detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR); - if (err != NULL) { - *err = error; +#if CL_HPP_TARGET_OPENCL_VERSION >= 200 && CL_HPP_MINIMUM_OPENCL_VERSION < 200 + // Run-time decision based on the actual platform + { + cl_uint version = detail::getContextPlatformVersion(context()); + useWithProperties = (version >= 0x20000); // OpenCL 2.0 or above } +#elif CL_HPP_TARGET_OPENCL_VERSION >= 200 + useWithProperties = true; #else - object_ = ::clCreateCommandQueue( - context(), devices[0](), properties, &error); - - detail::errHandler(error, __CREATE_COMMAND_QUEUE_ERR); - if (err != NULL) { - *err = error; - } + useWithProperties = false; #endif +#if CL_HPP_TARGET_OPENCL_VERSION >= 200 + if (useWithProperties) { + cl_queue_properties queue_properties[] = { + CL_QUEUE_PROPERTIES, properties, 0 }; + if ((properties & CL_QUEUE_ON_DEVICE) == 0) { + object_ = ::clCreateCommandQueueWithProperties( + context(), devices[0](), queue_properties, &error); + } + else { + error = CL_INVALID_QUEUE_PROPERTIES; + } + + detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR); + if (err != NULL) { + *err = error; + } + } +#endif // CL_HPP_TARGET_OPENCL_VERSION >= 200 +#if CL_HPP_MINIMUM_OPENCL_VERSION < 200 + if (!useWithProperties) { + object_ = ::clCreateCommandQueue( + context(), devices[0](), properties, &error); + + detail::errHandler(error, __CREATE_COMMAND_QUEUE_ERR); + if (err != NULL) { + *err = error; + } + } +#endif // CL_HPP_MINIMUM_OPENCL_VERSION < 200 } /*! @@ -6832,6 +7249,7 @@ public: cl_int* err = NULL) { cl_int error; + bool useWithProperties; vector devices; error = context.getInfo(CL_CONTEXT_DEVICES, &devices); @@ -6845,26 +7263,42 @@ public: return; } -#if CL_HPP_TARGET_OPENCL_VERSION >= 200 - cl_queue_properties queue_properties[] = { - CL_QUEUE_PROPERTIES, static_cast(properties), 0 }; - object_ = ::clCreateCommandQueueWithProperties( - context(), devices[0](), queue_properties, &error); - - detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR); - if (err != NULL) { - *err = error; +#if CL_HPP_TARGET_OPENCL_VERSION >= 200 && CL_HPP_MINIMUM_OPENCL_VERSION < 200 + // Run-time decision based on the actual platform + { + cl_uint version = detail::getContextPlatformVersion(context()); + useWithProperties = (version >= 0x20000); // OpenCL 2.0 or above } +#elif CL_HPP_TARGET_OPENCL_VERSION >= 200 + useWithProperties = true; #else - object_ = ::clCreateCommandQueue( - context(), devices[0](), static_cast(properties), &error); - - detail::errHandler(error, __CREATE_COMMAND_QUEUE_ERR); - if (err != NULL) { - *err = error; - } + useWithProperties = false; #endif +#if CL_HPP_TARGET_OPENCL_VERSION >= 200 + if (useWithProperties) { + cl_queue_properties queue_properties[] = { + CL_QUEUE_PROPERTIES, static_cast(properties), 0 }; + object_ = ::clCreateCommandQueueWithProperties( + context(), devices[0](), queue_properties, &error); + + detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR); + if (err != NULL) { + *err = error; + } + } +#endif // CL_HPP_TARGET_OPENCL_VERSION >= 200 +#if CL_HPP_MINIMUM_OPENCL_VERSION < 200 + if (!useWithProperties) { + object_ = ::clCreateCommandQueue( + context(), devices[0](), static_cast(properties), &error); + + detail::errHandler(error, __CREATE_COMMAND_QUEUE_ERR); + if (err != NULL) { + *err = error; + } + } +#endif // CL_HPP_MINIMUM_OPENCL_VERSION < 200 } /*! @@ -6878,26 +7312,44 @@ public: cl_int* err = NULL) { cl_int error; + bool useWithProperties; + +#if CL_HPP_TARGET_OPENCL_VERSION >= 200 && CL_HPP_MINIMUM_OPENCL_VERSION < 200 + // Run-time decision based on the actual platform + { + cl_uint version = detail::getContextPlatformVersion(context()); + useWithProperties = (version >= 0x20000); // OpenCL 2.0 or above + } +#elif CL_HPP_TARGET_OPENCL_VERSION >= 200 + useWithProperties = true; +#else + useWithProperties = false; +#endif #if CL_HPP_TARGET_OPENCL_VERSION >= 200 - cl_queue_properties queue_properties[] = { - CL_QUEUE_PROPERTIES, properties, 0 }; - object_ = ::clCreateCommandQueueWithProperties( - context(), device(), queue_properties, &error); - - detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR); - if (err != NULL) { - *err = error; - } -#else - object_ = ::clCreateCommandQueue( - context(), device(), properties, &error); + if (useWithProperties) { + cl_queue_properties queue_properties[] = { + CL_QUEUE_PROPERTIES, properties, 0 }; + object_ = ::clCreateCommandQueueWithProperties( + context(), device(), queue_properties, &error); - detail::errHandler(error, __CREATE_COMMAND_QUEUE_ERR); - if (err != NULL) { - *err = error; + detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR); + if (err != NULL) { + *err = error; + } } -#endif +#endif // CL_HPP_TARGET_OPENCL_VERSION >= 200 +#if CL_HPP_MINIMUM_OPENCL_VERSION < 200 + if (!useWithProperties) { + object_ = ::clCreateCommandQueue( + context(), device(), properties, &error); + + detail::errHandler(error, __CREATE_COMMAND_QUEUE_ERR); + if (err != NULL) { + *err = error; + } + } +#endif // CL_HPP_MINIMUM_OPENCL_VERSION < 200 } /*! @@ -6910,19 +7362,36 @@ public: QueueProperties properties, cl_int* err = NULL) { - cl_int error; + cl_int error; + bool useWithProperties; + +#if CL_HPP_TARGET_OPENCL_VERSION >= 200 && CL_HPP_MINIMUM_OPENCL_VERSION < 200 + // Run-time decision based on the actual platform + { + cl_uint version = detail::getContextPlatformVersion(context()); + useWithProperties = (version >= 0x20000); // OpenCL 2.0 or above + } +#elif CL_HPP_TARGET_OPENCL_VERSION >= 200 + useWithProperties = true; +#else + useWithProperties = false; +#endif #if CL_HPP_TARGET_OPENCL_VERSION >= 200 + if (useWithProperties) { cl_queue_properties queue_properties[] = { CL_QUEUE_PROPERTIES, static_cast(properties), 0 }; object_ = ::clCreateCommandQueueWithProperties( context(), device(), queue_properties, &error); - + detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR); if (err != NULL) { *err = error; } -#else + } +#endif // CL_HPP_TARGET_OPENCL_VERSION >= 200 +#if CL_HPP_MINIMUM_OPENCL_VERSION < 200 + if (!useWithProperties) { object_ = ::clCreateCommandQueue( context(), device(), static_cast(properties), &error); @@ -6930,8 +7399,9 @@ public: if (err != NULL) { *err = error; } -#endif } +#endif // CL_HPP_MINIMUM_OPENCL_VERSION < 200 + } static CommandQueue getDefault(cl_int * err = NULL) { @@ -7102,7 +7572,7 @@ public: return err; } - +#if CL_HPP_TARGET_OPENCL_VERSION >= 110 cl_int enqueueReadBufferRect( const Buffer& buffer, cl_bool blocking, @@ -7217,7 +7687,7 @@ public: return err; } - +#endif // CL_HPP_TARGET_OPENCL_VERSION >= 110 #if CL_HPP_TARGET_OPENCL_VERSION >= 120 /** * Enqueue a command to fill a buffer object with a pattern @@ -7775,7 +8245,7 @@ public: */ cl_int enqueueMarkerWithWaitList( const vector *events = 0, - Event *event = 0) + Event *event = 0) const { cl_event tmp; cl_int err = detail::errHandler( @@ -7805,7 +8275,7 @@ public: */ cl_int enqueueBarrierWithWaitList( const vector *events = 0, - Event *event = 0) + Event *event = 0) const { cl_event tmp; cl_int err = detail::errHandler( @@ -7831,7 +8301,7 @@ public: cl_mem_migration_flags flags, const vector* events = NULL, Event* event = NULL - ) + ) const { cl_event tmp; @@ -7840,8 +8310,7 @@ public: for( int i = 0; i < (int)memObjects.size(); ++i ) { localMemObjects[i] = memObjects[i](); } - - + cl_int err = detail::errHandler( ::clEnqueueMigrateMemObjects( object_, @@ -7860,6 +8329,128 @@ public: } #endif // CL_HPP_TARGET_OPENCL_VERSION >= 120 + +#if CL_HPP_TARGET_OPENCL_VERSION >= 210 + /** + * Enqueues a command that will allow the host associate ranges within a set of + * SVM allocations with a device. + * @param sizes - The length from each pointer to migrate. + */ + template + cl_int enqueueMigrateSVM( + const cl::vector &svmRawPointers, + const cl::vector &sizes, + cl_mem_migration_flags flags = 0, + const vector* events = NULL, + Event* event = NULL) const + { + cl_event tmp; + cl_int err = detail::errHandler(::clEnqueueSVMMigrateMem( + object_, + svmRawPointers.size(), static_cast(svmRawPointers.data()), + sizes.data(), // array of sizes not passed + flags, + (events != NULL) ? (cl_uint)events->size() : 0, + (events != NULL && events->size() > 0) ? (cl_event*)&events->front() : NULL, + (event != NULL) ? &tmp : NULL), + __ENQUEUE_MIGRATE_SVM_ERR); + + if (event != NULL && err == CL_SUCCESS) + *event = tmp; + + return err; + } + + /** + * Enqueues a command that will allow the host associate a set of SVM allocations with + * a device. + */ + template + cl_int enqueueMigrateSVM( + const cl::vector &svmRawPointers, + cl_mem_migration_flags flags = 0, + const vector* events = NULL, + Event* event = NULL) const + { + return enqueueMigrateSVM(svmRawPointers, cl::vector(svmRawPointers.size()), flags, events, event); + } + + + /** + * Enqueues a command that will allow the host associate ranges within a set of + * SVM allocations with a device. + * @param sizes - The length from each pointer to migrate. + */ + template + cl_int enqueueMigrateSVM( + const cl::vector> &svmPointers, + const cl::vector &sizes, + cl_mem_migration_flags flags = 0, + const vector* events = NULL, + Event* event = NULL) const + { + cl::vector svmRawPointers; + svmRawPointers.reserve(svmPointers.size()); + for (auto p : svmPointers) { + svmRawPointers.push_back(static_cast(p.get())); + } + + return enqueueMigrateSVM(svmRawPointers, sizes, flags, events, event); + } + + + /** + * Enqueues a command that will allow the host associate a set of SVM allocations with + * a device. + */ + template + cl_int enqueueMigrateSVM( + const cl::vector> &svmPointers, + cl_mem_migration_flags flags = 0, + const vector* events = NULL, + Event* event = NULL) const + { + return enqueueMigrateSVM(svmPointers, cl::vector(svmPointers.size()), flags, events, event); + } + + /** + * Enqueues a command that will allow the host associate ranges within a set of + * SVM allocations with a device. + * @param sizes - The length from the beginning of each container to migrate. + */ + template + cl_int enqueueMigrateSVM( + const cl::vector> &svmContainers, + const cl::vector &sizes, + cl_mem_migration_flags flags = 0, + const vector* events = NULL, + Event* event = NULL) const + { + cl::vector svmRawPointers; + svmRawPointers.reserve(svmContainers.size()); + for (auto p : svmContainers) { + svmRawPointers.push_back(static_cast(p.data())); + } + + return enqueueMigrateSVM(svmRawPointers, sizes, flags, events, event); + } + + /** + * Enqueues a command that will allow the host associate a set of SVM allocations with + * a device. + */ + template + cl_int enqueueMigrateSVM( + const cl::vector> &svmContainers, + cl_mem_migration_flags flags = 0, + const vector* events = NULL, + Event* event = NULL) const + { + return enqueueMigrateSVM(svmContainers, cl::vector(svmContainers.size()), flags, events, event); + } + +#endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 210 + cl_int enqueueNDRangeKernel( const Kernel& kernel, const NDRange& offset, @@ -8289,11 +8880,11 @@ public: } /*! - * Create a new default device command queue for the default device, - * in the default context and of the default size. - * If there is already a default queue for the specified device this - * function will return the pre-existing queue. - */ + * Create a new default device command queue for the default device, + * in the default context and of the default size. + * If there is already a default queue for the specified device this + * function will return the pre-existing queue. + */ static DeviceCommandQueue makeDefault( cl_int *err = nullptr) { @@ -8319,11 +8910,11 @@ public: } /*! - * Create a new default device command queue for the specified device - * and of the default size. - * If there is already a default queue for the specified device this - * function will return the pre-existing queue. - */ + * Create a new default device command queue for the specified device + * and of the default size. + * If there is already a default queue for the specified device this + * function will return the pre-existing queue. + */ static DeviceCommandQueue makeDefault( const Context &context, const Device &device, cl_int *err = nullptr) { @@ -8374,6 +8965,37 @@ public: return deviceQueue; } + + + +#if CL_HPP_TARGET_OPENCL_VERSION >= 210 + /*! + * Modify the default device command queue to be used for subsequent kernels. + * This can update the default command queue for a device repeatedly to account + * for kernels that rely on the default. + * @return updated default device command queue. + */ + static DeviceCommandQueue updateDefault(const Context &context, const Device &device, const DeviceCommandQueue &default_queue, cl_int *err = nullptr) + { + cl_int error; + error = clSetDefaultDeviceCommandQueue(context.get(), device.get(), default_queue.get()); + + detail::errHandler(error, __SET_DEFAULT_DEVICE_COMMAND_QUEUE_ERR); + if (err != NULL) { + *err = error; + } + return default_queue; + } + + /*! + * Return the current default command queue for the specified command queue + */ + static DeviceCommandQueue getDefault(const CommandQueue &queue, cl_int * err = NULL) + { + return queue.getInfo(err); + } + +#endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 210 }; // DeviceCommandQueue namespace detail @@ -9427,7 +10049,7 @@ public: } template - cl_int setSVMPointers(const T0 &t0, T1s... ts) + cl_int setSVMPointers(const T0 &t0, T1s &... ts) { return kernel_.setSVMPointers(t0, ts...); } @@ -9486,73 +10108,101 @@ namespace compatibility { #undef CL_HPP_ERR_STR_ #if !defined(CL_HPP_USER_OVERRIDE_ERROR_STRINGS) -#undef __GET_DEVICE_INFO_ERR -#undef __GET_PLATFORM_INFO_ERR -#undef __GET_DEVICE_IDS_ERR -#undef __GET_CONTEXT_INFO_ERR -#undef __GET_EVENT_INFO_ERR -#undef __GET_EVENT_PROFILE_INFO_ERR -#undef __GET_MEM_OBJECT_INFO_ERR -#undef __GET_IMAGE_INFO_ERR -#undef __GET_SAMPLER_INFO_ERR -#undef __GET_KERNEL_INFO_ERR -#undef __GET_KERNEL_ARG_INFO_ERR -#undef __GET_KERNEL_WORK_GROUP_INFO_ERR -#undef __GET_PROGRAM_INFO_ERR -#undef __GET_PROGRAM_BUILD_INFO_ERR -#undef __GET_COMMAND_QUEUE_INFO_ERR - -#undef __CREATE_CONTEXT_ERR -#undef __CREATE_CONTEXT_FROM_TYPE_ERR -#undef __GET_SUPPORTED_IMAGE_FORMATS_ERR - -#undef __CREATE_BUFFER_ERR -#undef __CREATE_SUBBUFFER_ERR -#undef __CREATE_IMAGE2D_ERR -#undef __CREATE_IMAGE3D_ERR -#undef __CREATE_SAMPLER_ERR -#undef __SET_MEM_OBJECT_DESTRUCTOR_CALLBACK_ERR - -#undef __CREATE_USER_EVENT_ERR -#undef __SET_USER_EVENT_STATUS_ERR -#undef __SET_EVENT_CALLBACK_ERR -#undef __SET_PRINTF_CALLBACK_ERR - -#undef __WAIT_FOR_EVENTS_ERR - -#undef __CREATE_KERNEL_ERR -#undef __SET_KERNEL_ARGS_ERR -#undef __CREATE_PROGRAM_WITH_SOURCE_ERR -#undef __CREATE_PROGRAM_WITH_BINARY_ERR -#undef __CREATE_PROGRAM_WITH_BUILT_IN_KERNELS_ERR -#undef __BUILD_PROGRAM_ERR -#undef __CREATE_KERNELS_IN_PROGRAM_ERR - -#undef __CREATE_COMMAND_QUEUE_ERR -#undef __SET_COMMAND_QUEUE_PROPERTY_ERR -#undef __ENQUEUE_READ_BUFFER_ERR -#undef __ENQUEUE_WRITE_BUFFER_ERR -#undef __ENQUEUE_READ_BUFFER_RECT_ERR -#undef __ENQUEUE_WRITE_BUFFER_RECT_ERR -#undef __ENQEUE_COPY_BUFFER_ERR -#undef __ENQEUE_COPY_BUFFER_RECT_ERR -#undef __ENQUEUE_READ_IMAGE_ERR -#undef __ENQUEUE_WRITE_IMAGE_ERR -#undef __ENQUEUE_COPY_IMAGE_ERR -#undef __ENQUEUE_COPY_IMAGE_TO_BUFFER_ERR -#undef __ENQUEUE_COPY_BUFFER_TO_IMAGE_ERR -#undef __ENQUEUE_MAP_BUFFER_ERR -#undef __ENQUEUE_MAP_IMAGE_ERR -#undef __ENQUEUE_UNMAP_MEM_OBJECT_ERR -#undef __ENQUEUE_NDRANGE_KERNEL_ERR -#undef __ENQUEUE_TASK_ERR -#undef __ENQUEUE_NATIVE_KERNEL - -#undef __UNLOAD_COMPILER_ERR -#undef __CREATE_SUB_DEVICES_ERR - -#undef __CREATE_PIPE_ERR -#undef __GET_PIPE_INFO_ERR +#undef __GET_DEVICE_INFO_ERR +#undef __GET_PLATFORM_INFO_ERR +#undef __GET_DEVICE_IDS_ERR +#undef __GET_PLATFORM_IDS_ERR +#undef __GET_CONTEXT_INFO_ERR +#undef __GET_EVENT_INFO_ERR +#undef __GET_EVENT_PROFILE_INFO_ERR +#undef __GET_MEM_OBJECT_INFO_ERR +#undef __GET_IMAGE_INFO_ERR +#undef __GET_SAMPLER_INFO_ERR +#undef __GET_KERNEL_INFO_ERR +#undef __GET_KERNEL_ARG_INFO_ERR +#undef __GET_KERNEL_SUB_GROUP_INFO_ERR +#undef __GET_KERNEL_WORK_GROUP_INFO_ERR +#undef __GET_PROGRAM_INFO_ERR +#undef __GET_PROGRAM_BUILD_INFO_ERR +#undef __GET_COMMAND_QUEUE_INFO_ERR +#undef __CREATE_CONTEXT_ERR +#undef __CREATE_CONTEXT_FROM_TYPE_ERR +#undef __GET_SUPPORTED_IMAGE_FORMATS_ERR +#undef __CREATE_BUFFER_ERR +#undef __COPY_ERR +#undef __CREATE_SUBBUFFER_ERR +#undef __CREATE_GL_BUFFER_ERR +#undef __CREATE_GL_RENDER_BUFFER_ERR +#undef __GET_GL_OBJECT_INFO_ERR +#undef __CREATE_IMAGE_ERR +#undef __CREATE_GL_TEXTURE_ERR +#undef __IMAGE_DIMENSION_ERR +#undef __SET_MEM_OBJECT_DESTRUCTOR_CALLBACK_ERR +#undef __CREATE_USER_EVENT_ERR +#undef __SET_USER_EVENT_STATUS_ERR +#undef __SET_EVENT_CALLBACK_ERR +#undef __WAIT_FOR_EVENTS_ERR +#undef __CREATE_KERNEL_ERR +#undef __SET_KERNEL_ARGS_ERR +#undef __CREATE_PROGRAM_WITH_SOURCE_ERR +#undef __CREATE_PROGRAM_WITH_IL_ERR +#undef __CREATE_PROGRAM_WITH_BINARY_ERR +#undef __CREATE_PROGRAM_WITH_IL_ERR +#undef __CREATE_PROGRAM_WITH_BUILT_IN_KERNELS_ERR +#undef __BUILD_PROGRAM_ERR +#undef __COMPILE_PROGRAM_ERR +#undef __LINK_PROGRAM_ERR +#undef __CREATE_KERNELS_IN_PROGRAM_ERR +#undef __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR +#undef __CREATE_SAMPLER_WITH_PROPERTIES_ERR +#undef __SET_COMMAND_QUEUE_PROPERTY_ERR +#undef __ENQUEUE_READ_BUFFER_ERR +#undef __ENQUEUE_READ_BUFFER_RECT_ERR +#undef __ENQUEUE_WRITE_BUFFER_ERR +#undef __ENQUEUE_WRITE_BUFFER_RECT_ERR +#undef __ENQEUE_COPY_BUFFER_ERR +#undef __ENQEUE_COPY_BUFFER_RECT_ERR +#undef __ENQUEUE_FILL_BUFFER_ERR +#undef __ENQUEUE_READ_IMAGE_ERR +#undef __ENQUEUE_WRITE_IMAGE_ERR +#undef __ENQUEUE_COPY_IMAGE_ERR +#undef __ENQUEUE_FILL_IMAGE_ERR +#undef __ENQUEUE_COPY_IMAGE_TO_BUFFER_ERR +#undef __ENQUEUE_COPY_BUFFER_TO_IMAGE_ERR +#undef __ENQUEUE_MAP_BUFFER_ERR +#undef __ENQUEUE_MAP_IMAGE_ERR +#undef __ENQUEUE_UNMAP_MEM_OBJECT_ERR +#undef __ENQUEUE_NDRANGE_KERNEL_ERR +#undef __ENQUEUE_NATIVE_KERNEL +#undef __ENQUEUE_MIGRATE_MEM_OBJECTS_ERR +#undef __ENQUEUE_MIGRATE_SVM_ERR +#undef __ENQUEUE_ACQUIRE_GL_ERR +#undef __ENQUEUE_RELEASE_GL_ERR +#undef __CREATE_PIPE_ERR +#undef __GET_PIPE_INFO_ERR +#undef __RETAIN_ERR +#undef __RELEASE_ERR +#undef __FLUSH_ERR +#undef __FINISH_ERR +#undef __VECTOR_CAPACITY_ERR +#undef __CREATE_SUB_DEVICES_ERR +#undef __CREATE_SUB_DEVICES_ERR +#undef __ENQUEUE_MARKER_ERR +#undef __ENQUEUE_WAIT_FOR_EVENTS_ERR +#undef __ENQUEUE_BARRIER_ERR +#undef __UNLOAD_COMPILER_ERR +#undef __CREATE_GL_TEXTURE_2D_ERR +#undef __CREATE_GL_TEXTURE_3D_ERR +#undef __CREATE_IMAGE2D_ERR +#undef __CREATE_IMAGE3D_ERR +#undef __CREATE_COMMAND_QUEUE_ERR +#undef __ENQUEUE_TASK_ERR +#undef __CREATE_SAMPLER_ERR +#undef __ENQUEUE_MARKER_WAIT_LIST_ERR +#undef __ENQUEUE_BARRIER_WAIT_LIST_ERR +#undef __CLONE_KERNEL_ERR +#undef __GET_HOST_TIMER_ERR +#undef __GET_DEVICE_AND_HOST_TIMER_ERR #endif //CL_HPP_USER_OVERRIDE_ERROR_STRINGS