xref: /aosp_15_r20/external/OpenCL-CTS/test_conformance/vulkan/main.cpp (revision 6467f958c7de8070b317fc65bcb0f6472e388d82)
1 //
2 // Copyright (c) 2022 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 
17 #include <stdio.h>
18 #include <stdlib.h>
19 
20 #if !defined(_WIN32)
21 #include <stdbool.h>
22 #endif
23 
24 #include <math.h>
25 #include <string.h>
26 
27 #if !defined(__APPLE__)
28 #include <CL/cl.h>
29 #else
30 #include <OpenCL/cl.h>
31 #endif
32 
33 
34 #include "procs.h"
35 #include "harness/testHarness.h"
36 #include "harness/parseParameters.h"
37 #include "harness/deviceInfo.h"
38 
39 #if !defined(_WIN32)
40 #include <unistd.h>
41 #endif
42 #include <vulkan_interop_common.hpp>
43 #include <vulkan_wrapper.hpp>
44 
45 #define BUFFERSIZE 3000
46 
params_reset()47 static void params_reset()
48 {
49     numCQ = 1;
50     multiImport = false;
51     multiCtx = false;
52 }
53 
54 extern int test_buffer_common(cl_device_id device_, cl_context context_,
55                               cl_command_queue queue_, int numElements_,
56                               float use_fence);
57 extern int test_image_common(cl_device_id device_, cl_context context_,
58                              cl_command_queue queue_, int numElements_);
59 
test_buffer_single_queue(cl_device_id device_,cl_context context_,cl_command_queue queue_,int numElements_)60 int test_buffer_single_queue(cl_device_id device_, cl_context context_,
61                              cl_command_queue queue_, int numElements_)
62 {
63     params_reset();
64     log_info("RUNNING TEST WITH ONE QUEUE...... \n\n");
65     return test_buffer_common(device_, context_, queue_, numElements_, false);
66 }
test_buffer_multiple_queue(cl_device_id device_,cl_context context_,cl_command_queue queue_,int numElements_)67 int test_buffer_multiple_queue(cl_device_id device_, cl_context context_,
68                                cl_command_queue queue_, int numElements_)
69 {
70     params_reset();
71     numCQ = 2;
72     log_info("RUNNING TEST WITH TWO QUEUE...... \n\n");
73     return test_buffer_common(device_, context_, queue_, numElements_, false);
74 }
test_buffer_multiImport_sameCtx(cl_device_id device_,cl_context context_,cl_command_queue queue_,int numElements_)75 int test_buffer_multiImport_sameCtx(cl_device_id device_, cl_context context_,
76                                     cl_command_queue queue_, int numElements_)
77 {
78     params_reset();
79     multiImport = true;
80     log_info("RUNNING TEST WITH MULTIPLE DEVICE MEMORY IMPORT "
81              "IN SAME CONTEXT...... \n\n");
82     return test_buffer_common(device_, context_, queue_, numElements_, false);
83 }
test_buffer_multiImport_diffCtx(cl_device_id device_,cl_context context_,cl_command_queue queue_,int numElements_)84 int test_buffer_multiImport_diffCtx(cl_device_id device_, cl_context context_,
85                                     cl_command_queue queue_, int numElements_)
86 {
87     params_reset();
88     multiImport = true;
89     multiCtx = true;
90     log_info("RUNNING TEST WITH MULTIPLE DEVICE MEMORY IMPORT "
91              "IN DIFFERENT CONTEXT...... \n\n");
92     return test_buffer_common(device_, context_, queue_, numElements_, false);
93 }
test_buffer_single_queue_fence(cl_device_id device_,cl_context context_,cl_command_queue queue_,int numElements_)94 int test_buffer_single_queue_fence(cl_device_id device_, cl_context context_,
95                                    cl_command_queue queue_, int numElements_)
96 {
97     params_reset();
98     log_info("RUNNING TEST WITH ONE QUEUE...... \n\n");
99     return test_buffer_common(device_, context_, queue_, numElements_, true);
100 }
test_buffer_multiple_queue_fence(cl_device_id device_,cl_context context_,cl_command_queue queue_,int numElements_)101 int test_buffer_multiple_queue_fence(cl_device_id device_, cl_context context_,
102                                      cl_command_queue queue_, int numElements_)
103 {
104     params_reset();
105     numCQ = 2;
106     log_info("RUNNING TEST WITH TWO QUEUE...... \n\n");
107     return test_buffer_common(device_, context_, queue_, numElements_, true);
108 }
test_buffer_multiImport_sameCtx_fence(cl_device_id device_,cl_context context_,cl_command_queue queue_,int numElements_)109 int test_buffer_multiImport_sameCtx_fence(cl_device_id device_,
110                                           cl_context context_,
111                                           cl_command_queue queue_,
112                                           int numElements_)
113 {
114     params_reset();
115     multiImport = true;
116     log_info("RUNNING TEST WITH MULTIPLE DEVICE MEMORY IMPORT "
117              "IN SAME CONTEXT...... \n\n");
118     return test_buffer_common(device_, context_, queue_, numElements_, true);
119 }
test_buffer_multiImport_diffCtx_fence(cl_device_id device_,cl_context context_,cl_command_queue queue_,int numElements_)120 int test_buffer_multiImport_diffCtx_fence(cl_device_id device_,
121                                           cl_context context_,
122                                           cl_command_queue queue_,
123                                           int numElements_)
124 {
125     params_reset();
126     multiImport = true;
127     multiCtx = true;
128     log_info("RUNNING TEST WITH MULTIPLE DEVICE MEMORY IMPORT "
129              "IN DIFFERENT CONTEXT...... \n\n");
130     return test_buffer_common(device_, context_, queue_, numElements_, true);
131 }
test_image_single_queue(cl_device_id device_,cl_context context_,cl_command_queue queue_,int numElements_)132 int test_image_single_queue(cl_device_id device_, cl_context context_,
133                             cl_command_queue queue_, int numElements_)
134 {
135     params_reset();
136     log_info("RUNNING TEST WITH ONE QUEUE...... \n\n");
137     return test_image_common(device_, context_, queue_, numElements_);
138 }
test_image_multiple_queue(cl_device_id device_,cl_context context_,cl_command_queue queue_,int numElements_)139 int test_image_multiple_queue(cl_device_id device_, cl_context context_,
140                               cl_command_queue queue_, int numElements_)
141 {
142     params_reset();
143     numCQ = 2;
144     log_info("RUNNING TEST WITH TWO QUEUE...... \n\n");
145     return test_image_common(device_, context_, queue_, numElements_);
146 }
147 
148 test_definition test_list[] = { ADD_TEST(buffer_single_queue),
149                                 ADD_TEST(buffer_multiple_queue),
150                                 ADD_TEST(buffer_multiImport_sameCtx),
151                                 ADD_TEST(buffer_multiImport_diffCtx),
152                                 ADD_TEST(buffer_single_queue_fence),
153                                 ADD_TEST(buffer_multiple_queue_fence),
154                                 ADD_TEST(buffer_multiImport_sameCtx_fence),
155                                 ADD_TEST(buffer_multiImport_diffCtx_fence),
156                                 ADD_TEST(image_single_queue),
157                                 ADD_TEST(image_multiple_queue),
158                                 ADD_TEST(consistency_external_buffer),
159                                 ADD_TEST(consistency_external_image),
160                                 ADD_TEST(consistency_external_semaphore),
161                                 ADD_TEST(platform_info),
162                                 ADD_TEST(device_info) };
163 
164 const int test_num = ARRAY_SIZE(test_list);
165 
166 cl_device_type gDeviceType = CL_DEVICE_TYPE_DEFAULT;
167 char *choosen_platform_name = NULL;
168 cl_platform_id platform = NULL;
169 cl_int choosen_platform_index = -1;
170 char platform_name[1024] = "";
171 cl_platform_id select_platform = NULL;
172 char *extensions = NULL;
173 size_t extensionSize = 0;
174 cl_uint num_devices = 0;
175 cl_uint device_no = 0;
176 cl_device_id *devices;
177 const size_t bufsize = BUFFERSIZE;
178 char buf[BUFFERSIZE];
179 cl_uchar uuid[CL_UUID_SIZE_KHR];
180 unsigned int numCQ;
181 bool multiImport;
182 bool multiCtx;
183 bool debug_trace = false;
184 bool useSingleImageKernel = false;
185 bool useDeviceLocal = false;
186 bool disableNTHandleType = false;
187 bool enableOffset = false;
188 
printUsage(const char * execName)189 static void printUsage(const char *execName)
190 {
191     const char *p = strrchr(execName, '/');
192     if (p != NULL) execName = p + 1;
193 
194     log_info("Usage: %s [test_names] [options]\n", execName);
195     log_info("Test names:\n");
196     for (int i = 0; i < test_num; i++)
197     {
198         log_info("\t%s\n", test_list[i].name);
199     }
200     log_info("\n");
201     log_info("Options:\n");
202     log_info("\t--debug_trace - Enables additional debug info logging\n");
203     log_info("\t--non_dedicated - Choose dedicated Vs. non_dedicated \n");
204 }
205 
parseParams(int argc,const char * argv[],const char ** argList)206 size_t parseParams(int argc, const char *argv[], const char **argList)
207 {
208     size_t argCount = 1;
209     for (int i = 1; i < argc; i++)
210     {
211         if (argv[i] == NULL) break;
212         if (argv[i][0] == '-')
213         {
214             if (!strcmp(argv[i], "--debug_trace"))
215             {
216                 debug_trace = true;
217             }
218             if (!strcmp(argv[i], "--useSingleImageKernel"))
219             {
220                 useSingleImageKernel = true;
221             }
222             if (!strcmp(argv[i], "--useDeviceLocal"))
223             {
224                 useDeviceLocal = true;
225             }
226             if (!strcmp(argv[i], "--disableNTHandleType"))
227             {
228                 disableNTHandleType = true;
229             }
230             if (!strcmp(argv[i], "--enableOffset"))
231             {
232                 enableOffset = true;
233             }
234             if (strcmp(argv[i], "-h") == 0)
235             {
236                 printUsage(argv[0]);
237                 argCount = 0; // Returning argCount=0 to assert error in main()
238                 break;
239             }
240         }
241         else
242         {
243             argList[argCount] = argv[i];
244             argCount++;
245         }
246     }
247     return argCount;
248 }
249 
main(int argc,const char * argv[])250 int main(int argc, const char *argv[])
251 {
252     int errNum = 0;
253 
254     test_start();
255     params_reset();
256 
257     if (!checkVkSupport())
258     {
259         log_info("Vulkan supported GPU not found \n");
260         log_info("TEST SKIPPED \n");
261         return 0;
262     }
263 
264     VulkanDevice vkDevice;
265 
266     cl_device_type requestedDeviceType = CL_DEVICE_TYPE_GPU;
267     char *force_cpu = getenv("CL_DEVICE_TYPE");
268     if (force_cpu != NULL)
269     {
270         if (strcmp(force_cpu, "gpu") == 0
271             || strcmp(force_cpu, "CL_DEVICE_TYPE_GPU") == 0)
272             requestedDeviceType = CL_DEVICE_TYPE_GPU;
273         else if (strcmp(force_cpu, "cpu") == 0
274                  || strcmp(force_cpu, "CL_DEVICE_TYPE_CPU") == 0)
275             requestedDeviceType = CL_DEVICE_TYPE_CPU;
276         else if (strcmp(force_cpu, "accelerator") == 0
277                  || strcmp(force_cpu, "CL_DEVICE_TYPE_ACCELERATOR") == 0)
278             requestedDeviceType = CL_DEVICE_TYPE_ACCELERATOR;
279         else if (strcmp(force_cpu, "CL_DEVICE_TYPE_DEFAULT") == 0)
280             requestedDeviceType = CL_DEVICE_TYPE_DEFAULT;
281     }
282 
283     if (requestedDeviceType != CL_DEVICE_TYPE_GPU)
284     {
285         log_info("Vulkan tests can only run on a GPU device.\n");
286         return 0;
287     }
288     gDeviceType = CL_DEVICE_TYPE_GPU;
289 
290     const char **argList = (const char **)calloc(argc, sizeof(char *));
291     size_t argCount = parseParams(argc, argv, argList);
292     if (argCount == 0) return 0;
293     // get the platform ID
294     errNum = clGetPlatformIDs(1, &platform, NULL);
295     if (errNum != CL_SUCCESS)
296     {
297         print_error(errNum, "Error: Failed to get platform\n");
298         return errNum;
299     }
300 
301     errNum =
302         clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 0, NULL, &num_devices);
303     if (CL_SUCCESS != errNum)
304     {
305         print_error(errNum, "clGetDeviceIDs failed in returning of devices\n");
306         return errNum;
307     }
308     devices = (cl_device_id *)malloc(num_devices * sizeof(cl_device_id));
309     if (NULL == devices)
310     {
311         print_error(errNum, "Unable to allocate memory for devices\n");
312         return CL_OUT_OF_HOST_MEMORY;
313     }
314     errNum = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, num_devices, devices,
315                             NULL);
316     if (CL_SUCCESS != errNum)
317     {
318         print_error(errNum, "Failed to get deviceID.\n");
319         return errNum;
320     }
321     for (device_no = 0; device_no < num_devices; device_no++)
322     {
323         errNum = clGetDeviceInfo(devices[device_no], CL_DEVICE_EXTENSIONS, 0,
324                                  NULL, &extensionSize);
325         if (CL_SUCCESS != errNum)
326         {
327             log_error("Error in clGetDeviceInfo for getting "
328                       "device_extension size....\n");
329             return errNum;
330         }
331         extensions = (char *)malloc(extensionSize);
332         if (NULL == extensions)
333         {
334             log_error("Unable to allocate memory for extensions\n");
335             return CL_OUT_OF_HOST_MEMORY;
336         }
337         errNum =
338             clGetDeviceInfo(devices[device_no], CL_DEVICE_EXTENSIONS,
339                             extensionSize, extensions, NULL /*&extensionSize*/);
340         if (CL_SUCCESS != errNum)
341         {
342             print_error(errNum,
343                         "Error in clGetDeviceInfo for getting "
344                         "device_extension\n");
345             return errNum;
346         }
347         errNum = clGetDeviceInfo(devices[device_no], CL_DEVICE_UUID_KHR,
348                                  CL_UUID_SIZE_KHR, uuid, &extensionSize);
349         if (CL_SUCCESS != errNum)
350         {
351             print_error(errNum, "clGetDeviceInfo failed with error\n ");
352             return errNum;
353         }
354         errNum =
355             memcmp(uuid, vkDevice.getPhysicalDevice().getUUID(), VK_UUID_SIZE);
356         if (errNum == 0)
357         {
358             break;
359         }
360     }
361     if (device_no >= num_devices)
362     {
363         fprintf(stderr,
364                 "OpenCL error: "
365                 "No Vulkan-OpenCL Interop capable GPU found.\n");
366     }
367     if (!(is_extension_available(devices[device_no], "cl_khr_external_memory")
368           && is_extension_available(devices[device_no],
369                                     "cl_khr_external_semaphore")))
370     {
371         log_info("Device does not support cl_khr_external_memory "
372                  "or cl_khr_external_semaphore\n");
373         log_info(" TEST SKIPPED\n");
374         return CL_SUCCESS;
375     }
376     init_cl_vk_ext(platform);
377 
378     // Execute tests.
379     // Note: don't use the entire harness, because we have a different way of
380     // obtaining the device (via the context)
381     test_harness_config config{};
382     config.forceNoContextCreation = true;
383     config.numElementsToUse = 1024;
384     config.queueProps = 0;
385     errNum = parseAndCallCommandLineTests(argCount, argList, devices[device_no],
386                                           test_num, test_list, config);
387     return errNum;
388 }
389