diff options
| author | Mingming Liu <mingmingl@google.com> | 2025-09-10 15:25:31 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-09-10 15:25:31 -0700 |
| commit | 1417dafa1db9cb1b2b09438aa9f53ea5ab6e36e2 (patch) | |
| tree | 57f4b1f313c8cf74eed8819870f39c36ea263c68 /offload/unittests/OffloadAPI | |
| parent | 898b813bc8a6d0276bf0f4769f5f2f64b34e632d (diff) | |
| parent | b8cefcb601ddaa18482555c4ff363c01a270c2fe (diff) | |
Merge branch 'main' into users/mingmingl-llvm/samplefdo-profile-formatusers/mingmingl-llvm/samplefdo-profile-format
Diffstat (limited to 'offload/unittests/OffloadAPI')
6 files changed, 188 insertions, 32 deletions
diff --git a/offload/unittests/OffloadAPI/common/Environment.cpp b/offload/unittests/OffloadAPI/common/Environment.cpp index ef092cd4187d..c9da6ef9be7c 100644 --- a/offload/unittests/OffloadAPI/common/Environment.cpp +++ b/offload/unittests/OffloadAPI/common/Environment.cpp @@ -41,9 +41,9 @@ raw_ostream &operator<<(raw_ostream &Out, raw_ostream &operator<<(raw_ostream &Out, const ol_device_handle_t &Device) { size_t Size; - olGetDeviceInfoSize(Device, OL_DEVICE_INFO_NAME, &Size); + olGetDeviceInfoSize(Device, OL_DEVICE_INFO_PRODUCT_NAME, &Size); std::vector<char> Name(Size); - olGetDeviceInfo(Device, OL_DEVICE_INFO_NAME, Size, Name.data()); + olGetDeviceInfo(Device, OL_DEVICE_INFO_PRODUCT_NAME, Size, Name.data()); Out << Name.data(); return Out; } @@ -129,6 +129,9 @@ const std::vector<TestEnvironment::Device> &TestEnvironment::getDevices() { } } + if (Devices.size() == 0) + errs() << "Warning: No devices found for OffloadAPI tests.\n"; + return Devices; } diff --git a/offload/unittests/OffloadAPI/common/Fixtures.hpp b/offload/unittests/OffloadAPI/common/Fixtures.hpp index fe7198a9c283..c5a35faba7a2 100644 --- a/offload/unittests/OffloadAPI/common/Fixtures.hpp +++ b/offload/unittests/OffloadAPI/common/Fixtures.hpp @@ -89,6 +89,40 @@ template <typename Fn> inline void threadify(Fn body) { } } +/// Enqueues a task to the queue that can be manually resolved. +// It will block until `trigger` is called. +struct ManuallyTriggeredTask { + std::mutex M; + std::condition_variable CV; + bool Flag = false; + ol_event_handle_t CompleteEvent; + + ol_result_t enqueue(ol_queue_handle_t Queue) { + if (auto Err = olLaunchHostFunction( + Queue, + [](void *That) { + static_cast<ManuallyTriggeredTask *>(That)->wait(); + }, + this)) + return Err; + + return olCreateEvent(Queue, &CompleteEvent); + } + + void wait() { + std::unique_lock<std::mutex> lk(M); + CV.wait_for(lk, std::chrono::milliseconds(1000), [&] { return Flag; }); + EXPECT_TRUE(Flag); + } + + ol_result_t trigger() { + Flag = true; + CV.notify_one(); + + return olSyncEvent(CompleteEvent); + } +}; + struct OffloadTest : ::testing::Test { ol_device_handle_t Host = TestEnvironment::getHostDevice(); }; @@ -216,9 +250,13 @@ struct OffloadEventTest : OffloadQueueTest { ol_event_handle_t Event = nullptr; }; +// Devices might not be available for offload testing, so allow uninstantiated +// tests (as the device list will be empty). This means that all tests requiring +// a device will be silently skipped. #define OFFLOAD_TESTS_INSTANTIATE_DEVICE_FIXTURE(FIXTURE) \ INSTANTIATE_TEST_SUITE_P( \ , FIXTURE, ::testing::ValuesIn(TestEnvironment::getDevices()), \ [](const ::testing::TestParamInfo<TestEnvironment::Device> &info) { \ return SanitizeString(info.param.Name); \ - }) + }); \ + GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(FIXTURE) diff --git a/offload/unittests/OffloadAPI/device/olGetDeviceInfo.cpp b/offload/unittests/OffloadAPI/device/olGetDeviceInfo.cpp index 212a5d6ddf22..8cb0b8065c33 100644 --- a/offload/unittests/OffloadAPI/device/olGetDeviceInfo.cpp +++ b/offload/unittests/OffloadAPI/device/olGetDeviceInfo.cpp @@ -86,6 +86,29 @@ TEST_P(olGetDeviceInfoTest, HostName) { ASSERT_EQ(std::strlen(Name.data()), Size - 1); } +TEST_P(olGetDeviceInfoTest, SuccessProductName) { + size_t Size = 0; + ASSERT_SUCCESS( + olGetDeviceInfoSize(Device, OL_DEVICE_INFO_PRODUCT_NAME, &Size)); + ASSERT_GT(Size, 0ul); + std::vector<char> Name; + Name.resize(Size); + ASSERT_SUCCESS( + olGetDeviceInfo(Device, OL_DEVICE_INFO_PRODUCT_NAME, Size, Name.data())); + ASSERT_EQ(std::strlen(Name.data()), Size - 1); +} + +TEST_P(olGetDeviceInfoTest, HostProductName) { + size_t Size = 0; + ASSERT_SUCCESS(olGetDeviceInfoSize(Host, OL_DEVICE_INFO_PRODUCT_NAME, &Size)); + ASSERT_GT(Size, 0ul); + std::vector<char> Name; + Name.resize(Size); + ASSERT_SUCCESS( + olGetDeviceInfo(Host, OL_DEVICE_INFO_PRODUCT_NAME, Size, Name.data())); + ASSERT_EQ(std::strlen(Name.data()), Size - 1); +} + TEST_P(olGetDeviceInfoTest, SuccessVendor) { size_t Size = 0; ASSERT_SUCCESS(olGetDeviceInfoSize(Device, OL_DEVICE_INFO_VENDOR, &Size)); @@ -122,6 +145,19 @@ TEST_P(olGetDeviceInfoTest, SuccessMaxWorkGroupSizePerDimension) { ASSERT_GT(Value.z, 0u); } +OL_DEVICE_INFO_TEST_VALUE_GT(MaxWorkSize, uint32_t, + OL_DEVICE_INFO_MAX_WORK_SIZE, 0); + +TEST_P(olGetDeviceInfoTest, SuccessMaxWorkSizePerDimension) { + ol_dimensions_t Value{0, 0, 0}; + ASSERT_SUCCESS(olGetDeviceInfo(Device, + OL_DEVICE_INFO_MAX_WORK_SIZE_PER_DIMENSION, + sizeof(Value), &Value)); + ASSERT_GT(Value.x, 0u); + ASSERT_GT(Value.y, 0u); + ASSERT_GT(Value.z, 0u); +} + OL_DEVICE_INFO_TEST_DEVICE_VALUE_GT(VendorId, uint32_t, OL_DEVICE_INFO_VENDOR_ID, 0); OL_DEVICE_INFO_TEST_HOST_SUCCESS(VendorId, uint32_t, OL_DEVICE_INFO_VENDOR_ID); diff --git a/offload/unittests/OffloadAPI/device/olGetDeviceInfoSize.cpp b/offload/unittests/OffloadAPI/device/olGetDeviceInfoSize.cpp index a28089d918e0..c4a3c2d5e3c7 100644 --- a/offload/unittests/OffloadAPI/device/olGetDeviceInfoSize.cpp +++ b/offload/unittests/OffloadAPI/device/olGetDeviceInfoSize.cpp @@ -31,10 +31,13 @@ OL_DEVICE_INFO_SIZE_TEST_EQ(Type, ol_device_type_t, OL_DEVICE_INFO_TYPE); OL_DEVICE_INFO_SIZE_TEST_EQ(Platform, ol_platform_handle_t, OL_DEVICE_INFO_PLATFORM); OL_DEVICE_INFO_SIZE_TEST_NONZERO(Name, OL_DEVICE_INFO_NAME); +OL_DEVICE_INFO_SIZE_TEST_NONZERO(ProductName, OL_DEVICE_INFO_PRODUCT_NAME); OL_DEVICE_INFO_SIZE_TEST_NONZERO(Vendor, OL_DEVICE_INFO_VENDOR); OL_DEVICE_INFO_SIZE_TEST_NONZERO(DriverVersion, OL_DEVICE_INFO_DRIVER_VERSION); OL_DEVICE_INFO_SIZE_TEST_EQ(MaxWorkGroupSize, uint32_t, OL_DEVICE_INFO_MAX_WORK_GROUP_SIZE); +OL_DEVICE_INFO_SIZE_TEST_EQ(MaxWorkSize, uint32_t, + OL_DEVICE_INFO_MAX_WORK_SIZE); OL_DEVICE_INFO_SIZE_TEST_EQ(VendorId, uint32_t, OL_DEVICE_INFO_VENDOR_ID); OL_DEVICE_INFO_SIZE_TEST_EQ(NumComputeUnits, uint32_t, OL_DEVICE_INFO_NUM_COMPUTE_UNITS); @@ -76,6 +79,14 @@ TEST_P(olGetDeviceInfoSizeTest, SuccessMaxWorkGroupSizePerDimension) { ASSERT_EQ(Size, sizeof(uint32_t) * 3); } +TEST_P(olGetDeviceInfoSizeTest, SuccessMaxWorkSizePerDimension) { + size_t Size = 0; + ASSERT_SUCCESS(olGetDeviceInfoSize( + Device, OL_DEVICE_INFO_MAX_WORK_SIZE_PER_DIMENSION, &Size)); + ASSERT_EQ(Size, sizeof(ol_dimensions_t)); + ASSERT_EQ(Size, sizeof(uint32_t) * 3); +} + TEST_P(olGetDeviceInfoSizeTest, InvalidNullHandle) { size_t Size = 0; ASSERT_ERROR(OL_ERRC_INVALID_NULL_HANDLE, diff --git a/offload/unittests/OffloadAPI/memory/olMemFill.cpp b/offload/unittests/OffloadAPI/memory/olMemFill.cpp index 1b0bafa20208..a84ed3d78ecc 100644 --- a/offload/unittests/OffloadAPI/memory/olMemFill.cpp +++ b/offload/unittests/OffloadAPI/memory/olMemFill.cpp @@ -10,75 +10,129 @@ #include <OffloadAPI.h> #include <gtest/gtest.h> -using olMemFillTest = OffloadQueueTest; +struct olMemFillTest : OffloadQueueTest { + template <typename PatternTy, PatternTy PatternVal, size_t Size, + bool Block = false> + void test_body() { + ManuallyTriggeredTask Manual; + + // Block/enqueue tests ensure that the test has been enqueued to a queue + // (rather than being done synchronously if the queue happens to be empty) + if constexpr (Block) { + ASSERT_SUCCESS(Manual.enqueue(Queue)); + } + + void *Alloc; + ASSERT_SUCCESS(olMemAlloc(Device, OL_ALLOC_TYPE_MANAGED, Size, &Alloc)); + + PatternTy Pattern = PatternVal; + ASSERT_SUCCESS(olMemFill(Queue, Alloc, sizeof(Pattern), &Pattern, Size)); + + if constexpr (Block) { + ASSERT_SUCCESS(Manual.trigger()); + } + olSyncQueue(Queue); + + size_t N = Size / sizeof(Pattern); + for (size_t i = 0; i < N; i++) { + PatternTy *AllocPtr = reinterpret_cast<PatternTy *>(Alloc); + ASSERT_EQ(AllocPtr[i], Pattern); + } + + olMemFree(Alloc); + } +}; OFFLOAD_TESTS_INSTANTIATE_DEVICE_FIXTURE(olMemFillTest); -TEST_P(olMemFillTest, Success8) { - constexpr size_t Size = 1024; - void *Alloc; - ASSERT_SUCCESS(olMemAlloc(Device, OL_ALLOC_TYPE_MANAGED, Size, &Alloc)); - - uint8_t Pattern = 0x42; - ASSERT_SUCCESS(olMemFill(Queue, Alloc, sizeof(Pattern), &Pattern, Size)); - - olSyncQueue(Queue); +TEST_P(olMemFillTest, Success8) { test_body<uint8_t, 0x42, 1024>(); } +TEST_P(olMemFillTest, Success8NotMultiple4) { + test_body<uint8_t, 0x42, 1023>(); +} +TEST_P(olMemFillTest, Success8Enqueue) { + test_body<uint8_t, 0x42, 1024, true>(); +} +TEST_P(olMemFillTest, Success8NotMultiple4Enqueue) { + test_body<uint8_t, 0x42, 1023, true>(); +} - size_t N = Size / sizeof(Pattern); - for (size_t i = 0; i < N; i++) { - uint8_t *AllocPtr = reinterpret_cast<uint8_t *>(Alloc); - ASSERT_EQ(AllocPtr[i], Pattern); - } +TEST_P(olMemFillTest, Success16) { test_body<uint8_t, 0x42, 1024>(); } +TEST_P(olMemFillTest, Success16NotMultiple4) { + test_body<uint16_t, 0x4243, 1022>(); +} +TEST_P(olMemFillTest, Success16Enqueue) { + test_body<uint8_t, 0x42, 1024, true>(); +} +TEST_P(olMemFillTest, Success16NotMultiple4Enqueue) { + test_body<uint16_t, 0x4243, 1022, true>(); +} - olMemFree(Alloc); +TEST_P(olMemFillTest, Success32) { test_body<uint32_t, 0xDEADBEEF, 1024>(); } +TEST_P(olMemFillTest, Success32Enqueue) { + test_body<uint32_t, 0xDEADBEEF, 1024, true>(); } -TEST_P(olMemFillTest, Success16) { +TEST_P(olMemFillTest, SuccessLarge) { constexpr size_t Size = 1024; void *Alloc; ASSERT_SUCCESS(olMemAlloc(Device, OL_ALLOC_TYPE_MANAGED, Size, &Alloc)); - uint16_t Pattern = 0x4242; + struct PatternT { + uint64_t A; + uint64_t B; + } Pattern{UINT64_MAX, UINT64_MAX}; + ASSERT_SUCCESS(olMemFill(Queue, Alloc, sizeof(Pattern), &Pattern, Size)); olSyncQueue(Queue); size_t N = Size / sizeof(Pattern); for (size_t i = 0; i < N; i++) { - uint16_t *AllocPtr = reinterpret_cast<uint16_t *>(Alloc); - ASSERT_EQ(AllocPtr[i], Pattern); + PatternT *AllocPtr = reinterpret_cast<PatternT *>(Alloc); + ASSERT_EQ(AllocPtr[i].A, UINT64_MAX); + ASSERT_EQ(AllocPtr[i].B, UINT64_MAX); } olMemFree(Alloc); } -TEST_P(olMemFillTest, Success32) { +TEST_P(olMemFillTest, SuccessLargeEnqueue) { constexpr size_t Size = 1024; void *Alloc; + ManuallyTriggeredTask Manual; + ASSERT_SUCCESS(Manual.enqueue(Queue)); + ASSERT_SUCCESS(olMemAlloc(Device, OL_ALLOC_TYPE_MANAGED, Size, &Alloc)); - uint32_t Pattern = 0xDEADBEEF; + struct PatternT { + uint64_t A; + uint64_t B; + } Pattern{UINT64_MAX, UINT64_MAX}; + ASSERT_SUCCESS(olMemFill(Queue, Alloc, sizeof(Pattern), &Pattern, Size)); + Manual.trigger(); olSyncQueue(Queue); size_t N = Size / sizeof(Pattern); for (size_t i = 0; i < N; i++) { - uint32_t *AllocPtr = reinterpret_cast<uint32_t *>(Alloc); - ASSERT_EQ(AllocPtr[i], Pattern); + PatternT *AllocPtr = reinterpret_cast<PatternT *>(Alloc); + ASSERT_EQ(AllocPtr[i].A, UINT64_MAX); + ASSERT_EQ(AllocPtr[i].B, UINT64_MAX); } olMemFree(Alloc); } -TEST_P(olMemFillTest, SuccessLarge) { - constexpr size_t Size = 1024; +TEST_P(olMemFillTest, SuccessLargeByteAligned) { + constexpr size_t Size = 17 * 64; void *Alloc; ASSERT_SUCCESS(olMemAlloc(Device, OL_ALLOC_TYPE_MANAGED, Size, &Alloc)); - struct PatternT { + struct __attribute__((packed)) PatternT { uint64_t A; uint64_t B; - } Pattern{UINT64_MAX, UINT64_MAX}; + uint8_t C; + } Pattern{UINT64_MAX, UINT64_MAX, 255}; ASSERT_SUCCESS(olMemFill(Queue, Alloc, sizeof(Pattern), &Pattern, Size)); @@ -89,14 +143,18 @@ TEST_P(olMemFillTest, SuccessLarge) { PatternT *AllocPtr = reinterpret_cast<PatternT *>(Alloc); ASSERT_EQ(AllocPtr[i].A, UINT64_MAX); ASSERT_EQ(AllocPtr[i].B, UINT64_MAX); + ASSERT_EQ(AllocPtr[i].C, 255); } olMemFree(Alloc); } -TEST_P(olMemFillTest, SuccessLargeByteAligned) { +TEST_P(olMemFillTest, SuccessLargeByteAlignedEnqueue) { constexpr size_t Size = 17 * 64; void *Alloc; + ManuallyTriggeredTask Manual; + ASSERT_SUCCESS(Manual.enqueue(Queue)); + ASSERT_SUCCESS(olMemAlloc(Device, OL_ALLOC_TYPE_MANAGED, Size, &Alloc)); struct __attribute__((packed)) PatternT { @@ -107,6 +165,7 @@ TEST_P(olMemFillTest, SuccessLargeByteAligned) { ASSERT_SUCCESS(olMemFill(Queue, Alloc, sizeof(Pattern), &Pattern, Size)); + Manual.trigger(); olSyncQueue(Queue); size_t N = Size / sizeof(Pattern); diff --git a/offload/unittests/OffloadAPI/queue/olDestroyQueue.cpp b/offload/unittests/OffloadAPI/queue/olDestroyQueue.cpp index 0dc8527df532..aa9e372ede2c 100644 --- a/offload/unittests/OffloadAPI/queue/olDestroyQueue.cpp +++ b/offload/unittests/OffloadAPI/queue/olDestroyQueue.cpp @@ -18,6 +18,15 @@ TEST_P(olDestroyQueueTest, Success) { Queue = nullptr; } +TEST_P(olDestroyQueueTest, SuccessDelayedResolution) { + ManuallyTriggeredTask Manual; + ASSERT_SUCCESS(Manual.enqueue(Queue)); + ASSERT_SUCCESS(olDestroyQueue(Queue)); + Queue = nullptr; + + ASSERT_SUCCESS(Manual.trigger()); +} + TEST_P(olDestroyQueueTest, InvalidNullHandle) { ASSERT_ERROR(OL_ERRC_INVALID_NULL_HANDLE, olDestroyQueue(nullptr)); } |
