From e295e74c0a53e9ee720bc54b776b9b9e42260dab Mon Sep 17 00:00:00 2001 From: Zbigniew Zdanowicz Date: Thu, 23 Sep 2021 13:06:18 +0000 Subject: [PATCH] Add preemption flags creation to shared code Signed-off-by: Zbigniew Zdanowicz --- level_zero/core/source/cmdlist/cmdlist.cpp | 9 +-- .../source/helpers/cl_preemption_helper.cpp | 22 ++--- opencl/source/helpers/cl_preemption_helper.h | 1 - .../unit_test/gen8/test_preemption_gen8.cpp | 9 +-- .../unit_test/preemption/preemption_tests.cpp | 81 ++++++++----------- shared/source/command_stream/preemption.cpp | 15 ++++ shared/source/command_stream/preemption.h | 2 + 7 files changed, 61 insertions(+), 78 deletions(-) diff --git a/level_zero/core/source/cmdlist/cmdlist.cpp b/level_zero/core/source/cmdlist/cmdlist.cpp index e16f8b9b90..bbceceaf2b 100644 --- a/level_zero/core/source/cmdlist/cmdlist.cpp +++ b/level_zero/core/source/cmdlist/cmdlist.cpp @@ -116,14 +116,7 @@ bool CommandList::isCopyOnly() const { } NEO::PreemptionMode CommandList::obtainFunctionPreemptionMode(Kernel *kernel) { - auto functionAttributes = kernel->getImmutableData()->getDescriptor().kernelAttributes; - NEO::PreemptionFlags flags = {}; - flags.flags.disabledMidThreadPreemptionKernel = functionAttributes.flags.requiresDisabledMidThreadPreemption; - flags.flags.usesFencesForReadWriteImages = functionAttributes.flags.usesFencesForReadWriteImages; - flags.flags.deviceSupportsVmePreemption = device->getDeviceInfo().vmeAvcSupportsPreemption; - flags.flags.disablePerCtxtPreemptionGranularityControl = device->getHwInfo().workaroundTable.waDisablePerCtxtPreemptionGranularityControl; - flags.flags.disableLSQCROPERFforOCL = device->getHwInfo().workaroundTable.waDisableLSQCROPERFforOCL; - + NEO::PreemptionFlags flags = NEO::PreemptionHelper::createPreemptionLevelFlags(*device->getNEODevice(), &kernel->getImmutableData()->getDescriptor(), false); return NEO::PreemptionHelper::taskPreemptionMode(device->getDevicePreemptionMode(), flags); } diff --git a/opencl/source/helpers/cl_preemption_helper.cpp b/opencl/source/helpers/cl_preemption_helper.cpp index f89ff2b105..4eca19780c 100644 --- a/opencl/source/helpers/cl_preemption_helper.cpp +++ b/opencl/source/helpers/cl_preemption_helper.cpp @@ -11,28 +11,20 @@ namespace NEO { -void ClPreemptionHelper::setPreemptionLevelFlags(PreemptionFlags &flags, Device &device, Kernel *kernel) { - if (kernel) { - const auto &kernelDescriptor = kernel->getKernelInfo().kernelDescriptor; - flags.flags.disabledMidThreadPreemptionKernel = kernelDescriptor.kernelAttributes.flags.requiresDisabledMidThreadPreemption; - flags.flags.vmeKernel = kernel->isVmeKernel(); - flags.flags.usesFencesForReadWriteImages = kernelDescriptor.kernelAttributes.flags.usesFencesForReadWriteImages; - flags.flags.schedulerKernel = kernel->isSchedulerKernel; - } - flags.flags.deviceSupportsVmePreemption = device.getDeviceInfo().vmeAvcSupportsPreemption; - flags.flags.disablePerCtxtPreemptionGranularityControl = device.getHardwareInfo().workaroundTable.waDisablePerCtxtPreemptionGranularityControl; - flags.flags.disableLSQCROPERFforOCL = device.getHardwareInfo().workaroundTable.waDisableLSQCROPERFforOCL; -} - PreemptionMode ClPreemptionHelper::taskPreemptionMode(Device &device, const MultiDispatchInfo &multiDispatchInfo) { PreemptionMode devMode = device.getPreemptionMode(); for (const auto &di : multiDispatchInfo) { auto kernel = di.getKernel(); - PreemptionFlags flags = {}; - setPreemptionLevelFlags(flags, device, kernel); + const KernelDescriptor *kernelDescriptor = nullptr; + bool schedulerKernel = false; + if (kernel != nullptr) { + kernelDescriptor = &kernel->getDescriptor(); + schedulerKernel = kernel->isSchedulerKernel; + } + PreemptionFlags flags = PreemptionHelper::createPreemptionLevelFlags(device, kernelDescriptor, schedulerKernel); PreemptionMode taskMode = PreemptionHelper::taskPreemptionMode(devMode, flags); if (devMode > taskMode) { devMode = taskMode; diff --git a/opencl/source/helpers/cl_preemption_helper.h b/opencl/source/helpers/cl_preemption_helper.h index 6144b2aac2..72df627065 100644 --- a/opencl/source/helpers/cl_preemption_helper.h +++ b/opencl/source/helpers/cl_preemption_helper.h @@ -16,7 +16,6 @@ struct MultiDispatchInfo; class ClPreemptionHelper { public: static PreemptionMode taskPreemptionMode(Device &device, const MultiDispatchInfo &multiDispatchInfo); - static void setPreemptionLevelFlags(PreemptionFlags &flags, Device &device, Kernel *kernel); }; } // namespace NEO diff --git a/opencl/test/unit_test/gen8/test_preemption_gen8.cpp b/opencl/test/unit_test/gen8/test_preemption_gen8.cpp index d14665a984..2381b5447b 100644 --- a/opencl/test/unit_test/gen8/test_preemption_gen8.cpp +++ b/opencl/test/unit_test/gen8/test_preemption_gen8.cpp @@ -20,8 +20,7 @@ using Gen8PreemptionEnqueueKernelTest = PreemptionEnqueueKernelTest; using Gen8ClPreemptionTests = DevicePreemptionTests; GEN8TEST_F(Gen8ClPreemptionTests, GivenEmptyFlagsWhenSettingPreemptionLevelFlagsThenThreadGroupPreemptionIsAllowed) { - PreemptionFlags flags = {}; - ClPreemptionHelper::setPreemptionLevelFlags(flags, device->getDevice(), kernel.get()); + PreemptionFlags flags = PreemptionHelper::createPreemptionLevelFlags(device->getDevice(), &kernel->getDescriptor(), kernel->isSchedulerKernel); EXPECT_TRUE(PreemptionHelper::allowThreadGroupPreemption(flags)); } @@ -71,8 +70,7 @@ GEN8TEST_F(Gen8PreemptionEnqueueKernelTest, givenValidKernelForPreemptionWhenEnq pDevice->resetCommandStreamReceiver(mockCsr); MockKernelWithInternals mockKernel(*pClDevice); - PreemptionFlags flags = {}; - ClPreemptionHelper::setPreemptionLevelFlags(flags, *pDevice, mockKernel.mockKernel); + PreemptionFlags flags = PreemptionHelper::createPreemptionLevelFlags(*pDevice, &mockKernel.mockKernel->getDescriptor(), mockKernel.mockKernel->isSchedulerKernel); EXPECT_EQ(PreemptionMode::ThreadGroup, PreemptionHelper::taskPreemptionMode(pDevice->getPreemptionMode(), flags)); UserEvent userEventObj; @@ -94,8 +92,7 @@ GEN8TEST_F(Gen8PreemptionEnqueueKernelTest, givenDisabledPreemptionWhenEnqueueKe pDevice->resetCommandStreamReceiver(mockCsr); MockKernelWithInternals mockKernel(*pClDevice); - PreemptionFlags flags = {}; - ClPreemptionHelper::setPreemptionLevelFlags(flags, *pDevice, mockKernel.mockKernel); + PreemptionFlags flags = PreemptionHelper::createPreemptionLevelFlags(*pDevice, &mockKernel.mockKernel->getDescriptor(), mockKernel.mockKernel->isSchedulerKernel); EXPECT_EQ(PreemptionMode::Disabled, PreemptionHelper::taskPreemptionMode(pDevice->getPreemptionMode(), flags)); size_t gws[3] = {1, 0, 0}; diff --git a/opencl/test/unit_test/preemption/preemption_tests.cpp b/opencl/test/unit_test/preemption/preemption_tests.cpp index 0ebf55bf21..0c645a0889 100644 --- a/opencl/test/unit_test/preemption/preemption_tests.cpp +++ b/opencl/test/unit_test/preemption/preemption_tests.cpp @@ -34,43 +34,38 @@ class MidThreadPreemptionTests : public DevicePreemptionTests { }; TEST_F(ThreadGroupPreemptionTests, GivenDisallowedByKmdThenThreadGroupPreemptionIsDisabled) { - PreemptionFlags flags = {}; waTable->waDisablePerCtxtPreemptionGranularityControl = 1; - ClPreemptionHelper::setPreemptionLevelFlags(flags, device->getDevice(), kernel.get()); + PreemptionFlags flags = PreemptionHelper::createPreemptionLevelFlags(device->getDevice(), &kernel->getDescriptor(), kernel->isSchedulerKernel); EXPECT_FALSE(PreemptionHelper::allowThreadGroupPreemption(flags)); EXPECT_EQ(PreemptionMode::MidBatch, PreemptionHelper::taskPreemptionMode(device->getPreemptionMode(), flags)); } TEST_F(ThreadGroupPreemptionTests, GivenDisallowByDeviceThenThreadGroupPreemptionIsDisabled) { - PreemptionFlags flags = {}; device->setPreemptionMode(PreemptionMode::MidThread); - ClPreemptionHelper::setPreemptionLevelFlags(flags, device->getDevice(), kernel.get()); + PreemptionFlags flags = PreemptionHelper::createPreemptionLevelFlags(device->getDevice(), &kernel->getDescriptor(), kernel->isSchedulerKernel); EXPECT_TRUE(PreemptionHelper::allowThreadGroupPreemption(flags)); EXPECT_EQ(PreemptionMode::MidThread, PreemptionHelper::taskPreemptionMode(device->getPreemptionMode(), flags)); } TEST_F(ThreadGroupPreemptionTests, GivenDisallowByReadWriteFencesWaThenThreadGroupPreemptionIsDisabled) { - PreemptionFlags flags = {}; kernelInfo->kernelDescriptor.kernelAttributes.flags.usesFencesForReadWriteImages = true; waTable->waDisableLSQCROPERFforOCL = 1; - ClPreemptionHelper::setPreemptionLevelFlags(flags, device->getDevice(), kernel.get()); + PreemptionFlags flags = PreemptionHelper::createPreemptionLevelFlags(device->getDevice(), &kernel->getDescriptor(), kernel->isSchedulerKernel); EXPECT_FALSE(PreemptionHelper::allowThreadGroupPreemption(flags)); EXPECT_EQ(PreemptionMode::MidBatch, PreemptionHelper::taskPreemptionMode(device->getPreemptionMode(), flags)); } TEST_F(ThreadGroupPreemptionTests, GivenDisallowBySchedulerKernelThenThreadGroupPreemptionIsDisabled) { - PreemptionFlags flags = {}; kernel.reset(new MockKernel(program.get(), *kernelInfo, *device, true)); - ClPreemptionHelper::setPreemptionLevelFlags(flags, device->getDevice(), kernel.get()); + PreemptionFlags flags = PreemptionHelper::createPreemptionLevelFlags(device->getDevice(), &kernel->getDescriptor(), kernel->isSchedulerKernel); EXPECT_FALSE(PreemptionHelper::allowThreadGroupPreemption(flags)); EXPECT_EQ(PreemptionMode::MidBatch, PreemptionHelper::taskPreemptionMode(device->getPreemptionMode(), flags)); } TEST_F(ThreadGroupPreemptionTests, GivenDisallowByVmeKernelThenThreadGroupPreemptionIsDisabled) { - PreemptionFlags flags = {}; kernelInfo->kernelDescriptor.kernelAttributes.flags.usesVme = true; kernel.reset(new MockKernel(program.get(), *kernelInfo, *device)); - ClPreemptionHelper::setPreemptionLevelFlags(flags, device->getDevice(), kernel.get()); + PreemptionFlags flags = PreemptionHelper::createPreemptionLevelFlags(device->getDevice(), &kernel->getDescriptor(), kernel->isSchedulerKernel); EXPECT_FALSE(PreemptionHelper::allowThreadGroupPreemption(flags)); EXPECT_EQ(PreemptionMode::MidBatch, PreemptionHelper::taskPreemptionMode(device->getPreemptionMode(), flags)); } @@ -82,40 +77,35 @@ TEST_F(ThreadGroupPreemptionTests, GivenDefaultThenThreadGroupPreemptionIsEnable } TEST_F(ThreadGroupPreemptionTests, GivenDefaultModeForNonKernelRequestThenThreadGroupPreemptionIsEnabled) { - PreemptionFlags flags = {}; - ClPreemptionHelper::setPreemptionLevelFlags(flags, device->getDevice(), nullptr); + PreemptionFlags flags = PreemptionHelper::createPreemptionLevelFlags(device->getDevice(), nullptr, false); EXPECT_EQ(PreemptionMode::ThreadGroup, PreemptionHelper::taskPreemptionMode(device->getPreemptionMode(), flags)); } TEST_F(ThreadGroupPreemptionTests, givenKernelWithEnvironmentPatchSetWhenLSQCWaIsTurnedOnThenThreadGroupPreemptionIsBeingSelected) { - PreemptionFlags flags = {}; kernelInfo->kernelDescriptor.kernelAttributes.flags.usesFencesForReadWriteImages = false; waTable->waDisableLSQCROPERFforOCL = 1; - ClPreemptionHelper::setPreemptionLevelFlags(flags, device->getDevice(), kernel.get()); + PreemptionFlags flags = PreemptionHelper::createPreemptionLevelFlags(device->getDevice(), &kernel->getDescriptor(), kernel->isSchedulerKernel); EXPECT_TRUE(PreemptionHelper::allowThreadGroupPreemption(flags)); EXPECT_EQ(PreemptionMode::ThreadGroup, PreemptionHelper::taskPreemptionMode(device->getPreemptionMode(), flags)); } TEST_F(ThreadGroupPreemptionTests, givenKernelWithEnvironmentPatchSetWhenLSQCWaIsTurnedOffThenThreadGroupPreemptionIsBeingSelected) { - PreemptionFlags flags = {}; kernelInfo->kernelDescriptor.kernelAttributes.flags.usesFencesForReadWriteImages = true; waTable->waDisableLSQCROPERFforOCL = 0; - ClPreemptionHelper::setPreemptionLevelFlags(flags, device->getDevice(), kernel.get()); + PreemptionFlags flags = PreemptionHelper::createPreemptionLevelFlags(device->getDevice(), &kernel->getDescriptor(), kernel->isSchedulerKernel); EXPECT_TRUE(PreemptionHelper::allowThreadGroupPreemption(flags)); EXPECT_EQ(PreemptionMode::ThreadGroup, PreemptionHelper::taskPreemptionMode(device->getPreemptionMode(), flags)); } TEST_F(ThreadGroupPreemptionTests, GivenDefaultThenMidBatchPreemptionIsEnabled) { - PreemptionFlags flags = {}; device->setPreemptionMode(PreemptionMode::MidBatch); - ClPreemptionHelper::setPreemptionLevelFlags(flags, device->getDevice(), nullptr); + PreemptionFlags flags = PreemptionHelper::createPreemptionLevelFlags(device->getDevice(), nullptr, false); EXPECT_EQ(PreemptionMode::MidBatch, PreemptionHelper::taskPreemptionMode(device->getPreemptionMode(), flags)); } TEST_F(ThreadGroupPreemptionTests, GivenDisabledThenPreemptionIsDisabled) { - PreemptionFlags flags = {}; device->setPreemptionMode(PreemptionMode::Disabled); - ClPreemptionHelper::setPreemptionLevelFlags(flags, device->getDevice(), nullptr); + PreemptionFlags flags = PreemptionHelper::createPreemptionLevelFlags(device->getDevice(), nullptr, false); EXPECT_EQ(PreemptionMode::Disabled, PreemptionHelper::taskPreemptionMode(device->getPreemptionMode(), flags)); } @@ -143,8 +133,7 @@ TEST_F(ThreadGroupPreemptionTests, GivenAtLeastOneInvalidKernelInMdiThenPreempti MockKernel schedulerKernel(program.get(), *kernelInfo, *device, true); DispatchInfo schedulerDispatchInfo(device.get(), &schedulerKernel, 1, Vec3(1, 1, 1), Vec3(1, 1, 1), Vec3(0, 0, 0)); - PreemptionFlags flags = {}; - ClPreemptionHelper::setPreemptionLevelFlags(flags, device->getDevice(), &schedulerKernel); + PreemptionFlags flags = PreemptionHelper::createPreemptionLevelFlags(device->getDevice(), &schedulerKernel.getDescriptor(), schedulerKernel.isSchedulerKernel); EXPECT_EQ(PreemptionMode::MidBatch, PreemptionHelper::taskPreemptionMode(device->getPreemptionMode(), flags)); MultiDispatchInfo multiDispatchInfo; @@ -156,104 +145,93 @@ TEST_F(ThreadGroupPreemptionTests, GivenAtLeastOneInvalidKernelInMdiThenPreempti } TEST_F(MidThreadPreemptionTests, GivenMidThreadPreemptionThenMidThreadPreemptionIsEnabled) { - PreemptionFlags flags = {}; device->setPreemptionMode(PreemptionMode::MidThread); kernelInfo->kernelDescriptor.kernelAttributes.flags.requiresDisabledMidThreadPreemption = false; - ClPreemptionHelper::setPreemptionLevelFlags(flags, device->getDevice(), kernel.get()); + PreemptionFlags flags = PreemptionHelper::createPreemptionLevelFlags(device->getDevice(), &kernel->getDescriptor(), kernel->isSchedulerKernel); EXPECT_TRUE(PreemptionHelper::allowMidThreadPreemption(flags)); } TEST_F(MidThreadPreemptionTests, GivenNullKernelThenMidThreadPreemptionIsEnabled) { - PreemptionFlags flags = {}; device->setPreemptionMode(PreemptionMode::MidThread); - ClPreemptionHelper::setPreemptionLevelFlags(flags, device->getDevice(), nullptr); + PreemptionFlags flags = PreemptionHelper::createPreemptionLevelFlags(device->getDevice(), nullptr, false); EXPECT_TRUE(PreemptionHelper::allowMidThreadPreemption(flags)); } TEST_F(MidThreadPreemptionTests, GivenMidThreadPreemptionDeviceSupportPreemptionOnVmeKernelThenMidThreadPreemptionIsEnabled) { - PreemptionFlags flags = {}; device->setPreemptionMode(PreemptionMode::MidThread); device->sharedDeviceInfo.vmeAvcSupportsPreemption = true; kernelInfo->kernelDescriptor.kernelAttributes.flags.usesVme = true; kernel.reset(new MockKernel(program.get(), *kernelInfo, *device)); - ClPreemptionHelper::setPreemptionLevelFlags(flags, device->getDevice(), kernel.get()); + PreemptionFlags flags = PreemptionHelper::createPreemptionLevelFlags(device->getDevice(), &kernel->getDescriptor(), kernel->isSchedulerKernel); EXPECT_TRUE(PreemptionHelper::allowMidThreadPreemption(flags)); } TEST_F(MidThreadPreemptionTests, GivenDisallowMidThreadPreemptionByDeviceThenMidThreadPreemptionIsEnabled) { - PreemptionFlags flags = {}; device->setPreemptionMode(PreemptionMode::ThreadGroup); kernelInfo->kernelDescriptor.kernelAttributes.flags.requiresDisabledMidThreadPreemption = false; - ClPreemptionHelper::setPreemptionLevelFlags(flags, device->getDevice(), kernel.get()); + PreemptionFlags flags = PreemptionHelper::createPreemptionLevelFlags(device->getDevice(), &kernel->getDescriptor(), kernel->isSchedulerKernel); EXPECT_TRUE(PreemptionHelper::allowMidThreadPreemption(flags)); EXPECT_EQ(PreemptionMode::ThreadGroup, PreemptionHelper::taskPreemptionMode(device->getPreemptionMode(), flags)); } TEST_F(MidThreadPreemptionTests, GivenDisallowMidThreadPreemptionByKernelThenMidThreadPreemptionIsEnabled) { - PreemptionFlags flags = {}; device->setPreemptionMode(PreemptionMode::MidThread); kernelInfo->kernelDescriptor.kernelAttributes.flags.requiresDisabledMidThreadPreemption = true; - ClPreemptionHelper::setPreemptionLevelFlags(flags, device->getDevice(), kernel.get()); + PreemptionFlags flags = PreemptionHelper::createPreemptionLevelFlags(device->getDevice(), &kernel->getDescriptor(), kernel->isSchedulerKernel); EXPECT_FALSE(PreemptionHelper::allowMidThreadPreemption(flags)); } TEST_F(MidThreadPreemptionTests, GivenDisallowMidThreadPreemptionByVmeKernelThenMidThreadPreemptionIsEnabled) { - PreemptionFlags flags = {}; device->setPreemptionMode(PreemptionMode::MidThread); device->sharedDeviceInfo.vmeAvcSupportsPreemption = false; kernelInfo->kernelDescriptor.kernelAttributes.flags.usesVme = true; kernel.reset(new MockKernel(program.get(), *kernelInfo, *device)); - ClPreemptionHelper::setPreemptionLevelFlags(flags, device->getDevice(), kernel.get()); + PreemptionFlags flags = PreemptionHelper::createPreemptionLevelFlags(device->getDevice(), &kernel->getDescriptor(), kernel->isSchedulerKernel); EXPECT_FALSE(PreemptionHelper::allowMidThreadPreemption(flags)); } TEST_F(MidThreadPreemptionTests, GivenTaskPreemptionDisallowMidThreadByDeviceThenThreadGroupPreemptionIsEnabled) { - PreemptionFlags flags = {}; kernelInfo->kernelDescriptor.kernelAttributes.flags.requiresDisabledMidThreadPreemption = false; device->setPreemptionMode(PreemptionMode::ThreadGroup); - ClPreemptionHelper::setPreemptionLevelFlags(flags, device->getDevice(), kernel.get()); + PreemptionFlags flags = PreemptionHelper::createPreemptionLevelFlags(device->getDevice(), &kernel->getDescriptor(), kernel->isSchedulerKernel); PreemptionMode outMode = PreemptionHelper::taskPreemptionMode(device->getPreemptionMode(), flags); EXPECT_EQ(PreemptionMode::ThreadGroup, outMode); } TEST_F(MidThreadPreemptionTests, GivenTaskPreemptionDisallowMidThreadByKernelThenThreadGroupPreemptionIsEnabled) { - PreemptionFlags flags = {}; kernelInfo->kernelDescriptor.kernelAttributes.flags.requiresDisabledMidThreadPreemption = true; device->setPreemptionMode(PreemptionMode::MidThread); - ClPreemptionHelper::setPreemptionLevelFlags(flags, device->getDevice(), kernel.get()); + PreemptionFlags flags = PreemptionHelper::createPreemptionLevelFlags(device->getDevice(), &kernel->getDescriptor(), kernel->isSchedulerKernel); PreemptionMode outMode = PreemptionHelper::taskPreemptionMode(device->getPreemptionMode(), flags); EXPECT_EQ(PreemptionMode::ThreadGroup, outMode); } TEST_F(MidThreadPreemptionTests, GivenTaskPreemptionDisallowMidThreadByVmeKernelThenThreadGroupPreemptionIsEnabled) { - PreemptionFlags flags = {}; kernelInfo->kernelDescriptor.kernelAttributes.flags.usesVme = true; device->sharedDeviceInfo.vmeAvcSupportsPreemption = false; kernel.reset(new MockKernel(program.get(), *kernelInfo, *device)); device->setPreemptionMode(PreemptionMode::MidThread); - ClPreemptionHelper::setPreemptionLevelFlags(flags, device->getDevice(), kernel.get()); + PreemptionFlags flags = PreemptionHelper::createPreemptionLevelFlags(device->getDevice(), &kernel->getDescriptor(), kernel->isSchedulerKernel); PreemptionMode outMode = PreemptionHelper::taskPreemptionMode(device->getPreemptionMode(), flags); //VME disables mid thread and thread group when device does not support it EXPECT_EQ(PreemptionMode::MidBatch, outMode); } TEST_F(MidThreadPreemptionTests, GivenDeviceSupportsMidThreadPreemptionThenMidThreadPreemptionIsEnabled) { - PreemptionFlags flags = {}; kernelInfo->kernelDescriptor.kernelAttributes.flags.requiresDisabledMidThreadPreemption = false; device->setPreemptionMode(PreemptionMode::MidThread); - ClPreemptionHelper::setPreemptionLevelFlags(flags, device->getDevice(), kernel.get()); + PreemptionFlags flags = PreemptionHelper::createPreemptionLevelFlags(device->getDevice(), &kernel->getDescriptor(), kernel->isSchedulerKernel); PreemptionMode outMode = PreemptionHelper::taskPreemptionMode(device->getPreemptionMode(), flags); EXPECT_EQ(PreemptionMode::MidThread, outMode); } TEST_F(MidThreadPreemptionTests, GivenTaskPreemptionAllowDeviceSupportsPreemptionOnVmeKernelThenMidThreadPreemptionIsEnabled) { - PreemptionFlags flags = {}; kernelInfo->kernelDescriptor.kernelAttributes.flags.requiresDisabledMidThreadPreemption = false; kernelInfo->kernelDescriptor.kernelAttributes.flags.usesVme = true; kernel.reset(new MockKernel(program.get(), *kernelInfo, *device)); device->sharedDeviceInfo.vmeAvcSupportsPreemption = true; device->setPreemptionMode(PreemptionMode::MidThread); - ClPreemptionHelper::setPreemptionLevelFlags(flags, device->getDevice(), kernel.get()); + PreemptionFlags flags = PreemptionHelper::createPreemptionLevelFlags(device->getDevice(), &kernel->getDescriptor(), kernel->isSchedulerKernel); PreemptionMode outMode = PreemptionHelper::taskPreemptionMode(device->getPreemptionMode(), flags); EXPECT_EQ(PreemptionMode::MidThread, outMode); } @@ -263,9 +241,8 @@ TEST_F(ThreadGroupPreemptionTests, GivenDebugKernelPreemptionWhenDeviceSupportsT EXPECT_EQ(PreemptionMode::ThreadGroup, device->getPreemptionMode()); - PreemptionFlags flags = {}; kernel.reset(new MockKernel(program.get(), *kernelInfo, *device)); - ClPreemptionHelper::setPreemptionLevelFlags(flags, device->getDevice(), kernel.get()); + PreemptionFlags flags = PreemptionHelper::createPreemptionLevelFlags(device->getDevice(), &kernel->getDescriptor(), kernel->isSchedulerKernel); PreemptionMode outMode = PreemptionHelper::taskPreemptionMode(device->getPreemptionMode(), flags); EXPECT_EQ(PreemptionMode::MidThread, outMode); } @@ -275,9 +252,17 @@ TEST_F(MidThreadPreemptionTests, GivenDebugKernelPreemptionWhenDeviceSupportsMid EXPECT_EQ(PreemptionMode::MidThread, device->getPreemptionMode()); - PreemptionFlags flags = {}; kernel.reset(new MockKernel(program.get(), *kernelInfo, *device)); - ClPreemptionHelper::setPreemptionLevelFlags(flags, device->getDevice(), kernel.get()); + PreemptionFlags flags = PreemptionHelper::createPreemptionLevelFlags(device->getDevice(), &kernel->getDescriptor(), kernel->isSchedulerKernel); PreemptionMode outMode = PreemptionHelper::taskPreemptionMode(device->getPreemptionMode(), flags); EXPECT_EQ(PreemptionMode::MidBatch, outMode); } + +TEST_F(MidThreadPreemptionTests, GivenMultiDispatchWithoutKernelWhenDevicePreemptionIsMidThreadThenTaskPreemptionIsMidThread) { + dispatchInfo.reset(new DispatchInfo(device.get(), nullptr, 1, Vec3(1, 1, 1), Vec3(1, 1, 1), Vec3(0, 0, 0))); + + MultiDispatchInfo multiDispatchInfo; + multiDispatchInfo.push(*dispatchInfo); + + EXPECT_EQ(PreemptionMode::MidThread, ClPreemptionHelper::taskPreemptionMode(device->getDevice(), multiDispatchInfo)); +} diff --git a/shared/source/command_stream/preemption.cpp b/shared/source/command_stream/preemption.cpp index d0ae7012d8..79475fba94 100644 --- a/shared/source/command_stream/preemption.cpp +++ b/shared/source/command_stream/preemption.cpp @@ -10,6 +10,7 @@ #include "shared/source/debug_settings/debug_settings_manager.h" #include "shared/source/device/device.h" #include "shared/source/helpers/string.h" +#include "shared/source/kernel/kernel_descriptor.h" namespace NEO { @@ -76,4 +77,18 @@ PreemptionMode PreemptionHelper::getDefaultPreemptionMode(const HardwareInfo &hw : static_cast(DebugManager.flags.ForcePreemptionMode.get()); } +PreemptionFlags PreemptionHelper::createPreemptionLevelFlags(Device &device, const KernelDescriptor *kernelDescriptor, bool schedulerKernel) { + PreemptionFlags flags = {}; + if (kernelDescriptor) { + flags.flags.disabledMidThreadPreemptionKernel = kernelDescriptor->kernelAttributes.flags.requiresDisabledMidThreadPreemption; + flags.flags.vmeKernel = kernelDescriptor->kernelAttributes.flags.usesVme; + flags.flags.usesFencesForReadWriteImages = kernelDescriptor->kernelAttributes.flags.usesFencesForReadWriteImages; + flags.flags.schedulerKernel = schedulerKernel; + } + flags.flags.deviceSupportsVmePreemption = device.getDeviceInfo().vmeAvcSupportsPreemption; + flags.flags.disablePerCtxtPreemptionGranularityControl = device.getHardwareInfo().workaroundTable.waDisablePerCtxtPreemptionGranularityControl; + flags.flags.disableLSQCROPERFforOCL = device.getHardwareInfo().workaroundTable.waDisableLSQCROPERFforOCL; + return flags; +} + } // namespace NEO diff --git a/shared/source/command_stream/preemption.h b/shared/source/command_stream/preemption.h index b8445d8571..aff759a1d9 100644 --- a/shared/source/command_stream/preemption.h +++ b/shared/source/command_stream/preemption.h @@ -15,6 +15,7 @@ namespace NEO { class Device; class GraphicsAllocation; +struct KernelDescriptor; struct PreemptionFlags { PreemptionFlags() { @@ -44,6 +45,7 @@ class PreemptionHelper { static bool allowThreadGroupPreemption(const PreemptionFlags &flags); static bool allowMidThreadPreemption(const PreemptionFlags &flags); static void adjustDefaultPreemptionMode(RuntimeCapabilityTable &deviceCapabilities, bool allowMidThread, bool allowThreadGroup, bool allowMidBatch); + static PreemptionFlags createPreemptionLevelFlags(Device &device, const KernelDescriptor *kernelDescriptor, bool schedulerKernel); template static size_t getRequiredPreambleSize(const Device &device);