From 0f8ee57f98b2318fc6836c14e779874bf99e4f4b Mon Sep 17 00:00:00 2001 From: Maciej Bielski Date: Tue, 1 Apr 2025 18:09:02 +0000 Subject: [PATCH] feature: add NEO_LOCAL_MEMORY_ALLOCATION_MODE Allow the application to force storageInfo.localOnly and get the out-of-memory returned if not possible. This is a windows-only feature supported on discrete platforms. Related-To: NEO-13428 Signed-off-by: Maciej Bielski --- .../core/source/context/context_imp.cpp | 24 +++++-- .../sources/context/test_context.cpp | 70 +++++++++++++++++++ .../unit_tests/sources/memory/test_memory.cpp | 12 +++- .../DRIVER_EXPERIMENTAL_EXTENSIONS.md | 5 +- .../LOCAL_MEMORY_ALLOCATION_MODE.md | 20 ++++++ .../debug_settings/release_variables.inl | 3 +- shared/source/helpers/common_types.h | 11 +++ .../product_helper_dg2_and_later_discrete.inl | 25 +++++++ .../definitions/storage_info.cpp | 21 +++--- .../source/memory_manager/memory_manager.cpp | 12 +++- shared/source/memory_manager/memory_manager.h | 5 ++ .../os_interface/linux/drm_memory_manager.cpp | 11 +++ .../os_interface/linux/drm_memory_manager.h | 1 + shared/source/os_interface/product_helper.h | 3 +- shared/source/os_interface/product_helper.inl | 4 ++ .../source/os_interface/product_helper_hw.h | 1 + .../windows/wddm_memory_manager.cpp | 1 + .../wddm_memory_operations_handler.cpp | 1 - .../windows/product_helper_bmg.cpp | 1 + .../windows/product_helper_dg2.cpp | 1 + .../mocks/linux/mock_drm_memory_manager.h | 1 + .../test/common/mocks/mock_memory_manager.cpp | 7 +- .../test/common/mocks/mock_memory_manager.h | 1 + .../test/common/mocks/mock_product_helper.h | 3 + shared/test/common/mocks/mock_svm_manager.h | 8 ++- shared/test/common/test_files/igdrcl.config | 1 + .../memory_manager/memory_manager_tests.cpp | 24 +++++++ .../memory_manager/storage_info_tests.cpp | 51 +++++++++++++- .../linux/drm_memory_manager_tests.cpp | 28 +++++++- .../windows/product_helper_win_tests.cpp | 24 +++++++ .../windows/wddm_memory_manager_tests.cpp | 10 +++ 31 files changed, 363 insertions(+), 27 deletions(-) create mode 100644 level_zero/doc/experimental_extensions/LOCAL_MEMORY_ALLOCATION_MODE.md create mode 100644 shared/source/helpers/windows/product_helper_dg2_and_later_discrete.inl diff --git a/level_zero/core/source/context/context_imp.cpp b/level_zero/core/source/context/context_imp.cpp index 7c7cf4cb88..a56de412f5 100644 --- a/level_zero/core/source/context/context_imp.cpp +++ b/level_zero/core/source/context/context_imp.cpp @@ -305,16 +305,28 @@ ze_result_t ContextImp::allocDeviceMem(ze_device_handle_t hDevice, this->driverHandle->svmAllocsManager->freeSVMAllocDeferImpl(); usmPtr = this->driverHandle->svmAllocsManager->createUnifiedMemoryAllocation(size, unifiedMemoryProperties); - if (usmPtr) { - *ptr = usmPtr; - return ZE_RESULT_SUCCESS; - } } + } + if (usmPtr == nullptr) { return ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY; } - *ptr = usmPtr; - return ZE_RESULT_SUCCESS; + ze_result_t ret{ZE_RESULT_SUCCESS}; + + if (this->driverHandle->getMemoryManager()->isLocalOnlyAllocationMode()) { + auto *allocData{this->driverHandle->svmAllocsManager->getSVMAlloc(usmPtr)}; + DEBUG_BREAK_IF(allocData == nullptr); + auto *gpuAllocation{allocData->gpuAllocations.getDefaultGraphicsAllocation()}; + DEBUG_BREAK_IF(gpuAllocation == nullptr); + + if (allocData->memoryType == InternalMemoryType::deviceUnifiedMemory && gpuAllocation->storageInfo.localOnlyRequired) { + ret = this->makeMemoryResident(hDevice, usmPtr, size); + } + } + if (ret == ZE_RESULT_SUCCESS) { + *ptr = usmPtr; + } + return ret; } ze_result_t ContextImp::allocSharedMem(ze_device_handle_t hDevice, diff --git a/level_zero/core/test/unit_tests/sources/context/test_context.cpp b/level_zero/core/test/unit_tests/sources/context/test_context.cpp index 61a7112acb..fcfa45c9f4 100644 --- a/level_zero/core/test/unit_tests/sources/context/test_context.cpp +++ b/level_zero/core/test/unit_tests/sources/context/test_context.cpp @@ -700,6 +700,76 @@ TEST_F(ContextMakeMemoryResidentTests, context->freeMem(ptr); } +TEST_F(ContextMakeMemoryResidentTests, givenDeviceUnifiedMemoryAndLocalOnlyAllocationModeThenCallMakeMemoryResidentImmediately) { + const size_t size = 4096; + void *ptr = nullptr; + ze_device_mem_alloc_desc_t deviceDesc = {}; + + auto *driverHandleImp{static_cast(hostDriverHandle.get())}; + driverHandleImp->memoryManager->usmDeviceAllocationMode = NEO::LocalMemAllocationMode::localOnly; + static_cast(driverHandleImp->memoryManager)->returnFakeAllocation = true; + + EXPECT_EQ(0U, mockMemoryInterface->makeResidentCalled); + mockMemoryInterface->makeResidentResult = NEO::MemoryOperationsStatus::success; + ze_result_t res1 = context->allocDeviceMem(device->toHandle(), + &deviceDesc, + size, + 0, + &ptr); + EXPECT_EQ(ZE_RESULT_SUCCESS, res1); + + auto allocData{driverHandleImp->svmAllocsManager->getSVMAlloc(ptr)}; + EXPECT_NE(allocData, nullptr); + const bool lmemAllocationModeSupported{allocData->gpuAllocations.getDefaultGraphicsAllocation()->storageInfo.localOnlyRequired}; + EXPECT_EQ(mockMemoryInterface->makeResidentCalled, (lmemAllocationModeSupported ? 1U : 0U)); + EXPECT_EQ(ZE_RESULT_SUCCESS, context->freeMem(ptr)); + + mockMemoryInterface->makeResidentResult = NEO::MemoryOperationsStatus::outOfMemory; + ze_result_t res2 = context->allocDeviceMem(device->toHandle(), + &deviceDesc, + size, + 0, + &ptr); + EXPECT_EQ(res2, (lmemAllocationModeSupported ? ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY : ZE_RESULT_SUCCESS)); + EXPECT_EQ(mockMemoryInterface->makeResidentCalled, (lmemAllocationModeSupported ? 2U : 0U)); + EXPECT_EQ(ZE_RESULT_SUCCESS, context->freeMem(ptr)); +} + +TEST_F(ContextMakeMemoryResidentTests, givenNonDeviceUnifiedMemoryWhenAllocDeviceMemCalledThenMakeMemoryResidentIsNotImmediatelyCalled) { + const size_t size = 4096; + void *ptr = nullptr; + ze_device_mem_alloc_desc_t deviceDesc = {}; + + auto *driverHandleImp{static_cast(hostDriverHandle.get())}; + driverHandleImp->memoryManager->usmDeviceAllocationMode = NEO::LocalMemAllocationMode::localOnly; + static_cast(driverHandleImp->memoryManager)->returnFakeAllocation = true; + + auto *origSvmAllocsManager{driverHandleImp->svmAllocsManager}; + auto fakeAllocationAddr{reinterpret_cast(0x1234)}; + + MockGraphicsAllocation mockUnifiedAllocation{}; + SvmAllocationData allocData(0U); + allocData.gpuAllocations.addAllocation(&mockUnifiedAllocation); + allocData.memoryType = InternalMemoryType::notSpecified; + + MockSVMAllocsManager mockSvmAllocsManager{driverHandleImp->memoryManager}; + mockSvmAllocsManager.createUnifiedMemoryAllocationCallBase = false; + mockSvmAllocsManager.createUnifiedMemoryAllocationReturnValue = fakeAllocationAddr; + mockSvmAllocsManager.insertSVMAlloc(fakeAllocationAddr, allocData); + driverHandleImp->svmAllocsManager = &mockSvmAllocsManager; + + EXPECT_EQ(0U, mockMemoryInterface->makeResidentCalled); + mockMemoryInterface->makeResidentResult = NEO::MemoryOperationsStatus::success; + ze_result_t res1 = context->allocDeviceMem(device->toHandle(), + &deviceDesc, + size, + 0, + &ptr); + EXPECT_EQ(ZE_RESULT_SUCCESS, res1); + EXPECT_EQ(mockMemoryInterface->makeResidentCalled, 0U); + driverHandleImp->svmAllocsManager = origSvmAllocsManager; +} + struct ContextMakeMemoryResidentAndMigrationTests : public ContextMakeMemoryResidentTests { struct MockResidentTestsPageFaultManager : public MockPageFaultManager { void moveAllocationToGpuDomain(void *ptr) override { diff --git a/level_zero/core/test/unit_tests/sources/memory/test_memory.cpp b/level_zero/core/test/unit_tests/sources/memory/test_memory.cpp index 12cc7f3b8c..8a7fb2ffa5 100644 --- a/level_zero/core/test/unit_tests/sources/memory/test_memory.cpp +++ b/level_zero/core/test/unit_tests/sources/memory/test_memory.cpp @@ -2295,7 +2295,15 @@ struct SVMAllocsManagerRelaxedSizeMock : public NEO::SVMAllocsManager { void *createUnifiedMemoryAllocation(size_t size, const UnifiedMemoryProperties &svmProperties) override { validateMemoryProperties(svmProperties); - return alignedMalloc(4096u, 4096u); + auto retPtr{alignedMalloc(4096u, 4096u)}; + + SvmAllocationData allocData(svmProperties.getRootDeviceIndex()); + mockUnifiedMemoryAllocation.setGpuPtr(reinterpret_cast(retPtr)); + mockUnifiedMemoryAllocation.setAllocationOffset(0U); + allocData.gpuAllocations.addAllocation(&mockUnifiedMemoryAllocation); + insertSVMAlloc(retPtr, allocData); + + return retPtr; } void *createSharedUnifiedMemoryAllocation(size_t size, @@ -2311,6 +2319,8 @@ struct SVMAllocsManagerRelaxedSizeMock : public NEO::SVMAllocsManager { return alignedMalloc(4096u, 4096u); } std::function validateMemoryProperties = [](const UnifiedMemoryProperties &properties) -> void {}; + + MockGraphicsAllocation mockUnifiedMemoryAllocation{}; }; struct ContextRelaxedSizeMock : public ContextImp { diff --git a/level_zero/doc/experimental_extensions/DRIVER_EXPERIMENTAL_EXTENSIONS.md b/level_zero/doc/experimental_extensions/DRIVER_EXPERIMENTAL_EXTENSIONS.md index a81c86e635..31e89ccd4f 100644 --- a/level_zero/doc/experimental_extensions/DRIVER_EXPERIMENTAL_EXTENSIONS.md +++ b/level_zero/doc/experimental_extensions/DRIVER_EXPERIMENTAL_EXTENSIONS.md @@ -1,6 +1,6 @@ + +# Local memory allocation mode + +At the moment this is supported on Windows only. + +In Level Zero, the API function to allocate a device (local) memory is [zeMemAllocDevice](https://oneapi-src.github.io/level-zero-spec/level-zero/latest/core/api.html#zememallocdevice). For such (device USM) allocations, there are two policies of handling the scenario enough resources being available: +- Local-preferred mode: A region is primarily allocated out of local-memory resources, however system-memory may be used as a fallback. +- Local-only mode: A can only be allocated out of local-memory resources. If the amount of available local-memory is not sufficient the `ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY` error is returned. + +Depending on the hardware, one of these two modes is being used by default or a specific one can be enforced by setting an environment variable `NEO_LOCAL_MEMORY_ALLOCATION_MODE` to respective value: +- `NEO_LOCAL_MEMORY_ALLOCATION_MODE=0`: HW-default (value of the flag when it is not set) +- `NEO_LOCAL_MEMORY_ALLOCATION_MODE=1`: Local-only +- `NEO_LOCAL_MEMORY_ALLOCATION_MODE=2`: Local-preferred \ No newline at end of file diff --git a/shared/source/debug_settings/release_variables.inl b/shared/source/debug_settings/release_variables.inl index f09921650b..bcee79a17f 100644 --- a/shared/source/debug_settings/release_variables.inl +++ b/shared/source/debug_settings/release_variables.inl @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020-2024 Intel Corporation + * Copyright (C) 2020-2025 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -15,3 +15,4 @@ DECLARE_DEBUG_VARIABLE(bool, NEO_CAL_ENABLED, false, "Set by the Compute Aggrega DECLARE_DEBUG_VARIABLE(std::string, ZE_AFFINITY_MASK, std::string("default"), "Refer to the Level Zero Specification for a description") DECLARE_DEBUG_VARIABLE(std::string, ZEX_NUMBER_OF_CCS, std::string("default"), "Define number of CCS engines per root device, e.g. setting Root Device Index 0 to 4 CCS, and Root Device Index 1 To 1 CCS: ZEX_NUMBER_OF_CCS=0:4,1:1") DECLARE_DEBUG_VARIABLE(bool, ZE_ENABLE_PCI_ID_DEVICE_ORDER, false, "Refer to the Level Zero Specification for a description") +DECLARE_DEBUG_VARIABLE(int32_t, NEO_LOCAL_MEMORY_ALLOCATION_MODE, 0, "Specify device-USM allocation policy. 0: default for given HW; 1: require local-memory (return out-of-memory error otherwise); 2: prefer local-memory but refer to system-memory as a fallback"); \ No newline at end of file diff --git a/shared/source/helpers/common_types.h b/shared/source/helpers/common_types.h index e9dd9ad9fe..e61fc4e564 100644 --- a/shared/source/helpers/common_types.h +++ b/shared/source/helpers/common_types.h @@ -121,6 +121,17 @@ enum class SynchronizedDispatchMode : uint32_t { limited = 2 }; +enum class LocalMemAllocationMode : uint32_t { + hwDefault = 0U, + localOnly = 1U, + localPreferred = 2U, + count = 3U +}; +constexpr inline auto toLocalMemAllocationMode(std::underlying_type_t modeFlag) { + DEBUG_BREAK_IF(modeFlag >= toUnderlying(LocalMemAllocationMode::count)); + return toEnum(modeFlag); +} + namespace InterruptId { static constexpr uint32_t notUsed = std::numeric_limits::max(); } diff --git a/shared/source/helpers/windows/product_helper_dg2_and_later_discrete.inl b/shared/source/helpers/windows/product_helper_dg2_and_later_discrete.inl new file mode 100644 index 0000000000..980f6e302b --- /dev/null +++ b/shared/source/helpers/windows/product_helper_dg2_and_later_discrete.inl @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2025 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "shared/source/debug_settings/debug_settings_manager.h" + +namespace NEO { + +template <> +bool ProductHelperHw::getStorageInfoLocalOnlyFlag(LocalMemAllocationMode usmDeviceAllocationMode, bool defaultValue) const { + switch (usmDeviceAllocationMode) { + case LocalMemAllocationMode::hwDefault: + return defaultValue; + case LocalMemAllocationMode::localOnly: + return true; + case LocalMemAllocationMode::localPreferred: + return false; + default: + UNRECOVERABLE_IF(true); + } +} +} // namespace NEO diff --git a/shared/source/memory_manager/definitions/storage_info.cpp b/shared/source/memory_manager/definitions/storage_info.cpp index 6862d61750..b37e74809c 100644 --- a/shared/source/memory_manager/definitions/storage_info.cpp +++ b/shared/source/memory_manager/definitions/storage_info.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020-2024 Intel Corporation + * Copyright (C) 2020-2025 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -29,9 +29,11 @@ StorageInfo MemoryManager::createStorageInfoFromProperties(const AllocationPrope return storageInfo; } - const auto deviceCount = GfxCoreHelper::getSubDevicesCount(executionEnvironment.rootDeviceEnvironments[properties.rootDeviceIndex]->getHardwareInfo()); + const auto *rootDeviceEnv{executionEnvironment.rootDeviceEnvironments[properties.rootDeviceIndex].get()}; + + const auto deviceCount = GfxCoreHelper::getSubDevicesCount(rootDeviceEnv->getHardwareInfo()); const auto leastOccupiedBank = getLocalMemoryUsageBankSelector(properties.allocationType, properties.rootDeviceIndex)->getLeastOccupiedBank(properties.subDevicesBitfield); - const auto subDevicesMask = executionEnvironment.rootDeviceEnvironments[properties.rootDeviceIndex]->deviceAffinityMask.getGenericSubDevicesMask().to_ulong(); + const auto subDevicesMask = rootDeviceEnv->deviceAffinityMask.getGenericSubDevicesMask().to_ulong(); const DeviceBitfield allTilesValue(properties.subDevicesBitfield.count() == 1 ? maxNBitValue(deviceCount) & subDevicesMask : properties.subDevicesBitfield); DeviceBitfield preferredTile; @@ -50,7 +52,6 @@ StorageInfo MemoryManager::createStorageInfoFromProperties(const AllocationPrope AppResourceHelper::copyResourceTagStr(storageInfo.resourceTag, properties.allocationType, sizeof(storageInfo.resourceTag)); - auto releaseHelper = executionEnvironment.rootDeviceEnvironments[properties.rootDeviceIndex]->getReleaseHelper(); switch (properties.allocationType) { case AllocationType::constantSurface: case AllocationType::kernelIsa: @@ -128,9 +129,6 @@ StorageInfo MemoryManager::createStorageInfoFromProperties(const AllocationPrope storageInfo.colouringPolicy = colouringPolicy; storageInfo.colouringGranularity = granularity; } - if (!releaseHelper || releaseHelper->isLocalOnlyAllowed()) { - storageInfo.localOnlyRequired = true; - } if (properties.flags.shareable) { storageInfo.isLockable = false; @@ -140,9 +138,12 @@ StorageInfo MemoryManager::createStorageInfoFromProperties(const AllocationPrope default: break; } - if (properties.flags.preferCompressed && (!releaseHelper || releaseHelper->isLocalOnlyAllowed())) { - storageInfo.localOnlyRequired = true; - } + + storageInfo.localOnlyRequired = getLocalOnlyRequired(properties.allocationType, + rootDeviceEnv->getProductHelper(), + rootDeviceEnv->getReleaseHelper(), + properties.flags.preferCompressed); + if (debugManager.flags.ForceMultiTileAllocPlacement.get()) { UNRECOVERABLE_IF(properties.allocationType == AllocationType::unknown); if ((1llu << (static_cast(properties.allocationType) - 1)) & debugManager.flags.ForceMultiTileAllocPlacement.get()) { diff --git a/shared/source/memory_manager/memory_manager.cpp b/shared/source/memory_manager/memory_manager.cpp index 2d314c5a6d..10b95d4061 100644 --- a/shared/source/memory_manager/memory_manager.cpp +++ b/shared/source/memory_manager/memory_manager.cpp @@ -42,6 +42,7 @@ #include "shared/source/os_interface/os_interface.h" #include "shared/source/os_interface/product_helper.h" #include "shared/source/page_fault_manager/cpu_page_fault_manager.h" +#include "shared/source/release_helper/release_helper.h" #include "shared/source/utilities/logger_neo_only.h" namespace NEO { @@ -653,11 +654,12 @@ bool MemoryManager::getAllocationData(AllocationData &allocationData, const Allo case AllocationType::svmGpu: case AllocationType::image: if (false == allocationData.flags.uncacheable && useLocalPreferredForCacheableBuffers) { - if (!allocationData.flags.preferCompressed) { + if ((usmDeviceAllocationMode == LocalMemAllocationMode::hwDefault) && !allocationData.flags.preferCompressed) { allocationData.storageInfo.localOnlyRequired = false; } allocationData.storageInfo.systemMemoryPlacement = false; } + break; default: break; } @@ -1250,4 +1252,12 @@ void MemoryManager::removeCustomHeapAllocatorConfig(AllocationType allocationTyp customHeapAllocators.erase({allocationType, isFrontWindowPool}); } +bool MemoryManager::getLocalOnlyRequired(AllocationType allocationType, const ProductHelper &productHelper, const ReleaseHelper *releaseHelper, bool preferCompressed) const { + const bool enabledForRelease{!releaseHelper || releaseHelper->isLocalOnlyAllowed()}; + + if (allocationType == AllocationType::buffer || allocationType == AllocationType::svmGpu) { + return productHelper.getStorageInfoLocalOnlyFlag(usmDeviceAllocationMode, enabledForRelease); + } + return (preferCompressed ? enabledForRelease : false); +} } // namespace NEO diff --git a/shared/source/memory_manager/memory_manager.h b/shared/source/memory_manager/memory_manager.h index 84bb15c0ac..c0155d567a 100644 --- a/shared/source/memory_manager/memory_manager.h +++ b/shared/source/memory_manager/memory_manager.h @@ -6,6 +6,7 @@ */ #pragma once +#include "shared/source/helpers/common_types.h" #include "shared/source/helpers/constants.h" #include "shared/source/helpers/engine_control.h" #include "shared/source/helpers/heap_assigner.h" @@ -46,6 +47,7 @@ class HostPtrManager; class OsContext; class PrefetchManager; class HeapAllocator; +class ReleaseHelper; enum AllocationUsage { TEMPORARY_ALLOCATION, @@ -342,6 +344,8 @@ class MemoryManager { void initUsmReuseLimits(); UsmReuseInfo usmReuseInfo; + LocalMemAllocationMode usmDeviceAllocationMode = LocalMemAllocationMode::hwDefault; + bool isLocalOnlyAllocationMode() const { return usmDeviceAllocationMode == LocalMemAllocationMode::localOnly; } bool shouldLimitAllocationsReuse() const { return getUsedSystemMemorySize() >= usmReuseInfo.getLimitAllocationsReuseThreshold(); @@ -387,6 +391,7 @@ class MemoryManager { void zeroCpuMemoryIfRequested(const AllocationData &allocationData, void *cpuPtr, size_t size); void updateLatestContextIdForRootDevice(uint32_t rootDeviceIndex); virtual DeviceBitfield computeStorageInfoMemoryBanks(const AllocationProperties &properties, DeviceBitfield preferredBank, DeviceBitfield allBanks); + virtual bool getLocalOnlyRequired(AllocationType allocationType, const ProductHelper &productHelper, const ReleaseHelper *releaseHelper, bool preferCompressed) const; bool initialized = false; bool forceNonSvmForExternalHostPtr = false; diff --git a/shared/source/os_interface/linux/drm_memory_manager.cpp b/shared/source/os_interface/linux/drm_memory_manager.cpp index 8d1d3f6392..595a746740 100644 --- a/shared/source/os_interface/linux/drm_memory_manager.cpp +++ b/shared/source/os_interface/linux/drm_memory_manager.cpp @@ -44,6 +44,7 @@ #include "shared/source/os_interface/linux/sys_calls.h" #include "shared/source/os_interface/os_interface.h" #include "shared/source/os_interface/product_helper.h" +#include "shared/source/release_helper/release_helper.h" #include #include @@ -3098,4 +3099,14 @@ bool DrmMemoryManager::reInitDeviceSpecificGfxPartition(uint32_t rootDeviceIndex void DrmMemoryManager::releaseDeviceSpecificGfxPartition(uint32_t rootDeviceIndex) { gfxPartitions.at(rootDeviceIndex).reset(); } + +bool DrmMemoryManager::getLocalOnlyRequired(AllocationType allocationType, const ProductHelper &productHelper, const ReleaseHelper *releaseHelper, bool preferCompressed) const { + const bool enabledForRelease{!releaseHelper || releaseHelper->isLocalOnlyAllowed()}; + + if (preferCompressed || allocationType == AllocationType::buffer || allocationType == AllocationType::svmGpu) { + return enabledForRelease; + } + + return false; +} } // namespace NEO diff --git a/shared/source/os_interface/linux/drm_memory_manager.h b/shared/source/os_interface/linux/drm_memory_manager.h index 45f1d19743..28182c01d6 100644 --- a/shared/source/os_interface/linux/drm_memory_manager.h +++ b/shared/source/os_interface/linux/drm_memory_manager.h @@ -198,6 +198,7 @@ class DrmMemoryManager : public MemoryManager { bool retrieveMmapOffsetForBufferObject(uint32_t rootDeviceIndex, BufferObject &bo, uint64_t flags, uint64_t &offset); BufferObject::BOType getBOTypeFromPatIndex(uint64_t patIndex, bool isPatIndexSupported) const; void setLocalMemBanksCount(uint32_t rootDeviceIndex); + bool getLocalOnlyRequired(AllocationType allocationType, const ProductHelper &productHelper, const ReleaseHelper *releaseHelper, bool preferCompressed) const override; std::vector pinBBs; std::vector memoryForPinBBs; diff --git a/shared/source/os_interface/product_helper.h b/shared/source/os_interface/product_helper.h index 31dafae262..7c5f593613 100644 --- a/shared/source/os_interface/product_helper.h +++ b/shared/source/os_interface/product_helper.h @@ -52,6 +52,7 @@ enum class GfxMemoryAllocationMethod : uint32_t; enum class AllocationType; enum class CacheRegion : uint16_t; enum class CachePolicy : uint32_t; +enum class LocalMemAllocationMode : uint32_t; using ProductHelperCreateFunctionType = std::unique_ptr (*)(); extern ProductHelperCreateFunctionType productHelperFactory[IGFX_MAX_PRODUCT]; @@ -268,7 +269,7 @@ class ProductHelper { virtual bool isCompressionForbidden(const HardwareInfo &hwInfo) const = 0; virtual bool isExposingSubdevicesAllowed() const = 0; virtual bool useAdditionalBlitProperties() const = 0; - + virtual bool getStorageInfoLocalOnlyFlag(LocalMemAllocationMode usmDeviceAllocationMode, bool defaultValue) const = 0; virtual ~ProductHelper() = default; protected: diff --git a/shared/source/os_interface/product_helper.inl b/shared/source/os_interface/product_helper.inl index 41ccf84a4a..41715fb3a6 100644 --- a/shared/source/os_interface/product_helper.inl +++ b/shared/source/os_interface/product_helper.inl @@ -1085,4 +1085,8 @@ bool ProductHelperHw::useAdditionalBlitProperties() const { return false; } +template +bool ProductHelperHw::getStorageInfoLocalOnlyFlag(LocalMemAllocationMode usmDeviceAllocationMode, bool defaultValue) const { + return defaultValue; +} } // namespace NEO diff --git a/shared/source/os_interface/product_helper_hw.h b/shared/source/os_interface/product_helper_hw.h index 0590139709..9b7894305f 100644 --- a/shared/source/os_interface/product_helper_hw.h +++ b/shared/source/os_interface/product_helper_hw.h @@ -206,6 +206,7 @@ class ProductHelperHw : public ProductHelper { bool isCompressionForbidden(const HardwareInfo &hwInfo) const override; bool isExposingSubdevicesAllowed() const override; bool useAdditionalBlitProperties() const override; + bool getStorageInfoLocalOnlyFlag(LocalMemAllocationMode usmDeviceAllocationMode, bool defaultValue) const override; ~ProductHelperHw() override = default; diff --git a/shared/source/os_interface/windows/wddm_memory_manager.cpp b/shared/source/os_interface/windows/wddm_memory_manager.cpp index 0676c4e2e1..ab103907a0 100644 --- a/shared/source/os_interface/windows/wddm_memory_manager.cpp +++ b/shared/source/os_interface/windows/wddm_memory_manager.cpp @@ -76,6 +76,7 @@ WddmMemoryManager::WddmMemoryManager(ExecutionEnvironment &executionEnvironment) alignmentSelector.addCandidateAlignment(customAlignment, false, AlignmentSelector::anyWastage); } osMemory = OSMemory::create(); + usmDeviceAllocationMode = toLocalMemAllocationMode(debugManager.flags.NEO_LOCAL_MEMORY_ALLOCATION_MODE.get()); initialized = true; } diff --git a/shared/source/os_interface/windows/wddm_memory_operations_handler.cpp b/shared/source/os_interface/windows/wddm_memory_operations_handler.cpp index db9e79e0d6..2e5a3bb1ca 100644 --- a/shared/source/os_interface/windows/wddm_memory_operations_handler.cpp +++ b/shared/source/os_interface/windows/wddm_memory_operations_handler.cpp @@ -85,7 +85,6 @@ MemoryOperationsStatus WddmMemoryOperationsHandler::isResident(Device *device, G MemoryOperationsStatus WddmMemoryOperationsHandler::free(Device *device, GraphicsAllocation &gfxAllocation) { if (gfxAllocation.isExplicitlyMadeResident()) { - WddmAllocation &wddmAllocation = reinterpret_cast(gfxAllocation); if (wddmAllocation.fragmentsStorage.fragmentCount > 0) { diff --git a/shared/source/xe2_hpg_core/windows/product_helper_bmg.cpp b/shared/source/xe2_hpg_core/windows/product_helper_bmg.cpp index d34edc6531..6a5ba1a17e 100644 --- a/shared/source/xe2_hpg_core/windows/product_helper_bmg.cpp +++ b/shared/source/xe2_hpg_core/windows/product_helper_bmg.cpp @@ -11,6 +11,7 @@ constexpr static auto gfxProduct = IGFX_BMG; +#include "shared/source/helpers/windows/product_helper_dg2_and_later_discrete.inl" #include "shared/source/xe2_hpg_core/bmg/os_agnostic_product_helper_bmg.inl" #include "shared/source/xe2_hpg_core/os_agnostic_product_helper_xe2_hpg_core.inl" diff --git a/shared/source/xe_hpg_core/windows/product_helper_dg2.cpp b/shared/source/xe_hpg_core/windows/product_helper_dg2.cpp index 319a8edfd5..f69916d8d8 100644 --- a/shared/source/xe_hpg_core/windows/product_helper_dg2.cpp +++ b/shared/source/xe_hpg_core/windows/product_helper_dg2.cpp @@ -11,6 +11,7 @@ constexpr static auto gfxProduct = IGFX_DG2; +#include "shared/source/helpers/windows/product_helper_dg2_and_later_discrete.inl" #include "shared/source/xe_hpg_core/dg2/os_agnostic_product_helper_dg2.inl" #include "shared/source/xe_hpg_core/os_agnostic_product_helper_xe_hpg_core.inl" diff --git a/shared/test/common/mocks/linux/mock_drm_memory_manager.h b/shared/test/common/mocks/linux/mock_drm_memory_manager.h index ede6a9789b..43390c51bd 100644 --- a/shared/test/common/mocks/linux/mock_drm_memory_manager.h +++ b/shared/test/common/mocks/linux/mock_drm_memory_manager.h @@ -58,6 +58,7 @@ class TestedDrmMemoryManager : public MemoryManagerCreate { using DrmMemoryManager::getBOTypeFromPatIndex; using DrmMemoryManager::getDefaultDrmContextId; using DrmMemoryManager::getDrm; + using DrmMemoryManager::getLocalOnlyRequired; using DrmMemoryManager::getRootDeviceIndex; using DrmMemoryManager::getUserptrAlignment; using DrmMemoryManager::gfxPartitions; diff --git a/shared/test/common/mocks/mock_memory_manager.cpp b/shared/test/common/mocks/mock_memory_manager.cpp index bef20e86ac..0bf1baefdb 100644 --- a/shared/test/common/mocks/mock_memory_manager.cpp +++ b/shared/test/common/mocks/mock_memory_manager.cpp @@ -94,7 +94,12 @@ GraphicsAllocation *MockMemoryManager::allocateGraphicsMemoryWithProperties(cons validateAllocateProperties(properties); lastAllocationProperties.reset(new AllocationProperties(properties)); if (returnFakeAllocation) { - return new GraphicsAllocation(properties.rootDeviceIndex, 1u /*num gmms*/, properties.allocationType, const_cast(ptr), dummyAddress, properties.size, 0, MemoryPool::system4KBPages, maxOsContextCount); + auto *allocation{new GraphicsAllocation(properties.rootDeviceIndex, 1u /*num gmms*/, properties.allocationType, const_cast(ptr), dummyAddress, properties.size, 0, MemoryPool::system4KBPages, maxOsContextCount)}; + + AllocationData allocationData; + getAllocationData(allocationData, properties, const_cast(ptr), createStorageInfoFromProperties(properties)); + allocation->storageInfo = allocationData.storageInfo; + return allocation; } if (isMockHostMemoryManager) { allocateGraphicsMemoryWithPropertiesCount++; diff --git a/shared/test/common/mocks/mock_memory_manager.h b/shared/test/common/mocks/mock_memory_manager.h index 582332bed2..7f3d31cccd 100644 --- a/shared/test/common/mocks/mock_memory_manager.h +++ b/shared/test/common/mocks/mock_memory_manager.h @@ -39,6 +39,7 @@ class MockMemoryManager : public MemoryManagerCreate { using MemoryManager::defaultEngineIndex; using MemoryManager::externalLocalMemoryUsageBankSelector; using MemoryManager::getAllocationData; + using MemoryManager::getLocalOnlyRequired; using MemoryManager::gfxPartitions; using MemoryManager::internalLocalMemoryUsageBankSelector; using MemoryManager::isNonSvmBuffer; diff --git a/shared/test/common/mocks/mock_product_helper.h b/shared/test/common/mocks/mock_product_helper.h index 249e22a545..00c682916e 100644 --- a/shared/test/common/mocks/mock_product_helper.h +++ b/shared/test/common/mocks/mock_product_helper.h @@ -12,6 +12,8 @@ namespace NEO { +enum class LocalMemAllocationMode : uint32_t; + struct MockProductHelper : ProductHelperHw { using ProductHelper::setupPreemptionSurfaceSize; MockProductHelper() = default; @@ -27,5 +29,6 @@ struct MockProductHelper : ProductHelperHw { ADDMETHOD_CONST_NOBASE(isDeviceUsmPoolAllocatorSupported, bool, false, ()); ADDMETHOD_CONST_NOBASE(is2MBLocalMemAlignmentEnabled, bool, false, ()); ADDMETHOD_CONST_NOBASE(isDisableScratchPagesRequiredForDebugger, bool, true, ()); + ADDMETHOD_CONST_NOBASE(getStorageInfoLocalOnlyFlag, bool, false, (LocalMemAllocationMode, bool)); }; } // namespace NEO diff --git a/shared/test/common/mocks/mock_svm_manager.h b/shared/test/common/mocks/mock_svm_manager.h index b55bdff51b..c2f44c9a65 100644 --- a/shared/test/common/mocks/mock_svm_manager.h +++ b/shared/test/common/mocks/mock_svm_manager.h @@ -15,6 +15,7 @@ namespace NEO { struct MockSVMAllocsManager : public SVMAllocsManager { public: + using SVMAllocsManager::insertSVMAlloc; using SVMAllocsManager::memoryManager; using SVMAllocsManager::mtxForIndirectAccess; using SVMAllocsManager::svmAllocs; @@ -32,9 +33,14 @@ struct MockSVMAllocsManager : public SVMAllocsManager { void *createUnifiedMemoryAllocation(size_t size, const UnifiedMemoryProperties &memoryProperties) override { requestedZeroedOutAllocation = memoryProperties.isInternalAllocation; - return SVMAllocsManager::createUnifiedMemoryAllocation(size, memoryProperties); + if (createUnifiedMemoryAllocationCallBase) { + return SVMAllocsManager::createUnifiedMemoryAllocation(size, memoryProperties); + } + return createUnifiedMemoryAllocationReturnValue; } bool requestedZeroedOutAllocation = false; + bool createUnifiedMemoryAllocationCallBase = true; + void *createUnifiedMemoryAllocationReturnValue = nullptr; }; template diff --git a/shared/test/common/test_files/igdrcl.config b/shared/test/common/test_files/igdrcl.config index 5368410d66..cc213f75a4 100644 --- a/shared/test/common/test_files/igdrcl.config +++ b/shared/test/common/test_files/igdrcl.config @@ -15,6 +15,7 @@ ZE_AFFINITY_MASK = default ZEX_NUMBER_OF_CCS = default ZE_ENABLE_PCI_ID_DEVICE_ORDER = 0 NEO_CAL_ENABLED = 0 +NEO_LOCAL_MEMORY_ALLOCATION_MODE = 0 AUBDumpFilterNamedKernelStartIdx = 0 AUBDumpFilterNamedKernelEndIdx = -1 AUBDumpSubCaptureMode = 0 diff --git a/shared/test/unit_test/memory_manager/memory_manager_tests.cpp b/shared/test/unit_test/memory_manager/memory_manager_tests.cpp index 552a89fdaa..62976b5042 100644 --- a/shared/test/unit_test/memory_manager/memory_manager_tests.cpp +++ b/shared/test/unit_test/memory_manager/memory_manager_tests.cpp @@ -3167,6 +3167,30 @@ HWTEST_F(MemoryAllocatorTest, givenUseLocalPreferredForCacheableBuffersAndCompre } } +HWTEST_F(MemoryAllocatorTest, givenNonDefaultLocalMemoryAllocationModeAndLocalPreferredForCacheableBuffersWhenGettingAllocDataForDeviceUsmThenLocalOnlyRequiredIsNotOverriden) { + DebugManagerStateRestore restorer; + debugManager.flags.UseLocalPreferredForCacheableBuffers.set(1); + + AllocationProperties properties(mockRootDeviceIndex, 1, AllocationType::buffer, mockDeviceBitfield); + properties.flags.uncacheable = false; + + MockMemoryManager mockMemoryManager; + auto releaseHelper = std::make_unique(); + mockMemoryManager.executionEnvironment.rootDeviceEnvironments[properties.rootDeviceIndex]->releaseHelper.reset(releaseHelper.get()); + + for (const auto debugKeyValue : std::to_array({1, 2})) { + mockMemoryManager.usmDeviceAllocationMode = toLocalMemAllocationMode(debugKeyValue); + releaseHelper->isLocalOnlyAllowedResult = (debugKeyValue == 1); + auto storageInfo{mockMemoryManager.createStorageInfoFromProperties(properties)}; + bool expectedValue{storageInfo.localOnlyRequired}; + + AllocationData allocData; + mockMemoryManager.getAllocationData(allocData, properties, nullptr, storageInfo); + EXPECT_EQ(expectedValue, allocData.storageInfo.localOnlyRequired); + } + releaseHelper.release(); +} + TEST(MemoryTransferHelperTest, WhenBlitterIsSelectedButBlitCopyFailsThenFallbackToCopyOnCPU) { constexpr uint32_t dataSize = 16; uint8_t destData[dataSize] = {}; diff --git a/shared/test/unit_test/memory_manager/storage_info_tests.cpp b/shared/test/unit_test/memory_manager/storage_info_tests.cpp index eb4835305b..2ca0597d71 100644 --- a/shared/test/unit_test/memory_manager/storage_info_tests.cpp +++ b/shared/test/unit_test/memory_manager/storage_info_tests.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021-2024 Intel Corporation + * Copyright (C) 2021-2025 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -18,6 +18,7 @@ #include "shared/test/common/mocks/mock_device.h" #include "shared/test/common/mocks/mock_graphics_allocation.h" #include "shared/test/common/mocks/mock_memory_manager.h" +#include "shared/test/common/mocks/mock_product_helper.h" #include "shared/test/common/mocks/mock_release_helper.h" #include "shared/test/common/mocks/ult_device_factory.h" #include "shared/test/common/test_macros/hw_test.h" @@ -746,3 +747,51 @@ TEST_F(MultiDeviceStorageInfoTest, givenDirectSubmissionForceLocalMemoryStorageE } } } + +TEST_F(MultiDeviceStorageInfoTest, givenBufferOrSvmGpuAllocationWhenLocalOnlyFlagValueComputedThenProductHelperIsUsed) { + constexpr bool preferCompressed{false}; + MockProductHelper productHelper{}; + MockReleaseHelper mockReleaseHelper{}; + + EXPECT_EQ(0U, productHelper.getStorageInfoLocalOnlyFlagCalled); + + const auto isEnabledForRelease{[](ReleaseHelper *releaseHelper) { return (!releaseHelper || releaseHelper->isLocalOnlyAllowed()); }}; + + for (const auto allocationType : std::array{AllocationType::buffer, AllocationType::svmGpu}) { + productHelper.getStorageInfoLocalOnlyFlagResult = isEnabledForRelease(nullptr); + EXPECT_EQ(memoryManager->getLocalOnlyRequired(allocationType, productHelper, nullptr, preferCompressed), + productHelper.getStorageInfoLocalOnlyFlagResult); + + for (const bool allowed : std::array{false, true}) { + mockReleaseHelper.isLocalOnlyAllowedResult = allowed; + productHelper.getStorageInfoLocalOnlyFlagResult = isEnabledForRelease(&mockReleaseHelper); + EXPECT_EQ(memoryManager->getLocalOnlyRequired(allocationType, productHelper, &mockReleaseHelper, preferCompressed), + productHelper.getStorageInfoLocalOnlyFlagResult); + } + } + EXPECT_EQ(6U, productHelper.getStorageInfoLocalOnlyFlagCalled); +} + +TEST_F(MultiDeviceStorageInfoTest, givenNeitherBufferNorSvmGpuAllocationWhenLocalOnlyFlagValueComputedThenProductHelperIsNotUsed) { + MockProductHelper productHelper{}; + MockReleaseHelper mockReleaseHelper{}; + + EXPECT_EQ(0U, productHelper.getStorageInfoLocalOnlyFlagCalled); + + const auto allocationType{AllocationType::unknown}; + + bool preferCompressed{true}; + for (const bool allowed : std::array{false, true}) { + mockReleaseHelper.isLocalOnlyAllowedResult = allowed; + EXPECT_EQ(memoryManager->getLocalOnlyRequired(allocationType, productHelper, &mockReleaseHelper, preferCompressed), + mockReleaseHelper.isLocalOnlyAllowedResult); + } + + preferCompressed = false; + for (const bool allowed : std::array{false, true}) { + mockReleaseHelper.isLocalOnlyAllowedResult = allowed; + EXPECT_EQ(memoryManager->getLocalOnlyRequired(allocationType, productHelper, &mockReleaseHelper, preferCompressed), + false); + } + EXPECT_EQ(0U, productHelper.getStorageInfoLocalOnlyFlagCalled); +} diff --git a/shared/test/unit_test/os_interface/linux/drm_memory_manager_tests.cpp b/shared/test/unit_test/os_interface/linux/drm_memory_manager_tests.cpp index ea282b5a8c..43e12a69cb 100644 --- a/shared/test/unit_test/os_interface/linux/drm_memory_manager_tests.cpp +++ b/shared/test/unit_test/os_interface/linux/drm_memory_manager_tests.cpp @@ -18,6 +18,7 @@ #include "shared/source/os_interface/linux/drm_memory_operations_handler_bind.h" #include "shared/source/os_interface/linux/i915.h" #include "shared/source/os_interface/linux/os_context_linux.h" +#include "shared/source/release_helper/release_helper.h" #include "shared/test/common/helpers/engine_descriptor_helper.h" #include "shared/test/common/helpers/gtest_helpers.h" #include "shared/test/common/mocks/linux/mock_drm_allocation.h" @@ -33,6 +34,7 @@ #include "shared/test/common/mocks/mock_gmm_resource_info.h" #include "shared/test/common/mocks/mock_host_ptr_manager.h" #include "shared/test/common/mocks/mock_product_helper.h" +// #include "shared/test/common/mocks/mock_release_helper.h" #include "shared/test/common/os_interface/linux/drm_memory_manager_fixture.h" #include "shared/test/common/os_interface/linux/drm_mock_cache_info.h" #include "shared/test/common/os_interface/linux/drm_mock_memory_info.h" @@ -5664,6 +5666,17 @@ TEST(DrmMemoryManagerSimpleTest, WhenDrmIsCreatedThenQueryPageFaultSupportIsCall using DrmMemoryManagerWithLocalMemoryTest = Test; +HWTEST_TEMPLATED_F(DrmMemoryManagerWithLocalMemoryTest, givenDrmMemoryManagerWithoutLocalMemoryWhenPreferCompressedIsSetThenLocalOnlyRequriedDeterminedByReleaseHelper) { + TestedDrmMemoryManager memoryManager(false, false, false, *executionEnvironment); + + AllocationProperties properties{1, true, 4096, AllocationType::unknown, false, 0b10}; + properties.flags.preferCompressed = true; + auto storageInfo = memoryManager.createStorageInfoFromProperties(properties); + + const auto *releaseHelper{executionEnvironment->rootDeviceEnvironments[0]->getReleaseHelper()}; + EXPECT_EQ(storageInfo.localOnlyRequired, (!releaseHelper || releaseHelper->isLocalOnlyAllowed())); +} + HWTEST_TEMPLATED_F(DrmMemoryManagerWithLocalMemoryTest, givenDrmMemoryManagerWithLocalMemoryWhenLockResourceIsCalledOnAllocationInLocalMemoryThenReturnNullPtr) { DrmAllocation drmAllocation(rootDeviceIndex, 1u /*num gmms*/, AllocationType::unknown, nullptr, nullptr, 0u, 0u, MemoryPool::localMemory); @@ -8998,4 +9011,17 @@ HWTEST_TEMPLATED_F(DrmMemoryManagerTest, givenGfxPartitionWhenReleasedAndReiniti EXPECT_EQ(heapExternalDeviceFrontWindow, heapExternalDeviceFrontWindow2); EXPECT_EQ(heapInternalFrontWindow, heapInternalFrontWindow2); EXPECT_EQ(heapInternalDeviceFrontWindow, heapInternalDeviceFrontWindow2); -} \ No newline at end of file +} + +HWTEST_TEMPLATED_F(DrmMemoryManagerTest, givenDeviceUsmAllocationWhenLocalOnlyFlagValueComputedThenProductHelperIsNotUsed) { + constexpr bool preferCompressed{false}; + MockProductHelper productHelper{}; + + EXPECT_EQ(0U, productHelper.getStorageInfoLocalOnlyFlagCalled); + + productHelper.getStorageInfoLocalOnlyFlagResult = false; + EXPECT_EQ(memoryManager->getLocalOnlyRequired(AllocationType::buffer, productHelper, nullptr, preferCompressed), true); + EXPECT_EQ(memoryManager->getLocalOnlyRequired(AllocationType::svmGpu, productHelper, nullptr, preferCompressed), true); + + EXPECT_EQ(0U, productHelper.getStorageInfoLocalOnlyFlagCalled); +} diff --git a/shared/test/unit_test/os_interface/windows/product_helper_win_tests.cpp b/shared/test/unit_test/os_interface/windows/product_helper_win_tests.cpp index 701727056d..c884b711d1 100644 --- a/shared/test/unit_test/os_interface/windows/product_helper_win_tests.cpp +++ b/shared/test/unit_test/os_interface/windows/product_helper_win_tests.cpp @@ -12,6 +12,7 @@ #include "shared/source/os_interface/os_interface.h" #include "shared/source/os_interface/product_helper.h" #include "shared/source/os_interface/windows/wddm/wddm.h" +#include "shared/test/common/helpers/debug_manager_state_restore.h" #include "shared/test/common/mocks/mock_execution_environment.h" #include "shared/test/common/test_macros/hw_test.h" @@ -116,4 +117,27 @@ HWTEST2_F(ProductHelperTestWindows, givenE2ECompressionWhenConfiguringHwInfoWddm EXPECT_FALSE(outHwInfo.capabilityTable.ftrRenderCompressedImages); } +HWTEST_F(ProductHelperTestWindows, givenProductFamilyWhenLocalMemAllocationModeSupportedThenLocalOnlyFlagIsSetAccordingly) { + DebugManagerStateRestore restore; + EXPECT_EQ(0, debugManager.flags.NEO_LOCAL_MEMORY_ALLOCATION_MODE.get()); + + const auto productFamily{defaultHwInfo->platform.eProductFamily}; + const bool isLocalMemModeKeySupported{productFamily == IGFX_DG2 || productFamily == IGFX_BMG}; + + EXPECT_TRUE(productHelper->getStorageInfoLocalOnlyFlag(LocalMemAllocationMode::hwDefault, true)); + EXPECT_FALSE(productHelper->getStorageInfoLocalOnlyFlag(LocalMemAllocationMode::hwDefault, false)); + + if (isLocalMemModeKeySupported) { + EXPECT_TRUE(productHelper->getStorageInfoLocalOnlyFlag(LocalMemAllocationMode::localOnly, true)); + EXPECT_TRUE(productHelper->getStorageInfoLocalOnlyFlag(LocalMemAllocationMode::localOnly, false)); + EXPECT_FALSE(productHelper->getStorageInfoLocalOnlyFlag(LocalMemAllocationMode::localPreferred, true)); + EXPECT_FALSE(productHelper->getStorageInfoLocalOnlyFlag(LocalMemAllocationMode::localPreferred, false)); + } else { + EXPECT_TRUE(productHelper->getStorageInfoLocalOnlyFlag(LocalMemAllocationMode::localOnly, true)); + EXPECT_FALSE(productHelper->getStorageInfoLocalOnlyFlag(LocalMemAllocationMode::localOnly, false)); + EXPECT_TRUE(productHelper->getStorageInfoLocalOnlyFlag(LocalMemAllocationMode::localPreferred, true)); + EXPECT_FALSE(productHelper->getStorageInfoLocalOnlyFlag(LocalMemAllocationMode::localPreferred, false)); + } +} + } // namespace NEO diff --git a/shared/test/unit_test/os_interface/windows/wddm_memory_manager_tests.cpp b/shared/test/unit_test/os_interface/windows/wddm_memory_manager_tests.cpp index b5c13e58bf..8b943dc225 100644 --- a/shared/test/unit_test/os_interface/windows/wddm_memory_manager_tests.cpp +++ b/shared/test/unit_test/os_interface/windows/wddm_memory_manager_tests.cpp @@ -107,6 +107,16 @@ class WddmMemoryManagerTests : public ::testing::Test { } }; +TEST_F(WddmMemoryManagerTests, GivenLocalMemoryAllocationModeReleaseKeyWhenWddmMemoryManagerConstructedThenUsmDeviceAllocationModeProperlySet) { + DebugManagerStateRestore restorer; + + for (const int32_t releaseKeyVal : std::array{0, 1, 2}) { + debugManager.flags.NEO_LOCAL_MEMORY_ALLOCATION_MODE.set(releaseKeyVal); + WddmMemoryManager memoryManager{*executionEnvironment}; + EXPECT_EQ(memoryManager.usmDeviceAllocationMode, toLocalMemAllocationMode(releaseKeyVal)); + } +} + TEST_F(WddmMemoryManagerTests, GivenAllocDataWithSVMCPUSetWhenAllocateGraphicsMemoryWithAlignmentThenProperFunctionIsUsed) { AllocationProperties allocationProperties{0u, 0u, NEO::AllocationType::svmCpu, {}}; NEO::AllocationData allocData = {};