mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-10-07 10:54:01 +00:00
[OpenMP] Add unit tests for nextgen plugins (#74398)
This patch add three GTest unit tests that test plugin read and write operations. Tests can be compiled with `ninja -C runtimes/runtimes-bins LibomptUnitTests`.
This commit is contained in:
parent
c6f29dbb59
commit
3c10e5b2f6
@ -150,3 +150,9 @@ add_subdirectory(${LIBOMPTARGET_SRC_DIR})
|
||||
|
||||
# Add tests.
|
||||
add_subdirectory(test)
|
||||
|
||||
# Add unit tests if GMock/GTest is present
|
||||
if (EXISTS ${LLVM_THIRD_PARTY_DIR}/unittest)
|
||||
add_subdirectory(${LLVM_THIRD_PARTY_DIR}/unittest ${CMAKE_CURRENT_BINARY_DIR}/third-party/unittest)
|
||||
add_subdirectory(unittests)
|
||||
endif()
|
||||
|
8
openmp/libomptarget/unittests/CMakeLists.txt
Normal file
8
openmp/libomptarget/unittests/CMakeLists.txt
Normal file
@ -0,0 +1,8 @@
|
||||
add_custom_target(LibomptUnitTests)
|
||||
set_target_properties(LibomptUnitTests PROPERTIES FOLDER "Tests/UnitTests")
|
||||
|
||||
function(add_libompt_unittest test_dirname)
|
||||
add_unittest(LibomptUnitTests ${test_dirname} ${ARGN})
|
||||
endfunction()
|
||||
|
||||
add_subdirectory(Plugins)
|
11
openmp/libomptarget/unittests/Plugins/CMakeLists.txt
Normal file
11
openmp/libomptarget/unittests/Plugins/CMakeLists.txt
Normal file
@ -0,0 +1,11 @@
|
||||
set(PLUGINS_TEST_COMMON omptarget OMPT omptarget.devicertl)
|
||||
set(PLUGINS_TEST_SOURCES NextgenPluginsTest.cpp)
|
||||
set(PLUGINS_TEST_INCLUDE ${LIBOMPTARGET_INCLUDE_DIR})
|
||||
|
||||
foreach(PLUGIN IN LISTS LIBOMPTARGET_TESTED_PLUGINS)
|
||||
libomptarget_say("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()
|
168
openmp/libomptarget/unittests/Plugins/NextgenPluginsTest.cpp
Normal file
168
openmp/libomptarget/unittests/Plugins/NextgenPluginsTest.cpp
Normal file
@ -0,0 +1,168 @@
|
||||
//===------- 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 "Shared/PluginAPI.h"
|
||||
#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));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user