From a9b8c072933cac11b71eea7b869c6a55ddea2235 Mon Sep 17 00:00:00 2001 From: Filip Hazubski Date: Mon, 17 Jun 2019 13:33:44 +0200 Subject: [PATCH] Update enqueueKernel Return CL_INVALID_GLOBAL_WORK_SIZE error if global_work_size contains 0 for OpenCL older than 2.1 Do not throw exception if global_work_size contains 0 Related-To: NEO-3111 Change-Id: If7b7884465117d9c0615ace2bb682b3b1c7d8bdb Signed-off-by: Filip Hazubski --- runtime/command_queue/enqueue_kernel.h | 5 +- .../command_queue/enqueue_kernel_1_tests.cpp | 3 +- .../command_queue/zero_size_enqueue_tests.cpp | 133 ++++++++++-------- unit_tests/mocks/mock_device.h | 1 + 4 files changed, 85 insertions(+), 57 deletions(-) diff --git a/runtime/command_queue/enqueue_kernel.h b/runtime/command_queue/enqueue_kernel.h index 92d1e1a6b0..d4cc3ff43b 100644 --- a/runtime/command_queue/enqueue_kernel.h +++ b/runtime/command_queue/enqueue_kernel.h @@ -64,6 +64,9 @@ cl_int CommandQueueHw::enqueueKernel( for (auto i = 0u; i < workDim; i++) { region[i] = globalWorkSizeIn ? globalWorkSizeIn[i] : 0; + if (region[i] == 0 && (kernel.getDevice().getEnabledClVersion() < 21)) { + return CL_INVALID_GLOBAL_WORK_SIZE; + } globalWorkOffset[i] = globalWorkOffsetIn ? globalWorkOffsetIn[i] : 0; @@ -78,7 +81,7 @@ cl_int CommandQueueHw::enqueueKernel( return CL_INVALID_WORK_GROUP_SIZE; } if (kernel.getAllowNonUniform()) { - workGroupSize[i] = std::min(localWorkSizeIn[i], globalWorkSizeIn[i]); + workGroupSize[i] = std::min(localWorkSizeIn[i], std::max(static_cast(1), globalWorkSizeIn[i])); } else { workGroupSize[i] = localWorkSizeIn[i]; } diff --git a/unit_tests/command_queue/enqueue_kernel_1_tests.cpp b/unit_tests/command_queue/enqueue_kernel_1_tests.cpp index baaefd5859..6240c3ceac 100644 --- a/unit_tests/command_queue/enqueue_kernel_1_tests.cpp +++ b/unit_tests/command_queue/enqueue_kernel_1_tests.cpp @@ -338,7 +338,8 @@ HWTEST_F(EnqueueKernelTest, givenEnqueueWithGlobalWorkSizeWhenZeroValueIsPassedI size_t gws[3] = {0, 0, 0}; MockKernelWithInternals mockKernel(*pDevice); auto ret = pCmdQ->enqueueKernel(mockKernel.mockKernel, 1, nullptr, gws, nullptr, 0, nullptr, nullptr); - EXPECT_EQ(CL_SUCCESS, ret); + auto expected = (pDevice->getEnabledClVersion() < 21 ? CL_INVALID_GLOBAL_WORK_SIZE : CL_SUCCESS); + EXPECT_EQ(expected, ret); } HWTEST_F(EnqueueKernelTest, givenCommandStreamReceiverInBatchingModeWhenEnqueueKernelIsCalledThenKernelIsRecorded) { diff --git a/unit_tests/command_queue/zero_size_enqueue_tests.cpp b/unit_tests/command_queue/zero_size_enqueue_tests.cpp index 3fd2235b43..a180f45b76 100644 --- a/unit_tests/command_queue/zero_size_enqueue_tests.cpp +++ b/unit_tests/command_queue/zero_size_enqueue_tests.cpp @@ -17,83 +17,106 @@ using namespace NEO; -class ZeroSizeEnqueueHandlerTest : public DeviceFixture, - public testing::Test { +class ZeroSizeEnqueueHandlerTest : public Test { public: - void SetUp() override { - DeviceFixture::SetUp(); - } - - void TearDown() override { - DeviceFixture::TearDown(); - } MockContext context; cl_int retVal; }; -HWTEST_F(ZeroSizeEnqueueHandlerTest, enqueueKernelWhenZeroSizeEnqueueIsDetectedThenCommandMarkerShouldBeEnqueued) { +class ZeroSizeEnqueueHandlerTestZeroGws : public ZeroSizeEnqueueHandlerTest { + public: + void SetUp() override { + ZeroSizeEnqueueHandlerTest::SetUp(); + + testGwsInputs[0] = std::make_tuple(1, nullptr); + testGwsInputs[1] = std::make_tuple(2, nullptr); + testGwsInputs[2] = std::make_tuple(3, nullptr); + testGwsInputs[3] = std::make_tuple(1, zeroGWS0); + testGwsInputs[4] = std::make_tuple(2, zeroGWS00); + testGwsInputs[5] = std::make_tuple(2, zeroGWS01); + testGwsInputs[6] = std::make_tuple(2, zeroGWS10); + testGwsInputs[7] = std::make_tuple(3, zeroGWS000); + testGwsInputs[8] = std::make_tuple(3, zeroGWS011); + testGwsInputs[9] = std::make_tuple(3, zeroGWS101); + testGwsInputs[10] = std::make_tuple(3, zeroGWS110); + testGwsInputs[11] = std::make_tuple(3, zeroGWS001); + testGwsInputs[12] = std::make_tuple(3, zeroGWS010); + testGwsInputs[13] = std::make_tuple(3, zeroGWS100); + } + + size_t zeroGWS0[1] = {0}; + size_t zeroGWS00[2] = {0, 0}; + size_t zeroGWS01[2] = {0, 1}; + size_t zeroGWS10[2] = {1, 0}; + size_t zeroGWS000[3] = {0, 0, 0}; + size_t zeroGWS011[3] = {0, 1, 1}; + size_t zeroGWS101[3] = {1, 0, 1}; + size_t zeroGWS110[3] = {1, 1, 0}; + size_t zeroGWS001[3] = {0, 0, 1}; + size_t zeroGWS010[3] = {0, 1, 0}; + size_t zeroGWS100[3] = {1, 0, 0}; + + std::tuple testGwsInputs[14]; +}; + +HWTEST_F(ZeroSizeEnqueueHandlerTestZeroGws, enqueueKernelWhenZeroSizeEnqueueIsDetectedAndOpenCLAtLeast21ThenCommandMarkerShouldBeEnqueued) { + pDevice->enabledClVersion = 21; + auto mockCmdQ = std::unique_ptr>(new MockCommandQueueHw(&context, pDevice, 0)); MockKernelWithInternals mockKernel(*pDevice); - size_t *nullGWS1 = nullptr; - mockCmdQ->enqueueKernel(mockKernel.mockKernel, 1, nullptr, nullGWS1, nullptr, 0, nullptr, nullptr); - EXPECT_EQ(static_cast(CL_COMMAND_MARKER), mockCmdQ->lastCommandType); + for (auto testInput : testGwsInputs) { + auto workDim = std::get<0>(testInput); + auto gws = std::get<1>(testInput); + mockCmdQ->lastCommandType = static_cast(CL_COMMAND_COPY_BUFFER); - size_t *nullGWS2 = nullptr; - mockCmdQ->enqueueKernel(mockKernel.mockKernel, 2, nullptr, nullGWS2, nullptr, 0, nullptr, nullptr); - EXPECT_EQ(static_cast(CL_COMMAND_MARKER), mockCmdQ->lastCommandType); + retVal = mockCmdQ->enqueueKernel(mockKernel.mockKernel, workDim, nullptr, gws, nullptr, 0, nullptr, nullptr); + EXPECT_EQ(CL_SUCCESS, retVal); + EXPECT_EQ(static_cast(CL_COMMAND_MARKER), mockCmdQ->lastCommandType); + } +} - size_t *nullGWS3 = nullptr; - mockCmdQ->enqueueKernel(mockKernel.mockKernel, 3, nullptr, nullGWS3, nullptr, 0, nullptr, nullptr); - EXPECT_EQ(static_cast(CL_COMMAND_MARKER), mockCmdQ->lastCommandType); +HWTEST_F(ZeroSizeEnqueueHandlerTestZeroGws, enqueueKernelWhenZeroSizeEnqueueIsDetectedAndOpenCLIs20OrOlderThenErrorIsReturned) { + int oclVersionsToTest[] = {12, 20}; + for (auto oclVersion : oclVersionsToTest) { + pDevice->enabledClVersion = oclVersion; - size_t zeroGWS0 = 0; - mockCmdQ->enqueueKernel(mockKernel.mockKernel, 1, nullptr, &zeroGWS0, nullptr, 0, nullptr, nullptr); - EXPECT_EQ(static_cast(CL_COMMAND_MARKER), mockCmdQ->lastCommandType); + auto mockCmdQ = std::unique_ptr>(new MockCommandQueueHw(&context, pDevice, 0)); - size_t zeroGWS00[] = {0, 0}; - mockCmdQ->enqueueKernel(mockKernel.mockKernel, 2, nullptr, zeroGWS00, nullptr, 0, nullptr, nullptr); - EXPECT_EQ(static_cast(CL_COMMAND_MARKER), mockCmdQ->lastCommandType); + MockKernelWithInternals mockKernel(*pDevice); - size_t zeroGWS01[] = {0, 1}; - mockCmdQ->enqueueKernel(mockKernel.mockKernel, 2, nullptr, zeroGWS01, nullptr, 0, nullptr, nullptr); - EXPECT_EQ(static_cast(CL_COMMAND_MARKER), mockCmdQ->lastCommandType); + for (auto testInput : testGwsInputs) { + auto workDim = std::get<0>(testInput); + auto gws = std::get<1>(testInput); + mockCmdQ->lastCommandType = static_cast(CL_COMMAND_COPY_BUFFER); - size_t zeroGWS10[] = {1, 0}; - mockCmdQ->enqueueKernel(mockKernel.mockKernel, 2, nullptr, zeroGWS10, nullptr, 0, nullptr, nullptr); - EXPECT_EQ(static_cast(CL_COMMAND_MARKER), mockCmdQ->lastCommandType); + retVal = mockCmdQ->enqueueKernel(mockKernel.mockKernel, workDim, nullptr, gws, nullptr, 0, nullptr, nullptr); + EXPECT_EQ(CL_INVALID_GLOBAL_WORK_SIZE, retVal); + EXPECT_EQ(static_cast(CL_COMMAND_COPY_BUFFER), mockCmdQ->lastCommandType); + } + } +} - size_t zeroGWS000[] = {0, 0, 0}; - mockCmdQ->enqueueKernel(mockKernel.mockKernel, 3, nullptr, zeroGWS000, nullptr, 0, nullptr, nullptr); - EXPECT_EQ(static_cast(CL_COMMAND_MARKER), mockCmdQ->lastCommandType); +HWTEST_F(ZeroSizeEnqueueHandlerTestZeroGws, enqueueKernelWhenZeroSizeEnqueueIsDetectedAndLocalWorkSizeIsSetThenNoExceptionIsThrown) { + auto mockCmdQ = std::unique_ptr>(new MockCommandQueueHw(&context, pDevice, 0)); - size_t zeroGWS011[] = {0, 1, 1}; - mockCmdQ->enqueueKernel(mockKernel.mockKernel, 3, nullptr, zeroGWS011, nullptr, 0, nullptr, nullptr); - EXPECT_EQ(static_cast(CL_COMMAND_MARKER), mockCmdQ->lastCommandType); + MockKernelWithInternals mockKernel(*pDevice); + mockKernel.mockProgram->setAllowNonUniform(true); - size_t zeroGWS101[] = {1, 0, 1}; - mockCmdQ->enqueueKernel(mockKernel.mockKernel, 3, nullptr, zeroGWS101, nullptr, 0, nullptr, nullptr); - EXPECT_EQ(static_cast(CL_COMMAND_MARKER), mockCmdQ->lastCommandType); + auto workDim = 1; + auto gws = zeroGWS0; + size_t lws[1] = {1}; - size_t zeroGWS110[] = {1, 1, 0}; - mockCmdQ->enqueueKernel(mockKernel.mockKernel, 3, nullptr, zeroGWS110, nullptr, 0, nullptr, nullptr); - EXPECT_EQ(static_cast(CL_COMMAND_MARKER), mockCmdQ->lastCommandType); - - size_t zeroGWS001[] = {0, 0, 1}; - mockCmdQ->enqueueKernel(mockKernel.mockKernel, 3, nullptr, zeroGWS001, nullptr, 0, nullptr, nullptr); - EXPECT_EQ(static_cast(CL_COMMAND_MARKER), mockCmdQ->lastCommandType); - - size_t zeroGWS010[] = {0, 1, 0}; - mockCmdQ->enqueueKernel(mockKernel.mockKernel, 3, nullptr, zeroGWS010, nullptr, 0, nullptr, nullptr); - EXPECT_EQ(static_cast(CL_COMMAND_MARKER), mockCmdQ->lastCommandType); - - size_t zeroGWS100[] = {1, 0, 0}; - mockCmdQ->enqueueKernel(mockKernel.mockKernel, 3, nullptr, zeroGWS100, nullptr, 0, nullptr, nullptr); - EXPECT_EQ(static_cast(CL_COMMAND_MARKER), mockCmdQ->lastCommandType); + EXPECT_NO_THROW(retVal = mockCmdQ->enqueueKernel(mockKernel.mockKernel, workDim, nullptr, gws, lws, 0, nullptr, nullptr)); + auto expected = (pDevice->getEnabledClVersion() < 21 ? CL_INVALID_GLOBAL_WORK_SIZE : CL_SUCCESS); + EXPECT_EQ(expected, retVal); } HWTEST_F(ZeroSizeEnqueueHandlerTest, enqueueKernelWhenZeroSizeEnqueueIsDetectedThenEventCommandTypeShoudBeUnchanged) { + if (pDevice->getEnabledClVersion() < 21) { + return; + } auto mockCmdQ = std::unique_ptr>(new MockCommandQueueHw(&context, pDevice, 0)); cl_event event; diff --git a/unit_tests/mocks/mock_device.h b/unit_tests/mocks/mock_device.h index a224581b51..cbf5c52c04 100644 --- a/unit_tests/mocks/mock_device.h +++ b/unit_tests/mocks/mock_device.h @@ -20,6 +20,7 @@ extern CommandStreamReceiver *createCommandStream(ExecutionEnvironment &executio class MockDevice : public Device { public: + using Device::enabledClVersion; using Device::engines; using Device::executionEnvironment; using Device::initializeCaps;