From c4e67d302d40a388129e4faf1b8bbb35f39ebb18 Mon Sep 17 00:00:00 2001
From: Michal Babej <michal.babej@intel.com>
Date: Wed, 9 Oct 2024 12:13:54 +0300
Subject: [PATCH] include/hpp/CL: update opencl.hpp to latest Khronos version

---
 include/hpp/CL/opencl.hpp | 1215 ++++++++++++++++++++++++++++++++-----
 1 file changed, 1052 insertions(+), 163 deletions(-)

diff --git a/include/hpp/CL/opencl.hpp b/include/hpp/CL/opencl.hpp
index d8d227e1b..970e67b1e 100644
--- a/include/hpp/CL/opencl.hpp
+++ b/include/hpp/CL/opencl.hpp
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 2008-2023 The Khronos Group Inc.
+// Copyright (c) 2008-2024 The Khronos Group Inc.
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -336,7 +336,7 @@
         // Traditional cl_mem allocations
 
         std::vector<int> output(numElements, 0xdeadbeef);
-        cl::Buffer outputBuffer(begin(output), end(output), false);
+        cl::Buffer outputBuffer(output.begin(), output.end(), false);
         cl::Pipe aPipe(sizeof(cl_int), numElements / 2);
 
         // Default command queue, also passed in as a parameter
@@ -373,7 +373,7 @@
             error
             );
 
-        cl::copy(outputBuffer, begin(output), end(output));
+        cl::copy(outputBuffer, output.begin(), output.end());
 
         cl::Device d = cl::Device::getDefault();
 
@@ -525,12 +525,6 @@
 #include <CL/opencl.h>
 #endif // !__APPLE__
 
-#if (__cplusplus >= 201103L || _MSVC_LANG >= 201103L )
-#define CL_HPP_NOEXCEPT_ noexcept
-#else
-#define CL_HPP_NOEXCEPT_
-#endif
-
 #if __cplusplus >= 201703L
 # define CL_HPP_DEFINE_STATIC_MEMBER_ inline
 #elif defined(_MSC_VER)
@@ -725,6 +719,7 @@ namespace cl {
 #endif
 
     class Memory;
+    class Platform;
     class Program;
     class Device;
     class Context;
@@ -764,13 +759,11 @@ namespace cl {
         Error(cl_int err, const char * errStr = nullptr) : err_(err), errStr_(errStr)
         {}
 
-        ~Error() throw() {}
-
         /*! \brief Get error string associated with exception
          *
          * \return A memory pointer to the error message string.
          */
-        virtual const char * what() const throw ()
+        const char * what() const noexcept override
         {
             if (errStr_ == nullptr) {
                 return "empty";
@@ -904,6 +897,10 @@ static inline cl_int errHandler (cl_int err, const char * errStr = nullptr)
 #define __ENQUEUE_COPY_IMAGE_TO_BUFFER_ERR  CL_HPP_ERR_STR_(clEnqueueCopyImageToBuffer)
 #define __ENQUEUE_COPY_BUFFER_TO_IMAGE_ERR  CL_HPP_ERR_STR_(clEnqueueCopyBufferToImage)
 #define __ENQUEUE_MAP_BUFFER_ERR            CL_HPP_ERR_STR_(clEnqueueMapBuffer)
+#define __ENQUEUE_MAP_SVM_ERR               CL_HPP_ERR_STR_(clEnqueueSVMMap)
+#define __ENQUEUE_FILL_SVM_ERR              CL_HPP_ERR_STR_(clEnqueueSVMMemFill)
+#define __ENQUEUE_COPY_SVM_ERR              CL_HPP_ERR_STR_(clEnqueueSVMMemcpy)
+#define __ENQUEUE_UNMAP_SVM_ERR             CL_HPP_ERR_STR_(clEnqueueSVMUnmap)
 #define __ENQUEUE_MAP_IMAGE_ERR             CL_HPP_ERR_STR_(clEnqueueMapImage)
 #define __ENQUEUE_UNMAP_MEM_OBJECT_ERR      CL_HPP_ERR_STR_(clEnqueueUnMapMemObject)
 #define __ENQUEUE_NDRANGE_KERNEL_ERR        CL_HPP_ERR_STR_(clEnqueueNDRangeKernel)
@@ -951,6 +948,11 @@ static inline cl_int errHandler (cl_int err, const char * errStr = nullptr)
 #define __RETAIN_SEMAPHORE_KHR_ERR                  CL_HPP_ERR_STR_(clRetainSemaphoreKHR)
 #define __RELEASE_SEMAPHORE_KHR_ERR                 CL_HPP_ERR_STR_(clReleaseSemaphoreKHR)
 #endif
+
+#ifdef cl_khr_external_semaphore
+#define __GET_SEMAPHORE_HANDLE_FOR_TYPE_KHR_ERR         CL_HPP_ERR_STR_(clGetSemaphoreHandleForTypeKHR)
+#endif // cl_khr_external_semaphore
+
 #if defined(cl_khr_command_buffer)
 #define __CREATE_COMMAND_BUFFER_KHR_ERR             CL_HPP_ERR_STR_(clCreateCommandBufferKHR)
 #define __GET_COMMAND_BUFFER_INFO_KHR_ERR           CL_HPP_ERR_STR_(clGetCommandBufferInfoKHR)
@@ -971,6 +973,10 @@ static inline cl_int errHandler (cl_int err, const char * errStr = nullptr)
 #define __RELEASE_COMMAND_BUFFER_KHR_ERR            CL_HPP_ERR_STR_(clReleaseCommandBufferKHR)
 #endif // cl_khr_command_buffer
 
+#if defined(cl_ext_image_requirements_info)
+#define __GET_IMAGE_REQUIREMENT_INFO_EXT_ERR            CL_HPP_ERR_STR_(clGetImageRequirementsInfoEXT)
+#endif //cl_ext_image_requirements_info
+
 /**
  * CL 1.2 version that uses device fission.
  */
@@ -1042,6 +1048,11 @@ CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clEnqueueSignalSemaphoresKHR       pfn_clEnqueu
 CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clGetSemaphoreInfoKHR              pfn_clGetSemaphoreInfoKHR               = nullptr;
 #endif // cl_khr_semaphore
 
+#ifdef cl_khr_external_semaphore
+CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clGetSemaphoreHandleForTypeKHR);
+CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clGetSemaphoreHandleForTypeKHR     pfn_clGetSemaphoreHandleForTypeKHR      = nullptr;
+#endif // cl_khr_external_semaphore
+
 #if defined(cl_khr_command_buffer)
 CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCreateCommandBufferKHR);
 CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clFinalizeCommandBufferKHR);
@@ -1084,6 +1095,17 @@ CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clUpdateMutableCommandsKHR pfn_clUpdateMutableC
 CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clGetMutableCommandInfoKHR pfn_clGetMutableCommandInfoKHR           = nullptr;
 #endif /* cl_khr_command_buffer_mutable_dispatch */
 
+#if defined(cl_ext_image_requirements_info)
+CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clGetImageRequirementsInfoEXT);
+CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clGetImageRequirementsInfoEXT pfn_clGetImageRequirementsInfoEXT  = nullptr;
+#endif
+
+#if defined(cl_ext_device_fission)
+CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCreateSubDevicesEXT);
+CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCreateSubDevicesEXT
+    pfn_clCreateSubDevicesEXT = nullptr;
+#endif
+
 namespace detail {
 
 // Generic getInfoHelper. The final parameter is used to guide overload
@@ -1121,7 +1143,6 @@ inline cl_int getInfoHelper(Func f, cl_uint name, vector<vector<unsigned char>>*
         }
     }
 
-
     return CL_SUCCESS;
 }
 
@@ -1205,7 +1226,7 @@ inline cl_int getInfoHelper(Func f, cl_uint name, string* param, long)
             return err;
         }
         if (param) {
-            param->assign(begin(value), prev(end(value)));
+            param->assign(value.begin(), value.end() - 1);
         }
     }
     else if (param) {
@@ -1322,7 +1343,7 @@ inline cl_int getInfoHelper(Func f, cl_uint name, T* param, int, typename T::cl_
     F(cl_device_info, CL_DEVICE_AVAILABLE, cl_bool) \
     F(cl_device_info, CL_DEVICE_COMPILER_AVAILABLE, cl_bool) \
     F(cl_device_info, CL_DEVICE_EXECUTION_CAPABILITIES, cl_device_exec_capabilities) \
-    F(cl_device_info, CL_DEVICE_PLATFORM, cl_platform_id) \
+    F(cl_device_info, CL_DEVICE_PLATFORM, cl::Platform) \
     F(cl_device_info, CL_DEVICE_NAME, string) \
     F(cl_device_info, CL_DEVICE_VENDOR, string) \
     F(cl_device_info, CL_DRIVER_VERSION, string) \
@@ -1519,8 +1540,13 @@ inline cl_int getInfoHelper(Func f, cl_uint name, T* param, int, typename T::cl_
 #define CL_HPP_PARAM_NAME_CL_KHR_EXTENDED_VERSIONING_KHRONLY_(F) \
     F(cl_device_info, CL_DEVICE_OPENCL_C_NUMERIC_VERSION_KHR, cl_version_khr)
 
+// Note: the query for CL_SEMAPHORE_DEVICE_HANDLE_LIST_KHR is handled specially!
 #define CL_HPP_PARAM_NAME_CL_KHR_SEMAPHORE_(F) \
+    F(cl_semaphore_info_khr, CL_SEMAPHORE_CONTEXT_KHR, cl::Context) \
+    F(cl_semaphore_info_khr, CL_SEMAPHORE_REFERENCE_COUNT_KHR, cl_uint) \
     F(cl_semaphore_info_khr, CL_SEMAPHORE_PROPERTIES_KHR, cl::vector<cl_semaphore_properties_khr>) \
+    F(cl_semaphore_info_khr, CL_SEMAPHORE_TYPE_KHR, cl_semaphore_type_khr) \
+    F(cl_semaphore_info_khr, CL_SEMAPHORE_PAYLOAD_KHR, cl_semaphore_payload_khr) \
     F(cl_platform_info, CL_PLATFORM_SEMAPHORE_TYPES_KHR,  cl::vector<cl_semaphore_type_khr>) \
     F(cl_device_info, CL_DEVICE_SEMAPHORE_TYPES_KHR,      cl::vector<cl_semaphore_type_khr>) \
 
@@ -1528,6 +1554,23 @@ inline cl_int getInfoHelper(Func f, cl_uint name, T* param, int, typename T::cl_
     F(cl_device_info, CL_DEVICE_EXTERNAL_MEMORY_IMPORT_HANDLE_TYPES_KHR, cl::vector<cl::ExternalMemoryType>) \
     F(cl_platform_info, CL_PLATFORM_EXTERNAL_MEMORY_IMPORT_HANDLE_TYPES_KHR, cl::vector<cl::ExternalMemoryType>)
 
+#define CL_HPP_PARAM_NAME_CL_KHR_EXTERNAL_SEMAPHORE_(F) \
+    F(cl_platform_info, CL_PLATFORM_SEMAPHORE_IMPORT_HANDLE_TYPES_KHR,  cl::vector<cl_external_semaphore_handle_type_khr>) \
+    F(cl_platform_info, CL_PLATFORM_SEMAPHORE_EXPORT_HANDLE_TYPES_KHR,  cl::vector<cl_external_semaphore_handle_type_khr>) \
+    F(cl_device_info, CL_DEVICE_SEMAPHORE_IMPORT_HANDLE_TYPES_KHR,      cl::vector<cl_external_semaphore_handle_type_khr>) \
+    F(cl_device_info, CL_DEVICE_SEMAPHORE_EXPORT_HANDLE_TYPES_KHR,      cl::vector<cl_external_semaphore_handle_type_khr>) \
+    F(cl_semaphore_info_khr, CL_SEMAPHORE_EXPORT_HANDLE_TYPES_KHR,      cl::vector<cl_external_semaphore_handle_type_khr>) \
+
+#define CL_HPP_PARAM_NAME_CL_KHR_EXTERNAL_SEMAPHORE_OPAQUE_FD_EXT(F) \
+    F(cl_external_semaphore_handle_type_khr, CL_SEMAPHORE_HANDLE_OPAQUE_FD_KHR, int) \
+
+#define CL_HPP_PARAM_NAME_CL_KHR_EXTERNAL_SEMAPHORE_SYNC_FD_EXT(F) \
+    F(cl_external_semaphore_handle_type_khr, CL_SEMAPHORE_HANDLE_SYNC_FD_KHR, int) \
+
+#define CL_HPP_PARAM_NAME_CL_KHR_EXTERNAL_SEMAPHORE_WIN32_EXT(F) \
+    F(cl_external_semaphore_handle_type_khr, CL_SEMAPHORE_HANDLE_OPAQUE_WIN32_KHR, void*) \
+    F(cl_external_semaphore_handle_type_khr, CL_SEMAPHORE_HANDLE_OPAQUE_WIN32_KMT_KHR, void*) \
+
 #define CL_HPP_PARAM_NAME_INFO_3_0_(F) \
     F(cl_platform_info, CL_PLATFORM_NUMERIC_VERSION, cl_version) \
     F(cl_platform_info, CL_PLATFORM_EXTENSIONS_WITH_VERSION, cl::vector<cl_name_version>) \
@@ -1553,6 +1596,18 @@ inline cl_int getInfoHelper(Func f, cl_uint name, T* param, int, typename T::cl_
     F(cl_pipe_info, CL_PIPE_PROPERTIES, cl::vector<cl_pipe_properties>) \
     F(cl_sampler_info, CL_SAMPLER_PROPERTIES, cl::vector<cl_sampler_properties>) \
 
+#define CL_HPP_PARAM_NAME_CL_IMAGE_REQUIREMENTS_EXT(F) \
+    F(cl_image_requirements_info_ext, CL_IMAGE_REQUIREMENTS_ROW_PITCH_ALIGNMENT_EXT, size_type) \
+    F(cl_image_requirements_info_ext, CL_IMAGE_REQUIREMENTS_BASE_ADDRESS_ALIGNMENT_EXT, size_type) \
+    F(cl_image_requirements_info_ext, CL_IMAGE_REQUIREMENTS_SIZE_EXT, size_type) \
+    F(cl_image_requirements_info_ext, CL_IMAGE_REQUIREMENTS_MAX_WIDTH_EXT, cl_uint) \
+    F(cl_image_requirements_info_ext, CL_IMAGE_REQUIREMENTS_MAX_HEIGHT_EXT, cl_uint) \
+    F(cl_image_requirements_info_ext, CL_IMAGE_REQUIREMENTS_MAX_DEPTH_EXT, cl_uint) \
+    F(cl_image_requirements_info_ext, CL_IMAGE_REQUIREMENTS_MAX_ARRAY_SIZE_EXT, cl_uint) \
+
+#define CL_HPP_PARAM_NAME_CL_IMAGE_REQUIREMENTS_SLICE_PITCH_ALIGNMENT_EXT(F) \
+    F(cl_image_requirements_info_ext, CL_IMAGE_REQUIREMENTS_SLICE_PITCH_ALIGNMENT_EXT, size_type) \
+
 template <typename enum_type, cl_int Name>
 struct param_traits {};
 
@@ -1629,12 +1684,29 @@ CL_HPP_PARAM_NAME_CL_KHR_EXTENDED_VERSIONING_KHRONLY_(CL_HPP_DECLARE_PARAM_TRAIT
 
 #if defined(cl_khr_semaphore)
 CL_HPP_PARAM_NAME_CL_KHR_SEMAPHORE_(CL_HPP_DECLARE_PARAM_TRAITS_)
-#endif // cl_khr_semaphore
+#if defined(CL_SEMAPHORE_DEVICE_HANDLE_LIST_KHR)
+CL_HPP_DECLARE_PARAM_TRAITS_(cl_semaphore_info_khr, CL_SEMAPHORE_DEVICE_HANDLE_LIST_KHR, cl::vector<cl::Device>)
+#endif // defined(CL_SEMAPHORE_DEVICE_HANDLE_LIST_KHR)
+#endif // defined(cl_khr_semaphore)
 
 #ifdef cl_khr_external_memory
 CL_HPP_PARAM_NAME_CL_KHR_EXTERNAL_MEMORY_(CL_HPP_DECLARE_PARAM_TRAITS_)
 #endif // cl_khr_external_memory
 
+#if defined(cl_khr_external_semaphore)
+CL_HPP_PARAM_NAME_CL_KHR_EXTERNAL_SEMAPHORE_(CL_HPP_DECLARE_PARAM_TRAITS_)
+#endif // cl_khr_external_semaphore
+
+#if defined(cl_khr_external_semaphore_opaque_fd)
+CL_HPP_PARAM_NAME_CL_KHR_EXTERNAL_SEMAPHORE_OPAQUE_FD_EXT(CL_HPP_DECLARE_PARAM_TRAITS_)
+#endif // cl_khr_external_semaphore_opaque_fd
+#if defined(cl_khr_external_semaphore_sync_fd)
+CL_HPP_PARAM_NAME_CL_KHR_EXTERNAL_SEMAPHORE_SYNC_FD_EXT(CL_HPP_DECLARE_PARAM_TRAITS_)
+#endif // cl_khr_external_semaphore_sync_fd
+#if defined(cl_khr_external_semaphore_win32)
+CL_HPP_PARAM_NAME_CL_KHR_EXTERNAL_SEMAPHORE_WIN32_EXT(CL_HPP_DECLARE_PARAM_TRAITS_)
+#endif // cl_khr_external_semaphore_win32
+
 #if defined(cl_khr_device_uuid)
 using uuid_array = array<cl_uchar, CL_UUID_SIZE_KHR>;
 using luid_array = array<cl_uchar, CL_LUID_SIZE_KHR>;
@@ -1667,6 +1739,14 @@ CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_INTEGER_DOT_PRODUCT_ACCEL
 #endif // defined(CL_DEVICE_INTEGER_DOT_PRODUCT_ACCELERATION_PROPERTIES_8BIT_KHR)
 #endif // defined(cl_khr_integer_dot_product)
 
+#if defined(cl_ext_image_requirements_info)
+CL_HPP_PARAM_NAME_CL_IMAGE_REQUIREMENTS_EXT(CL_HPP_DECLARE_PARAM_TRAITS_)
+#endif // cl_ext_image_requirements_info
+
+#if defined(cl_ext_image_from_buffer)
+CL_HPP_PARAM_NAME_CL_IMAGE_REQUIREMENTS_SLICE_PITCH_ALIGNMENT_EXT(CL_HPP_DECLARE_PARAM_TRAITS_)
+#endif // cl_ext_image_from_buffer
+
 #ifdef CL_PLATFORM_ICD_SUFFIX_KHR
 CL_HPP_DECLARE_PARAM_TRAITS_(cl_platform_info, CL_PLATFORM_ICD_SUFFIX_KHR, string)
 #endif
@@ -1763,7 +1843,7 @@ CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_INTEGRATED_MEMORY_NV, cl_
 
 #if defined(cl_khr_command_buffer)
 CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_COMMAND_BUFFER_CAPABILITIES_KHR, cl_device_command_buffer_capabilities_khr)
-CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_COMMAND_BUFFER_REQUIRED_QUEUE_PROPERTIES_KHR, cl_command_buffer_properties_khr)
+CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_COMMAND_BUFFER_REQUIRED_QUEUE_PROPERTIES_KHR, cl_command_queue_properties)
 CL_HPP_DECLARE_PARAM_TRAITS_(cl_command_buffer_info_khr, CL_COMMAND_BUFFER_QUEUES_KHR, cl::vector<CommandQueue>)
 CL_HPP_DECLARE_PARAM_TRAITS_(cl_command_buffer_info_khr, CL_COMMAND_BUFFER_NUM_QUEUES_KHR, cl_uint)
 CL_HPP_DECLARE_PARAM_TRAITS_(cl_command_buffer_info_khr, CL_COMMAND_BUFFER_REFERENCE_COUNT_KHR, cl_uint)
@@ -1775,7 +1855,12 @@ CL_HPP_DECLARE_PARAM_TRAITS_(cl_command_buffer_info_khr, CL_COMMAND_BUFFER_PROPE
 CL_HPP_DECLARE_PARAM_TRAITS_(cl_mutable_command_info_khr, CL_MUTABLE_COMMAND_COMMAND_QUEUE_KHR, CommandQueue)
 CL_HPP_DECLARE_PARAM_TRAITS_(cl_mutable_command_info_khr, CL_MUTABLE_COMMAND_COMMAND_BUFFER_KHR, CommandBufferKhr)
 CL_HPP_DECLARE_PARAM_TRAITS_(cl_mutable_command_info_khr, CL_MUTABLE_COMMAND_COMMAND_TYPE_KHR, cl_command_type)
+
+#if CL_KHR_COMMAND_BUFFER_MUTABLE_DISPATCH_EXTENSION_VERSION > CL_MAKE_VERSION(0, 9, 2)
+CL_HPP_DECLARE_PARAM_TRAITS_(cl_mutable_command_info_khr, CL_MUTABLE_COMMAND_PROPERTIES_ARRAY_KHR, cl::vector<cl_command_properties_khr>)
+#else
 CL_HPP_DECLARE_PARAM_TRAITS_(cl_mutable_command_info_khr, CL_MUTABLE_DISPATCH_PROPERTIES_ARRAY_KHR, cl::vector<cl_ndrange_kernel_command_properties_khr>)
+#endif
 CL_HPP_DECLARE_PARAM_TRAITS_(cl_mutable_command_info_khr, CL_MUTABLE_DISPATCH_KERNEL_KHR, cl_kernel)
 CL_HPP_DECLARE_PARAM_TRAITS_(cl_mutable_command_info_khr, CL_MUTABLE_DISPATCH_DIMENSIONS_KHR, cl_uint)
 CL_HPP_DECLARE_PARAM_TRAITS_(cl_mutable_command_info_khr, CL_MUTABLE_DISPATCH_GLOBAL_WORK_OFFSET_KHR, cl::vector<size_type>)
@@ -1783,6 +1868,10 @@ CL_HPP_DECLARE_PARAM_TRAITS_(cl_mutable_command_info_khr, CL_MUTABLE_DISPATCH_GL
 CL_HPP_DECLARE_PARAM_TRAITS_(cl_mutable_command_info_khr, CL_MUTABLE_DISPATCH_LOCAL_WORK_SIZE_KHR, cl::vector<size_type>)
 #endif /* cl_khr_command_buffer_mutable_dispatch */
 
+#if defined(cl_khr_kernel_clock)
+CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_KERNEL_CLOCK_CAPABILITIES_KHR, cl_device_kernel_clock_capabilities_khr)
+#endif /* cl_khr_kernel_clock */
+
 // Convenience functions
 
 template <typename Func, typename T>
@@ -2008,7 +2097,8 @@ struct ReferenceHandler<cl_mutable_command_khr>
 #endif // cl_khr_command_buffer
 
 
-#if CL_HPP_TARGET_OPENCL_VERSION >= 120 && CL_HPP_MINIMUM_OPENCL_VERSION < 120
+#if (CL_HPP_TARGET_OPENCL_VERSION >= 120 && CL_HPP_MINIMUM_OPENCL_VERSION < 120) || \
+    (CL_HPP_TARGET_OPENCL_VERSION >= 200 && CL_HPP_MINIMUM_OPENCL_VERSION < 200)
 // Extracts version number with major in the upper 16 bits, minor in the lower 16
 static cl_uint getVersion(const vector<char> &versionInfo)
 {
@@ -2058,7 +2148,7 @@ static cl_uint getContextPlatformVersion(cl_context context)
     clGetContextInfo(context, CL_CONTEXT_DEVICES, size, devices.data(), nullptr);
     return getDevicePlatformVersion(devices[0]);
 }
-#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120 && CL_HPP_MINIMUM_OPENCL_VERSION < 120
+#endif // CL_HPP_TARGET_OPENCL_VERSION && CL_HPP_MINIMUM_OPENCL_VERSION
 
 template <typename T>
 class Wrapper
@@ -2090,7 +2180,7 @@ public:
         detail::errHandler(retain(), __RETAIN_ERR);
     }
 
-    Wrapper(Wrapper<cl_type>&& rhs) CL_HPP_NOEXCEPT_
+    Wrapper(Wrapper<cl_type>&& rhs) noexcept
     {
         object_ = rhs.object_;
         rhs.object_ = nullptr;
@@ -2167,18 +2257,16 @@ protected:
     static bool isReferenceCountable(cl_device_id device)
     {
         bool retVal = false;
-#if CL_HPP_TARGET_OPENCL_VERSION >= 120
-#if CL_HPP_MINIMUM_OPENCL_VERSION < 120
+#if CL_HPP_TARGET_OPENCL_VERSION >= 120 && CL_HPP_MINIMUM_OPENCL_VERSION < 120
         if (device != nullptr) {
             int version = getDevicePlatformVersion(device);
             if(version > ((1 << 16) + 1)) {
                 retVal = true;
             }
         }
-#else // CL_HPP_MINIMUM_OPENCL_VERSION < 120
+#elif CL_HPP_TARGET_OPENCL_VERSION >= 120
         retVal = true;
-#endif // CL_HPP_MINIMUM_OPENCL_VERSION < 120
-#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
+#endif // CL_HPP_TARGET_OPENCL_VERSION
         (void)device;
         return retVal;
     }
@@ -2211,7 +2299,7 @@ public:
         detail::errHandler(retain(), __RETAIN_ERR);
     }
 
-    Wrapper(Wrapper<cl_type>&& rhs) CL_HPP_NOEXCEPT_
+    Wrapper(Wrapper<cl_type>&& rhs) noexcept
     {
         object_ = rhs.object_;
         referenceCountable_ = rhs.referenceCountable_;
@@ -2498,91 +2586,14 @@ public:
 
 #if CL_HPP_TARGET_OPENCL_VERSION >= 120
     //! \brief Wrapper for clCreateSubDevices().
-    cl_int createSubDevices(
-        const cl_device_partition_property * properties,
-        vector<Device>* devices)
-    {
-        cl_uint n = 0;
-        cl_int err = clCreateSubDevices(object_, properties, 0, nullptr, &n);
-        if (err != CL_SUCCESS) {
-            return detail::errHandler(err, __CREATE_SUB_DEVICES_ERR);
-        }
-
-        vector<cl_device_id> ids(n);
-        err = clCreateSubDevices(object_, properties, n, ids.data(), nullptr);
-        if (err != CL_SUCCESS) {
-            return detail::errHandler(err, __CREATE_SUB_DEVICES_ERR);
-        }
-
-        // Cannot trivially assign because we need to capture intermediates 
-        // with safe construction
-        if (devices) {
-            devices->resize(ids.size());
-
-            // Assign to param, constructing with retain behaviour
-            // to correctly capture each underlying CL object
-            for (size_type i = 0; i < ids.size(); i++) {
-                // We do not need to retain because this device is being created 
-                // by the runtime
-                (*devices)[i] = Device(ids[i], false);
-            }
-        }
-
-        return CL_SUCCESS;
-    }
-#endif
+    cl_int createSubDevices(const cl_device_partition_property* properties,
+                            vector<Device>* devices);
+#endif // defined (CL_HPP_TARGET_OPENCL_VERSION >= 120)
 
 #if defined(cl_ext_device_fission)
     //! \brief Wrapper for clCreateSubDevices().
-    cl_int createSubDevices(
-        const cl_device_partition_property_ext * properties,
-        vector<Device>* devices)
-    {
-        typedef CL_API_ENTRY cl_int 
-            ( CL_API_CALL * PFN_clCreateSubDevicesEXT)(
-                cl_device_id /*in_device*/,
-                const cl_device_partition_property_ext * /* properties */,
-                cl_uint /*num_entries*/,
-                cl_device_id * /*out_devices*/,
-                cl_uint * /*num_devices*/ ) CL_API_SUFFIX__VERSION_1_1;
-
-        static PFN_clCreateSubDevicesEXT pfn_clCreateSubDevicesEXT = nullptr;
-#if CL_HPP_TARGET_OPENCL_VERSION >= 120
-        cl::Device device(object_);
-        cl_platform_id platform = device.getInfo<CL_DEVICE_PLATFORM>();
-        CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clCreateSubDevicesEXT);
-#endif
-#if CL_HPP_MINIMUM_OPENCL_VERSION < 120
-        CL_HPP_INIT_CL_EXT_FCN_PTR_(clCreateSubDevicesEXT);
-#endif
-
-        cl_uint n = 0;
-        cl_int err = pfn_clCreateSubDevicesEXT(object_, properties, 0, nullptr, &n);
-        if (err != CL_SUCCESS) {
-            return detail::errHandler(err, __CREATE_SUB_DEVICES_ERR);
-        }
-
-        vector<cl_device_id> ids(n);
-        err = pfn_clCreateSubDevicesEXT(object_, properties, n, ids.data(), nullptr);
-        if (err != CL_SUCCESS) {
-            return detail::errHandler(err, __CREATE_SUB_DEVICES_ERR);
-        }
-        // Cannot trivially assign because we need to capture intermediates 
-        // with safe construction
-        if (devices) {
-            devices->resize(ids.size());
-
-            // Assign to param, constructing with retain behaviour
-            // to correctly capture each underlying CL object
-            for (size_type i = 0; i < ids.size(); i++) {
-                // We do not need to retain because this device is being created 
-                // by the runtime
-                (*devices)[i] = Device(ids[i], false);
-            }
-        }
-
-        return CL_SUCCESS;
-    }
+    cl_int createSubDevices(const cl_device_partition_property_ext* properties,
+                            vector<Device>* devices);
 #endif // defined(cl_ext_device_fission)
 };
 
@@ -3000,6 +3011,93 @@ public:
 #endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
 }; // class Platform
 
+#if CL_HPP_TARGET_OPENCL_VERSION >= 120
+   //! \brief Wrapper for clCreateSubDevices().
+inline cl_int Device::createSubDevices(const cl_device_partition_property* properties,
+                         vector<Device>* devices)
+{
+    cl_uint n = 0;
+    cl_int err = clCreateSubDevices(object_, properties, 0, nullptr, &n);
+    if (err != CL_SUCCESS)
+    {
+        return detail::errHandler(err, __CREATE_SUB_DEVICES_ERR);
+    }
+
+    vector<cl_device_id> ids(n);
+    err = clCreateSubDevices(object_, properties, n, ids.data(), nullptr);
+    if (err != CL_SUCCESS)
+    {
+        return detail::errHandler(err, __CREATE_SUB_DEVICES_ERR);
+    }
+
+    // Cannot trivially assign because we need to capture intermediates
+    // with safe construction
+    if (devices)
+    {
+        devices->resize(ids.size());
+
+        // Assign to param, constructing with retain behaviour
+        // to correctly capture each underlying CL object
+        for (size_type i = 0; i < ids.size(); i++)
+        {
+            // We do not need to retain because this device is being created
+            // by the runtime
+            (*devices)[i] = Device(ids[i], false);
+        }
+    }
+
+    return CL_SUCCESS;
+}
+#endif // defined (CL_HPP_TARGET_OPENCL_VERSION >= 120)
+
+#if defined(cl_ext_device_fission)
+   //! \brief Wrapper for clCreateSubDevices().
+inline cl_int Device::createSubDevices(const cl_device_partition_property_ext* properties,
+                        vector<Device>* devices)
+{
+#if CL_HPP_TARGET_OPENCL_VERSION >= 120
+    cl::Device device(object_);
+    cl_platform_id platform = device.getInfo<CL_DEVICE_PLATFORM>()();
+    CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clCreateSubDevicesEXT);
+#endif
+#if CL_HPP_MINIMUM_OPENCL_VERSION < 120
+    CL_HPP_INIT_CL_EXT_FCN_PTR_(clCreateSubDevicesEXT);
+#endif
+
+    cl_uint n = 0;
+    cl_int err = pfn_clCreateSubDevicesEXT(object_, properties, 0, nullptr, &n);
+    if (err != CL_SUCCESS)
+    {
+        return detail::errHandler(err, __CREATE_SUB_DEVICES_ERR);
+    }
+
+    vector<cl_device_id> ids(n);
+    err =
+        pfn_clCreateSubDevicesEXT(object_, properties, n, ids.data(), nullptr);
+    if (err != CL_SUCCESS)
+    {
+        return detail::errHandler(err, __CREATE_SUB_DEVICES_ERR);
+    }
+    // Cannot trivially assign because we need to capture intermediates
+    // with safe construction
+    if (devices)
+    {
+        devices->resize(ids.size());
+
+        // Assign to param, constructing with retain behaviour
+        // to correctly capture each underlying CL object
+        for (size_type i = 0; i < ids.size(); i++)
+        {
+            // We do not need to retain because this device is being created
+            // by the runtime
+            (*devices)[i] = Device(ids[i], false);
+        }
+    }
+
+    return CL_SUCCESS;
+}
+#endif // defined(cl_ext_device_fission)
+
 CL_HPP_DEFINE_STATIC_MEMBER_ std::once_flag Platform::default_initialized_;
 CL_HPP_DEFINE_STATIC_MEMBER_ Platform Platform::default_;
 CL_HPP_DEFINE_STATIC_MEMBER_ cl_int Platform::default_error_ = CL_SUCCESS;
@@ -3022,6 +3120,25 @@ UnloadCompiler()
 }
 #endif // #if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
 
+
+#if defined(cl_ext_image_requirements_info)
+enum ImageRequirementsInfoExt : cl_image_requirements_info_ext
+{
+    RowPitchAlign = CL_IMAGE_REQUIREMENTS_ROW_PITCH_ALIGNMENT_EXT,
+    BaseAddAlign = CL_IMAGE_REQUIREMENTS_BASE_ADDRESS_ALIGNMENT_EXT,
+    Size = CL_IMAGE_REQUIREMENTS_SIZE_EXT,
+    MaxWidth = CL_IMAGE_REQUIREMENTS_MAX_WIDTH_EXT,
+    MaxHeight = CL_IMAGE_REQUIREMENTS_MAX_HEIGHT_EXT,
+    MaxDepth = CL_IMAGE_REQUIREMENTS_MAX_DEPTH_EXT,
+    MaxArraySize = CL_IMAGE_REQUIREMENTS_MAX_ARRAY_SIZE_EXT,
+#if defined(cl_ext_image_from_buffer)
+    SlicePitchAlign = CL_IMAGE_REQUIREMENTS_SLICE_PITCH_ALIGNMENT_EXT,
+#endif
+};
+
+#endif // cl_ext_image_requirements_info
+
+
 /*! \brief Class interface for cl_context.
  *
  *  \note Copies of these objects are shallow, meaning that the copy will refer
@@ -3084,6 +3201,51 @@ private:
     static void makeDefaultProvided(const Context &c) {
         default_ = c;
     }
+
+#if defined(cl_ext_image_requirements_info)
+    struct ImageRequirementsInfo {
+
+        ImageRequirementsInfo(cl_mem_flags f, const cl_mem_properties* mem_properties, const ImageFormat* format, const cl_image_desc* desc)
+        {
+            flags = f;
+            properties = mem_properties;
+            image_format = format;
+            image_desc = desc;
+        }
+
+        cl_mem_flags flags = 0;
+        const cl_mem_properties* properties;
+        const ImageFormat* image_format;
+        const cl_image_desc* image_desc;
+    };
+
+    static cl_int getImageRequirementsInfoExtHelper(const Context &context,
+        const ImageRequirementsInfo &info,
+        cl_image_requirements_info_ext param_name,
+        size_type param_value_size,
+        void* param_value,
+        size_type* param_value_size_ret)
+    {
+
+#if CL_HPP_TARGET_OPENCL_VERSION >= 120
+        Device device = context.getInfo<CL_CONTEXT_DEVICES>().at(0);
+        cl_platform_id platform = device.getInfo<CL_DEVICE_PLATFORM>()();
+        CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clGetImageRequirementsInfoEXT);
+#else
+        CL_HPP_INIT_CL_EXT_FCN_PTR_(clGetImageRequirementsInfoEXT);
+#endif
+
+        if (pfn_clGetImageRequirementsInfoEXT == nullptr) {
+            return detail::errHandler(CL_INVALID_OPERATION, __GET_IMAGE_REQUIREMENT_INFO_EXT_ERR);
+        }
+
+        return detail::errHandler(
+            pfn_clGetImageRequirementsInfoEXT(context(), info.properties,
+                info.flags, info.image_format, info.image_desc, param_name,
+                param_value_size, param_value, param_value_size_ret),
+            __GET_IMAGE_REQUIREMENT_INFO_EXT_ERR);
+    }
+#endif // cl_ext_image_requirements_info
     
 public:
 #ifdef CL_HPP_UNIT_TEST_ENABLE
@@ -3363,7 +3525,7 @@ public:
                 return detail::errHandler(err, __GET_SUPPORTED_IMAGE_FORMATS_ERR);
             }
 
-            formats->assign(begin(value), end(value));
+            formats->assign(value.begin(), value.end());
         }
         else {
             // If no values are being returned, ensure an empty vector comes back
@@ -3373,6 +3535,41 @@ public:
         return CL_SUCCESS;
     }
 
+#if defined(cl_ext_image_requirements_info)
+    template <typename T>
+    cl_int getImageRequirementsInfoExt(cl_image_requirements_info_ext name,
+        T* param,
+        cl_mem_flags flags = 0,
+        const cl_mem_properties* properties = nullptr,
+        const ImageFormat* image_format = nullptr,
+        const cl_image_desc* image_desc = nullptr) const
+    {
+        ImageRequirementsInfo imageInfo = {flags, properties, image_format, image_desc};
+
+        return detail::errHandler(
+            detail::getInfo(
+                Context::getImageRequirementsInfoExtHelper, *this, imageInfo, name, param),
+                __GET_IMAGE_REQUIREMENT_INFO_EXT_ERR);
+    }
+
+    template <cl_image_requirements_info_ext type> typename
+    detail::param_traits<detail::cl_image_requirements_info_ext, type>::param_type
+        getImageRequirementsInfoExt(cl_mem_flags flags = 0,
+            const cl_mem_properties* properties = nullptr,
+            const ImageFormat* image_format = nullptr,
+            const cl_image_desc* image_desc = nullptr,
+            cl_int* err = nullptr) const
+    {
+        typename detail::param_traits<
+        detail::cl_image_requirements_info_ext, type>::param_type param;
+        cl_int result = getImageRequirementsInfoExt(type, &param, flags, properties, image_format, image_desc);
+        if (err != nullptr) {
+            *err = result;
+        }
+        return param;
+    }
+#endif // cl_ext_image_requirements_info
+
 #if CL_HPP_TARGET_OPENCL_VERSION >= 300
     /*! \brief  Registers a destructor callback function with a context.
      *
@@ -3870,12 +4067,12 @@ public:
     {
     }
 
-    pointer address(reference r) CL_HPP_NOEXCEPT_
+    pointer address(reference r) noexcept
     {
         return std::addressof(r);
     }
 
-    const_pointer address(const_reference r) CL_HPP_NOEXCEPT_
+    const_pointer address(const_reference r) noexcept
     {
         return std::addressof(r);
     }
@@ -3888,7 +4085,8 @@ public:
      */
     pointer allocate(
         size_type size,
-        typename cl::SVMAllocator<void, SVMTrait>::const_pointer = 0)
+        typename cl::SVMAllocator<void, SVMTrait>::const_pointer = 0,
+        bool map = true)
     {
         // Allocate memory with default alignment matching the size of the type
         void* voidPointer =
@@ -3907,11 +4105,15 @@ public:
 #endif // #if defined(CL_HPP_ENABLE_EXCEPTIONS)
 
         // If allocation was coarse-grained then map it
-        if (!(SVMTrait::getSVMMemFlags() & CL_MEM_SVM_FINE_GRAIN_BUFFER)) {
+        if (map && !(SVMTrait::getSVMMemFlags() & CL_MEM_SVM_FINE_GRAIN_BUFFER)) {
             cl_int err = enqueueMapSVM(retValue, CL_TRUE, CL_MAP_READ | CL_MAP_WRITE, size*sizeof(T));
             if (err != CL_SUCCESS) {
+                clSVMFree(context_(), retValue);
+                retValue = nullptr;
+#if defined(CL_HPP_ENABLE_EXCEPTIONS)
                 std::bad_alloc excep;
                 throw excep;
+#endif
             }
         }
 
@@ -3928,7 +4130,7 @@ public:
      * Return the maximum possible allocation size.
      * This is the minimum of the maximum sizes of all devices in the context.
      */
-    size_type max_size() const CL_HPP_NOEXCEPT_
+    size_type max_size() const noexcept
     {
         size_type maxSize = std::numeric_limits<size_type>::max() / sizeof(T);
 
@@ -4026,10 +4228,18 @@ cl::pointer<T, detail::Deleter<Alloc>> allocate_pointer(const Alloc &alloc_, Arg
 
     T* tmp = std::allocator_traits<Alloc>::allocate(alloc, copies);
     if (!tmp) {
+#if defined(CL_HPP_ENABLE_EXCEPTIONS)
         std::bad_alloc excep;
         throw excep;
+#else
+        return nullptr;
+#endif
     }
-    try {
+
+#if defined(CL_HPP_ENABLE_EXCEPTIONS)
+    try
+#endif
+    {
         std::allocator_traits<Alloc>::construct(
             alloc,
             std::addressof(*tmp),
@@ -4037,11 +4247,13 @@ cl::pointer<T, detail::Deleter<Alloc>> allocate_pointer(const Alloc &alloc_, Arg
 
         return cl::pointer<T, detail::Deleter<Alloc>>(tmp, detail::Deleter<Alloc>{alloc, copies});
     }
+#if defined(CL_HPP_ENABLE_EXCEPTIONS)
     catch (std::bad_alloc&)
     {
         std::allocator_traits<Alloc>::deallocate(alloc, tmp, copies);
         throw;
     }
+#endif
 }
 
 template< class T, class SVMTrait, class... Args >
@@ -4633,6 +4845,42 @@ public:
     //! \brief Default constructor - initializes to nullptr.
     Image1D() { }
 
+#if CL_HPP_TARGET_OPENCL_VERSION >= 300
+    /*! \brief Constructs a Image1D with specified properties.
+     *
+     *  Wraps clCreateImageWithProperties().
+     *
+     *  \param properties Optional list of properties for the image object and
+     *                    their corresponding values. The non-empty list must
+     *                    end with 0.
+     *  \param host_ptr Storage to be used if the CL_MEM_USE_HOST_PTR flag was
+     *                  specified. Note alignment & exclusivity requirements.
+     */
+    Image1D(const Context &context, const vector<cl_mem_properties> &properties,
+            cl_mem_flags flags, ImageFormat format, size_type width,
+            void *host_ptr = nullptr, cl_int *err = nullptr) {
+      cl_int error;
+
+      cl_image_desc desc = {};
+      desc.image_type = CL_MEM_OBJECT_IMAGE1D;
+      desc.image_width = width;
+
+      if (properties.empty()) {
+        object_ = ::clCreateImageWithProperties(
+            context(), nullptr, flags, &format, &desc, host_ptr, &error);
+      } else {
+        object_ =
+            ::clCreateImageWithProperties(context(), properties.data(), flags,
+                                          &format, &desc, host_ptr, &error);
+      }
+
+      detail::errHandler(error, __CREATE_IMAGE_ERR);
+      if (err != nullptr) {
+        *err = error;
+      }
+    }
+#endif //#if CL_HPP_TARGET_OPENCL_VERSION >= 300
+
     /*! \brief Constructor from cl_mem - takes ownership.
      *
      * \param retainObject will cause the constructor to retain its cl object.
@@ -4693,6 +4941,43 @@ public:
 
     Image1DBuffer() { }
 
+#if CL_HPP_TARGET_OPENCL_VERSION >= 300
+    /*! \brief Constructs a Image1DBuffer with specified properties.
+     *
+     *  Wraps clCreateImageWithProperties().
+     *
+     *  \param properties Optional list of properties for the image object and
+     *                    their corresponding values. The non-empty list must
+     *                    end with 0.
+     *  \param buffer Refer to a valid buffer or image memory object.
+     */
+    Image1DBuffer(const Context &context,
+                  const vector<cl_mem_properties> &properties,
+                  cl_mem_flags flags, ImageFormat format, size_type width,
+                  const Buffer &buffer, cl_int *err = nullptr) {
+      cl_int error;
+
+      cl_image_desc desc = {};
+      desc.image_type = CL_MEM_OBJECT_IMAGE1D_BUFFER;
+      desc.image_width = width;
+      desc.buffer = buffer();
+
+      if (properties.empty()) {
+        object_ = ::clCreateImageWithProperties(
+            context(), nullptr, flags, &format, &desc, nullptr, &error);
+      } else {
+        object_ =
+            ::clCreateImageWithProperties(context(), properties.data(), flags,
+                                          &format, &desc, nullptr, &error);
+      }
+
+      detail::errHandler(error, __CREATE_IMAGE_ERR);
+      if (err != nullptr) {
+        *err = error;
+      }
+    }
+#endif //#if CL_HPP_TARGET_OPENCL_VERSION >= 300
+
     /*! \brief Constructor from cl_mem - takes ownership.
      *
      * \param retainObject will cause the constructor to retain its cl object.
@@ -4708,9 +4993,6 @@ public:
         Image::operator=(rhs);
         return *this;
     }
-
-
-
 };
 
 /*! \class Image1DArray
@@ -4752,7 +5034,47 @@ public:
     }
 
     Image1DArray() { }
-  
+
+#if CL_HPP_TARGET_OPENCL_VERSION >= 300
+    /*! \brief Constructs a Image1DArray with specified properties.
+     *
+     *  Wraps clCreateImageWithProperties().
+     *
+     *  \param properties Optional list of properties for the image object and
+     *                    their corresponding values. The non-empty list must
+     *                    end with 0.
+     *  \param host_ptr Storage to be used if the CL_MEM_USE_HOST_PTR flag was
+     *                  specified. Note alignment & exclusivity requirements.
+     */
+    Image1DArray(const Context &context,
+                 const vector<cl_mem_properties> &properties,
+                 cl_mem_flags flags, ImageFormat format, size_type arraySize,
+                 size_type width, size_type rowPitch = 0,
+                 void *host_ptr = nullptr, cl_int *err = nullptr) {
+      cl_int error;
+
+      cl_image_desc desc = {};
+      desc.image_type = CL_MEM_OBJECT_IMAGE1D_ARRAY;
+      desc.image_width = width;
+      desc.image_array_size = arraySize;
+      desc.image_row_pitch = rowPitch;
+
+      if (properties.empty()) {
+        object_ = ::clCreateImageWithProperties(
+            context(), nullptr, flags, &format, &desc, host_ptr, &error);
+      } else {
+        object_ =
+            ::clCreateImageWithProperties(context(), properties.data(), flags,
+                                          &format, &desc, host_ptr, &error);
+      }
+
+      detail::errHandler(error, __CREATE_IMAGE_ERR);
+      if (err != nullptr) {
+        *err = error;
+      }
+    }
+#endif //#if CL_HPP_TARGET_OPENCL_VERSION >= 300
+
     /*! \brief Constructor from cl_mem - takes ownership.
      *
      * \param retainObject will cause the constructor to retain its cl object.
@@ -4955,6 +5277,83 @@ public:
     }
 #endif //#if CL_HPP_TARGET_OPENCL_VERSION >= 200
 
+#if CL_HPP_TARGET_OPENCL_VERSION >= 300
+    /*! \brief Constructs a Image2D with specified properties.
+     *
+     *  Wraps clCreateImageWithProperties().
+     *
+     *  \param properties Optional list of properties for the image object and
+     *                    their corresponding values. The non-empty list must
+     *                    end with 0.
+     *  \param host_ptr Storage to be used if the CL_MEM_USE_HOST_PTR flag was
+     *                  specified. Note alignment & exclusivity requirements.
+     */
+    Image2D(const Context &context, const vector<cl_mem_properties> &properties,
+            cl_mem_flags flags, ImageFormat format, size_type width,
+            size_type height, size_type row_pitch = 0, void *host_ptr = nullptr,
+            cl_int *err = nullptr) {
+      cl_int error;
+
+      cl_image_desc desc = {};
+      desc.image_type = CL_MEM_OBJECT_IMAGE2D;
+      desc.image_width = width;
+      desc.image_height = height;
+      desc.image_row_pitch = row_pitch;
+
+      if (properties.empty()) {
+        object_ = ::clCreateImageWithProperties(
+            context(), nullptr, flags, &format, &desc, host_ptr, &error);
+      } else {
+        object_ =
+            ::clCreateImageWithProperties(context(), properties.data(), flags,
+                                          &format, &desc, host_ptr, &error);
+      }
+
+      detail::errHandler(error, __CREATE_IMAGE_ERR);
+      if (err != nullptr) {
+        *err = error;
+      }
+    }
+
+    /*! \brief Constructs a Image2D with specified properties.
+     *
+     *  Wraps clCreateImageWithProperties().
+     *
+     *  \param properties Optional list of properties for the image object and
+     *                    their corresponding values. The non-empty list must
+     *                    end with 0.
+     *  \param buffer Refer to a valid buffer or image memory object.
+     */
+    Image2D(const Context &context, const vector<cl_mem_properties> &properties,
+            cl_mem_flags flags, ImageFormat format, const Buffer &buffer,
+            size_type width, size_type height, size_type row_pitch = 0,
+            cl_int *err = nullptr) {
+      cl_int error;
+
+      cl_image_desc desc = {};
+      desc.image_type = CL_MEM_OBJECT_IMAGE2D;
+      desc.image_width = width;
+      desc.image_height = height;
+      desc.image_row_pitch = row_pitch;
+      desc.buffer = buffer();
+
+      if (properties.empty()) {
+        object_ = ::clCreateImageWithProperties(
+            context(), nullptr, flags, &format, &desc, nullptr, &error);
+      } else {
+        object_ =
+            ::clCreateImageWithProperties(context(), properties.data(), flags,
+                                          &format, &desc, nullptr, &error);
+      }
+
+      detail::errHandler(error, __CREATE_IMAGE_ERR);
+      if (err != nullptr) {
+        *err = error;
+      }
+    }
+
+#endif //#if CL_HPP_TARGET_OPENCL_VERSION >= 300
+
     //! \brief Default constructor - initializes to nullptr.
     Image2D() { }
 
@@ -4977,10 +5376,6 @@ public:
         Image::operator=(rhs);
         return *this;
     }
-
-
-
-
 };
 
 
@@ -5097,6 +5492,49 @@ public:
         }
     }
 
+#if CL_HPP_TARGET_OPENCL_VERSION >= 300
+    /*! \brief Constructs a Image2DArray with specified properties.
+     *
+     *  Wraps clCreateImageWithProperties().
+     *
+     *  \param properties Optional list of properties for the image object and
+     *                    their corresponding values. The non-empty list must
+     *                    end with 0.
+     *  \param host_ptr Storage to be used if the CL_MEM_USE_HOST_PTR flag was
+     *                  specified. Note alignment & exclusivity requirements.
+     */
+    Image2DArray(const Context &context,
+                 const vector<cl_mem_properties> &properties,
+                 cl_mem_flags flags, ImageFormat format, size_type arraySize,
+                 size_type width, size_type height, size_type rowPitch = 0,
+                 size_type slicePitch = 0, void *host_ptr = nullptr,
+                 cl_int *err = nullptr) {
+      cl_int error;
+
+      cl_image_desc desc = {};
+      desc.image_type = CL_MEM_OBJECT_IMAGE2D_ARRAY;
+      desc.image_width = width;
+      desc.image_height = height;
+      desc.image_array_size = arraySize;
+      desc.image_row_pitch = rowPitch;
+      desc.image_slice_pitch = slicePitch;
+
+      if (properties.empty()) {
+        object_ = ::clCreateImageWithProperties(
+            context(), nullptr, flags, &format, &desc, host_ptr, &error);
+      } else {
+        object_ =
+            ::clCreateImageWithProperties(context(), properties.data(), flags,
+                                          &format, &desc, host_ptr, &error);
+      }
+
+      detail::errHandler(error, __CREATE_IMAGE_ERR);
+      if (err != nullptr) {
+        *err = error;
+      }
+    }
+#endif //#if CL_HPP_TARGET_OPENCL_VERSION >= 300
+
     Image2DArray() { }
     
     /*! \brief Constructor from cl_mem - takes ownership.
@@ -5197,6 +5635,48 @@ public:
 #endif // CL_HPP_MINIMUM_OPENCL_VERSION < 120
     }
 
+#if CL_HPP_TARGET_OPENCL_VERSION >= 300
+    /*! \brief Constructs a Image3D with specified properties.
+     *
+     *  Wraps clCreateImageWithProperties().
+     *
+     *  \param properties Optional list of properties for the image object and
+     *                    their corresponding values. The non-empty list must
+     *                    end with 0.
+     *  \param host_ptr Storage to be used if the CL_MEM_USE_HOST_PTR flag was
+     *                  specified. Note alignment & exclusivity requirements.
+     */
+    Image3D(const Context &context, const vector<cl_mem_properties> &properties,
+            cl_mem_flags flags, ImageFormat format, size_type width,
+            size_type height, size_type depth, size_type row_pitch = 0,
+            size_type slice_pitch = 0, void *host_ptr = nullptr,
+            cl_int *err = nullptr) {
+      cl_int error;
+
+      cl_image_desc desc = {};
+      desc.image_type = CL_MEM_OBJECT_IMAGE3D;
+      desc.image_width = width;
+      desc.image_height = height;
+      desc.image_depth = depth;
+      desc.image_row_pitch = row_pitch;
+      desc.image_slice_pitch = slice_pitch;
+
+      if (properties.empty()) {
+        object_ = ::clCreateImageWithProperties(
+            context(), nullptr, flags, &format, &desc, host_ptr, &error);
+      } else {
+        object_ =
+            ::clCreateImageWithProperties(context(), properties.data(), flags,
+                                          &format, &desc, host_ptr, &error);
+      }
+
+      detail::errHandler(error, __CREATE_IMAGE_ERR);
+      if (err != nullptr) {
+        *err = error;
+      }
+    }
+#endif //#if CL_HPP_TARGET_OPENCL_VERSION >= 300
+
     //! \brief Default constructor - initializes to nullptr.
     Image3D() : Image() { }
 
@@ -5718,6 +6198,7 @@ Local(size_type size)
 class Kernel : public detail::Wrapper<cl_kernel>
 {
 public:
+    inline Kernel(const Program& program, const string& name, cl_int* err = nullptr);
     inline Kernel(const Program& program, const char* name, cl_int* err = nullptr);
 
     //! \brief Default constructor - initializes to nullptr.
@@ -6196,7 +6677,6 @@ public:
         }
     }
 
-
 #if defined(CL_HPP_USE_IL_KHR) || CL_HPP_TARGET_OPENCL_VERSION >= 210
     /**
      * Program constructor to allow construction of program from SPIR-V or another IL.
@@ -6346,7 +6826,6 @@ public:
             return;
         }
 
-
         vector<size_type> lengths(numDevices);
         vector<const unsigned char*> images(numDevices);
 #if !defined(CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY)
@@ -6360,7 +6839,7 @@ public:
             lengths[i] = binaries[(int)i].second;
         }
 #endif // #if !defined(CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY)
-        
+
         vector<cl_device_id> deviceIDs(numDevices);
         for( size_type deviceIndex = 0; deviceIndex < numDevices; ++deviceIndex ) {
             deviceIDs[deviceIndex] = (devices[deviceIndex])();
@@ -6369,7 +6848,7 @@ public:
         if(binaryStatus) {
             binaryStatus->resize(numDevices);
         }
-        
+
         object_ = ::clCreateProgramWithBinary(
             context(), (cl_uint) devices.size(),
             deviceIDs.data(),
@@ -6436,6 +6915,14 @@ public:
         return *this;
     }
 
+    cl_int build(
+        const vector<Device>& devices,
+        const string& options,
+        void (CL_CALLBACK * notifyFptr)(cl_program, void *) = nullptr,
+        void* data = nullptr) const
+    {
+        return build(devices, options.c_str(), notifyFptr, data);
+    }
 
     cl_int build(
         const vector<Device>& devices,
@@ -6445,7 +6932,7 @@ public:
     {
         size_type numDevices = devices.size();
         vector<cl_device_id> deviceIDs(numDevices);
-        
+
         for( size_type deviceIndex = 0; deviceIndex < numDevices; ++deviceIndex ) {
             deviceIDs[deviceIndex] = (devices[deviceIndex])();
         }
@@ -6462,6 +6949,15 @@ public:
         return detail::buildErrHandler(buildError, __BUILD_PROGRAM_ERR, getBuildInfo<CL_PROGRAM_BUILD_LOG>());
     }
 
+    cl_int build(
+        const Device& device,
+        const string& options,
+        void (CL_CALLBACK * notifyFptr)(cl_program, void *) = nullptr,
+        void* data = nullptr) const
+    {
+        return build(device, options.c_str(), notifyFptr, data);
+    }
+
     cl_int build(
         const Device& device,
         const char* options = nullptr,
@@ -6483,6 +6979,14 @@ public:
         return detail::buildErrHandler(buildError, __BUILD_PROGRAM_ERR, buildLog);
     }
 
+    cl_int build(
+        const string& options,
+        void (CL_CALLBACK * notifyFptr)(cl_program, void *) = nullptr,
+        void* data = nullptr) const
+    {
+        return build(options.c_str(), notifyFptr, data);
+    }
+
     cl_int build(
         const char* options = nullptr,
         void (CL_CALLBACK * notifyFptr)(cl_program, void *) = nullptr,
@@ -6500,6 +7004,14 @@ public:
     }
 
 #if CL_HPP_TARGET_OPENCL_VERSION >= 120
+    cl_int compile(
+        const string& options,
+        void (CL_CALLBACK * notifyFptr)(cl_program, void *) = nullptr,
+        void* data = nullptr) const
+    {
+        return compile(options.c_str(), notifyFptr, data);
+    }
+
     cl_int compile(
         const char* options = nullptr,
         void (CL_CALLBACK * notifyFptr)(cl_program, void *) = nullptr,
@@ -6517,6 +7029,84 @@ public:
             data);
         return detail::buildErrHandler(error, __COMPILE_PROGRAM_ERR, getBuildInfo<CL_PROGRAM_BUILD_LOG>());
     }
+
+    cl_int compile(
+        const string& options,
+        const vector<Program>& inputHeaders,
+        const vector<string>& headerIncludeNames,
+        void (CL_CALLBACK * notifyFptr)(cl_program, void *) = nullptr,
+        void* data = nullptr) const
+    {
+        return compile(options.c_str(), inputHeaders, headerIncludeNames, notifyFptr, data);
+    }
+
+    cl_int compile(
+        const char* options,
+        const vector<Program>& inputHeaders,
+        const vector<string>& headerIncludeNames,
+        void (CL_CALLBACK * notifyFptr)(cl_program, void *) = nullptr,
+        void* data = nullptr) const
+    {
+        static_assert(sizeof(cl::Program) == sizeof(cl_program),
+            "Size of cl::Program must be equal to size of cl_program");
+        vector<const char*> headerIncludeNamesCStr;
+        for(const string& name: headerIncludeNames) {
+            headerIncludeNamesCStr.push_back(name.c_str());
+        }
+        cl_int error = ::clCompileProgram(
+            object_,
+            0,
+            nullptr,
+            options,
+            static_cast<cl_uint>(inputHeaders.size()),
+            reinterpret_cast<const cl_program*>(inputHeaders.data()),
+            reinterpret_cast<const char**>(headerIncludeNamesCStr.data()),
+            notifyFptr,
+            data);
+        return detail::buildErrHandler(error, __COMPILE_PROGRAM_ERR, getBuildInfo<CL_PROGRAM_BUILD_LOG>());
+    }
+
+    cl_int compile(
+        const string& options,
+        const vector<Device>& deviceList,
+        const vector<Program>& inputHeaders = vector<Program>(),
+        const vector<string>& headerIncludeNames = vector<string>(),
+        void (CL_CALLBACK * notifyFptr)(cl_program, void *) = nullptr,
+        void* data = nullptr) const
+    {
+        return compile(options.c_str(), deviceList, inputHeaders, headerIncludeNames, notifyFptr, data);
+    }
+
+    cl_int compile(
+        const char* options,
+        const vector<Device>& deviceList,
+        const vector<Program>& inputHeaders = vector<Program>(),
+        const vector<string>& headerIncludeNames = vector<string>(),
+        void (CL_CALLBACK * notifyFptr)(cl_program, void *) = nullptr,
+        void* data = nullptr) const
+    {
+        static_assert(sizeof(cl::Program) == sizeof(cl_program),
+            "Size of cl::Program must be equal to size of cl_program");
+        vector<const char*> headerIncludeNamesCStr;
+        for(const string& name: headerIncludeNames) {
+            headerIncludeNamesCStr.push_back(name.c_str());
+        }
+        vector<cl_device_id> deviceIDList;
+        for(const Device& device: deviceList) {
+            deviceIDList.push_back(device());
+        }
+        cl_int error = ::clCompileProgram(
+            object_,
+            static_cast<cl_uint>(deviceList.size()),
+            reinterpret_cast<const cl_device_id*>(deviceIDList.data()),
+            options,
+            static_cast<cl_uint>(inputHeaders.size()),
+            reinterpret_cast<const cl_program*>(inputHeaders.data()),
+            reinterpret_cast<const char**>(headerIncludeNamesCStr.data()),
+            notifyFptr,
+            data);
+        return detail::buildErrHandler(error, __COMPILE_PROGRAM_ERR, getBuildInfo<CL_PROGRAM_BUILD_LOG>());
+    }
 #endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
 
     template <typename T>
@@ -6732,6 +7322,17 @@ inline Program linkProgram(
     return Program(prog);
 }
 
+inline Program linkProgram(
+    const Program& input1,
+    const Program& input2,
+    const string& options,
+    void (CL_CALLBACK * notifyFptr)(cl_program, void *) = nullptr,
+    void* data = nullptr,
+    cl_int* err = nullptr)
+{
+    return linkProgram(input1, input2, options.c_str(), notifyFptr, data, err);
+}
+
 inline Program linkProgram(
     const vector<Program>& inputPrograms,
     const char* options = nullptr,
@@ -6770,6 +7371,16 @@ inline Program linkProgram(
 
     return Program(prog);
 }
+
+inline Program linkProgram(
+    const vector<Program>& inputPrograms,
+    const string& options,
+    void (CL_CALLBACK * notifyFptr)(cl_program, void *) = nullptr,
+    void* data = nullptr,
+    cl_int* err = nullptr)
+{
+    return linkProgram(inputPrograms, options.c_str(), notifyFptr, data, err);
+}
 #endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
 
 // Template specialization for CL_PROGRAM_BINARIES
@@ -6828,6 +7439,18 @@ inline cl_int cl::Program::setSpecializationConstant(cl_uint index, const bool &
 }
 #endif // CL_HPP_TARGET_OPENCL_VERSION >= 220
 
+inline Kernel::Kernel(const Program& program, const string& name, cl_int* err)
+{
+    cl_int error;
+
+    object_ = ::clCreateKernel(program(), name.c_str(), &error);
+    detail::errHandler(error, __CREATE_KERNEL_ERR);
+
+    if (err != nullptr) {
+        *err = error;
+    }
+}
+
 inline Kernel::Kernel(const Program& program, const char* name, cl_int* err)
 {
     cl_int error;
@@ -6838,27 +7461,24 @@ inline Kernel::Kernel(const Program& program, const char* name, cl_int* err)
     if (err != nullptr) {
         *err = error;
     }
-
 }
 
 #ifdef cl_khr_external_memory
 enum class ExternalMemoryType : cl_external_memory_handle_type_khr
 {
     None = 0,
-
+#ifdef cl_khr_external_memory_opaque_fd
     OpaqueFd = CL_EXTERNAL_MEMORY_HANDLE_OPAQUE_FD_KHR,
+#endif // cl_khr_external_memory_opaque_fd
+#ifdef cl_khr_external_memory_win32
     OpaqueWin32 = CL_EXTERNAL_MEMORY_HANDLE_OPAQUE_WIN32_KHR,
     OpaqueWin32Kmt = CL_EXTERNAL_MEMORY_HANDLE_OPAQUE_WIN32_KMT_KHR,
-
-    D3D11Texture = CL_EXTERNAL_MEMORY_HANDLE_D3D11_TEXTURE_KHR,
-    D3D11TextureKmt = CL_EXTERNAL_MEMORY_HANDLE_D3D11_TEXTURE_KMT_KHR,
-
-    D3D12Heap = CL_EXTERNAL_MEMORY_HANDLE_D3D12_HEAP_KHR,
-    D3D12Resource = CL_EXTERNAL_MEMORY_HANDLE_D3D12_RESOURCE_KHR,
-
+#endif // cl_khr_external_memory_win32
+#ifdef cl_khr_external_memory_dma_buf
     DmaBuf = CL_EXTERNAL_MEMORY_HANDLE_DMA_BUF_KHR,
+#endif // cl_khr_external_memory_dma_buf
 };
-#endif
+#endif // cl_khr_external_memory
 
 enum class QueueProperties : cl_command_queue_properties
 {
@@ -6933,7 +7553,7 @@ private:
 
     static void initMemoryExtension(const cl::Device& device) 
     {
-        auto platform = device.getInfo<CL_DEVICE_PLATFORM>();
+        auto platform = device.getInfo<CL_DEVICE_PLATFORM>()();
 
         CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clEnqueueAcquireExternalMemObjectsKHR);
         CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clEnqueueReleaseExternalMemObjectsKHR);
@@ -8111,6 +8731,162 @@ public:
     }
 
 #if CL_HPP_TARGET_OPENCL_VERSION >= 200
+
+    /**
+    * Enqueues a command that copies a region of memory from the source pointer to the destination pointer.
+    * This function is specifically for transferring data between the host and a coarse-grained SVM buffer.
+    */
+    template<typename T>
+    cl_int enqueueMemcpySVM(
+            T *dst_ptr,
+            const T *src_ptr,
+            cl_bool blocking,
+            size_type size,
+            const vector<Event> *events = nullptr,
+            Event *event = nullptr) const {
+        cl_event tmp;
+        cl_int err = detail::errHandler(::clEnqueueSVMMemcpy(
+                object_, blocking, static_cast<void *>(dst_ptr), static_cast<const void *>(src_ptr), size,
+                (events != nullptr) ? (cl_uint) events->size() : 0,
+                (events != nullptr && events->size() > 0) ? (cl_event *) &events->front() : nullptr,
+                (event != nullptr) ? &tmp : nullptr), __ENQUEUE_COPY_SVM_ERR);
+
+        if (event != nullptr && err == CL_SUCCESS)
+            *event = tmp;
+
+        return err;
+    }
+
+    /**
+    *Enqueues a command that will copy data from one coarse-grained SVM buffer to another.
+    *This function takes two cl::pointer instances representing the destination and source buffers.
+    */
+    template<typename T, class D>
+    cl_int enqueueMemcpySVM(
+            cl::pointer<T, D> &dst_ptr,
+            const cl::pointer<T, D> &src_ptr,
+            cl_bool blocking,
+            size_type size,
+            const vector<Event> *events = nullptr,
+            Event *event = nullptr) const {
+        cl_event tmp;
+        cl_int err = detail::errHandler(::clEnqueueSVMMemcpy(
+                object_, blocking, static_cast<void *>(dst_ptr.get()), static_cast<const void *>(src_ptr.get()),
+                size,
+                (events != nullptr) ? (cl_uint) events->size() : 0,
+                (events != nullptr && events->size() > 0) ? (cl_event *) &events->front() : nullptr,
+                (event != nullptr) ? &tmp : nullptr), __ENQUEUE_COPY_SVM_ERR);
+
+        if (event != nullptr && err == CL_SUCCESS)
+            *event = tmp;
+
+        return err;
+    }
+
+    /**
+    * Enqueues a command that will allow the host to update a region of a coarse-grained SVM buffer.
+    * This variant takes a cl::vector instance.
+    */
+    template<typename T, class Alloc>
+    cl_int enqueueMemcpySVM(
+            cl::vector<T, Alloc> &dst_container,
+            const cl::vector<T, Alloc> &src_container,
+            cl_bool blocking,
+            const vector<Event> *events = nullptr,
+            Event *event = nullptr) const {
+        cl_event tmp;
+        if(src_container.size() != dst_container.size()){
+            return detail::errHandler(CL_INVALID_VALUE,__ENQUEUE_COPY_SVM_ERR);
+        }
+        cl_int err = detail::errHandler(::clEnqueueSVMMemcpy(
+                object_, blocking, static_cast<void *>(dst_container.data()),
+                static_cast<const void *>(src_container.data()),
+                dst_container.size() * sizeof(T),
+                (events != nullptr) ? (cl_uint) events->size() : 0,
+                (events != nullptr && events->size() > 0) ? (cl_event *) &events->front() : nullptr,
+                (event != NULL) ? &tmp : nullptr), __ENQUEUE_COPY_SVM_ERR);
+
+        if (event != nullptr && err == CL_SUCCESS)
+            *event = tmp;
+
+        return err;
+    }
+
+    /**
+    * Enqueues a command to fill a SVM buffer with a pattern.
+    *
+    */
+    template<typename T, typename PatternType>
+    cl_int enqueueMemFillSVM(
+            T *ptr,
+            PatternType pattern,
+            size_type size,
+            const vector<Event> *events = nullptr,
+            Event *event = nullptr) const {
+        cl_event tmp;
+        cl_int err = detail::errHandler(::clEnqueueSVMMemFill(
+                object_, static_cast<void *>(ptr), static_cast<void *>(&pattern),
+                sizeof(PatternType), size,
+                (events != nullptr) ? (cl_uint) events->size() : 0,
+                (events != nullptr && events->size() > 0) ? (cl_event *) &events->front() : nullptr,
+                (event != nullptr) ? &tmp : nullptr), __ENQUEUE_FILL_SVM_ERR);
+
+        if (event != nullptr && err == CL_SUCCESS)
+            *event = tmp;
+
+        return err;
+    }
+
+    /**
+    * Enqueues a command that fills a region of a coarse-grained SVM buffer with a specified pattern.
+    * This variant takes a cl::pointer instance.
+    */
+    template<typename T, class D, typename PatternType>
+    cl_int enqueueMemFillSVM(
+            cl::pointer<T, D> &ptr,
+            PatternType pattern,
+            size_type size,
+            const vector<Event> *events = nullptr,
+            Event *event = nullptr) const {
+        cl_event tmp;
+        cl_int err = detail::errHandler(::clEnqueueSVMMemFill(
+                object_, static_cast<void *>(ptr.get()), static_cast<void *>(&pattern),
+                sizeof(PatternType), size,
+                (events != nullptr) ? (cl_uint) events->size() : 0,
+                (events != nullptr && events->size() > 0) ? (cl_event *) &events->front() : nullptr,
+                (event != nullptr) ? &tmp : nullptr), __ENQUEUE_FILL_SVM_ERR);
+
+        if (event != nullptr && err == CL_SUCCESS)
+            *event = tmp;
+
+        return err;
+    }
+
+    /**
+    * Enqueues a command that will allow the host to fill a region of a coarse-grained SVM buffer with a specified pattern.
+    * This variant takes a cl::vector instance.
+    */
+    template<typename T, class Alloc, typename PatternType>
+    cl_int enqueueMemFillSVM(
+            cl::vector<T, Alloc> &container,
+            PatternType pattern,
+            const vector<Event> *events = nullptr,
+            Event* event = nullptr) const
+    {
+        cl_event tmp;
+        cl_int err = detail::errHandler(::clEnqueueSVMMemFill(
+                object_, static_cast<void *>(container.data()), static_cast<void *>(&pattern),
+                sizeof(PatternType), container.size() * sizeof(T),
+                (events != nullptr) ? (cl_uint) events->size() : 0,
+                (events != nullptr && events->size() > 0) ? (cl_event *) &events->front() : nullptr,
+                (event != nullptr) ? &tmp : NULL), __ENQUEUE_FILL_SVM_ERR);
+
+        if (event != nullptr && err == CL_SUCCESS)
+            *event = tmp;
+
+        return err;
+    }
+
     /**
      * Enqueues a command that will allow the host to update a region of a coarse-grained SVM buffer.
      * This variant takes a raw SVM pointer.
@@ -8130,7 +8906,7 @@ public:
             (events != nullptr) ? (cl_uint)events->size() : 0,
             (events != nullptr && events->size() > 0) ? (cl_event*)&events->front() : nullptr,
             (event != nullptr) ? &tmp : nullptr),
-            __ENQUEUE_MAP_BUFFER_ERR);
+            __ENQUEUE_MAP_SVM_ERR);
 
         if (event != nullptr && err == CL_SUCCESS)
             *event = tmp;
@@ -8158,7 +8934,7 @@ public:
             (events != nullptr) ? (cl_uint)events->size() : 0,
             (events != nullptr && events->size() > 0) ? (cl_event*)&events->front() : nullptr,
             (event != nullptr) ? &tmp : nullptr),
-            __ENQUEUE_MAP_BUFFER_ERR);
+            __ENQUEUE_MAP_SVM_ERR);
 
         if (event != nullptr && err == CL_SUCCESS)
             *event = tmp;
@@ -8184,7 +8960,7 @@ public:
             (events != nullptr) ? (cl_uint)events->size() : 0,
             (events != nullptr && events->size() > 0) ? (cl_event*)&events->front() : nullptr,
             (event != nullptr) ? &tmp : nullptr),
-            __ENQUEUE_MAP_BUFFER_ERR);
+            __ENQUEUE_MAP_SVM_ERR);
 
         if (event != nullptr && err == CL_SUCCESS)
             *event = tmp;
@@ -8233,7 +9009,7 @@ public:
             (events != nullptr) ? (cl_uint)events->size() : 0,
             (events != nullptr && events->size() > 0) ? (cl_event*)&events->front() : nullptr,
             (event != nullptr) ? &tmp : nullptr),
-            __ENQUEUE_UNMAP_MEM_OBJECT_ERR);
+            __ENQUEUE_UNMAP_SVM_ERR);
 
         if (event != nullptr && err == CL_SUCCESS)
             *event = tmp;
@@ -8258,7 +9034,7 @@ public:
             (events != nullptr) ? (cl_uint)events->size() : 0,
             (events != nullptr && events->size() > 0) ? (cl_event*)&events->front() : nullptr,
             (event != nullptr) ? &tmp : nullptr),
-            __ENQUEUE_UNMAP_MEM_OBJECT_ERR);
+            __ENQUEUE_UNMAP_SVM_ERR);
 
         if (event != nullptr && err == CL_SUCCESS)
             *event = tmp;
@@ -8283,7 +9059,7 @@ public:
             (events != nullptr) ? (cl_uint)events->size() : 0,
             (events != nullptr && events->size() > 0) ? (cl_event*)&events->front() : nullptr,
             (event != nullptr) ? &tmp : nullptr),
-            __ENQUEUE_UNMAP_MEM_OBJECT_ERR);
+            __ENQUEUE_UNMAP_SVM_ERR);
 
         if (event != nullptr && err == CL_SUCCESS)
             *event = tmp;
@@ -9301,7 +10077,7 @@ inline cl_int enqueueMapSVM(
     cl_int error;
     CommandQueue queue = CommandQueue::getDefault(&error);
     if (error != CL_SUCCESS) {
-        return detail::errHandler(error, __ENQUEUE_MAP_BUFFER_ERR);
+        return detail::errHandler(error, __ENQUEUE_MAP_SVM_ERR);
     }
 
     return queue.enqueueMapSVM(
@@ -9348,7 +10124,7 @@ inline cl_int enqueueMapSVM(
     cl_int error;
     CommandQueue queue = CommandQueue::getDefault(&error);
     if (error != CL_SUCCESS) {
-        return detail::errHandler(error, __ENQUEUE_MAP_BUFFER_ERR);
+        return detail::errHandler(error, __ENQUEUE_MAP_SVM_ERR);
     }
 
     return queue.enqueueMapSVM(
@@ -9400,11 +10176,11 @@ inline cl_int enqueueUnmapSVM(
     cl_int error;
     CommandQueue queue = CommandQueue::getDefault(&error);
     if (error != CL_SUCCESS) {
-        return detail::errHandler(error, __ENQUEUE_UNMAP_MEM_OBJECT_ERR);
+        return detail::errHandler(error, __ENQUEUE_UNMAP_SVM_ERR);
     }
 
     return detail::errHandler(queue.enqueueUnmapSVM(ptr, events, event), 
-        __ENQUEUE_UNMAP_MEM_OBJECT_ERR);
+        __ENQUEUE_UNMAP_SVM_ERR);
 
 }
 
@@ -9422,11 +10198,11 @@ inline cl_int enqueueUnmapSVM(
     cl_int error;
     CommandQueue queue = CommandQueue::getDefault(&error);
     if (error != CL_SUCCESS) {
-        return detail::errHandler(error, __ENQUEUE_UNMAP_MEM_OBJECT_ERR);
+        return detail::errHandler(error, __ENQUEUE_UNMAP_SVM_ERR);
     }
 
     return detail::errHandler(queue.enqueueUnmapSVM(ptr, events, event),
-        __ENQUEUE_UNMAP_MEM_OBJECT_ERR);
+        __ENQUEUE_UNMAP_SVM_ERR);
 }
 
 /**
@@ -9443,11 +10219,11 @@ inline cl_int enqueueUnmapSVM(
     cl_int error;
     CommandQueue queue = CommandQueue::getDefault(&error);
     if (error != CL_SUCCESS) {
-        return detail::errHandler(error, __ENQUEUE_UNMAP_MEM_OBJECT_ERR);
+        return detail::errHandler(error, __ENQUEUE_UNMAP_SVM_ERR);
     }
 
     return detail::errHandler(queue.enqueueUnmapSVM(container, events, event),
-        __ENQUEUE_UNMAP_MEM_OBJECT_ERR);
+        __ENQUEUE_UNMAP_SVM_ERR);
 }
 
 #endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 200
@@ -9523,15 +10299,15 @@ inline cl_int copy( const CommandQueue &queue, IteratorType startIterator, Itera
     if( error != CL_SUCCESS ) {
         return error;
     }
-#if defined(_MSC_VER)
+#if defined(_MSC_VER) && _MSC_VER < 1920
     std::copy(
-        startIterator, 
-        endIterator, 
+        startIterator,
+        endIterator,
         stdext::checked_array_iterator<DataType*>(
             pointer, length));
 #else
     std::copy(startIterator, endIterator, pointer);
-#endif
+#endif // defined(_MSC_VER) && _MSC_VER < 1920
     Event endEvent;
     error = queue.enqueueUnmapMemObject(buffer, pointer, 0, &endEvent);
     // if exceptions enabled, enqueueUnmapMemObject will throw
@@ -10400,6 +11176,24 @@ namespace compatibility {
 } // namespace compatibility
 
 #ifdef cl_khr_semaphore
+
+#ifdef cl_khr_external_semaphore
+enum ExternalSemaphoreType : cl_external_semaphore_handle_type_khr
+{
+    None = 0,
+#ifdef cl_khr_external_semaphore_opaque_fd
+    OpaqueFd = CL_SEMAPHORE_HANDLE_OPAQUE_FD_KHR,
+#endif // cl_khr_external_semaphore_opaque_fd
+#ifdef cl_khr_external_semaphore_sync_fd
+    SyncFd = CL_SEMAPHORE_HANDLE_SYNC_FD_KHR,
+#endif // cl_khr_external_semaphore_sync_fd
+#ifdef cl_khr_external_semaphore_win32
+    OpaqueWin32 = CL_SEMAPHORE_HANDLE_OPAQUE_WIN32_KHR,
+    OpaqueWin32Kmt = CL_SEMAPHORE_HANDLE_OPAQUE_WIN32_KMT_KHR,
+#endif // cl_khr_external_semaphore_win32
+};
+#endif // cl_khr_external_semaphore
+
 class Semaphore : public detail::Wrapper<cl_semaphore_khr>
 {
 public:
@@ -10447,7 +11241,7 @@ public:
         }
 
         return detail::errHandler(
-            detail::getInfo(&pfn_clGetSemaphoreInfoKHR, object_, name, param),
+            detail::getInfo(pfn_clGetSemaphoreInfoKHR, object_, name, param),
             __GET_SEMAPHORE_KHR_INFO_ERR);
     }
     template <cl_semaphore_info_khr name> typename
@@ -10463,6 +11257,36 @@ public:
         return param;      
     }
 
+#ifdef cl_khr_external_semaphore
+    template <typename T>
+    cl_int getHandleForTypeKHR(
+        const Device& device, cl_external_semaphore_handle_type_khr name, T* param) const
+    {
+        if (pfn_clGetSemaphoreHandleForTypeKHR == nullptr) {
+            return detail::errHandler(CL_INVALID_OPERATION,
+                                      __GET_SEMAPHORE_HANDLE_FOR_TYPE_KHR_ERR);
+        }
+
+        return detail::errHandler(
+            detail::getInfo(
+                pfn_clGetSemaphoreHandleForTypeKHR, object_, device(), name, param),
+                __GET_SEMAPHORE_HANDLE_FOR_TYPE_KHR_ERR);
+    }
+
+    template <cl_external_semaphore_handle_type_khr type> typename
+    detail::param_traits<detail::cl_external_semaphore_handle_type_khr, type>::param_type
+        getHandleForTypeKHR(const Device& device, cl_int* err = nullptr) const
+    {
+        typename detail::param_traits<
+        detail::cl_external_semaphore_handle_type_khr, type>::param_type param;
+        cl_int result = getHandleForTypeKHR(device, type, &param);
+        if (err != nullptr) {
+            *err = result;
+        }
+        return param;
+    }
+#endif // cl_khr_external_semaphore
+
     cl_int retain()
     { 
         if (pfn_clRetainSemaphoreKHR == nullptr) {
@@ -10488,13 +11312,17 @@ private:
     {
 #if CL_HPP_TARGET_OPENCL_VERSION >= 120
         Device device = context.getInfo<CL_CONTEXT_DEVICES>().at(0);
-        cl_platform_id platform = device.getInfo<CL_DEVICE_PLATFORM>();
+        cl_platform_id platform = device.getInfo<CL_DEVICE_PLATFORM>()();
         CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clCreateSemaphoreWithPropertiesKHR);
         CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clReleaseSemaphoreKHR);
         CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clRetainSemaphoreKHR);
         CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clEnqueueWaitSemaphoresKHR);
         CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clEnqueueSignalSemaphoresKHR);
         CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clGetSemaphoreInfoKHR);
+#ifdef cl_khr_external_semaphore
+        CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clGetSemaphoreHandleForTypeKHR);
+#endif // cl_khr_external_semaphore
+
 #else
         CL_HPP_INIT_CL_EXT_FCN_PTR_(clCreateSemaphoreWithPropertiesKHR);
         CL_HPP_INIT_CL_EXT_FCN_PTR_(clReleaseSemaphoreKHR);
@@ -10502,12 +11330,19 @@ private:
         CL_HPP_INIT_CL_EXT_FCN_PTR_(clEnqueueWaitSemaphoresKHR);
         CL_HPP_INIT_CL_EXT_FCN_PTR_(clEnqueueSignalSemaphoresKHR);
         CL_HPP_INIT_CL_EXT_FCN_PTR_(clGetSemaphoreInfoKHR);
+#ifdef cl_khr_external_semaphore
+        CL_HPP_INIT_CL_EXT_FCN_PTR_(clGetSemaphoreHandleForTypeKHR);
+#endif // cl_khr_external_semaphore
+
 #endif
         if ((pfn_clCreateSemaphoreWithPropertiesKHR == nullptr) &&
             (pfn_clReleaseSemaphoreKHR              == nullptr) &&
             (pfn_clRetainSemaphoreKHR               == nullptr) &&
             (pfn_clEnqueueWaitSemaphoresKHR         == nullptr) &&
             (pfn_clEnqueueSignalSemaphoresKHR       == nullptr) &&
+#ifdef cl_khr_external_semaphore
+            (pfn_clGetSemaphoreHandleForTypeKHR     == nullptr) &&
+#endif // cl_khr_external_semaphore
             (pfn_clGetSemaphoreInfoKHR              == nullptr))
         {
             detail::errHandler(CL_INVALID_VALUE, __CREATE_SEMAPHORE_KHR_WITH_PROPERTIES_ERR);
@@ -10689,6 +11524,9 @@ public:
         cl_int error = detail::errHandler(
             pfn_clCommandBarrierWithWaitListKHR(object_,
                 (command_queue != nullptr) ? (*command_queue)() : nullptr,
+#if CL_KHR_COMMAND_BUFFER_EXTENSION_VERSION > CL_MAKE_VERSION(0, 9, 4)
+                nullptr, // Properties
+#endif
                 (sync_points_vec != nullptr) ? (cl_uint) sync_points_vec->size() : 0,
                 (sync_points_vec != nullptr && sync_points_vec->size() > 0) ? &sync_points_vec->front() : nullptr,
                 (sync_point != nullptr) ? &tmp_sync_point : nullptr,
@@ -10720,6 +11558,9 @@ public:
         cl_int error = detail::errHandler(
             pfn_clCommandCopyBufferKHR(object_,
                 (command_queue != nullptr) ? (*command_queue)() : nullptr,
+#if CL_KHR_COMMAND_BUFFER_EXTENSION_VERSION > CL_MAKE_VERSION(0, 9, 4)
+                nullptr, // Properties
+#endif
                 src(),
                 dst(),
                 src_offset,
@@ -10760,6 +11601,9 @@ public:
         cl_int error = detail::errHandler(
             pfn_clCommandCopyBufferRectKHR(object_,
                 (command_queue != nullptr) ? (*command_queue)() : nullptr,
+#if CL_KHR_COMMAND_BUFFER_EXTENSION_VERSION > CL_MAKE_VERSION(0, 9, 4)
+                nullptr, // Properties
+#endif
                 src(),
                 dst(),
                 src_origin.data(),
@@ -10800,6 +11644,9 @@ public:
         cl_int error = detail::errHandler(
             pfn_clCommandCopyBufferToImageKHR(object_,
                 (command_queue != nullptr) ? (*command_queue)() : nullptr,
+#if CL_KHR_COMMAND_BUFFER_EXTENSION_VERSION > CL_MAKE_VERSION(0, 9, 4)
+                nullptr, // Properties
+#endif
                 src(),
                 dst(),
                 src_offset,
@@ -10836,6 +11683,9 @@ public:
         cl_int error = detail::errHandler(
             pfn_clCommandCopyImageKHR(object_,
                 (command_queue != nullptr) ? (*command_queue)() : nullptr,
+#if CL_KHR_COMMAND_BUFFER_EXTENSION_VERSION > CL_MAKE_VERSION(0, 9, 4)
+                nullptr, // Properties
+#endif
                 src(),
                 dst(),
                 src_origin.data(),
@@ -10872,6 +11722,9 @@ public:
         cl_int error = detail::errHandler(
             pfn_clCommandCopyImageToBufferKHR(object_,
                 (command_queue != nullptr) ? (*command_queue)() : nullptr,
+#if CL_KHR_COMMAND_BUFFER_EXTENSION_VERSION > CL_MAKE_VERSION(0, 9, 4)
+                nullptr, // Properties
+#endif
                 src(),
                 dst(),
                 src_origin.data(),
@@ -10908,6 +11761,9 @@ public:
         cl_int error = detail::errHandler(
             pfn_clCommandFillBufferKHR(object_,
                 (command_queue != nullptr) ? (*command_queue)() : nullptr,
+#if CL_KHR_COMMAND_BUFFER_EXTENSION_VERSION > CL_MAKE_VERSION(0, 9, 4)
+                nullptr, // Properties
+#endif
                 buffer(),
                 static_cast<void*>(&pattern),
                 sizeof(PatternType),
@@ -10943,6 +11799,9 @@ public:
         cl_int error = detail::errHandler(
             pfn_clCommandFillImageKHR(object_,
                 (command_queue != nullptr) ? (*command_queue)() : nullptr,
+#if CL_KHR_COMMAND_BUFFER_EXTENSION_VERSION > CL_MAKE_VERSION(0, 9, 4)
+                nullptr, // Properties
+#endif
                 image(),
                 static_cast<void*>(&fillColor),
                 origin.data(),
@@ -10959,7 +11818,12 @@ public:
         return error;
     }
 
-    cl_int commandNDRangeKernel(const cl::vector<cl_ndrange_kernel_command_properties_khr> &properties,
+    cl_int commandNDRangeKernel(
+#if CL_KHR_COMMAND_BUFFER_EXTENSION_VERSION > CL_MAKE_VERSION(0, 9, 4)
+            const cl::vector<cl_command_properties_khr> &properties,
+#else
+            const cl::vector<cl_ndrange_kernel_command_properties_khr> &properties,
+#endif
         const Kernel& kernel,
         const NDRange& offset,
         const NDRange& global,
@@ -10997,6 +11861,8 @@ public:
     }
 
 #if defined(cl_khr_command_buffer_mutable_dispatch)
+#if CL_KHR_COMMAND_BUFFER_MUTABLE_DISPATCH_EXTENSION_VERSION <                 \
+    CL_MAKE_VERSION(0, 9, 2)
     cl_int updateMutableCommands(const cl_mutable_base_config_khr* mutable_config)
     {
         if (pfn_clUpdateMutableCommandsKHR == nullptr) {
@@ -11006,6 +11872,21 @@ public:
         return detail::errHandler(pfn_clUpdateMutableCommandsKHR(object_, mutable_config),
                         __UPDATE_MUTABLE_COMMANDS_KHR_ERR);
     }
+#else
+    template <int ArrayLength>
+    cl_int updateMutableCommands(std::array<cl_command_buffer_update_type_khr,
+                                            ArrayLength> &config_types,
+                                 std::array<void *, ArrayLength> &configs) {
+        if (pfn_clUpdateMutableCommandsKHR == nullptr) {
+            return detail::errHandler(CL_INVALID_OPERATION,
+                                      __UPDATE_MUTABLE_COMMANDS_KHR_ERR);
+        }
+        return detail::errHandler(
+            pfn_clUpdateMutableCommandsKHR(object_, configs.length(),
+                                           config_types.data().configs.data()),
+            __UPDATE_MUTABLE_COMMANDS_KHR_ERR);
+    }
+#endif /* CL_KHR_COMMAND_BUFFER_MUTABLE_DISPATCH_EXTENSION_VERSION */
 #endif /* cl_khr_command_buffer_mutable_dispatch */
 
 private:
@@ -11014,7 +11895,7 @@ private:
     static void initExtensions(const cl::Device& device)
     {
 #if CL_HPP_TARGET_OPENCL_VERSION >= 120
-        cl_platform_id platform = device.getInfo<CL_DEVICE_PLATFORM>();
+        cl_platform_id platform = device.getInfo<CL_DEVICE_PLATFORM>()();
         CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clCreateCommandBufferKHR);
         CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clFinalizeCommandBufferKHR);
         CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clRetainCommandBufferKHR);
@@ -11212,7 +12093,12 @@ public:
 #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_BUFFER_ERR
+#undef __ENQUEUE_MAP_IMAGE_ERR
+#undef __ENQUEUE_MAP_SVM_ERR
+#undef __ENQUEUE_FILL_SVM_ERR
+#undef __ENQUEUE_COPY_SVM_ERR
+#undef __ENQUEUE_UNMAP_SVM_ERR              
 #undef __ENQUEUE_MAP_IMAGE_ERR             
 #undef __ENQUEUE_UNMAP_MEM_OBJECT_ERR      
 #undef __ENQUEUE_NDRANGE_KERNEL_ERR        
@@ -11249,8 +12135,12 @@ public:
 #undef __GET_DEVICE_AND_HOST_TIMER_ERR
 #undef __GET_SEMAPHORE_KHR_INFO_ERR
 #undef __CREATE_SEMAPHORE_KHR_WITH_PROPERTIES_ERR
+#undef __GET_IMAGE_REQUIREMENT_INFO_EXT_ERR
 #undef __ENQUEUE_WAIT_SEMAPHORE_KHR_ERR
 #undef __ENQUEUE_SIGNAL_SEMAPHORE_KHR_ERR
+#undef __RETAIN_SEMAPHORE_KHR_ERR
+#undef __RELEASE_SEMAPHORE_KHR_ERR
+#undef __GET_SEMAPHORE_HANDLE_FOR_TYPE_KHR_ERR
 
 #endif //CL_HPP_USER_OVERRIDE_ERROR_STRINGS
 
@@ -11259,7 +12149,6 @@ public:
 #undef CL_HPP_INIT_CL_EXT_FCN_PTR_
 #undef CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_
 
-#undef CL_HPP_NOEXCEPT_
 #undef CL_HPP_DEFINE_STATIC_MEMBER_
 
 } // namespace cl
-- 
GitLab