Refactor TagAllocator

Signed-off-by: Bartosz Dunajski <bartosz.dunajski@intel.com>
This commit is contained in:
Bartosz Dunajski
2021-03-24 18:21:13 +00:00
committed by Compute-Runtime-Automation
parent cb4db7767e
commit 5a50ad098c
49 changed files with 868 additions and 430 deletions

View File

@@ -21,29 +21,69 @@
using namespace NEO;
struct TagAllocatorTest : public Test<MemoryAllocatorFixture> {
const DeviceBitfield deviceBitfield{0xf};
DebugManagerStateRestore restorer;
class MockTimestampPackets32 : public TimestampPackets<uint32_t> {
public:
void setTagToReadyState() {
auto packetsUsed = getPacketsUsed();
initialize();
uint32_t zeros[4] = {};
for (uint32_t i = 0; i < TimestampPacketSizeControl::preferredPacketCount; i++) {
assignDataToAllTimestamps(i, zeros);
}
setPacketsUsed(packetsUsed);
EXPECT_TRUE(isCompleted());
}
void setToNonReadyState() {
packets[0].contextEnd = 1;
EXPECT_FALSE(isCompleted());
}
};
void SetUp() override {
DebugManager.flags.CreateMultipleSubDevices.set(4);
MemoryAllocatorFixture::SetUp();
}
const DeviceBitfield deviceBitfield{0xf};
DebugManagerStateRestore restorer;
};
struct TimeStamps {
void initialize() {
start = 1;
end = 2;
release = true;
}
static GraphicsAllocation::AllocationType getAllocationType() {
static constexpr GraphicsAllocation::AllocationType getAllocationType() {
return GraphicsAllocation::AllocationType::PROFILING_TAG_BUFFER;
}
bool isCompleted() const { return release; }
uint32_t getImplicitGpuDependenciesCount() const { return 0; }
bool release;
static constexpr TagNodeType getTagNodeType() { return TagNodeType::HwTimeStamps; }
uint64_t getContextStartValue(uint32_t packetIndex) const {
return start;
}
uint64_t getGlobalStartValue(uint32_t packetIndex) const {
return start;
}
uint64_t getContextEndValue(uint32_t packetIndex) const {
return end;
}
uint64_t getGlobalEndValue(uint32_t packetIndex) const {
return end;
}
uint64_t start;
uint64_t end;
uint64_t ContextCompleteTS;
uint64_t GlobalEndTS;
};
template <typename TagType>
@@ -58,6 +98,7 @@ class MockTagAllocator : public TagAllocator<TagType> {
using BaseClass::populateFreeTags;
using BaseClass::releaseDeferredTags;
using BaseClass::usedTags;
using BaseClass::TagAllocatorBase::cleanUpResources;
MockTagAllocator(MemoryManager *memMngr, size_t tagCount, size_t tagAlignment, bool disableCompletionCheck, DeviceBitfield deviceBitfield)
: BaseClass(0, memMngr, tagCount, tagAlignment, sizeof(TagType), disableCompletionCheck, deviceBitfield) {
@@ -115,7 +156,7 @@ TEST_F(TagAllocatorTest, WhenGettingAndReturningTagThenFreeAndUsedListsAreUpdate
ASSERT_NE(nullptr, tagAllocator.getFreeTagsHead());
EXPECT_EQ(nullptr, tagAllocator.getUsedTagsHead());
TagNode<TimeStamps> *tagNode = tagAllocator.getTag();
auto tagNode = static_cast<TagNode<TimeStamps> *>(tagAllocator.getTag());
EXPECT_NE(nullptr, tagNode);
@@ -151,7 +192,7 @@ TEST_F(TagAllocatorTest, WhenTagIsAllocatedThenItIsAligned) {
ASSERT_NE(nullptr, tagAllocator.getFreeTagsHead());
TagNode<TimeStamps> *tagNode = tagAllocator.getTag();
TagNode<TimeStamps> *tagNode = static_cast<TagNode<TimeStamps> *>(tagAllocator.getTag());
ASSERT_NE(nullptr, tagNode);
EXPECT_EQ(0u, (uintptr_t)tagNode->tagForCpuAccess % alignment);
@@ -170,13 +211,13 @@ TEST_F(TagAllocatorTest, givenTagAllocatorWhenAllNodesWereUsedThenCreateNewGraph
TagNode<TimeStamps> *tagNodes[4];
for (size_t i = 0; i < 4; i++) {
tagNodes[i] = tagAllocator.getTag();
tagNodes[i] = static_cast<TagNode<TimeStamps> *>(tagAllocator.getTag());
EXPECT_NE(nullptr, tagNodes[i]);
}
EXPECT_EQ(1u, tagAllocator.getGraphicsAllocationsCount());
EXPECT_EQ(1u, tagAllocator.getTagPoolCount());
TagNode<TimeStamps> *tagNode = tagAllocator.getTag();
TagNode<TimeStamps> *tagNode = static_cast<TagNode<TimeStamps> *>(tagAllocator.getTag());
EXPECT_NE(nullptr, tagNode);
EXPECT_EQ(2u, tagAllocator.getGraphicsAllocationsCount());
@@ -188,7 +229,7 @@ TEST_F(TagAllocatorTest, givenInputTagCountWhenCreatingAllocatorThenRequestedNum
public:
using MockMemoryManager::MockMemoryManager;
GraphicsAllocation *allocateGraphicsMemoryWithAlignment(const AllocationData &allocationData) override {
return new MemoryAllocation(0, TimestampPacketStorage::getAllocationType(), nullptr, nullptr, 0, MemoryConstants::pageSize,
return new MemoryAllocation(0, TimestampPackets<uint32_t>::getAllocationType(), nullptr, nullptr, 0, MemoryConstants::pageSize,
1, MemoryPool::System4KBPages, false, false, mockMaxOsContextCount);
}
};
@@ -196,7 +237,7 @@ TEST_F(TagAllocatorTest, givenInputTagCountWhenCreatingAllocatorThenRequestedNum
auto mockMemoryManager = std::make_unique<MyMockMemoryManager>(true, true, *executionEnvironment);
const size_t tagsCount = 3;
MockTagAllocator<TimestampPacketStorage> tagAllocator(mockMemoryManager.get(), tagsCount, 1, deviceBitfield);
MockTagAllocator<TimestampPackets<uint32_t>> tagAllocator(mockMemoryManager.get(), tagsCount, 1, deviceBitfield);
size_t nodesFound = 0;
auto head = tagAllocator.freeTags.peekHead();
@@ -219,13 +260,13 @@ TEST_F(TagAllocatorTest, GivenSpecificOrderWhenReturningTagsThenFreeListIsUpdate
TagNode<TimeStamps> *tagNodes[4];
for (int i = 0; i < 4; i++) {
tagNodes[i] = tagAllocator.getTag();
tagNodes[i] = static_cast<TagNode<TimeStamps> *>(tagAllocator.getTag());
EXPECT_NE(nullptr, tagNodes[i]);
}
EXPECT_EQ(1u, tagAllocator.getGraphicsAllocationsCount());
EXPECT_EQ(1u, tagAllocator.getTagPoolCount());
TagNode<TimeStamps> *tagNode2 = tagAllocator.getTag();
TagNode<TimeStamps> *tagNode2 = static_cast<TagNode<TimeStamps> *>(tagAllocator.getTag());
EXPECT_NE(nullptr, tagNode2);
EXPECT_EQ(2u, tagAllocator.getGraphicsAllocationsCount());
EXPECT_EQ(2u, tagAllocator.getTagPoolCount());
@@ -263,10 +304,10 @@ TEST_F(TagAllocatorTest, WhenGettingTagsFromTwoPoolsThenTagsAreDifferent) {
TagNode<TimeStamps> *tagNode1, *tagNode2;
tagNode1 = tagAllocator.getTag();
tagNode1 = static_cast<TagNode<TimeStamps> *>(tagAllocator.getTag());
ASSERT_NE(nullptr, tagNode1);
tagNode2 = tagAllocator.getTag();
tagNode2 = static_cast<TagNode<TimeStamps> *>(tagAllocator.getTag());
ASSERT_NE(nullptr, tagNode2);
EXPECT_EQ(2u, tagAllocator.getGraphicsAllocationsCount());
@@ -286,11 +327,11 @@ TEST_F(TagAllocatorTest, WhenCleaningUpResourcesThenAllResourcesAreReleased) {
TagNode<TimeStamps> *tagNode1, *tagNode2;
// Allocate first Pool
tagNode1 = tagAllocator.getTag();
tagNode1 = static_cast<TagNode<TimeStamps> *>(tagAllocator.getTag());
EXPECT_NE(nullptr, tagNode1);
// Allocate second Pool
tagNode2 = tagAllocator.getTag();
tagNode2 = static_cast<TagNode<TimeStamps> *>(tagAllocator.getTag());
ASSERT_NE(nullptr, tagNode2);
// Two pools should have different gfxAllocations
@@ -312,7 +353,7 @@ TEST_F(TagAllocatorTest, whenNewTagIsTakenThenItIsInitialized) {
tagAllocator.getFreeTagsHead()->tagForCpuAccess->end = 4;
tagAllocator.getFreeTagsHead()->setProfilingCapable(false);
auto node = tagAllocator.getTag();
auto node = static_cast<TagNode<TimeStamps> *>(tagAllocator.getTag());
EXPECT_EQ(1u, node->tagForCpuAccess->start);
EXPECT_EQ(2u, node->tagForCpuAccess->end);
EXPECT_TRUE(node->isProfilingCapable());
@@ -337,10 +378,10 @@ TEST_F(TagAllocatorTest, givenMultipleReferencesOnTagWhenReleasingThenReturnWhen
}
TEST_F(TagAllocatorTest, givenNotReadyTagWhenReturnedThenMoveToDeferredList) {
MockTagAllocator<TimeStamps> tagAllocator(memoryManager, 1, 1, deviceBitfield);
auto node = tagAllocator.getTag();
MockTagAllocator<MockTimestampPackets32> tagAllocator(memoryManager, 1, 1, deviceBitfield);
auto node = static_cast<TagNode<MockTimestampPackets32> *>(tagAllocator.getTag());
node->tagForCpuAccess->release = false;
node->tagForCpuAccess->setToNonReadyState();
EXPECT_TRUE(tagAllocator.deferredTags.peekIsEmpty());
tagAllocator.returnTag(node);
EXPECT_FALSE(tagAllocator.deferredTags.peekIsEmpty());
@@ -379,10 +420,10 @@ TEST_F(TagAllocatorTest, givenTagAllocatorWhenDisabledCompletionCheckThenNodeInh
}
TEST_F(TagAllocatorTest, givenReadyTagWhenReturnedThenMoveToFreeList) {
MockTagAllocator<TimeStamps> tagAllocator(memoryManager, 1, 1, deviceBitfield);
auto node = tagAllocator.getTag();
MockTagAllocator<MockTimestampPackets32> tagAllocator(memoryManager, 1, 1, deviceBitfield);
auto node = static_cast<TagNode<MockTimestampPackets32> *>(tagAllocator.getTag());
node->tagForCpuAccess->release = true;
node->tagForCpuAccess->setTagToReadyState();
EXPECT_TRUE(tagAllocator.deferredTags.peekIsEmpty());
tagAllocator.returnTag(node);
EXPECT_TRUE(tagAllocator.deferredTags.peekIsEmpty());
@@ -390,25 +431,25 @@ TEST_F(TagAllocatorTest, givenReadyTagWhenReturnedThenMoveToFreeList) {
}
TEST_F(TagAllocatorTest, givenEmptyFreeListWhenAskingForNewTagThenTryToReleaseDeferredListFirst) {
MockTagAllocator<TimeStamps> tagAllocator(memoryManager, 1, 1, deviceBitfield);
auto node = tagAllocator.getTag();
MockTagAllocator<MockTimestampPackets32> tagAllocator(memoryManager, 1, 1, deviceBitfield);
auto node = static_cast<TagNode<MockTimestampPackets32> *>(tagAllocator.getTag());
node->tagForCpuAccess->release = false;
node->tagForCpuAccess->setToNonReadyState();
tagAllocator.returnTag(node);
node->tagForCpuAccess->release = false;
node->tagForCpuAccess->setToNonReadyState();
EXPECT_TRUE(tagAllocator.freeTags.peekIsEmpty());
node = tagAllocator.getTag();
node = static_cast<TagNode<MockTimestampPackets32> *>(tagAllocator.getTag());
EXPECT_NE(nullptr, node);
EXPECT_TRUE(tagAllocator.freeTags.peekIsEmpty()); // empty again - new pool wasnt allocated
}
TEST_F(TagAllocatorTest, givenTagsOnDeferredListWhenReleasingItThenMoveReadyTagsToFreePool) {
MockTagAllocator<TimeStamps> tagAllocator(memoryManager, 2, 1, deviceBitfield); // pool with 2 tags
auto node1 = tagAllocator.getTag();
auto node2 = tagAllocator.getTag();
MockTagAllocator<MockTimestampPackets32> tagAllocator(memoryManager, 2, 1, deviceBitfield); // pool with 2 tags
auto node1 = static_cast<TagNode<MockTimestampPackets32> *>(tagAllocator.getTag());
auto node2 = static_cast<TagNode<MockTimestampPackets32> *>(tagAllocator.getTag());
node1->tagForCpuAccess->release = false;
node2->tagForCpuAccess->release = false;
node1->tagForCpuAccess->setToNonReadyState();
node2->tagForCpuAccess->setToNonReadyState();
tagAllocator.returnTag(node1);
tagAllocator.returnTag(node2);
@@ -416,19 +457,19 @@ TEST_F(TagAllocatorTest, givenTagsOnDeferredListWhenReleasingItThenMoveReadyTags
EXPECT_FALSE(tagAllocator.deferredTags.peekIsEmpty());
EXPECT_TRUE(tagAllocator.freeTags.peekIsEmpty());
node1->tagForCpuAccess->release = true;
node1->tagForCpuAccess->setTagToReadyState();
tagAllocator.releaseDeferredTags();
EXPECT_FALSE(tagAllocator.deferredTags.peekIsEmpty());
EXPECT_FALSE(tagAllocator.freeTags.peekIsEmpty());
node2->tagForCpuAccess->release = true;
node2->tagForCpuAccess->setTagToReadyState();
tagAllocator.releaseDeferredTags();
EXPECT_TRUE(tagAllocator.deferredTags.peekIsEmpty());
EXPECT_FALSE(tagAllocator.freeTags.peekIsEmpty());
}
TEST_F(TagAllocatorTest, givenTagAllocatorWhenGraphicsAllocationIsCreatedThenSetValidllocationType) {
TagAllocator<TimestampPacketStorage> timestampPacketAllocator(mockRootDeviceIndex, memoryManager, 1, 1, sizeof(TimestampPacketStorage), false, mockDeviceBitfield);
TagAllocator<TimestampPackets<uint32_t>> timestampPacketAllocator(mockRootDeviceIndex, memoryManager, 1, 1, sizeof(TimestampPackets<uint32_t>), false, mockDeviceBitfield);
TagAllocator<HwTimeStamps> hwTimeStampsAllocator(mockRootDeviceIndex, memoryManager, 1, 1, sizeof(HwTimeStamps), false, mockDeviceBitfield);
TagAllocator<HwPerfCounter> hwPerfCounterAllocator(mockRootDeviceIndex, memoryManager, 1, 1, sizeof(HwPerfCounter), false, mockDeviceBitfield);
@@ -440,3 +481,53 @@ TEST_F(TagAllocatorTest, givenTagAllocatorWhenGraphicsAllocationIsCreatedThenSet
EXPECT_EQ(GraphicsAllocation::AllocationType::PROFILING_TAG_BUFFER, hwTimeStampsTag->getBaseGraphicsAllocation()->getAllocationType());
EXPECT_EQ(GraphicsAllocation::AllocationType::PROFILING_TAG_BUFFER, hwPerfCounterTag->getBaseGraphicsAllocation()->getAllocationType());
}
TEST_F(TagAllocatorTest, givenNotSupportedTagTypeWhenCallingMethodThenAbortOrReturnInitialValue) {
{
TagNode<HwPerfCounter> perfCounterNode = {};
EXPECT_ANY_THROW(perfCounterNode.getGlobalStartOffset());
EXPECT_ANY_THROW(perfCounterNode.getContextStartOffset());
EXPECT_ANY_THROW(perfCounterNode.getContextEndOffset());
EXPECT_ANY_THROW(perfCounterNode.getGlobalEndOffset());
EXPECT_ANY_THROW(perfCounterNode.getImplicitGpuDependenciesCountOffset());
EXPECT_ANY_THROW(perfCounterNode.getContextStartValue(0));
EXPECT_ANY_THROW(perfCounterNode.getGlobalStartValue(0));
EXPECT_ANY_THROW(perfCounterNode.getContextEndValue(0));
EXPECT_ANY_THROW(perfCounterNode.getGlobalEndValue(0));
EXPECT_ANY_THROW(perfCounterNode.getContextCompleteRef());
EXPECT_ANY_THROW(perfCounterNode.getGlobalEndRef());
EXPECT_ANY_THROW(perfCounterNode.setPacketsUsed(0));
EXPECT_ANY_THROW(perfCounterNode.getPacketsUsed());
EXPECT_EQ(0u, perfCounterNode.getImplicitGpuDependenciesCount());
EXPECT_ANY_THROW(perfCounterNode.getSinglePacketSize());
EXPECT_ANY_THROW(perfCounterNode.assignDataToAllTimestamps(0, nullptr));
EXPECT_TRUE(perfCounterNode.isCompleted());
}
{
TagNode<HwTimeStamps> hwTimestampNode = {};
EXPECT_ANY_THROW(hwTimestampNode.getGlobalStartOffset());
EXPECT_ANY_THROW(hwTimestampNode.getContextStartOffset());
EXPECT_ANY_THROW(hwTimestampNode.getContextEndOffset());
EXPECT_ANY_THROW(hwTimestampNode.getGlobalEndOffset());
EXPECT_ANY_THROW(hwTimestampNode.getImplicitGpuDependenciesCountOffset());
EXPECT_ANY_THROW(hwTimestampNode.setPacketsUsed(0));
EXPECT_ANY_THROW(hwTimestampNode.getPacketsUsed());
EXPECT_EQ(0u, hwTimestampNode.getImplicitGpuDependenciesCount());
EXPECT_ANY_THROW(hwTimestampNode.getSinglePacketSize());
EXPECT_ANY_THROW(hwTimestampNode.assignDataToAllTimestamps(0, nullptr));
EXPECT_TRUE(hwTimestampNode.isCompleted());
EXPECT_ANY_THROW(hwTimestampNode.getQueryHandleRef());
}
{
TagNode<TimestampPackets<uint32_t>> timestampPacketsNode = {};
EXPECT_ANY_THROW(timestampPacketsNode.getContextCompleteRef());
EXPECT_ANY_THROW(timestampPacketsNode.getGlobalEndRef());
EXPECT_ANY_THROW(timestampPacketsNode.getQueryHandleRef());
}
}