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