2121
2222namespace {
2323
24+ #define ADD_PROF_PARAM (prop ) { prop, #prop, 0 }
25+ struct ProfilingParam
26+ {
27+ cl_profiling_info param;
28+ std::string name;
29+ cl_ulong value;
30+ };
31+
32+ cl_int VerifyResult (const clEventWrapper& event)
33+ {
34+ cl_int error = CL_SUCCESS;
35+ cl_int status;
36+ error = clGetEventInfo (event, CL_EVENT_COMMAND_EXECUTION_STATUS,
37+ sizeof (status), &status, NULL );
38+ test_error (error, " clGetEventInfo() failed" );
39+
40+ if (status != CL_SUCCESS)
41+ test_fail (" Kernel execution status %d! (%s:%d)\n " , status, __FILE__,
42+ __LINE__);
43+
44+ std::vector<ProfilingParam> prof_params = {
45+ ADD_PROF_PARAM (CL_PROFILING_COMMAND_QUEUED),
46+ ADD_PROF_PARAM (CL_PROFILING_COMMAND_SUBMIT),
47+ ADD_PROF_PARAM (CL_PROFILING_COMMAND_START),
48+ ADD_PROF_PARAM (CL_PROFILING_COMMAND_END),
49+ };
50+
51+ // gather profiling timestamps
52+ for (auto && p : prof_params)
53+ {
54+ error = clGetEventProfilingInfo (event, p.param , sizeof (p.value ),
55+ &p.value , NULL );
56+ test_error (error, " clGetEventProfilingInfo() failed" );
57+ }
58+
59+ // verify the results by comparing timestamps
60+ bool all_vals_0 = prof_params.front ().value != 0 ;
61+ for (size_t i = 1 ; i < prof_params.size (); i++)
62+ {
63+ all_vals_0 = (prof_params[i].value != 0 ) ? false : all_vals_0;
64+ if (prof_params[i - 1 ].value > prof_params[i].value )
65+ {
66+ log_error (" Profiling %s=0x%x should be smaller than or equal "
67+ " to %s=0x%x for "
68+ " kernels that use the on-device queue" ,
69+ prof_params[i - 1 ].name .c_str (), prof_params[i - 1 ].param ,
70+ prof_params[i].name .c_str (), prof_params[i].param );
71+ return TEST_FAIL;
72+ }
73+ }
74+
75+ if (all_vals_0)
76+ {
77+ log_error (" All values are 0. This is exceedingly unlikely.\n " );
78+ return TEST_FAIL;
79+ }
80+
81+ log_info (" Profiling info for command-buffer kernel succeeded.\n " );
82+ return TEST_PASS;
83+ }
84+
2485// //////////////////////////////////////////////////////////////////////////////
2586// Command-buffer profiling test cases:
2687// -all commands are recorded to a single command-queue
2788// -profiling a command-buffer with simultaneous use
28-
2989template <bool simultaneous_request>
3090struct CommandBufferProfiling : public BasicCommandBufferTest
3191{
@@ -133,73 +193,6 @@ struct CommandBufferProfiling : public BasicCommandBufferTest
133193 return CL_SUCCESS;
134194 }
135195
136- // --------------------------------------------------------------------------
137- #define ADD_PROF_PARAM (prop ) \
138- { \
139- prop, #prop, 0 \
140- }
141- struct ProfilingParam
142- {
143- cl_profiling_info param;
144- std::string name;
145- cl_ulong value;
146- };
147-
148- // --------------------------------------------------------------------------
149- cl_int VerifyResult (const clEventWrapper& event)
150- {
151- cl_int error = CL_SUCCESS;
152- cl_int status;
153- error = clGetEventInfo (event, CL_EVENT_COMMAND_EXECUTION_STATUS,
154- sizeof (status), &status, NULL );
155- test_error (error, " clGetEventInfo() failed" );
156-
157- if (status != CL_SUCCESS)
158- test_fail (" Kernel execution status %d! (%s:%d)\n " , status, __FILE__,
159- __LINE__);
160-
161- std::vector<ProfilingParam> prof_params = {
162- ADD_PROF_PARAM (CL_PROFILING_COMMAND_QUEUED),
163- ADD_PROF_PARAM (CL_PROFILING_COMMAND_SUBMIT),
164- ADD_PROF_PARAM (CL_PROFILING_COMMAND_START),
165- ADD_PROF_PARAM (CL_PROFILING_COMMAND_END),
166- };
167-
168- // gather profiling timestamps
169- for (auto && p : prof_params)
170- {
171- error = clGetEventProfilingInfo (event, p.param , sizeof (p.value ),
172- &p.value , NULL );
173- test_error (error, " clGetEventProfilingInfo() failed" );
174- }
175-
176- // verify the results by comparing timestamps
177- bool all_vals_0 = prof_params.front ().value != 0 ;
178- for (size_t i = 1 ; i < prof_params.size (); i++)
179- {
180- all_vals_0 = (prof_params[i].value != 0 ) ? false : all_vals_0;
181- if (prof_params[i - 1 ].value > prof_params[i].value )
182- {
183- log_error (" Profiling %s=0x%x should be smaller than or equal "
184- " to %s=0x%x for "
185- " kernels that use the on-device queue" ,
186- prof_params[i - 1 ].name .c_str (),
187- prof_params[i - 1 ].param , prof_params[i].name .c_str (),
188- prof_params[i].param );
189- return TEST_FAIL;
190- }
191- }
192-
193- if (all_vals_0)
194- {
195- log_error (" All values are 0. This is exceedingly unlikely.\n " );
196- return TEST_FAIL;
197- }
198-
199- log_info (" Profiling info for command-buffer kernel succeeded.\n " );
200- return TEST_PASS;
201- }
202-
203196 // --------------------------------------------------------------------------
204197 cl_int RunSingle ()
205198 {
@@ -301,6 +294,63 @@ struct CommandBufferProfiling : public BasicCommandBufferTest
301294 const cl_int pattern = 0xA ;
302295};
303296
297+ // Test that we can create a command-buffer using a queue without the profiling
298+ // property, which is enqueued to an queue with the profiling property, and
299+ // the event returned can queried for profiling info.
300+ struct CommandBufferSubstituteQueueProfiling : public BasicCommandBufferTest
301+ {
302+ using BasicCommandBufferTest::BasicCommandBufferTest;
303+
304+ cl_int Run () override
305+ {
306+ cl_int error = clCommandNDRangeKernelKHR (
307+ command_buffer, nullptr , nullptr , kernel, 1 , nullptr , &num_elements,
308+ nullptr , 0 , nullptr , nullptr , nullptr );
309+ test_error (error, " clCommandNDRangeKernelKHR failed" );
310+
311+ error = clFinalizeCommandBufferKHR (command_buffer);
312+ test_error (error, " clFinalizeCommandBufferKHR failed" );
313+
314+ clEventWrapper event;
315+ error = clEnqueueCommandBufferKHR (1 , &profiling_queue, command_buffer,
316+ 0 , nullptr , &event);
317+ test_error (error, " clEnqueueCommandBufferKHR failed" );
318+
319+ error = clFinish (profiling_queue);
320+ test_error (error, " clFinish failed" );
321+
322+ error = VerifyResult (event);
323+ test_error (error, " VerifyResult failed" );
324+
325+ return CL_SUCCESS;
326+ }
327+
328+ cl_int SetUp (int elements) override
329+ {
330+ cl_command_queue_properties supported_properties;
331+ cl_int error = clGetDeviceInfo (
332+ device, CL_DEVICE_COMMAND_BUFFER_SUPPORTED_QUEUE_PROPERTIES_KHR,
333+ sizeof (supported_properties), &supported_properties, NULL );
334+ test_error (error,
335+ " Unable to query "
336+ " CL_DEVICE_COMMAND_BUFFER_SUPPORTED_QUEUE_PROPERTIES_KHR" );
337+
338+ // CL_QUEUE_PROFILING_ENABLE is mandated minimum property returned by
339+ // CL_DEVICE_COMMAND_BUFFER_SUPPORTED_QUEUE_PROPERTIES_KHR
340+ if (!(supported_properties & CL_QUEUE_PROFILING_ENABLE))
341+ {
342+ return TEST_FAIL;
343+ }
344+
345+ profiling_queue = clCreateCommandQueue (
346+ context, device, CL_QUEUE_PROFILING_ENABLE, &error);
347+ test_error (error, " clCreateCommandQueue failed" );
348+
349+ return BasicCommandBufferTest::SetUp (elements);
350+ }
351+
352+ clCommandQueueWrapper profiling_queue = nullptr ;
353+ };
304354} // anonymous namespace
305355
306356int test_basic_profiling (cl_device_id device, cl_context context,
@@ -316,3 +366,10 @@ int test_simultaneous_profiling(cl_device_id device, cl_context context,
316366 return MakeAndRunTest<CommandBufferProfiling<true >>(device, context, queue,
317367 num_elements);
318368}
369+
370+ int test_substitute_queue_profiling (cl_device_id device, cl_context context,
371+ cl_command_queue queue, int num_elements)
372+ {
373+ return MakeAndRunTest<CommandBufferSubstituteQueueProfiling>(
374+ device, context, queue, num_elements);
375+ }
0 commit comments