From 6854f63646bd0e536af9704cc0480578fd03205c Mon Sep 17 00:00:00 2001 From: Ben Ashbaugh Date: Thu, 15 Jan 2026 16:03:43 -0800 Subject: [PATCH 1/3] add checks for empty vectors --- include/CL/opencl.hpp | 130 ++++++++++++++++++++++++--------------- tests/test_openclhpp.cpp | 15 +++++ 2 files changed, 94 insertions(+), 51 deletions(-) diff --git a/include/CL/opencl.hpp b/include/CL/opencl.hpp index ff24f1ec..ba4da708 100644 --- a/include/CL/opencl.hpp +++ b/include/CL/opencl.hpp @@ -3393,8 +3393,9 @@ class Context } object_ = CL_(clCreateContext)( - properties, (cl_uint) numDevices, - deviceIDs.data(), + properties, + (cl_uint)deviceIDs.size(), + deviceIDs.empty() ? nullptr : deviceIDs.data(), notifyFptr, data, &error); detail::errHandler(error, __CREATE_CONTEXT_ERR); @@ -6463,10 +6464,11 @@ class Kernel : public detail::Wrapper /*! \brief setArg overload taking a vector type. */ template - cl_int setArg(cl_uint index, const cl::vector &argPtr) + cl_int setArg(cl_uint index, const cl::vector &arg) { return detail::errHandler( - CL_(clSetKernelArgSVMPointer)(object_, index, argPtr.data()), + CL_(clSetKernelArgSVMPointer)(object_, index, + arg.empty() ? nullptr : arg.data()), __SET_KERNEL_ARGS_ERR); } @@ -6515,8 +6517,8 @@ class Kernel : public detail::Wrapper CL_(clSetKernelExecInfo)( object_, CL_KERNEL_EXEC_INFO_SVM_PTRS, - sizeof(void*)*pointerList.size(), - pointerList.data())); + sizeof(void*) * pointerList.size(), + pointerList.empty() ? nullptr : pointerList.data())); } /*! @@ -6530,8 +6532,8 @@ class Kernel : public detail::Wrapper CL_(clSetKernelExecInfo)( object_, CL_KERNEL_EXEC_INFO_SVM_PTRS, - sizeof(void*)*pointerList.size(), - pointerList.data())); + sizeof(void*) * pointerList.size(), + pointerList.empty() ? nullptr : pointerList.data())); } /*! \brief Enable fine-grained system SVM. @@ -6597,7 +6599,7 @@ class Kernel : public detail::Wrapper CL_(clSetKernelExecInfo)( object_, CL_KERNEL_EXEC_INFO_SVM_PTRS, - sizeof(void*)*(1 + sizeof...(Ts)), + sizeof(void*) * (1 + sizeof...(Ts)), pointerList.data())); } @@ -6753,7 +6755,10 @@ class Program : public detail::Wrapper } object_ = CL_(clCreateProgramWithSource)( - context(), (cl_uint)n, strings.data(), lengths.data(), &error); + context(), (cl_uint)n, + strings.empty() ? nullptr : strings.data(), + lengths.empty() ? nullptr : lengths.data(), + &error); detail::errHandler(error, __CREATE_PROGRAM_WITH_SOURCE_ERR); if (err != nullptr) { @@ -6788,7 +6793,10 @@ class Program : public detail::Wrapper } object_ = CL_(clCreateProgramWithSource)( - context(), (cl_uint)n, strings.data(), lengths.data(), &error); + context(), (cl_uint)n, + strings.empty() ? nullptr : strings.data(), + lengths.empty() ? nullptr : lengths.data(), + &error); detail::errHandler(error, __CREATE_PROGRAM_WITH_SOURCE_ERR); if (err != nullptr) { @@ -6969,11 +6977,15 @@ class Program : public detail::Wrapper } object_ = CL_(clCreateProgramWithBinary)( - context(), (cl_uint) devices.size(), - deviceIDs.data(), - lengths.data(), images.data(), (binaryStatus != nullptr && numDevices > 0) + context(), + (cl_uint)deviceIDs.size(), + deviceIDs.empty() ? nullptr : deviceIDs.data(), + lengths.empty() ? nullptr : lengths.data(), + images.empty() ? nullptr : images.data(), + (binaryStatus != nullptr && numDevices > 0) ? &binaryStatus->front() - : nullptr, &error); + : nullptr, + &error); detail::errHandler(error, __CREATE_PROGRAM_WITH_BINARY_ERR); if (err != nullptr) { @@ -6995,7 +7007,6 @@ class Program : public detail::Wrapper { cl_int error; - size_type numDevices = devices.size(); vector deviceIDs(numDevices); for( size_type deviceIndex = 0; deviceIndex < numDevices; ++deviceIndex ) { @@ -7004,8 +7015,8 @@ class Program : public detail::Wrapper object_ = CL_(clCreateProgramWithBuiltInKernels)( context(), - (cl_uint) devices.size(), - deviceIDs.data(), + (cl_uint)deviceIDs.size(), + deviceIDs.empty() ? nullptr : deviceIDs.data(), kernelNames.c_str(), &error); @@ -7058,9 +7069,8 @@ class Program : public detail::Wrapper cl_int buildError = CL_(clBuildProgram)( object_, - (cl_uint) - devices.size(), - deviceIDs.data(), + (cl_uint)deviceIDs.size(), + deviceIDs.empty() ? nullptr : deviceIDs.data(), options, notifyFptr, data); @@ -7168,18 +7178,20 @@ class Program : public detail::Wrapper { static_assert(sizeof(cl::Program) == sizeof(cl_program), "Size of cl::Program must be equal to size of cl_program"); + vector headerIncludeNamesCStr; for(const string& name: headerIncludeNames) { headerIncludeNamesCStr.push_back(name.c_str()); } + cl_int error = CL_(clCompileProgram)( object_, 0, nullptr, options, static_cast(inputHeaders.size()), - reinterpret_cast(inputHeaders.data()), - reinterpret_cast(headerIncludeNamesCStr.data()), + reinterpret_cast(inputHeaders.empty() ? nullptr : inputHeaders.data()), + reinterpret_cast(headerIncludeNamesCStr.empty() ? nullptr : headerIncludeNamesCStr.data()), notifyFptr, data); return detail::buildErrHandler(error, __COMPILE_PROGRAM_ERR, getBuildInfo()); @@ -7198,7 +7210,7 @@ class Program : public detail::Wrapper cl_int compile( const char* options, - const vector& deviceList, + const vector& devices, const vector& inputHeaders = vector(), const vector& headerIncludeNames = vector(), void (CL_CALLBACK * notifyFptr)(cl_program, void *) = nullptr, @@ -7206,22 +7218,25 @@ class Program : public detail::Wrapper { static_assert(sizeof(cl::Program) == sizeof(cl_program), "Size of cl::Program must be equal to size of cl_program"); + + vector deviceIDs; + for(const Device& device: devices) { + deviceIDs.push_back(device()); + } + vector headerIncludeNamesCStr; for(const string& name: headerIncludeNames) { headerIncludeNamesCStr.push_back(name.c_str()); } - vector deviceIDList; - for(const Device& device: deviceList) { - deviceIDList.push_back(device()); - } + cl_int error = CL_(clCompileProgram)( object_, - static_cast(deviceList.size()), - reinterpret_cast(deviceIDList.data()), + static_cast(deviceIDs.size()), + reinterpret_cast(deviceIDs.empty() ? nullptr : deviceIDs.data()), options, static_cast(inputHeaders.size()), - reinterpret_cast(inputHeaders.data()), - reinterpret_cast(headerIncludeNamesCStr.data()), + reinterpret_cast(inputHeaders.empty() ? nullptr : inputHeaders.data()), + reinterpret_cast(headerIncludeNamesCStr.empty() ? nullptr : headerIncludeNamesCStr.data()), notifyFptr, data); return detail::buildErrHandler(error, __COMPILE_PROGRAM_ERR, getBuildInfo()); @@ -7325,9 +7340,11 @@ class Program : public detail::Wrapper } vector value(numKernels); - err = CL_(clCreateKernelsInProgram)( - object_, numKernels, value.data(), nullptr); + object_, + numKernels, + value.empty() ? nullptr : value.data(), + nullptr); if (err != CL_SUCCESS) { return detail::errHandler(err, __CREATE_KERNELS_IN_PROGRAM_ERR); } @@ -7478,7 +7495,7 @@ inline Program linkProgram( nullptr, options, static_cast(inputPrograms.size()), - reinterpret_cast(inputPrograms.data()), + reinterpret_cast(inputPrograms.empty() ? nullptr : inputPrograms.data()), notifyFptr, data, &error_local); @@ -8921,12 +8938,13 @@ class CommandQueue : public detail::Wrapper return detail::errHandler(CL_INVALID_VALUE,__ENQUEUE_COPY_SVM_ERR); } cl_int err = detail::errHandler(CL_(clEnqueueSVMMemcpy)( - object_, blocking, static_cast(dst_container.data()), - static_cast(src_container.data()), + object_, blocking, + dst_container.empty() ? nullptr : dst_container.data(), + src_container.empty() ? nullptr : src_container.data(), dst_container.size() * sizeof(T), (events != nullptr) ? (cl_uint) events->size() : 0, (events != nullptr && events->size() > 0) ? (const cl_event *) &events->front() : nullptr, - (event != NULL) ? &tmp : nullptr), __ENQUEUE_COPY_SVM_ERR); + (event != nullptr) ? &tmp : nullptr), __ENQUEUE_COPY_SVM_ERR); if (event != nullptr && err == CL_SUCCESS) *event = tmp; @@ -8997,8 +9015,11 @@ class CommandQueue : public detail::Wrapper { cl_event tmp; cl_int err = detail::errHandler(CL_(clEnqueueSVMMemFill)( - object_, static_cast(container.data()), static_cast(&pattern), - sizeof(PatternType), container.size() * sizeof(T), + object_, + container.empty() ? nullptr : container.data(), + &pattern, + sizeof(PatternType), + container.size() * sizeof(T), (events != nullptr) ? (cl_uint) events->size() : 0, (events != nullptr && events->size() > 0) ? (const cl_event *) &events->front() : nullptr, (event != nullptr) ? &tmp : NULL), __ENQUEUE_FILL_SVM_ERR); @@ -9078,7 +9099,9 @@ class CommandQueue : public detail::Wrapper { cl_event tmp; cl_int err = detail::errHandler(CL_(clEnqueueSVMMap)( - object_, blocking, flags, static_cast(container.data()), container.size()*sizeof(T), + object_, blocking, flags, + container.empty() ? nullptr : container.data(), + container.size() * sizeof(T), (events != nullptr) ? (cl_uint)events->size() : 0, (events != nullptr && events->size() > 0) ? (const cl_event*)&events->front() : nullptr, (event != nullptr) ? &tmp : nullptr), @@ -9177,7 +9200,8 @@ class CommandQueue : public detail::Wrapper cl_event tmp; cl_int err = detail::errHandler( CL_(clEnqueueSVMUnmap)( - object_, static_cast(container.data()), + object_, + container.empty() ? nullptr : container.data(), (events != nullptr) ? (cl_uint)events->size() : 0, (events != nullptr && events->size() > 0) ? (const cl_event*)&events->front() : nullptr, (event != nullptr) ? &tmp : nullptr), @@ -9274,7 +9298,7 @@ class CommandQueue : public detail::Wrapper CL_(clEnqueueMigrateMemObjects)( object_, (cl_uint)memObjects.size(), - localMemObjects.data(), + localMemObjects.empty() ? nullptr : localMemObjects.data(), flags, (events != nullptr) ? (cl_uint) events->size() : 0, (events != nullptr && events->size() > 0) ? (const cl_event*) &events->front() : nullptr, @@ -9306,8 +9330,9 @@ class CommandQueue : public detail::Wrapper cl_event tmp; cl_int err = detail::errHandler(CL_(clEnqueueSVMMigrateMem)( object_, - svmRawPointers.size(), static_cast(svmRawPointers.data()), - sizes.data(), // array of sizes not passed + svmRawPointers.size(), + svmRawPointers.empty() ? nullptr : svmRawPointers.data(), + sizes.empty() ? nullptr : sizes.data(), flags, (events != nullptr) ? (cl_uint)events->size() : 0, (events != nullptr && events->size() > 0) ? (const cl_event*)&events->front() : nullptr, @@ -9676,7 +9701,7 @@ typedef CL_API_ENTRY cl_int (CL_API_CALL *PFN_clEnqueueReleaseD3D10ObjectsKHR)( err = pfn_clEnqueueAcquireExternalMemObjectsKHR( object_, static_cast(mem_objects.size()), - (mem_objects.size() > 0) ? reinterpret_cast(mem_objects.data()) : nullptr, + reinterpret_cast(mem_objects.empty() ? nullptr : mem_objects.data()), (events_wait != nullptr) ? static_cast(events_wait->size()) : 0, (events_wait != nullptr && events_wait->size() > 0) ? reinterpret_cast(events_wait->data()) : nullptr, &tmp); @@ -9705,7 +9730,7 @@ typedef CL_API_ENTRY cl_int (CL_API_CALL *PFN_clEnqueueReleaseD3D10ObjectsKHR)( err = pfn_clEnqueueReleaseExternalMemObjectsKHR( object_, static_cast(mem_objects.size()), - (mem_objects.size() > 0) ? reinterpret_cast(mem_objects.data()) : nullptr, + reinterpret_cast(mem_objects.empty() ? nullptr : mem_objects.data()), (events_wait != nullptr) ? static_cast(events_wait->size()) : 0, (events_wait != nullptr && events_wait->size() > 0) ? reinterpret_cast(events_wait->data()) : nullptr, &tmp); @@ -11337,7 +11362,7 @@ class Semaphore : public detail::Wrapper { object_ = pfn_clCreateSemaphoreWithPropertiesKHR( context(), - sema_props.data(), + sema_props.empty() ? nullptr : sema_props.data(), &error); } @@ -11931,7 +11956,7 @@ class CommandBufferKhr : public detail::Wrapper nullptr, // Properties #endif image(), - static_cast(&fillColor), + &fillColor, origin.data(), region.data(), (sync_points_vec != nullptr) ? (cl_uint) sync_points_vec->size() : 0, @@ -12010,8 +12035,11 @@ class CommandBufferKhr : public detail::Wrapper __UPDATE_MUTABLE_COMMANDS_KHR_ERR); } return detail::errHandler( - pfn_clUpdateMutableCommandsKHR(object_, static_cast(configs.size()), - config_types.data(), configs.data()), + pfn_clUpdateMutableCommandsKHR( + object_, + static_cast(configs.size()), + config_types.empty() ? nullptr : config_types.data(), + configs.empty() ? nullptr : configs.data()), __UPDATE_MUTABLE_COMMANDS_KHR_ERR); } #endif /* CL_KHR_COMMAND_BUFFER_MUTABLE_DISPATCH_EXTENSION_VERSION */ diff --git a/tests/test_openclhpp.cpp b/tests/test_openclhpp.cpp index 28e5d55d..5e2bb323 100644 --- a/tests/test_openclhpp.cpp +++ b/tests/test_openclhpp.cpp @@ -2026,6 +2026,21 @@ void testKernelSetSVMPointers(void) TEST_ASSERT_EQUAL_HEX(expected, ret); #endif } + +void testKernelSetSVMPointersEmpty(void) +{ +#if CL_HPP_TARGET_OPENCL_VERSION >= 200 + clSetKernelExecInfo_ExpectAndReturn(make_kernel(0), + CL_KERNEL_EXEC_INFO_SVM_PTRS, + 0, nullptr, CL_SUCCESS); + + cl::vector vec; + cl_int ret = kernelPool[0].setSVMPointers(vec); + + TEST_ASSERT_EQUAL_HEX(CL_SUCCESS, ret); +#endif +} + cl_int clSetKernelExecInfo_EnableFineGrainedSystemSVM(cl_kernel kernel, cl_kernel_exec_info param_name, size_t param_value_size, From e08431a4fbfbeb4e98c4b19e2755be4cac790e96 Mon Sep 17 00:00:00 2001 From: Ben Ashbaugh Date: Thu, 15 Jan 2026 17:38:05 -0800 Subject: [PATCH 2/3] add more tests --- tests/test_openclhpp.cpp | 189 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 188 insertions(+), 1 deletion(-) diff --git a/tests/test_openclhpp.cpp b/tests/test_openclhpp.cpp index 5e2bb323..5668101a 100644 --- a/tests/test_openclhpp.cpp +++ b/tests/test_openclhpp.cpp @@ -535,6 +535,44 @@ void testMoveConstructContextNonNull(void); void testMoveConstructContextNull(void); MAKE_MOVE_TESTS(Context, make_context, clReleaseContext, contextPool) +#ifndef CL_HPP_ENABLE_EXCEPTIONS +static cl_context clCreateContext_EmptyDevices( + const cl_context_properties* properties, + cl_uint num_devices, + const cl_device_id* devices, + void (CL_CALLBACK* pfn_notify)(const char* errinfo, const void* private_info, size_t cb, void* user_data), + void* user_data, + cl_int* errcode_ret, + int num_calls) +{ + (void) num_calls; + + TEST_ASSERT_EQUAL(properties, nullptr); + TEST_ASSERT_EQUAL(num_devices, 0); + TEST_ASSERT_EQUAL(devices, nullptr); + TEST_ASSERT_EQUAL(pfn_notify, nullptr); + TEST_ASSERT_EQUAL(user_data, nullptr); + + if (errcode_ret) { + errcode_ret[0] = CL_INVALID_VALUE; + } + + return nullptr; +} +#endif + +void testContextCreateEmptyDevices(void) +{ +#ifndef CL_HPP_ENABLE_EXCEPTIONS + clCreateContext_StubWithCallback(clCreateContext_EmptyDevices); + + cl::vector vec; + cl::Context context(vec); + + TEST_ASSERT_EQUAL(nullptr, context()); +#endif +} + /// Stub for querying CL_CONTEXT_DEVICES that returns two devices static cl_int clGetContextInfo_testContextGetDevices( cl_context context, @@ -1967,6 +2005,15 @@ void testKernelSetArgBySetKernelArgSVMPointerWithVectorType(void) #endif } +void testKernelSetArgBySetKernelArgSVMPointerWithEmptyVectorType(void) +{ +#if CL_HPP_TARGET_OPENCL_VERSION >= 200 + VECTOR_CLASS vec; + clSetKernelArgSVMPointer_ExpectAndReturn(make_kernel(1), 2, nullptr, CL_SUCCESS); + TEST_ASSERT_EQUAL(kernelPool[1].setArg(2, vec), CL_SUCCESS); +#endif +} + void testKernelSetArgBySetKernelArgSVMPointerWithPointerType(void) { #if CL_HPP_TARGET_OPENCL_VERSION >= 200 @@ -2027,7 +2074,7 @@ void testKernelSetSVMPointers(void) #endif } -void testKernelSetSVMPointersEmpty(void) +void testKernelSetSVMPointersEmptyVec(void) { #if CL_HPP_TARGET_OPENCL_VERSION >= 200 clSetKernelExecInfo_ExpectAndReturn(make_kernel(0), @@ -2041,6 +2088,20 @@ void testKernelSetSVMPointersEmpty(void) #endif } +void testKernelSetSVMPointersEmptyArray(void) +{ +#if CL_HPP_TARGET_OPENCL_VERSION >= 200 + clSetKernelExecInfo_ExpectAndReturn(make_kernel(0), + CL_KERNEL_EXEC_INFO_SVM_PTRS, + 0, nullptr, CL_SUCCESS); + + std::array arr; + cl_int ret = kernelPool[0].setSVMPointers<0>(arr); + + TEST_ASSERT_EQUAL_HEX(CL_SUCCESS, ret); +#endif +} + cl_int clSetKernelExecInfo_EnableFineGrainedSystemSVM(cl_kernel kernel, cl_kernel_exec_info param_name, size_t param_value_size, @@ -2193,6 +2254,132 @@ void testCopyHostToBuffer(void) * Tests for building Programs ****************************************************************************/ +#ifndef CL_HPP_ENABLE_EXCEPTIONS +static cl_program clCreateProgramWithSource_EmptySource( + cl_context context, + cl_uint count, + const char** strings, + const size_t* lengths, + cl_int* errcode_ret, + int num_calls) +{ + (void) num_calls; + + TEST_ASSERT_EQUAL(context, make_context(1)); + TEST_ASSERT_EQUAL(count, 0); + TEST_ASSERT_EQUAL(strings, nullptr); + TEST_ASSERT_EQUAL(lengths, nullptr); + + if (errcode_ret) { + errcode_ret[0] = CL_INVALID_VALUE; + } + + return nullptr; +} +#endif + +void testProgramCreateEmptySources(void) +{ +#ifndef CL_HPP_ENABLE_EXCEPTIONS + clCreateProgramWithSource_StubWithCallback(clCreateProgramWithSource_EmptySource); + clReleaseContext_ExpectAndReturn(make_context(1), CL_SUCCESS); + + cl::Context context(make_context(1)); + + cl::Program::Sources sources; + cl::Program program(context, sources); + + TEST_ASSERT_EQUAL(nullptr, program()); +#endif +} + +#ifndef CL_HPP_ENABLE_EXCEPTIONS +static cl_program clCreateProgramWithBinary_EmptyBinaries( + cl_context context, + cl_uint num_devices, + const cl_device_id* device_list, + const size_t* lengths, + const unsigned char** binaries, + cl_int* binary_status, + cl_int* errcode_ret, + int num_calls) +{ + (void) num_calls; + + TEST_ASSERT_EQUAL(context, make_context(1)); + TEST_ASSERT_EQUAL(num_devices, 0); + TEST_ASSERT_EQUAL(device_list, nullptr); + TEST_ASSERT_EQUAL(lengths, nullptr); + TEST_ASSERT_EQUAL(binaries, nullptr); + TEST_ASSERT_EQUAL(binary_status, nullptr); + + if (errcode_ret) { + errcode_ret[0] = CL_INVALID_VALUE; + } + + return nullptr; +} +#endif + +void testProgramCreateEmptyBinaries(void) +{ +#ifndef CL_HPP_ENABLE_EXCEPTIONS + clCreateProgramWithBinary_StubWithCallback(clCreateProgramWithBinary_EmptyBinaries); + clReleaseContext_ExpectAndReturn(make_context(1), CL_SUCCESS); + + cl::Context context(make_context(1)); + + cl::vector devices; + cl::Program::Binaries binaries; + cl::Program program(context, devices, binaries); + + TEST_ASSERT_EQUAL(nullptr, program()); +#endif +} + +#if CL_HPP_TARGET_OPENCL_VERSION >= 120 +#ifndef CL_HPP_ENABLE_EXCEPTIONS +static cl_program clCreateProgramWithBuiltInKernels_EmptyDevices( + cl_context context, + cl_uint num_devices, + const cl_device_id* device_list, + const char* kernel_names, + cl_int* errcode_ret, + int num_calls) +{ + (void) num_calls; + + TEST_ASSERT_EQUAL(context, make_context(1)); + TEST_ASSERT_EQUAL(num_devices, 0); + TEST_ASSERT_EQUAL(device_list, nullptr); + TEST_ASSERT_EQUAL_STRING(kernel_names, "foo"); + + if (errcode_ret) { + errcode_ret[0] = CL_INVALID_VALUE; + } + + return nullptr; +} +#endif +#endif + +void testProgramCreateBuiltinKernelsEmptyDevices(void) +{ +#if CL_HPP_TARGET_OPENCL_VERSION >= 120 +#ifndef CL_HPP_ENABLE_EXCEPTIONS + clCreateProgramWithBuiltInKernels_StubWithCallback(clCreateProgramWithBuiltInKernels_EmptyDevices); + clReleaseContext_ExpectAndReturn(make_context(1), CL_SUCCESS); + + cl::Context context(make_context(1)); + + cl::vector devices; + cl::Program program(context, devices, "foo"); + + TEST_ASSERT_EQUAL(nullptr, program()); +#endif +#endif +} + static cl_int clGetDeviceInfo_testGetBuildInfo( cl_device_id device, cl_device_info param_name, From d91dea89b2585d632d6009a58ea1fdda6b2ea22b Mon Sep 17 00:00:00 2001 From: Ben Ashbaugh Date: Fri, 16 Jan 2026 11:10:02 -0800 Subject: [PATCH 3/3] refactor buffer and image creation with properties --- include/CL/opencl.hpp | 269 ++++++++++++++++++--------------------- tests/test_openclhpp.cpp | 45 +++++++ 2 files changed, 167 insertions(+), 147 deletions(-) diff --git a/include/CL/opencl.hpp b/include/CL/opencl.hpp index ba4da708..b2ad137c 100644 --- a/include/CL/opencl.hpp +++ b/include/CL/opencl.hpp @@ -4466,14 +4466,10 @@ class Buffer : public Memory { cl_int error; - if (properties.empty()) { - object_ = CL_(clCreateBufferWithProperties)(context(), nullptr, flags, - size, host_ptr, &error); - } - else { - object_ = CL_(clCreateBufferWithProperties)( - context(), properties.data(), flags, size, host_ptr, &error); - } + object_ = CL_(clCreateBufferWithProperties)( + context(), + properties.empty() ? nullptr : properties.data(), + flags, size, host_ptr, &error); detail::errHandler(error, __CREATE_BUFFER_ERR); if (err != nullptr) { @@ -4978,26 +4974,23 @@ class Image1D : public Image */ Image1D(const Context &context, const vector &properties, cl_mem_flags flags, ImageFormat format, size_type width, - void *host_ptr = nullptr, cl_int *err = nullptr) { - cl_int error; + 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; + cl_image_desc desc = {}; + desc.image_type = CL_MEM_OBJECT_IMAGE1D; + desc.image_width = width; - if (properties.empty()) { object_ = CL_(clCreateImageWithProperties)( - context(), nullptr, flags, &format, &desc, host_ptr, &error); - } else { - object_ = - CL_(clCreateImageWithProperties)(context(), properties.data(), flags, - &format, &desc, host_ptr, &error); - } - - detail::errHandler(error, __CREATE_IMAGE_ERR); - if (err != nullptr) { - *err = error; - } + context(), + properties.empty() ? nullptr : 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 @@ -5074,27 +5067,24 @@ class Image1DBuffer : public Image Image1DBuffer(const Context &context, const vector &properties, cl_mem_flags flags, ImageFormat format, size_type width, - const Buffer &buffer, cl_int *err = nullptr) { - cl_int error; + 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(); + cl_image_desc desc = {}; + desc.image_type = CL_MEM_OBJECT_IMAGE1D_BUFFER; + desc.image_width = width; + desc.buffer = buffer(); - if (properties.empty()) { object_ = CL_(clCreateImageWithProperties)( - context(), nullptr, flags, &format, &desc, nullptr, &error); - } else { - object_ = - CL_(clCreateImageWithProperties)(context(), properties.data(), flags, - &format, &desc, nullptr, &error); - } - - detail::errHandler(error, __CREATE_IMAGE_ERR); - if (err != nullptr) { - *err = error; - } + context(), + properties.empty() ? nullptr : 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 @@ -5170,28 +5160,25 @@ class Image1DArray : public Image const vector &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; + 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; + 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_ = CL_(clCreateImageWithProperties)( - context(), nullptr, flags, &format, &desc, host_ptr, &error); - } else { - object_ = - CL_(clCreateImageWithProperties)(context(), properties.data(), flags, - &format, &desc, host_ptr, &error); - } - - detail::errHandler(error, __CREATE_IMAGE_ERR); - if (err != nullptr) { - *err = error; - } + context(), + properties.empty() ? nullptr : 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 @@ -5411,28 +5398,25 @@ class Image2D : public Image Image2D(const Context &context, const vector &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_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; + 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_ = CL_(clCreateImageWithProperties)( - context(), nullptr, flags, &format, &desc, host_ptr, &error); - } else { - object_ = - CL_(clCreateImageWithProperties)(context(), properties.data(), flags, - &format, &desc, host_ptr, &error); - } - - detail::errHandler(error, __CREATE_IMAGE_ERR); - if (err != nullptr) { - *err = error; - } + context(), + properties.empty() ? nullptr : 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. @@ -5447,29 +5431,26 @@ class Image2D : public Image Image2D(const Context &context, const vector &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_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(); + 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_ = CL_(clCreateImageWithProperties)( - context(), nullptr, flags, &format, &desc, nullptr, &error); - } else { - object_ = - CL_(clCreateImageWithProperties)(context(), properties.data(), flags, - &format, &desc, nullptr, &error); - } - - detail::errHandler(error, __CREATE_IMAGE_ERR); - if (err != nullptr) { - *err = error; - } + context(), + properties.empty() ? nullptr : 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 @@ -5628,30 +5609,27 @@ class Image2DArray : public Image 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()) { + 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; + object_ = CL_(clCreateImageWithProperties)( - context(), nullptr, flags, &format, &desc, host_ptr, &error); - } else { - object_ = - CL_(clCreateImageWithProperties)(context(), properties.data(), flags, - &format, &desc, host_ptr, &error); - } - - detail::errHandler(error, __CREATE_IMAGE_ERR); - if (err != nullptr) { - *err = error; - } + context(), + properties.empty() ? nullptr : 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 @@ -5770,30 +5748,27 @@ class Image3D : public Image 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()) { + 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; + object_ = CL_(clCreateImageWithProperties)( - context(), nullptr, flags, &format, &desc, host_ptr, &error); - } else { - object_ = - CL_(clCreateImageWithProperties)(context(), properties.data(), flags, - &format, &desc, host_ptr, &error); - } - - detail::errHandler(error, __CREATE_IMAGE_ERR); - if (err != nullptr) { - *err = error; - } + context(), + properties.empty() ? nullptr : 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 diff --git a/tests/test_openclhpp.cpp b/tests/test_openclhpp.cpp index 5668101a..f9aff991 100644 --- a/tests/test_openclhpp.cpp +++ b/tests/test_openclhpp.cpp @@ -1405,6 +1405,51 @@ void testBufferWithProperties(void) #endif //CL_HPP_TARGET_OPENCL_VERSION >= 300 } +#if CL_HPP_TARGET_OPENCL_VERSION >= 300 +static cl_mem clCreateBufferWithProperties_EmptyProperties( + cl_context context, + const cl_mem_properties *properties, + cl_mem_flags flags, + size_t size, + void *host_ptr, + cl_int *errcode_ret, + int num_calls) +{ + (void) num_calls; + + TEST_ASSERT_EQUAL(context, make_context(1)); + TEST_ASSERT_EQUAL(properties, nullptr); + TEST_ASSERT_EQUAL_HEX(flags, CL_MEM_READ_WRITE); + TEST_ASSERT_EQUAL(size, 42); + TEST_ASSERT_NULL(host_ptr); + if (errcode_ret) + *errcode_ret = CL_SUCCESS; + + return make_mem(0); +} +#endif //CL_HPP_TARGET_OPENCL_VERSION >= 300 + +void testBufferWithEmptyProperties(void) +{ +#if CL_HPP_TARGET_OPENCL_VERSION >= 300 + clCreateBufferWithProperties_StubWithCallback(clCreateBufferWithProperties_EmptyProperties); + clReleaseContext_ExpectAndReturn(make_context(1), CL_SUCCESS); + + cl::Context context(make_context(1)); + + cl_int err; + + VECTOR_CLASS props; + cl::Buffer buffer(context, props, CL_MEM_READ_WRITE, 42, nullptr, &err); + + TEST_ASSERT_EQUAL_PTR(make_mem(0), buffer()); + TEST_ASSERT_EQUAL(CL_SUCCESS, err); + + // prevent destructor from interfering with the test + buffer() = nullptr; +#endif //CL_HPP_TARGET_OPENCL_VERSION >= 300 +} + /**************************************************************************** * Tests for cl::Image1DBuffer ****************************************************************************/