fix(OCL): Propagate error on kernel creation to API call

On clCreateKernelsInProgram API call, we do not propagate potential
error from MultiDeviceKernel::create function. User would not know that
i.e. out of 4 kernels, only 3 were created succesfully.
- Propagate error returned from MultiDeviceKernel::create function to
API call
- In case of a failure on kernel creation, release all resources for the
already created ones and return empty array (nullptrs).

Related-To: NEO-7879
Signed-off-by: Kacper Nowak <kacper.nowak@intel.com>
This commit is contained in:
Kacper Nowak
2023-04-05 18:21:36 +00:00
committed by Compute-Runtime-Automation
parent 6357ab73ea
commit 3459f3a7f6
2 changed files with 42 additions and 1 deletions

View File

@@ -1835,7 +1835,17 @@ cl_int CL_API_CALL clCreateKernelsInProgram(cl_program clProgram,
kernels[i] = MultiDeviceKernel::create(
pProgram,
kernelInfos,
nullptr);
&retVal);
if (nullptr == kernels[i]) {
UNRECOVERABLE_IF(CL_SUCCESS == retVal);
for (unsigned int createdIdx = 0; createdIdx < i; ++createdIdx) {
auto mDKernel = castToObject<MultiDeviceKernel>(kernels[createdIdx]);
mDKernel->release();
kernels[createdIdx] = nullptr;
}
TRACING_EXIT(ClCreateKernelsInProgram, &retVal);
return retVal;
}
gtpinNotifyKernelCreate(kernels[i]);
}
}

View File

@@ -6,7 +6,9 @@
*/
#include "shared/source/helpers/file_io.h"
#include "shared/source/helpers/gfx_core_helper.h"
#include "shared/test/common/helpers/test_files.h"
#include "shared/test/common/mocks/mock_kernel_info.h"
#include "opencl/source/context/context.h"
@@ -116,3 +118,32 @@ TEST_F(clCreateKernelsInProgramTests, GivenTooSmallOutputBufferWhenCreatingKerne
EXPECT_EQ(CL_INVALID_VALUE, retVal);
EXPECT_EQ(nullptr, kernel);
}
TEST_F(clCreateKernelsInProgramTests, whenKernelCreationFailsOnClCreateKernelsInProgramAPICallThenPropagateTheErrorToAPICallAndReturnNullptrForEachKernel) {
const auto rootDeviceIndex = pDevice->getRootDeviceIndex();
auto &kernelInfoArray = pProgram->getKernelInfoArray(rootDeviceIndex);
kernelInfoArray.push_back(new MockKernelInfo());
kernelInfoArray.push_back(new MockKernelInfo());
auto kernelInfo1 = kernelInfoArray[0];
auto kernelInfo2 = kernelInfoArray[1];
auto &rootDeviceEnvironment = pDevice->getRootDeviceEnvironment();
auto &gfxCoreHelper = rootDeviceEnvironment.getHelper<GfxCoreHelper>();
// Enforce CL_INVALID_KERNEL error for kernel created using kernelInfo2
// Kernel creation using kernelInfo1 should succeed.
auto minimalSimdSize = gfxCoreHelper.getMinimalSIMDSize();
kernelInfo1->kernelDescriptor.kernelAttributes.simdSize = minimalSimdSize;
kernelInfo2->kernelDescriptor.kernelAttributes.simdSize = minimalSimdSize - 1;
cl_kernel kernels[2];
cl_uint numKernels = 2;
retVal = clCreateKernelsInProgram(
pProgram,
numKernels,
kernels,
nullptr);
EXPECT_EQ(CL_INVALID_KERNEL, retVal);
EXPECT_EQ(nullptr, kernels[0]);
EXPECT_EQ(nullptr, kernels[1]);
}