Skip to content

Commit d160006

Browse files
Merge pull request #330 from oneapi-src/Add-support-for-testing-different-kernels
Add support for testing different devices
2 parents d7e4d2b + 02fcdff commit d160006

File tree

4 files changed

+192
-1
lines changed

4 files changed

+192
-1
lines changed

test/conformance/CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,13 @@ function(add_conformance_test name)
2121
set_tests_properties(${name} PROPERTIES LABELS "conformance")
2222
endfunction()
2323

24+
function(add_conformance_test_with_kernels_environment name)
25+
add_conformance_test(${name}
26+
${ARGN})
27+
set(KERNELS_DEFAULT_DIR "${PROJECT_SOURCE_DIR}/test/kernels")
28+
target_compile_definitions("test-${name}" PRIVATE KERNELS_ENVIRONMENT PRIVATE KERNELS_DEFAULT_DIR="${KERNELS_DEFAULT_DIR}")
29+
endfunction()
30+
2431
function(add_conformance_test_with_devices_environment name)
2532
add_conformance_test(${name}
2633
${ARGN})

test/conformance/source/environment.cpp

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// SPDX-License-Identifier: MIT
33

44
#include <cstring>
5+
#include <fstream>
56
#include <uur/environment.h>
67
#include <uur/utils.h>
78

@@ -176,4 +177,147 @@ void DevicesEnvironment::TearDown() {
176177
}
177178
}
178179
}
180+
181+
KernelsEnvironment *KernelsEnvironment::instance = nullptr;
182+
183+
KernelsEnvironment::KernelsEnvironment(int argc, char **argv, std::string kernels_default_dir) : DevicesEnvironment(argc, argv), kernel_options(parseKernelOptions(argc, argv, kernels_default_dir)) {
184+
instance = this;
185+
if (!error.empty()) {
186+
return;
187+
}
188+
}
189+
190+
KernelsEnvironment::KernelOptions KernelsEnvironment::parseKernelOptions(int argc, char **argv, std::string kernels_default_dir) {
191+
KernelOptions options;
192+
for (int argi = 1; argi < argc; ++argi) {
193+
const char *arg = argv[argi];
194+
if (std::strncmp(arg, "--kernel_directory=", sizeof("--kernel_directory=") - 1) == 0) {
195+
options.kernel_directory = std::string(&arg[std::strlen("--kernel_directory=")]);
196+
}
197+
}
198+
if (options.kernel_directory.empty()) {
199+
options.kernel_directory = kernels_default_dir;
200+
}
201+
202+
return options;
203+
}
204+
205+
std::string KernelsEnvironment::getSupportedILPostfix(uint32_t device_index) {
206+
std::stringstream IL;
207+
208+
if (instance->GetDevices().size() == 0) {
209+
error = "no devices available on the platform";
210+
return {};
211+
}
212+
213+
auto device = instance->GetDevices()[device_index];
214+
size_t size;
215+
if (urDeviceGetInfo(device, UR_DEVICE_INFO_IL_VERSION, 0, nullptr, &size)) {
216+
error = "failed getting device IL version";
217+
return {};
218+
}
219+
std::string IL_version(size, '\0');
220+
if (urDeviceGetInfo(device, UR_DEVICE_INFO_IL_VERSION, size, &IL_version[0],
221+
nullptr)) {
222+
error = "failed getting device IL version";
223+
return {};
224+
}
225+
226+
// Delete the ETX character at the end as it is not part of the name.
227+
IL_version.pop_back();
228+
229+
IL << "_" << IL_version;
230+
231+
// TODO: Add other IL types like ptx when they are defined how they will be
232+
// reported.
233+
if (IL_version.find("SPIR-V") != std::string::npos) {
234+
IL << ".spv";
235+
} else {
236+
error = "Undefined IL version: " + IL_version;
237+
return {};
238+
}
239+
240+
return IL.str();
241+
}
242+
243+
std::string KernelsEnvironment::getKernelSourcePath(const std::string &kernel_name, uint32_t device_index) {
244+
std::stringstream path;
245+
path << instance->getKernelDirectory();
246+
// il_postfix = supported_IL(SPIRV-PTX-...) + IL_version + extension(.spv -
247+
// .ptx - ....)
248+
std::string il_postfix = getSupportedILPostfix(device_index);
249+
250+
if (il_postfix.empty()) {
251+
error = "failed getting device supported IL";
252+
return {};
253+
}
254+
255+
path << "/" << kernel_name << il_postfix;
256+
257+
uint32_t address_bits;
258+
auto device = instance->GetDevices()[device_index];
259+
if (urDeviceGetInfo(device, UR_DEVICE_INFO_ADDRESS_BITS, sizeof(uint32_t),
260+
&address_bits, nullptr)) {
261+
error = "failed getting device address bits supported";
262+
return {};
263+
}
264+
path << address_bits;
265+
266+
return path.str();
267+
}
268+
269+
KernelsEnvironment::KernelSource KernelsEnvironment::LoadSource(const std::string &kernel_name, uint32_t device_index) {
270+
std::string source_path =
271+
instance->getKernelSourcePath(kernel_name, device_index);
272+
273+
if (source_path.empty()) {
274+
error = "failed retrieving kernel source path for kernel: " + kernel_name;
275+
return KernelSource{&kernel_name[0], nullptr, 0,
276+
UR_RESULT_ERROR_INVALID_BINARY};
277+
}
278+
279+
if (cached_kernels.find(source_path) != cached_kernels.end()) {
280+
return cached_kernels[source_path];
281+
}
282+
283+
std::ifstream source_file;
284+
source_file.open(source_path, std::ios::binary | std::ios::in | std::ios::ate);
285+
286+
if (!source_file.is_open()) {
287+
error = "failed opening kernel path: " + source_path;
288+
return KernelSource{&kernel_name[0], nullptr, 0,
289+
UR_RESULT_ERROR_INVALID_BINARY};
290+
}
291+
292+
uint32_t source_size = static_cast<uint32_t>(source_file.tellg());
293+
source_file.seekg(0, std::ios::beg);
294+
295+
char *source = new char[source_size];
296+
source_file.read(source, source_size);
297+
if (!source_file) {
298+
source_file.close();
299+
delete[] source;
300+
error = "failed reading kernel source data from file: " + source_path;
301+
return KernelSource{&kernel_name[0], nullptr, 0,
302+
UR_RESULT_ERROR_INVALID_BINARY};
303+
}
304+
source_file.close();
305+
306+
KernelSource kernel_source =
307+
KernelSource{&kernel_name[0], reinterpret_cast<uint32_t *>(source), source_size, UR_RESULT_SUCCESS};
308+
309+
return cached_kernels[source_path] = kernel_source;
310+
}
311+
312+
void KernelsEnvironment::SetUp() {
313+
DevicesEnvironment::SetUp();
314+
if (!error.empty()) {
315+
FAIL() << error;
316+
}
317+
}
318+
319+
void KernelsEnvironment::TearDown() {
320+
cached_kernels.clear();
321+
DevicesEnvironment::TearDown();
322+
}
179323
} // namespace uur

test/conformance/source/main.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,17 @@
44
#include <uur/environment.h>
55

66
int main(int argc, char **argv) {
7+
#ifdef KERNELS_ENVIRONMENT
8+
auto *environment = new uur::KernelsEnvironment(argc, argv, KERNELS_DEFAULT_DIR);
9+
#endif
710
#ifdef DEVICES_ENVIRONMENT
811
auto *environment = new uur::DevicesEnvironment(argc, argv);
912
#endif
1013
#ifdef PLATFORM_ENVIRONMENT
1114
auto *environment = new uur::PlatformEnvironment(argc, argv);
1215
#endif
1316
::testing::InitGoogleTest(&argc, argv);
14-
#if defined(DEVICES_ENVIRONMENT) || defined(PLATFORM_ENVIRONMENT)
17+
#if defined(DEVICES_ENVIRONMENT) || defined(PLATFORM_ENVIRONMENT) || defined(KERNELS_ENVIRONMENT)
1518
::testing::AddGlobalTestEnvironment(environment);
1619
#endif
1720
return RUN_ALL_TESTS();

test/conformance/testing/uur/environment.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <algorithm>
88
#include <gtest/gtest.h>
99
#include <string>
10+
#include <unordered_map>
1011
#include <ur_api.h>
1112
namespace uur {
1213

@@ -44,6 +45,42 @@ struct DevicesEnvironment : PlatformEnvironment {
4445
static DevicesEnvironment *instance;
4546
};
4647

48+
struct KernelsEnvironment : DevicesEnvironment {
49+
struct KernelOptions {
50+
std::string kernel_directory;
51+
};
52+
53+
struct KernelSource {
54+
const char *kernel_name;
55+
uint32_t *source;
56+
uint32_t source_length;
57+
ur_result_t status;
58+
59+
~KernelSource() { delete[] source; }
60+
};
61+
62+
KernelsEnvironment(int argc, char **argv, std::string kernels_default_dir);
63+
virtual ~KernelsEnvironment() override = default;
64+
65+
virtual void SetUp() override;
66+
virtual void TearDown() override;
67+
68+
KernelSource LoadSource(const std::string &kernel_name, uint32_t device_index);
69+
70+
static KernelsEnvironment *instance;
71+
72+
private:
73+
KernelOptions parseKernelOptions(int argc, char **argv, std::string kernels_default_dir);
74+
std::string getKernelDirectory() { return kernel_options.kernel_directory; }
75+
std::string getKernelSourcePath(const std::string &kernel_name,
76+
uint32_t device_index);
77+
std::string getSupportedILPostfix(uint32_t device_index);
78+
79+
KernelOptions kernel_options;
80+
// mapping between kernels (full_path + kernel_name) and their saved source.
81+
std::unordered_map<std::string, KernelSource> cached_kernels;
82+
};
83+
4784
} // namespace uur
4885

4986
#endif // UR_CONFORMANCE_INCLUDE_ENVIRONMENT_H_INCLUDED

0 commit comments

Comments
 (0)