| // |
| // Copyright (c) 2017 The Khronos Group Inc. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| // |
| #include "procs.h" |
| |
| #define TEST_VALUE_POSITIVE( string_name, name, value ) \ |
| { \ |
| if (name < value) { \ |
| log_error("FAILED: " string_name ": " #name " < " #value "\n"); \ |
| errors++;\ |
| } else { \ |
| log_info("\t" string_name ": " #name " >= " #value "\n"); \ |
| } \ |
| } |
| |
| #define TEST_VALUE_NEGATIVE( string_name, name, value ) \ |
| { \ |
| if (name > value) { \ |
| log_error("FAILED: " string_name ": " #name " > " #value "\n"); \ |
| errors++;\ |
| } else { \ |
| log_info("\t" string_name ": " #name " <= " #value "\n"); \ |
| } \ |
| } |
| |
| #define TEST_VALUE_EQUAL_LITERAL( string_name, name, value ) \ |
| { \ |
| if (name != value) { \ |
| log_error("FAILED: " string_name ": " #name " != " #value "\n"); \ |
| errors++;\ |
| } else { \ |
| log_info("\t" string_name ": " #name " = " #value "\n"); \ |
| } \ |
| } |
| |
| #define TEST_VALUE_EQUAL( string_name, name, value ) \ |
| { \ |
| if (name != value) { \ |
| log_error("FAILED: " string_name ": " #name " != %a (%17.21g)\n", value, value); \ |
| errors++;\ |
| } else { \ |
| log_info("\t" string_name ": " #name " = %a (%17.21g)\n", value, value); \ |
| } \ |
| } |
| |
| int test_host_numeric_constants(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements) |
| { |
| int errors = 0; |
| TEST_VALUE_EQUAL_LITERAL( "CL_CHAR_BIT", CL_CHAR_BIT, 8) |
| TEST_VALUE_EQUAL_LITERAL( "CL_SCHAR_MAX", CL_SCHAR_MAX, 127) |
| TEST_VALUE_EQUAL_LITERAL( "CL_SCHAR_MIN", CL_SCHAR_MIN, (-127-1)) |
| TEST_VALUE_EQUAL_LITERAL( "CL_CHAR_MAX", CL_CHAR_MAX, CL_SCHAR_MAX) |
| TEST_VALUE_EQUAL_LITERAL( "CL_CHAR_MIN", CL_CHAR_MIN, CL_SCHAR_MIN) |
| TEST_VALUE_EQUAL_LITERAL( "CL_UCHAR_MAX", CL_UCHAR_MAX, 255) |
| TEST_VALUE_EQUAL_LITERAL( "CL_SHRT_MAX", CL_SHRT_MAX, 32767) |
| TEST_VALUE_EQUAL_LITERAL( "CL_SHRT_MIN", CL_SHRT_MIN, (-32767-1)) |
| TEST_VALUE_EQUAL_LITERAL( "CL_USHRT_MAX", CL_USHRT_MAX, 65535) |
| TEST_VALUE_EQUAL_LITERAL( "CL_INT_MAX", CL_INT_MAX, 2147483647) |
| TEST_VALUE_EQUAL_LITERAL( "CL_INT_MIN", CL_INT_MIN, (-2147483647-1)) |
| TEST_VALUE_EQUAL_LITERAL( "CL_UINT_MAX", CL_UINT_MAX, 0xffffffffU) |
| TEST_VALUE_EQUAL_LITERAL( "CL_LONG_MAX", CL_LONG_MAX, ((cl_long) 0x7FFFFFFFFFFFFFFFLL)) |
| TEST_VALUE_EQUAL_LITERAL( "CL_LONG_MIN", CL_LONG_MIN, ((cl_long) -0x7FFFFFFFFFFFFFFFLL - 1LL)) |
| TEST_VALUE_EQUAL_LITERAL( "CL_ULONG_MAX", CL_ULONG_MAX, ((cl_ulong) 0xFFFFFFFFFFFFFFFFULL)) |
| |
| TEST_VALUE_EQUAL_LITERAL( "CL_FLT_DIG", CL_FLT_DIG, 6) |
| TEST_VALUE_EQUAL_LITERAL( "CL_FLT_MANT_DIG", CL_FLT_MANT_DIG, 24) |
| TEST_VALUE_EQUAL_LITERAL( "CL_FLT_MAX_10_EXP", CL_FLT_MAX_10_EXP, +38) |
| TEST_VALUE_EQUAL_LITERAL( "CL_FLT_MAX_EXP", CL_FLT_MAX_EXP, +128) |
| TEST_VALUE_EQUAL_LITERAL( "CL_FLT_MIN_10_EXP", CL_FLT_MIN_10_EXP, -37) |
| TEST_VALUE_EQUAL_LITERAL( "CL_FLT_MIN_EXP", CL_FLT_MIN_EXP, -125) |
| TEST_VALUE_EQUAL_LITERAL( "CL_FLT_RADIX", CL_FLT_RADIX, 2) |
| TEST_VALUE_EQUAL_LITERAL( "CL_FLT_MAX", CL_FLT_MAX, MAKE_HEX_FLOAT( 0x1.fffffep127f, 0x1fffffeL, 103)) |
| TEST_VALUE_EQUAL_LITERAL( "CL_FLT_MIN", CL_FLT_MIN, MAKE_HEX_FLOAT(0x1.0p-126f, 0x1L, -126)) |
| TEST_VALUE_EQUAL_LITERAL( "CL_FLT_EPSILON", CL_FLT_EPSILON, MAKE_HEX_FLOAT(0x1.0p-23f, 0x1L, -23)) |
| |
| TEST_VALUE_EQUAL_LITERAL( "CL_DBL_DIG", CL_DBL_DIG, 15) |
| TEST_VALUE_EQUAL_LITERAL( "CL_DBL_MANT_DIG", CL_DBL_MANT_DIG, 53) |
| TEST_VALUE_EQUAL_LITERAL( "CL_DBL_MAX_10_EXP", CL_DBL_MAX_10_EXP, +308) |
| TEST_VALUE_EQUAL_LITERAL( "CL_DBL_MAX_EXP", CL_DBL_MAX_EXP, +1024) |
| TEST_VALUE_EQUAL_LITERAL( "CL_DBL_MIN_10_EXP", CL_DBL_MIN_10_EXP, -307) |
| TEST_VALUE_EQUAL_LITERAL( "CL_DBL_MIN_EXP", CL_DBL_MIN_EXP, -1021) |
| TEST_VALUE_EQUAL_LITERAL( "CL_DBL_RADIX", CL_DBL_RADIX, 2) |
| TEST_VALUE_EQUAL( "CL_DBL_MAX", CL_DBL_MAX, MAKE_HEX_DOUBLE(0x1.fffffffffffffp1023, 0x1fffffffffffffLL, 971)) |
| TEST_VALUE_EQUAL( "CL_DBL_MIN", CL_DBL_MIN, MAKE_HEX_DOUBLE(0x1.0p-1022, 0x1LL, -1022)) |
| TEST_VALUE_EQUAL( "CL_DBL_EPSILON", CL_DBL_EPSILON, MAKE_HEX_DOUBLE(0x1.0p-52, 0x1LL, -52)) |
| |
| TEST_VALUE_EQUAL( "CL_M_E", CL_M_E, MAKE_HEX_DOUBLE(0x1.5bf0a8b145769p+1, 0x15bf0a8b145769LL, -51) ); |
| TEST_VALUE_EQUAL( "CL_M_LOG2E", CL_M_LOG2E, MAKE_HEX_DOUBLE(0x1.71547652b82fep+0, 0x171547652b82feLL, -52) ); |
| TEST_VALUE_EQUAL( "CL_M_LOG10E", CL_M_LOG10E, MAKE_HEX_DOUBLE(0x1.bcb7b1526e50ep-2, 0x1bcb7b1526e50eLL, -54) ); |
| TEST_VALUE_EQUAL( "CL_M_LN2", CL_M_LN2, MAKE_HEX_DOUBLE(0x1.62e42fefa39efp-1, 0x162e42fefa39efLL, -53) ); |
| TEST_VALUE_EQUAL( "CL_M_LN10", CL_M_LN10, MAKE_HEX_DOUBLE(0x1.26bb1bbb55516p+1, 0x126bb1bbb55516LL, -51) ); |
| TEST_VALUE_EQUAL( "CL_M_PI", CL_M_PI, MAKE_HEX_DOUBLE(0x1.921fb54442d18p+1, 0x1921fb54442d18LL, -51) ); |
| TEST_VALUE_EQUAL( "CL_M_PI_2", CL_M_PI_2, MAKE_HEX_DOUBLE(0x1.921fb54442d18p+0, 0x1921fb54442d18LL, -52) ); |
| TEST_VALUE_EQUAL( "CL_M_PI_4", CL_M_PI_4, MAKE_HEX_DOUBLE(0x1.921fb54442d18p-1, 0x1921fb54442d18LL, -53) ); |
| TEST_VALUE_EQUAL( "CL_M_1_PI", CL_M_1_PI, MAKE_HEX_DOUBLE(0x1.45f306dc9c883p-2, 0x145f306dc9c883LL, -54) ); |
| TEST_VALUE_EQUAL( "CL_M_2_PI", CL_M_2_PI, MAKE_HEX_DOUBLE(0x1.45f306dc9c883p-1, 0x145f306dc9c883LL, -53) ); |
| TEST_VALUE_EQUAL( "CL_M_2_SQRTPI", CL_M_2_SQRTPI, MAKE_HEX_DOUBLE(0x1.20dd750429b6dp+0, 0x120dd750429b6dLL, -52) ); |
| TEST_VALUE_EQUAL( "CL_M_SQRT2", CL_M_SQRT2, MAKE_HEX_DOUBLE(0x1.6a09e667f3bcdp+0, 0x16a09e667f3bcdLL, -52) ); |
| TEST_VALUE_EQUAL( "CL_M_SQRT1_2", CL_M_SQRT1_2, MAKE_HEX_DOUBLE(0x1.6a09e667f3bcdp-1, 0x16a09e667f3bcdLL, -53) ); |
| |
| TEST_VALUE_EQUAL( "CL_M_E_F", CL_M_E_F, MAKE_HEX_FLOAT(0x1.5bf0a8p+1f, 0x15bf0a8L, -23)); |
| TEST_VALUE_EQUAL( "CL_M_LOG2E_F", CL_M_LOG2E_F, MAKE_HEX_FLOAT(0x1.715476p+0f, 0x1715476L, -24)); |
| TEST_VALUE_EQUAL( "CL_M_LOG10E_F", CL_M_LOG10E_F, MAKE_HEX_FLOAT(0x1.bcb7b2p-2f, 0x1bcb7b2L, -26)); |
| TEST_VALUE_EQUAL( "CL_M_LN2_F", CL_M_LN2_F, MAKE_HEX_FLOAT(0x1.62e43p-1f, 0x162e43L, -21) ); |
| TEST_VALUE_EQUAL( "CL_M_LN10_F", CL_M_LN10_F, MAKE_HEX_FLOAT(0x1.26bb1cp+1f, 0x126bb1cL, -23)); |
| TEST_VALUE_EQUAL( "CL_M_PI_F", CL_M_PI_F, MAKE_HEX_FLOAT(0x1.921fb6p+1f, 0x1921fb6L, -23)); |
| TEST_VALUE_EQUAL( "CL_M_PI_2_F", CL_M_PI_2_F, MAKE_HEX_FLOAT(0x1.921fb6p+0f, 0x1921fb6L, -24)); |
| TEST_VALUE_EQUAL( "CL_M_PI_4_F", CL_M_PI_4_F, MAKE_HEX_FLOAT(0x1.921fb6p-1f, 0x1921fb6L, -25)); |
| TEST_VALUE_EQUAL( "CL_M_1_PI_F", CL_M_1_PI_F, MAKE_HEX_FLOAT(0x1.45f306p-2f, 0x145f306L, -26)); |
| TEST_VALUE_EQUAL( "CL_M_2_PI_F", CL_M_2_PI_F, MAKE_HEX_FLOAT(0x1.45f306p-1f, 0x145f306L, -25)); |
| TEST_VALUE_EQUAL( "CL_M_2_SQRTPI_F", CL_M_2_SQRTPI_F,MAKE_HEX_FLOAT(0x1.20dd76p+0f, 0x120dd76L, -24)); |
| TEST_VALUE_EQUAL( "CL_M_SQRT2_F", CL_M_SQRT2_F, MAKE_HEX_FLOAT(0x1.6a09e6p+0f, 0x16a09e6L, -24)); |
| TEST_VALUE_EQUAL( "CL_M_SQRT1_2_F", CL_M_SQRT1_2_F, MAKE_HEX_FLOAT(0x1.6a09e6p-1f, 0x16a09e6L, -25)); |
| |
| return errors; |
| } |
| |
| |
| const char *kernel_int_float[] = { |
| "__kernel void test( __global float *float_out, __global int *int_out, __global uint *uint_out) \n" |
| "{\n" |
| " int_out[0] = CHAR_BIT;\n" |
| " int_out[1] = SCHAR_MAX;\n" |
| " int_out[2] = SCHAR_MIN;\n" |
| " int_out[3] = CHAR_MAX;\n" |
| " int_out[4] = CHAR_MIN;\n" |
| " int_out[5] = UCHAR_MAX;\n" |
| " int_out[6] = SHRT_MAX;\n" |
| " int_out[7] = SHRT_MIN;\n" |
| " int_out[8] = USHRT_MAX;\n" |
| " int_out[9] = INT_MAX;\n" |
| " int_out[10] = INT_MIN;\n" |
| " uint_out[0] = UINT_MAX;\n" |
| |
| " int_out[11] = FLT_DIG;\n" |
| " int_out[12] = FLT_MANT_DIG;\n" |
| " int_out[13] = FLT_MAX_10_EXP;\n" |
| " int_out[14] = FLT_MAX_EXP;\n" |
| " int_out[15] = FLT_MIN_10_EXP;\n" |
| " int_out[16] = FLT_MIN_EXP;\n" |
| " int_out[17] = FLT_RADIX;\n" |
| "#ifdef __IMAGE_SUPPORT__\n" |
| " int_out[18] = __IMAGE_SUPPORT__;\n" |
| "#else\n" |
| " int_out[18] = 0xf00baa;\n" |
| "#endif\n" |
| " float_out[0] = FLT_MAX;\n" |
| " float_out[1] = FLT_MIN;\n" |
| " float_out[2] = FLT_EPSILON;\n" |
| " float_out[3] = M_E_F;\n" |
| " float_out[4] = M_LOG2E_F;\n" |
| " float_out[5] = M_LOG10E_F;\n" |
| " float_out[6] = M_LN2_F;\n" |
| " float_out[7] = M_LN10_F;\n" |
| " float_out[8] = M_PI_F;\n" |
| " float_out[9] = M_PI_2_F;\n" |
| " float_out[10] = M_PI_4_F;\n" |
| " float_out[11] = M_1_PI_F;\n" |
| " float_out[12] = M_2_PI_F;\n" |
| " float_out[13] = M_2_SQRTPI_F;\n" |
| " float_out[14] = M_SQRT2_F;\n" |
| " float_out[15] = M_SQRT1_2_F;\n" |
| "}\n" |
| }; |
| |
| const char *kernel_long[] = { |
| "__kernel void test(__global long *long_out, __global ulong *ulong_out) \n" |
| "{\n" |
| " long_out[0] = LONG_MAX;\n" |
| " long_out[1] = LONG_MIN;\n" |
| " ulong_out[0] = ULONG_MAX;\n" |
| "}\n" |
| }; |
| |
| const char *kernel_double[] = { |
| "#pragma OPENCL EXTENSION cl_khr_fp64 : enable\n" |
| "__kernel void test( __global double *double_out, __global long *long_out ) \n " |
| "{\n" |
| " long_out[0] = DBL_DIG;\n" |
| " long_out[1] = DBL_MANT_DIG;\n" |
| " long_out[2] = DBL_MAX_10_EXP;\n" |
| " long_out[3] = DBL_MAX_EXP;\n" |
| " long_out[4] = DBL_MIN_10_EXP;\n" |
| " long_out[5] = DBL_MIN_EXP;\n" |
| " long_out[6] = DBL_RADIX;\n" |
| " double_out[0] = DBL_MAX;\n" |
| " double_out[1] = DBL_MIN;\n" |
| " double_out[2] = DBL_EPSILON;\n" |
| " double_out[3] = M_E;\n" |
| " double_out[4] = M_LOG2E;\n" |
| " double_out[5] = M_LOG10E;\n" |
| " double_out[6] = M_LN2;\n" |
| " double_out[7] = M_LN10;\n" |
| " double_out[8] = M_PI;\n" |
| " double_out[9] = M_PI_2;\n" |
| " double_out[10] = M_PI_4;\n" |
| " double_out[11] = M_1_PI;\n" |
| " double_out[12] = M_2_PI;\n" |
| " double_out[13] = M_2_SQRTPI;\n" |
| " double_out[14] = M_SQRT2;\n" |
| " double_out[15] = M_SQRT1_2;\n" |
| "}\n" |
| }; |
| |
| |
| int test_kernel_numeric_constants(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements) |
| { |
| int error, errors = 0; |
| // clProgramWrapper program; |
| // clKernelWrapper kernel; |
| // clMemWrapper streams[3]; |
| cl_program program; |
| cl_kernel kernel; |
| cl_mem streams[3]; |
| |
| size_t threads[] = {1,1,1}; |
| cl_float float_out[16]; |
| cl_int int_out[19]; |
| cl_uint uint_out[1]; |
| cl_long long_out[7]; |
| cl_ulong ulong_out[1]; |
| cl_double double_out[16]; |
| |
| /** INTs and FLOATs **/ |
| |
| // Create the kernel |
| if( create_single_kernel_helper( context, &program, &kernel, 1, kernel_int_float, "test" ) != 0 ) |
| { |
| return -1; |
| } |
| |
| /* Create some I/O streams */ |
| streams[0] = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(float_out), |
| NULL, &error); |
| test_error( error, "Creating test array failed" ); |
| streams[1] = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(int_out), |
| NULL, &error); |
| test_error( error, "Creating test array failed" ); |
| streams[2] = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(uint_out), |
| NULL, &error); |
| test_error( error, "Creating test array failed" ); |
| |
| error = clSetKernelArg(kernel, 1, sizeof( streams[1] ), &streams[1]); |
| test_error( error, "Unable to set indexed kernel arguments" ); |
| error = clSetKernelArg(kernel, 0, sizeof( streams[0] ), &streams[0]); |
| test_error( error, "Unable to set indexed kernel arguments" ); |
| error = clSetKernelArg(kernel, 2, sizeof( streams[2] ), &streams[2]); |
| test_error( error, "Unable to set indexed kernel arguments" ); |
| |
| error = clEnqueueNDRangeKernel( queue, kernel, 1, NULL, threads, NULL, 0, NULL, NULL ); |
| test_error( error, "Kernel execution failed" ); |
| |
| error = clEnqueueReadBuffer( queue, streams[0], CL_TRUE, 0, sizeof(float_out), (void*)float_out, 0, NULL, NULL ); |
| test_error( error, "Unable to get result data" ); |
| error = clEnqueueReadBuffer( queue, streams[1], CL_TRUE, 0, sizeof(int_out), (void*)int_out, 0, NULL, NULL ); |
| test_error( error, "Unable to get result data" ); |
| error = clEnqueueReadBuffer( queue, streams[2], CL_TRUE, 0, sizeof(uint_out), (void*)uint_out, 0, NULL, NULL ); |
| test_error( error, "Unable to get result data" ); |
| |
| TEST_VALUE_EQUAL_LITERAL( "CHAR_BIT", int_out[0], 8) |
| TEST_VALUE_EQUAL_LITERAL( "SCHAR_MAX", int_out[1], 127) |
| TEST_VALUE_EQUAL_LITERAL( "SCHAR_MIN", int_out[2], (-127-1)) |
| TEST_VALUE_EQUAL_LITERAL( "CHAR_MAX", int_out[3], CL_SCHAR_MAX) |
| TEST_VALUE_EQUAL_LITERAL( "CHAR_MIN", int_out[4], CL_SCHAR_MIN) |
| TEST_VALUE_EQUAL_LITERAL( "UCHAR_MAX", int_out[5], 255) |
| TEST_VALUE_EQUAL_LITERAL( "SHRT_MAX", int_out[6], 32767) |
| TEST_VALUE_EQUAL_LITERAL( "SHRT_MIN",int_out[7], (-32767-1)) |
| TEST_VALUE_EQUAL_LITERAL( "USHRT_MAX", int_out[8], 65535) |
| TEST_VALUE_EQUAL_LITERAL( "INT_MAX", int_out[9], 2147483647) |
| TEST_VALUE_EQUAL_LITERAL( "INT_MIN", int_out[10], (-2147483647-1)) |
| TEST_VALUE_EQUAL_LITERAL( "UINT_MAX", uint_out[0], 0xffffffffU) |
| |
| TEST_VALUE_EQUAL_LITERAL( "FLT_DIG", int_out[11], 6) |
| TEST_VALUE_EQUAL_LITERAL( "FLT_MANT_DIG", int_out[12], 24) |
| TEST_VALUE_EQUAL_LITERAL( "FLT_MAX_10_EXP", int_out[13], +38) |
| TEST_VALUE_EQUAL_LITERAL( "FLT_MAX_EXP", int_out[14], +128) |
| TEST_VALUE_EQUAL_LITERAL( "FLT_MIN_10_EXP", int_out[15], -37) |
| TEST_VALUE_EQUAL_LITERAL( "FLT_MIN_EXP", int_out[16], -125) |
| TEST_VALUE_EQUAL_LITERAL( "FLT_RADIX", int_out[17], 2) |
| TEST_VALUE_EQUAL( "FLT_MAX", float_out[0], MAKE_HEX_FLOAT(0x1.fffffep127f, 0x1fffffeL, 103)) |
| TEST_VALUE_EQUAL( "FLT_MIN", float_out[1], MAKE_HEX_FLOAT(0x1.0p-126f, 0x1L, -126)) |
| TEST_VALUE_EQUAL( "FLT_EPSILON", float_out[2], MAKE_HEX_FLOAT(0x1.0p-23f, 0x1L, -23)) |
| TEST_VALUE_EQUAL( "M_E_F", float_out[3], CL_M_E_F ) |
| TEST_VALUE_EQUAL( "M_LOG2E_F", float_out[4], CL_M_LOG2E_F ) |
| TEST_VALUE_EQUAL( "M_LOG10E_F", float_out[5], CL_M_LOG10E_F ) |
| TEST_VALUE_EQUAL( "M_LN2_F", float_out[6], CL_M_LN2_F ) |
| TEST_VALUE_EQUAL( "M_LN10_F", float_out[7], CL_M_LN10_F ) |
| TEST_VALUE_EQUAL( "M_PI_F", float_out[8], CL_M_PI_F ) |
| TEST_VALUE_EQUAL( "M_PI_2_F", float_out[9], CL_M_PI_2_F ) |
| TEST_VALUE_EQUAL( "M_PI_4_F", float_out[10], CL_M_PI_4_F ) |
| TEST_VALUE_EQUAL( "M_1_PI_F", float_out[11], CL_M_1_PI_F ) |
| TEST_VALUE_EQUAL( "M_2_PI_F", float_out[12], CL_M_2_PI_F ) |
| TEST_VALUE_EQUAL( "M_2_SQRTPI_F", float_out[13], CL_M_2_SQRTPI_F ) |
| TEST_VALUE_EQUAL( "M_SQRT2_F", float_out[14], CL_M_SQRT2_F ) |
| TEST_VALUE_EQUAL( "M_SQRT1_2_F", float_out[15], CL_M_SQRT1_2_F ) |
| |
| // We need to check these values against what we know is supported on the device |
| if( checkForImageSupport( deviceID ) == 0 ) |
| { // has images |
| // If images are supported, the constant should have been defined to the value 1 |
| if( int_out[18] == 0xf00baa ) |
| { |
| log_error( "FAILURE: __IMAGE_SUPPORT__ undefined even though images are supported\n" ); |
| return -1; |
| } |
| else if( int_out[18] != 1 ) |
| { |
| log_error( "FAILURE: __IMAGE_SUPPORT__ defined, but to the wrong value (defined as %d, spec states it should be 1)\n", int_out[18] ); |
| return -1; |
| } |
| } |
| else |
| { // no images |
| // If images aren't supported, the constant should be undefined |
| if( int_out[18] != 0xf00baa ) |
| { |
| log_error( "FAILURE: __IMAGE_SUPPORT__ defined to value %d even though images aren't supported", int_out[18] ); |
| return -1; |
| } |
| } |
| log_info( "\t__IMAGE_SUPPORT__: %d\n", int_out[18]); |
| |
| clReleaseMemObject(streams[0]); streams[0] = NULL; |
| clReleaseMemObject(streams[1]); streams[1] = NULL; |
| clReleaseMemObject(streams[2]); streams[2] = NULL; |
| clReleaseKernel(kernel); kernel = NULL; |
| clReleaseProgram(program); program = NULL; |
| |
| /** LONGs **/ |
| |
| if(!gHasLong) { |
| log_info("Longs not supported; skipping long tests.\n"); |
| } |
| else |
| { |
| // Create the kernel |
| if( create_single_kernel_helper( context, &program, &kernel, 1, kernel_long, "test" ) != 0 ) |
| { |
| return -1; |
| } |
| |
| streams[0] = clCreateBuffer(context, CL_MEM_READ_WRITE, |
| sizeof(long_out), NULL, &error); |
| test_error( error, "Creating test array failed" ); |
| streams[1] = clCreateBuffer(context, CL_MEM_READ_WRITE, |
| sizeof(ulong_out), NULL, &error); |
| test_error( error, "Creating test array failed" ); |
| |
| error = clSetKernelArg(kernel, 1, sizeof( streams[1] ), &streams[1]); |
| test_error( error, "Unable to set indexed kernel arguments" ); |
| error = clSetKernelArg(kernel, 0, sizeof( streams[0] ), &streams[0]); |
| test_error( error, "Unable to set indexed kernel arguments" ); |
| |
| error = clEnqueueNDRangeKernel( queue, kernel, 1, NULL, threads, NULL, 0, NULL, NULL ); |
| test_error( error, "Kernel execution failed" ); |
| |
| error = clEnqueueReadBuffer( queue, streams[0], CL_TRUE, 0, sizeof(long_out), &long_out, 0, NULL, NULL ); |
| test_error( error, "Unable to get result data" ); |
| error = clEnqueueReadBuffer( queue, streams[1], CL_TRUE, 0, sizeof(ulong_out), &ulong_out, 0, NULL, NULL ); |
| test_error( error, "Unable to get result data" ); |
| |
| TEST_VALUE_EQUAL_LITERAL( "LONG_MAX", long_out[0], ((cl_long) 0x7FFFFFFFFFFFFFFFLL)) |
| TEST_VALUE_EQUAL_LITERAL( "LONG_MIN", long_out[1], ((cl_long) -0x7FFFFFFFFFFFFFFFLL - 1LL)) |
| TEST_VALUE_EQUAL_LITERAL( "ULONG_MAX", ulong_out[0], ((cl_ulong) 0xFFFFFFFFFFFFFFFFULL)) |
| |
| clReleaseMemObject(streams[0]); streams[0] = NULL; |
| clReleaseMemObject(streams[1]); streams[1] = NULL; |
| clReleaseKernel(kernel); kernel = NULL; |
| clReleaseProgram(program); program = NULL; |
| } |
| |
| /** DOUBLEs **/ |
| |
| if(!is_extension_available(deviceID, "cl_khr_fp64")) { |
| log_info("Extension cl_khr_fp64 not supported; skipping double tests.\n"); |
| } |
| else |
| { |
| // Create the kernel |
| if( create_single_kernel_helper( context, &program, &kernel, 1, kernel_double, "test" ) != 0 ) |
| { |
| return -1; |
| } |
| |
| streams[0] = clCreateBuffer(context, CL_MEM_READ_WRITE, |
| sizeof(double_out), NULL, &error); |
| test_error( error, "Creating test array failed" ); |
| streams[1] = clCreateBuffer(context, CL_MEM_READ_WRITE, |
| sizeof(long_out), NULL, &error); |
| test_error( error, "Creating test array failed" ); |
| |
| error = clSetKernelArg(kernel, 1, sizeof( streams[1] ), &streams[1]); |
| test_error( error, "Unable to set indexed kernel arguments" ); |
| error = clSetKernelArg(kernel, 0, sizeof( streams[0] ), &streams[0]); |
| test_error( error, "Unable to set indexed kernel arguments" ); |
| |
| error = clEnqueueNDRangeKernel( queue, kernel, 1, NULL, threads, NULL, 0, NULL, NULL ); |
| test_error( error, "Kernel execution failed" ); |
| |
| error = clEnqueueReadBuffer( queue, streams[0], CL_TRUE, 0, sizeof(double_out), &double_out, 0, NULL, NULL ); |
| test_error( error, "Unable to get result data" ); |
| error = clEnqueueReadBuffer( queue, streams[1], CL_TRUE, 0, sizeof(long_out), &long_out, 0, NULL, NULL ); |
| test_error( error, "Unable to get result data" ); |
| |
| TEST_VALUE_EQUAL_LITERAL( "DBL_DIG", long_out[0], 15) |
| TEST_VALUE_EQUAL_LITERAL( "DBL_MANT_DIG", long_out[1], 53) |
| TEST_VALUE_EQUAL_LITERAL( "DBL_MAX_10_EXP", long_out[2], +308) |
| TEST_VALUE_EQUAL_LITERAL( "DBL_MAX_EXP", long_out[3], +1024) |
| TEST_VALUE_EQUAL_LITERAL( "DBL_MIN_10_EXP", long_out[4], -307) |
| TEST_VALUE_EQUAL_LITERAL( "DBL_MIN_EXP", long_out[5], -1021) |
| TEST_VALUE_EQUAL_LITERAL( "DBL_RADIX", long_out[6], 2) |
| TEST_VALUE_EQUAL( "DBL_MAX", double_out[0], MAKE_HEX_DOUBLE(0x1.fffffffffffffp1023, 0x1fffffffffffffLL, 971)) |
| TEST_VALUE_EQUAL( "DBL_MIN", double_out[1], MAKE_HEX_DOUBLE(0x1.0p-1022, 0x1LL, -1022)) |
| TEST_VALUE_EQUAL( "DBL_EPSILON", double_out[2], MAKE_HEX_DOUBLE(0x1.0p-52, 0x1LL, -52)) |
| //TEST_VALUE_EQUAL( "M_E", double_out[3], CL_M_E ) |
| TEST_VALUE_EQUAL( "M_LOG2E", double_out[4], CL_M_LOG2E ) |
| TEST_VALUE_EQUAL( "M_LOG10E", double_out[5], CL_M_LOG10E ) |
| TEST_VALUE_EQUAL( "M_LN2", double_out[6], CL_M_LN2 ) |
| TEST_VALUE_EQUAL( "M_LN10", double_out[7], CL_M_LN10 ) |
| TEST_VALUE_EQUAL( "M_PI", double_out[8], CL_M_PI ) |
| TEST_VALUE_EQUAL( "M_PI_2", double_out[9], CL_M_PI_2 ) |
| TEST_VALUE_EQUAL( "M_PI_4", double_out[10], CL_M_PI_4 ) |
| TEST_VALUE_EQUAL( "M_1_PI", double_out[11], CL_M_1_PI ) |
| TEST_VALUE_EQUAL( "M_2_PI", double_out[12], CL_M_2_PI ) |
| TEST_VALUE_EQUAL( "M_2_SQRTPI", double_out[13], CL_M_2_SQRTPI ) |
| TEST_VALUE_EQUAL( "M_SQRT2", double_out[14], CL_M_SQRT2 ) |
| TEST_VALUE_EQUAL( "M_SQRT1_2", double_out[15], CL_M_SQRT1_2 ) |
| |
| clReleaseMemObject(streams[0]); streams[0] = NULL; |
| clReleaseMemObject(streams[1]); streams[1] = NULL; |
| clReleaseKernel(kernel); kernel = NULL; |
| clReleaseProgram(program); program = NULL; |
| } |
| |
| error = clFinish(queue); |
| test_error(error, "clFinish failed"); |
| |
| return errors; |
| } |
| |
| |
| const char *kernel_constant_limits[] = { |
| "__kernel void test( __global int *intOut, __global float *floatOut ) \n" |
| "{\n" |
| " intOut[0] = isinf( MAXFLOAT ) ? 1 : 0;\n" |
| " intOut[1] = isnormal( MAXFLOAT ) ? 1 : 0;\n" |
| " intOut[2] = isnan( MAXFLOAT ) ? 1 : 0;\n" |
| " intOut[3] = sizeof( MAXFLOAT );\n" |
| " intOut[4] = ( MAXFLOAT == FLT_MAX ) ? 1 : 0;\n" |
| // " intOut[5] = ( MAXFLOAT == CL_FLT_MAX ) ? 1 : 0;\n" |
| " intOut[6] = ( MAXFLOAT == MAXFLOAT ) ? 1 : 0;\n" |
| " intOut[7] = ( MAXFLOAT == 0x1.fffffep127f ) ? 1 : 0;\n" |
| " floatOut[0] = MAXFLOAT;\n" |
| "}\n" |
| }; |
| |
| const char *kernel_constant_extended_limits[] = { |
| "__kernel void test( __global int *intOut, __global float *floatOut ) \n" |
| "{\n" |
| " intOut[0] = ( INFINITY == HUGE_VALF ) ? 1 : 0;\n" |
| " intOut[1] = sizeof( INFINITY );\n" |
| " intOut[2] = isinf( INFINITY ) ? 1 : 0;\n" |
| " intOut[3] = isnormal( INFINITY ) ? 1 : 0;\n" |
| " intOut[4] = isnan( INFINITY ) ? 1 : 0;\n" |
| " intOut[5] = ( INFINITY > MAXFLOAT ) ? 1 : 0;\n" |
| " intOut[6] = ( -INFINITY < -MAXFLOAT ) ? 1 : 0;\n" |
| " intOut[7] = ( ( MAXFLOAT + MAXFLOAT ) == INFINITY ) ? 1 : 0;\n" |
| " intOut[8] = ( nextafter( MAXFLOAT, INFINITY ) == INFINITY ) ? 1 : 0;\n" |
| " intOut[9] = ( nextafter( -MAXFLOAT, -INFINITY ) == -INFINITY ) ? 1 : 0;\n" |
| " intOut[10] = ( INFINITY == INFINITY ) ? 1 : 0;\n" |
| " intOut[11] = ( as_uint( INFINITY ) == 0x7f800000 ) ? 1 : 0;\n" |
| " floatOut[0] = INFINITY;\n" |
| "\n" |
| " intOut[12] = sizeof( HUGE_VALF );\n" |
| " intOut[13] = ( HUGE_VALF == INFINITY ) ? 1 : 0;\n" |
| " floatOut[1] = HUGE_VALF;\n" |
| "\n" |
| " intOut[14] = ( NAN == NAN ) ? 1 : 0;\n" |
| " intOut[15] = ( NAN != NAN ) ? 1 : 0;\n" |
| " intOut[16] = isnan( NAN ) ? 1 : 0;\n" |
| " intOut[17] = isinf( NAN ) ? 1 : 0;\n" |
| " intOut[18] = isnormal( NAN ) ? 1 : 0;\n" |
| " intOut[19] = ( ( as_uint( NAN ) & 0x7fffffff ) > 0x7f800000 ) ? 1 : 0;\n" |
| " intOut[20] = sizeof( NAN );\n" |
| " floatOut[2] = NAN;\n" |
| "\n" |
| " intOut[21] = isnan( INFINITY / INFINITY ) ? 1 : 0;\n" |
| " intOut[22] = isnan( INFINITY - INFINITY ) ? 1 : 0;\n" |
| " intOut[23] = isnan( 0.f / 0.f ) ? 1 : 0;\n" |
| " intOut[24] = isnan( INFINITY * 0.f ) ? 1 : 0;\n" |
| " intOut[25] = ( INFINITY == NAN ); \n" |
| " intOut[26] = ( -INFINITY == NAN ); \n" |
| " intOut[27] = ( INFINITY > NAN ); \n" |
| " intOut[28] = ( -INFINITY < NAN ); \n" |
| " intOut[29] = ( INFINITY != NAN ); \n" |
| " intOut[30] = ( NAN > INFINITY ); \n" |
| " intOut[31] = ( NAN < -INFINITY ); \n" |
| |
| "}\n" |
| }; |
| |
| const char *kernel_constant_double_limits[] = { |
| "#pragma OPENCL EXTENSION cl_khr_fp64 : enable\n" |
| "__kernel void test( __global int *intOut, __global double *doubleOut ) \n" |
| "{\n" |
| " intOut[0] = sizeof( HUGE_VAL );\n" |
| " intOut[1] = ( HUGE_VAL == INFINITY ) ? 1 : 0;\n" |
| " intOut[2] = isinf( HUGE_VAL ) ? 1 : 0;\n" |
| " intOut[3] = isnormal( HUGE_VAL ) ? 1 : 0;\n" |
| " intOut[4] = isnan( HUGE_VAL ) ? 1 : 0;\n" |
| " intOut[5] = ( HUGE_VAL == HUGE_VALF ) ? 1 : 0;\n" |
| " intOut[6] = ( as_ulong( HUGE_VAL ) == 0x7ff0000000000000UL ) ? 1 : 0;\n" |
| " doubleOut[0] = HUGE_VAL;\n" |
| "}\n" |
| }; |
| |
| #define TEST_FLOAT_ASSERTION( a, msg, f ) if( !( a ) ) { log_error( "ERROR: Float constant failed requirement: %s (bitwise value is 0x%8.8x)\n", msg, *( (uint32_t *)&f ) ); return -1; } |
| #define TEST_DOUBLE_ASSERTION( a, msg, f ) if( !( a ) ) { log_error( "ERROR: Double constant failed requirement: %s (bitwise value is 0x%16.16llx)\n", msg, *( (uint64_t *)&f ) ); return -1; } |
| |
| int test_kernel_limit_constants(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements) |
| { |
| int error; |
| size_t threads[] = {1,1,1}; |
| clMemWrapper intStream, floatStream, doubleStream; |
| cl_int intOut[ 32 ]; |
| cl_float floatOut[ 3 ]; |
| cl_double doubleOut[ 1 ]; |
| |
| |
| /* Create some I/O streams */ |
| intStream = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(intOut), NULL, |
| &error); |
| test_error( error, "Creating test array failed" ); |
| floatStream = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(floatOut), |
| NULL, &error); |
| test_error( error, "Creating test array failed" ); |
| |
| // Stage 1: basic limits on MAXFLOAT |
| { |
| clProgramWrapper program; |
| clKernelWrapper kernel; |
| |
| if( create_single_kernel_helper( context, &program, &kernel, 1, kernel_constant_limits, "test" ) != 0 ) |
| { |
| return -1; |
| } |
| |
| error = clSetKernelArg( kernel, 0, sizeof( intStream ), &intStream ); |
| test_error( error, "Unable to set indexed kernel arguments" ); |
| error = clSetKernelArg( kernel, 1, sizeof( floatStream ), &floatStream ); |
| test_error( error, "Unable to set indexed kernel arguments" ); |
| |
| error = clEnqueueNDRangeKernel( queue, kernel, 1, NULL, threads, NULL, 0, NULL, NULL ); |
| test_error( error, "Kernel execution failed" ); |
| |
| error = clEnqueueReadBuffer( queue, intStream, CL_TRUE, 0, sizeof(intOut), intOut, 0, NULL, NULL ); |
| test_error( error, "Unable to get result data" ); |
| error = clEnqueueReadBuffer( queue, floatStream, CL_TRUE, 0, sizeof(floatOut), floatOut, 0, NULL, NULL ); |
| test_error( error, "Unable to get result data" ); |
| |
| // Test MAXFLOAT properties |
| TEST_FLOAT_ASSERTION( intOut[0] == 0, "isinf( MAXFLOAT ) = false", floatOut[0] ) |
| TEST_FLOAT_ASSERTION( intOut[1] == 1, "isnormal( MAXFLOAT ) = true", floatOut[0] ) |
| TEST_FLOAT_ASSERTION( intOut[2] == 0, "isnan( MAXFLOAT ) = false", floatOut[0] ) |
| TEST_FLOAT_ASSERTION( intOut[3] == 4, "sizeof( MAXFLOAT ) = 4", floatOut[0] ) |
| TEST_FLOAT_ASSERTION( intOut[4] == 1, "MAXFLOAT = FLT_MAX", floatOut[0] ) |
| TEST_FLOAT_ASSERTION( floatOut[0] == CL_FLT_MAX, "MAXFLOAT = CL_FLT_MAX", floatOut[0] ) |
| TEST_FLOAT_ASSERTION( intOut[6] == 1, "MAXFLOAT = MAXFLOAT", floatOut[0] ) |
| TEST_FLOAT_ASSERTION( floatOut[0] == MAKE_HEX_FLOAT( 0x1.fffffep127f, 0x1fffffeL, 103), "MAXFLOAT = 0x1.fffffep127f", floatOut[0] ) |
| } |
| |
| // Stage 2: INFINITY and NAN |
| char profileStr[128] = ""; |
| error = clGetDeviceInfo( deviceID, CL_DEVICE_PROFILE, sizeof( profileStr ), &profileStr, NULL ); |
| test_error( error, "Unable to run INFINITY/NAN tests (unable to get CL_DEVICE_PROFILE" ); |
| |
| bool testInfNan = true; |
| if( strcmp( profileStr, "EMBEDDED_PROFILE" ) == 0 ) |
| { |
| // We test if we're not an embedded profile, OR if the inf/nan flag in the config is set |
| cl_device_fp_config single = 0; |
| error = clGetDeviceInfo( deviceID, CL_DEVICE_SINGLE_FP_CONFIG, sizeof( single ), &single, NULL ); |
| test_error( error, "Unable to run INFINITY/NAN tests (unable to get FP_CONFIG bits)" ); |
| |
| if( ( single & CL_FP_INF_NAN ) == 0 ) |
| { |
| log_info( "Skipping INFINITY and NAN tests on embedded device (INF/NAN not supported on this device)" ); |
| testInfNan = false; |
| } |
| } |
| |
| if( testInfNan ) |
| { |
| clProgramWrapper program; |
| clKernelWrapper kernel; |
| |
| if( create_single_kernel_helper( context, &program, &kernel, 1, kernel_constant_extended_limits, "test" ) != 0 ) |
| { |
| return -1; |
| } |
| |
| error = clSetKernelArg( kernel, 0, sizeof( intStream ), &intStream ); |
| test_error( error, "Unable to set indexed kernel arguments" ); |
| error = clSetKernelArg( kernel, 1, sizeof( floatStream ), &floatStream ); |
| test_error( error, "Unable to set indexed kernel arguments" ); |
| |
| error = clEnqueueNDRangeKernel( queue, kernel, 1, NULL, threads, NULL, 0, NULL, NULL ); |
| test_error( error, "Kernel execution failed" ); |
| |
| error = clEnqueueReadBuffer( queue, intStream, CL_TRUE, 0, sizeof(intOut), intOut, 0, NULL, NULL ); |
| test_error( error, "Unable to get result data" ); |
| error = clEnqueueReadBuffer( queue, floatStream, CL_TRUE, 0, sizeof(floatOut), floatOut, 0, NULL, NULL ); |
| test_error( error, "Unable to get result data" ); |
| |
| TEST_FLOAT_ASSERTION( intOut[0] == 1, "INFINITY == HUGE_VALF", intOut[0] ) |
| TEST_FLOAT_ASSERTION( intOut[1] == 4, "sizeof( INFINITY ) == 4", intOut[1] ) |
| TEST_FLOAT_ASSERTION( intOut[2] == 1, "isinf( INFINITY ) == true", intOut[2] ) |
| TEST_FLOAT_ASSERTION( intOut[3] == 0, "isnormal( INFINITY ) == false", intOut[3] ) |
| TEST_FLOAT_ASSERTION( intOut[4] == 0, "isnan( INFINITY ) == false", intOut[4] ) |
| TEST_FLOAT_ASSERTION( intOut[5] == 1, "INFINITY > MAXFLOAT", intOut[5] ) |
| TEST_FLOAT_ASSERTION( intOut[6] == 1, "-INFINITY < -MAXFLOAT", intOut[6] ) |
| TEST_FLOAT_ASSERTION( intOut[7] == 1, "( MAXFLOAT + MAXFLOAT ) == INFINITY", intOut[7] ) |
| TEST_FLOAT_ASSERTION( intOut[8] == 1, "nextafter( MAXFLOAT, INFINITY ) == INFINITY", intOut[8] ) |
| TEST_FLOAT_ASSERTION( intOut[9] == 1, "nextafter( -MAXFLOAT, -INFINITY ) == -INFINITY", intOut[9] ) |
| TEST_FLOAT_ASSERTION( intOut[10] == 1, "INFINITY = INFINITY", intOut[10] ) |
| TEST_FLOAT_ASSERTION( intOut[11] == 1, "asuint( INFINITY ) == 0x7f800000", intOut[11] ) |
| TEST_FLOAT_ASSERTION( *( (uint32_t *)&floatOut[0] ) == 0x7f800000, "asuint( INFINITY ) == 0x7f800000", floatOut[0] ) |
| TEST_FLOAT_ASSERTION( floatOut[1] == INFINITY, "INFINITY == INFINITY", floatOut[1] ) |
| |
| TEST_FLOAT_ASSERTION( intOut[12] == 4, "sizeof( HUGE_VALF ) == 4", intOut[12] ) |
| TEST_FLOAT_ASSERTION( intOut[13] == 1, "HUGE_VALF == INFINITY", intOut[13] ) |
| TEST_FLOAT_ASSERTION( floatOut[1] == HUGE_VALF, "HUGE_VALF == HUGE_VALF", floatOut[1] ) |
| |
| TEST_FLOAT_ASSERTION( intOut[14] == 0, "(NAN == NAN) = false", intOut[14] ) |
| TEST_FLOAT_ASSERTION( intOut[15] == 1, "(NAN != NAN) = true", intOut[15] ) |
| TEST_FLOAT_ASSERTION( intOut[16] == 1, "isnan( NAN ) = true", intOut[16] ) |
| TEST_FLOAT_ASSERTION( intOut[17] == 0, "isinf( NAN ) = false", intOut[17] ) |
| TEST_FLOAT_ASSERTION( intOut[18] == 0, "isnormal( NAN ) = false", intOut[18] ) |
| TEST_FLOAT_ASSERTION( intOut[19] == 1, "( as_uint( NAN ) & 0x7fffffff ) > 0x7f800000", intOut[19] ) |
| TEST_FLOAT_ASSERTION( intOut[20] == 4, "sizeof( NAN ) = 4", intOut[20] ) |
| TEST_FLOAT_ASSERTION( ( *( (uint32_t *)&floatOut[2] ) & 0x7fffffff ) > 0x7f800000, "( as_uint( NAN ) & 0x7fffffff ) > 0x7f800000", floatOut[2] ) |
| |
| TEST_FLOAT_ASSERTION( intOut[ 21 ] == 1, "isnan( INFINITY / INFINITY ) = true", intOut[ 21 ] ) |
| TEST_FLOAT_ASSERTION( intOut[ 22 ] == 1, "isnan( INFINITY - INFINITY ) = true", intOut[ 22 ] ) |
| TEST_FLOAT_ASSERTION( intOut[ 23 ] == 1, "isnan( 0.f / 0.f ) = true", intOut[ 23 ] ) |
| TEST_FLOAT_ASSERTION( intOut[ 24 ] == 1, "isnan( INFINITY * 0.f ) = true", intOut[ 24 ] ) |
| TEST_FLOAT_ASSERTION( intOut[ 25 ] == 0, "( INFINITY == NAN ) = false", intOut[ 25 ] ) |
| TEST_FLOAT_ASSERTION( intOut[ 26 ] == 0, "(-INFINITY == NAN ) = false", intOut[ 26 ] ) |
| TEST_FLOAT_ASSERTION( intOut[ 27 ] == 0, "( INFINITY > NAN ) = false", intOut[ 27 ] ) |
| TEST_FLOAT_ASSERTION( intOut[ 28 ] == 0, "(-INFINITY < NAN ) = false", intOut[ 28 ] ) |
| TEST_FLOAT_ASSERTION( intOut[ 29 ] == 1, "( INFINITY != NAN ) = true", intOut[ 29 ] ) |
| TEST_FLOAT_ASSERTION( intOut[ 30 ] == 0, "( NAN < INFINITY ) = false", intOut[ 30 ] ) |
| TEST_FLOAT_ASSERTION( intOut[ 31 ] == 0, "( NAN > -INFINITY ) = false", intOut[ 31 ] ) |
| } |
| |
| // Stage 3: limits on HUGE_VAL (double) |
| if( !is_extension_available( deviceID, "cl_khr_fp64" ) ) |
| log_info( "Note: Skipping double HUGE_VAL tests (doubles unsupported on device)\n" ); |
| else |
| { |
| cl_device_fp_config config = 0; |
| error = clGetDeviceInfo( deviceID, CL_DEVICE_DOUBLE_FP_CONFIG, sizeof( config ), &config, NULL ); |
| test_error( error, "Unable to run INFINITY/NAN tests (unable to get double FP_CONFIG bits)" ); |
| |
| if( ( config & CL_FP_INF_NAN ) == 0 ) |
| log_info( "Skipping HUGE_VAL tests (INF/NAN not supported on this device)" ); |
| else |
| { |
| clProgramWrapper program; |
| clKernelWrapper kernel; |
| |
| if( create_single_kernel_helper( context, &program, &kernel, 1, kernel_constant_double_limits, "test" ) != 0 ) |
| { |
| return -1; |
| } |
| |
| doubleStream = clCreateBuffer(context, CL_MEM_READ_WRITE, |
| sizeof(doubleOut), NULL, &error); |
| test_error( error, "Creating test array failed" ); |
| |
| error = clSetKernelArg( kernel, 0, sizeof( intStream ), &intStream ); |
| test_error( error, "Unable to set indexed kernel arguments" ); |
| error = clSetKernelArg( kernel, 1, sizeof( doubleStream ), &doubleStream ); |
| test_error( error, "Unable to set indexed kernel arguments" ); |
| |
| error = clEnqueueNDRangeKernel( queue, kernel, 1, NULL, threads, NULL, 0, NULL, NULL ); |
| test_error( error, "Kernel execution failed" ); |
| |
| error = clEnqueueReadBuffer( queue, intStream, CL_TRUE, 0, sizeof(intOut), intOut, 0, NULL, NULL ); |
| test_error( error, "Unable to get result data" ); |
| error = clEnqueueReadBuffer( queue, doubleStream, CL_TRUE, 0, sizeof(doubleOut), doubleOut, 0, NULL, NULL ); |
| test_error( error, "Unable to get result data" ); |
| |
| TEST_DOUBLE_ASSERTION( intOut[0] == 8, "sizeof( HUGE_VAL ) = 8", intOut[0] ) |
| TEST_DOUBLE_ASSERTION( intOut[1] == 1, "HUGE_VAL = INFINITY", intOut[1] ) |
| TEST_DOUBLE_ASSERTION( intOut[2] == 1, "isinf( HUGE_VAL ) = true", intOut[2] ) |
| TEST_DOUBLE_ASSERTION( intOut[3] == 0, "isnormal( HUGE_VAL ) = false", intOut[3] ) |
| TEST_DOUBLE_ASSERTION( intOut[4] == 0, "isnan( HUGE_VAL ) = false", intOut[4] ) |
| TEST_DOUBLE_ASSERTION( intOut[5] == 1, "HUGE_VAL = HUGE_VAL", intOut[5] ) |
| TEST_DOUBLE_ASSERTION( intOut[6] == 1, "as_ulong( HUGE_VAL ) = 0x7ff0000000000000UL", intOut[6] ) |
| TEST_DOUBLE_ASSERTION( *( (uint64_t *)&doubleOut[0] ) == 0x7ff0000000000000ULL, "as_ulong( HUGE_VAL ) = 0x7ff0000000000000UL", doubleOut[0] ) |
| } |
| } |
| |
| return 0; |
| } |
| |
| |