• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 extern int test_image_common(cl_device_id device_, cl_context context_,
57                              cl_command_queue queue_, int numElements_);
58 
test_buffer_single_queue(cl_device_id device_,cl_context context_,cl_command_queue queue_,int numElements_)59 int test_buffer_single_queue(cl_device_id device_, cl_context context_,
60                              cl_command_queue queue_, int numElements_)
61 {
62     params_reset();
63     log_info("RUNNING TEST WITH ONE QUEUE...... \n\n");
64     return test_buffer_common(device_, context_, queue_, numElements_);
65 }
test_buffer_multiple_queue(cl_device_id device_,cl_context context_,cl_command_queue queue_,int numElements_)66 int test_buffer_multiple_queue(cl_device_id device_, cl_context context_,
67                                cl_command_queue queue_, int numElements_)
68 {
69     params_reset();
70     numCQ = 2;
71     log_info("RUNNING TEST WITH TWO QUEUE...... \n\n");
72     return test_buffer_common(device_, context_, queue_, numElements_);
73 }
test_buffer_multiImport_sameCtx(cl_device_id device_,cl_context context_,cl_command_queue queue_,int numElements_)74 int test_buffer_multiImport_sameCtx(cl_device_id device_, cl_context context_,
75                                     cl_command_queue queue_, int numElements_)
76 {
77     params_reset();
78     multiImport = true;
79     log_info("RUNNING TEST WITH MULTIPLE DEVICE MEMORY IMPORT "
80              "IN SAME CONTEXT...... \n\n");
81     return test_buffer_common(device_, context_, queue_, numElements_);
82 }
test_buffer_multiImport_diffCtx(cl_device_id device_,cl_context context_,cl_command_queue queue_,int numElements_)83 int test_buffer_multiImport_diffCtx(cl_device_id device_, cl_context context_,
84                                     cl_command_queue queue_, int numElements_)
85 {
86     params_reset();
87     multiImport = true;
88     multiCtx = true;
89     log_info("RUNNING TEST WITH MULTIPLE DEVICE MEMORY IMPORT "
90              "IN DIFFERENT CONTEXT...... \n\n");
91     return test_buffer_common(device_, context_, queue_, numElements_);
92 }
test_image_single_queue(cl_device_id device_,cl_context context_,cl_command_queue queue_,int numElements_)93 int test_image_single_queue(cl_device_id device_, cl_context context_,
94                             cl_command_queue queue_, int numElements_)
95 {
96     params_reset();
97     log_info("RUNNING TEST WITH ONE QUEUE...... \n\n");
98     return test_image_common(device_, context_, queue_, numElements_);
99 }
test_image_multiple_queue(cl_device_id device_,cl_context context_,cl_command_queue queue_,int numElements_)100 int test_image_multiple_queue(cl_device_id device_, cl_context context_,
101                               cl_command_queue queue_, int numElements_)
102 {
103     params_reset();
104     numCQ = 2;
105     log_info("RUNNING TEST WITH TWO QUEUE...... \n\n");
106     return test_image_common(device_, context_, queue_, numElements_);
107 }
108 
109 test_definition test_list[] = { ADD_TEST(buffer_single_queue),
110                                 ADD_TEST(buffer_multiple_queue),
111                                 ADD_TEST(buffer_multiImport_sameCtx),
112                                 ADD_TEST(buffer_multiImport_diffCtx),
113                                 ADD_TEST(image_single_queue),
114                                 ADD_TEST(image_multiple_queue),
115                                 ADD_TEST(consistency_external_buffer),
116                                 ADD_TEST(consistency_external_image),
117                                 ADD_TEST(consistency_external_semaphore),
118                                 ADD_TEST(platform_info),
119                                 ADD_TEST(device_info) };
120 
121 const int test_num = ARRAY_SIZE(test_list);
122 
123 cl_device_type gDeviceType = CL_DEVICE_TYPE_DEFAULT;
124 char *choosen_platform_name = NULL;
125 cl_platform_id platform = NULL;
126 cl_int choosen_platform_index = -1;
127 char platform_name[1024] = "";
128 cl_platform_id select_platform = NULL;
129 char *extensions = NULL;
130 size_t extensionSize = 0;
131 cl_uint num_devices = 0;
132 cl_uint device_no = 0;
133 cl_device_id *devices;
134 const size_t bufsize = BUFFERSIZE;
135 char buf[BUFFERSIZE];
136 cl_uchar uuid[CL_UUID_SIZE_KHR];
137 unsigned int numCQ;
138 bool multiImport;
139 bool multiCtx;
140 bool debug_trace = false;
141 bool useSingleImageKernel = false;
142 bool useDeviceLocal = false;
143 bool disableNTHandleType = false;
144 bool enableOffset = false;
145 bool non_dedicated = false;
146 
printUsage(const char * execName)147 static void printUsage(const char *execName)
148 {
149     const char *p = strrchr(execName, '/');
150     if (p != NULL) execName = p + 1;
151 
152     log_info("Usage: %s [test_names] [options]\n", execName);
153     log_info("Test names:\n");
154     for (int i = 0; i < test_num; i++)
155     {
156         log_info("\t%s\n", test_list[i].name);
157     }
158     log_info("\n");
159     log_info("Options:\n");
160     log_info("\t--debug_trace - Enables additional debug info logging\n");
161     log_info("\t--non_dedicated - Choose dedicated Vs. non_dedicated \n");
162 }
163 
parseParams(int argc,const char * argv[],const char ** argList)164 size_t parseParams(int argc, const char *argv[], const char **argList)
165 {
166     size_t argCount = 1;
167     for (int i = 1; i < argc; i++)
168     {
169         if (argv[i] == NULL) break;
170         if (argv[i][0] == '-')
171         {
172             if (!strcmp(argv[i], "--debug_trace"))
173             {
174                 debug_trace = true;
175             }
176             if (!strcmp(argv[i], "--useSingleImageKernel"))
177             {
178                 useSingleImageKernel = true;
179             }
180             if (!strcmp(argv[i], "--useDeviceLocal"))
181             {
182                 useDeviceLocal = true;
183             }
184             if (!strcmp(argv[i], "--disableNTHandleType"))
185             {
186                 disableNTHandleType = true;
187             }
188             if (!strcmp(argv[i], "--enableOffset"))
189             {
190                 enableOffset = true;
191             }
192             if (!strcmp(argv[i], "--non_dedicated"))
193             {
194                 non_dedicated = true;
195             }
196             if (strcmp(argv[i], "-h") == 0)
197             {
198                 printUsage(argv[0]);
199                 argCount = 0; // Returning argCount=0 to assert error in main()
200                 break;
201             }
202         }
203         else
204         {
205             argList[argCount] = argv[i];
206             argCount++;
207         }
208     }
209     return argCount;
210 }
211 
main(int argc,const char * argv[])212 int main(int argc, const char *argv[])
213 {
214     int errNum = 0;
215 
216     test_start();
217     params_reset();
218 
219     if (!checkVkSupport())
220     {
221         log_info("Vulkan supported GPU not found \n");
222         log_info("TEST SKIPPED \n");
223         return 0;
224     }
225 
226     VulkanDevice vkDevice;
227 
228     cl_device_type requestedDeviceType = CL_DEVICE_TYPE_GPU;
229     char *force_cpu = getenv("CL_DEVICE_TYPE");
230     if (force_cpu != NULL)
231     {
232         if (strcmp(force_cpu, "gpu") == 0
233             || strcmp(force_cpu, "CL_DEVICE_TYPE_GPU") == 0)
234             requestedDeviceType = CL_DEVICE_TYPE_GPU;
235         else if (strcmp(force_cpu, "cpu") == 0
236                  || strcmp(force_cpu, "CL_DEVICE_TYPE_CPU") == 0)
237             requestedDeviceType = CL_DEVICE_TYPE_CPU;
238         else if (strcmp(force_cpu, "accelerator") == 0
239                  || strcmp(force_cpu, "CL_DEVICE_TYPE_ACCELERATOR") == 0)
240             requestedDeviceType = CL_DEVICE_TYPE_ACCELERATOR;
241         else if (strcmp(force_cpu, "CL_DEVICE_TYPE_DEFAULT") == 0)
242             requestedDeviceType = CL_DEVICE_TYPE_DEFAULT;
243     }
244 
245     if (requestedDeviceType != CL_DEVICE_TYPE_GPU)
246     {
247         log_info("Vulkan tests can only run on a GPU device.\n");
248         return 0;
249     }
250     gDeviceType = CL_DEVICE_TYPE_GPU;
251 
252     const char **argList = (const char **)calloc(argc, sizeof(char *));
253     size_t argCount = parseParams(argc, argv, argList);
254     if (argCount == 0) return 0;
255     // get the platform ID
256     errNum = clGetPlatformIDs(1, &platform, NULL);
257     if (errNum != CL_SUCCESS)
258     {
259         print_error(errNum, "Error: Failed to get platform\n");
260         return errNum;
261     }
262 
263     errNum =
264         clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 0, NULL, &num_devices);
265     if (CL_SUCCESS != errNum)
266     {
267         print_error(errNum, "clGetDeviceIDs failed in returning of devices\n");
268         return errNum;
269     }
270     devices = (cl_device_id *)malloc(num_devices * sizeof(cl_device_id));
271     if (NULL == devices)
272     {
273         print_error(errNum, "Unable to allocate memory for devices\n");
274         return CL_OUT_OF_HOST_MEMORY;
275     }
276     errNum = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, num_devices, devices,
277                             NULL);
278     if (CL_SUCCESS != errNum)
279     {
280         print_error(errNum, "Failed to get deviceID.\n");
281         return errNum;
282     }
283     for (device_no = 0; device_no < num_devices; device_no++)
284     {
285         errNum = clGetDeviceInfo(devices[device_no], CL_DEVICE_EXTENSIONS, 0,
286                                  NULL, &extensionSize);
287         if (CL_SUCCESS != errNum)
288         {
289             log_error("Error in clGetDeviceInfo for getting "
290                       "device_extension size....\n");
291             return errNum;
292         }
293         extensions = (char *)malloc(extensionSize);
294         if (NULL == extensions)
295         {
296             log_error("Unable to allocate memory for extensions\n");
297             return CL_OUT_OF_HOST_MEMORY;
298         }
299         errNum =
300             clGetDeviceInfo(devices[device_no], CL_DEVICE_EXTENSIONS,
301                             extensionSize, extensions, NULL /*&extensionSize*/);
302         if (CL_SUCCESS != errNum)
303         {
304             print_error(errNum,
305                         "Error in clGetDeviceInfo for getting "
306                         "device_extension\n");
307             return errNum;
308         }
309         errNum = clGetDeviceInfo(devices[device_no], CL_DEVICE_UUID_KHR,
310                                  CL_UUID_SIZE_KHR, uuid, &extensionSize);
311         if (CL_SUCCESS != errNum)
312         {
313             print_error(errNum, "clGetDeviceInfo failed with error\n ");
314             return errNum;
315         }
316         errNum =
317             memcmp(uuid, vkDevice.getPhysicalDevice().getUUID(), VK_UUID_SIZE);
318         if (errNum == 0)
319         {
320             break;
321         }
322     }
323     if (device_no >= num_devices)
324     {
325         fprintf(stderr,
326                 "OpenCL error: "
327                 "No Vulkan-OpenCL Interop capable GPU found.\n");
328     }
329     if (!(is_extension_available(devices[device_no], "cl_khr_external_memory")
330           && is_extension_available(devices[device_no],
331                                     "cl_khr_external_semaphore")))
332     {
333         log_info("Device does not support cl_khr_external_memory "
334                  "or cl_khr_external_semaphore\n");
335         log_info(" TEST SKIPPED\n");
336         return CL_SUCCESS;
337     }
338     init_cl_vk_ext(platform);
339 
340     // Execute tests.
341     // Note: don't use the entire harness, because we have a different way of
342     // obtaining the device (via the context)
343     errNum = parseAndCallCommandLineTests(argCount, argList, devices[device_no],
344                                           test_num, test_list, true, 0, 1024);
345     return errNum;
346 }
347