Skip to content

Commit

Permalink
Command-buffer queue compatibility test update
Browse files Browse the repository at this point in the history
Update cl_khr_command_buffer tests to reflect changes from
KhronosGroup/OpenCL-Docs#1292

Required headers change
KhronosGroup/OpenCL-Headers#271 to enable
tests with version 0.9.7
  • Loading branch information
EwanC committed Jan 16, 2025
1 parent 2ff5cda commit 5434a27
Show file tree
Hide file tree
Showing 8 changed files with 519 additions and 203 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,74 @@

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
{
Expand Down Expand Up @@ -133,73 +196,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()
{
Expand Down Expand Up @@ -301,6 +297,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,
Expand All @@ -316,3 +369,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);
}
Loading

0 comments on commit 5434a27

Please sign in to comment.