// Copyright © Advanced Micro Devices, Inc., or its affiliates. // SPDX-License-Identifier: MIT #include #include #include #include #include #include using namespace hipdnn_data_sdk::utilities; // Test that allocators work with STL containers TEST(TestAllocators, HostAllocatorWithVector) { std::vector> vec; vec.push_back(1); vec.push_back(2); vec.push_back(3); EXPECT_EQ(vec.size(), 3); EXPECT_EQ(vec[0], 1); EXPECT_EQ(vec[1], 2); EXPECT_EQ(vec[2], 3); } TEST(TestAllocators, HostAllocatorWithList) { std::list> lst; lst.push_back(1.5); lst.push_back(2.5); lst.push_back(3.5); auto it = lst.begin(); EXPECT_EQ(*it++, 1.5); EXPECT_EQ(*it++, 2.5); EXPECT_EQ(*it++, 3.5); } TEST(TestAllocators, HostAllocatorBasicOperations) { HostAllocator alloc; // Allocate memory for 10 integers auto ptr = alloc.allocate(10); ASSERT_NE(ptr, nullptr); // Construct objects for(int i = 0; i < 10; ++i) { alloc.construct(&ptr[i], i * 2); } // Verify values for(int i = 0; i < 10; ++i) { EXPECT_EQ(ptr[i], i * 2); } // Destroy objects for(int i = 0; i < 10; ++i) { alloc.destroy(&ptr[i]); } // Deallocate memory alloc.deallocate(ptr, 10); } TEST(TestAllocators, HostAllocatorRebind) { HostAllocator intAlloc; typename HostAllocator::template rebind::other doubleAlloc; auto intPtr = intAlloc.allocate(5); auto doublePtr = doubleAlloc.allocate(5); ASSERT_NE(intPtr, nullptr); ASSERT_NE(doublePtr, nullptr); intAlloc.deallocate(intPtr, 5); doubleAlloc.deallocate(doublePtr, 5); } TEST(TestAllocators, HostAllocatorComparison) { const HostAllocator alloc1; const HostAllocator alloc2; const HostAllocator alloc3; EXPECT_TRUE(alloc1 == alloc2); EXPECT_FALSE(alloc1 != alloc2); EXPECT_TRUE(alloc1 == alloc3); } TEST(TestGpuAllocators, PinnedHostAllocatorWithVector) { SKIP_IF_NO_DEVICES(); std::vector> vec; vec.resize(100); for(size_t i = 0; i < vec.size(); ++i) { vec[i] = static_cast(i) * 0.5f; } for(size_t i = 0; i < vec.size(); ++i) { EXPECT_EQ(vec[i], static_cast(i) * 0.5f); } } TEST(TestGpuAllocators, PinnedHostAllocatorBasicOperations) { SKIP_IF_NO_DEVICES(); PinnedHostAllocator alloc; // Allocate pinned memory for 10 integers auto ptr = alloc.allocate(10); ASSERT_NE(ptr, nullptr); // Construct objects for(int i = 0; i < 10; ++i) { alloc.construct(&ptr[i], i * 3); } // Verify values for(int i = 0; i < 10; ++i) { EXPECT_EQ(ptr[i], i * 3); } // Destroy objects for(int i = 0; i < 10; ++i) { alloc.destroy(&ptr[i]); } // Deallocate memory alloc.deallocate(ptr, 10); } TEST(TestGpuAllocators, PinnedHostAllocatorRebind) { SKIP_IF_NO_DEVICES(); PinnedHostAllocator intAlloc; typename PinnedHostAllocator::template rebind::other doubleAlloc; auto intPtr = intAlloc.allocate(5); auto doublePtr = doubleAlloc.allocate(5); ASSERT_NE(intPtr, nullptr); ASSERT_NE(doublePtr, nullptr); intAlloc.deallocate(intPtr, 5); doubleAlloc.deallocate(doublePtr, 5); } TEST(TestGpuAllocators, DeviceAllocatorBasicOperations) { SKIP_IF_NO_DEVICES(); DeviceAllocator alloc; // Allocate device memory for 100 floats auto ptr = alloc.allocate(100); ASSERT_NE(ptr, nullptr); // Verify we can use the pointer with HIP operations std::vector hostData(100); for(size_t i = 0; i < hostData.size(); ++i) { hostData[i] = static_cast(i); } hipError_t err = hipMemcpy(ptr, hostData.data(), 100 * sizeof(float), hipMemcpyHostToDevice); EXPECT_EQ(err, hipSuccess); std::vector result(100); err = hipMemcpy(result.data(), ptr, 100 * sizeof(float), hipMemcpyDeviceToHost); EXPECT_EQ(err, hipSuccess); for(size_t i = 0; i < result.size(); ++i) { EXPECT_EQ(result[i], static_cast(i)); } // Deallocate memory alloc.deallocate(ptr, 100); } TEST(TestGpuAllocators, DeviceAllocatorRebind) { SKIP_IF_NO_DEVICES(); DeviceAllocator intAlloc; typename DeviceAllocator::template rebind::other doubleAlloc; auto intPtr = intAlloc.allocate(5); auto doublePtr = doubleAlloc.allocate(5); ASSERT_NE(intPtr, nullptr); ASSERT_NE(doublePtr, nullptr); intAlloc.deallocate(intPtr, 5); doubleAlloc.deallocate(doublePtr, 5); } TEST(TestGpuAllocators, DeviceAllocatorComparison) { SKIP_IF_NO_DEVICES(); const DeviceAllocator alloc1; const DeviceAllocator alloc2; const DeviceAllocator alloc3; EXPECT_TRUE(alloc1 == alloc2); EXPECT_FALSE(alloc1 != alloc2); EXPECT_TRUE(alloc1 == alloc3); } // Test allocator traits compatibility TEST(TestAllocators, AllocatorTraitsCompatibility) { using HostTraits = std::allocator_traits>; using PinnedTraits = std::allocator_traits>; using DeviceTraits = std::allocator_traits>; // Check that all required types are defined static_assert(std::is_same_v); static_assert(std::is_same_v); static_assert(std::is_same_v); static_assert(std::is_same_v); static_assert(std::is_same_v); static_assert(std::is_same_v); static_assert(std::is_same_v); static_assert(std::is_same_v); static_assert(std::is_same_v); static_assert(std::is_same_v); static_assert(std::is_same_v); static_assert(std::is_same_v); static_assert(std::is_same_v); static_assert(std::is_same_v); static_assert(std::is_same_v); } // Test exception handling TEST(TestAllocators, AllocationFailure) { HostAllocator alloc; // Try to allocate an impossibly large amount of memory EXPECT_THROW(std::ignore = alloc.allocate(std::numeric_limits::max()), std::bad_alloc); } TEST(TestGpuAllocators, PinnedAllocationFailure) { SKIP_IF_NO_DEVICES(); PinnedHostAllocator alloc; // Try to allocate an impossibly large amount of memory EXPECT_THROW(std::ignore = alloc.allocate(std::numeric_limits::max()), std::bad_alloc); } TEST(TestGpuAllocators, DeviceAllocationFailure) { SKIP_IF_NO_DEVICES(); DeviceAllocator alloc; // Try to allocate an impossibly large amount of memory EXPECT_THROW(std::ignore = alloc.allocate(std::numeric_limits::max()), std::bad_alloc); }