diff --git a/level_zero/core/source/kernel/kernel_imp.cpp b/level_zero/core/source/kernel/kernel_imp.cpp index 5f06d37f0a..d07cce880e 100644 --- a/level_zero/core/source/kernel/kernel_imp.cpp +++ b/level_zero/core/source/kernel/kernel_imp.cpp @@ -1640,8 +1640,8 @@ bool KernelImp::checkKernelContainsStatefulAccess() { auto moduleImp = static_cast(this->module); auto isUserKernel = (moduleImp->getModuleType() == ModuleType::user); auto isGeneratedByIgc = moduleImp->getTranslationUnit()->isGeneratedByIgc; - auto containsBufferStatefulAccess = NEO::AddressingModeHelper::containsBufferStatefulAccess(getKernelDescriptor(), false); - return containsBufferStatefulAccess && isUserKernel && isGeneratedByIgc; + auto containsStatefulAccess = NEO::AddressingModeHelper::containsStatefulAccess(getKernelDescriptor()); + return containsStatefulAccess && isUserKernel && isGeneratedByIgc; } uint8_t KernelImp::getRequiredSlmAlignment(uint32_t argIndex) const { diff --git a/level_zero/core/test/unit_tests/sources/cmdlist/test_cmdlist_1.cpp b/level_zero/core/test/unit_tests/sources/cmdlist/test_cmdlist_1.cpp index bacf121f89..cc34ae70d2 100644 --- a/level_zero/core/test/unit_tests/sources/cmdlist/test_cmdlist_1.cpp +++ b/level_zero/core/test/unit_tests/sources/cmdlist/test_cmdlist_1.cpp @@ -3753,9 +3753,13 @@ TEST_F(CommandListAppendLaunchKernelWithArgumentsTests, whenAppendLaunchKernelWi kernelInfo.kernelDescriptor.payloadMappings.explicitArgs[0].as().bindful = NEO::undefined; kernelInfo.kernelDescriptor.payloadMappings.explicitArgs[0].as().bindless = NEO::undefined; - kernelInfo.kernelDescriptor.payloadMappings.explicitArgs[1].type = NEO::ArgDescriptor::argTImage; // arg image + kernelInfo.kernelDescriptor.payloadMappings.explicitArgs[1].type = NEO::ArgDescriptor::argTImage; // arg image + kernelInfo.kernelDescriptor.payloadMappings.explicitArgs[1].as().bindful = NEO::undefined; + kernelInfo.kernelDescriptor.payloadMappings.explicitArgs[1].as().bindless = NEO::undefined; kernelInfo.kernelDescriptor.payloadMappings.explicitArgs[2].type = NEO::ArgDescriptor::argTSampler; // arg sampler - kernelInfo.kernelDescriptor.payloadMappings.explicitArgs[3].type = NEO::ArgDescriptor::argTValue; // arg immediate + kernelInfo.kernelDescriptor.payloadMappings.explicitArgs[2].as().bindful = NEO::undefined; + kernelInfo.kernelDescriptor.payloadMappings.explicitArgs[2].as().bindless = NEO::undefined; + kernelInfo.kernelDescriptor.payloadMappings.explicitArgs[3].type = NEO::ArgDescriptor::argTValue; // arg immediate kernelInfo.kernelDescriptor.payloadMappings.explicitArgs[3].as().elements.resize(3); kernelInfo.kernelDescriptor.payloadMappings.explicitArgs[3].as().elements[0].size = 4; kernelInfo.kernelDescriptor.payloadMappings.explicitArgs[3].as().elements[0].sourceOffset = 0; diff --git a/opencl/source/command_queue/hardware_interface_xehp_and_later.inl b/opencl/source/command_queue/hardware_interface_xehp_and_later.inl index f3b1537e39..cb360dc658 100644 --- a/opencl/source/command_queue/hardware_interface_xehp_and_later.inl +++ b/opencl/source/command_queue/hardware_interface_xehp_and_later.inl @@ -41,8 +41,8 @@ inline void HardwareInterface::dispatchWorkarounds( CommandQueue &commandQueue, Kernel &kernel, const bool &enable) { - bool containsBufferStatefulAccess = AddressingModeHelper::containsBufferStatefulAccess(kernel.getDescriptor(), false); - bool stateCacheInvalidationWaRequired = commandQueue.getDevice().getReleaseHelper()->isStateCacheInvalidationWaRequired() && containsBufferStatefulAccess; + bool containsStatefulAccess = AddressingModeHelper::containsStatefulAccess(kernel.getDescriptor()); + bool stateCacheInvalidationWaRequired = commandQueue.getDevice().getReleaseHelper()->isStateCacheInvalidationWaRequired() && containsStatefulAccess; if (!enable && stateCacheInvalidationWaRequired) { PipeControlArgs args{}; args.stateCacheInvalidationEnable = true; diff --git a/shared/source/helpers/addressing_mode_helper.cpp b/shared/source/helpers/addressing_mode_helper.cpp index 15b82a0a26..b95879b13e 100644 --- a/shared/source/helpers/addressing_mode_helper.cpp +++ b/shared/source/helpers/addressing_mode_helper.cpp @@ -55,6 +55,27 @@ bool containsBufferStatefulAccess(const std::vector &kernelInfos, return false; } +bool argIsStateful(const ArgDescriptor &arg) { + if (arg.is()) { + return (NEO::isValidOffset(arg.as().bindless) || NEO::isValidOffset(arg.as().bindful)); + } else if (arg.is()) { + return (NEO::isValidOffset(arg.as().bindless) || NEO::isValidOffset(arg.as().bindful)); + } else if (arg.is()) { + return (NEO::isValidOffset(arg.as().bindless) || NEO::isValidOffset(arg.as().bindful)); + } + return false; +} + +bool containsStatefulAccess(const KernelDescriptor &kernelDescriptor) { + auto size = static_cast(kernelDescriptor.payloadMappings.explicitArgs.size()); + for (auto i = 0; i < size; i++) { + if (argIsStateful(kernelDescriptor.payloadMappings.explicitArgs[i])) { + return true; + } + } + return false; +} + bool containsBindlessKernel(const std::vector &kernelInfos) { for (const auto &kernelInfo : kernelInfos) { if (NEO::KernelDescriptor::isBindlessAddressingKernel(kernelInfo->kernelDescriptor)) { diff --git a/shared/source/helpers/addressing_mode_helper.h b/shared/source/helpers/addressing_mode_helper.h index 7cf192f43b..93dc029ac5 100644 --- a/shared/source/helpers/addressing_mode_helper.h +++ b/shared/source/helpers/addressing_mode_helper.h @@ -17,6 +17,7 @@ namespace AddressingModeHelper { bool failBuildProgramWithBufferStatefulAccess(const RootDeviceEnvironment &rootDeviceEnvironment); bool containsBufferStatefulAccess(const KernelDescriptor &kernelDescriptor, bool skipLastExplicitArg); bool containsBufferStatefulAccess(const std::vector &kernelInfos, bool skipLastExplicitArg); +bool containsStatefulAccess(const KernelDescriptor &kernelDescriptor); bool containsBindlessKernel(const std::vector &kernelInfos); } // namespace AddressingModeHelper diff --git a/shared/test/unit_test/helpers/addressing_mode_helper_tests.cpp b/shared/test/unit_test/helpers/addressing_mode_helper_tests.cpp index 527292fd5e..da6ff8ac01 100644 --- a/shared/test/unit_test/helpers/addressing_mode_helper_tests.cpp +++ b/shared/test/unit_test/helpers/addressing_mode_helper_tests.cpp @@ -12,59 +12,147 @@ using namespace NEO; -TEST(AddressingModeHelperTest, GivenArgIsNotPointerWhenCheckingForStatefulAccessThenReturnFalse) { +TEST(AddressingModeHelperTest, GivenArgIsNotPointerWhenCheckingForBufferStatefulAccessThenReturnFalse) { auto argDescriptor = ArgDescriptor(ArgDescriptor::argTValue); - KernelDescriptor kernelDescriptor; + KernelDescriptor kernelDescriptor{}; kernelDescriptor.payloadMappings.explicitArgs.push_back(argDescriptor); EXPECT_FALSE(AddressingModeHelper::containsBufferStatefulAccess(kernelDescriptor, false)); } -TEST(AddressingModeHelperTest, GivenArgIsPointerWithInvalidStatefulOffsetWhenCheckingForStatefulAccessThenReturnFalse) { +TEST(AddressingModeHelperTest, GivenArgIsPointerWithInvalidStatefulOffsetWhenCheckingForBufferStatefulAccessThenReturnFalse) { auto argDescriptor = ArgDescriptor(ArgDescriptor::argTPointer); argDescriptor.as().bindful = undefined; argDescriptor.as().bindless = undefined; - KernelDescriptor kernelDescriptor; + KernelDescriptor kernelDescriptor{}; kernelDescriptor.payloadMappings.explicitArgs.push_back(argDescriptor); EXPECT_FALSE(AddressingModeHelper::containsBufferStatefulAccess(kernelDescriptor, false)); } -TEST(AddressingModeHelperTest, GivenArgIsPointerWithValidBindfulOffsetWhenCheckingForStatefulAccessThenReturnTrue) { +TEST(AddressingModeHelperTest, GivenArgIsPointerWithValidBindfulOffsetWhenCheckingForBufferStatefulAccessThenReturnTrue) { auto argDescriptor = ArgDescriptor(ArgDescriptor::argTPointer); argDescriptor.as().bindful = 0x40; argDescriptor.as().bindless = undefined; - KernelDescriptor kernelDescriptor; + KernelDescriptor kernelDescriptor{}; kernelDescriptor.payloadMappings.explicitArgs.push_back(argDescriptor); EXPECT_TRUE(AddressingModeHelper::containsBufferStatefulAccess(kernelDescriptor, false)); } -TEST(AddressingModeHelperTest, GivenArgIsPointerWithValidBindlessOffsetWhenCheckingForStatefulAccessThenReturnTrue) { +TEST(AddressingModeHelperTest, GivenArgIsPointerWithValidBindlessOffsetWhenCheckingForBufferStatefulAccessThenReturnTrue) { auto argDescriptor = ArgDescriptor(ArgDescriptor::argTPointer); argDescriptor.as().bindful = undefined; argDescriptor.as().bindless = 0x40; - KernelDescriptor kernelDescriptor; + KernelDescriptor kernelDescriptor{}; kernelDescriptor.payloadMappings.explicitArgs.push_back(argDescriptor); EXPECT_TRUE(AddressingModeHelper::containsBufferStatefulAccess(kernelDescriptor, false)); } -TEST(AddressingModeHelperTest, GivenLastArgIsPointerWithValidBindlessOffsetWhenIgnoreLastArgAndCheckingForStatefulAccessThenReturnFalse) { +TEST(AddressingModeHelperTest, GivenLastArgIsPointerWithValidBindlessOffsetWhenIgnoreLastArgAndCheckingForBufferStatefulAccessThenReturnFalse) { auto argDescriptor = ArgDescriptor(ArgDescriptor::argTPointer); argDescriptor.as().bindful = undefined; argDescriptor.as().bindless = 0x40; - KernelDescriptor kernelDescriptor; + KernelDescriptor kernelDescriptor{}; kernelDescriptor.payloadMappings.explicitArgs.push_back(argDescriptor); EXPECT_FALSE(AddressingModeHelper::containsBufferStatefulAccess(kernelDescriptor, true)); } +TEST(AddressingModeHelperTest, GivenInvalidArgWhenCheckingForStatefulAccessThenReturnFalse) { + auto argDescriptor = ArgDescriptor(ArgDescriptor::argTUnknown); + + KernelDescriptor kernelDescriptor{}; + kernelDescriptor.payloadMappings.explicitArgs.push_back(argDescriptor); + + EXPECT_FALSE(AddressingModeHelper::containsStatefulAccess(kernelDescriptor)); +} + +TEST(AddressingModeHelperTest, GivenValidArgWithInvalidStatefulOffsetWhenCheckingForStatefulAccessThenReturnFalse) { + auto argTPointer = ArgDescriptor(ArgDescriptor::argTPointer); + argTPointer.as().bindful = undefined; + argTPointer.as().bindless = undefined; + + auto argTImage = ArgDescriptor(ArgDescriptor::argTImage); + argTImage.as().bindful = undefined; + argTImage.as().bindless = undefined; + + auto argTSampler = ArgDescriptor(ArgDescriptor::argTSampler); + argTSampler.as().bindful = undefined; + argTSampler.as().bindless = undefined; + + KernelDescriptor kernelDescriptor{}; + kernelDescriptor.payloadMappings.explicitArgs.push_back(argTPointer); + kernelDescriptor.payloadMappings.explicitArgs.push_back(argTImage); + kernelDescriptor.payloadMappings.explicitArgs.push_back(argTSampler); + + EXPECT_FALSE(AddressingModeHelper::containsStatefulAccess(kernelDescriptor)); +} + +TEST(AddressingModeHelperTest, GivenValidArgWithValidBindfulOffsetWhenCheckingForStatefulAccessThenReturnTrue) { + auto argTPointer = ArgDescriptor(ArgDescriptor::argTPointer); + argTPointer.as().bindful = 0x40; + argTPointer.as().bindless = undefined; + + KernelDescriptor kernelDescriptor{}; + kernelDescriptor.payloadMappings.explicitArgs.push_back(argTPointer); + + EXPECT_TRUE(AddressingModeHelper::containsStatefulAccess(kernelDescriptor)); + + auto argTImage = ArgDescriptor(ArgDescriptor::argTImage); + argTImage.as().bindful = 0x40; + argTImage.as().bindless = undefined; + + kernelDescriptor.payloadMappings.explicitArgs.clear(); + kernelDescriptor.payloadMappings.explicitArgs.push_back(argTImage); + + EXPECT_TRUE(AddressingModeHelper::containsStatefulAccess(kernelDescriptor)); + + auto argTSampler = ArgDescriptor(ArgDescriptor::argTSampler); + argTSampler.as().bindful = 0x40; + argTSampler.as().bindless = undefined; + + kernelDescriptor.payloadMappings.explicitArgs.clear(); + kernelDescriptor.payloadMappings.explicitArgs.push_back(argTSampler); + + EXPECT_TRUE(AddressingModeHelper::containsStatefulAccess(kernelDescriptor)); +} + +TEST(AddressingModeHelperTest, GivenValidArgWithValidBindlessOffsetWhenCheckingForStatefulAccessThenReturnTrue) { + auto argTPointer = ArgDescriptor(ArgDescriptor::argTPointer); + argTPointer.as().bindful = undefined; + argTPointer.as().bindless = 0x40; + + KernelDescriptor kernelDescriptor{}; + kernelDescriptor.payloadMappings.explicitArgs.push_back(argTPointer); + + EXPECT_TRUE(AddressingModeHelper::containsStatefulAccess(kernelDescriptor)); + + auto argTImage = ArgDescriptor(ArgDescriptor::argTImage); + argTImage.as().bindful = undefined; + argTImage.as().bindless = 0x40; + + kernelDescriptor.payloadMappings.explicitArgs.clear(); + kernelDescriptor.payloadMappings.explicitArgs.push_back(argTImage); + + EXPECT_TRUE(AddressingModeHelper::containsStatefulAccess(kernelDescriptor)); + + auto argTSampler = ArgDescriptor(ArgDescriptor::argTSampler); + argTSampler.as().bindful = undefined; + argTSampler.as().bindless = 0x40; + + kernelDescriptor.payloadMappings.explicitArgs.clear(); + kernelDescriptor.payloadMappings.explicitArgs.push_back(argTSampler); + + EXPECT_TRUE(AddressingModeHelper::containsStatefulAccess(kernelDescriptor)); +} + TEST(AddressingModeHelperTest, GivenKernelInfosWhenCheckingForBindlessKernelThenReturnCorrectValue) { KernelInfo kernelInfo1{}; KernelInfo kernelInfo2{};