aboutsummaryrefslogtreecommitdiff
path: root/test_conformance/vulkan/main.cpp
blob: 5901420ad88e5f2d7ce5dd39267f01ad3460ae2d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
//
// Copyright (c) 2022 The Khronos Group Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#include <stdio.h>
#include <stdlib.h>

#if !defined(_WIN32)
#include <stdbool.h>
#endif

#include <math.h>
#include <string.h>

#if !defined(__APPLE__)
#include <CL/cl.h>
#else
#include <OpenCL/cl.h>
#endif


#include "procs.h"
#include "harness/testHarness.h"
#include "harness/parseParameters.h"
#include "harness/deviceInfo.h"

#if !defined(_WIN32)
#include <unistd.h>
#endif
#include <vulkan_interop_common.hpp>
#include <vulkan_wrapper.hpp>

#define BUFFERSIZE 3000

static void params_reset()
{
    numCQ = 1;
    multiImport = false;
    multiCtx = false;
}

extern int test_buffer_common(cl_device_id device_, cl_context context_,
                              cl_command_queue queue_, int numElements_);
extern int test_image_common(cl_device_id device_, cl_context context_,
                             cl_command_queue queue_, int numElements_);

int test_buffer_single_queue(cl_device_id device_, cl_context context_,
                             cl_command_queue queue_, int numElements_)
{
    params_reset();
    log_info("RUNNING TEST WITH ONE QUEUE...... \n\n");
    return test_buffer_common(device_, context_, queue_, numElements_);
}
int test_buffer_multiple_queue(cl_device_id device_, cl_context context_,
                               cl_command_queue queue_, int numElements_)
{
    params_reset();
    numCQ = 2;
    log_info("RUNNING TEST WITH TWO QUEUE...... \n\n");
    return test_buffer_common(device_, context_, queue_, numElements_);
}
int test_buffer_multiImport_sameCtx(cl_device_id device_, cl_context context_,
                                    cl_command_queue queue_, int numElements_)
{
    params_reset();
    multiImport = true;
    log_info("RUNNING TEST WITH MULTIPLE DEVICE MEMORY IMPORT "
             "IN SAME CONTEXT...... \n\n");
    return test_buffer_common(device_, context_, queue_, numElements_);
}
int test_buffer_multiImport_diffCtx(cl_device_id device_, cl_context context_,
                                    cl_command_queue queue_, int numElements_)
{
    params_reset();
    multiImport = true;
    multiCtx = true;
    log_info("RUNNING TEST WITH MULTIPLE DEVICE MEMORY IMPORT "
             "IN DIFFERENT CONTEXT...... \n\n");
    return test_buffer_common(device_, context_, queue_, numElements_);
}
int test_image_single_queue(cl_device_id device_, cl_context context_,
                            cl_command_queue queue_, int numElements_)
{
    params_reset();
    log_info("RUNNING TEST WITH ONE QUEUE...... \n\n");
    return test_image_common(device_, context_, queue_, numElements_);
}
int test_image_multiple_queue(cl_device_id device_, cl_context context_,
                              cl_command_queue queue_, int numElements_)
{
    params_reset();
    numCQ = 2;
    log_info("RUNNING TEST WITH TWO QUEUE...... \n\n");
    return test_image_common(device_, context_, queue_, numElements_);
}

test_definition test_list[] = { ADD_TEST(buffer_single_queue),
                                ADD_TEST(buffer_multiple_queue),
                                ADD_TEST(buffer_multiImport_sameCtx),
                                ADD_TEST(buffer_multiImport_diffCtx),
                                ADD_TEST(image_single_queue),
                                ADD_TEST(image_multiple_queue),
                                ADD_TEST(consistency_external_buffer),
                                ADD_TEST(consistency_external_image),
                                ADD_TEST(consistency_external_semaphore),
                                ADD_TEST(platform_info),
                                ADD_TEST(device_info) };

const int test_num = ARRAY_SIZE(test_list);

cl_device_type gDeviceType = CL_DEVICE_TYPE_DEFAULT;
char *choosen_platform_name = NULL;
cl_platform_id platform = NULL;
cl_int choosen_platform_index = -1;
char platform_name[1024] = "";
cl_platform_id select_platform = NULL;
char *extensions = NULL;
size_t extensionSize = 0;
cl_uint num_devices = 0;
cl_uint device_no = 0;
cl_device_id *devices;
const size_t bufsize = BUFFERSIZE;
char buf[BUFFERSIZE];
cl_uchar uuid[CL_UUID_SIZE_KHR];
unsigned int numCQ;
bool multiImport;
bool multiCtx;
bool debug_trace = false;
bool useSingleImageKernel = false;
bool useDeviceLocal = false;
bool disableNTHandleType = false;
bool enableOffset = false;
bool non_dedicated = false;

static void printUsage(const char *execName)
{
    const char *p = strrchr(execName, '/');
    if (p != NULL) execName = p + 1;

    log_info("Usage: %s [test_names] [options]\n", execName);
    log_info("Test names:\n");
    for (int i = 0; i < test_num; i++)
    {
        log_info("\t%s\n", test_list[i].name);
    }
    log_info("\n");
    log_info("Options:\n");
    log_info("\t--debug_trace - Enables additional debug info logging\n");
    log_info("\t--non_dedicated - Choose dedicated Vs. non_dedicated \n");
}

size_t parseParams(int argc, const char *argv[], const char **argList)
{
    size_t argCount = 1;
    for (int i = 1; i < argc; i++)
    {
        if (argv[i] == NULL) break;
        if (argv[i][0] == '-')
        {
            if (!strcmp(argv[i], "--debug_trace"))
            {
                debug_trace = true;
            }
            if (!strcmp(argv[i], "--useSingleImageKernel"))
            {
                useSingleImageKernel = true;
            }
            if (!strcmp(argv[i], "--useDeviceLocal"))
            {
                useDeviceLocal = true;
            }
            if (!strcmp(argv[i], "--disableNTHandleType"))
            {
                disableNTHandleType = true;
            }
            if (!strcmp(argv[i], "--enableOffset"))
            {
                enableOffset = true;
            }
            if (!strcmp(argv[i], "--non_dedicated"))
            {
                non_dedicated = true;
            }
            if (strcmp(argv[i], "-h") == 0)
            {
                printUsage(argv[0]);
                argCount = 0; // Returning argCount=0 to assert error in main()
                break;
            }
        }
        else
        {
            argList[argCount] = argv[i];
            argCount++;
        }
    }
    return argCount;
}

int main(int argc, const char *argv[])
{
    int errNum = 0;

    test_start();
    params_reset();

    if (!checkVkSupport())
    {
        log_info("Vulkan supported GPU not found \n");
        log_info("TEST SKIPPED \n");
        return 0;
    }

    VulkanDevice vkDevice;

    cl_device_type requestedDeviceType = CL_DEVICE_TYPE_GPU;
    char *force_cpu = getenv("CL_DEVICE_TYPE");
    if (force_cpu != NULL)
    {
        if (strcmp(force_cpu, "gpu") == 0
            || strcmp(force_cpu, "CL_DEVICE_TYPE_GPU") == 0)
            requestedDeviceType = CL_DEVICE_TYPE_GPU;
        else if (strcmp(force_cpu, "cpu") == 0
                 || strcmp(force_cpu, "CL_DEVICE_TYPE_CPU") == 0)
            requestedDeviceType = CL_DEVICE_TYPE_CPU;
        else if (strcmp(force_cpu, "accelerator") == 0
                 || strcmp(force_cpu, "CL_DEVICE_TYPE_ACCELERATOR") == 0)
            requestedDeviceType = CL_DEVICE_TYPE_ACCELERATOR;
        else if (strcmp(force_cpu, "CL_DEVICE_TYPE_DEFAULT") == 0)
            requestedDeviceType = CL_DEVICE_TYPE_DEFAULT;
    }

    if (requestedDeviceType != CL_DEVICE_TYPE_GPU)
    {
        log_info("Vulkan tests can only run on a GPU device.\n");
        return 0;
    }
    gDeviceType = CL_DEVICE_TYPE_GPU;

    const char **argList = (const char **)calloc(argc, sizeof(char *));
    size_t argCount = parseParams(argc, argv, argList);
    if (argCount == 0) return 0;
    // get the platform ID
    errNum = clGetPlatformIDs(1, &platform, NULL);
    if (errNum != CL_SUCCESS)
    {
        print_error(errNum, "Error: Failed to get platform\n");
        return errNum;
    }

    errNum =
        clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 0, NULL, &num_devices);
    if (CL_SUCCESS != errNum)
    {
        print_error(errNum, "clGetDeviceIDs failed in returning of devices\n");
        return errNum;
    }
    devices = (cl_device_id *)malloc(num_devices * sizeof(cl_device_id));
    if (NULL == devices)
    {
        print_error(errNum, "Unable to allocate memory for devices\n");
        return CL_OUT_OF_HOST_MEMORY;
    }
    errNum = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, num_devices, devices,
                            NULL);
    if (CL_SUCCESS != errNum)
    {
        print_error(errNum, "Failed to get deviceID.\n");
        return errNum;
    }
    for (device_no = 0; device_no < num_devices; device_no++)
    {
        errNum = clGetDeviceInfo(devices[device_no], CL_DEVICE_EXTENSIONS, 0,
                                 NULL, &extensionSize);
        if (CL_SUCCESS != errNum)
        {
            log_error("Error in clGetDeviceInfo for getting "
                      "device_extension size....\n");
            return errNum;
        }
        extensions = (char *)malloc(extensionSize);
        if (NULL == extensions)
        {
            log_error("Unable to allocate memory for extensions\n");
            return CL_OUT_OF_HOST_MEMORY;
        }
        errNum =
            clGetDeviceInfo(devices[device_no], CL_DEVICE_EXTENSIONS,
                            extensionSize, extensions, NULL /*&extensionSize*/);
        if (CL_SUCCESS != errNum)
        {
            print_error(errNum,
                        "Error in clGetDeviceInfo for getting "
                        "device_extension\n");
            return errNum;
        }
        errNum = clGetDeviceInfo(devices[device_no], CL_DEVICE_UUID_KHR,
                                 CL_UUID_SIZE_KHR, uuid, &extensionSize);
        if (CL_SUCCESS != errNum)
        {
            print_error(errNum, "clGetDeviceInfo failed with error\n ");
            return errNum;
        }
        errNum =
            memcmp(uuid, vkDevice.getPhysicalDevice().getUUID(), VK_UUID_SIZE);
        if (errNum == 0)
        {
            break;
        }
    }
    if (device_no >= num_devices)
    {
        fprintf(stderr,
                "OpenCL error: "
                "No Vulkan-OpenCL Interop capable GPU found.\n");
    }
    if (!(is_extension_available(devices[device_no], "cl_khr_external_memory")
          && is_extension_available(devices[device_no],
                                    "cl_khr_external_semaphore")))
    {
        log_info("Device does not support cl_khr_external_memory "
                 "or cl_khr_external_semaphore\n");
        log_info(" TEST SKIPPED\n");
        return CL_SUCCESS;
    }
    init_cl_vk_ext(platform);

    // Execute tests.
    // Note: don't use the entire harness, because we have a different way of
    // obtaining the device (via the context)
    test_harness_config config{};
    config.forceNoContextCreation = true;
    config.numElementsToUse = 1024;
    config.queueProps = 0;
    errNum = parseAndCallCommandLineTests(argCount, argList, devices[device_no],
                                          test_num, test_list, config);
    return errNum;
}