[llvm] [Offload] Add check-offload-unit for liboffload unittests (PR #137312)
Callum Fare via llvm-commits
llvm-commits at lists.llvm.org
Fri Apr 25 04:02:24 PDT 2025
https://github.com/callumfare updated https://github.com/llvm/llvm-project/pull/137312
>From ea0ea57e5784599770758dfce05cac583a3c3a76 Mon Sep 17 00:00:00 2001
From: Callum Fare <callum at codeplay.com>
Date: Thu, 24 Apr 2025 15:19:49 +0100
Subject: [PATCH] [Offload] Add check-offload-unit for liboffload unittests
---
offload/test/CMakeLists.txt | 34 ++++
offload/test/lit.cfg | 2 +-
offload/test/unit/lit.cfg.py | 24 +++
offload/test/unit/lit.site.cfg.in | 9 +
offload/unittests/CMakeLists.txt | 9 +-
offload/unittests/OffloadAPI/CMakeLists.txt | 4 +-
.../OffloadAPI/common/Environment.cpp | 7 +
.../OffloadAPI/device_code/CMakeLists.txt | 2 +-
offload/unittests/Plugins/CMakeLists.txt | 11 --
.../unittests/Plugins/NextgenPluginsTest.cpp | 167 ------------------
10 files changed, 82 insertions(+), 187 deletions(-)
create mode 100644 offload/test/unit/lit.cfg.py
create mode 100644 offload/test/unit/lit.site.cfg.in
delete mode 100644 offload/unittests/Plugins/CMakeLists.txt
delete mode 100644 offload/unittests/Plugins/NextgenPluginsTest.cpp
diff --git a/offload/test/CMakeLists.txt b/offload/test/CMakeLists.txt
index 4768d9ccf223b..6e103ccc720c8 100644
--- a/offload/test/CMakeLists.txt
+++ b/offload/test/CMakeLists.txt
@@ -63,3 +63,37 @@ add_offload_testsuite(check-offload
EXCLUDE_FROM_CHECK_ALL
DEPENDS llvm-offload-device-info omptarget ${OMP_DEPEND} ${LIBOMPTARGET_TESTED_PLUGINS}
ARGS ${LIBOMPTARGET_LIT_ARG_LIST})
+
+# Add liboffload unit tests based on available devices rather than configured targets
+macro(add_offload_unittest_suite target_name)
+ set(OFFLOAD_PLATFORM ${target_name})
+ string(TOLOWER "${OFFLOAD_PLATFORM}" SUITE_NAME)
+
+ configure_lit_site_cfg(
+ ${CMAKE_CURRENT_SOURCE_DIR}/unit/lit.site.cfg.in
+ ${CMAKE_CURRENT_BINARY_DIR}/unit/${SUITE_NAME}/lit.site.cfg
+ MAIN_CONFIG
+ ${CMAKE_CURRENT_SOURCE_DIR}/unit/lit.cfg.py)
+
+ add_lit_testsuite(check-offload-unit-${SUITE_NAME} "Running offload unittest suite for ${SUITE_NAME}"
+ ${CMAKE_CURRENT_BINARY_DIR}/unit/${SUITE_NAME}
+ EXCLUDE_FROM_CHECK_ALL
+ DEPENDS OffloadUnitTests)
+
+ list(APPEND OFFLOAD_UNIT_TEST_SUITES ${CMAKE_CURRENT_BINARY_DIR}/unit/${SUITE_NAME})
+endmacro()
+
+set (OFFLOAD_UNIT_TEST_SUITES "")
+
+if (LIBOMPTARGET_FOUND_NVIDIA_GPU)
+ add_offload_unittest_suite("CUDA")
+endif()
+
+if (LIBOMPTARGET_FOUND_AMDGPU_GPU)
+ add_offload_unittest_suite("AMDGPU")
+endif()
+
+add_lit_testsuite(check-offload-unit "Running offload unittest suites"
+ ${OFFLOAD_UNIT_TEST_SUITES}
+ EXCLUDE_FROM_CHECK_ALL
+ DEPENDS LLVMOffload OffloadUnitTests)
diff --git a/offload/test/lit.cfg b/offload/test/lit.cfg
index f7ed287e7aece..0725b56f0f05d 100644
--- a/offload/test/lit.cfg
+++ b/offload/test/lit.cfg
@@ -69,7 +69,7 @@ config.name = 'libomptarget :: ' + config.libomptarget_current_target
config.suffixes = ['.c', '.cpp', '.cc', '.f90', '.cu', '.td']
# excludes: A list of directories to exclude from the testuites.
-config.excludes = ['Inputs']
+config.excludes = ['Inputs', 'unit']
# test_source_root: The root path where tests are located.
config.test_source_root = os.path.dirname(__file__)
diff --git a/offload/test/unit/lit.cfg.py b/offload/test/unit/lit.cfg.py
new file mode 100644
index 0000000000000..08541f7dd7688
--- /dev/null
+++ b/offload/test/unit/lit.cfg.py
@@ -0,0 +1,24 @@
+# -*- Python -*-
+
+# Configuration file for the 'lit' test runner.
+
+import os
+import subprocess
+
+import lit.formats
+
+# name: The name of this test suite.
+config.name = "Offload-Unit-{}".format(config.offload_platform)
+
+# suffixes: A list of file extensions to treat as test files.
+config.suffixes = []
+
+config.environment = {"OFFLOAD_UNITTEST_PLATFORM": config.offload_platform}
+
+# test_source_root: The root path where tests are located.
+# test_exec_root: The root path where tests should be run.
+config.test_exec_root = os.path.join(config.library_dir, "unittests")
+config.test_source_root = config.test_exec_root
+
+# testFormat: The test format to use to interpret tests.
+config.test_format = lit.formats.GoogleTest(config.llvm_build_mode, ".unittests")
diff --git a/offload/test/unit/lit.site.cfg.in b/offload/test/unit/lit.site.cfg.in
new file mode 100644
index 0000000000000..aa1484058b576
--- /dev/null
+++ b/offload/test/unit/lit.site.cfg.in
@@ -0,0 +1,9 @@
+ at AUTO_GEN_COMMENT@
+
+config.library_dir = "@LIBOMPTARGET_LIBRARY_DIR@"
+config.llvm_build_mode = lit_config.substitute("@LLVM_BUILD_MODE@")
+config.offload_platform = "@OFFLOAD_PLATFORM@"
+
+# Let the main config do the real work.
+lit_config.load_config(config, "@CMAKE_CURRENT_SOURCE_DIR@/unit/lit.cfg.py")
+
diff --git a/offload/unittests/CMakeLists.txt b/offload/unittests/CMakeLists.txt
index 25ac4b2fa3675..f9cb56ae0c024 100644
--- a/offload/unittests/CMakeLists.txt
+++ b/offload/unittests/CMakeLists.txt
@@ -1,9 +1,8 @@
-add_custom_target(LibomptUnitTests)
-set_target_properties(LibomptUnitTests PROPERTIES FOLDER "Tests/UnitTests")
+add_custom_target(OffloadUnitTests)
+set_target_properties(OffloadUnitTests PROPERTIES FOLDER "Tests/UnitTests")
-function(add_libompt_unittest test_dirname)
- add_unittest(LibomptUnitTests ${test_dirname} ${ARGN})
+function(add_offload_unittest test_dirname)
+ add_unittest(OffloadUnitTests ${test_dirname} ${ARGN})
endfunction()
-# add_subdirectory(Plugins)
add_subdirectory(OffloadAPI)
diff --git a/offload/unittests/OffloadAPI/CMakeLists.txt b/offload/unittests/OffloadAPI/CMakeLists.txt
index c4d628a5a87f8..fb480e0443583 100644
--- a/offload/unittests/OffloadAPI/CMakeLists.txt
+++ b/offload/unittests/OffloadAPI/CMakeLists.txt
@@ -4,7 +4,7 @@ set(PLUGINS_TEST_INCLUDE ${LIBOMPTARGET_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}
add_subdirectory(device_code)
message(${OFFLOAD_TEST_DEVICE_CODE_PATH})
-add_libompt_unittest("offload.unittests"
+add_offload_unittest("offload.unittests"
${CMAKE_CURRENT_SOURCE_DIR}/common/Environment.cpp
${CMAKE_CURRENT_SOURCE_DIR}/platform/olGetPlatformInfo.cpp
${CMAKE_CURRENT_SOURCE_DIR}/platform/olGetPlatformInfoSize.cpp
@@ -22,7 +22,7 @@ add_libompt_unittest("offload.unittests"
${CMAKE_CURRENT_SOURCE_DIR}/kernel/olGetKernel.cpp
${CMAKE_CURRENT_SOURCE_DIR}/kernel/olLaunchKernel.cpp
)
-add_dependencies("offload.unittests" ${PLUGINS_TEST_COMMON} LibomptUnitTestsDeviceBins)
+add_dependencies("offload.unittests" ${PLUGINS_TEST_COMMON} OffloadUnitTestsDeviceBins)
target_compile_definitions("offload.unittests" PRIVATE DEVICE_CODE_PATH="${OFFLOAD_TEST_DEVICE_CODE_PATH}")
target_link_libraries("offload.unittests" PRIVATE ${PLUGINS_TEST_COMMON})
target_include_directories("offload.unittests" PRIVATE ${PLUGINS_TEST_INCLUDE})
diff --git a/offload/unittests/OffloadAPI/common/Environment.cpp b/offload/unittests/OffloadAPI/common/Environment.cpp
index 88cf33e45f3d5..7c2e86c0ec931 100644
--- a/offload/unittests/OffloadAPI/common/Environment.cpp
+++ b/offload/unittests/OffloadAPI/common/Environment.cpp
@@ -65,6 +65,13 @@ ol_device_handle_t TestEnvironment::getDevice() {
static ol_device_handle_t Device = nullptr;
if (!Device) {
+ if (const char *EnvStr = getenv("OFFLOAD_UNITTEST_PLATFORM")) {
+ if (SelectedPlatform != "")
+ errs() << "Warning: --platform argument ignored as "
+ "OFFLOAD_UNITTEST_PLATFORM env var overrides it.\n";
+ SelectedPlatform = EnvStr;
+ }
+
if (SelectedPlatform != "") {
olIterateDevices(
[](ol_device_handle_t D, void *Data) {
diff --git a/offload/unittests/OffloadAPI/device_code/CMakeLists.txt b/offload/unittests/OffloadAPI/device_code/CMakeLists.txt
index ded555b3a3cf4..5814943e4aaa9 100644
--- a/offload/unittests/OffloadAPI/device_code/CMakeLists.txt
+++ b/offload/unittests/OffloadAPI/device_code/CMakeLists.txt
@@ -62,6 +62,6 @@ endif()
add_offload_test_device_code(foo.c foo)
add_offload_test_device_code(bar.c bar)
-add_custom_target(LibomptUnitTestsDeviceBins DEPENDS ${BIN_PATHS})
+add_custom_target(OffloadUnitTestsDeviceBins DEPENDS ${BIN_PATHS})
set(OFFLOAD_TEST_DEVICE_CODE_PATH ${CMAKE_CURRENT_BINARY_DIR} PARENT_SCOPE)
diff --git a/offload/unittests/Plugins/CMakeLists.txt b/offload/unittests/Plugins/CMakeLists.txt
deleted file mode 100644
index 06e5288ad6f6b..0000000000000
--- a/offload/unittests/Plugins/CMakeLists.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-set(PLUGINS_TEST_COMMON omptarget)
-set(PLUGINS_TEST_SOURCES NextgenPluginsTest.cpp)
-set(PLUGINS_TEST_INCLUDE ${LIBOMPTARGET_INCLUDE_DIR})
-
-foreach(PLUGIN IN LISTS LIBOMPTARGET_TESTED_PLUGINS)
- message(STATUS "Building plugin unit tests for ${PLUGIN}")
- add_libompt_unittest("${PLUGIN}.unittests" ${PLUGINS_TEST_SOURCES})
- add_dependencies("${PLUGIN}.unittests" ${PLUGINS_TEST_COMMON} ${PLUGIN})
- target_link_libraries("${PLUGIN}.unittests" PRIVATE ${PLUGINS_TEST_COMMON} ${PLUGIN})
- target_include_directories("${PLUGIN}.unittests" PRIVATE ${PLUGINS_TEST_INCLUDE})
-endforeach()
diff --git a/offload/unittests/Plugins/NextgenPluginsTest.cpp b/offload/unittests/Plugins/NextgenPluginsTest.cpp
deleted file mode 100644
index 479b3f614aed2..0000000000000
--- a/offload/unittests/Plugins/NextgenPluginsTest.cpp
+++ /dev/null
@@ -1,167 +0,0 @@
-//===------- unittests/Plugins/NextgenPluginsTest.cpp - Plugin tests ------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "omptarget.h"
-#include "gtest/gtest.h"
-
-#include <unordered_set>
-
-const int DEVICE_ID = 0;
-std::unordered_set<int> setup_map;
-
-int init_test_device(int ID) {
- if (setup_map.find(ID) != setup_map.end()) {
- return OFFLOAD_SUCCESS;
- }
- if (__tgt_rtl_init_plugin() == OFFLOAD_FAIL ||
- __tgt_rtl_init_device(ID) == OFFLOAD_FAIL) {
- return OFFLOAD_FAIL;
- }
- setup_map.insert(ID);
- return OFFLOAD_SUCCESS;
-}
-
-// Test plugin initialization
-TEST(NextgenPluginsTest, PluginInit) {
- EXPECT_EQ(OFFLOAD_SUCCESS, init_test_device(DEVICE_ID));
-}
-
-// Test GPU allocation and R/W
-TEST(NextgenPluginsTest, PluginAlloc) {
- int32_t test_value = 23;
- int32_t host_value = -1;
- int64_t var_size = sizeof(int32_t);
-
- // Init plugin and device
- EXPECT_EQ(OFFLOAD_SUCCESS, init_test_device(DEVICE_ID));
-
- // Allocate memory
- void *device_ptr =
- __tgt_rtl_data_alloc(DEVICE_ID, var_size, nullptr, TARGET_ALLOC_DEFAULT);
-
- // Check that the result is not null
- EXPECT_NE(device_ptr, nullptr);
-
- // Submit data to device
- EXPECT_EQ(OFFLOAD_SUCCESS, __tgt_rtl_data_submit(DEVICE_ID, device_ptr,
- &test_value, var_size));
-
- // Read data from device
- EXPECT_EQ(OFFLOAD_SUCCESS, __tgt_rtl_data_retrieve(DEVICE_ID, &host_value,
- device_ptr, var_size));
-
- // Compare values
- EXPECT_EQ(host_value, test_value);
-
- // Cleanup data
- EXPECT_EQ(OFFLOAD_SUCCESS,
- __tgt_rtl_data_delete(DEVICE_ID, device_ptr, TARGET_ALLOC_DEFAULT));
-}
-
-// Test async GPU allocation and R/W
-TEST(NextgenPluginsTest, PluginAsyncAlloc) {
- int32_t test_value = 47;
- int32_t host_value = -1;
- int64_t var_size = sizeof(int32_t);
- __tgt_async_info *info;
-
- // Init plugin and device
- EXPECT_EQ(OFFLOAD_SUCCESS, init_test_device(DEVICE_ID));
-
- // Check if device supports async
- // Platforms like x86_64 don't support it
- if (__tgt_rtl_init_async_info(DEVICE_ID, &info) == OFFLOAD_SUCCESS) {
- // Allocate memory
- void *device_ptr = __tgt_rtl_data_alloc(DEVICE_ID, var_size, nullptr,
- TARGET_ALLOC_DEFAULT);
-
- // Check that the result is not null
- EXPECT_NE(device_ptr, nullptr);
-
- // Submit data to device asynchronously
- EXPECT_EQ(OFFLOAD_SUCCESS,
- __tgt_rtl_data_submit_async(DEVICE_ID, device_ptr, &test_value,
- var_size, info));
-
- // Wait for async request to process
- EXPECT_EQ(OFFLOAD_SUCCESS, __tgt_rtl_synchronize(DEVICE_ID, info));
-
- // Read data from device
- EXPECT_EQ(OFFLOAD_SUCCESS,
- __tgt_rtl_data_retrieve_async(DEVICE_ID, &host_value, device_ptr,
- var_size, info));
-
- // Wait for async request to process
- EXPECT_EQ(OFFLOAD_SUCCESS, __tgt_rtl_synchronize(DEVICE_ID, info));
-
- // Compare values
- EXPECT_EQ(host_value, test_value);
-
- // Cleanup data
- EXPECT_EQ(OFFLOAD_SUCCESS, __tgt_rtl_data_delete(DEVICE_ID, device_ptr,
- TARGET_ALLOC_DEFAULT));
- }
-}
-
-// Test GPU data exchange
-TEST(NextgenPluginsTest, PluginDataSwap) {
- int32_t test_value = 23;
- int32_t host_value = -1;
- int64_t var_size = sizeof(int32_t);
-
- // Look for compatible device
- int DEVICE_TWO = -1;
- for (int i = 1; i < __tgt_rtl_number_of_devices(); i++) {
- if (__tgt_rtl_is_data_exchangable(DEVICE_ID, i)) {
- DEVICE_TWO = i;
- break;
- }
- }
-
- // Only run test if we have multiple GPUs to test
- // GPUs must be compatible for test to work
- if (DEVICE_TWO >= 1) {
- // Init both GPUs
- EXPECT_EQ(OFFLOAD_SUCCESS, init_test_device(DEVICE_ID));
- EXPECT_EQ(OFFLOAD_SUCCESS, init_test_device(DEVICE_TWO));
-
- // Allocate memory on both GPUs
- // DEVICE_ID will be the source
- // DEVICE_TWO will be the destination
- void *source_ptr = __tgt_rtl_data_alloc(DEVICE_ID, var_size, nullptr,
- TARGET_ALLOC_DEFAULT);
- void *dest_ptr = __tgt_rtl_data_alloc(DEVICE_TWO, var_size, nullptr,
- TARGET_ALLOC_DEFAULT);
-
- // Check for success in allocation
- EXPECT_NE(source_ptr, nullptr);
- EXPECT_NE(dest_ptr, nullptr);
-
- // Write data to source
- EXPECT_EQ(OFFLOAD_SUCCESS, __tgt_rtl_data_submit(DEVICE_ID, source_ptr,
- &test_value, var_size));
-
- // Transfer data between devices
- EXPECT_EQ(OFFLOAD_SUCCESS,
- __tgt_rtl_data_exchange(DEVICE_ID, source_ptr, DEVICE_TWO,
- dest_ptr, var_size));
-
- // Read from destination device (DEVICE_TWO) memory
- EXPECT_EQ(OFFLOAD_SUCCESS, __tgt_rtl_data_retrieve(DEVICE_TWO, &host_value,
- dest_ptr, var_size));
-
- // Ensure match
- EXPECT_EQ(host_value, test_value);
-
- // Cleanup
- EXPECT_EQ(OFFLOAD_SUCCESS, __tgt_rtl_data_delete(DEVICE_ID, source_ptr,
- TARGET_ALLOC_DEFAULT));
- EXPECT_EQ(OFFLOAD_SUCCESS, __tgt_rtl_data_delete(DEVICE_TWO, dest_ptr,
- TARGET_ALLOC_DEFAULT));
- }
-}
More information about the llvm-commits
mailing list