1 | //===------- Offload API tests - gtest fixtures --==-----------------------===// |
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 <OffloadAPI.h> |
10 | #include <OffloadPrint.hpp> |
11 | #include <gtest/gtest.h> |
12 | |
13 | #include "Environment.hpp" |
14 | |
15 | #pragma once |
16 | |
17 | #ifndef ASSERT_SUCCESS |
18 | #define ASSERT_SUCCESS(ACTUAL) \ |
19 | do { \ |
20 | ol_result_t Res = ACTUAL; \ |
21 | if (Res && Res->Code != OL_ERRC_SUCCESS) { \ |
22 | GTEST_FAIL() << #ACTUAL " returned " << Res->Code << ": " \ |
23 | << Res->Details; \ |
24 | } \ |
25 | } while (0) |
26 | #endif |
27 | |
28 | // TODO: rework this so the EXPECTED/ACTUAL results are readable |
29 | #ifndef ASSERT_ERROR |
30 | #define ASSERT_ERROR(EXPECTED, ACTUAL) \ |
31 | do { \ |
32 | ol_result_t Res = ACTUAL; \ |
33 | ASSERT_TRUE(Res && (Res->Code == EXPECTED)); \ |
34 | } while (0) |
35 | #endif |
36 | |
37 | #ifndef ASSERT_ANY_ERROR |
38 | #define ASSERT_ANY_ERROR(ACTUAL) \ |
39 | do { \ |
40 | ol_result_t Res = ACTUAL; \ |
41 | ASSERT_TRUE(Res); \ |
42 | } while (0) |
43 | #endif |
44 | |
45 | #define RETURN_ON_FATAL_FAILURE(...) \ |
46 | __VA_ARGS__; \ |
47 | if (this->HasFatalFailure() || this->IsSkipped()) { \ |
48 | return; \ |
49 | } \ |
50 | (void)0 |
51 | |
52 | inline std::string SanitizeString(const std::string &Str) { |
53 | auto NewStr = Str; |
54 | std::replace_if( |
55 | first: NewStr.begin(), last: NewStr.end(), pred: [](char C) { return !std::isalnum(C); }, |
56 | new_value: '_'); |
57 | return NewStr; |
58 | } |
59 | |
60 | struct OffloadTest : ::testing::Test { |
61 | ol_device_handle_t Host = TestEnvironment::getHostDevice(); |
62 | }; |
63 | |
64 | struct OffloadDeviceTest |
65 | : OffloadTest, |
66 | ::testing::WithParamInterface<TestEnvironment::Device> { |
67 | void SetUp() override { |
68 | RETURN_ON_FATAL_FAILURE(OffloadTest::SetUp()); |
69 | |
70 | auto DeviceParam = GetParam(); |
71 | Device = DeviceParam.Handle; |
72 | if (Device == nullptr) |
73 | GTEST_SKIP() << "No available devices." ; |
74 | } |
75 | |
76 | ol_device_handle_t Device = nullptr; |
77 | }; |
78 | |
79 | struct OffloadPlatformTest : OffloadDeviceTest { |
80 | void SetUp() override { |
81 | RETURN_ON_FATAL_FAILURE(OffloadDeviceTest::SetUp()); |
82 | |
83 | ASSERT_SUCCESS(olGetDeviceInfo(Device, OL_DEVICE_INFO_PLATFORM, |
84 | sizeof(Platform), &Platform)); |
85 | ASSERT_NE(Platform, nullptr); |
86 | } |
87 | |
88 | ol_platform_handle_t Platform = nullptr; |
89 | }; |
90 | |
91 | // Fixture for a generic program test. If you want a different program, use |
92 | // offloadQueueTest and create your own program handle with the binary you want. |
93 | struct OffloadProgramTest : OffloadDeviceTest { |
94 | void SetUp() override { |
95 | RETURN_ON_FATAL_FAILURE(OffloadDeviceTest::SetUp()); |
96 | ASSERT_TRUE(TestEnvironment::loadDeviceBinary("foo" , Device, DeviceBin)); |
97 | ASSERT_GE(DeviceBin->getBufferSize(), 0lu); |
98 | ASSERT_SUCCESS(olCreateProgram(Device, DeviceBin->getBufferStart(), |
99 | DeviceBin->getBufferSize(), &Program)); |
100 | } |
101 | |
102 | void TearDown() override { |
103 | if (Program) { |
104 | olDestroyProgram(Program); |
105 | } |
106 | RETURN_ON_FATAL_FAILURE(OffloadDeviceTest::TearDown()); |
107 | } |
108 | |
109 | ol_program_handle_t Program = nullptr; |
110 | std::unique_ptr<llvm::MemoryBuffer> DeviceBin; |
111 | }; |
112 | |
113 | struct OffloadKernelTest : OffloadProgramTest { |
114 | void SetUp() override { |
115 | RETURN_ON_FATAL_FAILURE(OffloadProgramTest::SetUp()); |
116 | ASSERT_SUCCESS(olGetKernel(Program, "foo" , &Kernel)); |
117 | } |
118 | |
119 | void TearDown() override { |
120 | RETURN_ON_FATAL_FAILURE(OffloadProgramTest::TearDown()); |
121 | } |
122 | |
123 | ol_kernel_handle_t Kernel = nullptr; |
124 | }; |
125 | |
126 | struct OffloadQueueTest : OffloadDeviceTest { |
127 | void SetUp() override { |
128 | RETURN_ON_FATAL_FAILURE(OffloadDeviceTest::SetUp()); |
129 | ASSERT_SUCCESS(olCreateQueue(Device, &Queue)); |
130 | } |
131 | |
132 | void TearDown() override { |
133 | if (Queue) { |
134 | olDestroyQueue(Queue); |
135 | } |
136 | RETURN_ON_FATAL_FAILURE(OffloadDeviceTest::TearDown()); |
137 | } |
138 | |
139 | ol_queue_handle_t Queue = nullptr; |
140 | }; |
141 | |
142 | #define OFFLOAD_TESTS_INSTANTIATE_DEVICE_FIXTURE(FIXTURE) \ |
143 | INSTANTIATE_TEST_SUITE_P( \ |
144 | , FIXTURE, ::testing::ValuesIn(TestEnvironment::getDevices()), \ |
145 | [](const ::testing::TestParamInfo<TestEnvironment::Device> &info) { \ |
146 | return SanitizeString(info.param.Name); \ |
147 | }) |
148 | |