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