Command-buffer queue compatibility test update (#2230)

Update cl_khr_command_buffer tests to reflect changes from
https://github.com/KhronosGroup/OpenCL-Docs/pull/1292

* Moves negative test for
`CL_DEVICE_COMMAND_BUFFER_SUPPORTED_QUEUE_PROPERTIES_KHR` from
command-buffer creation to enqueue.
* Moves negative test for
`CL_DEVICE_COMMAND_BUFFER_REQUIRED_QUEUE_PROPERTIES_KHR` from
command-buffer creation to enqueue.
* Introduces a negative test for `CL_INVALID_DEVICE` on command-buffer
enqueue for new error condition in spec. Although it requires a context
to be contain more than 1 device, which I'm not sure if possible in
current test framework.
* Introduces a new test that created a command-buffer using a queue
without the profiling property set, then enqueues the command-buffer to
a queue with the profiling property set.
* Introduces a new test that creates a command-buffer with an in-order
queue, enqueued on an out-of-order queue.
* Introduces a new test that creates a command-buffer with an
out-of-order queue, enqueued on an in-order queue.
This commit is contained in:
Ewan Crawford
2025-02-11 16:47:15 +00:00
committed by GitHub
parent 54afc2e7a5
commit 044ec98f66
8 changed files with 523 additions and 274 deletions

View File

@@ -61,10 +61,9 @@ bool BasicCommandBufferTest::Skip()
"CL_DEVICE_COMMAND_BUFFER_SUPPORTED_QUEUE_PROPERTIES_KHR");
cl_command_queue_properties queue_properties;
error = clGetCommandQueueInfo(queue, CL_QUEUE_PROPERTIES,
sizeof(queue_properties), &queue_properties,
NULL);
test_error(error, "Unable to query CL_QUEUE_PROPERTIES");
error = clGetDeviceInfo(device, CL_DEVICE_QUEUE_PROPERTIES,
sizeof(queue_properties), &queue_properties, NULL);
test_error(error, "Unable to query CL_DEVICE_QUEUE_PROPERTIES");
queue_out_of_order_support =
queue_properties & CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE;

View File

@@ -104,9 +104,9 @@ int MakeAndRunTest(cl_device_id device, cl_context context,
cl_version extension_version =
get_extension_version(device, "cl_khr_command_buffer");
if (extension_version != CL_MAKE_VERSION(0, 9, 6))
if (extension_version != CL_MAKE_VERSION(0, 9, 7))
{
log_info("cl_khr_command_buffer version 0.9.6 is required to run "
log_info("cl_khr_command_buffer version 0.9.7 is required to run "
"the test, skipping.\n ");
return TEST_SKIPPED_ITSELF;
}

View File

@@ -21,11 +21,75 @@
namespace {
#define ADD_PROF_PARAM(prop) \
{ \
prop, #prop, 0 \
}
struct ProfilingParam
{
cl_profiling_info param;
std::string name;
cl_ulong value;
};
cl_int VerifyResult(const clEventWrapper& event)
{
cl_int error = CL_SUCCESS;
cl_int status;
error = clGetEventInfo(event, CL_EVENT_COMMAND_EXECUTION_STATUS,
sizeof(status), &status, NULL);
test_error(error, "clGetEventInfo() failed");
if (status != CL_SUCCESS)
test_fail("Kernel execution status %d! (%s:%d)\n", status, __FILE__,
__LINE__);
std::vector<ProfilingParam> prof_params = {
ADD_PROF_PARAM(CL_PROFILING_COMMAND_QUEUED),
ADD_PROF_PARAM(CL_PROFILING_COMMAND_SUBMIT),
ADD_PROF_PARAM(CL_PROFILING_COMMAND_START),
ADD_PROF_PARAM(CL_PROFILING_COMMAND_END),
};
// gather profiling timestamps
for (auto&& p : prof_params)
{
error = clGetEventProfilingInfo(event, p.param, sizeof(p.value),
&p.value, NULL);
test_error(error, "clGetEventProfilingInfo() failed");
}
// verify the results by comparing timestamps
bool all_vals_0 = prof_params.front().value != 0;
for (size_t i = 1; i < prof_params.size(); i++)
{
all_vals_0 = (prof_params[i].value != 0) ? false : all_vals_0;
if (prof_params[i - 1].value > prof_params[i].value)
{
log_error("Profiling %s=0x%x should be smaller than or equal "
"to %s=0x%x for "
"kernels that use the on-device queue",
prof_params[i - 1].name.c_str(), prof_params[i - 1].param,
prof_params[i].name.c_str(), prof_params[i].param);
return TEST_FAIL;
}
}
if (all_vals_0)
{
log_error("All values are 0. This is exceedingly unlikely.\n");
return TEST_FAIL;
}
log_info("Profiling info for command-buffer kernel succeeded.\n");
return TEST_PASS;
}
////////////////////////////////////////////////////////////////////////////////
// Command-buffer profiling test cases:
// -all commands are recorded to a single command-queue
// -profiling a command-buffer with simultaneous use
template <bool simultaneous_request>
struct CommandBufferProfiling : public BasicCommandBufferTest
{
@@ -133,73 +197,6 @@ struct CommandBufferProfiling : public BasicCommandBufferTest
return CL_SUCCESS;
}
//--------------------------------------------------------------------------
#define ADD_PROF_PARAM(prop) \
{ \
prop, #prop, 0 \
}
struct ProfilingParam
{
cl_profiling_info param;
std::string name;
cl_ulong value;
};
//--------------------------------------------------------------------------
cl_int VerifyResult(const clEventWrapper& event)
{
cl_int error = CL_SUCCESS;
cl_int status;
error = clGetEventInfo(event, CL_EVENT_COMMAND_EXECUTION_STATUS,
sizeof(status), &status, NULL);
test_error(error, "clGetEventInfo() failed");
if (status != CL_SUCCESS)
test_fail("Kernel execution status %d! (%s:%d)\n", status, __FILE__,
__LINE__);
std::vector<ProfilingParam> prof_params = {
ADD_PROF_PARAM(CL_PROFILING_COMMAND_QUEUED),
ADD_PROF_PARAM(CL_PROFILING_COMMAND_SUBMIT),
ADD_PROF_PARAM(CL_PROFILING_COMMAND_START),
ADD_PROF_PARAM(CL_PROFILING_COMMAND_END),
};
// gather profiling timestamps
for (auto&& p : prof_params)
{
error = clGetEventProfilingInfo(event, p.param, sizeof(p.value),
&p.value, NULL);
test_error(error, "clGetEventProfilingInfo() failed");
}
// verify the results by comparing timestamps
bool all_vals_0 = prof_params.front().value != 0;
for (size_t i = 1; i < prof_params.size(); i++)
{
all_vals_0 = (prof_params[i].value != 0) ? false : all_vals_0;
if (prof_params[i - 1].value > prof_params[i].value)
{
log_error("Profiling %s=0x%x should be smaller than or equal "
"to %s=0x%x for "
"kernels that use the on-device queue",
prof_params[i - 1].name.c_str(),
prof_params[i - 1].param, prof_params[i].name.c_str(),
prof_params[i].param);
return TEST_FAIL;
}
}
if (all_vals_0)
{
log_error("All values are 0. This is exceedingly unlikely.\n");
return TEST_FAIL;
}
log_info("Profiling info for command-buffer kernel succeeded.\n");
return TEST_PASS;
}
//--------------------------------------------------------------------------
cl_int RunSingle()
{
@@ -301,6 +298,63 @@ struct CommandBufferProfiling : public BasicCommandBufferTest
const cl_int pattern = 0xA;
};
// Test that we can create a command-buffer using a queue without the profiling
// property, which is enqueued to an queue with the profiling property, and
// the event returned can queried for profiling info.
struct CommandBufferSubstituteQueueProfiling : public BasicCommandBufferTest
{
using BasicCommandBufferTest::BasicCommandBufferTest;
cl_int Run() override
{
cl_int error = clCommandNDRangeKernelKHR(
command_buffer, nullptr, nullptr, kernel, 1, nullptr, &num_elements,
nullptr, 0, nullptr, nullptr, nullptr);
test_error(error, "clCommandNDRangeKernelKHR failed");
error = clFinalizeCommandBufferKHR(command_buffer);
test_error(error, "clFinalizeCommandBufferKHR failed");
clEventWrapper event;
error = clEnqueueCommandBufferKHR(1, &profiling_queue, command_buffer,
0, nullptr, &event);
test_error(error, "clEnqueueCommandBufferKHR failed");
error = clFinish(profiling_queue);
test_error(error, "clFinish failed");
error = VerifyResult(event);
test_error(error, "VerifyResult failed");
return CL_SUCCESS;
}
cl_int SetUp(int elements) override
{
cl_command_queue_properties supported_properties;
cl_int error = clGetDeviceInfo(
device, CL_DEVICE_COMMAND_BUFFER_SUPPORTED_QUEUE_PROPERTIES_KHR,
sizeof(supported_properties), &supported_properties, NULL);
test_error(error,
"Unable to query "
"CL_DEVICE_COMMAND_BUFFER_SUPPORTED_QUEUE_PROPERTIES_KHR");
// CL_QUEUE_PROFILING_ENABLE is mandated minimum property returned by
// CL_DEVICE_COMMAND_BUFFER_SUPPORTED_QUEUE_PROPERTIES_KHR
if (!(supported_properties & CL_QUEUE_PROFILING_ENABLE))
{
return TEST_FAIL;
}
profiling_queue = clCreateCommandQueue(
context, device, CL_QUEUE_PROFILING_ENABLE, &error);
test_error(error, "clCreateCommandQueue failed");
return BasicCommandBufferTest::SetUp(elements);
}
clCommandQueueWrapper profiling_queue = nullptr;
};
} // anonymous namespace
int test_basic_profiling(cl_device_id device, cl_context context,
@@ -316,3 +370,10 @@ int test_simultaneous_profiling(cl_device_id device, cl_context context,
return MakeAndRunTest<CommandBufferProfiling<true>>(device, context, queue,
num_elements);
}
int test_substitute_queue_profiling(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
{
return MakeAndRunTest<CommandBufferSubstituteQueueProfiling>(
device, context, queue, num_elements);
}

View File

@@ -252,6 +252,148 @@ struct SubstituteQueueTest : public BasicCommandBufferTest
clEventWrapper user_event;
};
// Command-queue substitution tests which handles below cases:
// * Template param is true - Create a command-buffer with an in-order queue,
// and enqueue command-buffer to an out-of-order queue.
// * Template param is false - Create a command-buffer with an out-of-order
// queue, and enqueue command-buffer to an in-order queue.
template <bool is_ooo_test>
struct QueueOrderTest : public BasicCommandBufferTest
{
using BasicCommandBufferTest::BasicCommandBufferTest;
QueueOrderTest(cl_device_id device, cl_context context,
cl_command_queue queue)
: BasicCommandBufferTest(device, context, queue), ooo_queue(nullptr),
ooo_command_buffer(this)
{}
cl_int RecordOutOfOrderCommandBuffer()
{
cl_sync_point_khr sync_points[2];
const cl_int pattern = pattern_pri;
cl_int error =
clCommandFillBufferKHR(ooo_command_buffer, nullptr, nullptr, in_mem,
&pattern, sizeof(cl_int), 0, data_size(), 0,
nullptr, &sync_points[0], nullptr);
test_error(error, "clCommandFillBufferKHR failed");
error = clCommandFillBufferKHR(ooo_command_buffer, nullptr, nullptr,
out_mem, &overwritten_pattern,
sizeof(cl_int), 0, data_size(), 0,
nullptr, &sync_points[1], nullptr);
test_error(error, "clCommandFillBufferKHR failed");
error = clCommandNDRangeKernelKHR(
ooo_command_buffer, nullptr, nullptr, kernel, 1, nullptr,
&num_elements, nullptr, 2, sync_points, nullptr, nullptr);
test_error(error, "clCommandNDRangeKernelKHR failed");
return CL_SUCCESS;
}
cl_int RecordInOrderCommandBuffer()
{
const cl_int pattern = pattern_pri;
cl_int error = clCommandFillBufferKHR(
command_buffer, nullptr, nullptr, in_mem, &pattern, sizeof(cl_int),
0, data_size(), 0, nullptr, nullptr, nullptr);
test_error(error, "clCommandFillBufferKHR failed");
error = clCommandFillBufferKHR(
command_buffer, nullptr, nullptr, out_mem, &overwritten_pattern,
sizeof(cl_int), 0, data_size(), 0, nullptr, nullptr, nullptr);
test_error(error, "clCommandFillBufferKHR failed");
error = clCommandNDRangeKernelKHR(
command_buffer, nullptr, nullptr, kernel, 1, nullptr, &num_elements,
nullptr, 0, nullptr, nullptr, nullptr);
test_error(error, "clCommandNDRangeKernelKHR failed");
return CL_SUCCESS;
}
cl_int Run() override
{
cl_int error = CL_SUCCESS;
if (is_ooo_test)
{
// command-buffer created in-order, but executed on ooo queue
error = RecordInOrderCommandBuffer();
test_error(error, "RecordInOrderCommandBuffer failed");
}
else
{
// command-buffer created ooo with sync point deps, but
// executed on in-order queue
error = RecordOutOfOrderCommandBuffer();
test_error(error, "RecordOutOfOrderCommandBuffer failed");
}
clCommandBufferWrapper& test_command_buffer =
is_ooo_test ? command_buffer : ooo_command_buffer;
error = clFinalizeCommandBufferKHR(test_command_buffer);
test_error(error, "clFinalizeCommandBufferKHR failed");
clCommandQueueWrapper& test_queue = is_ooo_test ? ooo_queue : queue;
error = clEnqueueCommandBufferKHR(1, &test_queue, test_command_buffer,
0, nullptr, nullptr);
test_error(error, "clEnqueueCommandBufferKHR failed");
error = clFinish(test_queue);
test_error(error, "clFinish failed");
// Verify output
std::vector<cl_int> output_buffer(num_elements);
error = clEnqueueReadBuffer(queue, out_mem, CL_TRUE, 0, data_size(),
output_buffer.data(), 0, nullptr, nullptr);
test_error(error, "clEnqueueReadBuffer failed");
for (size_t i = 0; i < num_elements; i++)
{
CHECK_VERIFICATION_ERROR(pattern_pri, output_buffer[i], i);
}
return CL_SUCCESS;
}
cl_int SetUp(int elements) override
{
cl_int error = BasicCommandBufferTest::SetUp(elements);
test_error(error, "BasicCommandBufferTest::SetUp failed");
ooo_queue = clCreateCommandQueue(
context, device, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, &error);
test_error(error,
"clCreateCommandQueue with "
"CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE failed");
ooo_command_buffer =
clCreateCommandBufferKHR(1, &ooo_queue, nullptr, &error);
test_error(error, "clCreateCommandBufferKHR failed");
return CL_SUCCESS;
}
bool Skip() override
{
if (BasicCommandBufferTest::Skip()) return true;
// Skip if we want to enqueue to an out-of-order command-queue,
// and this isn't supported.
bool skip = is_ooo_test ? !out_of_order_support : false;
// Skip if device doesn't support out-of-order queues, we need
// to create one for both instantiations of the test.
return skip || !queue_out_of_order_support;
}
clCommandQueueWrapper ooo_queue;
clCommandBufferWrapper ooo_command_buffer;
const cl_int overwritten_pattern = 0xACDC;
const cl_int pattern_pri = 42;
};
} // anonymous namespace
int test_queue_substitution(cl_device_id device, cl_context context,
@@ -276,3 +418,17 @@ int test_simultaneous_queue_substitution(cl_device_id device,
return MakeAndRunTest<SubstituteQueueTest<false, true>>(
device, context, queue, num_elements);
}
int test_queue_substitute_in_order(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
{
return MakeAndRunTest<QueueOrderTest<false>>(device, context, queue,
num_elements);
}
int test_queue_substitute_out_of_order(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
{
return MakeAndRunTest<QueueOrderTest<true>>(device, context, queue,
num_elements);
}

View File

@@ -30,6 +30,7 @@ test_definition test_list[] = {
ADD_TEST(info_context),
ADD_TEST(basic_profiling),
ADD_TEST(simultaneous_profiling),
ADD_TEST(substitute_queue_profiling),
ADD_TEST(regular_wait_for_command_buffer),
ADD_TEST(command_buffer_wait_for_command_buffer),
ADD_TEST(command_buffer_wait_for_sec_command_buffer),
@@ -44,6 +45,8 @@ test_definition test_list[] = {
ADD_TEST(queue_substitution),
ADD_TEST(properties_queue_substitution),
ADD_TEST(simultaneous_queue_substitution),
ADD_TEST(queue_substitute_in_order),
ADD_TEST(queue_substitute_out_of_order),
ADD_TEST(fill_image),
ADD_TEST(fill_buffer),
ADD_TEST(fill_svm_buffer),
@@ -93,9 +96,6 @@ test_definition test_list[] = {
ADD_TEST(negative_create_command_buffer_null_queues),
ADD_TEST(negative_create_command_buffer_repeated_properties),
ADD_TEST(negative_create_command_buffer_not_supported_properties),
ADD_TEST(negative_create_command_buffer_queue_without_min_properties),
ADD_TEST(
negative_create_command_buffer_device_does_not_support_out_of_order_queue),
ADD_TEST(negative_command_ndrange_queue_not_null),
ADD_TEST(negative_command_ndrange_kernel_with_different_context),
ADD_TEST(negative_command_ndrange_kernel_sync_points_null_or_num_zero),
@@ -155,10 +155,12 @@ test_definition test_list[] = {
ADD_TEST(
negative_enqueue_command_buffer_num_queues_not_zero_different_while_buffer_creation),
ADD_TEST(negative_enqueue_command_buffer_not_valid_queue_in_queues),
ADD_TEST(negative_enqueue_queue_not_compatible),
ADD_TEST(negative_enqueue_queue_with_different_context),
ADD_TEST(negative_enqueue_command_buffer_different_context_than_event),
ADD_TEST(negative_enqueue_event_wait_list_null_or_events_null),
ADD_TEST(negative_enqueue_queue_without_reqd_properties),
ADD_TEST(negative_enqueue_with_unsupported_queue_property),
ADD_TEST(negative_enqueue_inconsistent_device),
};
int main(int argc, const char *argv[])

View File

@@ -201,105 +201,6 @@ struct CreateCommandBufferNotSupportedProperties : public BasicCommandBufferTest
cl_command_buffer_properties_khr unsupported_prop = 0;
};
// CL_INCOMPATIBLE_COMMAND_QUEUE_KHR if the properties of any command-queue in
// queues does not contain the minimum properties specified by
// CL_DEVICE_COMMAND_BUFFER_REQUIRED_QUEUE_PROPERTIES_KHR.
struct CreateCommandBufferQueueWithoutMinProperties
: public BasicCommandBufferTest
{
using BasicCommandBufferTest::BasicCommandBufferTest;
cl_int Run() override
{
cl_int error = CL_SUCCESS;
command_buffer = clCreateCommandBufferKHR(1, &queue, nullptr, &error);
test_failure_error_ret(error, CL_INCOMPATIBLE_COMMAND_QUEUE_KHR,
"clCreateCommandBufferKHR should return "
"CL_INCOMPATIBLE_COMMAND_QUEUE_KHR",
TEST_FAIL);
return CL_SUCCESS;
}
bool Skip() override
{
if (BasicCommandBufferTest::Skip()) return true;
cl_command_queue_properties required_properties;
cl_int error = clGetDeviceInfo(
device, CL_DEVICE_COMMAND_BUFFER_REQUIRED_QUEUE_PROPERTIES_KHR,
sizeof(required_properties), &required_properties, NULL);
test_error(error,
"Unable to query "
"CL_DEVICE_COMMAND_BUFFER_REQUIRED_QUEUE_PROPERTIES_KHR");
cl_command_queue_properties queue_properties;
error = clGetCommandQueueInfo(queue, CL_QUEUE_PROPERTIES,
sizeof(queue_properties),
&queue_properties, NULL);
test_error(error, "Unable to query CL_QUEUE_PROPERTIES");
// Skip if queue properties contains those required
return required_properties == (required_properties & queue_properties);
}
};
// CL_INCOMPATIBLE_COMMAND_QUEUE_KHR if any command-queue in queues is an
// out-of-order command-queue and the device associated with the command-queue
// does not return CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE from
// CL_DEVICE_COMMAND_BUFFER_SUPPORTED_QUEUE_PROPERTIES_KHR
struct CreateCommandBufferDeviceDoesNotSupportOutOfOderQueue
: public BasicCommandBufferTest
{
CreateCommandBufferDeviceDoesNotSupportOutOfOderQueue(
cl_device_id device, cl_context context, cl_command_queue queue)
: BasicCommandBufferTest(device, context, queue),
out_of_order_queue(nullptr)
{}
cl_int Run() override
{
cl_int error = CL_SUCCESS;
command_buffer =
clCreateCommandBufferKHR(1, &out_of_order_queue, nullptr, &error);
test_failure_error_ret(error, CL_INCOMPATIBLE_COMMAND_QUEUE_KHR,
"clCreateCommandBufferKHR should return "
"CL_INCOMPATIBLE_COMMAND_QUEUE_KHR",
TEST_FAIL);
return CL_SUCCESS;
}
cl_int SetUp(int elements) override
{
cl_int error = CL_SUCCESS;
error = BasicCommandBufferTest::SetUp(elements);
test_error(error, "BasicCommandBufferTest::SetUp failed");
out_of_order_queue = clCreateCommandQueue(
context, device, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, &error);
test_error(error,
"clCreateCommandQueue with "
"CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE failed");
return CL_SUCCESS;
}
bool Skip() override
{
if (BasicCommandBufferTest::Skip()) return true;
// If device does not support out of order queue or if device supports
// out of order command buffer test should be skipped
return !queue_out_of_order_support || out_of_order_support;
}
clCommandQueueWrapper out_of_order_queue;
};
};
int test_negative_create_command_buffer_num_queues(cl_device_id device,
@@ -335,20 +236,3 @@ int test_negative_create_command_buffer_not_supported_properties(
return MakeAndRunTest<CreateCommandBufferNotSupportedProperties>(
device, context, queue, num_elements);
}
int test_negative_create_command_buffer_queue_without_min_properties(
cl_device_id device, cl_context context, cl_command_queue queue,
int num_elements)
{
return MakeAndRunTest<CreateCommandBufferQueueWithoutMinProperties>(
device, context, queue, num_elements);
}
int test_negative_create_command_buffer_device_does_not_support_out_of_order_queue(
cl_device_id device, cl_context context, cl_command_queue queue,
int num_elements)
{
return MakeAndRunTest<
CreateCommandBufferDeviceDoesNotSupportOutOfOderQueue>(
device, context, queue, num_elements);
}

View File

@@ -16,7 +16,6 @@
#include "basic_command_buffer.h"
#include "procs.h"
//--------------------------------------------------------------------------
namespace {
@@ -293,63 +292,6 @@ struct EnqueueCommandBufferNotValidQueueInQueues : public BasicCommandBufferTest
}
};
// CL_INCOMPATIBLE_COMMAND_QUEUE_KHR if any element of queues is not compatible
// with the command-queue set on command_buffer creation at the same list index.
struct EnqueueCommandBufferQueueNotCompatible : public BasicCommandBufferTest
{
EnqueueCommandBufferQueueNotCompatible(cl_device_id device,
cl_context context,
cl_command_queue queue)
: BasicCommandBufferTest(device, context, queue),
queue_not_compatible(nullptr)
{}
cl_int Run() override
{
cl_int error = clFinalizeCommandBufferKHR(command_buffer);
test_error(error, "clFinalizeCommandBufferKHR failed");
error = clEnqueueCommandBufferKHR(1, &queue_not_compatible,
command_buffer, 0, nullptr, nullptr);
test_failure_error_ret(error, CL_INCOMPATIBLE_COMMAND_QUEUE_KHR,
"clEnqueueCommandBufferKHR should return "
"CL_INCOMPATIBLE_COMMAND_QUEUE_KHR",
TEST_FAIL);
return CL_SUCCESS;
}
cl_int SetUp(int elements) override
{
cl_int error = BasicCommandBufferTest::SetUp(elements);
test_error(error, "BasicCommandBufferTest::SetUp failed");
queue_not_compatible = clCreateCommandQueue(
context, device, CL_QUEUE_PROFILING_ENABLE, &error);
test_error(error, "clCreateCommandQueue failed");
cl_command_queue_properties queue_properties;
error = clGetCommandQueueInfo(queue, CL_QUEUE_PROPERTIES,
sizeof(queue_properties),
&queue_properties, NULL);
test_error(error, "Unable to query CL_QUEUE_PROPERTIES");
cl_command_queue_properties queue_not_compatible_properties;
error = clGetCommandQueueInfo(queue_not_compatible, CL_QUEUE_PROPERTIES,
sizeof(queue_not_compatible_properties),
&queue_not_compatible_properties, NULL);
test_error(error, "Unable to query CL_QUEUE_PROPERTIES");
test_assert_error(queue_properties != queue_not_compatible_properties,
"Queues properties must be different");
return CL_SUCCESS;
}
clCommandQueueWrapper queue_not_compatible;
};
// CL_INVALID_CONTEXT if any element of queues does not have the same context as
// the command-queue set on command_buffer creation at the same list index.
struct EnqueueCommandBufferQueueWithDifferentContext
@@ -491,6 +433,185 @@ struct EnqueueCommandBufferEventWaitListNullOrEventsNull
return CL_SUCCESS;
}
};
// CL_INCOMPATIBLE_COMMAND_QUEUE_KHR if the properties of any command-queue in
// queues does not contain the minimum properties specified by
// CL_DEVICE_COMMAND_BUFFER_REQUIRED_QUEUE_PROPERTIES_KHR.
struct EnqueueCommandBufferQueueWithoutReqdProperties
: public BasicCommandBufferTest
{
using BasicCommandBufferTest::BasicCommandBufferTest;
cl_int Run() override
{
cl_int error = clFinalizeCommandBufferKHR(command_buffer);
test_error(error, "clFinalizeCommandBufferKHR failed");
error = clEnqueueCommandBufferKHR(0, nullptr, command_buffer, 0,
nullptr, nullptr);
test_failure_error_ret(error, CL_INCOMPATIBLE_COMMAND_QUEUE_KHR,
"clEnqueueCommandBufferKHR should return "
"CL_INCOMPATIBLE_COMMAND_QUEUE_KHR",
TEST_FAIL);
error = clEnqueueCommandBufferKHR(1, &queue, command_buffer, 0, nullptr,
nullptr);
test_failure_error_ret(error, CL_INCOMPATIBLE_COMMAND_QUEUE_KHR,
"clEnqueueCommandBufferKHR should return "
"CL_INCOMPATIBLE_COMMAND_QUEUE_KHR",
TEST_FAIL);
return CL_SUCCESS;
}
bool Skip() override
{
// Omit BasicCommandBufferTest::Skip() here because it skips
// if we don't have required properties, which is what we want to
// test an error for.
cl_command_queue_properties required_properties;
cl_int error = clGetDeviceInfo(
device, CL_DEVICE_COMMAND_BUFFER_REQUIRED_QUEUE_PROPERTIES_KHR,
sizeof(required_properties), &required_properties, NULL);
test_error(error,
"Unable to query "
"CL_DEVICE_COMMAND_BUFFER_REQUIRED_QUEUE_PROPERTIES_KHR");
cl_command_queue_properties queue_properties;
error = clGetCommandQueueInfo(queue, CL_QUEUE_PROPERTIES,
sizeof(queue_properties),
&queue_properties, NULL);
test_error(error, "Unable to query CL_QUEUE_PROPERTIES");
// Skip if queue properties contains those required
return required_properties == (required_properties & queue_properties);
}
};
// CL_INCOMPATIBLE_COMMAND_QUEUE_KHR if any command-queue in queues is an
// out-of-order command-queue and the device associated with the command-queue
// does not return CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE from
// CL_DEVICE_COMMAND_BUFFER_SUPPORTED_QUEUE_PROPERTIES_KHR
struct EnqueueCommandBufferWithUnsupportedQueueProperty
: public BasicCommandBufferTest
{
using BasicCommandBufferTest::BasicCommandBufferTest;
cl_int Run() override
{
cl_int error = clFinalizeCommandBufferKHR(command_buffer);
test_error(error, "clFinalizeCommandBufferKHR failed");
error = clEnqueueCommandBufferKHR(1, &out_of_order_queue,
command_buffer, 0, nullptr, nullptr);
test_failure_error_ret(error, CL_INCOMPATIBLE_COMMAND_QUEUE_KHR,
"clEnqueueCommandBufferKHR should return "
"CL_INCOMPATIBLE_COMMAND_QUEUE_KHR",
TEST_FAIL);
return CL_SUCCESS;
}
cl_int SetUp(int elements) override
{
cl_int error = BasicCommandBufferTest::SetUp(elements);
test_error(error, "BasicCommandBufferTest::SetUp failed");
out_of_order_queue = clCreateCommandQueue(
context, device, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, &error);
test_error(error,
"clCreateCommandQueue with "
"CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE failed");
return CL_SUCCESS;
}
bool Skip() override
{
if (BasicCommandBufferTest::Skip()) return true;
// If device does not support out of order queue or if device supports
// out of order command buffer test should be skipped
return !queue_out_of_order_support || out_of_order_support;
}
clCommandQueueWrapper out_of_order_queue = nullptr;
};
// CL_INVALID_DEVICE if any element of queues does not have the same device
// as the command-queue set on command_buffer creation at the
// same list index.
struct EnqueueCommandBufferInconsistentDevice : public BasicCommandBufferTest
{
using BasicCommandBufferTest::BasicCommandBufferTest;
cl_int Run() override
{
cl_int error = clFinalizeCommandBufferKHR(command_buffer);
test_error(error, "clFinalizeCommandBufferKHR failed");
error = clEnqueueCommandBufferKHR(1, &second_device_queue,
command_buffer, 0, nullptr, nullptr);
test_failure_error_ret(error, CL_INCOMPATIBLE_COMMAND_QUEUE_KHR,
"clEnqueueCommandBufferKHR should return "
"CL_INCOMPATIBLE_COMMAND_QUEUE_KHR",
TEST_FAIL);
return CL_SUCCESS;
}
cl_int SetUp(int elements) override
{
cl_int error = BasicCommandBufferTest::SetUp(elements);
test_error(error, "BasicCommandBufferTest::SetUp failed");
cl_device_id second_device = nullptr;
for (auto query_device : devices)
{
if (query_device != device)
{
second_device = query_device;
break;
}
}
test_assert_error(second_device != nullptr,
"Second device not found for testing");
second_device_queue =
clCreateCommandQueue(context, second_device, 0, &error);
test_error(error, "clCreateCommandQueue failed");
return CL_SUCCESS;
}
bool Skip() override
{
if (BasicCommandBufferTest::Skip()) return true;
size_t context_devices_size;
cl_int error = clGetContextInfo(context, CL_CONTEXT_DEVICES, 0, NULL,
&context_devices_size);
test_error(error, "clGetContextInfo failed");
size_t num_devices = context_devices_size / sizeof(cl_device_id);
if (num_devices < 2)
{
// We need a second device for test
return true;
}
devices.resize(num_devices);
error = clGetContextInfo(context, CL_CONTEXT_DEVICES, num_devices,
devices.data(), nullptr);
test_error(error, "clGetContextInfo failed");
return false;
}
std::vector<cl_device_id> devices;
clCommandQueueWrapper second_device_queue = nullptr;
};
};
int test_negative_enqueue_command_buffer_invalid_command_buffer(
@@ -544,15 +665,6 @@ int test_negative_enqueue_command_buffer_not_valid_queue_in_queues(
device, context, queue, num_elements);
}
int test_negative_enqueue_queue_not_compatible(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements)
{
return MakeAndRunTest<EnqueueCommandBufferQueueNotCompatible>(
device, context, queue, num_elements);
}
int test_negative_enqueue_queue_with_different_context(cl_device_id device,
cl_context context,
cl_command_queue queue,
@@ -577,3 +689,29 @@ int test_negative_enqueue_event_wait_list_null_or_events_null(
return MakeAndRunTest<EnqueueCommandBufferEventWaitListNullOrEventsNull>(
device, context, queue, num_elements);
}
int test_negative_enqueue_queue_without_reqd_properties(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements)
{
return MakeAndRunTest<EnqueueCommandBufferQueueWithoutReqdProperties>(
device, context, queue, num_elements);
}
int test_negative_enqueue_with_unsupported_queue_property(
cl_device_id device, cl_context context, cl_command_queue queue,
int num_elements)
{
return MakeAndRunTest<EnqueueCommandBufferWithUnsupportedQueueProperty>(
device, context, queue, num_elements);
}
int test_negative_enqueue_inconsistent_device(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements)
{
return MakeAndRunTest<EnqueueCommandBufferInconsistentDevice>(
device, context, queue, num_elements);
}

View File

@@ -91,6 +91,10 @@ extern int test_basic_profiling(cl_device_id device, cl_context context,
extern int test_simultaneous_profiling(cl_device_id device, cl_context context,
cl_command_queue queue,
int num_elements);
extern int test_substitute_queue_profiling(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements);
extern int test_queue_substitution(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements);
extern int test_properties_queue_substitution(cl_device_id device,
@@ -101,6 +105,14 @@ extern int test_simultaneous_queue_substitution(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements);
extern int test_queue_substitute_in_order(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements);
extern int test_queue_substitute_out_of_order(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements);
extern int test_fill_image(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements);
extern int test_fill_buffer(cl_device_id device, cl_context context,
@@ -211,13 +223,6 @@ extern int test_negative_create_command_buffer_repeated_properties(
extern int test_negative_create_command_buffer_not_supported_properties(
cl_device_id device, cl_context context, cl_command_queue queue,
int num_elements);
extern int test_negative_create_command_buffer_queue_without_min_properties(
cl_device_id device, cl_context context, cl_command_queue queue,
int num_elements);
extern int
test_negative_create_command_buffer_device_does_not_support_out_of_order_queue(
cl_device_id device, cl_context context, cl_command_queue queue,
int num_elements);
extern int test_negative_command_ndrange_queue_not_null(cl_device_id device,
cl_context context,
cl_command_queue queue,
@@ -383,10 +388,6 @@ extern int test_negative_command_buffer_copy_image_mutable_handle_not_null(
extern int test_negative_enqueue_command_buffer_not_valid_queue_in_queues(
cl_device_id device, cl_context context, cl_command_queue queue,
int num_elements);
extern int test_negative_enqueue_queue_not_compatible(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements);
extern int test_negative_enqueue_queue_with_different_context(
cl_device_id device, cl_context context, cl_command_queue queue,
int num_elements);
@@ -396,6 +397,14 @@ extern int test_negative_enqueue_command_buffer_different_context_than_event(
extern int test_negative_enqueue_event_wait_list_null_or_events_null(
cl_device_id device, cl_context context, cl_command_queue queue,
int num_elements);
extern int test_negative_enqueue_queue_without_reqd_properties(
cl_device_id device, cl_context context, cl_command_queue queue,
int num_elements);
extern int test_negative_enqueue_with_unsupported_queue_property(
cl_device_id device, cl_context context, cl_command_queue queue,
int num_elements);
extern int test_negative_enqueue_inconsistent_device(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements);
#endif // CL_KHR_COMMAND_BUFFER_PROCS_H