• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "compat.h"
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 
21 #include "errorHelpers.h"
22 
23 #include "parseParameters.h"
24 
IGetErrorString(int clErrorCode)25 const char    *IGetErrorString( int clErrorCode )
26 {
27     switch( clErrorCode )
28     {
29         case CL_SUCCESS:                return "CL_SUCCESS";
30         case CL_DEVICE_NOT_FOUND:        return "CL_DEVICE_NOT_FOUND";
31         case CL_DEVICE_NOT_AVAILABLE:    return "CL_DEVICE_NOT_AVAILABLE";
32         case CL_COMPILER_NOT_AVAILABLE:    return "CL_COMPILER_NOT_AVAILABLE";
33         case CL_MEM_OBJECT_ALLOCATION_FAILURE:    return "CL_MEM_OBJECT_ALLOCATION_FAILURE";
34         case CL_OUT_OF_RESOURCES:        return "CL_OUT_OF_RESOURCES";
35         case CL_OUT_OF_HOST_MEMORY:        return "CL_OUT_OF_HOST_MEMORY";
36         case CL_PROFILING_INFO_NOT_AVAILABLE: return "CL_PROFILING_INFO_NOT_AVAILABLE";
37         case CL_MEM_COPY_OVERLAP:        return "CL_MEM_COPY_OVERLAP";
38         case CL_IMAGE_FORMAT_MISMATCH:    return "CL_IMAGE_FORMAT_MISMATCH";
39         case CL_IMAGE_FORMAT_NOT_SUPPORTED:    return "CL_IMAGE_FORMAT_NOT_SUPPORTED";
40         case CL_BUILD_PROGRAM_FAILURE: return "CL_BUILD_PROGRAM_FAILURE";
41         case CL_MAP_FAILURE:            return "CL_MAP_FAILURE";
42         case CL_MISALIGNED_SUB_BUFFER_OFFSET: return "CL_MISALIGNED_SUB_BUFFER_OFFSET";
43         case CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST: return "CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST";
44         case CL_COMPILE_PROGRAM_FAILURE: return "CL_COMPILE_PROGRAM_FAILURE";
45         case CL_LINKER_NOT_AVAILABLE: return "CL_LINKER_NOT_AVAILABLE";
46         case CL_LINK_PROGRAM_FAILURE: return "CL_LINK_PROGRAM_FAILURE";
47         case CL_DEVICE_PARTITION_FAILED: return "CL_DEVICE_PARTITION_FAILED";
48         case CL_KERNEL_ARG_INFO_NOT_AVAILABLE: return "CL_KERNEL_ARG_INFO_NOT_AVAILABLE";
49         case CL_INVALID_VALUE:            return "CL_INVALID_VALUE";
50         case CL_INVALID_DEVICE_TYPE: return "CL_INVALID_DEVICE_TYPE";
51         case CL_INVALID_DEVICE:            return "CL_INVALID_DEVICE";
52         case CL_INVALID_CONTEXT:        return "CL_INVALID_CONTEXT";
53         case CL_INVALID_QUEUE_PROPERTIES:    return "CL_INVALID_QUEUE_PROPERTIES";
54         case CL_INVALID_COMMAND_QUEUE:    return "CL_INVALID_COMMAND_QUEUE";
55         case CL_INVALID_HOST_PTR:    return "CL_INVALID_HOST_PTR";
56         case CL_INVALID_MEM_OBJECT:        return "CL_INVALID_MEM_OBJECT";
57         case CL_INVALID_IMAGE_FORMAT_DESCRIPTOR:        return "CL_INVALID_IMAGE_FORMAT_DESCRIPTOR";
58         case CL_INVALID_IMAGE_SIZE:        return "CL_INVALID_IMAGE_SIZE";
59         case CL_INVALID_SAMPLER:        return "CL_INVALID_SAMPLER";
60         case CL_INVALID_BINARY:        return "CL_INVALID_BINARY";
61         case CL_INVALID_BUILD_OPTIONS:        return "CL_INVALID_BUILD_OPTIONS";
62         case CL_INVALID_PROGRAM:        return "CL_INVALID_PROGRAM";
63         case CL_INVALID_PROGRAM_EXECUTABLE:        return "CL_INVALID_PROGRAM_EXECUTABLE";
64         case CL_INVALID_KERNEL_NAME:    return "CL_INVALID_KERNEL_NAME";
65         case CL_INVALID_KERNEL_DEFINITION:    return "CL_INVALID_KERNEL_DEFINITION";
66         case CL_INVALID_KERNEL:            return "CL_INVALID_KERNEL";
67         case CL_INVALID_ARG_INDEX:        return "CL_INVALID_ARG_INDEX";
68         case CL_INVALID_ARG_VALUE:        return "CL_INVALID_ARG_VALUE";
69         case CL_INVALID_ARG_SIZE:        return "CL_INVALID_ARG_SIZE";
70         case CL_INVALID_KERNEL_ARGS:    return "CL_INVALID_KERNEL_ARGS";
71         case CL_INVALID_WORK_DIMENSION:        return "CL_INVALID_WORK_DIMENSION";
72         case CL_INVALID_WORK_GROUP_SIZE:    return "CL_INVALID_WORK_GROUP_SIZE";
73         case CL_INVALID_WORK_ITEM_SIZE:    return "CL_INVALID_WORK_ITEM_SIZE";
74         case CL_INVALID_GLOBAL_OFFSET:        return "CL_INVALID_GLOBAL_OFFSET";
75         case CL_INVALID_EVENT_WAIT_LIST:    return "CL_INVALID_EVENT_WAIT_LIST";
76         case CL_INVALID_EVENT:            return "CL_INVALID_EVENT";
77         case CL_INVALID_OPERATION:        return "CL_INVALID_OPERATION";
78         case CL_INVALID_GL_OBJECT:        return "CL_INVALID_GL_OBJECT";
79         case CL_INVALID_BUFFER_SIZE:    return "CL_INVALID_BUFFER_SIZE";
80         case CL_INVALID_MIP_LEVEL:      return "CL_INVALID_MIP_LEVEL";
81         case CL_INVALID_GLOBAL_WORK_SIZE: return "CL_INVALID_GLOBAL_WORK_SIZE";
82         case CL_INVALID_PROPERTY: return "CL_INVALID_PROPERTY";
83         case CL_INVALID_IMAGE_DESCRIPTOR: return "CL_INVALID_IMAGE_DESCRIPTOR";
84         case CL_INVALID_COMPILER_OPTIONS: return "CL_INVALID_COMPILER_OPTIONS";
85         case CL_INVALID_LINKER_OPTIONS: return "CL_INVALID_LINKER_OPTIONS";
86         case CL_INVALID_DEVICE_PARTITION_COUNT: return "CL_INVALID_DEVICE_PARTITION_COUNT";
87         default: return "(unknown)";
88     }
89 }
90 
GetChannelOrderName(cl_channel_order order)91 const char *GetChannelOrderName( cl_channel_order order )
92 {
93     switch( order )
94     {
95         case CL_R:      return "CL_R";
96         case CL_A:      return "CL_A";
97         case CL_Rx:     return "CL_Rx";
98         case CL_RG:     return "CL_RG";
99         case CL_RA:     return "CL_RA";
100         case CL_RGx:    return "CL_RGx";
101         case CL_RGB:    return "CL_RGB";
102         case CL_RGBx:   return "CL_RGBx";
103         case CL_RGBA:      return "CL_RGBA";
104         case CL_ARGB:      return "CL_ARGB";
105         case CL_BGRA:      return "CL_BGRA";
106         case CL_INTENSITY: return "CL_INTENSITY";
107         case CL_LUMINANCE: return "CL_LUMINANCE";
108 #if defined CL_1RGB_APPLE
109         case CL_1RGB_APPLE: return "CL_1RGB_APPLE";
110 #endif
111 #if defined CL_BGR1_APPLE
112         case CL_BGR1_APPLE: return "CL_BGR1_APPLE";
113 #endif
114 #if defined CL_ABGR_APPLE
115         case CL_ABGR_APPLE: return "CL_ABGR_APPLE";
116 #endif
117         case CL_DEPTH: return "CL_DEPTH";
118         case CL_DEPTH_STENCIL: return "CL_DEPTH_STENCIL";
119         case CL_sRGB: return "CL_sRGB";
120         case CL_sRGBA: return "CL_sRGBA";
121         case CL_sRGBx: return "CL_sRGBx";
122         case CL_sBGRA: return "CL_sBGRA";
123         case CL_ABGR: return "CL_ABGR";
124         default: return NULL;
125     }
126 }
127 
IsChannelOrderSupported(cl_channel_order order)128 int IsChannelOrderSupported( cl_channel_order order )
129 {
130     switch( order )
131     {
132         case CL_R:
133         case CL_A:
134         case CL_Rx:
135         case CL_RG:
136         case CL_RA:
137         case CL_RGx:
138         case CL_RGB:
139         case CL_RGBx:
140         case CL_RGBA:
141         case CL_ARGB:
142         case CL_BGRA:
143         case CL_INTENSITY:
144         case CL_LUMINANCE:
145         case CL_ABGR:
146         case CL_sRGB:
147         case CL_sRGBx:
148         case CL_sBGRA:
149         case CL_sRGBA:
150         case CL_DEPTH:
151             return 1;
152 #if defined CL_1RGB_APPLE
153         case CL_1RGB_APPLE:
154             return 1;
155 #endif
156 #if defined CL_BGR1_APPLE
157         case CL_BGR1_APPLE:
158             return 1;
159 #endif
160         default:
161             return 0;
162     }
163 }
164 
GetChannelTypeName(cl_channel_type type)165 const char *GetChannelTypeName( cl_channel_type type )
166 {
167     switch( type )
168     {
169         case CL_SNORM_INT8:         return "CL_SNORM_INT8";
170         case CL_SNORM_INT16:        return "CL_SNORM_INT16";
171         case CL_UNORM_INT8:         return "CL_UNORM_INT8";
172         case CL_UNORM_INT16:        return "CL_UNORM_INT16";
173         case CL_UNORM_SHORT_565:    return "CL_UNORM_SHORT_565";
174         case CL_UNORM_SHORT_555:    return "CL_UNORM_SHORT_555";
175         case CL_UNORM_INT_101010:   return "CL_UNORM_INT_101010";
176         case CL_SIGNED_INT8:        return "CL_SIGNED_INT8";
177         case CL_SIGNED_INT16:       return "CL_SIGNED_INT16";
178         case CL_SIGNED_INT32:       return "CL_SIGNED_INT32";
179         case CL_UNSIGNED_INT8:      return "CL_UNSIGNED_INT8";
180         case CL_UNSIGNED_INT16:     return "CL_UNSIGNED_INT16";
181         case CL_UNSIGNED_INT32:     return "CL_UNSIGNED_INT32";
182         case CL_HALF_FLOAT:         return "CL_HALF_FLOAT";
183         case CL_FLOAT:              return "CL_FLOAT";
184 #ifdef CL_SFIXED14_APPLE
185         case CL_SFIXED14_APPLE:     return "CL_SFIXED14_APPLE";
186 #endif
187         case CL_UNORM_INT24:        return "CL_UNORM_INT24";
188         default:                    return NULL;
189     }
190 }
191 
IsChannelTypeSupported(cl_channel_type type)192 int IsChannelTypeSupported( cl_channel_type type )
193 {
194     switch( type )
195     {
196         case CL_SNORM_INT8:
197         case CL_SNORM_INT16:
198         case CL_UNORM_INT8:
199         case CL_UNORM_INT16:
200         case CL_UNORM_INT24:
201         case CL_UNORM_SHORT_565:
202         case CL_UNORM_SHORT_555:
203         case CL_UNORM_INT_101010:
204         case CL_SIGNED_INT8:
205         case CL_SIGNED_INT16:
206         case CL_SIGNED_INT32:
207         case CL_UNSIGNED_INT8:
208         case CL_UNSIGNED_INT16:
209         case CL_UNSIGNED_INT32:
210         case CL_HALF_FLOAT:
211         case CL_FLOAT:
212             return 1;
213 #ifdef CL_SFIXED14_APPLE
214         case CL_SFIXED14_APPLE:
215             return 1;
216 #endif
217         default:
218             return 0;
219     }
220 }
221 
GetAddressModeName(cl_addressing_mode mode)222 const char *GetAddressModeName( cl_addressing_mode mode )
223 {
224     switch( mode )
225     {
226         case CL_ADDRESS_NONE:                return "CL_ADDRESS_NONE";
227         case CL_ADDRESS_CLAMP_TO_EDGE:        return "CL_ADDRESS_CLAMP_TO_EDGE";
228         case CL_ADDRESS_CLAMP:                return "CL_ADDRESS_CLAMP";
229         case CL_ADDRESS_REPEAT:                return "CL_ADDRESS_REPEAT";
230         case CL_ADDRESS_MIRRORED_REPEAT:    return "CL_ADDRESS_MIRRORED_REPEAT";
231         default:                            return NULL;
232     }
233 }
234 
GetDeviceTypeName(cl_device_type type)235 const char *GetDeviceTypeName( cl_device_type type )
236 {
237     switch( type )
238     {
239         case CL_DEVICE_TYPE_GPU:    return "CL_DEVICE_TYPE_GPU";
240         case CL_DEVICE_TYPE_CPU:    return "CL_DEVICE_TYPE_CPU";
241         case CL_DEVICE_TYPE_ACCELERATOR:    return "CL_DEVICE_TYPE_ACCELERATOR";
242         case CL_DEVICE_TYPE_ALL:    return "CL_DEVICE_TYPE_ALL";
243         default:                    return NULL;
244     }
245 }
246 
GetDataVectorString(void * dataBuffer,size_t typeSize,size_t vecSize,char * buffer)247 const char *GetDataVectorString( void *dataBuffer, size_t typeSize, size_t vecSize, char *buffer )
248 {
249     static char scratch[ 1024 ];
250     size_t i, j;
251 
252     if( buffer == NULL )
253         buffer = scratch;
254 
255     unsigned char *p = (unsigned char *)dataBuffer;
256     char *bPtr;
257 
258     buffer[ 0 ] = 0;
259     bPtr = buffer;
260     for( i = 0; i < vecSize; i++ )
261     {
262         if( i > 0 )
263         {
264             bPtr[ 0 ] = ' ';
265             bPtr++;
266         }
267         for( j = 0; j < typeSize; j++ )
268         {
269             sprintf( bPtr, "%02x", (unsigned int)p[ typeSize - j - 1 ] );
270             bPtr += 2;
271         }
272         p += typeSize;
273     }
274     bPtr[ 0 ] = 0;
275 
276     return buffer;
277 }
278 
279 #ifndef MAX
280 #define MAX( _a, _b )       ((_a) > (_b) ? (_a) : (_b))
281 #endif
282 
283 #if defined( _MSC_VER )
284 #define scalbnf(_a, _i )    ldexpf( _a, _i )
285 #define scalbn(_a, _i )     ldexp( _a, _i )
286 #define scalbnl(_a, _i )    ldexpl( _a, _i )
287 #endif
288 
289 static float Ulp_Error_Half_Float( float test, double reference );
290 static inline float  half2float( cl_ushort half );
291 
292 // taken from math tests
293 #define HALF_MIN_EXP    -13
294 #define HALF_MANT_DIG    11
Ulp_Error_Half_Float(float test,double reference)295 static float Ulp_Error_Half_Float( float test, double reference )
296 {
297     union{ double d; uint64_t u; }u;     u.d = reference;
298 
299     // Note: This function presumes that someone has already tested whether the result is correctly,
300     // rounded before calling this function.  That test:
301     //
302     //    if( (float) reference == test )
303     //        return 0.0f;
304     //
305     // would ensure that cases like fabs(reference) > FLT_MAX are weeded out before we get here.
306     // Otherwise, we'll return inf ulp error here, for what are otherwise correctly rounded
307     // results.
308 
309     double testVal = test;
310     if( u.u & 0x000fffffffffffffULL )
311     { // Non-power of two and NaN
312         if( isnan( reference ) && isnan( test ) )
313             return 0.0f;    // if we are expecting a NaN, any NaN is fine
314 
315         // The unbiased exponent of the ulp unit place
316         int ulp_exp = HALF_MANT_DIG - 1 - MAX( ilogb( reference), HALF_MIN_EXP-1 );
317 
318         // Scale the exponent of the error
319         return (float) scalbn( testVal - reference, ulp_exp );
320     }
321 
322     if( isinf( reference ) )
323     {
324         if( (double) test == reference )
325             return 0.0f;
326 
327         return (float) (testVal - reference );
328     }
329 
330     // reference is a normal power of two or a zero
331     int ulp_exp =  HALF_MANT_DIG - 1 - MAX( ilogb( reference) - 1, HALF_MIN_EXP-1 );
332 
333     // Scale the exponent of the error
334     return (float) scalbn( testVal - reference, ulp_exp );
335 }
336 
337 // Taken from vLoadHalf test
half2float(cl_ushort us)338 static inline float half2float( cl_ushort us )
339 {
340     uint32_t u = us;
341     uint32_t sign = (u << 16) & 0x80000000;
342     int32_t exponent = (u & 0x7c00) >> 10;
343     uint32_t mantissa = (u & 0x03ff) << 13;
344     union{ unsigned int u; float f;}uu;
345 
346     if( exponent == 0 )
347     {
348         if( mantissa == 0 )
349             return sign ? -0.0f : 0.0f;
350 
351         int shift = __builtin_clz( mantissa ) - 8;
352         exponent -= shift-1;
353         mantissa <<= shift;
354         mantissa &= 0x007fffff;
355     }
356     else
357         if( exponent == 31)
358         {
359             uu.u = mantissa | sign;
360             if( mantissa )
361                 uu.u |= 0x7fc00000;
362             else
363                 uu.u |= 0x7f800000;
364 
365             return uu.f;
366         }
367 
368     exponent += 127 - 15;
369     exponent <<= 23;
370 
371     exponent |= mantissa;
372     uu.u = exponent | sign;
373 
374     return uu.f;
375 }
376 
Ulp_Error_Half(cl_ushort test,float reference)377 float Ulp_Error_Half( cl_ushort test, float reference )
378 {
379     return Ulp_Error_Half_Float( half2float(test), reference );
380 }
381 
382 
Ulp_Error(float test,double reference)383 float Ulp_Error( float test, double reference )
384 {
385     union{ double d; uint64_t u; }u;     u.d = reference;
386     double testVal = test;
387 
388     // Note: This function presumes that someone has already tested whether the result is correctly,
389     // rounded before calling this function.  That test:
390     //
391     //    if( (float) reference == test )
392     //        return 0.0f;
393     //
394     // would ensure that cases like fabs(reference) > FLT_MAX are weeded out before we get here.
395     // Otherwise, we'll return inf ulp error here, for what are otherwise correctly rounded
396     // results.
397 
398 
399     if( isinf( reference ) )
400     {
401         if( testVal == reference )
402             return 0.0f;
403 
404         return (float) (testVal - reference );
405     }
406 
407     if( isinf( testVal) )
408     { // infinite test value, but finite (but possibly overflowing in float) reference.
409       //
410       // The function probably overflowed prematurely here. Formally, the spec says this is
411       // an infinite ulp error and should not be tolerated. Unfortunately, this would mean
412       // that the internal precision of some half_pow implementations would have to be 29+ bits
413       // at half_powr( 0x1.fffffep+31, 4) to correctly determine that 4*log2( 0x1.fffffep+31 )
414       // is not exactly 128.0. You might represent this for example as 4*(32 - ~2**-24), which
415       // after rounding to single is 4*32 = 128, which will ultimately result in premature
416       // overflow, even though a good faith representation would be correct to within 2**-29
417       // interally.
418 
419         // In the interest of not requiring the implementation go to extraordinary lengths to
420         // deliver a half precision function, we allow premature overflow within the limit
421         // of the allowed ulp error. Towards, that end, we "pretend" the test value is actually
422         // 2**128, the next value that would appear in the number line if float had sufficient range.
423         testVal = copysign( MAKE_HEX_DOUBLE(0x1.0p128, 0x1LL, 128), testVal );
424 
425         // Note that the same hack may not work in long double, which is not guaranteed to have
426         // more range than double.  It is not clear that premature overflow should be tolerated for
427         // double.
428     }
429 
430     if( u.u & 0x000fffffffffffffULL )
431     { // Non-power of two and NaN
432         if( isnan( reference ) && isnan( test ) )
433             return 0.0f;    // if we are expecting a NaN, any NaN is fine
434 
435         // The unbiased exponent of the ulp unit place
436         int ulp_exp = FLT_MANT_DIG - 1 - MAX( ilogb( reference), FLT_MIN_EXP-1 );
437 
438         // Scale the exponent of the error
439         return (float) scalbn( testVal - reference, ulp_exp );
440     }
441 
442     // reference is a normal power of two or a zero
443     // The unbiased exponent of the ulp unit place
444     int ulp_exp =  FLT_MANT_DIG - 1 - MAX( ilogb( reference) - 1, FLT_MIN_EXP-1 );
445 
446     // Scale the exponent of the error
447     return (float) scalbn( testVal - reference, ulp_exp );
448 }
449 
Ulp_Error_Double(double test,long double reference)450 float Ulp_Error_Double( double test, long double reference )
451 {
452   // Deal with long double = double
453   // On most systems long double is a higher precision type than double. They provide either
454   // a 80-bit or greater floating point type, or they provide a head-tail double double format.
455   // That is sufficient to represent the accuracy of a floating point result to many more bits
456   // than double and we can calculate sub-ulp errors. This is the standard system for which this
457   // test suite is designed.
458   //
459   // On some systems double and long double are the same thing. Then we run into a problem,
460   // because our representation of the infinitely precise result (passed in as reference above)
461   // can be off by as much as a half double precision ulp itself.  In this case, we inflate the
462   // reported error by half an ulp to take this into account.  A more correct and permanent fix
463   // would be to undertake refactoring the reference code to return results in this format:
464   //
465   //    typedef struct DoubleReference
466   //    { // true value = correctlyRoundedResult + ulps * ulp(correctlyRoundedResult)        (infinitely precise)
467   //        double  correctlyRoundedResult;     // as best we can
468   //        double  ulps;                       // plus a fractional amount to account for the difference
469   //    }DoubleReference;                       //     between infinitely precise result and correctlyRoundedResult, in units of ulps.
470   //
471   // This would provide a useful higher-than-double precision format for everyone that we can use,
472   // and would solve a few problems with representing absolute errors below DBL_MIN and over DBL_MAX for systems
473   // that use a head to tail double double for long double.
474 
475     // Note: This function presumes that someone has already tested whether the result is correctly,
476     // rounded before calling this function.  That test:
477     //
478     //    if( (float) reference == test )
479     //        return 0.0f;
480     //
481     // would ensure that cases like fabs(reference) > FLT_MAX are weeded out before we get here.
482     // Otherwise, we'll return inf ulp error here, for what are otherwise correctly rounded
483     // results.
484 
485 
486     int x;
487     long double testVal = test;
488     if( 0.5L != frexpl( reference, &x) )
489     { // Non-power of two and NaN
490         if( isinf( reference ) )
491         {
492             if( testVal == reference )
493                 return 0.0f;
494 
495             return (float) ( testVal - reference );
496         }
497 
498         if( isnan( reference ) && isnan( test ) )
499             return 0.0f;    // if we are expecting a NaN, any NaN is fine
500 
501         // The unbiased exponent of the ulp unit place
502         int ulp_exp = DBL_MANT_DIG - 1 - MAX( ilogbl( reference), DBL_MIN_EXP-1 );
503 
504         // Scale the exponent of the error
505         float result = (float) scalbnl( testVal - reference, ulp_exp );
506 
507         // account for rounding error in reference result on systems that do not have a higher precision floating point type (see above)
508         if( sizeof(long double) == sizeof( double ) )
509             result += copysignf( 0.5f, result);
510 
511         return result;
512 
513     }
514 
515     // reference is a normal power of two or a zero
516     // The unbiased exponent of the ulp unit place
517     int ulp_exp =  DBL_MANT_DIG - 1 - MAX( ilogbl( reference) - 1, DBL_MIN_EXP-1 );
518 
519     // Scale the exponent of the error
520     float result = (float) scalbnl( testVal - reference, ulp_exp );
521 
522     // account for rounding error in reference result on systems that do not have a higher precision floating point type (see above)
523     if( sizeof(long double) == sizeof( double ) )
524         result += copysignf( 0.5f, result);
525 
526     return result;
527 }
528 
OutputBuildLogs(cl_program program,cl_uint num_devices,cl_device_id * device_list)529 cl_int OutputBuildLogs(cl_program program, cl_uint num_devices, cl_device_id *device_list)
530 {
531   int error;
532   size_t size_ret;
533 
534   // Does the program object exist?
535   if (program != NULL) {
536 
537     // Was the number of devices given
538     if (num_devices == 0) {
539 
540       // If zero devices were specified then allocate and query the device list from the context
541       cl_context context;
542       error = clGetProgramInfo(program, CL_PROGRAM_CONTEXT, sizeof(context), &context, NULL);
543       test_error( error, "Unable to query program's context" );
544       error = clGetContextInfo(context, CL_CONTEXT_DEVICES, 0, NULL, &size_ret);
545       test_error( error, "Unable to query context's device size" );
546       num_devices = size_ret / sizeof(cl_device_id);
547       device_list = (cl_device_id *) malloc(size_ret);
548       if (device_list == NULL) {
549           print_error( error, "malloc failed" );
550           return CL_OUT_OF_HOST_MEMORY;
551       }
552       error = clGetContextInfo(context, CL_CONTEXT_DEVICES, size_ret, device_list, NULL);
553       test_error( error, "Unable to query context's devices" );
554 
555     }
556 
557     // For each device in the device_list
558     unsigned int i;
559     for (i = 0; i < num_devices; i++) {
560 
561       // Get the build status
562       cl_build_status build_status;
563       error = clGetProgramBuildInfo(program,
564                                     device_list[i],
565                                     CL_PROGRAM_BUILD_STATUS,
566                                     sizeof(build_status),
567                                     &build_status,
568                                     &size_ret);
569       test_error( error, "Unable to query build status" );
570 
571       // If the build failed then log the status, and allocate the build log, log it and free it
572       if (build_status != CL_BUILD_SUCCESS) {
573 
574         log_error("ERROR: CL_PROGRAM_BUILD_STATUS=%d\n", (int) build_status);
575         error = clGetProgramBuildInfo(program, device_list[i], CL_PROGRAM_BUILD_LOG, 0, NULL, &size_ret);
576         test_error( error, "Unable to query build log size" );
577         char *build_log = (char *) malloc(size_ret);
578         error = clGetProgramBuildInfo(program, device_list[i], CL_PROGRAM_BUILD_LOG, size_ret, build_log, &size_ret);
579         test_error( error, "Unable to query build log" );
580         log_error("ERROR: CL_PROGRAM_BUILD_LOG:\n%s\n", build_log);
581         free(build_log);
582 
583       }
584 
585     }
586 
587     // Was the number of devices given
588     if (num_devices == 0) {
589 
590       // If zero devices were specified then free the device list
591       free(device_list);
592 
593     }
594 
595   }
596 
597   return CL_SUCCESS;
598 }
599 
600 const char * subtests_requiring_opencl_1_2[] = {
601             "device_partition_equally",
602             "device_partition_by_counts",
603             "device_partition_by_affinity_domain_numa",
604             "device_partition_by_affinity_domain_l4_cache",
605             "device_partition_by_affinity_domain_l3_cache",
606             "device_partition_by_affinity_domain_l2_cache",
607             "device_partition_by_affinity_domain_l1_cache",
608             "device_partition_by_affinity_domain_next_partitionable",
609             "device_partition_all",
610     "buffer_fill_int",
611     "buffer_fill_uint",
612     "buffer_fill_short",
613     "buffer_fill_ushort",
614     "buffer_fill_char",
615     "buffer_fill_uchar",
616     "buffer_fill_long",
617     "buffer_fill_ulong",
618     "buffer_fill_float",
619     "buffer_fill_struct",
620   "test_mem_host_write_only_buffer",
621   "test_mem_host_write_only_subbuffer",
622   "test_mem_host_no_access_buffer",
623   "test_mem_host_no_access_subbuffer",
624   "test_mem_host_read_only_image",
625   "test_mem_host_write_only_image",
626   "test_mem_host_no_access_image",
627   // CL_MEM_HOST_{READ|WRITE}_ONLY api/
628     "get_buffer_info",
629     "get_image1d_info",
630     "get_image1d_array_info",
631     "get_image2d_array_info",
632   // gl/
633   "images_read_1D",
634   "images_write_1D",
635   "images_1D_getinfo",
636   "images_read_1Darray",
637   "images_write_1Darray",
638   "images_1Darray_getinfo",
639   "images_read_2Darray",
640   "images_write_2Darray",
641   "images_2Darray_getinfo",
642     "buffer_migrate",
643     "image_migrate",
644    // compiler/
645     "load_program_source",
646     "load_multistring_source",
647     "load_two_kernel_source",
648     "load_null_terminated_source",
649     "load_null_terminated_multi_line_source",
650     "load_null_terminated_partial_multi_line_source",
651     "load_discreet_length_source",
652     "get_program_source",
653     "get_program_build_info",
654     "get_program_info",
655     "large_compile",
656     "async_build",
657     "options_build_optimizations",
658     "options_build_macro",
659     "options_build_macro_existence",
660     "options_include_directory",
661     "options_denorm_cache",
662     "preprocessor_define_udef",
663     "preprocessor_include",
664     "preprocessor_line_error",
665     "preprocessor_pragma",
666     "compiler_defines_for_extensions",
667     "image_macro",
668     "simple_compile_only",
669     "simple_static_compile_only",
670     "simple_extern_compile_only",
671     "simple_compile_with_callback",
672     "simple_embedded_header_compile",
673     "simple_link_only",
674     "two_file_regular_variable_access",
675     "two_file_regular_struct_access",
676     "two_file_regular_function_access",
677     "simple_link_with_callback",
678     "simple_embedded_header_link",
679     "execute_after_simple_compile_and_link",
680     "execute_after_simple_compile_and_link_no_device_info",
681     "execute_after_simple_compile_and_link_with_defines",
682     "execute_after_simple_compile_and_link_with_callbacks",
683     "execute_after_simple_library_with_link",
684     "execute_after_two_file_link",
685     "execute_after_two_file_link",
686     "execute_after_embedded_header_link",
687     "execute_after_included_header_link",
688     "execute_after_serialize_reload_object",
689     "execute_after_serialize_reload_library",
690     "simple_library_only",
691     "simple_library_with_callback",
692     "simple_library_with_link",
693     "two_file_link",
694     "multi_file_libraries",
695     "multiple_files",
696     "multiple_libraries",
697     "multiple_files_multiple_libraries",
698     "multiple_embedded_headers",
699     "program_binary_type",
700     "compile_and_link_status_options_log",
701     // CL_PROGRAM_NUM_KERNELS, in api/
702     "get_kernel_arg_info",
703     "create_kernels_in_program",
704     // clEnqueue..WithWaitList, in events/
705     "event_enqueue_marker_with_event_list",
706     "event_enqueue_barrier_with_event_list",
707     "popcount"
708 };
709 
710 const char * subtests_to_skip_with_offline_compiler[] = {
711             "get_kernel_arg_info",
712             "binary_create",
713             "load_program_source",
714             "load_multistring_source",
715             "load_two_kernel_source",
716             "load_null_terminated_source",
717             "load_null_terminated_multi_line_source",
718             "load_null_terminated_partial_multi_line_source",
719             "load_discreet_length_source",
720             "get_program_source",
721             "get_program_build_info",
722             "options_build_optimizations",
723             "options_build_macro",
724             "options_build_macro_existence",
725             "options_include_directory",
726             "options_denorm_cache",
727             "preprocessor_define_udef",
728             "preprocessor_include",
729             "preprocessor_line_error",
730             "preprocessor_pragma",
731             "compiler_defines_for_extensions",
732             "image_macro",
733             "simple_extern_compile_only",
734             "simple_embedded_header_compile",
735             "two_file_regular_variable_access",
736             "two_file_regular_struct_access",
737             "two_file_regular_function_access",
738             "simple_embedded_header_link",
739             "execute_after_simple_compile_and_link_with_defines",
740             "execute_after_simple_compile_and_link_with_callbacks",
741             "execute_after_embedded_header_link",
742             "execute_after_included_header_link",
743             "multi_file_libraries",
744             "multiple_files",
745             "multiple_libraries",
746             "multiple_files_multiple_libraries",
747             "multiple_embedded_headers",
748             "program_binary_type",
749             "compile_and_link_status_options_log",
750             "kernel_preprocessor_macros",
751 };
752 
check_functions_for_offline_compiler(const char * subtestname,cl_device_id device)753 int check_functions_for_offline_compiler(const char *subtestname, cl_device_id device)
754 {
755     if (gCompilationMode != kOnline)
756     {
757         int nNotRequiredWithOfflineCompiler = sizeof(subtests_to_skip_with_offline_compiler)/sizeof(char *);
758         size_t i;
759         for(i=0; i < nNotRequiredWithOfflineCompiler; ++i) {
760             if(!strcmp(subtestname, subtests_to_skip_with_offline_compiler[i])) {
761                 return 1;
762             }
763         }
764     }
765     return 0;
766 }
767