diff --git a/runtime/command_stream/command_stream_receiver.h b/runtime/command_stream/command_stream_receiver.h index d181a63835..5c049215e1 100644 --- a/runtime/command_stream/command_stream_receiver.h +++ b/runtime/command_stream/command_stream_receiver.h @@ -144,6 +144,10 @@ class CommandStreamReceiver { bool initializeTagAllocation(); + KmdNotifyHelper *peekKmdNotifyHelper() { + return kmdNotifyHelper.get(); + } + protected: void setDisableL3Cache(bool val) { disableL3Cache = val; @@ -195,6 +199,7 @@ class CommandStreamReceiver { IndirectHeap *indirectHeap[IndirectHeap::NUM_TYPES]; std::unique_ptr flatBatchBufferHelper; std::unique_ptr experimentalCmdBuffer; + std::unique_ptr kmdNotifyHelper; }; typedef CommandStreamReceiver *(*CommandStreamReceiverCreateFunc)(const HardwareInfo &hwInfoIn, bool withAubDump); diff --git a/runtime/command_stream/command_stream_receiver_hw.h b/runtime/command_stream/command_stream_receiver_hw.h index 966f8d60be..155e88eb47 100644 --- a/runtime/command_stream/command_stream_receiver_hw.h +++ b/runtime/command_stream/command_stream_receiver_hw.h @@ -109,8 +109,6 @@ class CommandStreamReceiverHw : public CommandStreamReceiver { const HardwareInfo &hwInfo; CsrSizeRequestFlags csrSizeRequestFlags = {}; - - std::unique_ptr kmdNotifyHelper; }; } // namespace OCLRT diff --git a/runtime/context/context.cpp b/runtime/context/context.cpp index d39d10a6a4..3e58e306a0 100644 --- a/runtime/context/context.cpp +++ b/runtime/context/context.cpp @@ -31,6 +31,7 @@ #include "runtime/platform/platform.h" #include "runtime/helpers/string.h" #include "runtime/command_queue/command_queue.h" +#include "runtime/command_stream/command_stream_receiver.h" #include "runtime/built_ins/built_ins.h" #include "runtime/compiler_interface/compiler_interface.h" #include "runtime/memory_manager/svm_memory_manager.h" @@ -174,11 +175,15 @@ bool Context::createImpl(const cl_context_properties *properties, // We currently assume each device uses the same MemoryManager if (devices.size() > 0) { - this->memoryManager = this->getDevice(0)->getMemoryManager(); + auto device = this->getDevice(0); + this->memoryManager = device->getMemoryManager(); this->svmAllocsManager = new SVMAllocsManager(this->memoryManager); if (memoryManager->isAsyncDeleterEnabled()) { memoryManager->getDeferredDeleter()->addClient(); } + if (sharingBuilder->isSharingPresent(SharingType::VA_SHARING)) { + device->getCommandStreamReceiver().peekKmdNotifyHelper()->initMaxPowerSavingMode(); + } } for (auto &device : devices) { diff --git a/runtime/helpers/kmd_notify_properties.cpp b/runtime/helpers/kmd_notify_properties.cpp index bcbd4d6522..4ae5e83632 100644 --- a/runtime/helpers/kmd_notify_properties.cpp +++ b/runtime/helpers/kmd_notify_properties.cpp @@ -37,7 +37,9 @@ bool KmdNotifyHelper::obtainTimeoutParams(int64_t &timeoutValueOutput, quickKmdSleepRequest |= applyQuickKmdSleepForSporadicWait(); - if (!properties->enableKmdNotify && !acLineConnected) { + if (maxPowerSavingMode) { + timeoutValueOutput = 1; + } else if (!properties->enableKmdNotify && !acLineConnected) { timeoutValueOutput = KmdNotifyConstants::timeoutInMicrosecondsForDisconnectedAcLine; } else if (quickKmdSleepRequest && properties->enableQuickKmdSleep) { timeoutValueOutput = properties->delayQuickKmdSleepMicroseconds; diff --git a/runtime/helpers/kmd_notify_properties.h b/runtime/helpers/kmd_notify_properties.h index 2459882352..41e02a1d10 100644 --- a/runtime/helpers/kmd_notify_properties.h +++ b/runtime/helpers/kmd_notify_properties.h @@ -64,6 +64,10 @@ class KmdNotifyHelper { static void overrideFromDebugVariable(int32_t debugVariableValue, int64_t &destination); static void overrideFromDebugVariable(int32_t debugVariableValue, bool &destination); + void initMaxPowerSavingMode() { + maxPowerSavingMode = true; + } + protected: bool applyQuickKmdSleepForSporadicWait() const; int64_t getBaseTimeout(const int64_t &multiplier) const; @@ -72,5 +76,6 @@ class KmdNotifyHelper { const KmdNotifyProperties *properties = nullptr; std::atomic lastWaitForCompletionTimestampUs{0}; std::atomic acLineConnected{true}; + bool maxPowerSavingMode = false; }; } // namespace OCLRT diff --git a/runtime/sharings/sharing_factory.cpp b/runtime/sharings/sharing_factory.cpp index bde0c82e99..9c0a740510 100644 --- a/runtime/sharings/sharing_factory.cpp +++ b/runtime/sharings/sharing_factory.cpp @@ -81,6 +81,10 @@ bool SharingFactory::finalizeProperties(Context &context, int32_t &errcodeRet) { return true; } +bool SharingFactory::isSharingPresent(SharingType sharingId) { + return sharingContextBuilder[sharingId] != nullptr; +} + SharingBuilderFactory *SharingFactory::sharingContextBuilder[SharingType::MAX_SHARING_VALUE] = { nullptr, }; diff --git a/runtime/sharings/sharing_factory.h b/runtime/sharings/sharing_factory.h index 91155dafba..b3f0471b4a 100644 --- a/runtime/sharings/sharing_factory.h +++ b/runtime/sharings/sharing_factory.h @@ -70,6 +70,7 @@ class SharingFactory { static std::unique_ptr build(); bool processProperties(cl_context_properties &propertyType, cl_context_properties &propertyValue, cl_int &errcodeRet); bool finalizeProperties(Context &context, int32_t &errcodeRet); + bool isSharingPresent(SharingType sharingId); std::string getExtensions(); void fillGlobalDispatchTable(); void *getExtensionFunctionAddress(const std::string &functionName); diff --git a/unit_tests/helpers/kmd_notify_tests.cpp b/unit_tests/helpers/kmd_notify_tests.cpp index 963d78bbf1..7dfa832cef 100644 --- a/unit_tests/helpers/kmd_notify_tests.cpp +++ b/unit_tests/helpers/kmd_notify_tests.cpp @@ -59,6 +59,7 @@ struct KmdNotifyTests : public ::testing::Test { using KmdNotifyHelper::acLineConnected; using KmdNotifyHelper::getMicrosecondsSinceEpoch; using KmdNotifyHelper::lastWaitForCompletionTimestampUs; + using KmdNotifyHelper::maxPowerSavingMode; using KmdNotifyHelper::properties; MockKmdNotifyHelper() = delete; @@ -334,6 +335,25 @@ TEST_F(KmdNotifyTests, givenDisabledKmdNotifyMechanismWhenAcLineIsDisconnectedTh EXPECT_EQ(10000, KmdNotifyConstants::timeoutInMicrosecondsForDisconnectedAcLine); } +TEST_F(KmdNotifyTests, givenKmdNotifyEnabledWhenInitMaxPowerSavingModeIsCalledThenObtainReturnOneAsWaitValue) { + localHwInfo.capabilityTable.kmdNotifyProperties.enableKmdNotify = true; + MockKmdNotifyHelper helper(&(localHwInfo.capabilityTable.kmdNotifyProperties)); + + EXPECT_FALSE(helper.maxPowerSavingMode); + + int64_t timeout = 0; + bool timeoutEnabled = helper.obtainTimeoutParams(timeout, false, 1, 2, 2); + EXPECT_TRUE(timeoutEnabled); + EXPECT_EQ(2, timeout); + + helper.initMaxPowerSavingMode(); + EXPECT_TRUE(helper.maxPowerSavingMode); + timeoutEnabled = helper.obtainTimeoutParams(timeout, false, 1, 2, 2); + EXPECT_TRUE(timeoutEnabled); + + EXPECT_EQ(1, timeout); +} + TEST_F(KmdNotifyTests, givenEnabledKmdNotifyMechanismWhenAcLineIsDisconnectedThenDontChangeTimeoutValue) { localHwInfo.capabilityTable.kmdNotifyProperties.enableKmdNotify = true; localHwInfo.capabilityTable.kmdNotifyProperties.delayKmdNotifyMicroseconds = 5; diff --git a/unit_tests/sharings/sharing_factory_tests.cpp b/unit_tests/sharings/sharing_factory_tests.cpp index f892c40562..2f18bf34dd 100644 --- a/unit_tests/sharings/sharing_factory_tests.cpp +++ b/unit_tests/sharings/sharing_factory_tests.cpp @@ -22,6 +22,7 @@ #include "gtest/gtest.h" #include "runtime/context/context.h" +#include "runtime/command_stream/command_stream_receiver.h" #include "runtime/device/device.h" #include "runtime/helpers/string.h" #include "runtime/platform/platform.h" @@ -196,6 +197,14 @@ TEST(SharingFactoryTests, givenMockFactoryWithSharingWhenAskedThenAddressIsRetur EXPECT_EQ(reinterpret_cast(dummyHandler), ptr); } +TEST(SharingFactoryTests, givenSharingFactoryWhenSharingIsRegisteredThenIsSharingPresentReflectsThatStatus) { + SharingFactoryStateRestore stateRestore; + stateRestore.clearCurrentState(); + EXPECT_FALSE(stateRestore.isSharingPresent(SharingType::CLGL_SHARING)); + stateRestore.registerSharing(SharingType::CLGL_SHARING); + EXPECT_TRUE(stateRestore.isSharingPresent(SharingType::CLGL_SHARING)); +} + TEST(Context, givenMockSharingBuilderWhenContextWithInvalidPropertiesThenContextCreateShouldFail) { SharingFactoryStateRestore stateRestore; @@ -226,3 +235,35 @@ TEST(Context, givenMockSharingBuilderWhenContextWithInvalidPropertiesThenContext context.reset(Context::create(validProperties, deviceVector, nullptr, nullptr, retVal)); EXPECT_NE(nullptr, context.get()); }; + +TEST(Context, GivenVaContextWhenItIsCreatedItInitializesPowerSavingMode) { + SharingFactoryStateRestore stateRestore; + + stateRestore.clearCurrentState(); + stateRestore.registerSharing(SharingType::VA_SHARING); + + std::unique_ptr device(new MockDevice(*platformDevices[0])); + cl_device_id clDevice = static_cast(device.get()); + DeviceVector deviceVector((cl_device_id *)&clDevice, 1); + cl_int retVal; + + auto pPlatform = OCLRT::platform(); + cl_platform_id platformId[1]; + platformId[0] = pPlatform; + + auto &commandStreamReceiver = device->getCommandStreamReceiver(); + auto kmdNotifyHelper = commandStreamReceiver.peekKmdNotifyHelper(); + + int64_t timeout = 0; + kmdNotifyHelper->obtainTimeoutParams(timeout, true, 1, 10, 2); + EXPECT_NE(1, timeout); + + cl_context_properties validProperties[5] = {CL_CONTEXT_PLATFORM, (cl_context_properties)platformId[0], + clContextPropertyMock, mockContextPassFinalize, 0}; + + std::unique_ptr ctx(Context::create(validProperties, deviceVector, nullptr, nullptr, retVal)); + EXPECT_EQ(CL_SUCCESS, retVal); + EXPECT_NE(nullptr, ctx); + kmdNotifyHelper->obtainTimeoutParams(timeout, true, 1, 10, 2); + EXPECT_EQ(1, timeout); +}