[asan] Add a new AddressDescription structure, which can describe any type of address.
[lldb.git] / parallel-libs / streamexecutor / unittests / CoreTests / DeviceTest.cpp
1 //===-- DeviceTest.cpp - Tests for Device ---------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 ///
10 /// \file
11 /// This file contains the unit tests for Device code.
12 ///
13 //===----------------------------------------------------------------------===//
14
15 #include <cstdlib>
16 #include <cstring>
17
18 #include "SimpleHostPlatformDevice.h"
19 #include "streamexecutor/Device.h"
20 #include "streamexecutor/PlatformDevice.h"
21
22 #include "gtest/gtest.h"
23
24 namespace {
25
26 namespace se = ::streamexecutor;
27
28 const auto &getDeviceValue =
29     se::test::SimpleHostPlatformDevice::getDeviceValue<int>;
30
31 /// Test fixture to hold objects used by tests.
32 class DeviceTest : public ::testing::Test {
33 public:
34   DeviceTest()
35       : Device(&PDevice), HostA5{0, 1, 2, 3, 4}, HostB5{5, 6, 7, 8, 9},
36         HostA7{10, 11, 12, 13, 14, 15, 16}, HostB7{17, 18, 19, 20, 21, 22, 23},
37         DeviceA5(getOrDie(Device.allocateDeviceMemory<int>(5))),
38         DeviceB5(getOrDie(Device.allocateDeviceMemory<int>(5))),
39         DeviceA7(getOrDie(Device.allocateDeviceMemory<int>(7))),
40         DeviceB7(getOrDie(Device.allocateDeviceMemory<int>(7))),
41         Host5{24, 25, 26, 27, 28}, Host7{29, 30, 31, 32, 33, 34, 35} {
42     se::dieIfError(Device.synchronousCopyH2D<int>(HostA5, DeviceA5));
43     se::dieIfError(Device.synchronousCopyH2D<int>(HostB5, DeviceB5));
44     se::dieIfError(Device.synchronousCopyH2D<int>(HostA7, DeviceA7));
45     se::dieIfError(Device.synchronousCopyH2D<int>(HostB7, DeviceB7));
46   }
47
48   se::test::SimpleHostPlatformDevice PDevice;
49   se::Device Device;
50
51   // Device memory is backed by host arrays.
52   int HostA5[5];
53   int HostB5[5];
54   int HostA7[7];
55   int HostB7[7];
56   se::GlobalDeviceMemory<int> DeviceA5;
57   se::GlobalDeviceMemory<int> DeviceB5;
58   se::GlobalDeviceMemory<int> DeviceA7;
59   se::GlobalDeviceMemory<int> DeviceB7;
60
61   // Host memory to be used as actual host memory.
62   int Host5[5];
63   int Host7[7];
64 };
65
66 #define EXPECT_NO_ERROR(E) EXPECT_FALSE(static_cast<bool>(E))
67 #define EXPECT_ERROR(E)                                                        \
68   do {                                                                         \
69     se::Error E__ = E;                                                         \
70     EXPECT_TRUE(static_cast<bool>(E__));                                       \
71     consumeError(std::move(E__));                                              \
72   } while (false)
73
74 using llvm::ArrayRef;
75 using llvm::MutableArrayRef;
76
77 TEST_F(DeviceTest, GetName) {
78   EXPECT_EQ(Device.getName(), "SimpleHostPlatformDevice");
79 }
80
81 TEST_F(DeviceTest, AllocateAndFreeDeviceMemory) {
82   se::Expected<se::GlobalDeviceMemory<int>> MaybeMemory =
83       Device.allocateDeviceMemory<int>(10);
84   EXPECT_TRUE(static_cast<bool>(MaybeMemory));
85 }
86
87 TEST_F(DeviceTest, AllocateAndFreeHostMemory) {
88   se::Expected<int *> MaybeMemory = Device.allocateHostMemory<int>(10);
89   EXPECT_TRUE(static_cast<bool>(MaybeMemory));
90   EXPECT_NO_ERROR(Device.freeHostMemory(*MaybeMemory));
91 }
92
93 TEST_F(DeviceTest, RegisterAndUnregisterHostMemory) {
94   std::vector<int> Data(10);
95   EXPECT_NO_ERROR(Device.registerHostMemory(Data.data(), 10));
96   EXPECT_NO_ERROR(Device.unregisterHostMemory(Data.data()));
97 }
98
99 // D2H tests
100
101 TEST_F(DeviceTest, SyncCopyD2HToMutableArrayRefByCount) {
102   EXPECT_NO_ERROR(
103       Device.synchronousCopyD2H(DeviceA5, MutableArrayRef<int>(Host5), 5));
104   for (int I = 0; I < 5; ++I) {
105     EXPECT_EQ(HostA5[I], Host5[I]);
106   }
107
108   EXPECT_NO_ERROR(
109       Device.synchronousCopyD2H(DeviceB5, MutableArrayRef<int>(Host5), 2));
110   for (int I = 0; I < 2; ++I) {
111     EXPECT_EQ(HostB5[I], Host5[I]);
112   }
113
114   EXPECT_ERROR(
115       Device.synchronousCopyD2H(DeviceA7, MutableArrayRef<int>(Host5), 7));
116
117   EXPECT_ERROR(
118       Device.synchronousCopyD2H(DeviceA5, MutableArrayRef<int>(Host7), 7));
119
120   EXPECT_ERROR(
121       Device.synchronousCopyD2H(DeviceA5, MutableArrayRef<int>(Host5), 7));
122 }
123
124 TEST_F(DeviceTest, SyncCopyD2HToMutableArrayRef) {
125   EXPECT_NO_ERROR(
126       Device.synchronousCopyD2H(DeviceA5, MutableArrayRef<int>(Host5)));
127   for (int I = 0; I < 5; ++I) {
128     EXPECT_EQ(HostA5[I], Host5[I]);
129   }
130
131   EXPECT_ERROR(
132       Device.synchronousCopyD2H(DeviceA7, MutableArrayRef<int>(Host5)));
133
134   EXPECT_ERROR(
135       Device.synchronousCopyD2H(DeviceA5, MutableArrayRef<int>(Host7)));
136 }
137
138 TEST_F(DeviceTest, SyncCopyD2HToPointer) {
139   EXPECT_NO_ERROR(Device.synchronousCopyD2H(DeviceA5, Host5, 5));
140   for (int I = 0; I < 5; ++I) {
141     EXPECT_EQ(HostA5[I], Host5[I]);
142   }
143
144   EXPECT_ERROR(Device.synchronousCopyD2H(DeviceA5, Host7, 7));
145 }
146
147 TEST_F(DeviceTest, SyncCopyD2HSliceToMutableArrayRefByCount) {
148   EXPECT_NO_ERROR(Device.synchronousCopyD2H(
149       DeviceA5.asSlice().drop_front(1), MutableArrayRef<int>(Host5 + 1, 4), 4));
150   for (int I = 1; I < 5; ++I) {
151     EXPECT_EQ(HostA5[I], Host5[I]);
152   }
153
154   EXPECT_NO_ERROR(Device.synchronousCopyD2H(DeviceB5.asSlice().drop_back(1),
155                                             MutableArrayRef<int>(Host5), 2));
156   for (int I = 0; I < 2; ++I) {
157     EXPECT_EQ(HostB5[I], Host5[I]);
158   }
159
160   EXPECT_ERROR(Device.synchronousCopyD2H(DeviceA7.asSlice(),
161                                          MutableArrayRef<int>(Host5), 7));
162
163   EXPECT_ERROR(Device.synchronousCopyD2H(DeviceA5.asSlice(),
164                                          MutableArrayRef<int>(Host7), 7));
165
166   EXPECT_ERROR(Device.synchronousCopyD2H(DeviceA5.asSlice(),
167                                          MutableArrayRef<int>(Host5), 7));
168 }
169
170 TEST_F(DeviceTest, SyncCopyD2HSliceToMutableArrayRef) {
171   EXPECT_NO_ERROR(Device.synchronousCopyD2H(DeviceA7.asSlice().slice(1, 5),
172                                             MutableArrayRef<int>(Host5)));
173   for (int I = 0; I < 5; ++I) {
174     EXPECT_EQ(HostA7[I + 1], Host5[I]);
175   }
176
177   EXPECT_ERROR(Device.synchronousCopyD2H(DeviceA7.asSlice().drop_back(1),
178                                          MutableArrayRef<int>(Host5)));
179
180   EXPECT_ERROR(Device.synchronousCopyD2H(DeviceA5.asSlice(),
181                                          MutableArrayRef<int>(Host7)));
182 }
183
184 TEST_F(DeviceTest, SyncCopyD2HSliceToPointer) {
185   EXPECT_NO_ERROR(Device.synchronousCopyD2H(DeviceA5.asSlice().drop_front(1),
186                                             Host5 + 1, 4));
187   for (int I = 1; I < 5; ++I) {
188     EXPECT_EQ(HostA5[I], Host5[I]);
189   }
190
191   EXPECT_ERROR(Device.synchronousCopyD2H(DeviceA5.asSlice(), Host7, 7));
192 }
193
194 // H2D tests
195
196 TEST_F(DeviceTest, SyncCopyH2DToArrayRefByCount) {
197   EXPECT_NO_ERROR(Device.synchronousCopyH2D(ArrayRef<int>(Host5), DeviceA5, 5));
198   for (int I = 0; I < 5; ++I) {
199     EXPECT_EQ(getDeviceValue(DeviceA5, I), Host5[I]);
200   }
201
202   EXPECT_NO_ERROR(Device.synchronousCopyH2D(ArrayRef<int>(Host5), DeviceB5, 2));
203   for (int I = 0; I < 2; ++I) {
204     EXPECT_EQ(getDeviceValue(DeviceB5, I), Host5[I]);
205   }
206
207   EXPECT_ERROR(Device.synchronousCopyH2D(ArrayRef<int>(Host7), DeviceA5, 7));
208
209   EXPECT_ERROR(Device.synchronousCopyH2D(ArrayRef<int>(Host5), DeviceA7, 7));
210
211   EXPECT_ERROR(Device.synchronousCopyH2D(ArrayRef<int>(Host5), DeviceA5, 7));
212 }
213
214 TEST_F(DeviceTest, SyncCopyH2DToArrayRef) {
215   EXPECT_NO_ERROR(Device.synchronousCopyH2D(ArrayRef<int>(Host5), DeviceA5));
216   for (int I = 0; I < 5; ++I) {
217     EXPECT_EQ(getDeviceValue(DeviceA5, I), Host5[I]);
218   }
219
220   EXPECT_ERROR(Device.synchronousCopyH2D(ArrayRef<int>(Host5), DeviceA7));
221
222   EXPECT_ERROR(Device.synchronousCopyH2D(ArrayRef<int>(Host7), DeviceA5));
223 }
224
225 TEST_F(DeviceTest, SyncCopyH2DToPointer) {
226   EXPECT_NO_ERROR(Device.synchronousCopyH2D(Host5, DeviceA5, 5));
227   for (int I = 0; I < 5; ++I) {
228     EXPECT_EQ(getDeviceValue(DeviceA5, I), Host5[I]);
229   }
230
231   EXPECT_ERROR(Device.synchronousCopyH2D(Host7, DeviceA5, 7));
232 }
233
234 TEST_F(DeviceTest, SyncCopyH2DSliceToArrayRefByCount) {
235   EXPECT_NO_ERROR(Device.synchronousCopyH2D(
236       ArrayRef<int>(Host5 + 1, 4), DeviceA5.asSlice().drop_front(1), 4));
237   for (int I = 1; I < 5; ++I) {
238     EXPECT_EQ(getDeviceValue(DeviceA5, I), Host5[I]);
239   }
240
241   EXPECT_NO_ERROR(Device.synchronousCopyH2D(
242       ArrayRef<int>(Host5), DeviceB5.asSlice().drop_back(1), 2));
243   for (int I = 0; I < 2; ++I) {
244     EXPECT_EQ(getDeviceValue(DeviceB5, I), Host5[I]);
245   }
246
247   EXPECT_ERROR(
248       Device.synchronousCopyH2D(ArrayRef<int>(Host7), DeviceA5.asSlice(), 7));
249
250   EXPECT_ERROR(
251       Device.synchronousCopyH2D(ArrayRef<int>(Host5), DeviceA7.asSlice(), 7));
252
253   EXPECT_ERROR(
254       Device.synchronousCopyH2D(ArrayRef<int>(Host5), DeviceA5.asSlice(), 7));
255 }
256
257 TEST_F(DeviceTest, SyncCopyH2DSliceToArrayRef) {
258   EXPECT_NO_ERROR(
259       Device.synchronousCopyH2D(ArrayRef<int>(Host5), DeviceA5.asSlice()));
260   for (int I = 0; I < 5; ++I) {
261     EXPECT_EQ(getDeviceValue(DeviceA5, I), Host5[I]);
262   }
263
264   EXPECT_ERROR(
265       Device.synchronousCopyH2D(ArrayRef<int>(Host5), DeviceA7.asSlice()));
266
267   EXPECT_ERROR(
268       Device.synchronousCopyH2D(ArrayRef<int>(Host7), DeviceA5.asSlice()));
269 }
270
271 TEST_F(DeviceTest, SyncCopyH2DSliceToPointer) {
272   EXPECT_NO_ERROR(Device.synchronousCopyH2D(Host5, DeviceA5.asSlice(), 5));
273   for (int I = 0; I < 5; ++I) {
274     EXPECT_EQ(getDeviceValue(DeviceA5, I), Host5[I]);
275   }
276
277   EXPECT_ERROR(Device.synchronousCopyH2D(Host7, DeviceA5.asSlice(), 7));
278 }
279
280 // D2D tests
281
282 TEST_F(DeviceTest, SyncCopyD2DByCount) {
283   EXPECT_NO_ERROR(Device.synchronousCopyD2D(DeviceA5, DeviceB5, 5));
284   for (int I = 0; I < 5; ++I) {
285     EXPECT_EQ(getDeviceValue(DeviceA5, I), getDeviceValue(DeviceB5, I));
286   }
287
288   EXPECT_NO_ERROR(Device.synchronousCopyD2D(DeviceA7, DeviceB7, 2));
289   for (int I = 0; I < 2; ++I) {
290     EXPECT_EQ(getDeviceValue(DeviceA7, I), getDeviceValue(DeviceB7, I));
291   }
292
293   EXPECT_ERROR(Device.synchronousCopyD2D(DeviceA5, DeviceB5, 7));
294
295   EXPECT_ERROR(Device.synchronousCopyD2D(DeviceA7, DeviceB5, 7));
296
297   EXPECT_ERROR(Device.synchronousCopyD2D(DeviceA5, DeviceB7, 7));
298 }
299
300 TEST_F(DeviceTest, SyncCopyD2D) {
301   EXPECT_NO_ERROR(Device.synchronousCopyD2D(DeviceA5, DeviceB5));
302   for (int I = 0; I < 5; ++I) {
303     EXPECT_EQ(getDeviceValue(DeviceA5, I), getDeviceValue(DeviceB5, I));
304   }
305
306   EXPECT_ERROR(Device.synchronousCopyD2D(DeviceA7, DeviceB5));
307
308   EXPECT_ERROR(Device.synchronousCopyD2D(DeviceA5, DeviceB7));
309 }
310
311 TEST_F(DeviceTest, SyncCopySliceD2DByCount) {
312   EXPECT_NO_ERROR(
313       Device.synchronousCopyD2D(DeviceA5.asSlice().drop_front(1), DeviceB5, 4));
314   for (int I = 0; I < 4; ++I) {
315     EXPECT_EQ(getDeviceValue(DeviceA5, I + 1), getDeviceValue(DeviceB5, I));
316   }
317
318   EXPECT_NO_ERROR(
319       Device.synchronousCopyD2D(DeviceA7.asSlice().drop_back(1), DeviceB7, 2));
320   for (int I = 0; I < 2; ++I) {
321     EXPECT_EQ(getDeviceValue(DeviceA7, I), getDeviceValue(DeviceB7, I));
322   }
323
324   EXPECT_ERROR(Device.synchronousCopyD2D(DeviceA5.asSlice(), DeviceB5, 7));
325
326   EXPECT_ERROR(Device.synchronousCopyD2D(DeviceA7.asSlice(), DeviceB5, 7));
327
328   EXPECT_ERROR(Device.synchronousCopyD2D(DeviceA5.asSlice(), DeviceB7, 7));
329 }
330
331 TEST_F(DeviceTest, SyncCopySliceD2D) {
332   EXPECT_NO_ERROR(
333       Device.synchronousCopyD2D(DeviceA7.asSlice().drop_back(2), DeviceB5));
334   for (int I = 0; I < 5; ++I) {
335     EXPECT_EQ(getDeviceValue(DeviceA7, I), getDeviceValue(DeviceB5, I));
336   }
337
338   EXPECT_ERROR(
339       Device.synchronousCopyD2D(DeviceA7.asSlice().drop_front(1), DeviceB5));
340
341   EXPECT_ERROR(
342       Device.synchronousCopyD2D(DeviceA5.asSlice().drop_back(1), DeviceB7));
343 }
344
345 TEST_F(DeviceTest, SyncCopyD2DSliceByCount) {
346   EXPECT_NO_ERROR(
347       Device.synchronousCopyD2D(DeviceA5, DeviceB7.asSlice().drop_front(2), 5));
348   for (int I = 0; I < 5; ++I) {
349     EXPECT_EQ(getDeviceValue(DeviceA5, I), getDeviceValue(DeviceB7, I + 2));
350   }
351
352   EXPECT_NO_ERROR(
353       Device.synchronousCopyD2D(DeviceA7, DeviceB7.asSlice().drop_back(3), 2));
354   for (int I = 0; I < 2; ++I) {
355     EXPECT_EQ(getDeviceValue(DeviceA7, I), getDeviceValue(DeviceB7, I));
356   }
357
358   EXPECT_ERROR(Device.synchronousCopyD2D(DeviceA5, DeviceB5.asSlice(), 7));
359
360   EXPECT_ERROR(Device.synchronousCopyD2D(DeviceA7, DeviceB5.asSlice(), 7));
361
362   EXPECT_ERROR(Device.synchronousCopyD2D(DeviceA5, DeviceB7.asSlice(), 7));
363 }
364
365 TEST_F(DeviceTest, SyncCopyD2DSlice) {
366   EXPECT_NO_ERROR(
367       Device.synchronousCopyD2D(DeviceA5, DeviceB7.asSlice().drop_back(2)));
368   for (int I = 0; I < 5; ++I) {
369     EXPECT_EQ(getDeviceValue(DeviceA5, I), getDeviceValue(DeviceB7, I));
370   }
371
372   EXPECT_ERROR(Device.synchronousCopyD2D(DeviceA7, DeviceB5.asSlice()));
373
374   EXPECT_ERROR(Device.synchronousCopyD2D(DeviceA5, DeviceB7.asSlice()));
375 }
376
377 TEST_F(DeviceTest, SyncCopySliceD2DSliceByCount) {
378   EXPECT_NO_ERROR(
379       Device.synchronousCopyD2D(DeviceA5.asSlice(), DeviceB5.asSlice(), 5));
380   for (int I = 0; I < 5; ++I) {
381     EXPECT_EQ(getDeviceValue(DeviceA5, I), getDeviceValue(DeviceB5, I));
382   }
383
384   EXPECT_NO_ERROR(
385       Device.synchronousCopyD2D(DeviceA7.asSlice(), DeviceB7.asSlice(), 2));
386   for (int I = 0; I < 2; ++I) {
387     EXPECT_EQ(getDeviceValue(DeviceA7, I), getDeviceValue(DeviceB7, I));
388   }
389
390   EXPECT_ERROR(
391       Device.synchronousCopyD2D(DeviceA5.asSlice(), DeviceB5.asSlice(), 7));
392
393   EXPECT_ERROR(
394       Device.synchronousCopyD2D(DeviceA7.asSlice(), DeviceB5.asSlice(), 7));
395
396   EXPECT_ERROR(
397       Device.synchronousCopyD2D(DeviceA5.asSlice(), DeviceB7.asSlice(), 7));
398 }
399
400 TEST_F(DeviceTest, SyncCopySliceD2DSlice) {
401   EXPECT_NO_ERROR(
402       Device.synchronousCopyD2D(DeviceA5.asSlice(), DeviceB5.asSlice()));
403   for (int I = 0; I < 5; ++I) {
404     EXPECT_EQ(getDeviceValue(DeviceA5, I), getDeviceValue(DeviceB5, I));
405   }
406
407   EXPECT_ERROR(
408       Device.synchronousCopyD2D(DeviceA7.asSlice(), DeviceB5.asSlice()));
409
410   EXPECT_ERROR(
411       Device.synchronousCopyD2D(DeviceA5.asSlice(), DeviceB7.asSlice()));
412 }
413
414 } // namespace