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