CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
171 lines
6.7 KiB
C++
171 lines
6.7 KiB
C++
// Copyright Advanced Micro Devices, Inc., or its affiliates.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
#include "GenericContextFixture.hpp"
|
|
#include <rocRoller/DataTypes/DataTypes.hpp>
|
|
#include <rocRoller/InstructionValues/Register.hpp>
|
|
|
|
using namespace rocRoller;
|
|
|
|
namespace rocRollerTest
|
|
{
|
|
class LDSTest : public GenericContextFixture
|
|
{
|
|
};
|
|
|
|
TEST_F(LDSTest, LDSAllocationTest)
|
|
{
|
|
auto lds1 = Register::Value::AllocateLDS(m_context, DataType::Int32, 1000);
|
|
auto lds2 = Register::Value::AllocateLDS(m_context, DataType::Int32, 300);
|
|
|
|
EXPECT_EQ(lds1->toString(), "LDS:(Offset: 0, Size: 4000)");
|
|
EXPECT_EQ(lds2->toString(), "LDS:(Offset: 4000, Size: 1200)");
|
|
EXPECT_EQ(m_context->ldsAllocator()->currentUsed(), 5200);
|
|
EXPECT_EQ(m_context->ldsAllocator()->maxUsed(), 5200);
|
|
|
|
lds1.reset();
|
|
// Free blocks: [0, 4000]
|
|
|
|
// Can fit in free block, so offset starts at 0
|
|
lds1 = Register::Value::AllocateLDS(m_context, DataType::Int32, 500);
|
|
EXPECT_EQ(lds1->toString(), "LDS:(Offset: 0, Size: 2000)");
|
|
EXPECT_EQ(m_context->ldsAllocator()->currentUsed(), 3200);
|
|
EXPECT_EQ(m_context->ldsAllocator()->maxUsed(), 5200);
|
|
// Free blocks: [2000, 4000]
|
|
|
|
// Doesn't fit in free block, so needs to allocate from new memory
|
|
auto lds3 = Register::Value::AllocateLDS(m_context, DataType::Half, 1200, 2);
|
|
EXPECT_EQ(lds3->toString(), "LDS:(Offset: 5200, Size: 2400)");
|
|
EXPECT_EQ(m_context->ldsAllocator()->currentUsed(), 5600);
|
|
EXPECT_EQ(m_context->ldsAllocator()->maxUsed(), 7600);
|
|
|
|
// Does fit in free block, so no new memory needed
|
|
auto lds4 = Register::Value::AllocateLDS(m_context, DataType::Int32, 500);
|
|
EXPECT_EQ(lds4->toString(), "LDS:(Offset: 2000, Size: 2000)");
|
|
EXPECT_EQ(m_context->ldsAllocator()->currentUsed(), 7600);
|
|
EXPECT_EQ(m_context->ldsAllocator()->maxUsed(), 7600);
|
|
|
|
lds2.reset();
|
|
lds4.reset();
|
|
|
|
EXPECT_EQ(m_context->ldsAllocator()->currentUsed(), 4400);
|
|
// Free blocks [2000, 5200]
|
|
|
|
lds2 = Register::Value::AllocateLDS(m_context, DataType::Int32, 600);
|
|
EXPECT_EQ(lds2->toString(), "LDS:(Offset: 2000, Size: 2400)");
|
|
EXPECT_EQ(m_context->ldsAllocator()->currentUsed(), 6800);
|
|
EXPECT_EQ(m_context->ldsAllocator()->maxUsed(), 7600);
|
|
|
|
lds3.reset();
|
|
lds1.reset();
|
|
|
|
EXPECT_EQ(m_context->ldsAllocator()->currentUsed(), 2400);
|
|
// Free blocks [0, 2000]
|
|
|
|
// Doesn't fit in first free block, append to end
|
|
lds1 = Register::Value::AllocateLDS(m_context, DataType::Int32, 600);
|
|
EXPECT_EQ(lds1->toString(), "LDS:(Offset: 4400, Size: 2400)");
|
|
EXPECT_EQ(m_context->ldsAllocator()->currentUsed(), 4800);
|
|
// Free blocks [0, 2000]
|
|
|
|
// Fits in the first free block
|
|
lds4 = Register::Value::AllocateLDS(m_context, DataType::Int32, 100);
|
|
EXPECT_EQ(lds4->toString(), "LDS:(Offset: 0, Size: 400)");
|
|
EXPECT_EQ(m_context->ldsAllocator()->currentUsed(), 5200);
|
|
// Free blocks [400, 2000]
|
|
|
|
// Exercise merging two free blocks together
|
|
lds2.reset();
|
|
EXPECT_EQ(m_context->ldsAllocator()->currentUsed(), 2800);
|
|
// Free blocks [400, 4400]
|
|
lds1.reset();
|
|
EXPECT_EQ(m_context->ldsAllocator()->currentUsed(), 400);
|
|
// Free blocks: None
|
|
|
|
lds1 = Register::Value::AllocateLDS(m_context, DataType::Int32, 1800);
|
|
EXPECT_EQ(lds1->toString(), "LDS:(Offset: 400, Size: 7200)");
|
|
|
|
lds1.reset();
|
|
// Free blocks: None
|
|
|
|
EXPECT_EQ(m_context->ldsAllocator()->currentUsed(), 400);
|
|
EXPECT_EQ(m_context->ldsAllocator()->maxUsed(), 7600);
|
|
|
|
// Try different alignment
|
|
lds2 = Register::Value::AllocateLDS(m_context, DataType::Half, 1024, 2);
|
|
EXPECT_EQ(lds2->toString(), "LDS:(Offset: 400, Size: 2048)");
|
|
EXPECT_EQ(m_context->ldsAllocator()->currentUsed(), 2448);
|
|
EXPECT_EQ(m_context->ldsAllocator()->maxUsed(), 7600);
|
|
|
|
// Try over allocating
|
|
auto maxLDS = m_context->targetArchitecture().GetCapability(GPUCapability::MaxLdsSize);
|
|
EXPECT_THROW(Register::Value::AllocateLDS(m_context, DataType::Int32, maxLDS / 4),
|
|
FatalError);
|
|
}
|
|
|
|
TEST_F(LDSTest, LDSAlignment)
|
|
{
|
|
auto lds1 = Register::Value::AllocateLDS(m_context, DataType::Half, 1, 2);
|
|
EXPECT_EQ(lds1->toString(), "LDS:(Offset: 0, Size: 2)");
|
|
EXPECT_EQ(m_context->ldsAllocator()->currentUsed(), 2);
|
|
|
|
auto lds2 = Register::Value::AllocateLDS(m_context, DataType::Half, 2, 2);
|
|
EXPECT_EQ(lds2->toString(), "LDS:(Offset: 2, Size: 4)");
|
|
EXPECT_EQ(m_context->ldsAllocator()->currentUsed(), 6);
|
|
|
|
auto lds3 = Register::Value::AllocateLDS(m_context, DataType::Int32, 1, 4);
|
|
EXPECT_EQ(lds3->toString(), "LDS:(Offset: 8, Size: 4)");
|
|
EXPECT_EQ(m_context->ldsAllocator()->currentUsed(), 10);
|
|
|
|
lds1.reset();
|
|
EXPECT_EQ(m_context->ldsAllocator()->currentUsed(), 8);
|
|
|
|
lds3.reset();
|
|
EXPECT_EQ(m_context->ldsAllocator()->currentUsed(), 4);
|
|
|
|
lds2.reset();
|
|
EXPECT_EQ(m_context->ldsAllocator()->currentUsed(), 0);
|
|
// All free
|
|
}
|
|
|
|
TEST_F(LDSTest, LDSCurrentUsage)
|
|
{
|
|
auto lds1 = Register::Value::AllocateLDS(m_context, DataType::Int32, 1000);
|
|
EXPECT_EQ(lds1->toString(), "LDS:(Offset: 0, Size: 4000)");
|
|
EXPECT_EQ(m_context->ldsAllocator()->currentUsed(), 4000);
|
|
|
|
auto lds2 = Register::Value::AllocateLDS(m_context, DataType::Int32, 1000);
|
|
EXPECT_EQ(lds2->toString(), "LDS:(Offset: 4000, Size: 4000)");
|
|
EXPECT_EQ(m_context->ldsAllocator()->currentUsed(), 8000);
|
|
|
|
auto lds3 = Register::Value::AllocateLDS(m_context, DataType::Half, 10, 2);
|
|
EXPECT_EQ(lds3->toString(), "LDS:(Offset: 8000, Size: 20)");
|
|
EXPECT_EQ(m_context->ldsAllocator()->currentUsed(), 8020);
|
|
|
|
lds1.reset();
|
|
EXPECT_EQ(m_context->ldsAllocator()->currentUsed(), 4020);
|
|
|
|
lds3.reset();
|
|
EXPECT_EQ(m_context->ldsAllocator()->currentUsed(), 4000);
|
|
|
|
lds2.reset();
|
|
EXPECT_EQ(m_context->ldsAllocator()->currentUsed(), 0);
|
|
// All free
|
|
}
|
|
|
|
TEST_F(LDSTest, LDSOverAllocate)
|
|
{
|
|
auto maxLDS = m_context->targetArchitecture().GetCapability(GPUCapability::MaxLdsSize);
|
|
EXPECT_THROW(Register::Value::AllocateLDS(m_context, DataType::Int32, 1 + (maxLDS / 4), 4),
|
|
FatalError);
|
|
}
|
|
|
|
TEST_F(LDSTest, LDSAllocationDoubleFreeTest)
|
|
{
|
|
auto allocator = m_context->ldsAllocator();
|
|
auto alloc1 = allocator->allocate(100, 4);
|
|
allocator->deallocate(alloc1);
|
|
EXPECT_THROW(allocator->deallocate(alloc1), FatalError);
|
|
}
|
|
}
|