// // Copyright (c) 2017 The Khronos Group Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // #ifndef _errorHelpers_h #define _errorHelpers_h #ifdef __APPLE__ #include #else #include #endif #include #ifdef __cplusplus extern "C" { #endif #define LOWER_IS_BETTER 0 #define HIGHER_IS_BETTER 1 // If USE_ATF is defined, all log_error and log_info calls can be routed to test library // functions as described below. This is helpful for integration into an automated testing // system. #if USE_ATF // export BUILD_WITH_ATF=1 #include #define test_start() ATFTestStart() #define log_info ATFLogInfo #define log_error ATFLogError #define log_perf(_number, _higherBetter, _numType, _format, ...) ATFLogPerformanceNumber(_number, _higherBetter, _numType, _format, ##__VA_ARGS__) #define test_finish() ATFTestFinish() #define vlog_perf(_number, _higherBetter, _numType, _format, ...) ATFLogPerformanceNumber(_number, _higherBetter, _numType, _format,##__VA_ARGS__) #define vlog ATFLogInfo #define vlog_error ATFLogError #else #define test_start() #define log_info printf #define log_error printf #define log_perf(_number, _higherBetter, _numType, _format, ...) printf("Performance Number " _format " (in %s, %s): %g\n",##__VA_ARGS__, _numType, \ _higherBetter?"higher is better":"lower is better", _number ) #define test_finish() #define vlog_perf(_number, _higherBetter, _numType, _format, ...) printf("Performance Number " _format " (in %s, %s): %g\n",##__VA_ARGS__, _numType, \ _higherBetter?"higher is better":"lower is better" , _number) #ifdef _WIN32 #ifdef __MINGW32__ // Use __mingw_printf since it supports "%a" format specifier #define vlog __mingw_printf #define vlog_error __mingw_printf #else // Use home-baked function that treats "%a" as "%f" static int vlog_win32(const char *format, ...); #define vlog vlog_win32 #define vlog_error vlog_win32 #endif #else #define vlog_error printf #define vlog printf #endif #endif #define ct_assert(b) ct_assert_i(b, __LINE__) #define ct_assert_i(b, line) ct_assert_ii(b, line) #define ct_assert_ii(b, line) int _compile_time_assertion_on_line_##line[b ? 1 : -1]; #define test_error(errCode,msg) test_error_ret(errCode,msg,errCode) #define test_error_ret(errCode,msg,retValue) { if( errCode != CL_SUCCESS ) { print_error( errCode, msg ); return retValue ; } } #define print_error(errCode,msg) log_error( "ERROR: %s! (%s from %s:%d)\n", msg, IGetErrorString( errCode ), __FILE__, __LINE__ ); // expected error code vs. what we got #define test_failure_error(errCode, expectedErrCode, msg) test_failure_error_ret(errCode, expectedErrCode, msg, errCode != expectedErrCode) #define test_failure_error_ret(errCode, expectedErrCode, msg, retValue) { if( errCode != expectedErrCode ) { print_failure_error( errCode, expectedErrCode, msg ); return retValue ; } } #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__ ); #define test_failure_warning(errCode, expectedErrCode, msg) test_failure_warning_ret(errCode, expectedErrCode, msg, errCode != expectedErrCode) #define test_failure_warning_ret(errCode, expectedErrCode, msg, retValue) { if( errCode != expectedErrCode ) { print_failure_warning( errCode, expectedErrCode, msg ); warnings++ ; } } #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__ ); extern const char *IGetErrorString( int clErrorCode ); extern float Ulp_Error_Half( cl_ushort test, float reference ); extern float Ulp_Error( float test, double reference ); extern float Ulp_Error_Double( double test, long double reference ); extern const char *GetChannelTypeName( cl_channel_type type ); extern int IsChannelTypeSupported( cl_channel_type type ); extern const char *GetChannelOrderName( cl_channel_order order ); extern int IsChannelOrderSupported( cl_channel_order order ); extern const char *GetAddressModeName( cl_addressing_mode mode ); extern const char *GetDeviceTypeName( cl_device_type type ); // NON-REENTRANT UNLESS YOU PROVIDE A BUFFER PTR (pass null to use static storage, but it's not reentrant then!) extern const char *GetDataVectorString( void *dataBuffer, size_t typeSize, size_t vecSize, char *buffer ); #if defined (_WIN32) && !defined(__MINGW32__) #include #include #include static int vlog_win32(const char *format, ...) { const char *new_format = format; if (strstr(format, "%a")) { char *temp; if ((temp = strdup(format)) == NULL) { printf("vlog_win32: Failed to allocate memory for strdup\n"); return -1; } new_format = temp; while (*temp) { // replace %a with %f if ((*temp == '%') && (*(temp+1) == 'a')) { *(temp+1) = 'f'; } temp++; } } va_list args; va_start(args, format); vprintf(new_format, args); va_end(args); if (new_format != format) { free((void*)new_format); } return 0; } #endif #ifdef __cplusplus } #endif #endif // _errorHelpers_h