mirror of
https://github.com/KhronosGroup/OpenCL-CTS.git
synced 2026-03-19 06:09:01 +00:00
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:
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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[])
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user