#include "testBase.h"
#include "harness/testHarness.h"
#include "harness/deviceInfo.h"
static const char* test_kernel = R"CLC(
__kernel void test(__global int* dst) {
dst[0] = 0;
}
)CLC";
int test_consistency_svm(cl_device_id deviceID, cl_context context,
cl_command_queue queue, int num_elements)
{
cl_int error;
const size_t allocSize = 16;
clMemWrapper mem;
clProgramWrapper program;
clKernelWrapper kernel;
cl_device_svm_capabilities svmCaps = 0;
error = clGetDeviceInfo(deviceID, CL_DEVICE_SVM_CAPABILITIES,
sizeof(svmCaps), &svmCaps, NULL);
test_error(error, "Unable to query CL_DEVICE_SVM_CAPABILITIES");
if (svmCaps == 0)
{
mem =
clCreateBuffer(context, CL_MEM_READ_WRITE, allocSize, NULL, &error);
test_error(error, "Unable to create test buffer");
error = create_single_kernel_helper(context, &program, &kernel, 1,
&test_kernel, "test");
test_error(error, "Unable to create test kernel");
cl_bool usesSVMPointer;
error =
clGetMemObjectInfo(mem, CL_MEM_USES_SVM_POINTER,
sizeof(usesSVMPointer), &usesSVMPointer, NULL);
test_error(error, "Unable to query CL_MEM_USES_SVM_POINTER");
test_assert_error(usesSVMPointer == CL_FALSE,
"CL_DEVICE_SVM_CAPABILITIES returned 0 but "
"CL_MEM_USES_SVM_POINTER did not return CL_FALSE");
void* ptr0 = clSVMAlloc(context, CL_MEM_READ_WRITE, allocSize, 0);
void* ptr1 = clSVMAlloc(context, CL_MEM_READ_WRITE, allocSize, 0);
test_assert_error(ptr0 == NULL && ptr1 == NULL,
"CL_DEVICE_SVM_CAPABILITIES returned 0 but "
"clSVMAlloc returned a non-NULL value");
void* bogus0 = (void*)0xDEADBEEF;
void* bogus1 = (void*)0xDEADDEAD;
cl_uint pattern = 0xAAAAAAAA;
error = clEnqueueSVMMemFill(queue, bogus0, &pattern, sizeof(pattern),
allocSize, 0, NULL, NULL);
test_failure_error(
error, CL_INVALID_OPERATION,
"CL_DEVICE_SVM_CAPABILITIES returned 0 but clEnqueueSVMMemFill did "
"not return CL_INVALID_OPERATION");
error = clEnqueueSVMMemcpy(queue, CL_TRUE, bogus1, bogus0, allocSize, 0,
NULL, NULL);
test_failure_error(
error, CL_INVALID_OPERATION,
"CL_DEVICE_SVM_CAPABILITIES returned 0 but "
"clEnqueueSVMMemcpy did not return CL_INVALID_OPERATION");
error = clEnqueueSVMMap(queue, CL_TRUE, CL_MAP_READ, bogus1, allocSize,
0, NULL, NULL);
test_failure_error(
error, CL_INVALID_OPERATION,
"CL_DEVICE_SVM_CAPABILITIES returned 0 but "
"clEnqueueSVMMap did not return CL_INVALID_OPERATION");
error = clEnqueueSVMUnmap(queue, bogus1, 0, NULL, NULL);
test_failure_error(
error, CL_INVALID_OPERATION,
"CL_DEVICE_SVM_CAPABILITIES returned 0 but "
"clEnqueueSVMUnmap did not return CL_INVALID_OPERATION");
error = clEnqueueSVMMigrateMem(queue, 1, (const void**)&bogus1, NULL, 0,
0, NULL, NULL);
test_failure_error(
error, CL_INVALID_OPERATION,
"CL_DEVICE_SVM_CAPABILITIES returned 0 but "
"clEnqueueSVMMigrateMem did not return CL_INVALID_OPERATION");
clSVMFree(context, bogus0);
error = clEnqueueSVMFree(queue, 1, &bogus0, NULL, NULL, 0, NULL, NULL);
test_failure_error(
error, CL_INVALID_OPERATION,
"CL_DEVICE_SVM_CAPABILITIES returned 0 but "
"clEnqueueSVMFree did not return CL_INVALID_OPERATION");
error = clSetKernelArgSVMPointer(kernel, 0, NULL);
test_failure_error(
error, CL_INVALID_OPERATION,
"CL_DEVICE_SVM_CAPABILITIES returned 0 but "
"clSetKernelArgSVMPointer did not return CL_INVALID_OPERATION");
error =
clSetKernelExecInfo(kernel, CL_KERNEL_EXEC_INFO_SVM_PTRS, 0, NULL);
test_failure_error(
error, CL_INVALID_OPERATION,
"CL_DEVICE_SVM_CAPABILITIES returned 0 but "
"clSetKernelExecInfo did not return CL_INVALID_OPERATION");
}
return TEST_PASS;
}
static int check_atomic_capabilities(cl_device_atomic_capabilities atomicCaps,
cl_device_atomic_capabilities requiredCaps)
{
if ((atomicCaps & requiredCaps) != requiredCaps)
{
log_error("Atomic capabilities %llx is missing support for at least "
"one required capability %llx!\n",
atomicCaps, requiredCaps);
return TEST_FAIL;
}
if ((atomicCaps & CL_DEVICE_ATOMIC_SCOPE_ALL_DEVICES) != 0
&& (atomicCaps & CL_DEVICE_ATOMIC_SCOPE_DEVICE) == 0)
{
log_error("Support for CL_DEVICE_ATOMIC_SCOPE_ALL_DEVICES requires "
"support for CL_DEVICE_ATOMIC_SCOPE_DEVICE!\n");
return TEST_FAIL;
}
if ((atomicCaps & CL_DEVICE_ATOMIC_SCOPE_DEVICE) != 0
&& (atomicCaps & CL_DEVICE_ATOMIC_SCOPE_WORK_GROUP) == 0)
{
log_error("Support for CL_DEVICE_ATOMIC_SCOPE_DEVICE requires "
"support for CL_DEVICE_ATOMIC_SCOPE_WORK_GROUP!\n");
return TEST_FAIL;
}
if ((atomicCaps & CL_DEVICE_ATOMIC_ORDER_SEQ_CST) != 0
&& (atomicCaps & CL_DEVICE_ATOMIC_ORDER_ACQ_REL) == 0)
{
log_error("Support for CL_DEVICE_ATOMIC_ORDER_SEQ_CST requires "
"support for CL_DEVICE_ATOMIC_ORDER_ACQ_REL!\n");
return TEST_FAIL;
}
if ((atomicCaps & CL_DEVICE_ATOMIC_ORDER_ACQ_REL) != 0
&& (atomicCaps & CL_DEVICE_ATOMIC_ORDER_RELAXED) == 0)
{
log_error("Support for CL_DEVICE_ATOMIC_ORDER_ACQ_REL requires "
"support for CL_DEVICE_ATOMIC_ORDER_RELAXED!\n");
return TEST_FAIL;
}
return TEST_PASS;
}
int test_consistency_memory_model(cl_device_id deviceID, cl_context context,
cl_command_queue queue, int num_elements)
{
cl_int error;
cl_device_atomic_capabilities atomicCaps = 0;
error = clGetDeviceInfo(deviceID, CL_DEVICE_ATOMIC_MEMORY_CAPABILITIES,
sizeof(atomicCaps), &atomicCaps, NULL);
test_error(error, "Unable to query CL_DEVICE_ATOMIC_MEMORY_CAPABILITIES");
error = check_atomic_capabilities(atomicCaps,
CL_DEVICE_ATOMIC_ORDER_RELAXED
| CL_DEVICE_ATOMIC_SCOPE_WORK_GROUP);
if (error == TEST_FAIL)
{
log_error("Checks failed for CL_DEVICE_ATOMIC_MEMORY_CAPABILITIES\n");
return error;
}
error = clGetDeviceInfo(deviceID, CL_DEVICE_ATOMIC_FENCE_CAPABILITIES,
sizeof(atomicCaps), &atomicCaps, NULL);
test_error(error, "Unable to query CL_DEVICE_ATOMIC_FENCE_CAPABILITIES");
error = check_atomic_capabilities(atomicCaps,
CL_DEVICE_ATOMIC_ORDER_RELAXED
| CL_DEVICE_ATOMIC_ORDER_ACQ_REL
| CL_DEVICE_ATOMIC_SCOPE_WORK_GROUP);
if (error == TEST_FAIL)
{
log_error("Checks failed for CL_DEVICE_ATOMIC_FENCE_CAPABILITIES\n");
return error;
}
return TEST_PASS;
}
int test_consistency_device_enqueue(cl_device_id deviceID, cl_context context,
cl_command_queue queue, int num_elements)
{
cl_int error;
cl_device_device_enqueue_capabilities dseCaps = 0;
error = clGetDeviceInfo(deviceID, CL_DEVICE_DEVICE_ENQUEUE_CAPABILITIES,
sizeof(dseCaps), &dseCaps, NULL);
test_error(error, "Unable to query CL_DEVICE_DEVICE_ENQUEUE_CAPABILITIES");
if (dseCaps == 0)
{
cl_command_queue_properties devQueueProps = 0;
error = clGetDeviceInfo(deviceID, CL_DEVICE_QUEUE_ON_DEVICE_PROPERTIES,
sizeof(devQueueProps), &devQueueProps, NULL);
test_error(error,
"Unable to query CL_DEVICE_QUEUE_ON_DEVICE_PROPERTIES");
test_assert_error(
devQueueProps == 0,
"CL_DEVICE_DEVICE_ENQUEUE_CAPABILITIES returned 0 but "
"CL_DEVICE_QUEUE_ON_DEVICE_PROPERTIES returned a non-zero value");
cl_uint u = 0;
error =
clGetDeviceInfo(deviceID, CL_DEVICE_QUEUE_ON_DEVICE_PREFERRED_SIZE,
sizeof(u), &u, NULL);
test_error(error,
"Unable to query CL_DEVICE_QUEUE_ON_DEVICE_PREFERRED_SIZE");
test_assert_error(u == 0,
"CL_DEVICE_DEVICE_ENQUEUE_CAPABILITIES returned 0 "
"but CL_DEVICE_QUEUE_ON_DEVICE_PREFERRED_SIZE "
"returned a non-zero value");
error = clGetDeviceInfo(deviceID, CL_DEVICE_QUEUE_ON_DEVICE_MAX_SIZE,
sizeof(u), &u, NULL);
test_error(error, "Unable to query CL_DEVICE_QUEUE_ON_DEVICE_MAX_SIZE");
test_assert_error(
u == 0,
"CL_DEVICE_DEVICE_ENQUEUE_CAPABILITIES returned 0 but "
"CL_DEVICE_QUEUE_ON_DEVICE_MAX_SIZE returned a non-zero value");
error = clGetDeviceInfo(deviceID, CL_DEVICE_MAX_ON_DEVICE_QUEUES,
sizeof(u), &u, NULL);
test_error(error, "Unable to query CL_DEVICE_MAX_ON_DEVICE_QUEUES");
test_assert_error(
u == 0,
"CL_DEVICE_DEVICE_ENQUEUE_CAPABILITIES returned 0 but "
"CL_DEVICE_MAX_ON_DEVICE_QUEUES returned a non-zero value");
error = clGetDeviceInfo(deviceID, CL_DEVICE_MAX_ON_DEVICE_EVENTS,
sizeof(u), &u, NULL);
test_error(error, "Unable to query CL_DEVICE_MAX_ON_DEVICE_EVENTS");
test_assert_error(
u == 0,
"CL_DEVICE_DEVICE_ENQUEUE_CAPABILITIES returned 0 but "
"CL_DEVICE_MAX_ON_DEVICE_EVENTS returned a non-zero value");
error =
clGetCommandQueueInfo(queue, CL_QUEUE_SIZE, sizeof(u), &u, NULL);
test_failure_error(
error, CL_INVALID_COMMAND_QUEUE,
"CL_DEVICE_DEVICE_ENQUEUE_CAPABILITIES returned 0 but "
"CL_QUEUE_SIZE did not return CL_INVALID_COMMAND_QUEUE");
cl_command_queue q = NULL;
error = clGetCommandQueueInfo(queue, CL_QUEUE_DEVICE_DEFAULT, sizeof(q),
&q, NULL);
test_error(error, "Unable to query CL_QUEUE_DEVICE_DEFAULT");
test_assert_error(
q == NULL,
"CL_DEVICE_DEVICE_ENQUEUE_CAPABILITIES returned 0 but "
"CL_QUEUE_DEVICE_DEFAULT returned a non-NULL value");
error = clSetDefaultDeviceCommandQueue(context, deviceID, NULL);
test_failure_error(error, CL_INVALID_OPERATION,
"CL_DEVICE_DEVICE_ENQUEUE_CAPABILITIES returned 0 "
"but clSetDefaultDeviceCommandQueue did not return "
"CL_INVALID_OPERATION");
}
else
{
if ((dseCaps & CL_DEVICE_QUEUE_REPLACEABLE_DEFAULT) == 0)
{
error = clSetDefaultDeviceCommandQueue(context, deviceID, NULL);
test_failure_error(
error, CL_INVALID_OPERATION,
"CL_DEVICE_DEVICE_ENQUEUE_CAPABILITIES did not "
"include CL_DEVICE_QUEUE_REPLACEABLE_DEFAULT but "
"clSetDefaultDeviceCommandQueue did not return "
"CL_INVALID_OPERATION");
}
if ((dseCaps & CL_DEVICE_QUEUE_REPLACEABLE_DEFAULT) != 0
&& (dseCaps & CL_DEVICE_QUEUE_SUPPORTED) == 0)
{
log_error("DEVICE_QUEUE_REPLACEABLE_DEFAULT is set but "
"DEVICE_QUEUE_SUPPORTED is not set\n");
return TEST_FAIL;
}
if ((dseCaps & CL_DEVICE_QUEUE_SUPPORTED) != 0)
{
cl_bool b;
error = clGetDeviceInfo(deviceID,
CL_DEVICE_GENERIC_ADDRESS_SPACE_SUPPORT,
sizeof(b), &b, NULL);
test_error(
error,
"Unable to query CL_DEVICE_GENERIC_ADDRESS_SPACE_SUPPORT");
test_assert_error(
b == CL_TRUE,
"DEVICE_QUEUE_SUPPORTED is set but "
"CL_DEVICE_GENERIC_ADDRESS_SPACE_SUPPORT returned CL_FALSE");
}
}
return TEST_PASS;
}
int test_consistency_pipes(cl_device_id deviceID, cl_context context,
cl_command_queue queue, int num_elements)
{
cl_int error;
cl_bool pipeSupport = CL_FALSE;
error = clGetDeviceInfo(deviceID, CL_DEVICE_PIPE_SUPPORT,
sizeof(pipeSupport), &pipeSupport, NULL);
test_error(error, "Unable to query CL_DEVICE_PIPE_SUPPORT");
if (pipeSupport == CL_FALSE)
{
cl_uint u = 0;
error = clGetDeviceInfo(deviceID, CL_DEVICE_MAX_PIPE_ARGS, sizeof(u),
&u, NULL);
test_error(error, "Unable to query CL_DEVICE_MAX_PIPE_ARGS");
test_assert_error(u == 0,
"CL_DEVICE_PIPE_SUPPORT returned CL_FALSE, but "
"CL_DEVICE_MAX_PIPE_ARGS returned a non-zero value");
error =
clGetDeviceInfo(deviceID, CL_DEVICE_PIPE_MAX_ACTIVE_RESERVATIONS,
sizeof(u), &u, NULL);
test_error(error,
"Unable to query CL_DEVICE_PIPE_MAX_ACTIVE_RESERVATIONS");
test_assert_error(u == 0,
"CL_DEVICE_PIPE_SUPPORT returned CL_FALSE, but "
"CL_DEVICE_PIPE_MAX_ACTIVE_RESERVATIONS returned "
"a non-zero value");
error = clGetDeviceInfo(deviceID, CL_DEVICE_PIPE_MAX_PACKET_SIZE,
sizeof(u), &u, NULL);
test_error(error, "Unable to query CL_DEVICE_PIPE_MAX_PACKET_SIZE");
test_assert_error(
u == 0,
"CL_DEVICE_PIPE_SUPPORT returned CL_FALSE, but "
"CL_DEVICE_PIPE_MAX_PACKET_SIZE returned a non-zero value");
clMemWrapper mem =
clCreatePipe(context, CL_MEM_HOST_NO_ACCESS, 4, 4, NULL, &error);
test_failure_error(error, CL_INVALID_OPERATION,
"CL_DEVICE_PIPE_SUPPORT returned CL_FALSE but "
"clCreatePipe did not return CL_INVALID_OPERATION");
clMemWrapper not_a_pipe =
clCreateBuffer(context, CL_MEM_READ_WRITE, 4, NULL, &error);
test_error(error, "Unable to create non-pipe buffer");
error =
clGetPipeInfo(not_a_pipe, CL_PIPE_PACKET_SIZE, sizeof(u), &u, NULL);
test_failure_error(
error, CL_INVALID_MEM_OBJECT,
"CL_DEVICE_PIPE_SUPPORT returned CL_FALSE but clGetPipeInfo did "
"not return CL_INVALID_MEM_OBJECT");
}
else
{
cl_bool b;
error =
clGetDeviceInfo(deviceID, CL_DEVICE_GENERIC_ADDRESS_SPACE_SUPPORT,
sizeof(b), &b, NULL);
test_error(error,
"Unable to query CL_DEVICE_GENERIC_ADDRESS_SPACE_SUPPORT");
test_assert_error(
b == CL_TRUE,
"CL_DEVICE_PIPE_SUPPORT returned CL_TRUE but "
"CL_DEVICE_GENERIC_ADDRESS_SPACE_SUPPORT returned CL_FALSE");
}
return TEST_PASS;
}
int test_consistency_progvar(cl_device_id deviceID, cl_context context,
cl_command_queue queue, int num_elements)
{
cl_int error;
clProgramWrapper program;
clKernelWrapper kernel;
size_t maxGlobalVariableSize = 0;
error = clGetDeviceInfo(deviceID, CL_DEVICE_MAX_GLOBAL_VARIABLE_SIZE,
sizeof(maxGlobalVariableSize),
&maxGlobalVariableSize, NULL);
test_error(error, "Unable to query CL_DEVICE_MAX_GLOBAL_VARIABLE_SIZE");
if (maxGlobalVariableSize == 0)
{
error = create_single_kernel_helper(context, &program, &kernel, 1,
&test_kernel, "test");
test_error(error, "Unable to create test kernel");
size_t sz = SIZE_MAX;
error = clGetDeviceInfo(deviceID,
CL_DEVICE_GLOBAL_VARIABLE_PREFERRED_TOTAL_SIZE,
sizeof(sz), &sz, NULL);
test_error(
error,
"Unable to query CL_DEVICE_GLOBAL_VARIABLE_PREFERRED_TOTAL_SIZE");
test_assert_error(
sz == 0,
"CL_DEVICE_MAX_GLOBAL_VARIABLE_SIZE returned 0 but "
"CL_DEVICE_GLOBAL_VARIABLE_PREFERRED_TOTAL_SIZE returned a "
"non-zero value");
error = clGetProgramBuildInfo(
program, deviceID, CL_PROGRAM_BUILD_GLOBAL_VARIABLE_TOTAL_SIZE,
sizeof(sz), &sz, NULL);
test_error(
error,
"Unable to query CL_PROGRAM_BUILD_GLOBAL_VARIABLE_TOTAL_SIZE");
test_assert_error(sz == 0,
"CL_DEVICE_MAX_GLOBAL_VARIABLE_SIZE returned 0 "
"but CL_PROGRAM_BUILD_GLOBAL_VARIABLE_TOTAL_SIZE "
"returned a non-zero value");
}
return TEST_PASS;
}
int test_consistency_non_uniform_work_group(cl_device_id deviceID,
cl_context context,
cl_command_queue queue,
int num_elements)
{
cl_int error;
const size_t allocSize = 16;
clMemWrapper mem;
clProgramWrapper program;
clKernelWrapper kernel;
cl_bool nonUniformWorkGroupSupport = CL_FALSE;
error = clGetDeviceInfo(deviceID, CL_DEVICE_NON_UNIFORM_WORK_GROUP_SUPPORT,
sizeof(nonUniformWorkGroupSupport),
&nonUniformWorkGroupSupport, NULL);
test_error(error,
"Unable to query CL_DEVICE_NON_UNIFORM_WORK_GROUP_SUPPORT");
if (nonUniformWorkGroupSupport == CL_FALSE)
{
mem =
clCreateBuffer(context, CL_MEM_READ_WRITE, allocSize, NULL, &error);
test_error(error, "Unable to create test buffer");
error = create_single_kernel_helper(context, &program, &kernel, 1,
&test_kernel, "test");
test_error(error, "Unable to create test kernel");
error = clSetKernelArg(kernel, 0, sizeof(mem), &mem);
size_t global_work_size[] = { 3, 3, 3 };
size_t local_work_size[] = { 2, 2, 2 };
error = clEnqueueNDRangeKernel(queue, kernel, 1, NULL, global_work_size,
NULL, 0, NULL, NULL);
test_error(error,
"Unable to enqueue kernel with a NULL local work size");
error = clFinish(queue);
test_error(error, "Error calling clFinish after NULL local work size");
error = clEnqueueNDRangeKernel(queue, kernel, 1, NULL, global_work_size,
local_work_size, 0, NULL, NULL);
test_failure_error(
error, CL_INVALID_WORK_GROUP_SIZE,
"CL_DEVICE_NON_UNIFORM_WORK_GROUP_SUPPORT returned CL_FALSE but 1D "
"clEnqueueNDRangeKernel did not return CL_INVALID_WORK_GROUP_SIZE");
global_work_size[0] = local_work_size[0];
error = clEnqueueNDRangeKernel(queue, kernel, 2, NULL, global_work_size,
local_work_size, 0, NULL, NULL);
test_failure_error(
error, CL_INVALID_WORK_GROUP_SIZE,
"CL_DEVICE_NON_UNIFORM_WORK_GROUP_SUPPORT returned CL_FALSE but 2D "
"clEnqueueNDRangeKernel did not return CL_INVALID_WORK_GROUP_SIZE");
global_work_size[1] = local_work_size[1];
error = clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size,
local_work_size, 0, NULL, NULL);
test_failure_error(
error, CL_INVALID_WORK_GROUP_SIZE,
"CL_DEVICE_NON_UNIFORM_WORK_GROUP_SUPPORT returned CL_FALSE but 3D "
"clEnqueueNDRangeKernel did not return CL_INVALID_WORK_GROUP_SIZE");
}
return TEST_PASS;
}
int test_consistency_read_write_images(cl_device_id deviceID,
cl_context context,
cl_command_queue queue, int num_elements)
{
cl_int error;
cl_uint maxReadWriteImageArgs = 0;
error = clGetDeviceInfo(deviceID, CL_DEVICE_MAX_READ_WRITE_IMAGE_ARGS,
sizeof(maxReadWriteImageArgs),
&maxReadWriteImageArgs, NULL);
test_error(error,
"Unable to query "
"CL_DEVICE_MAX_READ_WRITE_IMAGE_ARGS");
cl_uint totalReadWriteImageFormats = 0;
const cl_mem_object_type image_types[] = {
CL_MEM_OBJECT_IMAGE1D, CL_MEM_OBJECT_IMAGE1D_BUFFER,
CL_MEM_OBJECT_IMAGE2D, CL_MEM_OBJECT_IMAGE3D,
CL_MEM_OBJECT_IMAGE1D_ARRAY, CL_MEM_OBJECT_IMAGE2D_ARRAY,
};
for (int i = 0; i < ARRAY_SIZE(image_types); i++)
{
cl_uint numImageFormats = 0;
error = clGetSupportedImageFormats(
context, CL_MEM_KERNEL_READ_AND_WRITE, image_types[i], 0, NULL,
&numImageFormats);
test_error(error,
"Unable to query number of CL_MEM_KERNEL_READ_AND_WRITE "
"image formats");
totalReadWriteImageFormats += numImageFormats;
}
if (maxReadWriteImageArgs == 0)
{
test_assert_error(
totalReadWriteImageFormats == 0,
"CL_DEVICE_MAX_READ_WRITE_IMAGE_ARGS returned 0 "
"but clGetSupportedImageFormats(CL_MEM_KERNEL_READ_AND_WRITE) "
"returned a non-empty set");
}
else
{
test_assert_error(
totalReadWriteImageFormats != 0,
"CL_DEVICE_MAX_READ_WRITE_IMAGE_ARGS is non-zero "
"but clGetSupportedImageFormats(CL_MEM_KERNEL_READ_AND_WRITE) "
"returned an empty set");
}
return TEST_PASS;
}
int test_consistency_2d_image_from_buffer(cl_device_id deviceID,
cl_context context,
cl_command_queue queue,
int num_elements)
{
cl_int error;
const cl_image_format imageFormat = { CL_RGBA, CL_UNORM_INT8 };
const size_t imageDim = 2;
const size_t elementSize = 4;
const size_t bufferSize = imageDim * imageDim * elementSize;
clMemWrapper buffer;
clMemWrapper image;
cl_uint imagePitchAlignment = 0;
error = clGetDeviceInfo(deviceID, CL_DEVICE_IMAGE_PITCH_ALIGNMENT,
sizeof(imagePitchAlignment), &imagePitchAlignment,
NULL);
test_error(error,
"Unable to query "
"CL_DEVICE_IMAGE_PITCH_ALIGNMENT");
cl_uint imageBaseAddressAlignment = 0;
error = clGetDeviceInfo(deviceID, CL_DEVICE_IMAGE_BASE_ADDRESS_ALIGNMENT,
sizeof(imageBaseAddressAlignment),
&imageBaseAddressAlignment, NULL);
test_error(error,
"Unable to query "
"CL_DEVICE_IMAGE_BASE_ADDRESS_ALIGNMENT");
bool supports_cl_khr_image2d_from_buffer =
is_extension_available(deviceID, "cl_khr_image2d_from_buffer");
if (imagePitchAlignment == 0 || imageBaseAddressAlignment == 0)
{
buffer =
clCreateBuffer(context, CL_MEM_READ_ONLY, bufferSize, NULL, &error);
test_error(error, "Unable to create test buffer");
test_assert_error(
imagePitchAlignment == 0,
"CL_DEVICE_IMAGE_PITCH_ALIGNMENT returned a non-zero value but "
"CL_DEVICE_IMAGE_BASE_ADDRESS_ALIGNMENT returned 0");
test_assert_error(
imageBaseAddressAlignment == 0,
"CL_DEVICE_IMAGE_BASE_ADDRESS_ALIGNMENT returned a non-zero value "
"but CL_DEVICE_IMAGE_PITCH_ALIGNMENT returned 0");
test_assert_error(supports_cl_khr_image2d_from_buffer == false,
"Device does not support Creating a 2D Image from a "
"Buffer but does support cl_khr_image2d_from_buffer");
cl_image_desc imageDesc = { 0 };
imageDesc.image_type = CL_MEM_OBJECT_IMAGE2D;
imageDesc.image_width = imageDim;
imageDesc.image_height = imageDim;
imageDesc.mem_object = buffer;
image = clCreateImage(context, CL_MEM_READ_ONLY, &imageFormat,
&imageDesc, NULL, &error);
test_failure_error(
error, CL_INVALID_OPERATION,
"Device does not support Creating a 2D Image from a "
"Buffer but clCreateImage did not return CL_INVALID_OPERATION");
image =
clCreateImageWithProperties(context, NULL, CL_MEM_READ_ONLY,
&imageFormat, &imageDesc, NULL, &error);
test_failure_error(error, CL_INVALID_OPERATION,
"Device does not support Creating a 2D Image from a "
"Buffer but clCreateImageWithProperties did not "
"return CL_INVALID_OPERATION");
}
else
{
test_assert_error(supports_cl_khr_image2d_from_buffer,
"Device supports Creating a 2D Image from a Buffer "
"but does not support cl_khr_image2d_from_buffer");
}
return TEST_PASS;
}
int test_consistency_depth_images(cl_device_id deviceID, cl_context context,
cl_command_queue queue, int num_elements)
{
cl_int error;
cl_uint totalDepthImageFormats = 0;
const cl_mem_flags mem_flags[] = {
CL_MEM_WRITE_ONLY,
CL_MEM_READ_WRITE,
CL_MEM_KERNEL_READ_AND_WRITE,
};
for (int i = 0; i < ARRAY_SIZE(mem_flags); i++)
{
cl_uint numImageFormats = 0;
error = clGetSupportedImageFormats(context, mem_flags[i],
CL_MEM_OBJECT_IMAGE2D, 0, NULL,
&numImageFormats);
test_error(
error,
"Unable to query number of CL_MEM_OBJECT_IMAGE2D image formats");
std::vector<cl_image_format> imageFormats(numImageFormats);
error = clGetSupportedImageFormats(
context, mem_flags[i], CL_MEM_OBJECT_IMAGE2D, imageFormats.size(),
imageFormats.data(), NULL);
test_error(error,
"Unable to query CL_MEM_OBJECT_IMAGE2D image formats");
for (auto& imageFormat : imageFormats)
{
if (imageFormat.image_channel_order == CL_DEPTH)
{
totalDepthImageFormats++;
}
}
}
bool supports_cl_khr_depth_images =
is_extension_available(deviceID, "cl_khr_depth_images");
if (totalDepthImageFormats == 0)
{
test_assert_error(supports_cl_khr_depth_images == false,
"Device does not support Depth Images but does "
"support cl_khr_depth_images");
}
else
{
test_assert_error(supports_cl_khr_depth_images,
"Device supports Depth Images but does not support "
"cl_khr_depth_images");
}
return TEST_PASS;
}
int test_consistency_device_and_host_timer(cl_device_id deviceID,
cl_context context,
cl_command_queue queue,
int num_elements)
{
cl_int error;
cl_platform_id platform = NULL;
error = clGetDeviceInfo(deviceID, CL_DEVICE_PLATFORM, sizeof(platform),
&platform, NULL);
test_error(error, "Unable to query CL_DEVICE_PLATFORM");
cl_ulong hostTimerResolution = 0;
error = clGetPlatformInfo(platform, CL_PLATFORM_HOST_TIMER_RESOLUTION,
sizeof(hostTimerResolution), &hostTimerResolution,
NULL);
test_error(error, "Unable to query CL_PLATFORM_HOST_TIMER_RESOLUTION");
if (hostTimerResolution == 0)
{
cl_ulong dt = 0;
cl_ulong ht = 0;
error = clGetDeviceAndHostTimer(deviceID, &dt, &ht);
test_failure_error(
error, CL_INVALID_OPERATION,
"CL_PLATFORM_HOST_TIMER_RESOLUTION returned 0 but "
"clGetDeviceAndHostTimer did not return CL_INVALID_OPERATION");
error = clGetHostTimer(deviceID, &ht);
test_failure_error(
error, CL_INVALID_OPERATION,
"CL_PLATFORM_HOST_TIMER_RESOLUTION returned 0 but "
"clGetHostTimer did not return CL_INVALID_OPERATION");
}
return TEST_PASS;
}
int test_consistency_il_programs(cl_device_id deviceID, cl_context context,
cl_command_queue queue, int num_elements)
{
cl_int error;
clProgramWrapper program;
clKernelWrapper kernel;
size_t sz = SIZE_MAX;
error = clGetDeviceInfo(deviceID, CL_DEVICE_IL_VERSION, 0, NULL, &sz);
test_error(error, "Unable to query CL_DEVICE_IL_VERSION");
test_assert_error(sz != 0,
"CL_DEVICE_IL_VERSION should return a non-zero size");
std::string ilVersion = get_device_il_version_string(deviceID);
error = clGetDeviceInfo(deviceID, CL_DEVICE_ILS_WITH_VERSION, 0, NULL, &sz);
test_error(error, "Unable to query CL_DEVICE_ILS_WITH_VERSION");
if (ilVersion == "" || sz == 0)
{
test_assert_error(
ilVersion == "",
"CL_DEVICE_IL_VERSION returned a non-empty string but "
"CL_DEVICE_ILS_WITH_VERSION returned no supported ILs");
test_assert_error(sz == 0,
"CL_DEVICE_ILS_WITH_VERSION returned supported ILs "
"but CL_DEVICE_IL_VERSION returned an empty string");
bool supports_cl_khr_il_program =
is_extension_available(deviceID, "cl_khr_il_program");
test_assert_error(supports_cl_khr_il_program == false,
"Device does not support IL Programs but does "
"support cl_khr_il_program");
error = create_single_kernel_helper(context, &program, &kernel, 1,
&test_kernel, "test");
test_error(error, "Unable to create test kernel");
error = clGetProgramInfo(program, CL_PROGRAM_IL, 0, NULL, &sz);
test_error(error, "Unable to query CL_PROGRAM_IL");
test_assert_error(sz == 0,
"Device does not support IL Programs but "
"CL_PROGRAM_IL returned a non-zero size");
cl_uint bogus = 0xDEADBEEF;
clProgramWrapper ilProgram =
clCreateProgramWithIL(context, &bogus, sizeof(bogus), &error);
test_failure_error(
error, CL_INVALID_OPERATION,
"Device does not support IL Programs but clCreateProgramWithIL did "
"not return CL_INVALID_OPERATION");
cl_uint specConst = 42;
error = clSetProgramSpecializationConstant(
program, 0, sizeof(specConst), &specConst);
test_failure_error(error, CL_INVALID_OPERATION,
"Device does not support IL Programs but "
"clSetProgramSpecializationConstant did not return "
"CL_INVALID_OPERATION");
}
return TEST_PASS;
}
int test_consistency_subgroups(cl_device_id deviceID, cl_context context,
cl_command_queue queue, int num_elements)
{
cl_int error;
clProgramWrapper program;
clKernelWrapper kernel;
cl_uint maxNumSubGroups = 0;
error = clGetDeviceInfo(deviceID, CL_DEVICE_MAX_NUM_SUB_GROUPS,
sizeof(maxNumSubGroups), &maxNumSubGroups, NULL);
test_error(error, "Unable to query CL_DEVICE_MAX_NUM_SUB_GROUPS");
if (maxNumSubGroups == 0)
{
error = create_single_kernel_helper(context, &program, &kernel, 1,
&test_kernel, "test");
test_error(error, "Unable to create test kernel");
cl_bool ifp = CL_FALSE;
error = clGetDeviceInfo(
deviceID, CL_DEVICE_SUB_GROUP_INDEPENDENT_FORWARD_PROGRESS,
sizeof(ifp), &ifp, NULL);
test_error(
error,
"Unable to query CL_DEVICE_SUB_GROUP_INDEPENDENT_FORWARD_PROGRESS");
test_assert_error(ifp == CL_FALSE,
"Device does not support Subgroups but "
"CL_DEVICE_SUB_GROUP_INDEPENDENT_FORWARD_PROGRESS "
"did not return CL_FALSE");
bool supports_cl_khr_subgroups =
is_extension_available(deviceID, "cl_khr_subgroups");
test_assert_error(supports_cl_khr_subgroups == false,
"Device does not support Subgroups but does "
"support cl_khr_subgroups");
size_t sz = SIZE_MAX;
error = clGetKernelSubGroupInfo(kernel, deviceID,
CL_KERNEL_MAX_NUM_SUB_GROUPS, 0, NULL,
sizeof(sz), &sz, NULL);
test_failure_error(
error, CL_INVALID_OPERATION,
"Device does not support Subgroups but clGetKernelSubGroupInfo did "
"not return CL_INVALID_OPERATION");
}
return TEST_PASS;
}
static void CL_CALLBACK program_callback(cl_program, void*) {}
int test_consistency_prog_ctor_dtor(cl_device_id deviceID, cl_context context,
cl_command_queue queue, int num_elements)
{
cl_int error;
clProgramWrapper program;
clKernelWrapper kernel;
error = create_single_kernel_helper(context, &program, &kernel, 1,
&test_kernel, "test");
test_error(error, "Unable to create test kernel");
cl_bool b = CL_FALSE;
error = clGetProgramInfo(program, CL_PROGRAM_SCOPE_GLOBAL_CTORS_PRESENT,
sizeof(b), &b, NULL);
test_error(error, "Unable to query CL_PROGRAM_SCOPE_GLOBAL_CTORS_PRESENT");
test_assert_error(
b == CL_FALSE,
"CL_PROGRAM_SCOPE_GLOBAL_CTORS_PRESENT did not return CL_FALSE");
error = clGetProgramInfo(program, CL_PROGRAM_SCOPE_GLOBAL_DTORS_PRESENT,
sizeof(b), &b, NULL);
test_error(error, "Unable to query CL_PROGRAM_SCOPE_GLOBAL_DTORS_PRESENT");
test_assert_error(
b == CL_FALSE,
"CL_PROGRAM_SCOPE_GLOBAL_DTORS_PRESENT did not return CL_FALSE");
error = clSetProgramReleaseCallback(program, program_callback, NULL);
test_failure_error(
error, CL_INVALID_OPERATION,
"clSetProgramReleaseCallback did not return CL_INVALID_OPERATION");
return TEST_PASS;
}
int test_consistency_3d_image_writes(cl_device_id deviceID, cl_context context,
cl_command_queue queue, int num_elements)
{
cl_int error;
cl_uint total3DImageWriteFormats = 0;
const cl_mem_flags mem_flags[] = {
CL_MEM_WRITE_ONLY,
CL_MEM_READ_WRITE,
CL_MEM_KERNEL_READ_AND_WRITE,
};
for (int i = 0; i < ARRAY_SIZE(mem_flags); i++)
{
cl_uint numImageFormats = 0;
error = clGetSupportedImageFormats(context, mem_flags[i],
CL_MEM_OBJECT_IMAGE3D, 0, NULL,
&numImageFormats);
test_error(
error,
"Unable to query number of CL_MEM_OBJECT_IMAGE3D image formats");
total3DImageWriteFormats += numImageFormats;
}
bool supports_cl_khr_3d_image_writes =
is_extension_available(deviceID, "cl_khr_3d_image_writes");
if (total3DImageWriteFormats == 0)
{
test_assert_error(supports_cl_khr_3d_image_writes == false,
"Device does not support Writing to 3D Image Objects "
"but does support cl_khr_3d_image_writes");
}
else
{
test_assert_error(supports_cl_khr_3d_image_writes,
"Device supports Writing to 3D Image Objects but "
"does not support cl_khr_3d_image_writes");
}
return TEST_PASS;
}