Initial open source release of OpenCL 2.2 CTS.

This commit is contained in:
Kedar Patil
2017-05-16 18:25:37 +05:30
parent 6911ba5116
commit 2821bf1323
1035 changed files with 343518 additions and 0 deletions

View File

@@ -0,0 +1,17 @@
set(MODULE_NAME C11_ATOMICS)
set(${MODULE_NAME}_SOURCES
common.cpp
host_atomics.cpp
main.cpp
test_atomics.cpp
../../test_common/harness/ThreadPool.c
../../test_common/harness/errorHelpers.c
../../test_common/harness/testHarness.c
../../test_common/harness/kernelHelpers.c
../../test_common/harness/mt19937.c
../../test_common/harness/msvc9.c
../../test_common/harness/parseParameters.cpp
)
include(../CMakeCommon.txt)

View File

@@ -0,0 +1,46 @@
ifdef BUILD_WITH_ATF
ATF = -framework ATF
USE_ATF = -DUSE_ATF
endif
SRCS = main.c \
test_atomics.cpp \
host_atomics.cpp \
common.cpp \
../../test_common/harness/errorHelpers.c \
../../test_common/harness/threadTesting.c \
../../test_common/harness/testHarness.c \
../../test_common/harness/kernelHelpers.c \
../../test_common/harness/typeWrappers.cpp \
../../test_common/harness/mt19937.c \
../../test_common/harness/conversions.c \
../../test_common/harness/ThreadPool.c
DEFINES = DONT_TEST_GARBAGE_POINTERS
SOURCES = $(abspath $(SRCS))
LIBPATH += -L/System/Library/Frameworks/OpenCL.framework/Libraries
LIBPATH += -L.
HEADERS =
TARGET = test_atomics_c11
INCLUDE =
COMPILERFLAGS = -c -Wall -g -Wshorten-64-to-32
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,208 @@
//
// 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/testHarness.h"
#include "../../test_common/harness/kernelHelpers.h"
#include "../../test_common/harness/typeWrappers.h"
#include "common.h"
const char *get_memory_order_type_name(TExplicitMemoryOrderType orderType)
{
switch (orderType)
{
case MEMORY_ORDER_EMPTY:
return "";
case MEMORY_ORDER_RELAXED:
return "memory_order_relaxed";
case MEMORY_ORDER_ACQUIRE:
return "memory_order_acquire";
case MEMORY_ORDER_RELEASE:
return "memory_order_release";
case MEMORY_ORDER_ACQ_REL:
return "memory_order_acq_rel";
case MEMORY_ORDER_SEQ_CST:
return "memory_order_seq_cst";
default:
return 0;
}
}
const char *get_memory_scope_type_name(TExplicitMemoryScopeType scopeType)
{
switch (scopeType)
{
case MEMORY_SCOPE_EMPTY:
return "";
case MEMORY_SCOPE_WORK_GROUP:
return "memory_scope_work_group";
case MEMORY_SCOPE_DEVICE:
return "memory_scope_device";
case MEMORY_SCOPE_ALL_SVM_DEVICES:
return "memory_scope_all_svm_devices";
default:
return 0;
}
}
cl_uint AtomicTypeInfo::Size(cl_device_id device)
{
switch(_type)
{
case TYPE_ATOMIC_INT:
case TYPE_ATOMIC_UINT:
case TYPE_ATOMIC_FLOAT:
case TYPE_ATOMIC_FLAG:
return sizeof(cl_int);
case TYPE_ATOMIC_LONG:
case TYPE_ATOMIC_ULONG:
case TYPE_ATOMIC_DOUBLE:
return sizeof(cl_long);
case TYPE_ATOMIC_INTPTR_T:
case TYPE_ATOMIC_UINTPTR_T:
case TYPE_ATOMIC_SIZE_T:
case TYPE_ATOMIC_PTRDIFF_T:
{
int error;
cl_uint addressBits = 0;
error = clGetDeviceInfo(device, CL_DEVICE_ADDRESS_BITS, sizeof(addressBits), &addressBits, 0);
test_error_ret(error, "clGetDeviceInfo", 0);
return addressBits/8;
}
default:
return 0;
}
}
const char *AtomicTypeInfo::AtomicTypeName()
{
switch(_type)
{
case TYPE_ATOMIC_INT:
return "atomic_int";
case TYPE_ATOMIC_UINT:
return "atomic_uint";
case TYPE_ATOMIC_FLOAT:
return "atomic_float";
case TYPE_ATOMIC_FLAG:
return "atomic_flag";
case TYPE_ATOMIC_LONG:
return "atomic_long";
case TYPE_ATOMIC_ULONG:
return "atomic_ulong";
case TYPE_ATOMIC_DOUBLE:
return "atomic_double";
case TYPE_ATOMIC_INTPTR_T:
return "atomic_intptr_t";
case TYPE_ATOMIC_UINTPTR_T:
return "atomic_uintptr_t";
case TYPE_ATOMIC_SIZE_T:
return "atomic_size_t";
case TYPE_ATOMIC_PTRDIFF_T:
return "atomic_ptrdiff_t";
default:
return 0;
}
}
const char *AtomicTypeInfo::RegularTypeName()
{
switch(_type)
{
case TYPE_ATOMIC_INT:
return "int";
case TYPE_ATOMIC_UINT:
return "uint";
case TYPE_ATOMIC_FLOAT:
return "float";
case TYPE_ATOMIC_FLAG:
return "int";
case TYPE_ATOMIC_LONG:
return "long";
case TYPE_ATOMIC_ULONG:
return "ulong";
case TYPE_ATOMIC_DOUBLE:
return "double";
case TYPE_ATOMIC_INTPTR_T:
return "intptr_t";
case TYPE_ATOMIC_UINTPTR_T:
return "uintptr_t";
case TYPE_ATOMIC_SIZE_T:
return "size_t";
case TYPE_ATOMIC_PTRDIFF_T:
return "ptrdiff_t";
default:
return 0;
}
}
const char *AtomicTypeInfo::AddSubOperandTypeName()
{
switch(_type)
{
case TYPE_ATOMIC_INTPTR_T:
case TYPE_ATOMIC_UINTPTR_T:
return AtomicTypeInfo(TYPE_ATOMIC_PTRDIFF_T).RegularTypeName();
default:
return RegularTypeName();
}
}
int AtomicTypeInfo::IsSupported(cl_device_id device)
{
switch(_type)
{
case TYPE_ATOMIC_INT:
case TYPE_ATOMIC_UINT:
case TYPE_ATOMIC_FLOAT:
case TYPE_ATOMIC_FLAG:
return 1;
case TYPE_ATOMIC_LONG:
case TYPE_ATOMIC_ULONG:
return is_extension_available(device, "cl_khr_int64_base_atomics") &&
is_extension_available(device, "cl_khr_int64_extended_atomics");
case TYPE_ATOMIC_DOUBLE:
return is_extension_available(device, "cl_khr_int64_base_atomics") &&
is_extension_available(device, "cl_khr_int64_extended_atomics") &&
is_extension_available(device, "cl_khr_fp64");
case TYPE_ATOMIC_INTPTR_T:
case TYPE_ATOMIC_UINTPTR_T:
case TYPE_ATOMIC_SIZE_T:
case TYPE_ATOMIC_PTRDIFF_T:
if(Size(device) == 4)
return 1;
return is_extension_available(device, "cl_khr_int64_base_atomics") &&
is_extension_available(device, "cl_khr_int64_extended_atomics");
default:
return 0;
}
}
template<> cl_int AtomicTypeExtendedInfo<cl_int>::MinValue() {return CL_INT_MIN;}
template<> cl_uint AtomicTypeExtendedInfo<cl_uint>::MinValue() {return 0;}
template<> cl_long AtomicTypeExtendedInfo<cl_long>::MinValue() {return CL_LONG_MIN;}
template<> cl_ulong AtomicTypeExtendedInfo<cl_ulong>::MinValue() {return 0;}
template<> cl_float AtomicTypeExtendedInfo<cl_float>::MinValue() {return CL_FLT_MIN;}
template<> cl_double AtomicTypeExtendedInfo<cl_double>::MinValue() {return CL_DBL_MIN;}
template<> cl_int AtomicTypeExtendedInfo<cl_int>::MaxValue() {return CL_INT_MAX;}
template<> cl_uint AtomicTypeExtendedInfo<cl_uint>::MaxValue() {return CL_UINT_MAX;}
template<> cl_long AtomicTypeExtendedInfo<cl_long>::MaxValue() {return CL_LONG_MAX;}
template<> cl_ulong AtomicTypeExtendedInfo<cl_ulong>::MaxValue() {return CL_ULONG_MAX;}
template<> cl_float AtomicTypeExtendedInfo<cl_float>::MaxValue() {return CL_FLT_MAX;}
template<> cl_double AtomicTypeExtendedInfo<cl_double>::MaxValue() {return CL_DBL_MAX;}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,66 @@
//
// 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 "host_atomics.h"
void host_atomic_thread_fence(TExplicitMemoryOrderType order)
{
if(order != MEMORY_ORDER_RELAXED) {
#if defined( _MSC_VER ) || (defined( __INTEL_COMPILER ) && defined(WIN32))
MemoryBarrier();
#elif defined(__GNUC__)
__sync_synchronize();
#else
log_info("Host function not implemented: host_atomic_thread_fence\n");
#endif
}
}
template <>
HOST_FLOAT host_atomic_exchange(volatile HOST_ATOMIC_FLOAT* a, HOST_FLOAT c, TExplicitMemoryOrderType order)
{
HOST_UINT tmp = host_atomic_exchange((volatile HOST_ATOMIC_UINT*)a, *(HOST_UINT*)&c, order);
return *(float*)&tmp;
}
template <>
HOST_DOUBLE host_atomic_exchange(volatile HOST_ATOMIC_DOUBLE* a, HOST_DOUBLE c, TExplicitMemoryOrderType order)
{
HOST_ULONG tmp = host_atomic_exchange((volatile HOST_ATOMIC_ULONG*)a, *(HOST_ULONG*)&c, order);
return *(double*)&tmp;
}
template <>
HOST_FLOAT host_atomic_load(volatile HOST_ATOMIC_FLOAT* a, TExplicitMemoryOrderType order)
{
HOST_UINT tmp = host_atomic_load<HOST_ATOMIC_UINT, HOST_UINT>((volatile HOST_ATOMIC_UINT*)a, order);
return *(float*)&tmp;
}
template <>
HOST_DOUBLE host_atomic_load(volatile HOST_ATOMIC_DOUBLE* a, TExplicitMemoryOrderType order)
{
HOST_ULONG tmp = host_atomic_load<HOST_ATOMIC_ULONG, HOST_ULONG>((volatile HOST_ATOMIC_ULONG*)a, order);
return *(double*)&tmp;
}
bool host_atomic_flag_test_and_set(volatile HOST_ATOMIC_FLAG *a, TExplicitMemoryOrderType order)
{
HOST_FLAG old = host_atomic_exchange(a, 1, order);
return old != 0;
}
void host_atomic_flag_clear(volatile HOST_ATOMIC_FLAG *a, TExplicitMemoryOrderType order)
{
host_atomic_store(a, 0, order);
}

View File

@@ -0,0 +1,250 @@
//
// 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 _HOST_ATOMICS_H_
#define _HOST_ATOMICS_H_
#include "../../test_common/harness/testHarness.h"
#ifdef WIN32
#include "Windows.h"
#endif
//flag for test verification (good test should discover non-atomic functions and fail)
//#define NON_ATOMIC_FUNCTIONS
enum TExplicitMemoryOrderType
{
MEMORY_ORDER_EMPTY,
MEMORY_ORDER_RELAXED,
MEMORY_ORDER_ACQUIRE,
MEMORY_ORDER_RELEASE,
MEMORY_ORDER_ACQ_REL,
MEMORY_ORDER_SEQ_CST
};
// host atomic types (applicable for atomic functions supported on host OS)
#ifdef WIN32
#define HOST_ATOMIC_INT unsigned long
#define HOST_ATOMIC_UINT unsigned long
#define HOST_ATOMIC_LONG unsigned long long
#define HOST_ATOMIC_ULONG unsigned long long
#define HOST_ATOMIC_FLOAT float
#define HOST_ATOMIC_DOUBLE double
#else
#define HOST_ATOMIC_INT cl_int
#define HOST_ATOMIC_UINT cl_uint
#define HOST_ATOMIC_LONG cl_long
#define HOST_ATOMIC_ULONG cl_ulong
#define HOST_ATOMIC_FLOAT cl_float
#define HOST_ATOMIC_DOUBLE cl_double
#endif
#define HOST_ATOMIC_INTPTR_T32 HOST_ATOMIC_INT
#define HOST_ATOMIC_UINTPTR_T32 HOST_ATOMIC_INT
#define HOST_ATOMIC_SIZE_T32 HOST_ATOMIC_UINT
#define HOST_ATOMIC_PTRDIFF_T32 HOST_ATOMIC_INT
#define HOST_ATOMIC_INTPTR_T64 HOST_ATOMIC_LONG
#define HOST_ATOMIC_UINTPTR_T64 HOST_ATOMIC_LONG
#define HOST_ATOMIC_SIZE_T64 HOST_ATOMIC_ULONG
#define HOST_ATOMIC_PTRDIFF_T64 HOST_ATOMIC_LONG
#define HOST_ATOMIC_FLAG HOST_ATOMIC_INT
// host regular types corresponding to atomic types
#define HOST_INT cl_int
#define HOST_UINT cl_uint
#define HOST_LONG cl_long
#define HOST_ULONG cl_ulong
#define HOST_FLOAT cl_float
#define HOST_DOUBLE cl_double
#define HOST_INTPTR_T32 cl_int
#define HOST_UINTPTR_T32 cl_uint
#define HOST_SIZE_T32 cl_uint
#define HOST_PTRDIFF_T32 cl_int
#define HOST_INTPTR_T64 cl_long
#define HOST_UINTPTR_T64 cl_ulong
#define HOST_SIZE_T64 cl_ulong
#define HOST_PTRDIFF_T64 cl_long
#define HOST_FLAG cl_uint
// host atomic functions
void host_atomic_thread_fence(TExplicitMemoryOrderType order);
template <typename AtomicType, typename CorrespondingType>
CorrespondingType host_atomic_fetch_add(volatile AtomicType *a, CorrespondingType c,
TExplicitMemoryOrderType order)
{
#if defined( _MSC_VER ) || (defined( __INTEL_COMPILER ) && defined(WIN32))
return InterlockedExchangeAdd(a, c);
#elif defined(__GNUC__)
return __sync_fetch_and_add(a, c);
#else
log_info("Host function not implemented: atomic_fetch_add\n");
return 0;
#endif
}
template <typename AtomicType, typename CorrespondingType>
CorrespondingType host_atomic_fetch_sub(volatile AtomicType *a, CorrespondingType c,
TExplicitMemoryOrderType order)
{
#if defined( _MSC_VER ) || (defined( __INTEL_COMPILER ) && defined(WIN32))
return InterlockedExchangeSubtract(a, c);
#elif defined(__GNUC__)
return __sync_fetch_and_sub(a, c);
#else
log_info("Host function not implemented: atomic_fetch_sub\n");
return 0;
#endif
}
template <typename AtomicType, typename CorrespondingType>
CorrespondingType host_atomic_exchange(volatile AtomicType *a, CorrespondingType c,
TExplicitMemoryOrderType order)
{
#if defined( _MSC_VER ) || (defined( __INTEL_COMPILER ) && defined(WIN32))
return InterlockedExchange(a, c);
#elif defined(__GNUC__)
return __sync_lock_test_and_set(a, c);
#else
log_info("Host function not implemented: atomic_exchange\n");
return 0;
#endif
}
template <> HOST_FLOAT host_atomic_exchange(volatile HOST_ATOMIC_FLOAT *a, HOST_FLOAT c,
TExplicitMemoryOrderType order);
template <> HOST_DOUBLE host_atomic_exchange(volatile HOST_ATOMIC_DOUBLE *a, HOST_DOUBLE c,
TExplicitMemoryOrderType order);
template <typename AtomicType, typename CorrespondingType>
bool host_atomic_compare_exchange(volatile AtomicType *a, CorrespondingType *expected, CorrespondingType desired,
TExplicitMemoryOrderType order_success,
TExplicitMemoryOrderType order_failure)
{
CorrespondingType tmp;
#if defined( _MSC_VER ) || (defined( __INTEL_COMPILER ) && defined(WIN32))
tmp = InterlockedCompareExchange(a, desired, *expected);
#elif defined(__GNUC__)
tmp = __sync_val_compare_and_swap(a, *expected, desired);
#else
log_info("Host function not implemented: atomic_compare_exchange\n");
tmp = 0;
#endif
if(tmp == *expected)
return true;
*expected = tmp;
return false;
}
template <typename AtomicType, typename CorrespondingType>
CorrespondingType host_atomic_load(volatile AtomicType *a,
TExplicitMemoryOrderType order)
{
#if defined( _MSC_VER ) || (defined( __INTEL_COMPILER ) && defined(WIN32))
return InterlockedExchangeAdd(a, 0);
#elif defined(__GNUC__)
return __sync_add_and_fetch(a, 0);
#else
log_info("Host function not implemented: atomic_load\n");
return 0;
#endif
}
template <> HOST_FLOAT host_atomic_load(volatile HOST_ATOMIC_FLOAT *a,
TExplicitMemoryOrderType order);
template <> HOST_DOUBLE host_atomic_load(volatile HOST_ATOMIC_DOUBLE *a,
TExplicitMemoryOrderType order);
template <typename AtomicType, typename CorrespondingType>
void host_atomic_store(volatile AtomicType* a, CorrespondingType c,
TExplicitMemoryOrderType order)
{
host_atomic_exchange(a, c, order);
}
template <typename AtomicType, typename CorrespondingType>
void host_atomic_init(volatile AtomicType* a, CorrespondingType c)
{
host_atomic_exchange(a, c, MEMORY_ORDER_RELAXED);
}
template <typename AtomicType, typename CorrespondingType>
CorrespondingType host_atomic_fetch_or(volatile AtomicType *a, CorrespondingType c,
TExplicitMemoryOrderType order)
{
CorrespondingType expected = host_atomic_load<AtomicType, CorrespondingType>(a, order);
CorrespondingType desired;
do
desired = expected | c;
while(!host_atomic_compare_exchange(a, &expected, desired, order, order));
return expected;
}
template <typename AtomicType, typename CorrespondingType>
CorrespondingType host_atomic_fetch_and(volatile AtomicType *a, CorrespondingType c,
TExplicitMemoryOrderType order)
{
CorrespondingType expected = host_atomic_load<AtomicType, CorrespondingType>(a, order);
CorrespondingType desired;
do
desired = expected & c;
while(!host_atomic_compare_exchange(a, &expected, desired, order, order));
return expected;
}
template <typename AtomicType, typename CorrespondingType>
CorrespondingType host_atomic_fetch_xor(volatile AtomicType *a, CorrespondingType c,
TExplicitMemoryOrderType order)
{
CorrespondingType expected = host_atomic_load<AtomicType, CorrespondingType>(a, order);
CorrespondingType desired;
do
desired = expected ^ c;
while(!host_atomic_compare_exchange(a, &expected, desired, order, order));
return expected;
}
template <typename AtomicType, typename CorrespondingType>
CorrespondingType host_atomic_fetch_min(volatile AtomicType *a, CorrespondingType c,
TExplicitMemoryOrderType order)
{
CorrespondingType expected = host_atomic_load<AtomicType, CorrespondingType>(a, order);
CorrespondingType desired;
do
desired = expected < c ? expected : c;
while(!host_atomic_compare_exchange(a, &expected, desired, order, order));
return expected;
}
template <typename AtomicType, typename CorrespondingType>
CorrespondingType host_atomic_fetch_max(volatile AtomicType *a, CorrespondingType c,
TExplicitMemoryOrderType order)
{
CorrespondingType expected = host_atomic_load<AtomicType, CorrespondingType>(a, order);
CorrespondingType desired;
do
desired = expected > c ? expected : c;
while(!host_atomic_compare_exchange(a, &expected, desired, order, order));
return expected;
}
bool host_atomic_flag_test_and_set(volatile HOST_ATOMIC_FLAG *a, TExplicitMemoryOrderType order);
void host_atomic_flag_clear(volatile HOST_ATOMIC_FLAG *a, TExplicitMemoryOrderType order);
#endif //_HOST_ATOMICS_H_

View File

@@ -0,0 +1,230 @@
//
// 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/testHarness.h"
#include <iostream>
#include <string>
bool gHost = false; // flag for testing native host threads (test verification)
bool gOldAPI = false; // flag for testing with old API (OpenCL 1.2) - test verification
bool gContinueOnError = false; // execute all cases even when errors detected
bool gNoGlobalVariables = false; // disable cases with global atomics in program scope
bool gNoGenericAddressSpace = false; // disable cases with generic address space
bool gUseHostPtr = false; // use malloc/free with CL_MEM_USE_HOST_PTR instead of clSVMAlloc/clSVMFree
bool gDebug = false; // always print OpenCL kernel code
int gInternalIterations = 10000; // internal test iterations for atomic operation, sufficient to verify atomicity
int gMaxDeviceThreads = 1024; // maximum number of threads executed on OCL device
extern int test_atomic_init(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_atomic_store(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_atomic_load(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_atomic_store_load(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_atomic_exchange(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_atomic_compare_exchange_weak(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_atomic_compare_exchange_strong(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_atomic_fetch_add(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_atomic_fetch_sub(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_atomic_fetch_and(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_atomic_fetch_or(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_atomic_fetch_orand(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_atomic_fetch_xor(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_atomic_fetch_xor2(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_atomic_fetch_min(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_atomic_fetch_max(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_atomic_flag(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_atomic_fence(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_atomic_init_svm(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_atomic_store_svm(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_atomic_load_svm(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_atomic_store_load_svm(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_atomic_exchange_svm(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_atomic_compare_exchange_weak_svm(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_atomic_compare_exchange_strong_svm(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_atomic_fetch_add_svm(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_atomic_fetch_sub_svm(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_atomic_fetch_and_svm(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_atomic_fetch_or_svm(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_atomic_fetch_orand_svm(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_atomic_fetch_xor_svm(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_atomic_fetch_xor2_svm(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_atomic_fetch_min_svm(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_atomic_fetch_max_svm(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_atomic_flag_svm(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_atomic_fence_svm(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
basefn basefn_list[] = {
test_atomic_init,
test_atomic_store,
test_atomic_load,
test_atomic_exchange,
test_atomic_compare_exchange_weak,
test_atomic_compare_exchange_strong,
test_atomic_fetch_add,
test_atomic_fetch_sub,
test_atomic_fetch_and,
test_atomic_fetch_or,
test_atomic_fetch_orand,
test_atomic_fetch_xor,
test_atomic_fetch_xor2,
test_atomic_fetch_min,
test_atomic_fetch_max,
test_atomic_flag,
test_atomic_fence,
test_atomic_init_svm,
test_atomic_store_svm,
test_atomic_load_svm,
test_atomic_exchange_svm,
test_atomic_compare_exchange_weak_svm,
test_atomic_compare_exchange_strong_svm,
test_atomic_fetch_add_svm,
test_atomic_fetch_sub_svm,
test_atomic_fetch_and_svm,
test_atomic_fetch_or_svm,
test_atomic_fetch_orand_svm,
test_atomic_fetch_xor_svm,
test_atomic_fetch_xor2_svm,
test_atomic_fetch_min_svm,
test_atomic_fetch_max_svm,
test_atomic_flag_svm,
test_atomic_fence_svm
};
const char *basefn_names[] = {
"atomic_init",
"atomic_store",
"atomic_load",
"atomic_exchange",
"atomic_compare_exchange_weak",
"atomic_compare_exchange_strong",
"atomic_fetch_add",
"atomic_fetch_sub",
"atomic_fetch_and",
"atomic_fetch_or",
"atomic_fetch_orand",
"atomic_fetch_xor",
"atomic_fetch_xor2",
"atomic_fetch_min",
"atomic_fetch_max",
"atomic_flag",
"atomic_fence",
"svm_atomic_init",
"svm_atomic_store",
"svm_atomic_load",
"svm_atomic_exchange",
"svm_atomic_compare_exchange_weak",
"svm_atomic_compare_exchange_strong",
"svm_atomic_fetch_add",
"svm_atomic_fetch_sub",
"svm_atomic_fetch_and",
"svm_atomic_fetch_or",
"svm_atomic_fetch_orand",
"svm_atomic_fetch_xor",
"svm_atomic_fetch_xor2",
"svm_atomic_fetch_min",
"svm_atomic_fetch_max",
"svm_atomic_flag",
"svm_atomic_fence",
};
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[])
{
bool noCert = false;
while(true)
{
if(std::string(argv[argc-1]) == "-h")
{
log_info("Test options:\n");
log_info(" '-host' flag for testing native host threads (test verification)\n");
log_info(" '-oldAPI' flag for testing with old API (OpenCL 1.2) - test verification\n");
log_info(" '-continueOnError' execute all cases even when errors detected\n");
log_info(" '-noGlobalVariables' disable cases with global atomics in program scope\n");
log_info(" '-noGenericAddressSpace' disable cases with generic address space\n");
log_info(" '-useHostPtr' use malloc/free with CL_MEM_USE_HOST_PTR instead of clSVMAlloc/clSVMFree\n");
log_info(" '-debug' always print OpenCL kernel code\n");
log_info(" '-internalIterations <X>' internal test iterations for atomic operation, sufficient to verify atomicity\n");
log_info(" '-maxDeviceThreads <X>' maximum number of threads executed on OCL device");
break;
}
if(std::string(argv[argc-1]) == "-host") // temporary option for testing native host threads
{
gHost = true;
noCert = true;
}
else if(std::string(argv[argc-1]) == "-oldAPI") // temporary flag for testing with old API (OpenCL 1.2)
{
gOldAPI = true;
gNoGlobalVariables = true;
gNoGenericAddressSpace = true;
gUseHostPtr = true;
noCert = true;
}
else if(std::string(argv[argc-1]) == "-continueOnError") // execute all cases even when errors detected
gContinueOnError = true;
else if(std::string(argv[argc-1]) == "-noGlobalVariables") // disable cases with global atomics in program scope
{
gNoGlobalVariables = true;
noCert = true;
}
else if(std::string(argv[argc-1]) == "-noGenericAddressSpace") // disable cases with generic address space
{
gNoGenericAddressSpace = true;
noCert = true;
}
else if(std::string(argv[argc-1]) == "-useHostPtr") // use malloc/free with CL_MEM_USE_HOST_PTR instead of clSVMAlloc/clSVMFree
{
gUseHostPtr = true;
noCert = true;
}
else if(std::string(argv[argc-1]) == "-debug") // print OpenCL kernel code
gDebug = true;
else if(argc > 2 && std::string(argv[argc-2]) == "-internalIterations") // internal test iterations for atomic operation, sufficient to verify atomicity
{
gInternalIterations = atoi(argv[argc-1]);
if(gInternalIterations < 1)
{
log_info("Invalid value: Number of internal iterations (%d) must be > 0\n", gInternalIterations);
return -1;
}
argc--;
noCert = true;
}
else if(argc > 2 && std::string(argv[argc-2]) == "-maxDeviceThreads") // maximum number of threads executed on OCL device
{
gMaxDeviceThreads = atoi(argv[argc-1]);
argc--;
noCert = true;
}
else
break;
argc--;
}
if(noCert)
{
log_info("\n" );
log_info("*** ***\n");
log_info("*** WARNING: Test execution in debug mode (forced by command-line option)! ***\n");
log_info("*** Use of this mode is not sufficient to verify correctness. ***\n");
log_info("*** ***\n");
}
return runTestHarness(argc, argv, num_fns, basefn_list, basefn_names, false, false, 0);
}

File diff suppressed because it is too large Load Diff