• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright (c) 2020 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 "harness/compat.h"
17 
18 #include <array>
19 #include <bitset>
20 
21 #include "harness/testHarness.h"
22 #include "harness/deviceInfo.h"
23 
24 using uuid = std::array<cl_uchar, CL_UUID_SIZE_KHR>;
25 using luid = std::array<cl_uchar, CL_LUID_SIZE_KHR>;
26 
log_info_uuid(const T & id)27 template <typename T> static void log_info_uuid(const T &id)
28 {
29     for (const cl_uchar c : id)
30     {
31         log_info("%02x", static_cast<unsigned>(c));
32     }
33 }
34 
log_error_uuid(const T & id)35 template <typename T> static void log_error_uuid(const T &id)
36 {
37     for (const cl_uchar c : id)
38     {
39         log_error("%02x", static_cast<unsigned>(c));
40     }
41 }
42 
check_device_info_returns(const cl_int err,const size_t size,const size_t expected_size)43 static bool check_device_info_returns(const cl_int err, const size_t size,
44                                       const size_t expected_size)
45 {
46     if (err != CL_SUCCESS)
47     {
48         print_error(err, "clGetDeviceInfo failed");
49         return false;
50     }
51     else if (size != expected_size)
52     {
53         log_error("Invalid size written by clGetDeviceInfo (%zu != %zu)\n",
54                   size, expected_size);
55         return false;
56     }
57 
58     return true;
59 }
60 
61 template <typename T>
get_uuid(const cl_device_id device,const cl_device_info info,T & id,const bool twice=true)62 static bool get_uuid(const cl_device_id device, const cl_device_info info,
63                      T &id, const bool twice = true)
64 {
65     const size_t id_size = id.size() * sizeof(id[0]);
66 
67     size_t size_ret;
68     cl_int err = clGetDeviceInfo(device, info, id_size, id.data(), &size_ret);
69     if (!check_device_info_returns(err, size_ret, id_size))
70     {
71         return false;
72     }
73 
74     /* Check that IDs are (at the very least) stable across two successive
75      * clGetDeviceInfo calls. Check conditionally, as it is undefined what the
76      * query for CL_DEVICE_LUID_KHR returns if CL_DEVICE_LUID_VALID_KHR returns
77      * false. */
78     if (twice)
79     {
80         T id_2;
81         size_t size_ret_2;
82         err = clGetDeviceInfo(device, info, id_size, id_2.data(), &size_ret_2);
83         if (!check_device_info_returns(err, size_ret_2, id_size))
84         {
85             return false;
86         }
87 
88         if (id != id_2)
89         {
90             log_error("Got different IDs from the same ID device info (");
91             log_error_uuid(id);
92             log_error(" != ");
93             log_error_uuid(id_2);
94             log_error(")\n");
95             return false;
96         }
97     }
98 
99     return true;
100 }
101 
test_device_uuid(cl_device_id deviceID,cl_context context,cl_command_queue ignoreQueue,int num_elements)102 int test_device_uuid(cl_device_id deviceID, cl_context context,
103                      cl_command_queue ignoreQueue, int num_elements)
104 {
105     if (!is_extension_available(deviceID, "cl_khr_device_uuid"))
106     {
107         log_info("cl_khr_device_uuid not supported. Skipping test...\n");
108         return 0;
109     }
110 
111     int total_errors = 0;
112 
113     /* CL_DEVICE_UUID_KHR */
114     uuid device_uuid;
115     bool success = get_uuid(deviceID, CL_DEVICE_UUID_KHR, device_uuid);
116     if (!success)
117     {
118         log_error("Error getting device UUID\n");
119         ++total_errors;
120     }
121     else
122     {
123         log_info("\tDevice UUID: ");
124         log_info_uuid(device_uuid);
125         log_info("\n");
126     }
127 
128     /* CL_DRIVER_UUID_KHR */
129     uuid driver_uuid;
130     success = get_uuid(deviceID, CL_DRIVER_UUID_KHR, driver_uuid);
131     if (!success)
132     {
133         log_error("Error getting driver UUID\n");
134         ++total_errors;
135     }
136     else
137     {
138         log_info("\tDriver UUID: ");
139         log_info_uuid(driver_uuid);
140         log_info("\n");
141     }
142 
143     size_t size_ret{};
144 
145     /* CL_DEVICE_LUID_VALID_KHR */
146     cl_bool device_luid_valid{};
147     cl_int err = clGetDeviceInfo(deviceID, CL_DEVICE_LUID_VALID_KHR,
148                                  sizeof(device_luid_valid), &device_luid_valid,
149                                  &size_ret);
150     if (!check_device_info_returns(err, size_ret, sizeof(device_luid_valid)))
151     {
152         log_error("Error getting device LUID validity\n");
153         ++total_errors;
154         device_luid_valid = false;
155     }
156     else
157     {
158         log_info("\tDevice LUID validity is %s\n",
159                  device_luid_valid ? "true" : "false");
160     }
161 
162     /* CL_DEVICE_LUID_KHR */
163     luid device_luid;
164     success =
165         get_uuid(deviceID, CL_DEVICE_LUID_KHR, device_luid, device_luid_valid);
166     if (!success)
167     {
168         log_error("Error getting device LUID\n");
169         ++total_errors;
170     }
171     else
172     {
173         log_info("\tDevice LUID: ");
174         log_info_uuid(device_luid);
175         log_info("\n");
176     }
177 
178     /* CL_DEVICE_NODE_MASK_KHR */
179     cl_uint device_node_mask{};
180     err =
181         clGetDeviceInfo(deviceID, CL_DEVICE_NODE_MASK_KHR,
182                         sizeof(device_node_mask), &device_node_mask, &size_ret);
183     if (!check_device_info_returns(err, size_ret, sizeof(device_node_mask)))
184     {
185         log_error("Error getting device node mask\n");
186         ++total_errors;
187     }
188     else
189     {
190         log_info("\tNode mask  : %08lx\n",
191                  static_cast<unsigned long>(device_node_mask));
192 
193         /* If the LUID is valid, there must be one and only one bit set in the
194          * node mask */
195         if (device_luid_valid)
196         {
197             static constexpr size_t cl_uint_size_in_bits = 32;
198             const size_t bit_count =
199                 std::bitset<cl_uint_size_in_bits>(device_node_mask).count();
200             if (1 != bit_count)
201             {
202                 log_error("Wrong amount of bits set in node mask (%zu != 1) "
203                           "with valid LUID\n",
204                           bit_count);
205                 ++total_errors;
206             }
207         }
208     }
209 
210     return total_errors;
211 }
212