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>
376 lines
11 KiB
C
376 lines
11 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 "structs.h"
|
|
|
|
|
|
#include "defines.h"
|
|
|
|
#define DEBUG_MEM_ALLOC 0
|
|
|
|
/** typedef struct _bufferStruct
|
|
{
|
|
void * m_pIn;
|
|
void * m_pOut;
|
|
|
|
cl_mem m_outBuffer;
|
|
cl_mem m_inBuffer;
|
|
|
|
size_t m_bufSize;
|
|
} bufferStruct;
|
|
*/
|
|
|
|
|
|
clState * newClState(cl_device_id device, cl_context context, cl_command_queue queue)
|
|
{
|
|
clState * pResult = (clState *)malloc(sizeof(clState));
|
|
#if DEBUG_MEM_ALLOC
|
|
log_info("malloc clState * %x\n", pResult);
|
|
#endif
|
|
|
|
pResult->m_device = device;
|
|
pResult->m_context = context;
|
|
pResult->m_queue = queue;
|
|
|
|
pResult->m_kernel = NULL; pResult->m_program = NULL;
|
|
return pResult;
|
|
}
|
|
|
|
clState * destroyClState(clState * pState)
|
|
{
|
|
clStateDestroyProgramAndKernel(pState);
|
|
#if DEBUG_MEM_ALLOC
|
|
log_info("delete (free) clState * %x\n", pState);
|
|
#endif
|
|
free(pState);
|
|
return NULL;
|
|
}
|
|
|
|
|
|
int clStateMakeProgram(clState * pState, const char * prog,
|
|
const char * kernelName)
|
|
{
|
|
const char * srcArr[1] = {NULL};
|
|
srcArr[0] = prog;
|
|
int err = create_single_kernel_helper(pState->m_context,
|
|
&(pState->m_program),
|
|
&(pState->m_kernel),
|
|
1, srcArr, kernelName );
|
|
#if DEBUG_MEM_ALLOC
|
|
log_info("create program and kernel\n");
|
|
#endif
|
|
return err;
|
|
}
|
|
|
|
int runKernel(clState * pState, size_t numThreads) {
|
|
int err;
|
|
pState->m_numThreads = numThreads;
|
|
err = clEnqueueNDRangeKernel(pState->m_queue, pState->m_kernel,
|
|
1, NULL, &(pState->m_numThreads),
|
|
NULL, 0, NULL, NULL);
|
|
if(err != CL_SUCCESS)
|
|
{
|
|
log_error("clEnqueueNDRangeKernel returned %d (%x)\n",
|
|
err, err);
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
void clStateDestroyProgramAndKernel(clState * pState)
|
|
{
|
|
#if DEBUG_MEM_ALLOC
|
|
log_info("destroy program and kernel\n");
|
|
#endif
|
|
if(pState->m_kernel != NULL) {
|
|
clReleaseKernel( pState->m_kernel );
|
|
pState->m_kernel = NULL;
|
|
}
|
|
if(pState->m_program != NULL) {
|
|
clReleaseProgram( pState->m_program );
|
|
pState->m_program = NULL;
|
|
}
|
|
}
|
|
|
|
bufferStruct * newBufferStruct(size_t inSize, size_t outSize, clState * pClState) {
|
|
int error;
|
|
bufferStruct * pResult = (bufferStruct *)malloc(sizeof(bufferStruct));
|
|
#if DEBUG_MEM_ALLOC
|
|
log_info("malloc bufferStruct * %x\n", pResult);
|
|
#endif
|
|
|
|
pResult->m_bufSizeIn = inSize;
|
|
pResult->m_bufSizeOut = outSize;
|
|
|
|
pResult->m_pIn = malloc(inSize);
|
|
pResult->m_pOut = malloc(outSize);
|
|
#if DEBUG_MEM_ALLOC
|
|
log_info("malloc m_pIn %x\n", pResult->m_pIn);
|
|
log_info("malloc m_pOut %x\n", pResult->m_pOut);
|
|
#endif
|
|
|
|
pResult->m_inBuffer = clCreateBuffer(pClState->m_context, CL_MEM_READ_ONLY,
|
|
inSize, NULL, &error);
|
|
if( pResult->m_inBuffer == NULL )
|
|
{
|
|
vlog_error( "clCreateArray failed for input (%d)\n", error );
|
|
return destroyBufferStruct(pResult, pClState);
|
|
}
|
|
#if DEBUG_MEM_ALLOC
|
|
log_info("clCreateBuffer %x\n", pResult->m_inBuffer);
|
|
#endif
|
|
|
|
pResult->m_outBuffer = clCreateBuffer( pClState->m_context,
|
|
CL_MEM_WRITE_ONLY,
|
|
outSize,
|
|
NULL,
|
|
&error );
|
|
if( pResult->m_outBuffer == NULL )
|
|
{
|
|
vlog_error( "clCreateArray failed for output (%d)\n", error );
|
|
return destroyBufferStruct(pResult, pClState);
|
|
}
|
|
#if DEBUG_MEM_ALLOC
|
|
log_info("clCreateBuffer %x\n", pResult->m_outBuffer);
|
|
#endif
|
|
|
|
pResult->m_bufferUploaded = false;
|
|
|
|
return pResult;
|
|
}
|
|
|
|
bufferStruct * destroyBufferStruct(bufferStruct * destroyMe, clState * pClState) {
|
|
if(destroyMe)
|
|
{
|
|
if(destroyMe->m_outBuffer != NULL) {
|
|
#if DEBUG_MEM_ALLOC
|
|
log_info("clReleaseMemObject %x\n", destroyMe->m_outBuffer);
|
|
#endif
|
|
clReleaseMemObject(destroyMe->m_outBuffer);
|
|
destroyMe->m_outBuffer = NULL;
|
|
}
|
|
if(destroyMe->m_inBuffer != NULL) {
|
|
#if DEBUG_MEM_ALLOC
|
|
log_info("clReleaseMemObject %x\n", destroyMe->m_outBuffer);
|
|
#endif
|
|
clReleaseMemObject(destroyMe->m_inBuffer);
|
|
destroyMe->m_inBuffer = NULL;
|
|
}
|
|
if(destroyMe->m_pIn != NULL) {
|
|
#if DEBUG_MEM_ALLOC
|
|
log_info("delete (free) m_pIn %x\n", destroyMe->m_pIn);
|
|
#endif
|
|
free(destroyMe->m_pIn);
|
|
destroyMe->m_pIn = NULL;
|
|
}
|
|
if(destroyMe->m_pOut != NULL) {
|
|
#if DEBUG_MEM_ALLOC
|
|
log_info("delete (free) m_pOut %x\n", destroyMe->m_pOut);
|
|
#endif
|
|
free(destroyMe->m_pOut);
|
|
destroyMe->m_pOut = NULL;
|
|
}
|
|
#if DEBUG_MEM_ALLOC
|
|
log_info("delete (free) bufferStruct * %x\n", destroyMe);
|
|
#endif
|
|
free((void *)destroyMe);
|
|
destroyMe = NULL;
|
|
}
|
|
return destroyMe;
|
|
}
|
|
|
|
void initContents(bufferStruct * pBufferStruct, clState * pClState,
|
|
size_t typeSize,
|
|
size_t countIn, size_t countOut )
|
|
{
|
|
size_t i;
|
|
|
|
uint64_t start = 0;
|
|
|
|
switch(typeSize)
|
|
{
|
|
case 1: {
|
|
uint8_t* ub = (uint8_t *)(pBufferStruct->m_pIn);
|
|
for (i=0; i < countIn; ++i)
|
|
{
|
|
ub[i] = (uint8_t)start++;
|
|
}
|
|
break;
|
|
}
|
|
case 2: {
|
|
uint16_t* us = (uint16_t *)(pBufferStruct->m_pIn);
|
|
for (i=0; i < countIn; ++i)
|
|
{
|
|
us[i] = (uint16_t)start++;
|
|
}
|
|
break;
|
|
}
|
|
case 4: {
|
|
if (!g_wimpyMode) {
|
|
uint32_t* ui = (uint32_t *)(pBufferStruct->m_pIn);
|
|
for (i=0; i < countIn; ++i) {
|
|
ui[i] = (uint32_t)start++;
|
|
}
|
|
}
|
|
else {
|
|
// The short test doesn't iterate over the entire 32 bit space so
|
|
// we alternate between positive and negative values
|
|
int32_t* ui = (int32_t *)(pBufferStruct->m_pIn);
|
|
int32_t sign = 1;
|
|
for (i=0; i < countIn; ++i, ++start) {
|
|
ui[i] = (int32_t)start*sign;
|
|
sign = sign * -1;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 8: {
|
|
// We don't iterate over the entire space of 64 bit so for the
|
|
// selects, we want to test positive and negative values
|
|
int64_t* ll = (int64_t *)(pBufferStruct->m_pIn);
|
|
int64_t sign = 1;
|
|
for (i=0; i < countIn; ++i, ++start) {
|
|
ll[i] = start*sign;
|
|
sign = sign * -1;
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
log_error("invalid type size %x\n", (int)typeSize);
|
|
}
|
|
}
|
|
// pBufferStruct->m_bufSizeIn
|
|
// pBufferStruct->m_bufSizeOut
|
|
}
|
|
|
|
int pushArgs(bufferStruct * pBufferStruct, clState * pClState)
|
|
{
|
|
int err;
|
|
if( !pBufferStruct->m_bufferUploaded )
|
|
{
|
|
err = clEnqueueWriteBuffer(pClState->m_queue, pBufferStruct->m_inBuffer,
|
|
CL_TRUE, 0, pBufferStruct->m_bufSizeIn,
|
|
pBufferStruct->m_pIn, 0, NULL, NULL);
|
|
#if DEBUG_MEM_ALLOC
|
|
log_info("clEnqueueWriteBuffer %x\n", pBufferStruct->m_inBuffer);
|
|
#endif
|
|
if(err != CL_SUCCESS)
|
|
{
|
|
log_error("clEnqueueWriteBuffer failed\n");
|
|
return -1;
|
|
}
|
|
pBufferStruct->m_bufferUploaded = true;
|
|
}
|
|
|
|
err = clSetKernelArg(pClState->m_kernel, 0,
|
|
sizeof(pBufferStruct->m_inBuffer), // pBufferStruct->m_bufSizeIn,
|
|
&(pBufferStruct->m_inBuffer));
|
|
#if DEBUG_MEM_ALLOC
|
|
// log_info("clSetKernelArg 0, %x\n", pBufferStruct->m_inBuffer);
|
|
#endif
|
|
if(err != CL_SUCCESS)
|
|
{
|
|
log_error("clSetKernelArgs failed, first arg (0)\n");
|
|
return -1;
|
|
}
|
|
|
|
err = clSetKernelArg(pClState->m_kernel, 1,
|
|
sizeof(pBufferStruct->m_outBuffer), // pBufferStruct->m_bufSizeOut,
|
|
&(pBufferStruct->m_outBuffer));
|
|
if(err != CL_SUCCESS)
|
|
{
|
|
log_error("clSetKernelArgs failed, second arg (1)\n");
|
|
return -1;
|
|
}
|
|
|
|
#if DEBUG_MEM_ALLOC
|
|
// log_info("clSetKernelArg 0, %x\n", pBufferStruct->m_outBuffer);
|
|
#endif
|
|
|
|
return 0;
|
|
}
|
|
|
|
int retrieveResults(bufferStruct * pBufferStruct, clState * pClState)
|
|
{
|
|
int err;
|
|
err = clEnqueueReadBuffer(pClState->m_queue, pBufferStruct->m_outBuffer,
|
|
CL_TRUE, 0, pBufferStruct->m_bufSizeOut,
|
|
pBufferStruct->m_pOut, 0, NULL, NULL);
|
|
if(err != CL_SUCCESS)
|
|
{
|
|
log_error("clEnqueueReadBuffer failed\n");
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
// vecSizeIdx indexes into g_arrVecAlignMasks, g_arrVecSizeNames
|
|
// and g_arrVecSizes
|
|
int checkCorrectness(bufferStruct * pBufferStruct, clState * pClState,
|
|
size_t minAlign)
|
|
{
|
|
size_t i;
|
|
cl_ulong * targetArr = (cl_ulong *)(pBufferStruct->m_pOut);
|
|
for(i = 0; i < pClState->m_numThreads; ++i)
|
|
{
|
|
if((targetArr[i])%minAlign != (cl_ulong)0)
|
|
{
|
|
vlog_error("Error %ld (of %ld). Expected a multple of %lx, got %llx\n",
|
|
i, pClState->m_numThreads,
|
|
minAlign,
|
|
targetArr[i]);
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
/* log_info("\n");
|
|
for(i = 0; i < 4; ++i) {
|
|
log_info("%lx, ", targetArr[i]);
|
|
}
|
|
log_info("\n");
|
|
fflush(stdout); */
|
|
return 0;
|
|
}
|
|
|
|
|
|
// vecSizeIdx indexes into g_arrVecAlignMasks, g_arrVecSizeNames
|
|
// and g_arrVecSizes
|
|
int checkPackedCorrectness(bufferStruct * pBufferStruct, clState * pClState,
|
|
size_t totSize, size_t beforeSize)
|
|
{
|
|
size_t i;
|
|
cl_ulong * targetArr = (cl_ulong *)(pBufferStruct->m_pOut);
|
|
for(i = 0; i < pClState->m_numThreads; ++i)
|
|
{
|
|
if((targetArr[i]-beforeSize)%totSize != (cl_ulong)0)
|
|
{
|
|
vlog_error("Error %ld (of %ld). Expected %ld more than a multple of %ld, got %lld \n",
|
|
i, pClState->m_numThreads, beforeSize,
|
|
totSize,
|
|
targetArr[i]);
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
/* log_info("\n");
|
|
for(i = 0; i < 4; ++i) {
|
|
log_info("%lx, ", targetArr[i]);
|
|
}
|
|
log_info("\n");
|
|
fflush(stdout); */
|
|
return 0;
|
|
}
|