Skip to content

Commit 4f57f26

Browse files
kbenzieaarongreig
authored andcommitted
Add CTS macro for marking tests as known failures in code
The new `UUR_KNOWN_FAILURE_ON` macro can be used to skip tests on devices where the test is known to fail. This can be done in the following situations. For all devices in an adapter: ```cpp UUR_KNOWN_FAILURE_ON(uur::LevelZero{}); ``` By substring match of the device name within and adapter: ```cpp UUR_KNOWN_FAILURE_ON(uur::OpenCL{"Intel(R) UHD Graphics 770"}); ``` > Note: This invocation is used in a few places in this patch to > facilitate clean runs when using this decice. In certain test suits, where there is no access to a device, the platform name is used instead: ```cpp UUR_KNOWN_FAILURE_ON(uur::CUDA{"NVIDIA CUDA BACKEND"}); ``` When neither device or platform is available in a test suite, the name is ignored and only the adapter backend is used to determine if the test is a known failure. The macro is variadic making it possible to specify known failures for multiple adapters in a single place and multiple names can also be provided per adapter: ```cpp UUR_KNOWN_FAILURE_ON( uur::OpenCL{ "Intel(R) UHD Graphics 750", "Intel(R) UHD Graphics 770", }, uur::HIP{"Radeon RX 7700"}, uur::NativeCPU{}); ```
1 parent 3c34372 commit 4f57f26

File tree

8 files changed

+273
-4
lines changed

8 files changed

+273
-4
lines changed

scripts/core/INTRO.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,13 @@ no valid platforms, then the tests will fail. Command line arguments take priori
430430

431431
A (case insensitive) backend to force the test to use. For example, `opencl`, `level_zero`, `hip` and so on.
432432

433+
.. envvar:: UR_CTS_ALSO_RUN_KNOWN_FAILURES
434+
435+
A boolean option to enable running tests which have been marked as known
436+
failures using the :c:macro:`UUR_KNOWN_FAILURE_ON` macro. Enabled when the
437+
environment variable is set to any of the following values: ``1``, ``on``,
438+
``ON``, ``yes``, ``YES``, ``true``, ``TRUE``.
439+
433440
Service identifiers
434441
---------------------
435442

test/conformance/README.md

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,54 @@ all available devices/platforms, set 0. The default value is 1.
1919
If you run binaries for the tests, you can use the parameter
2020
`--platforms_count=COUNT` or `--devices_count=COUNT`.
2121
To set test device/platform name you want to run the tests on, use
22-
parameter `--platform=NAME` or `--device=NAME`.
22+
parameter `--platform=NAME` or `--device=NAME`.
23+
24+
## Known failures
25+
26+
The `UUR_KNOWN_FAILURE_ON` macro can be used to skip tests on devices where the
27+
test is known to fail. This can be done in the following situations.
28+
29+
For all devices in an adapter:
30+
31+
```cpp
32+
UUR_KNOWN_FAILURE_ON(uur::LevelZero{});
33+
```
34+
35+
By substring match of the device name within and adapter:
36+
37+
```cpp
38+
UUR_KNOWN_FAILURE_ON(uur::OpenCL{"Intel(R) UHD Graphics 770"});
39+
```
40+
41+
In certain test suits, where there is no access to a device, the platform name
42+
is used instead:
43+
44+
```cpp
45+
UUR_KNOWN_FAILURE_ON(uur::CUDA{"NVIDIA CUDA BACKEND"});
46+
```
47+
48+
When neither device or platform is available in a test suite, the name is
49+
ignored and only the adapter backend is used to determine if the test is a
50+
known failure.
51+
52+
The macro is variadic making it possible to specify known failures for multiple
53+
adapters in a single place and multiple names can also be provided per adapter:
54+
55+
```cpp
56+
UUR_KNOWN_FAILURE_ON(
57+
uur::OpenCL{
58+
"Intel(R) UHD Graphics 750",
59+
"Intel(R) UHD Graphics 770",
60+
},
61+
uur::HIP{"Radeon RX 7700"},
62+
uur::NativeCPU{});
63+
```
64+
65+
The following adapter matcher objects are available:
66+
67+
* `uur::OpenCL`
68+
* `uur::LevelZero`
69+
* `uur::LevelZeroV2`
70+
* `uur::CUDA`
71+
* `uur::HIP`
72+
* `uur::NativeCPU`

test/conformance/kernel/urKernelSetArgValue.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// See LICENSE.TXT
44
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
55

6+
#include "uur/known_failure.h"
67
#include <uur/fixtures.h>
78

89
struct urKernelSetArgValueTest : uur::urKernelTest {
@@ -45,6 +46,7 @@ TEST_P(urKernelSetArgValueTest, InvalidKernelArgumentIndex) {
4546
}
4647

4748
TEST_P(urKernelSetArgValueTest, InvalidKernelArgumentSize) {
49+
UUR_KNOWN_FAILURE_ON(uur::OpenCL{"Intel(R) UHD Graphics 770"});
4850
ASSERT_EQ_RESULT(UR_RESULT_ERROR_INVALID_KERNEL_ARGUMENT_SIZE,
4951
urKernelSetArgValue(kernel, 2, 0, nullptr, &arg_value));
5052
}

test/conformance/memory/urMemImageCreate.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM Exceptions.
33
// See LICENSE.TXT
44
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5+
#include "uur/known_failure.h"
56
#include <uur/fixtures.h>
67
#include <uur/raii.h>
78

@@ -188,6 +189,7 @@ TEST_P(urMemImageCreateTest, InvalidNullPointerImageFormat) {
188189
}
189190

190191
TEST_P(urMemImageCreateTest, InvalidSize) {
192+
UUR_KNOWN_FAILURE_ON(uur::OpenCL{"Intel(R) UHD Graphics 770"});
191193

192194
uur::raii::Mem image_handle = nullptr;
193195

test/conformance/memory/urMemImageCreateWithImageFormatParam.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM Exceptions.
33
// See LICENSE.TXT
44
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5+
#include "uur/known_failure.h"
56
#include <uur/fixtures.h>
67
#include <vector>
78

@@ -90,6 +91,7 @@ UUR_DEVICE_TEST_SUITE_P(
9091
uur::deviceTestWithParamPrinter<ur_image_format_t>);
9192

9293
TEST_P(urMemImageCreateTestWithImageFormatParam, Success) {
94+
UUR_KNOWN_FAILURE_ON(uur::OpenCL{"Intel(R) UHD Graphics 770"});
9395
ur_image_channel_order_t channel_order =
9496
std::get<1>(GetParam()).channelOrder;
9597
ur_image_channel_type_t channel_type = std::get<1>(GetParam()).channelType;

test/conformance/program/urProgramGetFunctionPointer.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// See LICENSE.TXT
44
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
55

6+
#include "uur/known_failure.h"
67
#include <uur/fixtures.h>
78

89
struct urProgramGetFunctionPointerTest : uur::urProgramTest {
@@ -20,6 +21,7 @@ struct urProgramGetFunctionPointerTest : uur::urProgramTest {
2021
UUR_INSTANTIATE_KERNEL_TEST_SUITE_P(urProgramGetFunctionPointerTest);
2122

2223
TEST_P(urProgramGetFunctionPointerTest, Success) {
24+
UUR_KNOWN_FAILURE_ON(uur::OpenCL{"Intel(R) UHD Graphics 770"});
2325
void *function_pointer = nullptr;
2426
ASSERT_SUCCESS(urProgramGetFunctionPointer(
2527
device, program, function_name.data(), &function_pointer));
Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
// Copyright (C) 2024 Intel Corporation
2+
// Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM Exceptions.
3+
// See LICENSE.TXT
4+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5+
6+
#ifndef UR_CONFORMANCE_INCLUDE_KNOWN_FAILURE_H_INCLUDED
7+
#define UR_CONFORMANCE_INCLUDE_KNOWN_FAILURE_H_INCLUDED
8+
9+
#include "uur/environment.h"
10+
#include "uur/utils.h"
11+
#include <string>
12+
#include <string_view>
13+
#include <tuple>
14+
#include <vector>
15+
16+
namespace uur {
17+
struct Matcher {
18+
Matcher(uint32_t adapterVersion, ur_adapter_backend_t backend,
19+
std::vector<std::string> deviceNames)
20+
: adapterVersion(adapterVersion), backend(backend), names(deviceNames) {
21+
}
22+
23+
uint32_t adapterVersion;
24+
ur_adapter_backend_t backend;
25+
std::vector<std::string> names;
26+
};
27+
28+
struct OpenCL : Matcher {
29+
OpenCL(std::initializer_list<std::string> il)
30+
: Matcher(1, UR_ADAPTER_BACKEND_OPENCL, {il.begin(), il.end()}) {}
31+
};
32+
33+
struct LevelZero : Matcher {
34+
LevelZero(std::initializer_list<std::string> il)
35+
: Matcher(1, UR_ADAPTER_BACKEND_LEVEL_ZERO, {il.begin(), il.end()}) {}
36+
};
37+
38+
struct LevelZeroV2 : Matcher {
39+
LevelZeroV2(std::initializer_list<std::string> il)
40+
: Matcher(2, UR_ADAPTER_BACKEND_LEVEL_ZERO, {il.begin(), il.end()}) {}
41+
};
42+
43+
struct CUDA : Matcher {
44+
CUDA(std::initializer_list<std::string> il)
45+
: Matcher(1, UR_ADAPTER_BACKEND_CUDA, {il.begin(), il.end()}) {}
46+
};
47+
48+
struct HIP : Matcher {
49+
HIP(std::initializer_list<std::string> il)
50+
: Matcher(1, UR_ADAPTER_BACKEND_HIP, {il.begin(), il.end()}) {}
51+
};
52+
53+
struct NativeCPU : Matcher {
54+
NativeCPU(std::initializer_list<std::string> il)
55+
: Matcher(1, UR_ADAPTER_BACKEND_NATIVE_CPU, {il.begin(), il.end()}) {}
56+
};
57+
58+
namespace detail {
59+
struct AdapterInfo {
60+
uint32_t version;
61+
ur_adapter_backend_t backend;
62+
};
63+
64+
inline AdapterInfo getAdapterInfo(ur_adapter_handle_t adapter) {
65+
AdapterInfo info;
66+
urAdapterGetInfo(adapter, UR_ADAPTER_INFO_VERSION, sizeof(info.version),
67+
&info.version, nullptr);
68+
urAdapterGetInfo(adapter, UR_ADAPTER_INFO_BACKEND, sizeof(info.backend),
69+
&info.backend, nullptr);
70+
return info;
71+
}
72+
} // namespace detail
73+
74+
inline bool isKnownFailureOn(ur_adapter_handle_t adapter,
75+
const std::vector<Matcher> &matchers) {
76+
for (const auto &matcher : matchers) {
77+
auto adapterInfo = detail::getAdapterInfo(adapter);
78+
if (matcher.adapterVersion == adapterInfo.version &&
79+
matcher.backend == adapterInfo.backend) {
80+
return true;
81+
}
82+
}
83+
return false;
84+
}
85+
86+
template <class Param>
87+
inline bool
88+
isKnownFailureOn(const std::tuple<ur_platform_handle_t, Param> &param,
89+
const std::vector<Matcher> &matchers) {
90+
ur_platform_handle_t platform = std::get<0>(param);
91+
ur_adapter_handle_t adapter;
92+
urPlatformGetInfo(platform, UR_PLATFORM_INFO_ADAPTER,
93+
sizeof(ur_adapter_handle_t), &adapter, nullptr);
94+
for (const auto &matcher : matchers) {
95+
auto adapterInfo = detail::getAdapterInfo(adapter);
96+
if (matcher.adapterVersion != adapterInfo.version &&
97+
matcher.backend != adapterInfo.backend) {
98+
continue;
99+
}
100+
if (matcher.names.empty()) {
101+
return true;
102+
}
103+
std::string name;
104+
uur::GetPlatformInfo<std::string>(platform, UR_PLATFORM_INFO_NAME,
105+
name);
106+
for (const auto &matcherName : matcher.names) {
107+
if (name.find(matcherName) != std::string::npos) {
108+
return true;
109+
}
110+
}
111+
}
112+
return false;
113+
}
114+
115+
inline bool isKnownFailureOn(const DeviceTuple &param,
116+
const std::vector<Matcher> &matchers) {
117+
for (const auto &matcher : matchers) {
118+
auto adapterInfo = detail::getAdapterInfo(param.adapter);
119+
if (matcher.adapterVersion != adapterInfo.version &&
120+
matcher.backend != adapterInfo.backend) {
121+
continue;
122+
}
123+
if (matcher.names.empty()) {
124+
return true;
125+
}
126+
std::string name;
127+
uur::GetDeviceInfo<std::string>(param.device, UR_DEVICE_INFO_NAME,
128+
name);
129+
for (const auto &matcherName : matcher.names) {
130+
if (name.find(matcherName) != std::string::npos) {
131+
return true;
132+
}
133+
}
134+
}
135+
return false;
136+
}
137+
138+
template <class Param>
139+
inline bool isKnownFailureOn(const std::tuple<DeviceTuple, Param> &param,
140+
const std::vector<Matcher> &matchers) {
141+
return isKnownFailureOn(std::get<0>(param), matchers);
142+
}
143+
144+
inline std::string knownFailureMessage(ur_adapter_handle_t adapter) {
145+
std::string backend = uur::GetAdapterBackendName(adapter);
146+
return "Known failure on: " + backend;
147+
}
148+
149+
template <class Param>
150+
inline std::string
151+
knownFailureMessage(const std::tuple<ur_platform_handle_t, Param> &param) {
152+
ur_platform_handle_t platform = std::get<0>(param);
153+
ur_adapter_handle_t adapter;
154+
urPlatformGetInfo(platform, UR_PLATFORM_INFO_ADAPTER,
155+
sizeof(ur_adapter_handle_t), &adapter, nullptr);
156+
std::string backend = uur::GetAdapterBackendName(adapter);
157+
std::string platformName;
158+
uur::GetPlatformInfo<std::string>(platform, UR_PLATFORM_INFO_NAME,
159+
platformName);
160+
return "Known failure on: " + backend + ", " + platformName;
161+
}
162+
163+
inline std::string knownFailureMessage(const DeviceTuple &param) {
164+
std::string backend = uur::GetAdapterBackendName(param.adapter);
165+
std::string platformName;
166+
uur::GetPlatformInfo<std::string>(param.platform, UR_PLATFORM_INFO_NAME,
167+
platformName);
168+
std::string deviceName;
169+
uur::GetDeviceInfo<std::string>(param.device, UR_DEVICE_INFO_NAME,
170+
deviceName);
171+
return "Known failure on: " + backend + ", " + platformName + ", " +
172+
deviceName;
173+
}
174+
175+
template <class Param>
176+
inline std::string
177+
knownFailureMessage(const std::tuple<DeviceTuple, Param> &param) {
178+
return knownFailureMessage(std::get<0>(param));
179+
}
180+
181+
inline bool alsoRunKnownFailures() {
182+
if (const char *envvar = std::getenv("UR_CTS_ALSO_RUN_KNOWN_FAILURES")) {
183+
std::string_view value(envvar);
184+
return value == "1" || value == "ON" || value == "on" ||
185+
value == "YES" || value == "yes" || value == "true" ||
186+
value == "TRUE";
187+
}
188+
return false;
189+
}
190+
} // namespace uur
191+
192+
#define UUR_KNOWN_FAILURE_ON(...) \
193+
if (uur::isKnownFailureOn(GetParam(), {__VA_ARGS__})) { \
194+
auto message = uur::knownFailureMessage(GetParam()); \
195+
if (uur::alsoRunKnownFailures()) { \
196+
std::cerr << message << "\n"; \
197+
} else { \
198+
GTEST_SKIP() << message; \
199+
} \
200+
} \
201+
(void)0
202+
203+
#endif // UR_CONFORMANCE_INCLUDE_KNOWN_FAILURE_H_INCLUDED

test/conformance/testing/include/uur/utils.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,13 @@ ur_result_t GetInfo(ObjectTy object, InfoTy info, Callable cb, T &out_value) {
4343

4444
// special case for strings
4545
if constexpr (std::is_same_v<std::string, T>) {
46-
std::vector<char> data(size);
47-
result = cb(object, info, size, data.data(), nullptr);
46+
std::string value(size, '\0');
47+
result = cb(object, info, size, value.data(), nullptr);
4848
if (result != UR_RESULT_SUCCESS) {
4949
return result;
5050
}
51-
out_value = std::string(data.data(), data.size());
51+
out_value =
52+
value.substr(0, std::min(value.find_last_of('\0'), value.size()));
5253
return UR_RESULT_SUCCESS;
5354
} else {
5455
if (size != sizeof(T)) {

0 commit comments

Comments
 (0)