mirror of
https://github.com/KhronosGroup/OpenCL-CTS.git
synced 2026-03-19 14:09:03 +00:00
The maintenance of the conformance tests is moving to Github. This commit contains all the changes that have been done in Gitlab since the first public release of the conformance tests. Signed-off-by: Kevin Petit <kevin.petit@arm.com>
209 lines
7.4 KiB
C++
209 lines
7.4 KiB
C++
//
|
|
// 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 "testBase.h"
|
|
#include "../../test_common/harness/conversions.h"
|
|
|
|
#define TEST_SIZE 512
|
|
|
|
enum OpKonstants
|
|
{
|
|
kIncrement = 0,
|
|
kDecrement,
|
|
kBoth
|
|
};
|
|
|
|
const char *testKernel =
|
|
"__kernel void test( __global %s *inOut, __global char * control )\n"
|
|
"{\n"
|
|
" size_t tid = get_global_id(0);\n"
|
|
"\n"
|
|
" %s%s inOutVal = %s;\n"
|
|
"\n"
|
|
" if( control[tid] == 0 )\n"
|
|
" inOutVal++;\n"
|
|
" else if( control[tid] == 1 )\n"
|
|
" ++inOutVal;\n"
|
|
" else if( control[tid] == 2 )\n"
|
|
" inOutVal--;\n"
|
|
" else // if( control[tid] == 3 )\n"
|
|
" --inOutVal;\n"
|
|
"\n"
|
|
" %s;\n"
|
|
"}\n";
|
|
|
|
typedef int (*OpVerifyFn)( void * actualPtr, void * inputPtr, size_t vecSize, size_t numVecs, cl_char * controls );
|
|
|
|
int test_unary_op( cl_command_queue queue, cl_context context, OpKonstants whichOp,
|
|
ExplicitType vecType, size_t vecSize,
|
|
MTdata d, OpVerifyFn verifyFn )
|
|
{
|
|
clProgramWrapper program;
|
|
clKernelWrapper kernel;
|
|
clMemWrapper streams[2];
|
|
cl_long inData[TEST_SIZE * 16], outData[TEST_SIZE * 16];
|
|
cl_char controlData[TEST_SIZE];
|
|
int error;
|
|
size_t i;
|
|
size_t threads[1], localThreads[1];
|
|
char kernelSource[10240];
|
|
char *programPtr;
|
|
|
|
|
|
// Create the source
|
|
char loadLine[ 1024 ], storeLine[ 1024 ];
|
|
if( vecSize == 1 )
|
|
{
|
|
sprintf( loadLine, "inOut[tid]" );
|
|
sprintf( storeLine, "inOut[tid] = inOutVal" );
|
|
}
|
|
else
|
|
{
|
|
sprintf( loadLine, "vload%ld( tid, inOut )", vecSize );
|
|
sprintf( storeLine, "vstore%ld( inOutVal, tid, inOut )", vecSize );
|
|
}
|
|
|
|
char sizeNames[][4] = { "", "", "2", "3", "4", "", "", "", "8", "", "", "", "", "", "", "", "16" };
|
|
sprintf( kernelSource, testKernel, get_explicit_type_name( vecType ), /*sizeNames[ vecSize ],*/
|
|
get_explicit_type_name( vecType ), sizeNames[ vecSize ],
|
|
loadLine, storeLine );
|
|
|
|
// Create the kernel
|
|
programPtr = kernelSource;
|
|
if( create_single_kernel_helper( context, &program, &kernel, 1, (const char **)&programPtr, "test" ) )
|
|
{
|
|
log_error( "ERROR: Unable to create test program!\n" );
|
|
return -1;
|
|
}
|
|
|
|
// Generate two streams. The first is our random data to test against, the second is our control stream
|
|
generate_random_data( vecType, vecSize * TEST_SIZE, d, inData );
|
|
streams[0] = clCreateBuffer( context, (cl_mem_flags)(CL_MEM_COPY_HOST_PTR),
|
|
get_explicit_type_size( vecType ) * vecSize * TEST_SIZE,
|
|
inData, &error );
|
|
test_error( error, "Creating input data array failed" );
|
|
|
|
cl_uint bits;
|
|
for( i = 0; i < TEST_SIZE; i++ )
|
|
{
|
|
size_t which = i & 7;
|
|
if( which == 0 )
|
|
bits = genrand_int32(d);
|
|
|
|
controlData[ i ] = ( bits >> ( which << 1 ) ) & 0x03;
|
|
if( whichOp == kDecrement )
|
|
// For sub ops, the min control value is 2. Otherwise, it's 0
|
|
controlData[ i ] |= 0x02;
|
|
else if( whichOp == kIncrement )
|
|
// For addition ops, the MAX control value is 1. Otherwise, it's 3
|
|
controlData[ i ] &= ~0x02;
|
|
}
|
|
streams[1] = clCreateBuffer( context, (cl_mem_flags)(CL_MEM_COPY_HOST_PTR),
|
|
sizeof( controlData ), controlData, &error );
|
|
test_error( error, "Unable to create control stream" );
|
|
|
|
// Assign streams and execute
|
|
error = clSetKernelArg( kernel, 0, sizeof( streams[0] ), &streams[0] );
|
|
test_error( error, "Unable to set indexed kernel arguments" );
|
|
error = clSetKernelArg( kernel, 1, sizeof( streams[1] ), &streams[1] );
|
|
test_error( error, "Unable to set indexed kernel arguments" );
|
|
|
|
|
|
// Run the kernel
|
|
threads[0] = TEST_SIZE;
|
|
|
|
error = get_max_common_work_group_size( context, kernel, threads[0], &localThreads[0] );
|
|
test_error( error, "Unable to get work group size to use" );
|
|
|
|
error = clEnqueueNDRangeKernel( queue, kernel, 1, NULL, threads, localThreads, 0, NULL, NULL );
|
|
test_error( error, "Unable to execute test kernel" );
|
|
|
|
|
|
// Read the results
|
|
error = clEnqueueReadBuffer( queue, streams[0], CL_TRUE, 0,
|
|
get_explicit_type_size( vecType ) * TEST_SIZE * vecSize,
|
|
outData, 0, NULL, NULL );
|
|
test_error( error, "Unable to read output array!" );
|
|
|
|
// Now verify the results
|
|
return verifyFn( outData, inData, vecSize, TEST_SIZE, controlData );
|
|
}
|
|
|
|
template<typename T> int VerifyFn( void * actualPtr, void * inputPtr, size_t vecSize, size_t numVecs, cl_char * controls )
|
|
{
|
|
T * actualData = (T *)actualPtr;
|
|
T * inputData = (T *)inputPtr;
|
|
|
|
size_t index = 0;
|
|
for( size_t i = 0; i < numVecs; i++ )
|
|
{
|
|
for( size_t j = 0; j < vecSize; j++, index++ )
|
|
{
|
|
T nextVal = inputData[ index ];
|
|
if( controls[ i ] & 0x02 )
|
|
nextVal--;
|
|
else
|
|
nextVal++;
|
|
|
|
if( actualData[ index ] != nextVal )
|
|
{
|
|
log_error( "ERROR: Validation failed on vector %ld:%ld (expected %lld, got %lld)", i, j,
|
|
(cl_long)nextVal, (cl_long)actualData[ index ] );
|
|
return -1;
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int test_unary_op_set( cl_command_queue queue, cl_context context, OpKonstants whichOp )
|
|
{
|
|
ExplicitType types[] = { kChar, kUChar, kShort, kUShort, kInt, kUInt, kLong, kULong, kNumExplicitTypes };
|
|
OpVerifyFn verifys[] = { VerifyFn<cl_char>, VerifyFn<cl_uchar>, VerifyFn<cl_short>, VerifyFn<cl_ushort>, VerifyFn<cl_int>, VerifyFn<cl_uint>, VerifyFn<cl_long>, VerifyFn<cl_ulong>, NULL };
|
|
unsigned int vecSizes[] = { 1, 2, 3, 4, 8, 16, 0 };
|
|
unsigned int index, typeIndex;
|
|
int retVal = 0;
|
|
RandomSeed seed(gRandomSeed );
|
|
|
|
for( typeIndex = 0; types[ typeIndex ] != kNumExplicitTypes; typeIndex++ )
|
|
{
|
|
for( index = 0; vecSizes[ index ] != 0; index++ )
|
|
{
|
|
if( test_unary_op( queue, context, whichOp, types[ typeIndex ], vecSizes[ index ], seed, verifys[ typeIndex ] ) != 0 )
|
|
{
|
|
log_error( " Vector %s%d FAILED\n", get_explicit_type_name( types[ typeIndex ] ), vecSizes[ index ] );
|
|
retVal = -1;
|
|
}
|
|
}
|
|
}
|
|
|
|
return retVal;
|
|
}
|
|
|
|
int test_unary_ops_full(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
|
{
|
|
return test_unary_op_set( queue, context, kBoth );
|
|
}
|
|
|
|
int test_unary_ops_increment(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
|
{
|
|
return test_unary_op_set( queue, context, kIncrement );
|
|
}
|
|
|
|
int test_unary_ops_decrement(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
|
{
|
|
return test_unary_op_set( queue, context, kDecrement );
|
|
}
|