xref: /llvm-project/offload/unittests/Plugins/NextgenPluginsTest.cpp (revision fa9e90f5d23312587b3a17920941334e0d1a58a1)
1 //===------- unittests/Plugins/NextgenPluginsTest.cpp - Plugin tests ------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "omptarget.h"
10 #include "gtest/gtest.h"
11 
12 #include <unordered_set>
13 
14 const int DEVICE_ID = 0;
15 std::unordered_set<int> setup_map;
16 
init_test_device(int ID)17 int init_test_device(int ID) {
18   if (setup_map.find(ID) != setup_map.end()) {
19     return OFFLOAD_SUCCESS;
20   }
21   if (__tgt_rtl_init_plugin() == OFFLOAD_FAIL ||
22       __tgt_rtl_init_device(ID) == OFFLOAD_FAIL) {
23     return OFFLOAD_FAIL;
24   }
25   setup_map.insert(ID);
26   return OFFLOAD_SUCCESS;
27 }
28 
29 // Test plugin initialization
TEST(NextgenPluginsTest,PluginInit)30 TEST(NextgenPluginsTest, PluginInit) {
31   EXPECT_EQ(OFFLOAD_SUCCESS, init_test_device(DEVICE_ID));
32 }
33 
34 // Test GPU allocation and R/W
TEST(NextgenPluginsTest,PluginAlloc)35 TEST(NextgenPluginsTest, PluginAlloc) {
36   int32_t test_value = 23;
37   int32_t host_value = -1;
38   int64_t var_size = sizeof(int32_t);
39 
40   // Init plugin and device
41   EXPECT_EQ(OFFLOAD_SUCCESS, init_test_device(DEVICE_ID));
42 
43   // Allocate memory
44   void *device_ptr =
45       __tgt_rtl_data_alloc(DEVICE_ID, var_size, nullptr, TARGET_ALLOC_DEFAULT);
46 
47   // Check that the result is not null
48   EXPECT_NE(device_ptr, nullptr);
49 
50   // Submit data to device
51   EXPECT_EQ(OFFLOAD_SUCCESS, __tgt_rtl_data_submit(DEVICE_ID, device_ptr,
52                                                    &test_value, var_size));
53 
54   // Read data from device
55   EXPECT_EQ(OFFLOAD_SUCCESS, __tgt_rtl_data_retrieve(DEVICE_ID, &host_value,
56                                                      device_ptr, var_size));
57 
58   // Compare values
59   EXPECT_EQ(host_value, test_value);
60 
61   // Cleanup data
62   EXPECT_EQ(OFFLOAD_SUCCESS,
63             __tgt_rtl_data_delete(DEVICE_ID, device_ptr, TARGET_ALLOC_DEFAULT));
64 }
65 
66 // Test async GPU allocation and R/W
TEST(NextgenPluginsTest,PluginAsyncAlloc)67 TEST(NextgenPluginsTest, PluginAsyncAlloc) {
68   int32_t test_value = 47;
69   int32_t host_value = -1;
70   int64_t var_size = sizeof(int32_t);
71   __tgt_async_info *info;
72 
73   // Init plugin and device
74   EXPECT_EQ(OFFLOAD_SUCCESS, init_test_device(DEVICE_ID));
75 
76   // Check if device supports async
77   // Platforms like x86_64 don't support it
78   if (__tgt_rtl_init_async_info(DEVICE_ID, &info) == OFFLOAD_SUCCESS) {
79     // Allocate memory
80     void *device_ptr = __tgt_rtl_data_alloc(DEVICE_ID, var_size, nullptr,
81                                             TARGET_ALLOC_DEFAULT);
82 
83     // Check that the result is not null
84     EXPECT_NE(device_ptr, nullptr);
85 
86     // Submit data to device asynchronously
87     EXPECT_EQ(OFFLOAD_SUCCESS,
88               __tgt_rtl_data_submit_async(DEVICE_ID, device_ptr, &test_value,
89                                           var_size, info));
90 
91     // Wait for async request to process
92     EXPECT_EQ(OFFLOAD_SUCCESS, __tgt_rtl_synchronize(DEVICE_ID, info));
93 
94     // Read data from device
95     EXPECT_EQ(OFFLOAD_SUCCESS,
96               __tgt_rtl_data_retrieve_async(DEVICE_ID, &host_value, device_ptr,
97                                             var_size, info));
98 
99     // Wait for async request to process
100     EXPECT_EQ(OFFLOAD_SUCCESS, __tgt_rtl_synchronize(DEVICE_ID, info));
101 
102     // Compare values
103     EXPECT_EQ(host_value, test_value);
104 
105     // Cleanup data
106     EXPECT_EQ(OFFLOAD_SUCCESS, __tgt_rtl_data_delete(DEVICE_ID, device_ptr,
107                                                      TARGET_ALLOC_DEFAULT));
108   }
109 }
110 
111 // Test GPU data exchange
TEST(NextgenPluginsTest,PluginDataSwap)112 TEST(NextgenPluginsTest, PluginDataSwap) {
113   int32_t test_value = 23;
114   int32_t host_value = -1;
115   int64_t var_size = sizeof(int32_t);
116 
117   // Look for compatible device
118   int DEVICE_TWO = -1;
119   for (int i = 1; i < __tgt_rtl_number_of_devices(); i++) {
120     if (__tgt_rtl_is_data_exchangable(DEVICE_ID, i)) {
121       DEVICE_TWO = i;
122       break;
123     }
124   }
125 
126   // Only run test if we have multiple GPUs to test
127   // GPUs must be compatible for test to work
128   if (DEVICE_TWO >= 1) {
129     // Init both GPUs
130     EXPECT_EQ(OFFLOAD_SUCCESS, init_test_device(DEVICE_ID));
131     EXPECT_EQ(OFFLOAD_SUCCESS, init_test_device(DEVICE_TWO));
132 
133     // Allocate memory on both GPUs
134     // DEVICE_ID will be the source
135     // DEVICE_TWO will be the destination
136     void *source_ptr = __tgt_rtl_data_alloc(DEVICE_ID, var_size, nullptr,
137                                             TARGET_ALLOC_DEFAULT);
138     void *dest_ptr = __tgt_rtl_data_alloc(DEVICE_TWO, var_size, nullptr,
139                                           TARGET_ALLOC_DEFAULT);
140 
141     // Check for success in allocation
142     EXPECT_NE(source_ptr, nullptr);
143     EXPECT_NE(dest_ptr, nullptr);
144 
145     // Write data to source
146     EXPECT_EQ(OFFLOAD_SUCCESS, __tgt_rtl_data_submit(DEVICE_ID, source_ptr,
147                                                      &test_value, var_size));
148 
149     // Transfer data between devices
150     EXPECT_EQ(OFFLOAD_SUCCESS,
151               __tgt_rtl_data_exchange(DEVICE_ID, source_ptr, DEVICE_TWO,
152                                       dest_ptr, var_size));
153 
154     // Read from destination device (DEVICE_TWO) memory
155     EXPECT_EQ(OFFLOAD_SUCCESS, __tgt_rtl_data_retrieve(DEVICE_TWO, &host_value,
156                                                        dest_ptr, var_size));
157 
158     // Ensure match
159     EXPECT_EQ(host_value, test_value);
160 
161     // Cleanup
162     EXPECT_EQ(OFFLOAD_SUCCESS, __tgt_rtl_data_delete(DEVICE_ID, source_ptr,
163                                                      TARGET_ALLOC_DEFAULT));
164     EXPECT_EQ(OFFLOAD_SUCCESS, __tgt_rtl_data_delete(DEVICE_TWO, dest_ptr,
165                                                      TARGET_ALLOC_DEFAULT));
166   }
167 }
168