Skip to content

Commit 6022a52

Browse files
authored
[Offload] Add check-offload-unit for liboffload unittests (#137312)
Adds a `check-offload-unit` target for running the liboffload unit test suite. This unit test binary runs the tests for every available device. This can optionally filtered to devices from a single platform, but the check target runs on everything. The target is not part of `check-offload` and does not get propagated to the top level build. I'm not sure if either of these things are desirable, but I'm happy to look into it if we want. Also remove the `offload/unittests/Plugins` test as it's dead code and doesn't build.
1 parent 7b70fc7 commit 6022a52

29 files changed

+322
-398
lines changed

offload/liboffload/src/OffloadImpl.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,9 @@ void initPlugins() {
142142

143143
// Preemptively initialize all devices in the plugin
144144
for (auto &Platform : Platforms()) {
145+
// Do not use the host plugin - it isn't supported.
146+
if (Platform.BackendType == OL_PLATFORM_BACKEND_UNKNOWN)
147+
continue;
145148
auto Err = Platform.Plugin->init();
146149
[[maybe_unused]] std::string InfoMsg = toString(std::move(Err));
147150
for (auto DevNum = 0; DevNum < Platform.Plugin->number_of_devices();

offload/test/CMakeLists.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,15 @@ add_offload_testsuite(check-offload
6363
EXCLUDE_FROM_CHECK_ALL
6464
DEPENDS llvm-offload-device-info omptarget ${OMP_DEPEND} ${LIBOMPTARGET_TESTED_PLUGINS}
6565
ARGS ${LIBOMPTARGET_LIT_ARG_LIST})
66+
67+
# Add liboffload unit tests - the test binary will run on all available devices
68+
configure_lit_site_cfg(
69+
${CMAKE_CURRENT_SOURCE_DIR}/unit/lit.site.cfg.in
70+
${CMAKE_CURRENT_BINARY_DIR}/unit/lit.site.cfg
71+
MAIN_CONFIG
72+
${CMAKE_CURRENT_SOURCE_DIR}/unit/lit.cfg.py)
73+
74+
add_lit_testsuite(check-offload-unit "Running offload unittest suites"
75+
${CMAKE_CURRENT_BINARY_DIR}/unit
76+
EXCLUDE_FROM_CHECK_ALL
77+
DEPENDS LLVMOffload OffloadUnitTests)

offload/test/lit.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ config.name = 'libomptarget :: ' + config.libomptarget_current_target
6969
config.suffixes = ['.c', '.cpp', '.cc', '.f90', '.cu', '.td']
7070

7171
# excludes: A list of directories to exclude from the testuites.
72-
config.excludes = ['Inputs']
72+
config.excludes = ['Inputs', 'unit']
7373

7474
# test_source_root: The root path where tests are located.
7575
config.test_source_root = os.path.dirname(__file__)

offload/test/unit/lit.cfg.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# -*- Python -*-
2+
3+
# Configuration file for the 'lit' test runner.
4+
5+
import os
6+
import subprocess
7+
8+
import lit.formats
9+
10+
# name: The name of this test suite.
11+
config.name = "Offload-Unit"
12+
13+
# suffixes: A list of file extensions to treat as test files.
14+
config.suffixes = []
15+
16+
# test_source_root: The root path where tests are located.
17+
# test_exec_root: The root path where tests should be run.
18+
config.test_exec_root = os.path.join(config.library_dir, "unittests")
19+
config.test_source_root = config.test_exec_root
20+
21+
# testFormat: The test format to use to interpret tests.
22+
config.test_format = lit.formats.GoogleTest(config.llvm_build_mode, ".unittests")

offload/test/unit/lit.site.cfg.in

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
@AUTO_GEN_COMMENT@
2+
3+
config.library_dir = "@LIBOMPTARGET_LIBRARY_DIR@"
4+
config.llvm_build_mode = lit_config.substitute("@LLVM_BUILD_MODE@")
5+
6+
# Let the main config do the real work.
7+
lit_config.load_config(config, "@CMAKE_CURRENT_SOURCE_DIR@/unit/lit.cfg.py")
8+

offload/unittests/CMakeLists.txt

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
add_custom_target(LibomptUnitTests)
2-
set_target_properties(LibomptUnitTests PROPERTIES FOLDER "Tests/UnitTests")
1+
add_custom_target(OffloadUnitTests)
2+
set_target_properties(OffloadUnitTests PROPERTIES FOLDER "Tests/UnitTests")
33

4-
function(add_libompt_unittest test_dirname)
5-
add_unittest(LibomptUnitTests ${test_dirname} ${ARGN})
4+
function(add_offload_unittest test_dirname)
5+
add_unittest(OffloadUnitTests ${test_dirname} ${ARGN})
66
endfunction()
77

8-
# add_subdirectory(Plugins)
98
add_subdirectory(OffloadAPI)

offload/unittests/OffloadAPI/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ set(PLUGINS_TEST_INCLUDE ${LIBOMPTARGET_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}
44
add_subdirectory(device_code)
55
message(${OFFLOAD_TEST_DEVICE_CODE_PATH})
66

7-
add_libompt_unittest("offload.unittests"
7+
add_offload_unittest("offload.unittests"
88
${CMAKE_CURRENT_SOURCE_DIR}/common/Environment.cpp
99
${CMAKE_CURRENT_SOURCE_DIR}/platform/olGetPlatformInfo.cpp
1010
${CMAKE_CURRENT_SOURCE_DIR}/platform/olGetPlatformInfoSize.cpp
@@ -22,7 +22,7 @@ add_libompt_unittest("offload.unittests"
2222
${CMAKE_CURRENT_SOURCE_DIR}/kernel/olGetKernel.cpp
2323
${CMAKE_CURRENT_SOURCE_DIR}/kernel/olLaunchKernel.cpp
2424
)
25-
add_dependencies("offload.unittests" ${PLUGINS_TEST_COMMON} LibomptUnitTestsDeviceBins)
25+
add_dependencies("offload.unittests" ${PLUGINS_TEST_COMMON} OffloadUnitTestsDeviceBins)
2626
target_compile_definitions("offload.unittests" PRIVATE DEVICE_CODE_PATH="${OFFLOAD_TEST_DEVICE_CODE_PATH}")
2727
target_link_libraries("offload.unittests" PRIVATE ${PLUGINS_TEST_COMMON})
2828
target_include_directories("offload.unittests" PRIVATE ${PLUGINS_TEST_INCLUDE})

offload/unittests/OffloadAPI/common/Environment.cpp

Lines changed: 47 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,15 @@ raw_ostream &operator<<(raw_ostream &Out,
3737
return Out;
3838
}
3939

40+
raw_ostream &operator<<(raw_ostream &Out, const ol_device_handle_t &Device) {
41+
size_t Size;
42+
olGetDeviceInfoSize(Device, OL_DEVICE_INFO_NAME, &Size);
43+
std::vector<char> Name(Size);
44+
olGetDeviceInfo(Device, OL_DEVICE_INFO_NAME, Size, Name.data());
45+
Out << Name.data();
46+
return Out;
47+
}
48+
4049
void printPlatforms() {
4150
SmallDenseSet<ol_platform_handle_t> Platforms;
4251
using DeviceVecT = SmallVector<ol_device_handle_t, 8>;
@@ -61,48 +70,64 @@ void printPlatforms() {
6170
}
6271
}
6372

64-
ol_device_handle_t TestEnvironment::getDevice() {
65-
static ol_device_handle_t Device = nullptr;
73+
const std::vector<TestEnvironment::Device> &TestEnvironment::getDevices() {
74+
static std::vector<TestEnvironment::Device> Devices{};
75+
if (Devices.empty()) {
76+
// If a specific platform is requested, filter to devices belonging to it.
77+
if (const char *EnvStr = getenv("OFFLOAD_UNITTEST_PLATFORM")) {
78+
if (SelectedPlatform != "")
79+
errs() << "Warning: --platform argument ignored as "
80+
"OFFLOAD_UNITTEST_PLATFORM env var overrides it.\n";
81+
SelectedPlatform = EnvStr;
82+
}
6683

67-
if (!Device) {
6884
if (SelectedPlatform != "") {
6985
olIterateDevices(
7086
[](ol_device_handle_t D, void *Data) {
7187
ol_platform_handle_t Platform;
7288
olGetDeviceInfo(D, OL_DEVICE_INFO_PLATFORM, sizeof(Platform),
7389
&Platform);
74-
90+
ol_platform_backend_t Backend;
91+
olGetPlatformInfo(Platform, OL_PLATFORM_INFO_BACKEND,
92+
sizeof(Backend), &Backend);
7593
std::string PlatformName;
7694
raw_string_ostream S(PlatformName);
7795
S << Platform;
78-
79-
if (PlatformName == SelectedPlatform) {
80-
*(static_cast<ol_device_handle_t *>(Data)) = D;
81-
return false;
96+
if (PlatformName == SelectedPlatform &&
97+
Backend != OL_PLATFORM_BACKEND_HOST) {
98+
std::string Name;
99+
raw_string_ostream NameStr(Name);
100+
NameStr << PlatformName << "_" << D;
101+
static_cast<std::vector<TestEnvironment::Device> *>(Data)
102+
->push_back({D, Name});
82103
}
83-
84104
return true;
85105
},
86-
&Device);
87-
88-
if (Device == nullptr) {
89-
errs() << "No device found with the platform \"" << SelectedPlatform
90-
<< "\". Choose from:"
91-
<< "\n";
92-
printPlatforms();
93-
std::exit(1);
94-
}
106+
&Devices);
95107
} else {
108+
// No platform specified, discover every device that isn't the host.
96109
olIterateDevices(
97110
[](ol_device_handle_t D, void *Data) {
98-
*(static_cast<ol_device_handle_t *>(Data)) = D;
99-
return false;
111+
ol_platform_handle_t Platform;
112+
olGetDeviceInfo(D, OL_DEVICE_INFO_PLATFORM, sizeof(Platform),
113+
&Platform);
114+
ol_platform_backend_t Backend;
115+
olGetPlatformInfo(Platform, OL_PLATFORM_INFO_BACKEND,
116+
sizeof(Backend), &Backend);
117+
if (Backend != OL_PLATFORM_BACKEND_HOST) {
118+
std::string Name;
119+
raw_string_ostream NameStr(Name);
120+
NameStr << Platform << "_" << D;
121+
static_cast<std::vector<TestEnvironment::Device> *>(Data)
122+
->push_back({D, Name});
123+
}
124+
return true;
100125
},
101-
&Device);
126+
&Devices);
102127
}
103128
}
104129

105-
return Device;
130+
return Devices;
106131
}
107132

108133
ol_device_handle_t TestEnvironment::getHostDevice() {

offload/unittests/OffloadAPI/common/Environment.hpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,13 @@
1313
#include <gtest/gtest.h>
1414

1515
namespace TestEnvironment {
16-
ol_device_handle_t getDevice();
16+
17+
struct Device {
18+
ol_device_handle_t Handle;
19+
std::string Name;
20+
};
21+
22+
const std::vector<Device> &getDevices();
1723
ol_device_handle_t getHostDevice();
1824
bool loadDeviceBinary(const std::string &BinaryName, ol_device_handle_t Device,
1925
std::unique_ptr<llvm::MemoryBuffer> &BinaryOut);

offload/unittests/OffloadAPI/common/Fixtures.hpp

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,26 @@
4242
} \
4343
(void)0
4444

45+
inline std::string SanitizeString(const std::string &Str) {
46+
auto NewStr = Str;
47+
std::replace_if(
48+
NewStr.begin(), NewStr.end(), [](char C) { return !std::isalnum(C); },
49+
'_');
50+
return NewStr;
51+
}
52+
4553
struct OffloadTest : ::testing::Test {
4654
ol_device_handle_t Host = TestEnvironment::getHostDevice();
4755
};
4856

49-
struct OffloadDeviceTest : OffloadTest {
57+
struct OffloadDeviceTest
58+
: OffloadTest,
59+
::testing::WithParamInterface<TestEnvironment::Device> {
5060
void SetUp() override {
5161
RETURN_ON_FATAL_FAILURE(OffloadTest::SetUp());
5262

53-
Device = TestEnvironment::getDevice();
63+
auto DeviceParam = GetParam();
64+
Device = DeviceParam.Handle;
5465
if (Device == nullptr)
5566
GTEST_SKIP() << "No available devices.";
5667
}
@@ -120,3 +131,10 @@ struct OffloadQueueTest : OffloadDeviceTest {
120131

121132
ol_queue_handle_t Queue = nullptr;
122133
};
134+
135+
#define OFFLOAD_TESTS_INSTANTIATE_DEVICE_FIXTURE(FIXTURE) \
136+
INSTANTIATE_TEST_SUITE_P( \
137+
, FIXTURE, ::testing::ValuesIn(TestEnvironment::getDevices()), \
138+
[](const ::testing::TestParamInfo<TestEnvironment::Device> &info) { \
139+
return SanitizeString(info.param.Name); \
140+
})

offload/unittests/OffloadAPI/device/olDeviceInfo.hpp

Lines changed: 0 additions & 21 deletions
This file was deleted.

0 commit comments

Comments
 (0)