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 #include "common.h"
17 
18 
19 // This tests that all devices and the host share a common address space using fine-grain mode with no buffers.
20 // This is done by creating a linked list on a device and then verifying the correctness of the list
21 // on another device or the host.  This basic test is performed for all combinations of devices and the host that exist within
22 // the platform.  The test passes only if every combination passes.
test_svm_shared_address_space_fine_grain(cl_device_id deviceID,cl_context context2,cl_command_queue queue,int num_elements)23 int test_svm_shared_address_space_fine_grain(cl_device_id deviceID, cl_context context2, cl_command_queue queue, int num_elements)
24 {
25   clContextWrapper    context = NULL;
26   clProgramWrapper    program = NULL;
27   cl_uint     num_devices = 0;
28   cl_int      error = CL_SUCCESS;
29   clCommandQueueWrapper queues[MAXQ];
30 
31   error = create_cl_objects(deviceID, &linked_list_create_and_verify_kernels[0], &context, &program, &queues[0], &num_devices, CL_DEVICE_SVM_FINE_GRAIN_SYSTEM);
32   if(error == 1) return 0; // no devices capable of requested SVM level, so don't execute but count test as passing.
33   if(error < 0) return -1; // fail test.
34 
35   size_t numLists =  num_elements;
36   cl_int ListLength = 32;
37 
38   clKernelWrapper kernel_create_lists = clCreateKernel(program, "create_linked_lists", &error);
39   test_error(error, "clCreateKernel failed");
40 
41   clKernelWrapper kernel_verify_lists = clCreateKernel(program, "verify_linked_lists", &error);
42   test_error(error, "clCreateKernel failed");
43 
44   // this allocation holds the linked list nodes.
45   // FIXME: remove the alignment once prototype can handle it
46   Node* pNodes = (Node*) align_malloc(numLists*ListLength*sizeof(Node),128);
47   test_error2(error, pNodes, "malloc failed");
48 
49   // this allocation holds an index into the nodes buffer, it is used for node allocation
50   size_t* pAllocator = (size_t*) align_malloc(sizeof(cl_int), 128);
51   test_error2(error, pAllocator, "malloc failed");
52 
53   // this allocation holds the count of correct nodes, which is computed by the verify kernel.
54   cl_int* pNum_correct = (cl_int*) align_malloc(sizeof(cl_int), 128);
55   test_error2(error, pNum_correct, "malloc failed");
56 
57 
58   error |= clSetKernelArgSVMPointer(kernel_create_lists, 0, pNodes);
59   error |= clSetKernelArgSVMPointer(kernel_create_lists, 1, pAllocator);
60   error |= clSetKernelArg(kernel_create_lists, 2, sizeof(cl_int),(void *) &ListLength);
61 
62   error |= clSetKernelArgSVMPointer(kernel_verify_lists, 0, pNodes);
63   error |= clSetKernelArgSVMPointer(kernel_verify_lists, 1, pNum_correct);
64   error |= clSetKernelArg(kernel_verify_lists, 2, sizeof(cl_int),   (void *) &ListLength);
65   test_error(error, "clSetKernelArg failed");
66 
67   // Create linked list on one device and verify on another device (or the host).
68   // Do this for all possible combinations of devices and host within the platform.
69   for (int ci=0; ci<(int)num_devices+1; ci++)  // ci is CreationIndex, index of device/q to create linked list on
70   {
71     for (int vi=0; vi<(int)num_devices+1; vi++)  // vi is VerificationIndex, index of device/q to verify linked list on
72     {
73       if(ci == num_devices) // last device index represents the host, note the num_device+1 above.
74       {
75         log_info("creating linked list on host ");
76         create_linked_lists(pNodes, numLists, ListLength);
77       }
78       else
79       {
80         error = create_linked_lists_on_device_no_map(ci, queues[ci], pAllocator, kernel_create_lists, numLists);
81         if(error) return -1;
82       }
83 
84       if(vi == num_devices)
85       {
86         error = verify_linked_lists(pNodes, numLists, ListLength);
87         if(error) return -1;
88       }
89       else
90       {
91         error = verify_linked_lists_on_device_no_map(vi, queues[vi], pNum_correct, kernel_verify_lists, ListLength, numLists);
92         if(error) return -1;
93       }
94     }
95   }
96 
97   align_free(pNodes);
98   align_free(pAllocator);
99   align_free(pNum_correct);
100   return 0;
101 }
102