Initial open source release of OpenCL 2.0 CTS.

This commit is contained in:
Kedar Patil
2017-05-16 18:50:35 +05:30
parent 6911ba5116
commit 3a440d17c8
883 changed files with 318212 additions and 0 deletions

View File

@@ -0,0 +1,21 @@
set(MODULE_NAME VECALIGN)
set(${MODULE_NAME}_SOURCES
globals.c
main.c
structs.c
test_vec_align.c
type_replacer.c
../../test_common/harness/testHarness.c
../../test_common/harness/mt19937.c
../../test_common/harness/msvc9.c
../../test_common/harness/kernelHelpers.c
../../test_common/harness/errorHelpers.c
../../test_common/harness/conversions.c
)
set_source_files_properties(
COMPILE_FLAGS -msse2)
include(../CMakeCommon.txt)

View File

@@ -0,0 +1,19 @@
project
: requirements
-<library>/harness//harness <use>/harness//harness
# <toolset>gcc:<cflags>-xc
<toolset>msvc:<cflags>"/TP"
;
exe test_step
: test_step.c
globals.c
main.c
/harness//mt19937.c
;
install dist
: test_step
: <variant>debug:<location>$(DIST)/debug/tests/test_conformance/vec_step
<variant>release:<location>$(DIST)/release/tests/test_conformance/vec_step
;

View File

@@ -0,0 +1,46 @@
ifdef BUILD_WITH_ATF
ATF = -framework ATF
USE_ATF = -DUSE_ATF
endif
SRCS = main.c \
structs.c \
test_vec_align.c \
globals.c \
type_replacer.c \
../../test_common/harness/errorHelpers.c \
../../test_common/harness/threadTesting.c \
../../test_common/harness/testHarness.c \
../../test_common/harness/kernelHelpers.c \
../../test_common/harness/mt19937.c \
../../test_common/harness/conversions.c
DEFINES =
SOURCES = $(abspath $(SRCS))
LIBPATH += -L/System/Library/Frameworks/OpenCL.framework/Libraries
LIBPATH += -L.
FRAMEWORK = $(SOURCES)
HEADERS =
TARGET = test_vecalign
INCLUDE =
COMPILERFLAGS = -c -Wall -g -Wshorten-64-to-32 -Os
CC = c++
CFLAGS = $(COMPILERFLAGS) ${RC_CFLAGS} ${USE_ATF} $(DEFINES:%=-D%) $(INCLUDE)
CXXFLAGS = $(COMPILERFLAGS) ${RC_CFLAGS} ${USE_ATF} $(DEFINES:%=-D%) $(INCLUDE)
LIBRARIES = -framework OpenCL -framework OpenGL -framework GLUT -framework AppKit ${ATF}
OBJECTS := ${SOURCES:.c=.o}
OBJECTS := ${OBJECTS:.cpp=.o}
TARGETOBJECT =
all: $(TARGET)
$(TARGET): $(OBJECTS)
$(CC) $(RC_CFLAGS) $(OBJECTS) -o $@ $(LIBPATH) $(LIBRARIES)
clean:
rm -f $(TARGET) $(OBJECTS)
.DEFAULT:
@echo The target \"$@\" does not exist in Makefile.

View File

@@ -0,0 +1,42 @@
//
// 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 "../../test_common/harness/errorHelpers.h"
#include "../../test_common/harness/kernelHelpers.h"
#include "../../test_common/harness/threadTesting.h"
#include "../../test_common/harness/typeWrappers.h"
#include "../../test_common/harness/conversions.h"
#include "../../test_common/harness/mt19937.h"
// 1,2,3,4,8,16 or
// 1,2,4,8,16,3
#define NUM_VECTOR_SIZES 6
extern int g_arrVecSizes[NUM_VECTOR_SIZES];
extern int g_arrVecSteps[NUM_VECTOR_SIZES];
extern bool g_wimpyMode;
extern const char * g_arrVecSizeNames[NUM_VECTOR_SIZES];
extern size_t g_arrVecAlignMasks[NUM_VECTOR_SIZES];
// Define the buffer size that we want to block our test with
#define BUFFER_SIZE (1024*1024)
#define KPAGESIZE 4096
extern ExplicitType types[];
extern const char *g_arrTypeNames[];
extern const size_t g_arrTypeSizes[];

View File

@@ -0,0 +1,59 @@
//
// 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 "defines.h"
// 1,2,3,4,8,16 or
// 1,2,4,8,16,3
int g_arrVecSizes[NUM_VECTOR_SIZES] = {1,2,3,4,8,16};
int g_arrVecSteps[NUM_VECTOR_SIZES] = {1,2,4,4,8,16};
const char * g_arrVecSizeNames[NUM_VECTOR_SIZES] = {"", "2","3","4","8","16"};
size_t g_arrVecAlignMasks[NUM_VECTOR_SIZES] = {(size_t)0,
(size_t)0x1, // 2
(size_t)0x3, // 3
(size_t)0x3, // 4
(size_t)0x7, // 8
(size_t)0xf // 16
};
bool g_wimpyMode = false;
ExplicitType types[] = { kChar, kUChar,
kShort, kUShort,
kInt, kUInt,
kLong, kULong,
kFloat, kDouble,
kNumExplicitTypes };
const char *g_arrTypeNames[] =
{
"char", "uchar",
"short", "ushort",
"int", "uint",
"long", "ulong",
"float", "double"
};
extern const size_t g_arrTypeSizes[] =
{
1, 1,
2, 2,
4, 4,
8, 8,
4, 8
};

View File

@@ -0,0 +1,57 @@
//
// 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 "../../test_common/harness/compat.h"
#include <stdio.h>
#include <string.h>
#include "procs.h"
#include "../../test_common/harness/testHarness.h"
#if !defined(_WIN32)
#include <unistd.h>
#endif
basefn basefn_list[] = {
test_vec_align_array,
test_vec_align_struct,
test_vec_align_packed_struct,
test_vec_align_struct_arr,
test_vec_align_packed_struct_arr
};
const char *basefn_names[] = {
"vec_align_array",
"vec_align_struct",
"vec_align_packed_struct",
"vec_align_struct_arr",
"vec_align_packed_struct_arr",
};
ct_assert((sizeof(basefn_names) / sizeof(basefn_names[0])) == (sizeof(basefn_list) / sizeof(basefn_list[0])));
int num_fns = sizeof(basefn_names) / sizeof(char *);
int main(int argc, const char *argv[])
{
return runTestHarness( argc, argv, num_fns, basefn_list, basefn_names, false, false, 0 );
}

View File

@@ -0,0 +1,39 @@
//
// 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 "../../test_common/harness/errorHelpers.h"
#include "../../test_common/harness/kernelHelpers.h"
#include "../../test_common/harness/threadTesting.h"
#include "../../test_common/harness/typeWrappers.h"
#include "../../test_common/harness/conversions.h"
#include "../../test_common/harness/mt19937.h"
// The number of errors to print out for each test in the shuffle tests
#define MAX_ERRORS_TO_PRINT 1
extern int create_program_and_kernel(const char *source, const char *kernel_name, cl_program *program_ret, cl_kernel *kernel_ret);
int test_vec_align_array(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
int test_vec_align_struct(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
int test_vec_align_packed_struct(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
int test_vec_align_struct_arr(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
int test_vec_align_packed_struct_arr(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);

View File

@@ -0,0 +1,375 @@
//
// 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_uint * targetArr = (cl_uint *)(pBufferStruct->m_pOut);
for(i = 0; i < pClState->m_numThreads; ++i)
{
if((targetArr[i])%minAlign != (cl_uint)0)
{
vlog_error("Error %d (of %d). Expected a multple of %x, got %x\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_uint * targetArr = (cl_uint *)(pBufferStruct->m_pOut);
for(i = 0; i < pClState->m_numThreads; ++i)
{
if((targetArr[i]-beforeSize)%totSize != (cl_uint)0)
{
vlog_error("Error %d (of %d). Expected %d more than a multple of %d, got %d \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;
}

View File

@@ -0,0 +1,73 @@
//
// 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"
#include "../../test_common/harness/typeWrappers.h"
typedef struct _clState
{
cl_device_id m_device;
cl_context m_context;
cl_command_queue m_queue;
cl_program m_program;
cl_kernel m_kernel;
size_t m_numThreads;
} clState;
clState * newClState(cl_device_id device, cl_context context, cl_command_queue queue);
clState * destroyClState(clState * pState);
int clStateMakeProgram(clState * pState, const char * prog,
const char * kernelName);
void clStateDestroyProgramAndKernel(clState * pState);
int runKernel(clState * pState, size_t numThreads);
typedef struct _bufferStruct
{
void * m_pIn;
void * m_pOut;
cl_mem m_outBuffer;
cl_mem m_inBuffer;
size_t m_bufSizeIn, m_bufSizeOut;
int m_bufferUploaded;
} bufferStruct;
bufferStruct * newBufferStruct(size_t inSize, size_t outSize, clState * pClState);
bufferStruct * destroyBufferStruct(bufferStruct * destroyMe, clState * pClState);
void initContents(bufferStruct * pBufferStruct, clState * pClState,
size_t typeSize,
size_t vecWidth);
int pushArgs(bufferStruct * pBufferStruct, clState * pClState);
int retrieveResults(bufferStruct * pBufferStruct, clState * pClState);
// vecSizeIdx indexes into g_arrVecAlignMasks, g_arrVecSizeNames
// and g_arrVecSizes
int checkCorrectness(bufferStruct * pBufferStruct, clState * pClState,
size_t minAlign);
int checkPackedCorrectness(bufferStruct * pBufferStruct, clState * pClState,
size_t totSize, size_t beforeSize);

View File

@@ -0,0 +1,28 @@
//
// 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.
//
#ifndef _testBase_h
#define _testBase_h
#include "../../test_common/harness/compat.h"
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "procs.h"
#endif // _testBase_h

View File

@@ -0,0 +1,545 @@
//
// 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"
#include "../../test_common/harness/typeWrappers.h"
#include "../../test_common/harness/testHarness.h"
#include "structs.h"
#include "defines.h"
#include "type_replacer.h"
size_t get_align(size_t vecSize)
{
if(vecSize == 3)
{
return 4;
}
return vecSize;
}
/* // Lots of conditionals means this is not gonna be an optimal min on intel. */
/* // That's okay, make sure we only call a few times per test, not for every */
/* // element */
/* size_t min_of_nonzero(size_t a, size_t b) */
/* { */
/* if(a != 0 && (a<=b || b==0)) */
/* { */
/* return a; */
/* } */
/* if(b != 0 && (b<a || a==0)) */
/* { */
/* return b; */
/* } */
/* return 0; */
/* } */
/* size_t get_min_packed_alignment(size_t preSize, size_t typeMultiplePreSize, */
/* size_t postSize, size_t typeMultiplePostSize, */
/* ExplicitType kType, size_t vecSize) */
/* { */
/* size_t pre_min = min_of_nonzero(preSize, */
/* typeMultiplePreSize* */
/* get_explicit_type_size(kType)); */
/* size_t post_min = min_of_nonzero(postSize, */
/* typeMultiplePostSize* */
/* get_explicit_type_size(kType)); */
/* size_t struct_min = min_of_nonzero(pre_min, post_min); */
/* size_t result = min_of_nonzero(struct_min, get_align(vecSize) */
/* *get_explicit_type_size(kType)); */
/* return result; */
/* } */
int test_vec_internal(cl_device_id deviceID, cl_context context,
cl_command_queue queue, const char * pattern,
const char * testName, size_t bufSize,
size_t preSize, size_t typeMultiplePreSize,
size_t postSize, size_t typeMultiplePostSize)
{
int err;
int typeIdx, vecSizeIdx;
char tmpBuffer[2048];
char srcBuffer[2048];
size_t preSizeBytes, postSizeBytes, typeSize, totSize;
clState * pClState = newClState(deviceID, context, queue);
bufferStruct * pBuffers =
newBufferStruct(bufSize, bufSize*sizeof(cl_uint)/sizeof(cl_char), pClState);
if(pBuffers == NULL) {
destroyClState(pClState);
vlog_error("%s : Could not create buffer\n", testName);
return -1;
}
for(typeIdx = 0; types[typeIdx] != kNumExplicitTypes; ++typeIdx)
{
// Skip doubles if it is not supported otherwise enable pragma
if (types[typeIdx] == kDouble) {
if (!is_extension_available(deviceID, "cl_khr_fp64")) {
continue;
} else {
doReplace(tmpBuffer, 2048, pattern,
".PRAGMA.", "#pragma OPENCL EXTENSION cl_khr_fp64: ",
".STATE.", "enable");
}
} else {
if (types[typeIdx] == kLong || types[typeIdx] == kULong) {
if (gIsEmbedded)
continue;
}
doReplace(tmpBuffer, 2048, pattern,
".PRAGMA.", " ",
".STATE.", " ");
}
typeSize = get_explicit_type_size(types[typeIdx]);
preSizeBytes = preSize + typeSize*typeMultiplePreSize;
postSizeBytes = postSize + typeSize*typeMultiplePostSize;
for(vecSizeIdx = 1; vecSizeIdx < NUM_VECTOR_SIZES; ++vecSizeIdx) {
totSize = preSizeBytes + postSizeBytes +
typeSize*get_align(g_arrVecSizes[vecSizeIdx]);
doReplace(srcBuffer, 2048, tmpBuffer,
".TYPE.", g_arrTypeNames[typeIdx],
".NUM.", g_arrVecSizeNames[vecSizeIdx]);
if(srcBuffer[0] == '\0') {
vlog_error("%s: failed to fill source buf for type %s%s\n",
testName,
g_arrTypeNames[typeIdx],
g_arrVecSizeNames[vecSizeIdx]);
destroyBufferStruct(pBuffers, pClState);
destroyClState(pClState);
return -1;
}
// log_info("Buffer is \"\n%s\n\"\n", srcBuffer);
// fflush(stdout);
err = clStateMakeProgram(pClState, srcBuffer, testName );
if (err) {
vlog_error("%s: Error compiling \"\n%s\n\"",
testName, srcBuffer);
destroyBufferStruct(pBuffers, pClState);
destroyClState(pClState);
return -1;
}
err = pushArgs(pBuffers, pClState);
if(err != 0) {
vlog_error("%s: failed to push args %s%s\n",
testName,
g_arrTypeNames[typeIdx],
g_arrVecSizeNames[vecSizeIdx]);
destroyBufferStruct(pBuffers, pClState);
destroyClState(pClState);
return -1;
}
// log_info("About to Run kernel\n"); fflush(stdout);
// now we run the kernel
err = runKernel(pClState,
bufSize/(g_arrVecSizes[vecSizeIdx]* g_arrTypeSizes[typeIdx]));
if(err != 0) {
vlog_error("%s: runKernel fail (%ld threads) %s%s\n",
testName, pClState->m_numThreads,
g_arrTypeNames[typeIdx],
g_arrVecSizeNames[vecSizeIdx]);
destroyBufferStruct(pBuffers, pClState);
destroyClState(pClState);
return -1;
}
// log_info("About to retrieve results\n"); fflush(stdout);
err = retrieveResults(pBuffers, pClState);
if(err != 0) {
vlog_error("%s: failed to retrieve results %s%s\n",
testName,
g_arrTypeNames[typeIdx],
g_arrVecSizeNames[vecSizeIdx]);
destroyBufferStruct(pBuffers, pClState);
destroyClState(pClState);
return -1;
}
if(preSizeBytes+postSizeBytes == 0)
{
// log_info("About to Check Correctness\n"); fflush(stdout);
err = checkCorrectness(pBuffers, pClState,
get_align(g_arrVecSizes[vecSizeIdx])*
typeSize);
}
else
{
// we're checking for an aligned struct
err = checkPackedCorrectness(pBuffers, pClState, totSize,
preSizeBytes);
}
if(err != 0) {
vlog_error("%s: incorrect results %s%s\n",
testName,
g_arrTypeNames[typeIdx],
g_arrVecSizeNames[vecSizeIdx]);
vlog_error("%s: Source was \"\n%s\n\"",
testName, srcBuffer);
destroyBufferStruct(pBuffers, pClState);
destroyClState(pClState);
return -1;
}
clStateDestroyProgramAndKernel(pClState);
}
}
destroyBufferStruct(pBuffers, pClState);
destroyClState(pClState);
// vlog_error("%s : implementation incomplete : FAIL\n", testName);
return 0; // -1; // fails on account of not being written.
}
const char * patterns[] = {
".PRAGMA..STATE.\n"
"__kernel void test_vec_align_array(.SRC_SCOPE. .TYPE..NUM. *source, .DST_SCOPE. uint *dest)\n"
"{\n"
" int tid = get_global_id(0);\n"
" dest[tid] = (uint)((.SRC_SCOPE. uchar *)(source+tid));\n"
"}\n",
".PRAGMA..STATE.\n"
"typedef struct myUnpackedStruct { \n"
".PRE."
" .TYPE..NUM. vec;\n"
".POST."
"} testStruct;\n"
"__kernel void test_vec_align_struct(__constant .TYPE..NUM. *source, .DST_SCOPE. uint *dest)\n"
"{\n"
" .SRC_SCOPE. testStruct test;\n"
" int tid = get_global_id(0);\n"
" dest[tid] = (uint)((.SRC_SCOPE. uchar *)&(test.vec));\n"
"}\n",
".PRAGMA..STATE.\n"
"typedef struct __attribute__ ((packed)) myPackedStruct { \n"
".PRE."
" .TYPE..NUM. vec;\n"
".POST."
"} testStruct;\n"
"__kernel void test_vec_align_packed_struct(__constant .TYPE..NUM. *source, .DST_SCOPE. uint *dest)\n"
"{\n"
" .SRC_SCOPE. testStruct test;\n"
" int tid = get_global_id(0);\n"
" dest[tid] = (uint)((.SRC_SCOPE. uchar *)&(test.vec) - (.SRC_SCOPE. uchar *)&test);\n"
"}\n",
".PRAGMA..STATE.\n"
"typedef struct myStruct { \n"
".PRE."
" .TYPE..NUM. vec;\n"
".POST."
"} testStruct;\n"
"__kernel void test_vec_align_struct_arr(.SRC_SCOPE. testStruct *source, .DST_SCOPE. uint *dest)\n"
"{\n"
" int tid = get_global_id(0);\n"
" dest[tid] = (uint)((.SRC_SCOPE. uchar *)&(source[tid].vec));\n"
"}\n",
".PRAGMA..STATE.\n"
"typedef struct __attribute__ ((packed)) myPackedStruct { \n"
".PRE."
" .TYPE..NUM. vec;\n"
".POST."
"} testStruct;\n"
"__kernel void test_vec_align_packed_struct_arr(.SRC_SCOPE. testStruct *source, .DST_SCOPE. uint *dest)\n"
"{\n"
" int tid = get_global_id(0);\n"
" dest[tid] = (uint)((.SRC_SCOPE. uchar *)&(source[tid].vec) - (.SRC_SCOPE. uchar *)&(source[0]));\n"
"}\n",
// __attribute__ ((packed))
};
const char * pre_substitution_arr[] = {
"",
"char c;\n",
"short3 s;",
".TYPE.3 tPre;\n",
".TYPE. arrPre[5];\n",
".TYPE. arrPre[12];\n",
NULL
};
// alignments of everything in pre_substitution_arr as raw alignments
// 0 if such a thing is meaningless
size_t pre_align_arr[] = {
0,
sizeof(cl_char),
4*sizeof(cl_short),
0, // taken care of in type_multiple_pre_align_arr
0,
0
};
// alignments of everything in pre_substitution_arr as multiples of
// sizeof(.TYPE.)
// 0 if such a thing is meaningless
size_t type_multiple_pre_align_arr[] = {
0,
0,
0,
4,
5,
12
};
const char * post_substitution_arr[] = {
"",
"char cPost;\n",
".TYPE. arrPost[3];\n",
".TYPE. arrPost[5];\n",
".TYPE.3 arrPost;\n",
".TYPE. arrPost[12];\n",
NULL
};
// alignments of everything in post_substitution_arr as raw alignments
// 0 if such a thing is meaningless
size_t post_align_arr[] = {
0,
sizeof(cl_char),
0, // taken care of in type_multiple_post_align_arr
0,
0,
0
};
// alignments of everything in post_substitution_arr as multiples of
// sizeof(.TYPE.)
// 0 if such a thing is meaningless
size_t type_multiple_post_align_arr[] = {
0,
0,
3,
5,
4,
12
};
// there hsould be a packed version of this?
int test_vec_align_array(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
{
char tmp[2048];
int result;
log_info("Testing global\n");
doReplace(tmp, (size_t)2048, patterns[0],
".SRC_SCOPE.", "__global",
".DST_SCOPE.", "__global"); //
result = test_vec_internal(deviceID, context, queue, tmp,
"test_vec_align_array",
BUFFER_SIZE, 0, 0, 0, 0);
return result;
}
int test_vec_align_struct(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
{
char tmp1[2048], tmp2[2048];
int result = 0;
int preIdx, postIdx;
log_info("testing __private\n");
doReplace(tmp2, (size_t)2048, patterns[1],
".SRC_SCOPE.", "__private",
".DST_SCOPE.", "__global"); //
for(preIdx = 0; pre_substitution_arr[preIdx] != NULL; ++preIdx) {
for(postIdx = 0; post_substitution_arr[postIdx] != NULL; ++postIdx) {
doReplace(tmp1, (size_t)2048, tmp2,
".PRE.", pre_substitution_arr[preIdx],
".POST.", post_substitution_arr[postIdx]);
result = test_vec_internal(deviceID, context, queue, tmp1,
"test_vec_align_struct",
512, 0, 0, 0, 0);
if (result != 0) {
return result;
}
}
}
log_info("testing __local\n");
doReplace(tmp2, (size_t)2048, patterns[1],
".SRC_SCOPE.", "__local",
".DST_SCOPE.", "__global"); //
for(preIdx = 0; pre_substitution_arr[preIdx] != NULL; ++preIdx) {
for(postIdx = 0; post_substitution_arr[postIdx] != NULL; ++postIdx) {
doReplace(tmp1, (size_t)2048, tmp2,
".PRE.", pre_substitution_arr[preIdx],
".POST.", post_substitution_arr[postIdx]);
result = test_vec_internal(deviceID, context, queue, tmp1,
"test_vec_align_struct",
512, 0, 0, 0, 0);
if(result != 0) {
return result;
}
}
}
return 0;
}
int test_vec_align_packed_struct(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
{
char tmp1[2048], tmp2[2048];
int result = 0;
int preIdx, postIdx;
log_info("Testing __private\n");
doReplace(tmp2, (size_t)2048, patterns[2],
".SRC_SCOPE.", "__private",
".DST_SCOPE.", "__global"); //
for(preIdx = 0; pre_substitution_arr[preIdx] != NULL; ++preIdx) {
for(postIdx = 0; post_substitution_arr[postIdx] != NULL; ++postIdx) {
doReplace(tmp1, (size_t)2048, tmp2,
".PRE.", pre_substitution_arr[preIdx],
".POST.", post_substitution_arr[postIdx]);
result = test_vec_internal(deviceID, context, queue, tmp1,
"test_vec_align_packed_struct",
512, pre_align_arr[preIdx],
type_multiple_pre_align_arr[preIdx],
post_align_arr[postIdx],
type_multiple_post_align_arr[postIdx]);
if(result != 0) {
return result;
}
}
}
log_info("testing __local\n");
doReplace(tmp2, (size_t)2048, patterns[2],
".SRC_SCOPE.", "__local",
".DST_SCOPE.", "__global"); //
for(preIdx = 0; pre_substitution_arr[preIdx] != NULL; ++preIdx) {
for(postIdx = 0; post_substitution_arr[postIdx] != NULL; ++postIdx) {
doReplace(tmp1, (size_t)2048, tmp2,
".PRE.", pre_substitution_arr[preIdx],
".POST.", post_substitution_arr[postIdx]);
result = test_vec_internal(deviceID, context, queue, tmp1,
"test_vec_align_packed_struct",
512, pre_align_arr[preIdx],
type_multiple_pre_align_arr[preIdx],
post_align_arr[postIdx],
type_multiple_post_align_arr[postIdx]);
if (result != 0) {
return result;
}
}
}
return 0;
}
int test_vec_align_struct_arr(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
{
char tmp1[2048], tmp2[2048];
int result = 0;
int preIdx, postIdx;
log_info("testing __global\n");
doReplace(tmp2, (size_t)2048, patterns[3],
".SRC_SCOPE.", "__global",
".DST_SCOPE.", "__global"); //
for(preIdx = 0; pre_substitution_arr[preIdx] != NULL; ++preIdx) {
for(postIdx = 0; post_substitution_arr[postIdx] != NULL; ++postIdx) {
doReplace(tmp1, (size_t)2048, tmp2,
".PRE.", pre_substitution_arr[preIdx],
".POST.", post_substitution_arr[postIdx]);
result = test_vec_internal(deviceID, context, queue, tmp1,
"test_vec_align_struct_arr",
BUFFER_SIZE, 0, 0, 0, 0);
if(result != 0) {
return result;
}
}
}
return 0;
}
int test_vec_align_packed_struct_arr(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
{
char tmp1[2048], tmp2[2048];
int result = 0;
int preIdx, postIdx;
log_info("Testing __global\n");
doReplace(tmp2, (size_t)2048, patterns[4],
".SRC_SCOPE.", "__global",
".DST_SCOPE.", "__global"); //
for(preIdx = 0; pre_substitution_arr[preIdx] != NULL; ++preIdx) {
for(postIdx = 0; post_substitution_arr[postIdx] != NULL; ++postIdx) {
doReplace(tmp1, (size_t)2048, tmp2,
".PRE.", pre_substitution_arr[preIdx],
".POST.", post_substitution_arr[postIdx]);
result = test_vec_internal(deviceID, context, queue, tmp1,
"test_vec_align_packed_struct_arr",
BUFFER_SIZE, pre_align_arr[preIdx],
type_multiple_pre_align_arr[preIdx],
post_align_arr[postIdx],
type_multiple_post_align_arr[postIdx]);
if(result != 0)
return result;
}
}
return 0;
}

View File

@@ -0,0 +1,115 @@
//
// 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 <string.h>
#if !defined(_MSC_VER)
#include <stdint.h>
#endif // !_MSC_VER
size_t doReplace(char * dest, size_t destLength, const char * source,
const char * stringToReplace1, const char * replaceWith1,
const char * stringToReplace2, const char * replaceWith2)
{
size_t copyCount = 0;
const char * sourcePtr = source;
char * destPtr = dest;
const char * ptr1;
const char * ptr2;
size_t nJump;
size_t len1, len2;
size_t lenReplace1, lenReplace2;
len1 = strlen(stringToReplace1);
len2 = strlen(stringToReplace2);
lenReplace1 = strlen(replaceWith1);
lenReplace2 = strlen(replaceWith2);
for(;copyCount < destLength && *sourcePtr; )
{
ptr1 = strstr(sourcePtr, stringToReplace1);
ptr2 = strstr(sourcePtr, stringToReplace2);
if(ptr1 != NULL && (ptr2 == NULL || ptr2 > ptr1))
{
nJump = ptr1-sourcePtr;
if(((uintptr_t)ptr1-(uintptr_t)sourcePtr) > destLength-copyCount) { return -1; }
copyCount += nJump;
strncpy(destPtr, sourcePtr, nJump);
destPtr += nJump;
sourcePtr += nJump + len1;
strcpy(destPtr, replaceWith1);
destPtr += lenReplace1;
}
else if(ptr2 != NULL && (ptr1 == NULL || ptr1 >= ptr2))
{
nJump = ptr2-sourcePtr;
if(nJump > destLength-copyCount) { return -2; }
copyCount += nJump;
strncpy(destPtr, sourcePtr, nJump);
destPtr += nJump;
sourcePtr += nJump + len2;
strcpy(destPtr, replaceWith2);
destPtr += lenReplace2;
}
else
{
nJump = strlen(sourcePtr);
if(nJump > destLength-copyCount) { return -3; }
copyCount += nJump;
strcpy(destPtr, sourcePtr);
destPtr += nJump;
sourcePtr += nJump;
}
}
*destPtr = '\0';
return copyCount;
}
size_t doSingleReplace(char * dest, size_t destLength, const char * source,
const char * stringToReplace, const char * replaceWith)
{
size_t copyCount = 0;
const char * sourcePtr = source;
char * destPtr = dest;
const char * ptr;
size_t nJump;
size_t len;
size_t lenReplace;
len = strlen(stringToReplace);
lenReplace = strlen(replaceWith);
for(;copyCount < destLength && *sourcePtr; )
{
ptr = strstr(sourcePtr, stringToReplace);
if(ptr != NULL)
{
nJump = ptr-sourcePtr;
if(((uintptr_t)ptr-(uintptr_t)sourcePtr) > destLength-copyCount) { return -1; }
copyCount += nJump;
strncpy(destPtr, sourcePtr, nJump);
destPtr += nJump;
sourcePtr += nJump + len;
strcpy(destPtr, replaceWith);
destPtr += lenReplace;
}
else
{
nJump = strlen(sourcePtr);
if(nJump > destLength-copyCount) { return -3; }
copyCount += nJump;
strcpy(destPtr, sourcePtr);
destPtr += nJump;
sourcePtr += nJump;
}
}
*destPtr = '\0';
return copyCount;
}

View File

@@ -0,0 +1,23 @@
//
// 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 <stdlib.h>
size_t doReplace(char * dest, size_t destLength, const char * source,
const char * stringToReplace1, const char * replaceWith1,
const char * stringToReplace2, const char * replaceWith2);
size_t doSingleReplace(char * dest, size_t destLength, const char * source,
const char * stringToReplace, const char * replaceWith);