refactor: SortedVectorBasedAllocationTracker

Move code out to base class. This will allow to use the sorted vector
class with different values than only SvmData.

Signed-off-by: Dominik Dabek <dominik.dabek@intel.com>
This commit is contained in:
Dominik Dabek 2023-12-13 11:34:50 +00:00 committed by Compute-Runtime-Automation
parent 073000f105
commit 2146cd07ee
8 changed files with 123 additions and 74 deletions

View File

@ -42,25 +42,6 @@ void SVMAllocsManager::MapBasedAllocationTracker::remove(const SvmAllocationData
allocations.erase(iter);
}
void SVMAllocsManager::SortedVectorBasedAllocationTracker::insert(const SvmAllocationData &allocationsPair) {
allocations.push_back(std::make_pair(reinterpret_cast<void *>(allocationsPair.gpuAllocations.getDefaultGraphicsAllocation()->getGpuAddress()), std::make_unique<SvmAllocationData>(allocationsPair)));
for (size_t i = allocations.size() - 1; i > 0; --i) {
if (allocations[i].first < allocations[i - 1].first) {
std::iter_swap(allocations.begin() + i, allocations.begin() + i - 1);
} else {
break;
}
}
}
void SVMAllocsManager::SortedVectorBasedAllocationTracker::remove(const SvmAllocationData &allocationsPair) {
auto gpuAddress = reinterpret_cast<void *>(allocationsPair.gpuAllocations.getDefaultGraphicsAllocation()->getGpuAddress());
auto removeIt = std::remove_if(allocations.begin(), allocations.end(), [&gpuAddress](const auto &other) {
return gpuAddress == other.first;
});
allocations.erase(removeIt);
}
void SVMAllocsManager::SvmAllocationCache::insert(size_t size, void *ptr) {
std::lock_guard<std::mutex> lock(this->mtx);
allocations.emplace(std::lower_bound(allocations.begin(), allocations.end(), size), size, ptr);
@ -132,34 +113,6 @@ SvmAllocationData *SVMAllocsManager::MapBasedAllocationTracker::get(const void *
return nullptr;
}
SvmAllocationData *SVMAllocsManager::SortedVectorBasedAllocationTracker::get(const void *ptr) {
if (allocations.size() == 0) {
return nullptr;
}
if (!ptr) {
return nullptr;
}
int begin = 0;
int end = static_cast<int>(allocations.size() - 1);
while (end >= begin) {
int currentPos = (begin + end) / 2;
const auto &allocation = allocations[currentPos];
if (allocation.first == ptr || (allocation.first < ptr &&
(reinterpret_cast<uintptr_t>(ptr) < (reinterpret_cast<uintptr_t>(allocation.first) + allocation.second->size)))) {
return allocation.second.get();
} else if (ptr < allocation.first) {
end = currentPos - 1;
continue;
} else {
begin = currentPos + 1;
continue;
}
}
return nullptr;
}
void SVMAllocsManager::MapOperationsTracker::insert(SvmMapOperation mapOperation) {
operations.insert(std::make_pair(mapOperation.regionSvmPtr, mapOperation));
}
@ -286,7 +239,7 @@ void *SVMAllocsManager::createHostUnifiedMemoryAllocation(size_t size,
allocData.setAllocId(this->allocationsCounter++);
std::unique_lock<std::shared_mutex> lock(mtx);
this->svmAllocs.insert(allocData);
this->svmAllocs.insert(usmPtr, allocData);
return usmPtr;
}
@ -368,9 +321,9 @@ void *SVMAllocsManager::createUnifiedMemoryAllocation(size_t size,
allocData.setAllocId(this->allocationsCounter++);
std::unique_lock<std::shared_mutex> lock(mtx);
this->svmAllocs.insert(allocData);
auto retPtr = reinterpret_cast<void *>(unifiedMemoryAllocation->getGpuAddress());
this->svmAllocs.insert(retPtr, allocData);
UNRECOVERABLE_IF(useExternalHostPtrForCpu && (externalPtr != retPtr));
return retPtr;
@ -455,8 +408,9 @@ void *SVMAllocsManager::createUnifiedKmdMigratedAllocation(size_t size, const Sv
allocData.setAllocId(this->allocationsCounter++);
std::unique_lock<std::shared_mutex> lock(mtx);
this->svmAllocs.insert(allocData);
return allocationGpu->getUnderlyingBuffer();
auto retPtr = allocationGpu->getUnderlyingBuffer();
this->svmAllocs.insert(retPtr, allocData);
return retPtr;
}
void SVMAllocsManager::setUnifiedAllocationProperties(GraphicsAllocation *allocation, const SvmAllocationProperties &svmProperties) {
@ -466,12 +420,12 @@ void SVMAllocsManager::setUnifiedAllocationProperties(GraphicsAllocation *alloca
void SVMAllocsManager::insertSVMAlloc(const SvmAllocationData &svmAllocData) {
std::unique_lock<std::shared_mutex> lock(mtx);
svmAllocs.insert(svmAllocData);
svmAllocs.insert(reinterpret_cast<void *>(svmAllocData.gpuAllocations.getDefaultGraphicsAllocation()->getGpuAddress()), svmAllocData);
}
void SVMAllocsManager::removeSVMAlloc(const SvmAllocationData &svmAllocData) {
std::unique_lock<std::shared_mutex> lock(mtx);
svmAllocs.remove(svmAllocData);
svmAllocs.remove(reinterpret_cast<void *>(svmAllocData.gpuAllocations.getDefaultGraphicsAllocation()->getGpuAddress()));
}
bool SVMAllocsManager::freeSVMAlloc(void *ptr, bool blocking) {
@ -608,7 +562,7 @@ void *SVMAllocsManager::createZeroCopySvmAllocation(size_t size, const SvmAlloca
allocData.size = size;
std::unique_lock<std::shared_mutex> lock(mtx);
this->svmAllocs.insert(allocData);
this->svmAllocs.insert(usmPtr, allocData);
return usmPtr;
}
@ -676,14 +630,14 @@ void *SVMAllocsManager::createUnifiedAllocationWithDeviceStorage(size_t size, co
allocData.setAllocId(this->allocationsCounter++);
std::unique_lock<std::shared_mutex> lock(mtx);
this->svmAllocs.insert(allocData);
this->svmAllocs.insert(svmPtr, allocData);
return svmPtr;
}
void SVMAllocsManager::freeSVMData(SvmAllocationData *svmData) {
std::unique_lock<std::mutex> lockForIndirect(mtxForIndirectAccess);
std::unique_lock<std::shared_mutex> lock(mtx);
svmAllocs.remove(*svmData);
svmAllocs.remove(reinterpret_cast<void *>(svmData->gpuAllocations.getDefaultGraphicsAllocation()->getGpuAddress()));
}
void SVMAllocsManager::freeZeroCopySvmAllocation(SvmAllocationData *svmData) {

View File

@ -11,6 +11,7 @@
#include "shared/source/memory_manager/multi_graphics_allocation.h"
#include "shared/source/memory_manager/residency_container.h"
#include "shared/source/unified_memory/unified_memory.h"
#include "shared/source/utilities/sorted_vector.h"
#include "memory_properties_flags.h"
@ -84,18 +85,13 @@ struct SvmMapOperation {
class SVMAllocsManager {
public:
class SortedVectorBasedAllocationTracker {
friend class SVMAllocsManager;
public:
using SvmAllocationContainer = std::vector<std::pair<const void *, std::unique_ptr<SvmAllocationData>>>;
void insert(const SvmAllocationData &);
void remove(const SvmAllocationData &);
SvmAllocationData *get(const void *);
size_t getNumAllocs() const { return allocations.size(); };
SvmAllocationContainer allocations;
struct CompareAcceptOffsetSvmPointers {
bool operator()(const std::unique_ptr<SvmAllocationData> &svmData, const void *ptr, const void *otherPtr) {
return ptr == otherPtr || (otherPtr < ptr &&
(reinterpret_cast<uintptr_t>(ptr) < (reinterpret_cast<uintptr_t>(otherPtr) + svmData->size)));
}
};
using SortedVectorBasedAllocationTracker = BaseSortedPointerWithValueVector<SvmAllocationData, CompareAcceptOffsetSvmPointers>;
class MapBasedAllocationTracker {
friend class SVMAllocsManager;

View File

@ -1,5 +1,5 @@
#
# Copyright (C) 2019-2022 Intel Corporation
# Copyright (C) 2019-2023 Intel Corporation
#
# SPDX-License-Identifier: MIT
#
@ -37,6 +37,7 @@ set(NEO_CORE_UTILITIES
${CMAKE_CURRENT_SOURCE_DIR}/software_tags.h
${CMAKE_CURRENT_SOURCE_DIR}/software_tags_manager.cpp
${CMAKE_CURRENT_SOURCE_DIR}/software_tags_manager.h
${CMAKE_CURRENT_SOURCE_DIR}/sorted_vector.h
${CMAKE_CURRENT_SOURCE_DIR}/spinlock.h
${CMAKE_CURRENT_SOURCE_DIR}/stackvec.h
${CMAKE_CURRENT_SOURCE_DIR}/tag_allocator.cpp

View File

@ -0,0 +1,75 @@
/*
* Copyright (C) 2018-2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include <algorithm>
#include <memory>
#include <vector>
namespace NEO {
template <typename ValueType, class Compare>
class BaseSortedPointerWithValueVector {
public:
using PointerPair = std::pair<const void *, std::unique_ptr<ValueType>>;
using Container = std::vector<PointerPair>;
BaseSortedPointerWithValueVector() : compareFunctor(Compare()){};
void insert(const void *ptr, const ValueType &value) {
allocations.push_back(std::make_pair(ptr, std::make_unique<ValueType>(value)));
for (size_t i = allocations.size() - 1; i > 0; --i) {
if (allocations[i].first < allocations[i - 1].first) {
std::iter_swap(allocations.begin() + i, allocations.begin() + i - 1);
} else {
break;
}
}
}
void remove(const void *ptr) {
auto removeIt = std::remove_if(allocations.begin(), allocations.end(), [&ptr](const PointerPair &other) {
return ptr == other.first;
});
allocations.erase(removeIt);
}
ValueType *get(const void *ptr) {
if (allocations.size() == 0) {
return nullptr;
}
if (nullptr == ptr) {
return nullptr;
}
int begin = 0;
int end = static_cast<int>(allocations.size() - 1);
while (end >= begin) {
int currentPos = (begin + end) / 2;
const auto &allocation = allocations[currentPos];
if (compareFunctor(allocation.second, ptr, allocation.first)) {
return allocation.second.get();
} else if (ptr < allocation.first) {
end = currentPos - 1;
continue;
} else {
begin = currentPos + 1;
continue;
}
}
return nullptr;
}
size_t getNumAllocs() const { return allocations.size(); }
Container allocations;
Compare compareFunctor;
};
} // namespace NEO

View File

@ -35,12 +35,12 @@ TEST(SortedVectorBasedAllocationTrackerTests, givenSortedVectorBasedAllocationTr
for (uint32_t i = graphicsAllocationsSize - 1; i >= graphicsAllocationsSize / 2; --i) {
data.gpuAllocations.addAllocation(&graphicsAllocations[i]);
data.device = reinterpret_cast<Device *>(graphicsAllocations[i].getGpuAddress());
tracker.insert(data);
tracker.insert(reinterpret_cast<void *>(data.gpuAllocations.getDefaultGraphicsAllocation()->getGpuAddress()), data);
}
for (uint32_t i = 0; i < graphicsAllocationsSize / 2; ++i) {
data.gpuAllocations.addAllocation(&graphicsAllocations[i]);
data.device = reinterpret_cast<Device *>(graphicsAllocations[i].getGpuAddress());
tracker.insert(data);
tracker.insert(reinterpret_cast<void *>(data.gpuAllocations.getDefaultGraphicsAllocation()->getGpuAddress()), data);
}
EXPECT_EQ(tracker.getNumAllocs(), graphicsAllocationsSize);
@ -56,7 +56,7 @@ TEST(SortedVectorBasedAllocationTrackerTests, givenSortedVectorBasedAllocationTr
MockGraphicsAllocation graphicsAlloc{reinterpret_cast<void *>(0x0), MemoryConstants::pageSize64k};
data.gpuAllocations.addAllocation(&graphicsAlloc);
data.device = reinterpret_cast<Device *>(graphicsAlloc.getGpuAddress());
tracker.insert(data);
tracker.insert(reinterpret_cast<void *>(data.gpuAllocations.getDefaultGraphicsAllocation()->getGpuAddress()), data);
EXPECT_EQ(tracker.getNumAllocs(), graphicsAllocationsSize + 1);
for (uint64_t i = 0; i < graphicsAllocationsSize + 1; ++i) {
@ -69,7 +69,7 @@ TEST(SortedVectorBasedAllocationTrackerTests, givenSortedVectorBasedAllocationTr
auto data2 = tracker.get(addr2);
EXPECT_EQ(data1->device, addr1);
EXPECT_EQ(data2->device, addr2);
tracker.remove(*data2);
tracker.remove(addr2);
EXPECT_EQ(tracker.getNumAllocs(), graphicsAllocationsSize);
for (uint64_t i = 0; i < graphicsAllocationsSize; ++i) {
if (i < 2) {

View File

@ -223,7 +223,7 @@ TEST_F(SVMLocalMemoryAllocatorTest, whenMultiplePointerWithOffsetPassedThenPrope
allocationData.memoryType = InternalMemoryType::HOST_UNIFIED_MEMORY;
allocationData.size = mockAllocation.getUnderlyingBufferSize();
allocationData.gpuAllocations.addAllocation(&mockAllocation);
svmManager->svmAllocs.insert(allocationData);
svmManager->svmAllocs.insert(unalignedPointer, allocationData);
auto offsetedPointer = ptrOffset(ptr, 2048);
auto usmAllocationData = svmManager->getSVMAlloc(offsetedPointer);
@ -234,7 +234,7 @@ TEST_F(SVMLocalMemoryAllocatorTest, whenMultiplePointerWithOffsetPassedThenPrope
usmAllocationData = svmManager->getSVMAlloc(unalignedPointer);
EXPECT_NE(nullptr, usmAllocationData);
svmManager->svmAllocs.remove(allocationData);
svmManager->svmAllocs.remove(reinterpret_cast<void *>(allocationData.gpuAllocations.getDefaultGraphicsAllocation()->getGpuAddress()));
svmManager->freeSVMAlloc(ptr, true);
svmManager->freeSVMAlloc(ptr2, true);
}

View File

@ -21,6 +21,7 @@ target_sources(neo_shared_tests PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/perf_profiler_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/reference_tracked_object_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/software_tags_manager_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/sorted_vector_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/spinlock_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/tag_allocator_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/timer_util_tests.cpp

View File

@ -0,0 +1,22 @@
/*
* Copyright (C) 2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/utilities/sorted_vector.h"
#include "gtest/gtest.h"
struct Comparator {
bool operator()(const std::unique_ptr<size_t> &svmData, const void *ptr, const void *otherPtr) {
return false;
}
};
using TestedSortedVector = NEO::BaseSortedPointerWithValueVector<size_t, Comparator>;
TEST(SortedVectorTest, givenBaseSortedVectorWhenGettingNullptrThenNullptrIsReturned) {
TestedSortedVector testedVector;
EXPECT_EQ(nullptr, testedVector.get(nullptr));
}