xref: /aosp_15_r20/external/OpenCL-CTS/test_common/harness/errorHelpers.h (revision 6467f958c7de8070b317fc65bcb0f6472e388d82)
1*6467f958SSadaf Ebrahimi //
2*6467f958SSadaf Ebrahimi // Copyright (c) 2017 The Khronos Group Inc.
3*6467f958SSadaf Ebrahimi //
4*6467f958SSadaf Ebrahimi // Licensed under the Apache License, Version 2.0 (the "License");
5*6467f958SSadaf Ebrahimi // you may not use this file except in compliance with the License.
6*6467f958SSadaf Ebrahimi // You may obtain a copy of the License at
7*6467f958SSadaf Ebrahimi //
8*6467f958SSadaf Ebrahimi //    http://www.apache.org/licenses/LICENSE-2.0
9*6467f958SSadaf Ebrahimi //
10*6467f958SSadaf Ebrahimi // Unless required by applicable law or agreed to in writing, software
11*6467f958SSadaf Ebrahimi // distributed under the License is distributed on an "AS IS" BASIS,
12*6467f958SSadaf Ebrahimi // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*6467f958SSadaf Ebrahimi // See the License for the specific language governing permissions and
14*6467f958SSadaf Ebrahimi // limitations under the License.
15*6467f958SSadaf Ebrahimi //
16*6467f958SSadaf Ebrahimi #ifndef _errorHelpers_h
17*6467f958SSadaf Ebrahimi #define _errorHelpers_h
18*6467f958SSadaf Ebrahimi 
19*6467f958SSadaf Ebrahimi #include <sstream>
20*6467f958SSadaf Ebrahimi 
21*6467f958SSadaf Ebrahimi #ifdef __APPLE__
22*6467f958SSadaf Ebrahimi #include <OpenCL/opencl.h>
23*6467f958SSadaf Ebrahimi #else
24*6467f958SSadaf Ebrahimi #include <CL/opencl.h>
25*6467f958SSadaf Ebrahimi #endif
26*6467f958SSadaf Ebrahimi #include <stdlib.h>
27*6467f958SSadaf Ebrahimi #define LOWER_IS_BETTER 0
28*6467f958SSadaf Ebrahimi #define HIGHER_IS_BETTER 1
29*6467f958SSadaf Ebrahimi 
30*6467f958SSadaf Ebrahimi #include <stdio.h>
31*6467f958SSadaf Ebrahimi #define test_start()
32*6467f958SSadaf Ebrahimi #define log_info printf
33*6467f958SSadaf Ebrahimi #define log_error printf
34*6467f958SSadaf Ebrahimi #define log_missing_feature printf
35*6467f958SSadaf Ebrahimi #define log_perf(_number, _higherBetter, _numType, _format, ...)               \
36*6467f958SSadaf Ebrahimi     printf("Performance Number " _format " (in %s, %s): %g\n", ##__VA_ARGS__,  \
37*6467f958SSadaf Ebrahimi            _numType, _higherBetter ? "higher is better" : "lower is better",   \
38*6467f958SSadaf Ebrahimi            _number)
39*6467f958SSadaf Ebrahimi #define vlog_perf(_number, _higherBetter, _numType, _format, ...)              \
40*6467f958SSadaf Ebrahimi     printf("Performance Number " _format " (in %s, %s): %g\n", ##__VA_ARGS__,  \
41*6467f958SSadaf Ebrahimi            _numType, _higherBetter ? "higher is better" : "lower is better",   \
42*6467f958SSadaf Ebrahimi            _number)
43*6467f958SSadaf Ebrahimi #ifdef _WIN32
44*6467f958SSadaf Ebrahimi #ifdef __MINGW32__
45*6467f958SSadaf Ebrahimi // Use __mingw_printf since it supports "%a" format specifier
46*6467f958SSadaf Ebrahimi #define vlog __mingw_printf
47*6467f958SSadaf Ebrahimi #define vlog_error __mingw_printf
48*6467f958SSadaf Ebrahimi #else
49*6467f958SSadaf Ebrahimi // Use home-baked function that treats "%a" as "%f"
50*6467f958SSadaf Ebrahimi static int vlog_win32(const char *format, ...);
51*6467f958SSadaf Ebrahimi #define vlog vlog_win32
52*6467f958SSadaf Ebrahimi #define vlog_error vlog_win32
53*6467f958SSadaf Ebrahimi #endif
54*6467f958SSadaf Ebrahimi #else
55*6467f958SSadaf Ebrahimi #define vlog_error printf
56*6467f958SSadaf Ebrahimi #define vlog printf
57*6467f958SSadaf Ebrahimi #endif
58*6467f958SSadaf Ebrahimi 
59*6467f958SSadaf Ebrahimi #define test_fail(msg, ...)                                                    \
60*6467f958SSadaf Ebrahimi     {                                                                          \
61*6467f958SSadaf Ebrahimi         log_error(msg, ##__VA_ARGS__);                                         \
62*6467f958SSadaf Ebrahimi         return TEST_FAIL;                                                      \
63*6467f958SSadaf Ebrahimi     }
64*6467f958SSadaf Ebrahimi #define test_error(errCode, msg) test_error_ret(errCode, msg, errCode)
65*6467f958SSadaf Ebrahimi #define test_error_fail(errCode, msg) test_error_ret(errCode, msg, TEST_FAIL)
66*6467f958SSadaf Ebrahimi #define test_error_ret(errCode, msg, retValue)                                 \
67*6467f958SSadaf Ebrahimi     {                                                                          \
68*6467f958SSadaf Ebrahimi         auto errCodeResult = errCode;                                          \
69*6467f958SSadaf Ebrahimi         if (errCodeResult != CL_SUCCESS)                                       \
70*6467f958SSadaf Ebrahimi         {                                                                      \
71*6467f958SSadaf Ebrahimi             print_error(errCodeResult, msg);                                   \
72*6467f958SSadaf Ebrahimi             return retValue;                                                   \
73*6467f958SSadaf Ebrahimi         }                                                                      \
74*6467f958SSadaf Ebrahimi     }
75*6467f958SSadaf Ebrahimi #define print_error(errCode, msg)                                              \
76*6467f958SSadaf Ebrahimi     log_error("ERROR: %s! (%s from %s:%d)\n", msg, IGetErrorString(errCode),   \
77*6467f958SSadaf Ebrahimi               __FILE__, __LINE__);
78*6467f958SSadaf Ebrahimi 
79*6467f958SSadaf Ebrahimi #define test_missing_feature(errCode, msg)                                     \
80*6467f958SSadaf Ebrahimi     test_missing_feature_ret(errCode, msg, errCode)
81*6467f958SSadaf Ebrahimi // this macro should always return CL_SUCCESS, but print the missing feature
82*6467f958SSadaf Ebrahimi // message
83*6467f958SSadaf Ebrahimi #define test_missing_feature_ret(errCode, msg, retValue)                       \
84*6467f958SSadaf Ebrahimi     {                                                                          \
85*6467f958SSadaf Ebrahimi         if (errCode != CL_SUCCESS)                                             \
86*6467f958SSadaf Ebrahimi         {                                                                      \
87*6467f958SSadaf Ebrahimi             print_missing_feature(errCode, msg);                               \
88*6467f958SSadaf Ebrahimi             return CL_SUCCESS;                                                 \
89*6467f958SSadaf Ebrahimi         }                                                                      \
90*6467f958SSadaf Ebrahimi     }
91*6467f958SSadaf Ebrahimi #define print_missing_feature(errCode, msg)                                    \
92*6467f958SSadaf Ebrahimi     log_missing_feature("ERROR: Subtest %s tests a feature not supported by "  \
93*6467f958SSadaf Ebrahimi                         "the device version! (from %s:%d)\n",                  \
94*6467f958SSadaf Ebrahimi                         msg, __FILE__, __LINE__);
95*6467f958SSadaf Ebrahimi 
96*6467f958SSadaf Ebrahimi // expected error code vs. what we got
97*6467f958SSadaf Ebrahimi #define test_failure_error(errCode, expectedErrCode, msg)                      \
98*6467f958SSadaf Ebrahimi     test_failure_error_ret(errCode, expectedErrCode, msg,                      \
99*6467f958SSadaf Ebrahimi                            errCode != expectedErrCode)
100*6467f958SSadaf Ebrahimi #define test_failure_error_ret(errCode, expectedErrCode, msg, retValue)        \
101*6467f958SSadaf Ebrahimi     {                                                                          \
102*6467f958SSadaf Ebrahimi         if (errCode != expectedErrCode)                                        \
103*6467f958SSadaf Ebrahimi         {                                                                      \
104*6467f958SSadaf Ebrahimi             print_failure_error(errCode, expectedErrCode, msg);                \
105*6467f958SSadaf Ebrahimi             return retValue;                                                   \
106*6467f958SSadaf Ebrahimi         }                                                                      \
107*6467f958SSadaf Ebrahimi     }
108*6467f958SSadaf Ebrahimi #define print_failure_error(errCode, expectedErrCode, msg)                     \
109*6467f958SSadaf Ebrahimi     log_error("ERROR: %s! (Got %s, expected %s from %s:%d)\n", msg,            \
110*6467f958SSadaf Ebrahimi               IGetErrorString(errCode), IGetErrorString(expectedErrCode),      \
111*6467f958SSadaf Ebrahimi               __FILE__, __LINE__);
112*6467f958SSadaf Ebrahimi #define test_failure_warning(errCode, expectedErrCode, msg)                    \
113*6467f958SSadaf Ebrahimi     test_failure_warning_ret(errCode, expectedErrCode, msg,                    \
114*6467f958SSadaf Ebrahimi                              errCode != expectedErrCode)
115*6467f958SSadaf Ebrahimi #define test_failure_warning_ret(errCode, expectedErrCode, msg, retValue)      \
116*6467f958SSadaf Ebrahimi     {                                                                          \
117*6467f958SSadaf Ebrahimi         if (errCode != expectedErrCode)                                        \
118*6467f958SSadaf Ebrahimi         {                                                                      \
119*6467f958SSadaf Ebrahimi             print_failure_warning(errCode, expectedErrCode, msg);              \
120*6467f958SSadaf Ebrahimi             warnings++;                                                        \
121*6467f958SSadaf Ebrahimi         }                                                                      \
122*6467f958SSadaf Ebrahimi     }
123*6467f958SSadaf Ebrahimi #define print_failure_warning(errCode, expectedErrCode, msg)                   \
124*6467f958SSadaf Ebrahimi     log_error("WARNING: %s! (Got %s, expected %s from %s:%d)\n", msg,          \
125*6467f958SSadaf Ebrahimi               IGetErrorString(errCode), IGetErrorString(expectedErrCode),      \
126*6467f958SSadaf Ebrahimi               __FILE__, __LINE__);
127*6467f958SSadaf Ebrahimi 
128*6467f958SSadaf Ebrahimi // generate an error when an assertion is false (not error code related)
129*6467f958SSadaf Ebrahimi #define test_assert_error(condition, msg)                                      \
130*6467f958SSadaf Ebrahimi     test_assert_error_ret(condition, msg, TEST_FAIL)
131*6467f958SSadaf Ebrahimi #define test_assert_error_ret(condition, msg, retValue)                        \
132*6467f958SSadaf Ebrahimi     {                                                                          \
133*6467f958SSadaf Ebrahimi         if (!(condition))                                                      \
134*6467f958SSadaf Ebrahimi         {                                                                      \
135*6467f958SSadaf Ebrahimi             print_assertion_error(condition, msg);                             \
136*6467f958SSadaf Ebrahimi             return retValue;                                                   \
137*6467f958SSadaf Ebrahimi         }                                                                      \
138*6467f958SSadaf Ebrahimi     }
139*6467f958SSadaf Ebrahimi #define print_assertion_error(condition, msg)                                  \
140*6467f958SSadaf Ebrahimi     log_error("ERROR: %s! (!(%s) from %s:%d)\n", msg, #condition, __FILE__,    \
141*6467f958SSadaf Ebrahimi               __LINE__);
142*6467f958SSadaf Ebrahimi 
143*6467f958SSadaf Ebrahimi #define ASSERT_SUCCESS(expr, msg)                                              \
144*6467f958SSadaf Ebrahimi     do                                                                         \
145*6467f958SSadaf Ebrahimi     {                                                                          \
146*6467f958SSadaf Ebrahimi         cl_int _temp_retval = (expr);                                          \
147*6467f958SSadaf Ebrahimi         if (_temp_retval != CL_SUCCESS)                                        \
148*6467f958SSadaf Ebrahimi         {                                                                      \
149*6467f958SSadaf Ebrahimi             std::stringstream ss;                                              \
150*6467f958SSadaf Ebrahimi             ss << "ERROR: " << msg << "=" << IGetErrorString(_temp_retval)     \
151*6467f958SSadaf Ebrahimi                << " at " << __FILE__ << ":" << __LINE__ << "\n";               \
152*6467f958SSadaf Ebrahimi             throw std::runtime_error(ss.str());                                \
153*6467f958SSadaf Ebrahimi         }                                                                      \
154*6467f958SSadaf Ebrahimi     } while (0)
155*6467f958SSadaf Ebrahimi 
156*6467f958SSadaf Ebrahimi #define test_assert_event_status(comparison_operator, event)                   \
157*6467f958SSadaf Ebrahimi     do                                                                         \
158*6467f958SSadaf Ebrahimi     {                                                                          \
159*6467f958SSadaf Ebrahimi         cl_int status;                                                         \
160*6467f958SSadaf Ebrahimi         cl_int err = clGetEventInfo(event, CL_EVENT_COMMAND_EXECUTION_STATUS,  \
161*6467f958SSadaf Ebrahimi                                     sizeof(status), &status, nullptr);         \
162*6467f958SSadaf Ebrahimi         test_error(err, "Could not get " #event " info");                      \
163*6467f958SSadaf Ebrahimi         test_assert_error(status comparison_operator CL_COMPLETE,              \
164*6467f958SSadaf Ebrahimi                           "Unexpected status for " #event);                    \
165*6467f958SSadaf Ebrahimi     } while (false)
166*6467f958SSadaf Ebrahimi 
167*6467f958SSadaf Ebrahimi #define test_assert_event_inprogress(event) test_assert_event_status(>, event)
168*6467f958SSadaf Ebrahimi #define test_assert_event_terminated(event) test_assert_event_status(<, event)
169*6467f958SSadaf Ebrahimi #define test_assert_event_complete(event) test_assert_event_status(==, event)
170*6467f958SSadaf Ebrahimi 
171*6467f958SSadaf Ebrahimi extern const char *IGetErrorString(int clErrorCode);
172*6467f958SSadaf Ebrahimi 
173*6467f958SSadaf Ebrahimi extern float Ulp_Error_Half(cl_half test, float reference);
174*6467f958SSadaf Ebrahimi extern float Ulp_Error(float test, double reference);
175*6467f958SSadaf Ebrahimi extern float Ulp_Error_Double(double test, long double reference);
176*6467f958SSadaf Ebrahimi 
177*6467f958SSadaf Ebrahimi extern const char *GetChannelTypeName(cl_channel_type type);
178*6467f958SSadaf Ebrahimi extern int IsChannelTypeSupported(cl_channel_type type);
179*6467f958SSadaf Ebrahimi extern const char *GetChannelOrderName(cl_channel_order order);
180*6467f958SSadaf Ebrahimi extern int IsChannelOrderSupported(cl_channel_order order);
181*6467f958SSadaf Ebrahimi extern const char *GetAddressModeName(cl_addressing_mode mode);
182*6467f958SSadaf Ebrahimi extern const char *GetQueuePropertyName(cl_command_queue_properties properties);
183*6467f958SSadaf Ebrahimi 
184*6467f958SSadaf Ebrahimi extern const char *GetDeviceTypeName(cl_device_type type);
185*6467f958SSadaf Ebrahimi bool check_functions_for_offline_compiler(const char *subtestname);
186*6467f958SSadaf Ebrahimi cl_int OutputBuildLogs(cl_program program, cl_uint num_devices,
187*6467f958SSadaf Ebrahimi                        cl_device_id *device_list);
188*6467f958SSadaf Ebrahimi 
189*6467f958SSadaf Ebrahimi // NON-REENTRANT UNLESS YOU PROVIDE A BUFFER PTR (pass null to use static
190*6467f958SSadaf Ebrahimi // storage, but it's not reentrant then!)
191*6467f958SSadaf Ebrahimi extern const char *GetDataVectorString(void *dataBuffer, size_t typeSize,
192*6467f958SSadaf Ebrahimi                                        size_t vecSize, char *buffer);
193*6467f958SSadaf Ebrahimi 
194*6467f958SSadaf Ebrahimi #if defined(_WIN32) && !defined(__MINGW32__)
195*6467f958SSadaf Ebrahimi #include <stdarg.h>
196*6467f958SSadaf Ebrahimi #include <stdio.h>
197*6467f958SSadaf Ebrahimi #include <string.h>
vlog_win32(const char * format,...)198*6467f958SSadaf Ebrahimi static int vlog_win32(const char *format, ...)
199*6467f958SSadaf Ebrahimi {
200*6467f958SSadaf Ebrahimi     const char *new_format = format;
201*6467f958SSadaf Ebrahimi 
202*6467f958SSadaf Ebrahimi     if (strstr(format, "%a"))
203*6467f958SSadaf Ebrahimi     {
204*6467f958SSadaf Ebrahimi         char *temp;
205*6467f958SSadaf Ebrahimi         if ((temp = strdup(format)) == NULL)
206*6467f958SSadaf Ebrahimi         {
207*6467f958SSadaf Ebrahimi             printf("vlog_win32: Failed to allocate memory for strdup\n");
208*6467f958SSadaf Ebrahimi             return -1;
209*6467f958SSadaf Ebrahimi         }
210*6467f958SSadaf Ebrahimi         new_format = temp;
211*6467f958SSadaf Ebrahimi         while (*temp)
212*6467f958SSadaf Ebrahimi         {
213*6467f958SSadaf Ebrahimi             // replace %a with %f
214*6467f958SSadaf Ebrahimi             if ((*temp == '%') && (*(temp + 1) == 'a'))
215*6467f958SSadaf Ebrahimi             {
216*6467f958SSadaf Ebrahimi                 *(temp + 1) = 'f';
217*6467f958SSadaf Ebrahimi             }
218*6467f958SSadaf Ebrahimi             temp++;
219*6467f958SSadaf Ebrahimi         }
220*6467f958SSadaf Ebrahimi     }
221*6467f958SSadaf Ebrahimi 
222*6467f958SSadaf Ebrahimi     va_list args;
223*6467f958SSadaf Ebrahimi     va_start(args, format);
224*6467f958SSadaf Ebrahimi     vprintf(new_format, args);
225*6467f958SSadaf Ebrahimi     va_end(args);
226*6467f958SSadaf Ebrahimi 
227*6467f958SSadaf Ebrahimi     if (new_format != format)
228*6467f958SSadaf Ebrahimi     {
229*6467f958SSadaf Ebrahimi         free((void *)new_format);
230*6467f958SSadaf Ebrahimi     }
231*6467f958SSadaf Ebrahimi 
232*6467f958SSadaf Ebrahimi     return 0;
233*6467f958SSadaf Ebrahimi }
234*6467f958SSadaf Ebrahimi #endif
235*6467f958SSadaf Ebrahimi 
236*6467f958SSadaf Ebrahimi 
237*6467f958SSadaf Ebrahimi #endif // _errorHelpers_h
238