Files
compute-runtime/shared/source/utilities/isa_pool_allocator.cpp
Fabian Zwoliński bf20ae7ae8 fix: configure ISA Pool params based on productHelper
When is2MBLocalMemAlignmentEnabled returns true,
increase pool size for builtins from 64k to 2MB.

Additionally, set appropriate alignment for kernel ISA heap allocations.
Additionally, configure isaAllocationPageSize based on productHelper

Related-To: NEO-12287
Signed-off-by: Fabian Zwoliński <fabian.zwolinski@intel.com>
2025-02-20 08:42:35 +01:00

154 lines
5.6 KiB
C++

/*
* Copyright (C) 2024-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/utilities/isa_pool_allocator.h"
#include "shared/source/device/device.h"
#include "shared/source/helpers/aligned_memory.h"
#include "shared/source/memory_manager/allocation_properties.h"
#include "shared/source/memory_manager/memory_manager.h"
#include "shared/source/utilities/buffer_pool_allocator.inl"
namespace NEO {
ISAPool::ISAPool(Device *device, bool isBuiltin, size_t storageSize)
: BaseType(device->getMemoryManager(), nullptr), device(device), isBuiltin(isBuiltin) {
DEBUG_BREAK_IF(device->getProductHelper().is2MBLocalMemAlignmentEnabled() &&
!isAligned(storageSize, MemoryConstants::pageSize2M));
this->chunkAllocator.reset(new NEO::HeapAllocator(params.startingOffset, storageSize, MemoryConstants::pageSize, 0u));
auto allocationType = isBuiltin ? NEO::AllocationType::kernelIsaInternal : NEO::AllocationType::kernelIsa;
auto graphicsAllocation = memoryManager->allocateGraphicsMemoryWithProperties({device->getRootDeviceIndex(),
storageSize,
allocationType,
device->getDeviceBitfield()});
this->mainStorage.reset(graphicsAllocation);
this->mtx = std::make_unique<std::mutex>();
this->stackVec.push_back(graphicsAllocation);
}
ISAPool::ISAPool(ISAPool &&pool) : BaseType(std::move(pool)) {
this->isBuiltin = pool.isBuiltin;
mtx.reset(pool.mtx.release());
this->stackVec = std::move(pool.stackVec);
this->device = pool.device;
}
ISAPool::~ISAPool() {
if (mainStorage) {
device->getMemoryManager()->freeGraphicsMemory(mainStorage.release());
}
}
SharedIsaAllocation *ISAPool::allocateISA(size_t requestedSize) const {
auto offset = static_cast<size_t>(this->chunkAllocator->allocate(requestedSize));
if (offset == 0) {
return nullptr;
}
return new SharedIsaAllocation{this->mainStorage.get(), offset - params.startingOffset, requestedSize, mtx.get()};
}
const StackVec<NEO::GraphicsAllocation *, 1> &ISAPool::getAllocationsVector() {
return stackVec;
}
ISAPoolAllocator::ISAPoolAllocator(Device *device) : device(device) {
initAllocParams();
}
/**
* @brief This method allocates SharedIsaAllocation object for a single user (module or program).
* In first step, it checks if requested size for the ISA is higher than default pool size
* and creates new ISA pool if it is.
* Next, it tries to allocate using existing pools.
* If failed, all existing pools are drained and performs allocation again.
* If failed, creates another ISA pool and tries to allocate again.
*
* @param[in] isBuiltin flag specifying whether ISA will be used for builtin kernels
* @param[in] size size requested by the client.
*
* @return returns SharedIsaAllocation or nullptr if allocation didn't succeeded
*/
SharedIsaAllocation *ISAPoolAllocator::requestGraphicsAllocationForIsa(bool isBuiltin, size_t size) {
std::unique_lock lock(allocatorMtx);
auto maxAllocationSize = getAllocationSize(isBuiltin);
if (size > maxAllocationSize) {
addNewBufferPool(ISAPool(device, isBuiltin, alignToPoolSize(size)));
}
auto sharedIsaAllocation = tryAllocateISA(isBuiltin, size);
if (sharedIsaAllocation) {
return sharedIsaAllocation;
}
drain();
sharedIsaAllocation = tryAllocateISA(isBuiltin, size);
if (sharedIsaAllocation) {
return sharedIsaAllocation;
}
addNewBufferPool(ISAPool(device, isBuiltin, alignToPoolSize(getAllocationSize(isBuiltin))));
return tryAllocateISA(isBuiltin, size);
}
/**
* @brief This method releases SharedIsaAllocation.
*
* @param[in] sharedIsaAllocation SharedIsaAllocation to free.
*
* @note actual chunk is not released immediately, it's freed during drain call.
*/
void ISAPoolAllocator::freeSharedIsaAllocation(SharedIsaAllocation *sharedIsaAllocation) {
std::unique_lock lock(allocatorMtx);
tryFreeFromPoolBuffer(sharedIsaAllocation->getGraphicsAllocation(), sharedIsaAllocation->getOffset(), sharedIsaAllocation->getSize());
delete sharedIsaAllocation;
}
/**
* @brief This method iterates over existing pools and tries to allocate shared isa allocation
* on one of them. It will use only pools with correct isa type.
*
* @param[in] isBuiltin flag specifying whether ISA will be used for builtin kernels
* @param[in] size size requested by the user.
*
* @return returns SharedIsaAllocation or nullptr if allocation didn't succeeded
*/
SharedIsaAllocation *ISAPoolAllocator::tryAllocateISA(bool isBuiltin, size_t size) {
for (auto &isaPoolParent : this->bufferPools) {
auto &isaPool = static_cast<ISAPool &>(isaPoolParent);
if (isaPool.isBuiltinPool() == isBuiltin) {
auto sharedIsaAllocation = isaPool.allocateISA(size);
if (sharedIsaAllocation != nullptr) {
return sharedIsaAllocation;
}
}
}
return nullptr;
}
void ISAPoolAllocator::initAllocParams() {
if (device->getProductHelper().is2MBLocalMemAlignmentEnabled()) {
userAllocationSize = MemoryConstants::pageSize2M * 2;
buitinAllocationSize = MemoryConstants::pageSize2M;
poolAlignment = MemoryConstants::pageSize2M;
} else {
userAllocationSize = MemoryConstants::pageSize2M * 2;
buitinAllocationSize = MemoryConstants::pageSize64k;
}
}
size_t ISAPoolAllocator::alignToPoolSize(size_t size) const {
return alignUp(size, poolAlignment);
}
} // namespace NEO