Remove cleaning allocation lists methods from memory manager

Change-Id: I4a58a5373e7dc4cf8dc5d90390e84c4f23689139
Signed-off-by: Mateusz Jablonski <mateusz.jablonski@intel.com>
This commit is contained in:
Mateusz Jablonski 2018-10-26 11:05:31 +00:00 committed by sys_ocldev
parent 7b1d19eaec
commit a30c70d84b
16 changed files with 263 additions and 288 deletions

View File

@ -51,10 +51,10 @@ CommandStreamReceiver::~CommandStreamReceiver() {
cleanupResources();
if (!allocationsForReuse.peekIsEmpty()) {
getMemoryManager()->freeAllocationsList(-1, allocationsForReuse);
internalAllocationStorage->freeAllocationsList(-1, allocationsForReuse);
}
if (!temporaryAllocations.peekIsEmpty()) {
getMemoryManager()->freeAllocationsList(-1, temporaryAllocations);
internalAllocationStorage->freeAllocationsList(-1, temporaryAllocations);
}
}
@ -115,7 +115,7 @@ void CommandStreamReceiver::waitForTaskCountAndCleanAllocationList(uint32_t requ
if (allocationList.peekIsEmpty()) {
return;
}
getMemoryManager()->freeAllocationsList(requiredTaskCount, allocationList);
internalAllocationStorage->freeAllocationsList(requiredTaskCount, allocationList);
}
MemoryManager *CommandStreamReceiver::getMemoryManager() const {

View File

@ -8,7 +8,7 @@
#include "public/cl_ext_private.h"
#include "runtime/command_queue/command_queue.h"
#include "runtime/command_stream/command_stream_receiver.h"
#include "runtime/memory_manager/memory_manager.h"
#include "runtime/memory_manager/internal_allocation_storage.h"
#include "runtime/context/context.h"
#include "runtime/device/device.h"
#include "runtime/event/event.h"
@ -310,8 +310,8 @@ inline bool Event::wait(bool blocking, bool useQuickKmdSleep) {
DEBUG_BREAK_IF(this->taskLevel == Event::eventNotReady && this->executionStatus >= 0);
auto *memoryManager = cmdQueue->getDevice().getMemoryManager();
memoryManager->cleanAllocationList(this->taskCount, TEMPORARY_ALLOCATION);
auto *allocationStorage = cmdQueue->getDevice().getCommandStreamReceiver().getInternalAllocationStorage();
allocationStorage->cleanAllocationList(this->taskCount, TEMPORARY_ALLOCATION);
return true;
}
@ -346,7 +346,8 @@ void Event::updateExecutionStatus() {
transitionExecutionStatus(CL_COMPLETE);
executeCallbacks(CL_COMPLETE);
unblockEventsBlockedByThis(CL_COMPLETE);
cmdQueue->getDevice().getMemoryManager()->cleanAllocationList(this->taskCount, TEMPORARY_ALLOCATION);
auto *allocationStorage = cmdQueue->getDevice().getCommandStreamReceiver().getInternalAllocationStorage();
allocationStorage->cleanAllocationList(this->taskCount, TEMPORARY_ALLOCATION);
return;
}

View File

@ -7,6 +7,7 @@
#include "runtime/command_stream/command_stream_receiver.h"
#include "runtime/memory_manager/host_ptr_manager.h"
#include "runtime/memory_manager/internal_allocation_storage.h"
#include "runtime/memory_manager/memory_manager.h"
using namespace OCLRT;
@ -282,8 +283,9 @@ RequirementsStatus HostPtrManager::checkAllocationsForOverlapping(MemoryManager
// clean temporary allocations
auto commandStreamReceiver = memoryManager.getCommandStreamReceiver(0);
auto allocationStorage = commandStreamReceiver->getInternalAllocationStorage();
uint32_t taskCount = *commandStreamReceiver->getTagAddress();
memoryManager.cleanAllocationList(taskCount, TEMPORARY_ALLOCATION);
allocationStorage->cleanAllocationList(taskCount, TEMPORARY_ALLOCATION);
// check overlapping again
checkedFragments->fragments[i] = getFragmentAndCheckForOverlaps(requirements->AllocationFragments[i].allocationPtr, requirements->AllocationFragments[i].allocationSize, checkedFragments->status[i]);
@ -294,7 +296,7 @@ RequirementsStatus HostPtrManager::checkAllocationsForOverlapping(MemoryManager
;
taskCount = *commandStreamReceiver->getTagAddress();
memoryManager.cleanAllocationList(taskCount, TEMPORARY_ALLOCATION);
allocationStorage->cleanAllocationList(taskCount, TEMPORARY_ALLOCATION);
// check overlapping last time
checkedFragments->fragments[i] = getFragmentAndCheckForOverlaps(requirements->AllocationFragments[i].allocationPtr, requirements->AllocationFragments[i].allocationSize, checkedFragments->status[i]);
@ -306,4 +308,4 @@ RequirementsStatus HostPtrManager::checkAllocationsForOverlapping(MemoryManager
}
}
return status;
}
}

View File

@ -17,14 +17,15 @@ class GraphicsAllocation;
class InternalAllocationStorage {
public:
MOCKABLE_VIRTUAL ~InternalAllocationStorage() = default;
InternalAllocationStorage(CommandStreamReceiver &commandStreamReceiver);
void cleanAllocationList(uint32_t waitTaskCount, uint32_t allocationUsage);
MOCKABLE_VIRTUAL void cleanAllocationList(uint32_t waitTaskCount, uint32_t allocationUsage);
void freeAllocationsList(uint32_t waitTaskCount, AllocationsList &allocationsList);
void storeAllocation(std::unique_ptr<GraphicsAllocation> gfxAllocation, uint32_t allocationUsage);
void storeAllocationWithTaskCount(std::unique_ptr<GraphicsAllocation> gfxAllocation, uint32_t allocationUsage, uint32_t taskCount);
std::unique_ptr<GraphicsAllocation> obtainReusableAllocation(size_t requiredSize, bool isInternalAllocationRequired);
private:
protected:
std::recursive_mutex mutex;
CommandStreamReceiver &commandStreamReceiver;
};

View File

@ -171,15 +171,6 @@ void MemoryManager::applyCommonCleanup() {
}
}
bool MemoryManager::cleanAllocationList(uint32_t waitTaskCount, uint32_t allocationUsage) {
getCommandStreamReceiver(0)->getInternalAllocationStorage()->cleanAllocationList(waitTaskCount, allocationUsage);
return false;
}
void MemoryManager::freeAllocationsList(uint32_t waitTaskCount, AllocationsList &allocationsList) {
getCommandStreamReceiver(0)->getInternalAllocationStorage()->freeAllocationsList(waitTaskCount, allocationsList);
}
TagAllocator<HwTimeStamps> *MemoryManager::getEventTsAllocator() {
if (profilingTimeStampAllocator.get() == nullptr) {
profilingTimeStampAllocator = std::make_unique<TagAllocator<HwTimeStamps>>(this, TagCount, MemoryConstants::cacheLineSize);

View File

@ -200,10 +200,6 @@ class MemoryManager {
virtual uint64_t getInternalHeapBaseAddress() = 0;
virtual bool cleanAllocationList(uint32_t waitTaskCount, uint32_t allocationUsage);
void freeAllocationsList(uint32_t waitTaskCount, AllocationsList &allocationsList);
TagAllocator<HwTimeStamps> *getEventTsAllocator();
TagAllocator<HwPerfCounter> *getEventPerfCountAllocator();
TagAllocator<TimestampPacket> *getTimestampPacketAllocator();

View File

@ -1053,7 +1053,7 @@ HWTEST_F(CommandQueueHwTest, givenReadOnlyHostPointerWhenAllocationForHostSurfac
EXPECT_NE(memory, allocation->getUnderlyingBuffer());
EXPECT_THAT(allocation->getUnderlyingBuffer(), MemCompare(memory, size));
gmockMemoryManager->cleanAllocationList(-1, TEMPORARY_ALLOCATION);
allocation->taskCount = device->getCommandStreamReceiver().peekLatestFlushedTaskCount();
mockCmdQ->release();
mockContext->release();
}
@ -1091,7 +1091,6 @@ HWTEST_F(CommandQueueHwTest, givenReadOnlyHostPointerWhenAllocationForHostSurfac
auto allocation = surface.getAllocation();
EXPECT_EQ(nullptr, allocation);
gmockMemoryManager->cleanAllocationList(-1, TEMPORARY_ALLOCATION);
mockCmdQ->release();
mockContext->release();
}
@ -1117,7 +1116,6 @@ struct ReducedAddrSpaceCommandQueueHwTest : public CommandQueueHwTest {
void TearDown() override {
CommandQueueHwTest::TearDown();
gmockMemoryManager->cleanAllocationList(-1, TEMPORARY_ALLOCATION);
mockContext->release();
}
};

View File

@ -10,17 +10,11 @@
#include "unit_tests/mocks/mock_memory_manager.h"
using namespace OCLRT;
using ::testing::NiceMock;
void MemoryManagerWithCsrFixture::SetUp() {
csr = new MockCommandStreamReceiver(this->executionEnvironment);
gmockMemoryManager = new NiceMock<GMockMemoryManager>(executionEnvironment);
memoryManager = gmockMemoryManager;
memoryManager = new MockMemoryManager(executionEnvironment);
executionEnvironment.memoryManager.reset(memoryManager);
ON_CALL(*gmockMemoryManager, cleanAllocationList(::testing::_, ::testing::_)).WillByDefault(::testing::Invoke(gmockMemoryManager, &GMockMemoryManager::MemoryManagerCleanAllocationList));
ON_CALL(*gmockMemoryManager, populateOsHandles(::testing::_)).WillByDefault(::testing::Invoke(gmockMemoryManager, &GMockMemoryManager::MemoryManagerPopulateOsHandles));
csr->tagAddress = &currentGpuTag;
executionEnvironment.commandStreamReceivers.push_back(std::unique_ptr<CommandStreamReceiver>(csr));
}

View File

@ -6,19 +6,19 @@
*/
#pragma once
#include "unit_tests/mocks/mock_csr.h"
#include "runtime/execution_environment/execution_environment.h"
#include "runtime/helpers/options.h"
using namespace OCLRT;
class MockCommandStreamReceiver;
namespace OCLRT {
class MemoryManager;
class GMockMemoryManager;
class MockMemoryManager;
}; // namespace OCLRT
class MemoryManagerWithCsrFixture {
public:
MemoryManager *memoryManager;
GMockMemoryManager *gmockMemoryManager;
MockMemoryManager *memoryManager;
ExecutionEnvironment executionEnvironment;
MockCommandStreamReceiver *csr;
uint32_t taskCount = 0;

View File

@ -5,6 +5,7 @@
*
*/
#include "runtime/memory_manager/internal_allocation_storage.h"
#include "unit_tests/fixtures/device_fixture.h"
#include "unit_tests/mocks/mock_kernel.h"
#include "test.h"
@ -108,6 +109,7 @@ TEST_F(KernelSubstituteTest, givenKernelWithUsedKernelAllocationWhenSubstituteKe
MockKernelWithInternals kernel(*pDevice);
auto pHeader = const_cast<SKernelBinaryHeaderCommon *>(kernel.kernelInfo.heapInfo.pKernelHeader);
auto memoryManager = pDevice->getMemoryManager();
auto &commandStreamReceiver = pDevice->getCommandStreamReceiver();
const size_t initialHeapSize = 0x40;
pHeader->KernelHeapSize = initialHeapSize;
@ -120,13 +122,13 @@ TEST_F(KernelSubstituteTest, givenKernelWithUsedKernelAllocationWhenSubstituteKe
const size_t newHeapSize = initialHeapSize + 1;
char newHeap[newHeapSize];
EXPECT_TRUE(memoryManager->getCommandStreamReceiver(0)->getTemporaryAllocations().peekIsEmpty());
EXPECT_TRUE(commandStreamReceiver.getTemporaryAllocations().peekIsEmpty());
kernel.mockKernel->substituteKernelHeap(newHeap, newHeapSize);
auto secondAllocation = kernel.kernelInfo.kernelAllocation;
EXPECT_FALSE(memoryManager->getCommandStreamReceiver(0)->getTemporaryAllocations().peekIsEmpty());
EXPECT_EQ(memoryManager->getCommandStreamReceiver(0)->getTemporaryAllocations().peekHead(), firstAllocation);
EXPECT_FALSE(commandStreamReceiver.getTemporaryAllocations().peekIsEmpty());
EXPECT_EQ(commandStreamReceiver.getTemporaryAllocations().peekHead(), firstAllocation);
memoryManager->checkGpuUsageAndDestroyGraphicsAllocations(secondAllocation);
memoryManager->cleanAllocationList(firstAllocation->taskCount, TEMPORARY_ALLOCATION);
commandStreamReceiver.getInternalAllocationStorage()->cleanAllocationList(firstAllocation->taskCount, TEMPORARY_ALLOCATION);
}

View File

@ -11,6 +11,9 @@
#include "unit_tests/fixtures/memory_manager_fixture.h"
#include "unit_tests/gen_common/test.h"
#include "unit_tests/mocks/mock_host_ptr_manager.h"
#include "unit_tests/mocks/mock_internal_allocation_storage.h"
#include "unit_tests/mocks/mock_memory_manager.h"
#include "unit_tests/mocks/mock_csr.h"
using namespace OCLRT;
@ -807,4 +810,201 @@ TEST_F(HostPtrAllocationTest, whenPrepareOsHandlesForAllocationThenPopulateAsMan
memoryManager->cleanOsHandles(osStorage);
EXPECT_EQ(0u, hostPtrManager->getFragmentCount());
}
}
}
TEST_F(HostPtrAllocationTest, whenOverlappedFragmentIsBiggerThenStoredAndStoredFragmentIsDestroyedDuringSecondCleaningThenCheckForOverlappingReturnsSuccess) {
void *cpuPtr1 = (void *)0x100004;
auto hostPtrManager = static_cast<MockHostPtrManager *>(memoryManager->getHostPtrManager());
auto graphicsAllocation1 = memoryManager->allocateGraphicsMemory(MemoryConstants::pageSize, cpuPtr1);
EXPECT_EQ(2u, hostPtrManager->getFragmentCount());
EXPECT_NE(nullptr, graphicsAllocation1);
auto fragment1 = hostPtrManager->getFragment(alignDown(cpuPtr1, MemoryConstants::pageSize));
EXPECT_NE(nullptr, fragment1);
auto fragment2 = hostPtrManager->getFragment(alignUp(cpuPtr1, MemoryConstants::pageSize));
EXPECT_NE(nullptr, fragment2);
uint32_t taskCountReady = 2;
auto storage = new MockInternalAllocationStorage(*csr);
csr->internalAllocationStorage.reset(storage);
storage->storeAllocationWithTaskCount(std::unique_ptr<GraphicsAllocation>(graphicsAllocation1), TEMPORARY_ALLOCATION, taskCountReady);
storage->updateCompletionAfterCleaningList(taskCountReady);
// All fragments ready for release
currentGpuTag = 1;
csr->latestSentTaskCount = taskCountReady - 1;
AllocationRequirements requirements;
CheckedFragments checkedFragments;
requirements.requiredFragmentsCount = 1;
requirements.totalRequiredSize = MemoryConstants::pageSize * 10;
requirements.AllocationFragments[0].allocationPtr = alignDown(cpuPtr1, MemoryConstants::pageSize);
requirements.AllocationFragments[0].allocationSize = MemoryConstants::pageSize * 10;
requirements.AllocationFragments[0].fragmentPosition = FragmentPosition::NONE;
RequirementsStatus status = hostPtrManager->checkAllocationsForOverlapping(*memoryManager, &requirements, &checkedFragments);
EXPECT_EQ(RequirementsStatus::SUCCESS, status);
EXPECT_EQ(1u, checkedFragments.count);
EXPECT_EQ(OverlapStatus::FRAGMENT_NOT_OVERLAPING_WITH_ANY_OTHER, checkedFragments.status[0]);
EXPECT_EQ(nullptr, checkedFragments.fragments[0]);
for (uint32_t i = 1; i < maxFragmentsCount; i++) {
EXPECT_EQ(OverlapStatus::FRAGMENT_NOT_CHECKED, checkedFragments.status[i]);
EXPECT_EQ(nullptr, checkedFragments.fragments[i]);
}
}
TEST_F(HostPtrAllocationTest, whenOverlappedFragmentIsBiggerThenStoredAndStoredFragmentCannotBeDestroyedThenCheckForOverlappingReturnsError) {
void *cpuPtr1 = (void *)0x100004;
auto hostPtrManager = static_cast<MockHostPtrManager *>(memoryManager->getHostPtrManager());
auto graphicsAllocation1 = memoryManager->allocateGraphicsMemory(MemoryConstants::pageSize, cpuPtr1);
EXPECT_EQ(2u, hostPtrManager->getFragmentCount());
EXPECT_NE(nullptr, graphicsAllocation1);
auto fragment1 = hostPtrManager->getFragment(alignDown(cpuPtr1, MemoryConstants::pageSize));
EXPECT_NE(nullptr, fragment1);
auto fragment2 = hostPtrManager->getFragment(alignUp(cpuPtr1, MemoryConstants::pageSize));
EXPECT_NE(nullptr, fragment2);
uint32_t taskCountReady = 2;
auto storage = csr->getInternalAllocationStorage();
storage->storeAllocationWithTaskCount(std::unique_ptr<GraphicsAllocation>(graphicsAllocation1), TEMPORARY_ALLOCATION, taskCountReady);
// All fragments ready for release
currentGpuTag = taskCountReady - 1;
csr->latestSentTaskCount = taskCountReady - 1;
AllocationRequirements requirements;
CheckedFragments checkedFragments;
requirements.requiredFragmentsCount = 1;
requirements.totalRequiredSize = MemoryConstants::pageSize * 10;
requirements.AllocationFragments[0].allocationPtr = alignDown(cpuPtr1, MemoryConstants::pageSize);
requirements.AllocationFragments[0].allocationSize = MemoryConstants::pageSize * 10;
requirements.AllocationFragments[0].fragmentPosition = FragmentPosition::NONE;
RequirementsStatus status = hostPtrManager->checkAllocationsForOverlapping(*memoryManager, &requirements, &checkedFragments);
EXPECT_EQ(RequirementsStatus::FATAL, status);
EXPECT_EQ(1u, checkedFragments.count);
EXPECT_EQ(OverlapStatus::FRAGMENT_OVERLAPING_AND_BIGGER_THEN_STORED_FRAGMENT, checkedFragments.status[0]);
EXPECT_EQ(nullptr, checkedFragments.fragments[0]);
for (uint32_t i = 1; i < maxFragmentsCount; i++) {
EXPECT_EQ(OverlapStatus::FRAGMENT_NOT_CHECKED, checkedFragments.status[i]);
EXPECT_EQ(nullptr, checkedFragments.fragments[i]);
}
}
TEST_F(HostPtrAllocationTest, checkAllocationsForOverlappingWithoutBiggerOverlap) {
void *cpuPtr1 = (void *)0x100004;
void *cpuPtr2 = (void *)0x101008;
auto hostPtrManager = static_cast<MockHostPtrManager *>(memoryManager->getHostPtrManager());
auto graphicsAllocation1 = memoryManager->allocateGraphicsMemory(MemoryConstants::pageSize, cpuPtr1);
EXPECT_EQ(2u, hostPtrManager->getFragmentCount());
auto graphicsAllocation2 = memoryManager->allocateGraphicsMemory(MemoryConstants::pageSize * 3, cpuPtr2);
EXPECT_EQ(4u, hostPtrManager->getFragmentCount());
EXPECT_NE(nullptr, graphicsAllocation1);
EXPECT_NE(nullptr, graphicsAllocation2);
auto fragment1 = hostPtrManager->getFragment(alignDown(cpuPtr1, MemoryConstants::pageSize));
EXPECT_NE(nullptr, fragment1);
auto fragment2 = hostPtrManager->getFragment(alignUp(cpuPtr1, MemoryConstants::pageSize));
EXPECT_NE(nullptr, fragment2);
auto fragment3 = hostPtrManager->getFragment(alignDown(cpuPtr2, MemoryConstants::pageSize));
EXPECT_NE(nullptr, fragment3);
auto fragment4 = hostPtrManager->getFragment(alignUp(cpuPtr2, MemoryConstants::pageSize));
EXPECT_NE(nullptr, fragment4);
AllocationRequirements requirements;
CheckedFragments checkedFragments;
requirements.requiredFragmentsCount = 2;
requirements.totalRequiredSize = MemoryConstants::pageSize * 2;
requirements.AllocationFragments[0].allocationPtr = alignDown(cpuPtr1, MemoryConstants::pageSize);
requirements.AllocationFragments[0].allocationSize = MemoryConstants::pageSize;
requirements.AllocationFragments[0].fragmentPosition = FragmentPosition::LEADING;
requirements.AllocationFragments[1].allocationPtr = alignUp(cpuPtr1, MemoryConstants::pageSize);
requirements.AllocationFragments[1].allocationSize = MemoryConstants::pageSize;
requirements.AllocationFragments[1].fragmentPosition = FragmentPosition::TRAILING;
RequirementsStatus status = hostPtrManager->checkAllocationsForOverlapping(*memoryManager, &requirements, &checkedFragments);
EXPECT_EQ(RequirementsStatus::SUCCESS, status);
EXPECT_EQ(2u, checkedFragments.count);
EXPECT_EQ(OverlapStatus::FRAGMENT_WITH_EXACT_SIZE_AS_STORED_FRAGMENT, checkedFragments.status[0]);
EXPECT_EQ(alignDown(cpuPtr1, MemoryConstants::pageSize), checkedFragments.fragments[0]->fragmentCpuPointer);
EXPECT_EQ(MemoryConstants::pageSize, checkedFragments.fragments[0]->fragmentSize);
EXPECT_EQ(1, checkedFragments.fragments[0]->refCount);
EXPECT_EQ(OverlapStatus::FRAGMENT_WITH_EXACT_SIZE_AS_STORED_FRAGMENT, checkedFragments.status[1]);
EXPECT_EQ(alignUp(cpuPtr1, MemoryConstants::pageSize), checkedFragments.fragments[1]->fragmentCpuPointer);
EXPECT_EQ(MemoryConstants::pageSize, checkedFragments.fragments[1]->fragmentSize);
EXPECT_EQ(2, checkedFragments.fragments[1]->refCount);
memoryManager->freeGraphicsMemory(graphicsAllocation1);
memoryManager->freeGraphicsMemory(graphicsAllocation2);
}
TEST_F(HostPtrAllocationTest, checkAllocationsForOverlappingWithBiggerOverlapUntilFirstClean) {
void *cpuPtr1 = (void *)0x100004;
auto graphicsAllocation1 = memoryManager->allocateGraphicsMemory(MemoryConstants::pageSize, cpuPtr1);
auto hostPtrManager = static_cast<MockHostPtrManager *>(memoryManager->getHostPtrManager());
EXPECT_EQ(2u, hostPtrManager->getFragmentCount());
EXPECT_NE(nullptr, graphicsAllocation1);
auto fragment1 = hostPtrManager->getFragment(alignDown(cpuPtr1, MemoryConstants::pageSize));
EXPECT_NE(nullptr, fragment1);
auto fragment2 = hostPtrManager->getFragment(alignUp(cpuPtr1, MemoryConstants::pageSize));
EXPECT_NE(nullptr, fragment2);
uint32_t taskCountReady = 1;
auto storage = csr->getInternalAllocationStorage();
storage->storeAllocationWithTaskCount(std::unique_ptr<GraphicsAllocation>(graphicsAllocation1), TEMPORARY_ALLOCATION, taskCountReady);
// All fragments ready for release
taskCount = taskCountReady;
csr->latestSentTaskCount = taskCountReady;
AllocationRequirements requirements;
CheckedFragments checkedFragments;
requirements.requiredFragmentsCount = 1;
requirements.totalRequiredSize = MemoryConstants::pageSize * 10;
requirements.AllocationFragments[0].allocationPtr = alignDown(cpuPtr1, MemoryConstants::pageSize);
requirements.AllocationFragments[0].allocationSize = MemoryConstants::pageSize * 10;
requirements.AllocationFragments[0].fragmentPosition = FragmentPosition::NONE;
RequirementsStatus status = hostPtrManager->checkAllocationsForOverlapping(*memoryManager, &requirements, &checkedFragments);
EXPECT_EQ(RequirementsStatus::SUCCESS, status);
EXPECT_EQ(1u, checkedFragments.count);
EXPECT_EQ(OverlapStatus::FRAGMENT_NOT_OVERLAPING_WITH_ANY_OTHER, checkedFragments.status[0]);
EXPECT_EQ(nullptr, checkedFragments.fragments[0]);
for (uint32_t i = 1; i < maxFragmentsCount; i++) {
EXPECT_EQ(OverlapStatus::FRAGMENT_NOT_CHECKED, checkedFragments.status[i]);
EXPECT_EQ(nullptr, checkedFragments.fragments[i]);
}
}

View File

@ -24,6 +24,7 @@
#include "unit_tests/helpers/memory_management.h"
#include "unit_tests/helpers/variable_backup.h"
#include "unit_tests/mocks/mock_context.h"
#include "unit_tests/mocks/mock_csr.h"
#include "unit_tests/mocks/mock_deferrable_deletion.h"
#include "unit_tests/mocks/mock_deferred_deleter.h"
#include "unit_tests/mocks/mock_device.h"
@ -228,31 +229,6 @@ TEST_F(MemoryAllocatorTest, allocateGraphicsMoreThanPageAligned) {
memoryManager->freeGraphicsMemory(allocation);
}
TEST_F(MemoryAllocatorTest, givenMemoryManagerWhenCleanTempoaryAllocationsThenUseFirstCommandStreamReceiver) {
void *host_ptr = (void *)0x1234;
auto allocation = memoryManager->allocateGraphicsMemory(1, host_ptr);
allocation->taskCount = 1;
auto csr = memoryManager->getCommandStreamReceiver(0);
EXPECT_TRUE(csr->getTemporaryAllocations().peekIsEmpty());
csr->getInternalAllocationStorage()->storeAllocation(std::unique_ptr<GraphicsAllocation>(allocation), TEMPORARY_ALLOCATION);
EXPECT_FALSE(csr->getTemporaryAllocations().peekIsEmpty());
memoryManager->cleanAllocationList(1, TEMPORARY_ALLOCATION);
EXPECT_TRUE(csr->getTemporaryAllocations().peekIsEmpty());
}
TEST_F(MemoryAllocatorTest, givenMemoryManagerWhenCleanReusableAllocationsThenUseFirstCommandStreamReceiver) {
void *host_ptr = (void *)0x1234;
auto allocation = memoryManager->allocateGraphicsMemory(1, host_ptr);
allocation->taskCount = 1;
auto csr = memoryManager->getCommandStreamReceiver(0);
EXPECT_TRUE(csr->getAllocationsForReuse().peekIsEmpty());
csr->getInternalAllocationStorage()->storeAllocation(std::unique_ptr<GraphicsAllocation>(allocation), REUSABLE_ALLOCATION);
EXPECT_FALSE(csr->getAllocationsForReuse().peekIsEmpty());
memoryManager->cleanAllocationList(1, REUSABLE_ALLOCATION);
EXPECT_TRUE(csr->getAllocationsForReuse().peekIsEmpty());
}
TEST_F(MemoryAllocatorTest, AlignedHostPtrWithAlignedSizeWhenAskedForGraphicsAllocationReturnsNullStorageFromHostPtrManager) {
auto ptr = (void *)0x1000;
MockMemoryManager mockMemoryManager(*executionEnvironment);
@ -1219,220 +1195,6 @@ TEST_F(MemoryManagerWithCsrTest, GivenAllocationsInHostPtrManagerReadyForCleanin
memoryManager->freeGraphicsMemory(graphicsAllocation3);
}
TEST_F(MemoryManagerWithCsrTest, checkAllocationsForOverlappingWithoutBiggerOverlap) {
void *cpuPtr1 = (void *)0x100004;
void *cpuPtr2 = (void *)0x101008;
auto hostPtrManager = static_cast<MockHostPtrManager *>(memoryManager->getHostPtrManager());
auto graphicsAllocation1 = memoryManager->allocateGraphicsMemory(MemoryConstants::pageSize, cpuPtr1);
EXPECT_EQ(2u, hostPtrManager->getFragmentCount());
auto graphicsAllocation2 = memoryManager->allocateGraphicsMemory(MemoryConstants::pageSize * 3, cpuPtr2);
EXPECT_EQ(4u, hostPtrManager->getFragmentCount());
EXPECT_NE(nullptr, graphicsAllocation1);
EXPECT_NE(nullptr, graphicsAllocation2);
auto fragment1 = hostPtrManager->getFragment(alignDown(cpuPtr1, MemoryConstants::pageSize));
EXPECT_NE(nullptr, fragment1);
auto fragment2 = hostPtrManager->getFragment(alignUp(cpuPtr1, MemoryConstants::pageSize));
EXPECT_NE(nullptr, fragment2);
auto fragment3 = hostPtrManager->getFragment(alignDown(cpuPtr2, MemoryConstants::pageSize));
EXPECT_NE(nullptr, fragment3);
auto fragment4 = hostPtrManager->getFragment(alignUp(cpuPtr2, MemoryConstants::pageSize));
EXPECT_NE(nullptr, fragment4);
AllocationRequirements requirements;
CheckedFragments checkedFragments;
requirements.requiredFragmentsCount = 2;
requirements.totalRequiredSize = MemoryConstants::pageSize * 2;
requirements.AllocationFragments[0].allocationPtr = alignDown(cpuPtr1, MemoryConstants::pageSize);
requirements.AllocationFragments[0].allocationSize = MemoryConstants::pageSize;
requirements.AllocationFragments[0].fragmentPosition = FragmentPosition::LEADING;
requirements.AllocationFragments[1].allocationPtr = alignUp(cpuPtr1, MemoryConstants::pageSize);
requirements.AllocationFragments[1].allocationSize = MemoryConstants::pageSize;
requirements.AllocationFragments[1].fragmentPosition = FragmentPosition::TRAILING;
RequirementsStatus status = hostPtrManager->checkAllocationsForOverlapping(*memoryManager, &requirements, &checkedFragments);
EXPECT_EQ(RequirementsStatus::SUCCESS, status);
EXPECT_EQ(2u, checkedFragments.count);
EXPECT_EQ(OverlapStatus::FRAGMENT_WITH_EXACT_SIZE_AS_STORED_FRAGMENT, checkedFragments.status[0]);
EXPECT_EQ(alignDown(cpuPtr1, MemoryConstants::pageSize), checkedFragments.fragments[0]->fragmentCpuPointer);
EXPECT_EQ(MemoryConstants::pageSize, checkedFragments.fragments[0]->fragmentSize);
EXPECT_EQ(1, checkedFragments.fragments[0]->refCount);
EXPECT_EQ(OverlapStatus::FRAGMENT_WITH_EXACT_SIZE_AS_STORED_FRAGMENT, checkedFragments.status[1]);
EXPECT_EQ(alignUp(cpuPtr1, MemoryConstants::pageSize), checkedFragments.fragments[1]->fragmentCpuPointer);
EXPECT_EQ(MemoryConstants::pageSize, checkedFragments.fragments[1]->fragmentSize);
EXPECT_EQ(2, checkedFragments.fragments[1]->refCount);
memoryManager->freeGraphicsMemory(graphicsAllocation1);
memoryManager->freeGraphicsMemory(graphicsAllocation2);
}
TEST_F(MemoryManagerWithCsrTest, checkAllocationsForOverlappingWithBiggerOverlapUntilFirstClean) {
void *cpuPtr1 = (void *)0x100004;
auto graphicsAllocation1 = memoryManager->allocateGraphicsMemory(MemoryConstants::pageSize, cpuPtr1);
auto hostPtrManager = static_cast<MockHostPtrManager *>(memoryManager->getHostPtrManager());
EXPECT_EQ(2u, hostPtrManager->getFragmentCount());
EXPECT_NE(nullptr, graphicsAllocation1);
auto fragment1 = hostPtrManager->getFragment(alignDown(cpuPtr1, MemoryConstants::pageSize));
EXPECT_NE(nullptr, fragment1);
auto fragment2 = hostPtrManager->getFragment(alignUp(cpuPtr1, MemoryConstants::pageSize));
EXPECT_NE(nullptr, fragment2);
uint32_t taskCountReady = 1;
auto storage = csr->getInternalAllocationStorage();
storage->storeAllocationWithTaskCount(std::unique_ptr<GraphicsAllocation>(graphicsAllocation1), TEMPORARY_ALLOCATION, taskCountReady);
// All fragments ready for release
taskCount = taskCountReady;
csr->latestSentTaskCount = taskCountReady;
AllocationRequirements requirements;
CheckedFragments checkedFragments;
requirements.requiredFragmentsCount = 1;
requirements.totalRequiredSize = MemoryConstants::pageSize * 10;
requirements.AllocationFragments[0].allocationPtr = alignDown(cpuPtr1, MemoryConstants::pageSize);
requirements.AllocationFragments[0].allocationSize = MemoryConstants::pageSize * 10;
requirements.AllocationFragments[0].fragmentPosition = FragmentPosition::NONE;
RequirementsStatus status = hostPtrManager->checkAllocationsForOverlapping(*memoryManager, &requirements, &checkedFragments);
EXPECT_EQ(RequirementsStatus::SUCCESS, status);
EXPECT_EQ(1u, checkedFragments.count);
EXPECT_EQ(OverlapStatus::FRAGMENT_NOT_OVERLAPING_WITH_ANY_OTHER, checkedFragments.status[0]);
EXPECT_EQ(nullptr, checkedFragments.fragments[0]);
for (uint32_t i = 1; i < maxFragmentsCount; i++) {
EXPECT_EQ(OverlapStatus::FRAGMENT_NOT_CHECKED, checkedFragments.status[i]);
EXPECT_EQ(nullptr, checkedFragments.fragments[i]);
}
}
TEST_F(MemoryManagerWithCsrTest, checkAllocationsForOverlappingWithBiggerOverlapUntilWaitForCompletionAndSecondClean) {
void *cpuPtr1 = (void *)0x100004;
auto hostPtrManager = static_cast<MockHostPtrManager *>(memoryManager->getHostPtrManager());
auto graphicsAllocation1 = memoryManager->allocateGraphicsMemory(MemoryConstants::pageSize, cpuPtr1);
EXPECT_EQ(2u, hostPtrManager->getFragmentCount());
EXPECT_NE(nullptr, graphicsAllocation1);
auto fragment1 = hostPtrManager->getFragment(alignDown(cpuPtr1, MemoryConstants::pageSize));
EXPECT_NE(nullptr, fragment1);
auto fragment2 = hostPtrManager->getFragment(alignUp(cpuPtr1, MemoryConstants::pageSize));
EXPECT_NE(nullptr, fragment2);
uint32_t taskCountReady = 2;
auto storage = csr->getInternalAllocationStorage();
storage->storeAllocationWithTaskCount(std::unique_ptr<GraphicsAllocation>(graphicsAllocation1), TEMPORARY_ALLOCATION, taskCountReady);
// All fragments ready for release
currentGpuTag = 1;
csr->latestSentTaskCount = taskCountReady - 1;
AllocationRequirements requirements;
CheckedFragments checkedFragments;
requirements.requiredFragmentsCount = 1;
requirements.totalRequiredSize = MemoryConstants::pageSize * 10;
requirements.AllocationFragments[0].allocationPtr = alignDown(cpuPtr1, MemoryConstants::pageSize);
requirements.AllocationFragments[0].allocationSize = MemoryConstants::pageSize * 10;
requirements.AllocationFragments[0].fragmentPosition = FragmentPosition::NONE;
GMockMemoryManager *memMngr = gmockMemoryManager;
auto cleanAllocations = [memMngr](uint32_t waitTaskCount, uint32_t allocationUsage) -> bool {
return memMngr->MemoryManagerCleanAllocationList(waitTaskCount, allocationUsage);
};
auto cleanAllocationsWithTaskCount = [taskCountReady, memMngr](uint32_t waitTaskCount, uint32_t allocationUsage) -> bool {
return memMngr->MemoryManagerCleanAllocationList(taskCountReady, allocationUsage);
};
EXPECT_CALL(*gmockMemoryManager, cleanAllocationList(::testing::_, ::testing::_)).Times(2).WillOnce(::testing::Invoke(cleanAllocations)).WillOnce(::testing::Invoke(cleanAllocationsWithTaskCount));
RequirementsStatus status = hostPtrManager->checkAllocationsForOverlapping(*memoryManager, &requirements, &checkedFragments);
EXPECT_EQ(RequirementsStatus::SUCCESS, status);
EXPECT_EQ(1u, checkedFragments.count);
EXPECT_EQ(OverlapStatus::FRAGMENT_NOT_OVERLAPING_WITH_ANY_OTHER, checkedFragments.status[0]);
EXPECT_EQ(nullptr, checkedFragments.fragments[0]);
for (uint32_t i = 1; i < maxFragmentsCount; i++) {
EXPECT_EQ(OverlapStatus::FRAGMENT_NOT_CHECKED, checkedFragments.status[i]);
EXPECT_EQ(nullptr, checkedFragments.fragments[i]);
}
}
TEST_F(MemoryManagerWithCsrTest, checkAllocationsForOverlappingWithBiggerOverlapForever) {
void *cpuPtr1 = (void *)0x100004;
auto hostPtrManager = static_cast<MockHostPtrManager *>(memoryManager->getHostPtrManager());
auto graphicsAllocation1 = memoryManager->allocateGraphicsMemory(MemoryConstants::pageSize, cpuPtr1);
EXPECT_EQ(2u, hostPtrManager->getFragmentCount());
EXPECT_NE(nullptr, graphicsAllocation1);
auto fragment1 = hostPtrManager->getFragment(alignDown(cpuPtr1, MemoryConstants::pageSize));
EXPECT_NE(nullptr, fragment1);
auto fragment2 = hostPtrManager->getFragment(alignUp(cpuPtr1, MemoryConstants::pageSize));
EXPECT_NE(nullptr, fragment2);
uint32_t taskCountReady = 2;
auto storage = csr->getInternalAllocationStorage();
storage->storeAllocationWithTaskCount(std::unique_ptr<GraphicsAllocation>(graphicsAllocation1), TEMPORARY_ALLOCATION, taskCountReady);
// All fragments ready for release
currentGpuTag = taskCountReady - 1;
csr->latestSentTaskCount = taskCountReady - 1;
AllocationRequirements requirements;
CheckedFragments checkedFragments;
requirements.requiredFragmentsCount = 1;
requirements.totalRequiredSize = MemoryConstants::pageSize * 10;
requirements.AllocationFragments[0].allocationPtr = alignDown(cpuPtr1, MemoryConstants::pageSize);
requirements.AllocationFragments[0].allocationSize = MemoryConstants::pageSize * 10;
requirements.AllocationFragments[0].fragmentPosition = FragmentPosition::NONE;
GMockMemoryManager *memMngr = gmockMemoryManager;
auto cleanAllocations = [memMngr](uint32_t waitTaskCount, uint32_t allocationUsage) -> bool {
return memMngr->MemoryManagerCleanAllocationList(waitTaskCount, allocationUsage);
};
EXPECT_CALL(*gmockMemoryManager, cleanAllocationList(::testing::_, ::testing::_)).Times(2).WillRepeatedly(::testing::Invoke(cleanAllocations));
RequirementsStatus status = hostPtrManager->checkAllocationsForOverlapping(*memoryManager, &requirements, &checkedFragments);
EXPECT_EQ(RequirementsStatus::FATAL, status);
EXPECT_EQ(1u, checkedFragments.count);
EXPECT_EQ(OverlapStatus::FRAGMENT_OVERLAPING_AND_BIGGER_THEN_STORED_FRAGMENT, checkedFragments.status[0]);
EXPECT_EQ(nullptr, checkedFragments.fragments[0]);
for (uint32_t i = 1; i < maxFragmentsCount; i++) {
EXPECT_EQ(OverlapStatus::FRAGMENT_NOT_CHECKED, checkedFragments.status[i]);
EXPECT_EQ(nullptr, checkedFragments.fragments[i]);
}
}
TEST_F(MemoryManagerWithCsrTest, givenAllocationThatWasNotUsedWhencheckGpuUsageAndDestroyGraphicsAllocationsIsCalledThenItIsDestroyedInPlace) {
auto notUsedAllocation = memoryManager->allocateGraphicsMemory(4096);
memoryManager->checkGpuUsageAndDestroyGraphicsAllocations(notUsedAllocation);

View File

@ -43,6 +43,7 @@ set(IGDRCL_SRCS_tests_mocks
${CMAKE_CURRENT_SOURCE_DIR}${BRANCH_DIR_SUFFIX}/mock_gmm_client_context.cpp
${CMAKE_CURRENT_SOURCE_DIR}${BRANCH_DIR_SUFFIX}/mock_gmm_client_context.h
${CMAKE_CURRENT_SOURCE_DIR}/mock_host_ptr_manager.h
${CMAKE_CURRENT_SOURCE_DIR}/mock_internal_allocation_storage.h
${CMAKE_CURRENT_SOURCE_DIR}/mock_image.h
${CMAKE_CURRENT_SOURCE_DIR}/mock_kernel.cpp
${CMAKE_CURRENT_SOURCE_DIR}/mock_kernel.h

View File

@ -209,6 +209,7 @@ class MockFlatBatchBufferHelper : public FlatBatchBufferHelperHw<GfxFamily> {
class MockCommandStreamReceiver : public CommandStreamReceiver {
public:
using CommandStreamReceiver::CommandStreamReceiver;
using CommandStreamReceiver::internalAllocationStorage;
using CommandStreamReceiver::latestFlushedTaskCount;
using CommandStreamReceiver::latestSentTaskCount;
using CommandStreamReceiver::tagAddress;

View File

@ -0,0 +1,30 @@
/*
* Copyright (C) 2018 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "runtime/command_stream/command_stream_receiver.h"
#include "runtime/memory_manager/internal_allocation_storage.h"
namespace OCLRT {
class MockInternalAllocationStorage : public InternalAllocationStorage {
public:
using InternalAllocationStorage::InternalAllocationStorage;
void cleanAllocationList(uint32_t waitTaskCount, uint32_t allocationUsage) override {
InternalAllocationStorage::cleanAllocationList(waitTaskCount, allocationUsage);
if (doUpdateCompletion) {
*commandStreamReceiver.getTagAddress() = valueToUpdateCompletion;
doUpdateCompletion = false;
}
}
void updateCompletionAfterCleaningList(uint32_t newValue) {
doUpdateCompletion = true;
valueToUpdateCompletion = newValue;
}
bool doUpdateCompletion = false;
uint32_t valueToUpdateCompletion;
};
} // namespace OCLRT

View File

@ -55,13 +55,9 @@ class MockMemoryManager : public OsAgnosticMemoryManager {
class GMockMemoryManager : public MockMemoryManager {
public:
GMockMemoryManager(const ExecutionEnvironment &executionEnvironment) : MockMemoryManager(const_cast<ExecutionEnvironment &>(executionEnvironment)){};
MOCK_METHOD2(cleanAllocationList, bool(uint32_t waitTaskCount, uint32_t allocationUsage));
// cleanAllocationList call defined in MemoryManager.
MOCK_METHOD1(populateOsHandles, MemoryManager::AllocationStatus(OsHandleStorage &handleStorage));
MOCK_METHOD2(allocateGraphicsMemoryForNonSvmHostPtr, GraphicsAllocation *(size_t, void *));
bool MemoryManagerCleanAllocationList(uint32_t waitTaskCount, uint32_t allocationUsage) { return MemoryManager::cleanAllocationList(waitTaskCount, allocationUsage); }
MemoryManager::AllocationStatus MemoryManagerPopulateOsHandles(OsHandleStorage &handleStorage) { return OsAgnosticMemoryManager::populateOsHandles(handleStorage); }
};