1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
|
//===------- 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));
}
}
|