mirror of
https://github.com/KhronosGroup/OpenCL-CTS.git
synced 2026-03-19 06:09:01 +00:00
Memory consistency model optionality (#907)
* Test minimum memory consistency capabilities for a device reporting >= 3.0. Skip tests where unsupported memory consistency capabilities are being requested. * Pass nullptr as program build option. Allows the CTS framework to select an appropriate CL C version. * Removed redundant braces.
This commit is contained in:
@@ -65,6 +65,8 @@ extern bool gUseHostPtr; // use malloc/free instead of clSVMAlloc/clSVMFree
|
||||
extern bool gDebug; // print OpenCL kernel code
|
||||
extern int gInternalIterations; // internal test iterations for atomic operation, sufficient to verify atomicity
|
||||
extern int gMaxDeviceThreads; // maximum number of threads executed on OCL device
|
||||
extern cl_device_atomic_capabilities gAtomicMemCap,
|
||||
gAtomicFenceCap; // atomic memory and fence capabilities for this device
|
||||
|
||||
extern const char *get_memory_order_type_name(TExplicitMemoryOrderType orderType);
|
||||
extern const char *get_memory_scope_type_name(TExplicitMemoryScopeType scopeType);
|
||||
@@ -281,6 +283,88 @@ public:
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CheckCapabilities(TExplicitMemoryScopeType memoryScope,
|
||||
TExplicitMemoryOrderType memoryOrder)
|
||||
{
|
||||
/*
|
||||
Differentiation between atomic fence and other atomic operations
|
||||
does not need to occur here.
|
||||
|
||||
The initialisation of this test checks that the minimum required
|
||||
capabilities are supported by this device.
|
||||
|
||||
The following switches allow the test to skip if optional capabilites
|
||||
are not supported by the device.
|
||||
*/
|
||||
switch (memoryScope)
|
||||
{
|
||||
case MEMORY_SCOPE_EMPTY: {
|
||||
break;
|
||||
}
|
||||
case MEMORY_SCOPE_WORK_GROUP: {
|
||||
if ((gAtomicMemCap & CL_DEVICE_ATOMIC_SCOPE_WORK_GROUP) == 0)
|
||||
{
|
||||
return TEST_SKIPPED_ITSELF;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MEMORY_SCOPE_DEVICE: {
|
||||
if ((gAtomicMemCap & CL_DEVICE_ATOMIC_SCOPE_DEVICE) == 0)
|
||||
{
|
||||
return TEST_SKIPPED_ITSELF;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MEMORY_SCOPE_ALL_SVM_DEVICES: {
|
||||
if ((gAtomicMemCap & CL_DEVICE_ATOMIC_SCOPE_ALL_DEVICES) == 0)
|
||||
{
|
||||
return TEST_SKIPPED_ITSELF;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
log_info("Invalid memory scope\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (memoryOrder)
|
||||
{
|
||||
case MEMORY_ORDER_EMPTY: {
|
||||
break;
|
||||
}
|
||||
case MEMORY_ORDER_RELAXED: {
|
||||
if ((gAtomicMemCap & CL_DEVICE_ATOMIC_ORDER_RELAXED) == 0)
|
||||
{
|
||||
return TEST_SKIPPED_ITSELF;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MEMORY_ORDER_ACQUIRE:
|
||||
case MEMORY_ORDER_RELEASE:
|
||||
case MEMORY_ORDER_ACQ_REL: {
|
||||
if ((gAtomicMemCap & CL_DEVICE_ATOMIC_ORDER_ACQ_REL) == 0)
|
||||
{
|
||||
return TEST_SKIPPED_ITSELF;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MEMORY_ORDER_SEQ_CST: {
|
||||
if ((gAtomicMemCap & CL_DEVICE_ATOMIC_ORDER_SEQ_CST) == 0)
|
||||
{
|
||||
return TEST_SKIPPED_ITSELF;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
log_info("Invalid memory order\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
virtual bool SVMDataBufferAllSVMConsistent() {return false;}
|
||||
bool UseSVM() {return _useSVM;}
|
||||
void StartValue(HostDataType startValue) {_startValue = startValue;}
|
||||
@@ -339,6 +423,7 @@ class CBasicTestMemOrderScope : public CBasicTest<HostAtomicType, HostDataType>
|
||||
public:
|
||||
using CBasicTest<HostAtomicType, HostDataType>::LocalMemory;
|
||||
using CBasicTest<HostAtomicType, HostDataType>::MaxGroupSize;
|
||||
using CBasicTest<HostAtomicType, HostDataType>::CheckCapabilities;
|
||||
CBasicTestMemOrderScope(TExplicitAtomicType dataType, bool useSVM = false) : CBasicTest<HostAtomicType, HostDataType>(dataType, useSVM)
|
||||
{
|
||||
}
|
||||
@@ -389,6 +474,10 @@ public:
|
||||
MaxGroupSize(16); // increase number of groups by forcing smaller group size
|
||||
else
|
||||
MaxGroupSize(0); // group size limited by device capabilities
|
||||
|
||||
if (CheckCapabilities(MemoryScope(), MemoryOrder()) == TEST_SKIPPED_ITSELF)
|
||||
return 0; // skip test - not applicable
|
||||
|
||||
return CBasicTest<HostAtomicType, HostDataType>::ExecuteSingleTest(deviceID, context, queue);
|
||||
}
|
||||
virtual int ExecuteForEachParameterSet(cl_device_id deviceID, cl_context context, cl_command_queue queue)
|
||||
@@ -470,6 +559,8 @@ public:
|
||||
using CBasicTestMemOrderScope<HostAtomicType, HostDataType>::MemoryScope;
|
||||
using CBasicTestMemOrderScope<HostAtomicType, HostDataType>::MemoryOrderStr;
|
||||
using CBasicTestMemOrderScope<HostAtomicType, HostDataType>::MemoryScopeStr;
|
||||
using CBasicTest<HostAtomicType, HostDataType>::CheckCapabilities;
|
||||
|
||||
CBasicTestMemOrder2Scope(TExplicitAtomicType dataType, bool useSVM = false) : CBasicTestMemOrderScope<HostAtomicType, HostDataType>(dataType, useSVM)
|
||||
{
|
||||
}
|
||||
@@ -517,6 +608,15 @@ public:
|
||||
MemoryOrder(memoryOrder[oi]);
|
||||
MemoryOrder2(memoryOrder[o2i]);
|
||||
MemoryScope(memoryScope[si]);
|
||||
|
||||
if (CheckCapabilities(MemoryScope(), MemoryOrder())
|
||||
== TEST_SKIPPED_ITSELF)
|
||||
continue; // skip test - not applicable
|
||||
|
||||
if (CheckCapabilities(MemoryScope(), MemoryOrder2())
|
||||
== TEST_SKIPPED_ITSELF)
|
||||
continue; // skip test - not applicable
|
||||
|
||||
EXECUTE_TEST(error, (CBasicTest<HostAtomicType, HostDataType>::ExecuteForEachParameterSet(deviceID, context, queue)));
|
||||
}
|
||||
}
|
||||
@@ -855,8 +955,9 @@ int CBasicTest<HostAtomicType, HostDataType>::ExecuteSingleTest(cl_device_id dev
|
||||
// Set up the kernel code
|
||||
programSource = PragmaHeader(deviceID)+ProgramHeader(numDestItems)+FunctionCode()+KernelCode(numDestItems);
|
||||
programLine = programSource.c_str();
|
||||
if(create_single_kernel_helper_with_build_options(context, &program, &kernel, 1, &programLine, "test_atomic_kernel",
|
||||
gOldAPI ? "" : "-cl-std=CL2.0"))
|
||||
if (create_single_kernel_helper_with_build_options(
|
||||
context, &program, &kernel, 1, &programLine, "test_atomic_kernel",
|
||||
gOldAPI ? "" : nullptr))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -26,6 +26,8 @@ bool gUseHostPtr = false; // use malloc/free with CL_MEM_USE_HOST_PTR instead of
|
||||
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
|
||||
cl_device_atomic_capabilities gAtomicMemCap,
|
||||
gAtomicFenceCap; // atomic memory and fence capabilities for this 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);
|
||||
@@ -108,6 +110,7 @@ const int test_num = ARRAY_SIZE( test_list );
|
||||
test_status InitCL(cl_device_id device) {
|
||||
auto version = get_device_cl_version(device);
|
||||
auto expected_min_version = Version(2, 0);
|
||||
|
||||
if (version < expected_min_version)
|
||||
{
|
||||
version_expected_info("Test", "OpenCL",
|
||||
@@ -115,6 +118,63 @@ test_status InitCL(cl_device_id device) {
|
||||
version.to_string().c_str());
|
||||
return TEST_SKIP;
|
||||
}
|
||||
|
||||
if (version >= Version(3, 0))
|
||||
{
|
||||
cl_int error;
|
||||
|
||||
error = clGetDeviceInfo(device, CL_DEVICE_ATOMIC_MEMORY_CAPABILITIES,
|
||||
sizeof(gAtomicMemCap), &gAtomicMemCap, NULL);
|
||||
if (error != CL_SUCCESS)
|
||||
{
|
||||
print_error(error, "Unable to get atomic memory capabilities\n");
|
||||
return TEST_FAIL;
|
||||
}
|
||||
|
||||
error =
|
||||
clGetDeviceInfo(device, CL_DEVICE_ATOMIC_FENCE_CAPABILITIES,
|
||||
sizeof(gAtomicFenceCap), &gAtomicFenceCap, NULL);
|
||||
if (error != CL_SUCCESS)
|
||||
{
|
||||
print_error(error, "Unable to get atomic fence capabilities\n");
|
||||
return TEST_FAIL;
|
||||
}
|
||||
|
||||
if ((gAtomicFenceCap
|
||||
& (CL_DEVICE_ATOMIC_ORDER_RELAXED | CL_DEVICE_ATOMIC_ORDER_ACQ_REL
|
||||
| CL_DEVICE_ATOMIC_SCOPE_WORK_GROUP))
|
||||
== 0)
|
||||
{
|
||||
log_info(
|
||||
"Minimum atomic fence capabilities unsupported by device\n");
|
||||
return TEST_FAIL;
|
||||
}
|
||||
|
||||
if ((gAtomicMemCap
|
||||
& (CL_DEVICE_ATOMIC_ORDER_RELAXED
|
||||
| CL_DEVICE_ATOMIC_SCOPE_WORK_GROUP))
|
||||
== 0)
|
||||
{
|
||||
log_info(
|
||||
"Minimum atomic memory capabilities unsupported by device\n");
|
||||
return TEST_FAIL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// OpenCL 2.x device, default to all capabilities
|
||||
gAtomicMemCap = CL_DEVICE_ATOMIC_ORDER_RELAXED
|
||||
| CL_DEVICE_ATOMIC_ORDER_ACQ_REL | CL_DEVICE_ATOMIC_ORDER_SEQ_CST
|
||||
| CL_DEVICE_ATOMIC_SCOPE_WORK_GROUP | CL_DEVICE_ATOMIC_SCOPE_DEVICE
|
||||
| CL_DEVICE_ATOMIC_SCOPE_ALL_DEVICES;
|
||||
|
||||
gAtomicFenceCap = CL_DEVICE_ATOMIC_ORDER_RELAXED
|
||||
| CL_DEVICE_ATOMIC_ORDER_ACQ_REL | CL_DEVICE_ATOMIC_ORDER_SEQ_CST
|
||||
| CL_DEVICE_ATOMIC_SCOPE_WORK_ITEM
|
||||
| CL_DEVICE_ATOMIC_SCOPE_WORK_GROUP | CL_DEVICE_ATOMIC_SCOPE_DEVICE
|
||||
| CL_DEVICE_ATOMIC_SCOPE_ALL_DEVICES;
|
||||
}
|
||||
|
||||
return TEST_PASS;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,9 @@ class CBasicTestStore : public CBasicTestMemOrderScope<HostAtomicType, HostDataT
|
||||
public:
|
||||
using CBasicTestMemOrderScope<HostAtomicType, HostDataType>::OldValueCheck;
|
||||
using CBasicTestMemOrderScope<HostAtomicType, HostDataType>::MemoryOrder;
|
||||
using CBasicTestMemOrderScope<HostAtomicType, HostDataType>::MemoryScope;
|
||||
using CBasicTestMemOrderScope<HostAtomicType, HostDataType>::MemoryOrderScopeStr;
|
||||
using CBasicTest<HostAtomicType, HostDataType>::CheckCapabilities;
|
||||
CBasicTestStore(TExplicitAtomicType dataType, bool useSVM) : CBasicTestMemOrderScope<HostAtomicType, HostDataType>(dataType, useSVM)
|
||||
{
|
||||
OldValueCheck(false);
|
||||
@@ -43,6 +45,10 @@ public:
|
||||
if(MemoryOrder() == MEMORY_ORDER_ACQUIRE ||
|
||||
MemoryOrder() == MEMORY_ORDER_ACQ_REL)
|
||||
return 0; //skip test - not applicable
|
||||
|
||||
if (CheckCapabilities(MemoryScope(), MemoryOrder()) == TEST_SKIPPED_ITSELF)
|
||||
return 0; // skip test - not applicable
|
||||
|
||||
return CBasicTestMemOrderScope<HostAtomicType, HostDataType>::ExecuteSingleTest(deviceID, context, queue);
|
||||
}
|
||||
virtual std::string ProgramCore()
|
||||
@@ -198,7 +204,9 @@ class CBasicTestLoad : public CBasicTestMemOrderScope<HostAtomicType, HostDataTy
|
||||
public:
|
||||
using CBasicTestMemOrderScope<HostAtomicType, HostDataType>::OldValueCheck;
|
||||
using CBasicTestMemOrderScope<HostAtomicType, HostDataType>::MemoryOrder;
|
||||
using CBasicTestMemOrderScope<HostAtomicType, HostDataType>::MemoryScope;
|
||||
using CBasicTestMemOrderScope<HostAtomicType, HostDataType>::MemoryOrderScopeStr;
|
||||
using CBasicTest<HostAtomicType, HostDataType>::CheckCapabilities;
|
||||
CBasicTestLoad(TExplicitAtomicType dataType, bool useSVM) : CBasicTestMemOrderScope<HostAtomicType, HostDataType>(dataType, useSVM)
|
||||
{
|
||||
OldValueCheck(false);
|
||||
@@ -212,6 +220,10 @@ public:
|
||||
if(MemoryOrder() == MEMORY_ORDER_RELEASE ||
|
||||
MemoryOrder() == MEMORY_ORDER_ACQ_REL)
|
||||
return 0; //skip test - not applicable
|
||||
|
||||
if (CheckCapabilities(MemoryScope(), MemoryOrder()) == TEST_SKIPPED_ITSELF)
|
||||
return 0; // skip test - not applicable
|
||||
|
||||
return CBasicTestMemOrderScope<HostAtomicType, HostDataType>::ExecuteSingleTest(deviceID, context, queue);
|
||||
}
|
||||
virtual std::string ProgramCore()
|
||||
@@ -435,9 +447,11 @@ public:
|
||||
using CBasicTestMemOrder2Scope<HostAtomicType, HostDataType>::MemoryOrder;
|
||||
using CBasicTestMemOrder2Scope<HostAtomicType, HostDataType>::MemoryOrder2;
|
||||
using CBasicTestMemOrder2Scope<HostAtomicType, HostDataType>::MemoryOrderScope;
|
||||
using CBasicTestMemOrder2Scope<HostAtomicType, HostDataType>::MemoryScope;
|
||||
using CBasicTestMemOrder2Scope<HostAtomicType, HostDataType>::DataType;
|
||||
using CBasicTestMemOrder2Scope<HostAtomicType, HostDataType>::Iterations;
|
||||
using CBasicTestMemOrder2Scope<HostAtomicType, HostDataType>::IterationsStr;
|
||||
using CBasicTest<HostAtomicType, HostDataType>::CheckCapabilities;
|
||||
CBasicTestCompareStrong(TExplicitAtomicType dataType, bool useSVM) : CBasicTestMemOrder2Scope<HostAtomicType, HostDataType>(dataType, useSVM)
|
||||
{
|
||||
StartValue(123456);
|
||||
@@ -451,6 +465,13 @@ public:
|
||||
if((MemoryOrder() == MEMORY_ORDER_RELAXED && MemoryOrder2() != MEMORY_ORDER_RELAXED) ||
|
||||
(MemoryOrder() != MEMORY_ORDER_SEQ_CST && MemoryOrder2() == MEMORY_ORDER_SEQ_CST))
|
||||
return 0; // failure argument shall be no stronger than the success
|
||||
|
||||
if (CheckCapabilities(MemoryScope(), MemoryOrder()) == TEST_SKIPPED_ITSELF)
|
||||
return 0; // skip test - not applicable
|
||||
|
||||
if (CheckCapabilities(MemoryScope(), MemoryOrder2()) == TEST_SKIPPED_ITSELF)
|
||||
return 0; // skip test - not applicable
|
||||
|
||||
return CBasicTestMemOrder2Scope<HostAtomicType, HostDataType>::ExecuteSingleTest(deviceID, context, queue);
|
||||
}
|
||||
virtual std::string ProgramCore()
|
||||
|
||||
Reference in New Issue
Block a user