2020-01-11 18:25:26 +01:00
|
|
|
/*
|
2025-08-18 15:15:55 +00:00
|
|
|
* Copyright (C) 2020-2025 Intel Corporation
|
2020-01-11 18:25:26 +01:00
|
|
|
*
|
|
|
|
|
* SPDX-License-Identifier: MIT
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "program_initialization.h"
|
|
|
|
|
|
2025-09-19 14:53:48 +00:00
|
|
|
#include "shared/source/command_stream/command_stream_receiver.h"
|
2020-02-23 22:44:01 +01:00
|
|
|
#include "shared/source/compiler_interface/linker.h"
|
|
|
|
|
#include "shared/source/device/device.h"
|
2020-07-10 17:04:42 +02:00
|
|
|
#include "shared/source/helpers/blit_commands_helper.h"
|
2023-02-01 16:23:01 +00:00
|
|
|
#include "shared/source/helpers/gfx_core_helper.h"
|
2020-02-23 22:44:01 +01:00
|
|
|
#include "shared/source/helpers/string.h"
|
2022-12-07 11:51:44 +00:00
|
|
|
#include "shared/source/memory_manager/allocation_properties.h"
|
2020-02-23 22:44:01 +01:00
|
|
|
#include "shared/source/memory_manager/memory_manager.h"
|
|
|
|
|
#include "shared/source/memory_manager/unified_memory_manager.h"
|
2025-08-18 15:15:55 +00:00
|
|
|
#include "shared/source/memory_manager/unified_memory_pooling.h"
|
2020-02-23 22:44:01 +01:00
|
|
|
#include "shared/source/program/program_info.h"
|
2020-01-11 18:25:26 +01:00
|
|
|
|
2025-09-19 14:53:48 +00:00
|
|
|
#include <mutex>
|
|
|
|
|
|
2020-01-11 18:25:26 +01:00
|
|
|
namespace NEO {
|
|
|
|
|
|
2025-08-18 15:15:55 +00:00
|
|
|
SharedPoolAllocation *allocateGlobalsSurface(NEO::SVMAllocsManager *const svmAllocManager, NEO::Device &device, size_t totalSize, size_t zeroInitSize, bool constant,
|
|
|
|
|
LinkerInput *const linkerInput, const void *initData) {
|
|
|
|
|
size_t allocationOffset{0u};
|
|
|
|
|
size_t allocatedSize{0u};
|
2020-01-11 18:25:26 +01:00
|
|
|
bool globalsAreExported = false;
|
2020-10-07 12:37:13 +02:00
|
|
|
GraphicsAllocation *gpuAllocation = nullptr;
|
2025-09-19 14:53:48 +00:00
|
|
|
bool isAllocatedFromPool = false;
|
|
|
|
|
std::mutex *usmAllocPoolMutex = nullptr;
|
2023-04-04 10:02:03 +00:00
|
|
|
const auto rootDeviceIndex = device.getRootDeviceIndex();
|
|
|
|
|
const auto deviceBitfield = device.getDeviceBitfield();
|
2020-10-07 12:37:13 +02:00
|
|
|
|
2020-01-11 18:25:26 +01:00
|
|
|
if (linkerInput != nullptr) {
|
|
|
|
|
globalsAreExported = constant ? linkerInput->getTraits().exportsGlobalConstants : linkerInput->getTraits().exportsGlobalVariables;
|
|
|
|
|
}
|
2023-12-11 14:24:36 +00:00
|
|
|
const auto allocationType = constant ? AllocationType::constantSurface : AllocationType::globalSurface;
|
2020-01-11 18:25:26 +01:00
|
|
|
if (globalsAreExported && (svmAllocManager != nullptr)) {
|
2022-04-07 13:09:40 +00:00
|
|
|
RootDeviceIndicesContainer rootDeviceIndices;
|
2023-06-12 13:52:45 +00:00
|
|
|
rootDeviceIndices.pushUnique(rootDeviceIndex);
|
2020-12-23 13:47:18 +00:00
|
|
|
std::map<uint32_t, DeviceBitfield> subDeviceBitfields;
|
|
|
|
|
subDeviceBitfields.insert({rootDeviceIndex, deviceBitfield});
|
2023-12-13 10:09:37 +00:00
|
|
|
NEO::SVMAllocsManager::UnifiedMemoryProperties unifiedMemoryProperties(InternalMemoryType::deviceUnifiedMemory, 1, rootDeviceIndices, subDeviceBitfields);
|
2022-09-23 13:05:43 +00:00
|
|
|
unifiedMemoryProperties.device = &device;
|
2023-04-04 10:02:03 +00:00
|
|
|
unifiedMemoryProperties.requestedAllocationType = allocationType;
|
2024-05-29 10:52:58 +00:00
|
|
|
unifiedMemoryProperties.isInternalAllocation = true;
|
2025-09-19 14:53:48 +00:00
|
|
|
|
|
|
|
|
UsmMemAllocPool *allocPool = nullptr;
|
|
|
|
|
if (allocationType == AllocationType::constantSurface) {
|
|
|
|
|
allocPool = device.getUsmConstantSurfaceAllocPool();
|
|
|
|
|
} else {
|
|
|
|
|
allocPool = device.getUsmGlobalSurfaceAllocPool();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (allocPool && device.getProductHelper().is2MBLocalMemAlignmentEnabled()) {
|
|
|
|
|
if (!allocPool->isInitialized()) {
|
|
|
|
|
constexpr size_t alignment = MemoryConstants::pageSize2M;
|
|
|
|
|
constexpr size_t poolSize = MemoryConstants::pageSize2M;
|
|
|
|
|
constexpr size_t minServicedSize = 0u;
|
|
|
|
|
constexpr size_t maxServicedSize = 2 * MemoryConstants::megaByte;
|
|
|
|
|
|
|
|
|
|
NEO::SVMAllocsManager::UnifiedMemoryProperties poolMemoryProperties(InternalMemoryType::deviceUnifiedMemory, alignment, rootDeviceIndices, subDeviceBitfields);
|
|
|
|
|
poolMemoryProperties.device = &device;
|
|
|
|
|
poolMemoryProperties.requestedAllocationType = allocationType;
|
|
|
|
|
poolMemoryProperties.isInternalAllocation = true;
|
|
|
|
|
|
|
|
|
|
allocPool->initialize(svmAllocManager, poolMemoryProperties, poolSize, minServicedSize, maxServicedSize);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (allocPool->isInitialized()) {
|
|
|
|
|
unifiedMemoryProperties.alignment = MemoryConstants::pageSize;
|
|
|
|
|
auto pooledPtr = allocPool->createUnifiedMemoryAllocation(totalSize, unifiedMemoryProperties);
|
|
|
|
|
if (pooledPtr) {
|
|
|
|
|
allocationOffset = allocPool->getOffsetInPool(pooledPtr);
|
|
|
|
|
allocatedSize = allocPool->getPooledAllocationSize(pooledPtr);
|
|
|
|
|
auto usmAlloc = svmAllocManager->getSVMAlloc(reinterpret_cast<void *>(allocPool->getPoolAddress()));
|
|
|
|
|
UNRECOVERABLE_IF(usmAlloc == nullptr);
|
|
|
|
|
gpuAllocation = usmAlloc->gpuAllocations.getGraphicsAllocation(rootDeviceIndex);
|
|
|
|
|
usmAllocPoolMutex = &allocPool->getMutex();
|
|
|
|
|
isAllocatedFromPool = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!gpuAllocation) {
|
|
|
|
|
auto ptr = svmAllocManager->createUnifiedMemoryAllocation(totalSize, unifiedMemoryProperties);
|
|
|
|
|
DEBUG_BREAK_IF(ptr == nullptr);
|
|
|
|
|
if (ptr == nullptr) {
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
auto usmAlloc = svmAllocManager->getSVMAlloc(ptr);
|
|
|
|
|
UNRECOVERABLE_IF(usmAlloc == nullptr);
|
|
|
|
|
gpuAllocation = usmAlloc->gpuAllocations.getGraphicsAllocation(rootDeviceIndex);
|
|
|
|
|
allocationOffset = 0u;
|
|
|
|
|
allocatedSize = gpuAllocation->getUnderlyingBufferSize();
|
2020-01-11 18:25:26 +01:00
|
|
|
}
|
|
|
|
|
} else {
|
2020-12-23 13:47:18 +00:00
|
|
|
gpuAllocation = device.getMemoryManager()->allocateGraphicsMemoryWithProperties({rootDeviceIndex,
|
2020-04-16 17:24:38 +02:00
|
|
|
true, // allocateMemory
|
2023-02-08 17:05:30 +00:00
|
|
|
totalSize, allocationType,
|
2020-04-16 17:24:38 +02:00
|
|
|
false, // isMultiStorageAllocation
|
2020-12-23 13:47:18 +00:00
|
|
|
deviceBitfield});
|
2025-09-19 14:53:48 +00:00
|
|
|
if (nullptr == gpuAllocation) {
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
allocationOffset = 0u;
|
|
|
|
|
allocatedSize = gpuAllocation->getUnderlyingBufferSize();
|
2020-01-11 18:25:26 +01:00
|
|
|
}
|
2020-10-07 12:37:13 +02:00
|
|
|
|
2023-01-26 16:21:09 +00:00
|
|
|
auto &rootDeviceEnvironment = device.getRootDeviceEnvironment();
|
2022-12-15 13:33:28 +00:00
|
|
|
auto &productHelper = device.getProductHelper();
|
2020-10-07 12:37:13 +02:00
|
|
|
|
2023-02-08 17:05:30 +00:00
|
|
|
bool isOnlyBssData = (totalSize == zeroInitSize);
|
|
|
|
|
if (false == isOnlyBssData) {
|
|
|
|
|
auto initSize = totalSize - zeroInitSize;
|
2023-03-31 13:25:38 +02:00
|
|
|
auto success = MemoryTransferHelper::transferMemoryToAllocation(productHelper.isBlitCopyRequiredForLocalMemory(rootDeviceEnvironment, *gpuAllocation),
|
2025-08-18 15:15:55 +00:00
|
|
|
device, gpuAllocation, allocationOffset, initData, initSize);
|
2023-02-08 17:05:30 +00:00
|
|
|
UNRECOVERABLE_IF(!success);
|
2025-09-19 14:53:48 +00:00
|
|
|
|
|
|
|
|
if (auto csr = device.getDefaultEngine().commandStreamReceiver;
|
|
|
|
|
isAllocatedFromPool && csr->getType() != NEO::CommandStreamReceiverType::hardware) {
|
|
|
|
|
auto writeMemoryOperation = [&]() {
|
|
|
|
|
constexpr uint32_t allBanks = std::numeric_limits<uint32_t>::max();
|
|
|
|
|
if (gpuAllocation->isTbxWritable(allBanks)) {
|
|
|
|
|
// initialize full page tables for the first time
|
|
|
|
|
csr->writeMemory(*gpuAllocation, false, 0, 0);
|
|
|
|
|
}
|
|
|
|
|
gpuAllocation->setTbxWritable(true, allBanks);
|
|
|
|
|
[[maybe_unused]] const auto writeMemoryStatus = csr->writeMemory(*gpuAllocation, true, allocationOffset, allocatedSize);
|
|
|
|
|
DEBUG_BREAK_IF(!writeMemoryStatus);
|
|
|
|
|
gpuAllocation->setTbxWritable(false, allBanks);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (usmAllocPoolMutex) {
|
|
|
|
|
std::lock_guard<std::mutex> lock(*usmAllocPoolMutex);
|
|
|
|
|
writeMemoryOperation();
|
|
|
|
|
} else {
|
|
|
|
|
writeMemoryOperation();
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-02-08 17:05:30 +00:00
|
|
|
}
|
2025-08-18 15:15:55 +00:00
|
|
|
return new SharedPoolAllocation(gpuAllocation, allocationOffset, allocatedSize, nullptr);
|
2020-01-11 18:25:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace NEO
|