1 //
2 // Copyright (c) 2017 The Khronos Group Inc.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 #ifndef _errorHelpers_h
17 #define _errorHelpers_h
18
19 #include <sstream>
20
21 #ifdef __APPLE__
22 #include <OpenCL/opencl.h>
23 #else
24 #include <CL/opencl.h>
25 #endif
26 #include <stdlib.h>
27 #define LOWER_IS_BETTER 0
28 #define HIGHER_IS_BETTER 1
29
30 #include <stdio.h>
31 #define test_start()
32 #define log_info printf
33 #define log_error printf
34 #define log_missing_feature printf
35 #define log_perf(_number, _higherBetter, _numType, _format, ...) printf("Performance Number " _format " (in %s, %s): %g\n",##__VA_ARGS__, _numType, \
36 _higherBetter?"higher is better":"lower is better", _number )
37 #define vlog_perf(_number, _higherBetter, _numType, _format, ...) printf("Performance Number " _format " (in %s, %s): %g\n",##__VA_ARGS__, _numType, \
38 _higherBetter?"higher is better":"lower is better" , _number)
39 #ifdef _WIN32
40 #ifdef __MINGW32__
41 // Use __mingw_printf since it supports "%a" format specifier
42 #define vlog __mingw_printf
43 #define vlog_error __mingw_printf
44 #else
45 // Use home-baked function that treats "%a" as "%f"
46 static int vlog_win32(const char *format, ...);
47 #define vlog vlog_win32
48 #define vlog_error vlog_win32
49 #endif
50 #else
51 #define vlog_error printf
52 #define vlog printf
53 #endif
54
55 #define ct_assert(b) ct_assert_i(b, __LINE__)
56 #define ct_assert_i(b, line) ct_assert_ii(b, line)
57 #define ct_assert_ii(b, line) int _compile_time_assertion_on_line_##line[b ? 1 : -1];
58
59 #define test_error(errCode,msg) test_error_ret(errCode,msg,errCode)
60 #define test_error_ret(errCode,msg,retValue) { if( errCode != CL_SUCCESS ) { print_error( errCode, msg ); return retValue ; } }
61 #define print_error(errCode,msg) log_error( "ERROR: %s! (%s from %s:%d)\n", msg, IGetErrorString( errCode ), __FILE__, __LINE__ );
62
63 #define test_missing_feature(errCode, msg) test_missing_feature_ret(errCode, msg, errCode)
64 // this macro should always return CL_SUCCESS, but print the missing feature message
65 #define test_missing_feature_ret(errCode,msg,retValue) { if( errCode != CL_SUCCESS ) { print_missing_feature( errCode, msg ); return CL_SUCCESS ; } }
66 #define print_missing_feature(errCode, msg) log_missing_feature("ERROR: Subtest %s tests a feature not supported by the device version! (from %s:%d)\n", msg, __FILE__, __LINE__ );
67
68 #define test_missing_support_offline_cmpiler(errCode, msg) test_missing_support_offline_cmpiler_ret(errCode, msg, errCode)
69 // this macro should always return CL_SUCCESS, but print the skip message on test not supported with offline compiler
70 #define test_missing_support_offline_cmpiler_ret(errCode,msg,retValue) { if( errCode != CL_SUCCESS ) { log_info( "INFO: Subtest %s tests is not supported in offline compiler execution path! (from %s:%d)\n", msg, __FILE__, __LINE__ ); return TEST_SKIP ; } }
71
72 // expected error code vs. what we got
73 #define test_failure_error(errCode, expectedErrCode, msg) test_failure_error_ret(errCode, expectedErrCode, msg, errCode != expectedErrCode)
74 #define test_failure_error_ret(errCode, expectedErrCode, msg, retValue) { if( errCode != expectedErrCode ) { print_failure_error( errCode, expectedErrCode, msg ); return retValue ; } }
75 #define print_failure_error(errCode, expectedErrCode, msg) log_error( "ERROR: %s! (Got %s, expected %s from %s:%d)\n", msg, IGetErrorString( errCode ), IGetErrorString( expectedErrCode ), __FILE__, __LINE__ );
76 #define test_failure_warning(errCode, expectedErrCode, msg) test_failure_warning_ret(errCode, expectedErrCode, msg, errCode != expectedErrCode)
77 #define test_failure_warning_ret(errCode, expectedErrCode, msg, retValue) { if( errCode != expectedErrCode ) { print_failure_warning( errCode, expectedErrCode, msg ); warnings++ ; } }
78 #define print_failure_warning(errCode, expectedErrCode, msg) log_error( "WARNING: %s! (Got %s, expected %s from %s:%d)\n", msg, IGetErrorString( errCode ), IGetErrorString( expectedErrCode ), __FILE__, __LINE__ );
79
80 #define ASSERT_SUCCESS(expr, msg) \
81 do \
82 { \
83 cl_int _temp_retval = (expr); \
84 if (_temp_retval != CL_SUCCESS) \
85 { \
86 std::stringstream ss; \
87 ss << "ERROR: " << msg << "=" << IGetErrorString(_temp_retval) \
88 << " at " << __FILE__ << ":" << __LINE__ << "\n"; \
89 throw std::runtime_error(ss.str()); \
90 } \
91 } while (0)
92
93 extern const char *IGetErrorString( int clErrorCode );
94
95 extern float Ulp_Error_Half( cl_ushort test, float reference );
96 extern float Ulp_Error( float test, double reference );
97 extern float Ulp_Error_Double( double test, long double reference );
98
99 extern const char *GetChannelTypeName( cl_channel_type type );
100 extern int IsChannelTypeSupported( cl_channel_type type );
101 extern const char *GetChannelOrderName( cl_channel_order order );
102 extern int IsChannelOrderSupported( cl_channel_order order );
103 extern const char *GetAddressModeName( cl_addressing_mode mode );
104
105 extern const char *GetDeviceTypeName( cl_device_type type );
106 int check_functions_for_offline_compiler(const char *subtestname, cl_device_id device);
107
108 // NON-REENTRANT UNLESS YOU PROVIDE A BUFFER PTR (pass null to use static storage, but it's not reentrant then!)
109 extern const char *GetDataVectorString( void *dataBuffer, size_t typeSize, size_t vecSize, char *buffer );
110
111 #if defined (_WIN32) && !defined(__MINGW32__)
112 #include <stdarg.h>
113 #include <stdio.h>
114 #include <string.h>
vlog_win32(const char * format,...)115 static int vlog_win32(const char *format, ...)
116 {
117 const char *new_format = format;
118
119 if (strstr(format, "%a")) {
120 char *temp;
121 if ((temp = strdup(format)) == NULL) {
122 printf("vlog_win32: Failed to allocate memory for strdup\n");
123 return -1;
124 }
125 new_format = temp;
126 while (*temp) {
127 // replace %a with %f
128 if ((*temp == '%') && (*(temp+1) == 'a')) {
129 *(temp+1) = 'f';
130 }
131 temp++;
132 }
133 }
134
135 va_list args;
136 va_start(args, format);
137 vprintf(new_format, args);
138 va_end(args);
139
140 if (new_format != format) {
141 free((void*)new_format);
142 }
143
144 return 0;
145 }
146 #endif
147
148
149 #endif // _errorHelpers_h
150
151
152