diff options
Diffstat (limited to 'test_conformance/basic/test_hiloeo.cpp')
-rw-r--r-- | test_conformance/basic/test_hiloeo.cpp | 363 |
1 files changed, 119 insertions, 244 deletions
diff --git a/test_conformance/basic/test_hiloeo.cpp b/test_conformance/basic/test_hiloeo.cpp index 3470ad00..4e921a6e 100644 --- a/test_conformance/basic/test_hiloeo.cpp +++ b/test_conformance/basic/test_hiloeo.cpp @@ -1,6 +1,6 @@ // -// Copyright (c) 2017 The Khronos Group Inc. -// +// Copyright (c) 2023 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 @@ -13,14 +13,13 @@ // See the License for the specific language governing permissions and // limitations under the License. // -#include "harness/compat.h" - +#include <iomanip> +#include <limits.h> #include <stdio.h> #include <string.h> -#include <limits.h> #include <sys/types.h> #include <sys/stat.h> - +#include <vector> #include "procs.h" @@ -31,9 +30,10 @@ int odd_offset( int index, int vectorSize ) { return index * 2 + 1; } typedef int (*OffsetFunc)( int index, int vectorSize ); static const OffsetFunc offsetFuncs[4] = { hi_offset, lo_offset, even_offset, odd_offset }; -typedef int (*verifyFunc)( const void *, const void *, const void *, int n, const char *sizeName ); static const char *operatorToUse_names[] = { "hi", "lo", "even", "odd" }; -static const char *test_str_names[] = { "char", "uchar", "short", "ushort", "int", "uint", "long", "ulong", "float", "double" }; +static const char *test_str_names[] = { "char", "uchar", "short", "ushort", + "int", "uint", "long", "ulong", + "half", "float", "double" }; static const unsigned int vector_sizes[] = { 1, 2, 3, 4, 8, 16}; static const unsigned int vector_aligns[] = { 1, 2, 4, 4, 8, 16}; @@ -45,43 +45,41 @@ static const unsigned int out_vector_idx[] = { 0, 0, 1, 1, 3, 4}; // strcat(gentype, vector_size_names[out_vector_idx[i]]); static const char *vector_size_names[] = { "", "2", "3", "4", "8", "16"}; -static const size_t kSizes[] = { 1, 1, 2, 2, 4, 4, 8, 8, 4, 8 }; +static const size_t kSizes[] = { 1, 1, 2, 2, 4, 4, 8, 8, 2, 4, 8 }; static int CheckResults( void *in, void *out, size_t elementCount, int type, int vectorSize, int operatorToUse ); int test_hiloeo(cl_device_id device, cl_context context, cl_command_queue queue, int n_elems) { - cl_int *input_ptr, *output_ptr, *p; int err; - cl_uint i; int hasDouble = is_extension_available( device, "cl_khr_fp64" ); + int hasHalf = is_extension_available(device, "cl_khr_fp16"); cl_uint vectorSize, operatorToUse; cl_uint type; - MTdata d; + MTdataHolder d(gRandomSeed); int expressionMode; int numExpressionModes = 2; size_t length = sizeof(cl_int) * 4 * n_elems; - input_ptr = (cl_int*)malloc(length); - output_ptr = (cl_int*)malloc(length); + std::vector<cl_int> input_ptr(4 * n_elems); + std::vector<cl_int> output_ptr(4 * n_elems); - p = input_ptr; - d = init_genrand( gRandomSeed ); - for (i=0; i<4 * (cl_uint) n_elems; i++) - p[i] = genrand_int32(d); - free_mtdata(d); d = NULL; + for (cl_uint i = 0; i < 4 * (cl_uint)n_elems; i++) + input_ptr[i] = genrand_int32(d); for( type = 0; type < sizeof( test_str_names ) / sizeof( test_str_names[0] ); type++ ) { // Note: restrict the element count here so we don't end up overrunning the output buffer if we're compensating for 32-bit writes size_t elementCount = length / kSizes[type]; - cl_mem streams[2]; + clMemWrapper streams[2]; // skip double if unavailable if( !hasDouble && ( 0 == strcmp( test_str_names[type], "double" ))) continue; + if (!hasHalf && (0 == strcmp(test_str_names[type], "half"))) continue; + if( !gHasLong && (( 0 == strcmp( test_str_names[type], "long" )) || ( 0 == strcmp( test_str_names[type], "ulong" )))) @@ -104,12 +102,9 @@ int test_hiloeo(cl_device_id device, cl_context context, cl_command_queue queue, return -1; } - err = clEnqueueWriteBuffer(queue, streams[0], CL_TRUE, 0, length, input_ptr, 0, NULL, NULL); - if (err != CL_SUCCESS) - { - log_error("clEnqueueWriteBuffer failed\n"); - return -1; - } + err = clEnqueueWriteBuffer(queue, streams[0], CL_TRUE, 0, length, + input_ptr.data(), 0, NULL, NULL); + test_error(err, "clEnqueueWriteBuffer failed\n"); for( operatorToUse = 0; operatorToUse < sizeof( operatorToUse_names ) / sizeof( operatorToUse_names[0] ); operatorToUse++ ) { @@ -118,8 +113,8 @@ int test_hiloeo(cl_device_id device, cl_context context, cl_command_queue queue, for( vectorSize = 1; vectorSize < sizeof( vector_size_names ) / sizeof( vector_size_names[0] ); vectorSize++ ) { for(expressionMode = 0; expressionMode < numExpressionModes; ++expressionMode) { - cl_program program = NULL; - cl_kernel kernel = NULL; + clProgramWrapper program; + clKernelWrapper kernel; cl_uint outVectorSize = out_vector_idx[vectorSize]; char expression[1024]; @@ -139,92 +134,64 @@ int test_hiloeo(cl_device_id device, cl_context context, cl_command_queue queue, "}\n" }; - if(expressionMode == 0) { - sprintf(expression, "srcA[tid]"); - } else if(expressionMode == 1) { - switch(vector_sizes[vectorSize]) { - case 16: - sprintf(expression, - "((%s16)(srcA[tid].s0, srcA[tid].s1, srcA[tid].s2, srcA[tid].s3, srcA[tid].s4, srcA[tid].s5, srcA[tid].s6, srcA[tid].s7, srcA[tid].s8, srcA[tid].s9, srcA[tid].sA, srcA[tid].sB, srcA[tid].sC, srcA[tid].sD, srcA[tid].sE, srcA[tid].sf))", - test_str_names[type] - ); - break; - case 8: - sprintf(expression, - "((%s8)(srcA[tid].s0, srcA[tid].s1, srcA[tid].s2, srcA[tid].s3, srcA[tid].s4, srcA[tid].s5, srcA[tid].s6, srcA[tid].s7))", - test_str_names[type] - ); - break; - case 4: - sprintf(expression, - "((%s4)(srcA[tid].s0, srcA[tid].s1, srcA[tid].s2, srcA[tid].s3))", - test_str_names[type] - ); - break; - case 3: - sprintf(expression, - "((%s3)(srcA[tid].s0, srcA[tid].s1, srcA[tid].s2))", - test_str_names[type] - ); - break; - case 2: - sprintf(expression, - "((%s2)(srcA[tid].s0, srcA[tid].s1))", - test_str_names[type] - ); - break; - default : - sprintf(expression, "srcA[tid]"); - log_info("Default\n"); - } - } else { - sprintf(expression, "srcA[tid]"); + if (expressionMode == 1 && vector_sizes[vectorSize] != 1) + { + std::ostringstream sstr; + const char *index_chars[] = { "0", "1", "2", "3", + "4", "5", "6", "7", + "8", "9", "A", "B", + "C", "D", "E", "f" }; + sstr << "((" << test_str_names[type] + << std::to_string(vector_sizes[vectorSize]) + << ")("; + for (unsigned i = 0; i < vector_sizes[vectorSize]; i++) + sstr << " srcA[tid].s" << index_chars[i] << ","; + sstr.seekp(-1, sstr.cur); + sstr << "))"; + std::snprintf(expression, sizeof(expression), "%s", + sstr.str().c_str()); + } + else + { + std::snprintf(expression, sizeof(expression), + "srcA[tid]"); } if (0 == strcmp( test_str_names[type], "double" )) source[0] = "#pragma OPENCL EXTENSION cl_khr_fp64 : enable\n"; + if (0 == strcmp(test_str_names[type], "half")) + source[0] = + "#pragma OPENCL EXTENSION cl_khr_fp16 : enable\n"; + char kernelName[128]; snprintf( kernelName, sizeof( kernelName ), "test_%s_%s%s", operatorToUse_names[ operatorToUse ], test_str_names[type], vector_size_names[vectorSize] ); err = create_single_kernel_helper(context, &program, &kernel, sizeof( source ) / sizeof( source[0] ), source, kernelName ); - if (err) - return -1; + test_error(err, "create_single_kernel_helper failed\n"); err = clSetKernelArg(kernel, 0, sizeof streams[0], &streams[0]); err |= clSetKernelArg(kernel, 1, sizeof streams[1], &streams[1]); - if (err != CL_SUCCESS) - { - log_error("clSetKernelArgs failed\n"); - return -1; - } + test_error(err, "clSetKernelArg failed\n"); //Wipe the output buffer clean uint32_t pattern = 0xdeadbeef; - memset_pattern4( output_ptr, &pattern, length ); - err = clEnqueueWriteBuffer(queue, streams[1], CL_TRUE, 0, length, output_ptr, 0, NULL, NULL); - if (err != CL_SUCCESS) - { - log_error("clEnqueueWriteBuffer failed\n"); - return -1; - } + memset_pattern4(output_ptr.data(), &pattern, length); + err = clEnqueueWriteBuffer(queue, streams[1], CL_TRUE, 0, + length, output_ptr.data(), 0, + NULL, NULL); + test_error(err, "clEnqueueWriteBuffer failed\n"); size_t size = elementCount / (vector_aligns[vectorSize]); err = clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &size, NULL, 0, NULL, NULL); - if (err != CL_SUCCESS) - { - log_error("clEnqueueNDRangeKernel failed\n"); - return -1; - } + test_error(err, "clEnqueueNDRangeKernel failed\n"); - err = clEnqueueReadBuffer(queue, streams[1], CL_TRUE, 0, length, output_ptr, 0, NULL, NULL); - if (err != CL_SUCCESS) - { - log_error("clEnqueueReadBuffer failed\n"); - return -1; - } + err = clEnqueueReadBuffer(queue, streams[1], CL_TRUE, 0, + length, output_ptr.data(), 0, + NULL, NULL); + test_error(err, "clEnqueueReadBuffer failed\n"); - char *inP = (char *)input_ptr; - char *outP = (char *)output_ptr; + char *inP = (char *)input_ptr.data(); + char *outP = (char *)output_ptr.data(); outP += kSizes[type] * ( ( vector_sizes[outVectorSize] ) - ( vector_sizes[ out_vector_idx[vectorSize] ] ) ); // was outP += kSizes[type] * ( ( 1 << outVectorSize ) - ( 1 << ( vectorSize - 1 ) ) ); @@ -240,180 +207,88 @@ int test_hiloeo(cl_device_id device, cl_context context, cl_command_queue queue, inP += kSizes[type] * ( vector_aligns[vectorSize] ); outP += kSizes[type] * ( vector_aligns[outVectorSize] ); } - - clReleaseKernel( kernel ); - clReleaseProgram( program ); log_info( "." ); fflush( stdout ); } } } - - clReleaseMemObject( streams[0] ); - clReleaseMemObject( streams[1] ); log_info( "done\n" ); } log_info("HiLoEO test passed\n"); - - free(input_ptr); - free(output_ptr); - return err; } -static int CheckResults( void *in, void *out, size_t elementCount, int type, int vectorSize, int operatorToUse ) +template <typename T> +cl_int verify(void *in, void *out, size_t elementCount, int type, + int vectorSize, int operatorToUse, size_t cmpVectorSize) { - cl_ulong array[8]; + size_t halfVectorSize = vector_sizes[out_vector_idx[vectorSize]]; + size_t elementSize = kSizes[type]; + OffsetFunc f = offsetFuncs[operatorToUse]; + cl_ulong array[8]; void *p = array; - size_t halfVectorSize = vector_sizes[out_vector_idx[vectorSize]]; - size_t cmpVectorSize = vector_sizes[out_vector_idx[vectorSize]]; - // was 1 << (vectorSize-1); - OffsetFunc f = offsetFuncs[ operatorToUse ]; - size_t elementSize = kSizes[type]; - - if(vector_size_names[vectorSize][0] == '3') { - if(operatorToUse_names[operatorToUse][0] == 'h' || - operatorToUse_names[operatorToUse][0] == 'o') // hi or odd - { - cmpVectorSize = 1; // special case for vec3 ignored values - } - } - switch( elementSize ) - { - case 1: - { - char *i = (char*)in; - char *o = (char*)out; - size_t j; - cl_uint k; - OffsetFunc f = offsetFuncs[ operatorToUse ]; - - for( k = 0; k < elementCount; k++ ) - { - char *o2 = (char*)p; - for( j = 0; j < halfVectorSize; j++ ) - o2[j] = i[ f((int)j, (int)halfVectorSize*2) ]; - - if( memcmp( o, o2, elementSize * cmpVectorSize ) ) - { - log_info( "\n%d) Failure for %s%s.%s { %d", k, test_str_names[type], vector_size_names[ vectorSize ], operatorToUse_names[ operatorToUse ], i[0] ); - for( j = 1; j < halfVectorSize * 2; j++ ) - log_info( ", %d", i[j] ); - log_info( " } --> { %d", o[0] ); - for( j = 1; j < halfVectorSize; j++ ) - log_info( ", %d", o[j] ); - log_info( " }\n" ); - return -1; - } - i += 2 * halfVectorSize; - o += halfVectorSize; - } - } - break; + std::ostringstream ss; - case 2: - { - short *i = (short*)in; - short *o = (short*)out; - size_t j; - cl_uint k; - - for( k = 0; k < elementCount; k++ ) - { - short *o2 = (short*)p; - for( j = 0; j < halfVectorSize; j++ ) - o2[j] = i[ f((int)j, (int)halfVectorSize*2) ]; - - if( memcmp( o, o2, elementSize * cmpVectorSize ) ) - { - log_info( "\n%d) Failure for %s%s.%s { %d", k, test_str_names[type], vector_size_names[ vectorSize ], operatorToUse_names[ operatorToUse ], i[0] ); - for( j = 1; j < halfVectorSize * 2; j++ ) - log_info( ", %d", i[j] ); - log_info( " } --> { %d", o[0] ); - for( j = 1; j < halfVectorSize; j++ ) - log_info( ", %d", o[j] ); - log_info( " }\n" ); - return -1; - } - i += 2 * halfVectorSize; - o += halfVectorSize; - } - } - break; + T *i = (T *)in, *o = (T *)out; - case 4: - { - int *i = (int*)in; - int *o = (int*)out; - size_t j; - cl_uint k; - - for( k = 0; k < elementCount; k++ ) - { - int *o2 = (int *)p; - for( j = 0; j < halfVectorSize; j++ ) - o2[j] = i[ f((int)j, (int)halfVectorSize*2) ]; - - for( j = 0; j < cmpVectorSize; j++ ) + for (cl_uint k = 0; k < elementCount; k++) + { + T *o2 = (T *)p; + for (size_t j = 0; j < halfVectorSize; j++) + o2[j] = i[f((int)j, (int)halfVectorSize * 2)]; + + if (memcmp(o, o2, elementSize * cmpVectorSize)) { - /* Allow float nans to be binary different */ - if( memcmp( &o[j], &o2[j], elementSize ) && !((strcmp(test_str_names[type], "float") == 0) && isnan(((float *)o)[j]) && isnan(((float *)o2)[j]))) - { - log_info( "\n%d) Failure for %s%s.%s { 0x%8.8x", k, test_str_names[type], vector_size_names[ vectorSize ], operatorToUse_names[ operatorToUse ], i[0] ); - for( j = 1; j < halfVectorSize * 2; j++ ) - log_info( ", 0x%8.8x", i[j] ); - log_info( " } --> { 0x%8.8x", o[0] ); - for( j = 1; j < halfVectorSize; j++ ) - log_info( ", 0x%8.8x", o[j] ); - log_info( " }\n" ); + ss << "\n" + << k << ") Failure for" << test_str_names[type] + << vector_size_names[vectorSize] << '.' + << operatorToUse_names[operatorToUse] << " { " + << "0x" << std::setfill('0') << std::setw(elementSize * 2) + << std::hex << i[0]; + + for (size_t j = 1; j < halfVectorSize * 2; j++) ss << ", " << i[j]; + ss << " } --> { " << o[0]; + for (size_t j = 1; j < halfVectorSize; j++) ss << ", " << o[j]; + ss << " }\n"; return -1; - } } i += 2 * halfVectorSize; o += halfVectorSize; - } - } - break; - - case 8: - { - cl_ulong *i = (cl_ulong*)in; - cl_ulong *o = (cl_ulong*)out; - size_t j; - cl_uint k; - - for( k = 0; k < elementCount; k++ ) - { - cl_ulong *o2 = (cl_ulong*)p; - for( j = 0; j < halfVectorSize; j++ ) - o2[j] = i[ f((int)j, (int)halfVectorSize*2) ]; - - if( memcmp( o, o2, elementSize * cmpVectorSize ) ) - { - log_info( "\n%d) Failure for %s%s.%s { 0x%16.16llx", k, test_str_names[type], vector_size_names[ vectorSize ], operatorToUse_names[ operatorToUse ], i[0] ); - for( j = 1; j < halfVectorSize * 2; j++ ) - log_info( ", 0x%16.16llx", i[j] ); - log_info( " } --> { 0x%16.16llx", o[0] ); - for( j = 1; j < halfVectorSize; j++ ) - log_info( ", 0x%16.16llx", o[j] ); - log_info( " }\n" ); - return -1; - } - i += 2 * halfVectorSize; - o += halfVectorSize; - } - } - break; - - default: - log_info( "Internal error. Unknown data type\n" ); - return -2; } - return 0; } +static int CheckResults(void *in, void *out, size_t elementCount, int type, + int vectorSize, int operatorToUse) +{ + size_t cmpVectorSize = vector_sizes[out_vector_idx[vectorSize]]; + size_t elementSize = kSizes[type]; + if (vector_size_names[vectorSize][0] == '3') + { + if (operatorToUse_names[operatorToUse][0] == 'h' + || operatorToUse_names[operatorToUse][0] == 'o') // hi or odd + { + cmpVectorSize = 1; // special case for vec3 ignored values + } + } + switch (elementSize) + { + case 1: + return verify<char>(in, out, elementCount, type, vectorSize, + operatorToUse, cmpVectorSize); + case 2: + return verify<short>(in, out, elementCount, type, vectorSize, + operatorToUse, cmpVectorSize); + case 4: + return verify<int>(in, out, elementCount, type, vectorSize, + operatorToUse, cmpVectorSize); + case 8: + return verify<cl_ulong>(in, out, elementCount, type, vectorSize, + operatorToUse, cmpVectorSize); + default: log_info("Internal error. Unknown data type\n"); return -2; + } +} |