xref: /aosp_15_r20/external/OpenCL-CTS/test_conformance/events/test_userevents.cpp (revision 6467f958c7de8070b317fc65bcb0f6472e388d82)
1 //
2 // Copyright (c) 2017 The Khronos Group Inc.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //    http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 #if defined(__APPLE__)
17 #include <OpenCL/opencl.h>
18 #include <mach/mach_time.h>
19 #else
20 #include <CL/cl.h>
21 #include <malloc.h>
22 #endif
23 #include <assert.h>
24 #include <stdio.h>
25 #include <string.h>
26 #include "harness/kernelHelpers.h"
27 
28 ///////////////////////////////////////////////////////////////////////////////
29 // CL error checking.
30 
31 #if defined(_MSC_VER)
32 #define CL_EXIT_ERROR(cmd, ...)                                                \
33     {                                                                          \
34         if ((cmd) != CL_SUCCESS)                                               \
35         {                                                                      \
36             log_error("CL ERROR: %s %u: ", __FILE__, __LINE__);                \
37             log_error(##__VA_ARGS__);                                          \
38             log_error("\n");                                                   \
39             return -1;                                                         \
40         }                                                                      \
41     }
42 #else
43 #define CL_EXIT_ERROR(cmd, format, ...)                                        \
44     {                                                                          \
45         if ((cmd) != CL_SUCCESS)                                               \
46         {                                                                      \
47             log_error("CL ERROR: %s %u: ", __FILE__, __LINE__);                \
48             log_error(format, ##__VA_ARGS__);                                  \
49             log_error("\n");                                                   \
50             return -1;                                                         \
51         }                                                                      \
52     }
53 #endif
54 
55 #define CL_EXIT_BUILD_ERROR(cmd, program, format, ...)                         \
56     {                                                                          \
57         if ((cmd) != CL_SUCCESS)                                               \
58         {                                                                      \
59             cl_uint num_devices_;                                              \
60             clGetProgramInfo(program, CL_PROGRAM_NUM_DEVICES,                  \
61                              sizeof(num_devices_), &num_devices_, NULL);       \
62             cl_device_id *device_list;                                         \
63             device_list =                                                      \
64                 (cl_device_id *)malloc(num_devices_ * sizeof(cl_device_id));   \
65             clGetProgramInfo(program, CL_PROGRAM_DEVICES,                      \
66                              num_devices_ * sizeof(cl_device_id), device_list, \
67                              NULL);                                            \
68             for (unsigned i = 0; i < num_devices_; ++i)                        \
69             {                                                                  \
70                 size_t len;                                                    \
71                 char buffer[2048];                                             \
72                 clGetProgramBuildInfo(program, device_list[i],                 \
73                                       CL_PROGRAM_BUILD_LOG, sizeof(buffer),    \
74                                       buffer, &len);                           \
75                 log_error("DEVICE %u CL BUILD ERROR: %s(%u): ", i, __FILE__,   \
76                           __LINE__);                                           \
77                 log_error(format, ##__VA_ARGS__);                              \
78                 log_error("\n");                                               \
79             }                                                                  \
80             free(device_list);                                                 \
81             return -1;                                                         \
82         }                                                                      \
83     }
84 
85 const char *src[] = { "__kernel void simple_task(__global float* output) {\n"
86                       "  output[0] += 1;\n"
87                       "}\n" };
88 
89 enum
90 {
91     MaxDevices = 8
92 };
93 
test_userevents(cl_device_id deviceID,cl_context context,cl_command_queue queue,int num_elements)94 int test_userevents(cl_device_id deviceID, cl_context context,
95                     cl_command_queue queue, int num_elements)
96 {
97 
98     cl_int err;
99 
100     cl_event u1 = clCreateUserEvent(context, &err);
101     CL_EXIT_ERROR(err, "clCreateUserEvent failed");
102 
103     // Test event properties.
104     cl_int s;
105     size_t sizeofs;
106     CL_EXIT_ERROR(clGetEventInfo(u1, CL_EVENT_COMMAND_EXECUTION_STATUS,
107                                  sizeof s, &s, &sizeofs),
108                   "clGetEventInfo failed");
109     CL_EXIT_ERROR((sizeof s == sizeofs) ? CL_SUCCESS : -1,
110                   "clGetEventInfo returned wrong size for "
111                   "CL_EVENT_COMMAND_EXECUTION_STATUS");
112     CL_EXIT_ERROR((s == CL_SUBMITTED) ? CL_SUCCESS : -1,
113                   "clGetEventInfo returned wrong value for "
114                   "CL_EVENT_COMMAND_EXECUTION_STATUS");
115 
116     cl_command_type t;
117     size_t sizeoft;
118     CL_EXIT_ERROR(
119         clGetEventInfo(u1, CL_EVENT_COMMAND_TYPE, sizeof t, &t, &sizeoft),
120         "clGetEventInfo failed");
121     CL_EXIT_ERROR(
122         (sizeof t == sizeoft) ? CL_SUCCESS : -1,
123         "clGetEventInfo returned wrong size for CL_EVENT_COMMAND_TYPE");
124     CL_EXIT_ERROR(
125         (t == CL_COMMAND_USER) ? CL_SUCCESS : -1,
126         "clGetEventInfo returned wrong value for CL_EVENT_COMMAND_TYPE");
127 
128     cl_command_queue q;
129     size_t sizeofq;
130     CL_EXIT_ERROR(
131         clGetEventInfo(u1, CL_EVENT_COMMAND_QUEUE, sizeof q, &q, &sizeofq),
132         "clGetEventInfo failed");
133     CL_EXIT_ERROR(
134         (sizeof q == sizeofq) ? CL_SUCCESS : -1,
135         "clGetEventInfo returned wrong size for CL_EVENT_COMMAND_QUEUE");
136     CL_EXIT_ERROR(
137         (q == NULL) ? CL_SUCCESS : -1,
138         "clGetEventInfo returned wrong value for CL_EVENT_COMMAND_QUEUE");
139 
140     cl_context c;
141     size_t sizeofc;
142     CL_EXIT_ERROR(clGetEventInfo(u1, CL_EVENT_CONTEXT, sizeof c, &c, &sizeofc),
143                   "clGetEventInfo failed");
144     CL_EXIT_ERROR((sizeof c == sizeofc) ? CL_SUCCESS : -1,
145                   "clGetEventInfo returned wrong size for CL_EVENT_CONTEXT");
146     CL_EXIT_ERROR((c == context) ? CL_SUCCESS : -1,
147                   "clGetEventInfo returned wrong value for CL_EVENT_CONTEXT");
148 
149     cl_ulong p;
150     err = clGetEventProfilingInfo(u1, CL_PROFILING_COMMAND_QUEUED, sizeof p, &p,
151                                   0);
152     CL_EXIT_ERROR((err != CL_SUCCESS) ? CL_SUCCESS : -1,
153                   "clGetEventProfilingInfo returned wrong error.");
154 
155     // Test semantics.
156     cl_program program;
157     err = create_single_kernel_helper_create_program(context, &program, 1, src);
158     CL_EXIT_ERROR(err, "clCreateProgramWithSource failed");
159 
160     CL_EXIT_BUILD_ERROR(clBuildProgram(program, 0, NULL, "", NULL, NULL),
161                         program, "Building program from inline src:\t%s",
162                         src[0]);
163 
164     cl_kernel k0 = clCreateKernel(program, "simple_task", &err);
165     CL_EXIT_ERROR(err, "clCreateKernel failed");
166 
167     float buffer[1];
168     cl_mem output = clCreateBuffer(context, CL_MEM_USE_HOST_PTR, sizeof buffer,
169                                    buffer, &err);
170     CL_EXIT_ERROR(err, "clCreateBuffer failed.");
171 
172     CL_EXIT_ERROR(clSetKernelArg(k0, 0, sizeof(output), &output),
173                   "clSetKernelArg failed");
174 
175 
176     // Successful case.
177     // //////////////////////////////////////////////////////////////////////////////////////
178     {
179         cl_event e[4];
180         cl_uint N = sizeof e / sizeof(cl_event);
181 
182         log_info("Enqueuing tasks\n");
183         for (cl_uint i = 0; i != N; ++i)
184             CL_EXIT_ERROR(clEnqueueTask(queue, k0, 1, &u1, &e[i]),
185                           "clEnqueueTaskFailed");
186 
187         log_info("Checking task status before setting user event status\n");
188         for (cl_uint i = 0; i != N; ++i)
189         {
190             CL_EXIT_ERROR(clGetEventInfo(e[i],
191                                          CL_EVENT_COMMAND_EXECUTION_STATUS,
192                                          sizeof s, &s, 0),
193                           "clGetEventInfo failed");
194             CL_EXIT_ERROR(
195                 (s >= CL_SUBMITTED) ? CL_SUCCESS : -1,
196                 "clGetEventInfo %u returned wrong status before user event", i);
197         }
198 
199         log_info("Setting user event status to complete\n");
200         CL_EXIT_ERROR(clSetUserEventStatus(u1, CL_COMPLETE),
201                       "clSetUserEventStatus failed");
202 
203         log_info("Waiting for tasks to finish executing\n");
204         CL_EXIT_ERROR(clWaitForEvents(1, &e[N - 1]), "clWaitForEvent failed");
205 
206         log_info("Checking task status after setting user event status\n");
207         for (cl_uint i = 0; i != N; ++i)
208         {
209             CL_EXIT_ERROR(clGetEventInfo(e[i],
210                                          CL_EVENT_COMMAND_EXECUTION_STATUS,
211                                          sizeof s, &s, 0),
212                           "clGetEventInfo failed");
213             CL_EXIT_ERROR((s != CL_QUEUED) ? CL_SUCCESS : -1,
214                           "clGetEventInfo %u returned wrong status %04x after "
215                           "successful user event",
216                           i, s);
217         }
218 
219         CL_EXIT_ERROR(clReleaseEvent(u1), "clReleaseEvent failed");
220 
221         for (cl_uint i = 0; i != N; ++i)
222             CL_EXIT_ERROR(clReleaseEvent(e[i]), "clReleaseEvent failed");
223 
224         log_info("Successful user event case passed.\n");
225     }
226 
227     // Test unsuccessful user event case.
228     // ///////////////////////////////////////////////////////////////////
229     {
230         cl_event u2 = clCreateUserEvent(context, &err);
231         CL_EXIT_ERROR(err, "clCreateUserEvent failed");
232 
233         cl_event e[4];
234         cl_uint N = sizeof e / sizeof(cl_event);
235 
236         log_info("Enqueuing tasks\n");
237         for (cl_uint i = 0; i != N; ++i)
238             CL_EXIT_ERROR(clEnqueueTask(queue, k0, 1, &u2, &e[i]),
239                           "clEnqueueTaskFailed");
240 
241         log_info("Checking task status before setting user event status\n");
242         for (cl_uint i = 0; i != N; ++i)
243         {
244             CL_EXIT_ERROR(clGetEventInfo(e[i],
245                                          CL_EVENT_COMMAND_EXECUTION_STATUS,
246                                          sizeof s, &s, 0),
247                           "clGetEventInfo failed");
248             CL_EXIT_ERROR(
249                 (s == CL_QUEUED || s == CL_SUBMITTED) ? CL_SUCCESS : -1,
250                 "clGetEventInfo %u returned wrong status %d before user event",
251                 i, (int)s);
252         }
253 
254         log_info("Setting user event status to unsuccessful result\n");
255         CL_EXIT_ERROR(clSetUserEventStatus(u2, -1),
256                       "clSetUserEventStatus failed");
257 
258         log_info("Waiting for tasks to finish executing\n");
259         CL_EXIT_ERROR((clWaitForEvents(N, &e[0]) != CL_SUCCESS) ? CL_SUCCESS
260                                                                 : -1,
261                       "clWaitForEvent succeeded when it should have failed");
262 
263         log_info("Checking task status after setting user event status\n");
264         for (cl_uint i = 0; i != N; ++i)
265         {
266             CL_EXIT_ERROR(clGetEventInfo(e[i],
267                                          CL_EVENT_COMMAND_EXECUTION_STATUS,
268                                          sizeof s, &s, 0),
269                           "clGetEventInfo failed");
270             CL_EXIT_ERROR((s != CL_QUEUED) ? CL_SUCCESS : -1,
271                           "clGetEventInfo %u returned wrong status %04x after "
272                           "unsuccessful user event",
273                           i, s);
274         }
275 
276         CL_EXIT_ERROR(clReleaseEvent(u2), "clReleaseEvent failed");
277 
278         for (cl_uint i = 0; i != N; ++i)
279             CL_EXIT_ERROR(clReleaseEvent(e[i]), "clReleaseEvent failed");
280 
281         log_info("Unsuccessful user event case passed.\n");
282     }
283 
284     clReleaseKernel(k0);
285     clReleaseProgram(program);
286     clReleaseMemObject(output);
287 
288     return 0;
289 }
290