summaryrefslogtreecommitdiff
path: root/offload/unittests/OffloadAPI
diff options
context:
space:
mode:
authorMingming Liu <mingmingl@google.com>2025-09-10 15:25:31 -0700
committerGitHub <noreply@github.com>2025-09-10 15:25:31 -0700
commit1417dafa1db9cb1b2b09438aa9f53ea5ab6e36e2 (patch)
tree57f4b1f313c8cf74eed8819870f39c36ea263c68 /offload/unittests/OffloadAPI
parent898b813bc8a6d0276bf0f4769f5f2f64b34e632d (diff)
parentb8cefcb601ddaa18482555c4ff363c01a270c2fe (diff)
Merge branch 'main' into users/mingmingl-llvm/samplefdo-profile-formatusers/mingmingl-llvm/samplefdo-profile-format
Diffstat (limited to 'offload/unittests/OffloadAPI')
-rw-r--r--offload/unittests/OffloadAPI/common/Environment.cpp7
-rw-r--r--offload/unittests/OffloadAPI/common/Fixtures.hpp40
-rw-r--r--offload/unittests/OffloadAPI/device/olGetDeviceInfo.cpp36
-rw-r--r--offload/unittests/OffloadAPI/device/olGetDeviceInfoSize.cpp11
-rw-r--r--offload/unittests/OffloadAPI/memory/olMemFill.cpp117
-rw-r--r--offload/unittests/OffloadAPI/queue/olDestroyQueue.cpp9
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));
}