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