You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
895 lines
21 KiB
895 lines
21 KiB
//
|
|
// 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 "harness/compat.h"
|
|
#include "harness/rounding_mode.h"
|
|
#include "harness/kernelHelpers.h"
|
|
|
|
#include "test_printf.h"
|
|
#include <assert.h>
|
|
|
|
// Helpers for generating runtime reference results
|
|
static void intRefBuilder(printDataGenParameters&, char*, const size_t);
|
|
static void floatRefBuilder(printDataGenParameters&, char* rResult, const size_t);
|
|
static void octalRefBuilder(printDataGenParameters&, char*, const size_t);
|
|
static void unsignedRefBuilder(printDataGenParameters&, char*, const size_t);
|
|
static void hexRefBuilder(printDataGenParameters&, char*, const size_t);
|
|
|
|
//==================================
|
|
|
|
// int
|
|
|
|
//==================================
|
|
|
|
//------------------------------------------------------
|
|
|
|
// [string] format | [string] int-data representation |
|
|
|
|
//------------------------------------------------------
|
|
|
|
std::vector<printDataGenParameters> printIntGenParameters = {
|
|
|
|
//(Minimum)Five-wide,default(right)-justified
|
|
|
|
{"%5d","10"},
|
|
|
|
//(Minimum)Five-wide,left-justified
|
|
|
|
{"%-5d","10"},
|
|
|
|
//(Minimum)Five-wide,default(right)-justified,zero-filled
|
|
|
|
{"%05d","10"},
|
|
|
|
//(Minimum)Five-wide,default(right)-justified,with sign
|
|
|
|
{"%+5d","10"},
|
|
|
|
//(Minimum)Five-wide ,left-justified,with sign
|
|
|
|
{"%-+5d","10"},
|
|
|
|
//(Minimum)Five-digit(zero-filled in absent digits),default(right)-justified
|
|
|
|
{"%.5i","100"},
|
|
|
|
//(Minimum)Six-wide,Five-digit(zero-filled in absent digits),default(right)-justified
|
|
|
|
{"%6.5i","100"},
|
|
|
|
//0 and - flag both apper ==>0 is ignored,left-justified,capital I
|
|
|
|
{"%-06i","100"},
|
|
|
|
//(Minimum)Six-wide,Five-digit(zero-filled in absent digits),default(right)-justified
|
|
|
|
{"%06.5i","100"}
|
|
|
|
};
|
|
|
|
//-----------------------------------------------
|
|
|
|
//test case for int |
|
|
|
|
//-----------------------------------------------
|
|
|
|
testCase testCaseInt = {
|
|
|
|
TYPE_INT,
|
|
|
|
correctBufferInt,
|
|
|
|
printIntGenParameters,
|
|
|
|
intRefBuilder,
|
|
|
|
kint
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
//==============================================
|
|
|
|
// float
|
|
|
|
//==============================================
|
|
|
|
|
|
|
|
//--------------------------------------------------------
|
|
|
|
// [string] format | [string] float-data representation |
|
|
|
|
//--------------------------------------------------------
|
|
|
|
std::vector<printDataGenParameters> printFloatGenParameters = {
|
|
|
|
//Default(right)-justified
|
|
|
|
{"%f","10.3456"},
|
|
|
|
//One position after the decimal,default(right)-justified
|
|
|
|
{"%.1f","10.3456"},
|
|
|
|
//Two positions after the decimal,default(right)-justified
|
|
|
|
{"%.2f","10.3456"},
|
|
|
|
//(Minimum)Eight-wide,three positions after the decimal,default(right)-justified
|
|
|
|
{"%8.3f","10.3456"},
|
|
|
|
//(Minimum)Eight-wide,two positions after the decimal,zero-filled,default(right)-justified
|
|
|
|
{"%08.2f","10.3456"},
|
|
|
|
//(Minimum)Eight-wide,two positions after the decimal,left-justified
|
|
|
|
{"%-8.2f","10.3456"},
|
|
|
|
//(Minimum)Eight-wide,two positions after the decimal,with sign,default(right)-justified
|
|
|
|
{"%+8.2f","-10.3456"},
|
|
|
|
//Zero positions after the decimal([floor]rounding),default(right)-justified
|
|
|
|
{"%.0f","0.1"},
|
|
|
|
//Zero positions after the decimal([ceil]rounding),default(right)-justified
|
|
|
|
{"%.0f","0.6"},
|
|
|
|
//Zero-filled,default positions number after the decimal,default(right)-justified
|
|
|
|
{"%0f","0.6"},
|
|
|
|
//Double argument representing floating-point,used by f style,default(right)-justified
|
|
|
|
{"%4g","12345.6789"},
|
|
|
|
//Double argument representing floating-point,used by e style,default(right)-justified
|
|
|
|
{"%4.2g","12345.6789"},
|
|
|
|
//Double argument representing floating-point,used by f style,default(right)-justified
|
|
|
|
{"%4G","0.0000023"},
|
|
|
|
//Double argument representing floating-point,used by e style,default(right)-justified
|
|
|
|
{"%4G","0.023"},
|
|
|
|
//Double argument representing floating-point,with exponent,left-justified,default(right)-justified
|
|
|
|
{"%-#20.15e","789456123.0"},
|
|
|
|
//Double argument representing floating-point,with exponent,left-justified,with sign,capital E,default(right)-justified
|
|
|
|
{"%+#21.15E","789456123.0"},
|
|
|
|
//Double argument representing floating-point,in [-]xh.hhhhpAd style
|
|
|
|
{"%.6a","0.1"},
|
|
|
|
//(Minimum)Ten-wide,Double argument representing floating-point,in xh.hhhhpAd style,default(right)-justified
|
|
|
|
{"%10.2a","9990.235"},
|
|
};
|
|
|
|
//---------------------------------------------------------
|
|
|
|
//Test case for float |
|
|
|
|
//---------------------------------------------------------
|
|
|
|
testCase testCaseFloat = {
|
|
|
|
TYPE_FLOAT,
|
|
|
|
correctBufferFloat,
|
|
|
|
printFloatGenParameters,
|
|
|
|
floatRefBuilder,
|
|
|
|
kfloat
|
|
|
|
};
|
|
|
|
//==============================================
|
|
|
|
// float limits
|
|
|
|
//==============================================
|
|
|
|
|
|
|
|
//--------------------------------------------------------
|
|
|
|
// [string] format | [string] float-data representation |
|
|
|
|
//--------------------------------------------------------
|
|
|
|
|
|
std::vector<printDataGenParameters> printFloatLimitsGenParameters = {
|
|
|
|
//Infinity (1.0/0.0)
|
|
|
|
{"%f","1.0f/0.0f"},
|
|
|
|
//NaN
|
|
|
|
{"%f","sqrt(-1.0f)"},
|
|
|
|
//NaN
|
|
{"%f","acospi(2.0f)"}
|
|
};
|
|
//--------------------------------------------------------
|
|
|
|
// Lookup table - [string]float-correct buffer |
|
|
|
|
//--------------------------------------------------------
|
|
|
|
std::vector<std::string> correctBufferFloatLimits = {
|
|
|
|
"inf",
|
|
|
|
"-nan",
|
|
|
|
"nan"
|
|
};
|
|
|
|
//---------------------------------------------------------
|
|
|
|
//Test case for float |
|
|
|
|
//---------------------------------------------------------
|
|
|
|
testCase testCaseFloatLimits = {
|
|
|
|
TYPE_FLOAT_LIMITS,
|
|
|
|
correctBufferFloatLimits,
|
|
|
|
printFloatLimitsGenParameters,
|
|
|
|
NULL
|
|
|
|
};
|
|
|
|
//=========================================================
|
|
|
|
// octal
|
|
|
|
//=========================================================
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// [string] format | [string] octal-data representation |
|
|
|
|
//---------------------------------------------------------
|
|
|
|
std::vector<printDataGenParameters> printOctalGenParameters = {
|
|
|
|
//Default(right)-justified
|
|
|
|
{"%o","10"},
|
|
|
|
//Five-digit,default(right)-justified
|
|
|
|
{"%.5o","10"},
|
|
|
|
//Default(right)-justified,increase precision
|
|
|
|
{"%#o","100000000"},
|
|
|
|
//(Minimum)Four-wide,Five-digit,0-flag ignored(because of precision),default(right)-justified
|
|
|
|
{"%04.5o","10"}
|
|
|
|
};
|
|
|
|
//-------------------------------------------------------
|
|
|
|
//Test case for octal |
|
|
|
|
//-------------------------------------------------------
|
|
|
|
testCase testCaseOctal = {
|
|
|
|
TYPE_OCTAL,
|
|
|
|
correctBufferOctal,
|
|
|
|
printOctalGenParameters,
|
|
|
|
octalRefBuilder,
|
|
|
|
kulong
|
|
|
|
};
|
|
|
|
|
|
|
|
//=========================================================
|
|
|
|
// unsigned
|
|
|
|
//=========================================================
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// [string] format | [string] unsined-data representation |
|
|
|
|
//---------------------------------------------------------
|
|
|
|
std::vector<printDataGenParameters> printUnsignedGenParameters = {
|
|
|
|
//Default(right)-justified
|
|
|
|
{"%u","10"},
|
|
|
|
//Zero precision for zero,default(right)-justified
|
|
|
|
{"%.0u","0"},
|
|
|
|
};
|
|
|
|
//-------------------------------------------------------
|
|
|
|
//Test case for octal |
|
|
|
|
//-------------------------------------------------------
|
|
|
|
testCase testCaseUnsigned = {
|
|
|
|
TYPE_UNSIGNED,
|
|
|
|
correctBufferUnsigned,
|
|
|
|
printUnsignedGenParameters,
|
|
|
|
unsignedRefBuilder,
|
|
|
|
kulong
|
|
|
|
};
|
|
|
|
|
|
|
|
//=======================================================
|
|
|
|
// hexadecimal
|
|
|
|
//=======================================================
|
|
|
|
|
|
|
|
//--------------------------------------------------------------
|
|
|
|
// [string] format | [string] hexadecimal-data representation |
|
|
|
|
//--------------------------------------------------------------
|
|
|
|
std::vector<printDataGenParameters> printHexadecimalGenParameters = {
|
|
|
|
//Add 0x,low x,default(right)-justified
|
|
|
|
{"%#x","0xABCDEF"},
|
|
|
|
//Add 0x,capital X,default(right)-justified
|
|
|
|
{"%#X","0xABCDEF"},
|
|
|
|
//Not add 0x,if zero,default(right)-justified
|
|
|
|
{"%#X","0"},
|
|
|
|
//(Minimum)Eight-wide,default(right)-justified
|
|
|
|
{"%8x","399"},
|
|
|
|
//(Minimum)Four-wide,zero-filled,default(right)-justified
|
|
|
|
{"%04x","399"}
|
|
|
|
};
|
|
|
|
//--------------------------------------------------------------
|
|
|
|
//Test case for hexadecimal |
|
|
|
|
//--------------------------------------------------------------
|
|
|
|
testCase testCaseHexadecimal = {
|
|
|
|
TYPE_HEXADEC,
|
|
|
|
correctBufferHexadecimal,
|
|
|
|
printHexadecimalGenParameters,
|
|
|
|
hexRefBuilder,
|
|
|
|
kulong
|
|
|
|
};
|
|
|
|
|
|
|
|
//=============================================================
|
|
|
|
// char
|
|
|
|
//=============================================================
|
|
|
|
|
|
|
|
//-----------------------------------------------------------
|
|
|
|
// [string] format | [string] string-data representation |
|
|
|
|
//-----------------------------------------------------------
|
|
|
|
std::vector<printDataGenParameters> printCharGenParameters = {
|
|
|
|
//Four-wide,zero-filled,default(right)-justified
|
|
|
|
{"%4c","\'1\'"},
|
|
|
|
//Four-wide,left-justified
|
|
|
|
{"%-4c","\'1\'"},
|
|
|
|
//(unsigned) int argument,default(right)-justified
|
|
|
|
{"%c","66"}
|
|
|
|
};
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// Lookup table -[string] char-correct buffer |
|
|
|
|
//---------------------------------------------------------
|
|
|
|
std::vector<std::string> correctBufferChar = {
|
|
|
|
" 1",
|
|
|
|
"1 ",
|
|
|
|
"B",
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------
|
|
|
|
//Test case for char |
|
|
|
|
//----------------------------------------------------------
|
|
|
|
testCase testCaseChar = {
|
|
|
|
TYPE_CHAR,
|
|
|
|
correctBufferChar,
|
|
|
|
printCharGenParameters,
|
|
|
|
NULL,
|
|
|
|
kchar
|
|
|
|
};
|
|
|
|
|
|
|
|
//==========================================================
|
|
|
|
// string
|
|
|
|
//==========================================================
|
|
|
|
|
|
|
|
//--------------------------------------------------------
|
|
|
|
// [string]format | [string] string-data representation |
|
|
|
|
//--------------------------------------------------------
|
|
|
|
std::vector<printDataGenParameters> printStringGenParameters = {
|
|
|
|
//(Minimum)Four-wide,zero-filled,default(right)-justified
|
|
|
|
{"%4s","\"foo\""},
|
|
|
|
//One-digit(precision ignored),left-justified
|
|
|
|
{"%.1s","\"foo\""},
|
|
|
|
//%% specification
|
|
|
|
{"%s","\"%%\""},
|
|
};
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// Lookup table -[string] string-correct buffer |
|
|
|
|
//---------------------------------------------------------
|
|
|
|
std::vector<std::string> correctBufferString = {
|
|
|
|
" foo",
|
|
|
|
"f",
|
|
|
|
"%%",
|
|
};
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
//Test case for string |
|
|
|
|
//---------------------------------------------------------
|
|
|
|
testCase testCaseString = {
|
|
|
|
TYPE_STRING,
|
|
|
|
correctBufferString,
|
|
|
|
printStringGenParameters,
|
|
|
|
NULL,
|
|
|
|
kchar
|
|
|
|
};
|
|
|
|
|
|
|
|
//=========================================================
|
|
|
|
// vector
|
|
|
|
//=========================================================
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------------------------------------------------
|
|
|
|
//[string] flag | [string] specifier | [string] type | [string] vector-data representation | [string] vector size |
|
|
|
|
//-------------------------------------------------------------------------------------------------------------------
|
|
|
|
std::vector<printDataGenParameters> printVectorGenParameters = {
|
|
|
|
//(Minimum)Two-wide,two positions after decimal
|
|
|
|
{NULL,"(1.0f,2.0f,3.0f,4.0f)","%2.2","hlf","float","4"},
|
|
|
|
//Alternative form,uchar argument
|
|
|
|
{NULL,"(0xFA,0xFB)","%#","hhx","uchar","2"},
|
|
|
|
//Alternative form,ushort argument
|
|
|
|
{NULL,"(0x1234,0x8765)","%#","hx","ushort","2"},
|
|
|
|
//Alternative form,uint argument
|
|
|
|
{NULL,"(0x12345678,0x87654321)","%#","hlx","uint","2"},
|
|
|
|
//Alternative form,long argument
|
|
|
|
{NULL,"(12345678,98765432)","%","ld","long","2"}
|
|
|
|
};
|
|
|
|
//------------------------------------------------------------
|
|
|
|
// Lookup table -[string] vector-correct buffer |
|
|
|
|
//------------------------------------------------------------
|
|
|
|
std::vector<std::string> correctBufferVector = {
|
|
|
|
"1.00,2.00,3.00,4.00",
|
|
|
|
"0xfa,0xfb",
|
|
|
|
"0x1234,0x8765",
|
|
|
|
"0x12345678,0x87654321",
|
|
|
|
"12345678,98765432"
|
|
|
|
};
|
|
|
|
//-----------------------------------------------------------
|
|
|
|
//Test case for vector |
|
|
|
|
//-----------------------------------------------------------
|
|
|
|
testCase testCaseVector = {
|
|
|
|
TYPE_VECTOR,
|
|
|
|
correctBufferVector,
|
|
|
|
printVectorGenParameters,
|
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
|
|
|
//==================================================================
|
|
|
|
// address space
|
|
|
|
//==================================================================
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
// [string] argument type qualifier |[string] variable type qualifier + initialization | [string] format | [string] parameter |[string]%p indicator/additional code |
|
|
|
|
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
std::vector<printDataGenParameters> printAddrSpaceGenParameters = {
|
|
|
|
//Global memory region
|
|
|
|
{"\"%d\\n\"",NULL,NULL,NULL,NULL,NULL,"__global int* x","","*x",""},
|
|
|
|
//Global,constant, memory region
|
|
|
|
{"\"%d\\n\"",NULL,NULL,NULL,NULL,NULL,"constant int* x","","*x",""},
|
|
|
|
//Local memory region
|
|
|
|
{"\"%+d\\n\"",NULL,NULL,NULL,NULL,NULL,"","local int x;\n x= (int)3;\n","x",""},
|
|
|
|
//Private memory region
|
|
|
|
{"\"%i\\n\"",NULL,NULL,NULL,NULL,NULL,"","private int x;\n x = (int)-1;\n","x",""},
|
|
|
|
//Address of void * from global memory region
|
|
|
|
{"\"%p\\n\"",NULL,NULL,NULL,NULL,NULL,"__global void* x,__global intptr_t* xAddr","","x","*xAddr = (intptr_t)x;\n"}
|
|
|
|
};
|
|
|
|
//-------------------------------------------------------------------------------
|
|
|
|
// Lookup table -[string] address space -correct buffer |
|
|
|
|
//-------------------------------------------------------------------------------
|
|
|
|
std::vector<std::string> correctAddrSpace = {
|
|
|
|
"2","2","+3","-1",""
|
|
|
|
};
|
|
|
|
//-------------------------------------------------------------------------------
|
|
|
|
//Test case for address space |
|
|
|
|
//-------------------------------------------------------------------------------
|
|
|
|
testCase testCaseAddrSpace = {
|
|
|
|
TYPE_ADDRESS_SPACE,
|
|
|
|
correctAddrSpace,
|
|
|
|
printAddrSpaceGenParameters,
|
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------------
|
|
|
|
//All Test cases |
|
|
|
|
//-------------------------------------------------------------------------------
|
|
|
|
std::vector<testCase*> allTestCase = {&testCaseInt,&testCaseFloat,&testCaseFloatLimits,&testCaseOctal,&testCaseUnsigned,&testCaseHexadecimal,&testCaseChar,&testCaseString,&testCaseVector,&testCaseAddrSpace};
|
|
|
|
|
|
//-----------------------------------------
|
|
|
|
// Check functions
|
|
|
|
//-----------------------------------------
|
|
|
|
size_t verifyOutputBuffer(char *analysisBuffer,testCase* pTestCase,size_t testId,cl_ulong pAddr)
|
|
{
|
|
int terminatePos = strlen(analysisBuffer);
|
|
if(terminatePos > 0)
|
|
{
|
|
analysisBuffer[terminatePos - 1] = '\0';
|
|
}
|
|
|
|
//Convert analysis buffer to long for address space
|
|
if(pTestCase->_type == TYPE_ADDRESS_SPACE && strcmp(pTestCase->_genParameters[testId].addrSpacePAdd,""))
|
|
|
|
{
|
|
char analysisBufferTmp[ANALYSIS_BUFFER_SIZE];
|
|
|
|
if(strstr(analysisBuffer,"0x") == NULL)
|
|
// Need to prepend 0x to ASCII number before calling strtol.
|
|
strcpy(analysisBufferTmp,"0x");
|
|
|
|
else analysisBufferTmp[0]='\0';
|
|
strcat(analysisBufferTmp,analysisBuffer);
|
|
if (sizeof(long) == 8) {
|
|
if(strtoul(analysisBufferTmp,NULL,0) == pAddr) return 0;
|
|
}
|
|
else {
|
|
if(strtoull(analysisBufferTmp,NULL,0) == pAddr) return 0;
|
|
}
|
|
return 1;
|
|
|
|
}
|
|
|
|
char* exp;
|
|
//Exponenent representation
|
|
if((exp = strstr(analysisBuffer,"E+")) != NULL || (exp = strstr(analysisBuffer,"e+")) != NULL || (exp = strstr(analysisBuffer,"E-")) != NULL || (exp = strstr(analysisBuffer,"e-")) != NULL)
|
|
{
|
|
char correctExp[3]={0};
|
|
strncpy(correctExp,exp,2);
|
|
|
|
char* eCorrectBuffer = strstr((char*)pTestCase->_correctBuffer[testId].c_str(),correctExp);
|
|
if(eCorrectBuffer == NULL)
|
|
return 1;
|
|
|
|
eCorrectBuffer+=2;
|
|
exp += 2;
|
|
|
|
//Exponent always contains at least two digits
|
|
if(strlen(exp) < 2)
|
|
return 1;
|
|
//Skip leading zeros in the exponent
|
|
while(*exp == '0')
|
|
++exp;
|
|
while(*eCorrectBuffer == '0')
|
|
++eCorrectBuffer;
|
|
return strcmp(eCorrectBuffer,exp);
|
|
}
|
|
if(!strcmp(pTestCase->_correctBuffer[testId].c_str(),"inf"))
|
|
return strcmp(analysisBuffer,"inf")&&strcmp(analysisBuffer,"infinity")&&strcmp(analysisBuffer,"1.#INF00")&&strcmp(analysisBuffer,"Inf");
|
|
if(!strcmp(pTestCase->_correctBuffer[testId].c_str(),"nan") || !strcmp(pTestCase->_correctBuffer[testId].c_str(),"-nan")) {
|
|
return strcmp(analysisBuffer,"nan")&&strcmp(analysisBuffer,"-nan")&&strcmp(analysisBuffer,"1.#IND00")&&strcmp(analysisBuffer,"-1.#IND00")&&strcmp(analysisBuffer,"NaN")&&strcmp(analysisBuffer,"nan(ind)")&&strcmp(analysisBuffer,"nan(snan)")&&strcmp(analysisBuffer,"-nan(ind)");
|
|
}
|
|
return strcmp(analysisBuffer,pTestCase->_correctBuffer[testId].c_str());
|
|
}
|
|
|
|
static void intRefBuilder(printDataGenParameters& params, char* refResult, const size_t refSize)
|
|
{
|
|
snprintf(refResult, refSize, params.genericFormat, atoi(params.dataRepresentation));
|
|
}
|
|
|
|
static void floatRefBuilder(printDataGenParameters& params, char* refResult, const size_t refSize)
|
|
{
|
|
snprintf(refResult, refSize, params.genericFormat, strtof(params.dataRepresentation, NULL));
|
|
}
|
|
|
|
static void octalRefBuilder(printDataGenParameters& params, char* refResult, const size_t refSize)
|
|
{
|
|
const unsigned long int data = strtoul(params.dataRepresentation, NULL, 10);
|
|
snprintf(refResult, refSize, params.genericFormat, data);
|
|
}
|
|
|
|
static void unsignedRefBuilder(printDataGenParameters& params, char* refResult, const size_t refSize)
|
|
{
|
|
const unsigned long int data = strtoul(params.dataRepresentation, NULL, 10);
|
|
snprintf(refResult, refSize, params.genericFormat, data);
|
|
}
|
|
|
|
static void hexRefBuilder(printDataGenParameters& params, char* refResult, const size_t refSize)
|
|
{
|
|
const unsigned long int data = strtoul(params.dataRepresentation, NULL, 0);
|
|
snprintf(refResult, refSize, params.genericFormat, data);
|
|
}
|
|
|
|
/*
|
|
Generate reference results.
|
|
|
|
Results are only generated for test cases
|
|
that can easily be generated by using CPU
|
|
printf.
|
|
|
|
If that is not the case, results are constants
|
|
that have been hard-coded.
|
|
*/
|
|
void generateRef(const cl_device_id device)
|
|
{
|
|
int fd = -1;
|
|
char _refBuffer[ANALYSIS_BUFFER_SIZE];
|
|
const cl_device_fp_config fpConfig = get_default_rounding_mode(device);
|
|
const RoundingMode hostRound = get_round();
|
|
RoundingMode deviceRound;
|
|
|
|
// Map device rounding to CTS rounding type
|
|
// get_default_rounding_mode supports RNE and RTZ
|
|
if (fpConfig == CL_FP_ROUND_TO_NEAREST)
|
|
{
|
|
deviceRound = kRoundToNearestEven;
|
|
}
|
|
else if (fpConfig == CL_FP_ROUND_TO_ZERO)
|
|
{
|
|
deviceRound = kRoundTowardZero;
|
|
}
|
|
else
|
|
{
|
|
assert(false && "Unreachable");
|
|
}
|
|
|
|
// Loop through all test cases
|
|
for (auto &caseToTest: allTestCase)
|
|
{
|
|
/*
|
|
Cases that have a NULL function pointer
|
|
already have their reference results
|
|
as they're constant and hard-coded
|
|
*/
|
|
if (caseToTest->printFN == NULL)
|
|
continue;
|
|
|
|
// Make sure the reference result is empty
|
|
assert(caseToTest->_correctBuffer.size() == 0);
|
|
|
|
// Loop through each input
|
|
for (auto ¶ms: caseToTest->_genParameters)
|
|
{
|
|
char refResult[ANALYSIS_BUFFER_SIZE];
|
|
// Set CPU rounding mode to match that of the device
|
|
set_round(deviceRound, caseToTest->dataType);
|
|
// Generate the result
|
|
caseToTest->printFN(params, refResult, ARRAY_SIZE(refResult));
|
|
// Restore the original CPU rounding mode
|
|
set_round(hostRound, kfloat);
|
|
// Save the reference result
|
|
caseToTest->_correctBuffer.push_back(refResult);
|
|
}
|
|
}
|
|
}
|