xref: /aosp_15_r20/external/OpenCL-CTS/test_conformance/subgroups/test_queries.cpp (revision 6467f958c7de8070b317fc65bcb0f6472e388d82)
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 "procs.h"
17 #include "subhelpers.h"
18 
19 typedef struct
20 {
21     cl_uint maxSubGroupSize;
22     cl_uint numSubGroups;
23 } result_data;
24 
25 
test_sub_group_info(cl_device_id device,cl_context context,cl_command_queue queue,int num_elements,bool useCoreSubgroups)26 int test_sub_group_info(cl_device_id device, cl_context context,
27                         cl_command_queue queue, int num_elements,
28                         bool useCoreSubgroups)
29 {
30     static const size_t gsize0 = 80;
31     int i, error;
32     size_t realSize;
33     size_t kernel_max_subgroup_size, kernel_subgroup_count;
34     size_t global[] = { gsize0, 14, 10 };
35     size_t local[] = { 0, 0, 0 };
36     result_data result[gsize0];
37 
38     cl_uint max_dimensions;
39 
40     error = clGetDeviceInfo(device, CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS,
41                             sizeof(max_dimensions), &max_dimensions, NULL);
42     test_error(error,
43                "clGetDeviceInfo failed for CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS");
44 
45     cl_platform_id platform;
46     clProgramWrapper program;
47     clKernelWrapper kernel;
48     clMemWrapper out;
49     std::stringstream kernel_sstr;
50     if (useCoreSubgroups)
51     {
52         kernel_sstr << "#pragma OPENCL EXTENSION cl_khr_subgroups : enable\n";
53     }
54     kernel_sstr
55         << "\n"
56            "typedef struct {\n"
57            "    uint maxSubGroupSize;\n"
58            "    uint numSubGroups;\n"
59            "} result_data;\n"
60            "\n"
61            "__kernel void query_kernel( __global result_data *outData )\n"
62            "{\n"
63            "    int gid = get_global_id( 0 );\n"
64            "    outData[gid].maxSubGroupSize = get_max_sub_group_size();\n"
65            "    outData[gid].numSubGroups = get_num_sub_groups();\n"
66            "}";
67 
68     const std::string &kernel_str = kernel_sstr.str();
69     const char *kernel_src = kernel_str.c_str();
70     error = create_single_kernel_helper(context, &program, &kernel, 1,
71                                         &kernel_src, "query_kernel");
72     if (error != 0) return error;
73 
74     // Determine some local dimensions to use for the test.
75     if (max_dimensions == 1)
76     {
77         error = get_max_common_work_group_size(context, kernel, global[0],
78                                                &local[0]);
79         test_error(error, "get_max_common_work_group_size failed");
80     }
81     else if (max_dimensions == 2)
82     {
83         error =
84             get_max_common_2D_work_group_size(context, kernel, global, local);
85         test_error(error, "get_max_common_2D_work_group_size failed");
86     }
87     else
88     {
89         error =
90             get_max_common_3D_work_group_size(context, kernel, global, local);
91         test_error(error, "get_max_common_3D_work_group_size failed");
92     }
93 
94     error = clGetDeviceInfo(device, CL_DEVICE_PLATFORM, sizeof(platform),
95                             (void *)&platform, NULL);
96     test_error(error, "clDeviceInfo failed for CL_DEVICE_PLATFORM");
97 
98     subgroupsAPI subgroupsApiSet(platform, useCoreSubgroups);
99     clGetKernelSubGroupInfoKHR_fn clGetKernelSubGroupInfo_ptr =
100         subgroupsApiSet.clGetKernelSubGroupInfo_ptr();
101     if (clGetKernelSubGroupInfo_ptr == NULL)
102     {
103         log_error("ERROR: %s function not available\n",
104                   subgroupsApiSet.clGetKernelSubGroupInfo_name);
105         return TEST_FAIL;
106     }
107 
108     error = clGetKernelSubGroupInfo_ptr(
109         kernel, device, CL_KERNEL_MAX_SUB_GROUP_SIZE_FOR_NDRANGE, sizeof(local),
110         (void *)&local, sizeof(kernel_max_subgroup_size),
111         (void *)&kernel_max_subgroup_size, &realSize);
112     if (error != CL_SUCCESS)
113     {
114         log_error("ERROR: %s function error for "
115                   "CL_KERNEL_MAX_SUB_GROUP_SIZE_FOR_NDRANGE\n",
116                   subgroupsApiSet.clGetKernelSubGroupInfo_name);
117         return TEST_FAIL;
118     }
119     log_info(
120         "The CL_KERNEL_MAX_SUB_GROUP_SIZE_FOR_NDRANGE for the kernel is %d.\n",
121         (int)kernel_max_subgroup_size);
122     if (realSize != sizeof(kernel_max_subgroup_size))
123     {
124         log_error("ERROR: Returned size of max sub group size not valid! "
125                   "(Expected %d, got %d)\n",
126                   (int)sizeof(kernel_max_subgroup_size), (int)realSize);
127         return TEST_FAIL;
128     }
129     error = clGetKernelSubGroupInfo_ptr(
130         kernel, device, CL_KERNEL_SUB_GROUP_COUNT_FOR_NDRANGE, sizeof(local),
131         (void *)&local, sizeof(kernel_subgroup_count),
132         (void *)&kernel_subgroup_count, &realSize);
133     if (error != CL_SUCCESS)
134     {
135         log_error("ERROR: %s function error "
136                   "for CL_KERNEL_SUB_GROUP_COUNT_FOR_NDRANGE\n",
137                   subgroupsApiSet.clGetKernelSubGroupInfo_name);
138         return TEST_FAIL;
139     }
140     log_info(
141         "The CL_KERNEL_SUB_GROUP_COUNT_FOR_NDRANGE for the kernel is %d.\n",
142         (int)kernel_subgroup_count);
143 
144     if (realSize != sizeof(kernel_subgroup_count))
145     {
146         log_error("ERROR: Returned size of sub group count not valid! "
147                   "(Expected %d, got %d)\n",
148                   (int)sizeof(kernel_subgroup_count), (int)realSize);
149         return TEST_FAIL;
150     }
151 
152     // Verify that the kernel gets the same max_subgroup_size and subgroup_count
153     out = clCreateBuffer(context, CL_MEM_WRITE_ONLY, sizeof(result), NULL,
154                          &error);
155     test_error(error, "clCreateBuffer failed");
156 
157     error = clSetKernelArg(kernel, 0, sizeof(out), &out);
158     test_error(error, "clSetKernelArg failed");
159 
160     error = clEnqueueNDRangeKernel(queue, kernel, max_dimensions, NULL, global,
161                                    local, 0, NULL, NULL);
162     test_error(error, "clEnqueueNDRangeKernel failed");
163 
164     error = clEnqueueReadBuffer(queue, out, CL_FALSE, 0, sizeof(result),
165                                 &result, 0, NULL, NULL);
166     test_error(error, "clEnqueueReadBuffer failed");
167 
168     error = clFinish(queue);
169     test_error(error, "clFinish failed");
170 
171     for (i = 0; i < (int)gsize0; ++i)
172     {
173         if (result[i].maxSubGroupSize != (cl_uint)kernel_max_subgroup_size)
174         {
175             log_error("ERROR: get_max_subgroup_size() doesn't match result "
176                       "from clGetKernelSubGroupInfoKHR, %u vs %u\n",
177                       result[i].maxSubGroupSize,
178                       (cl_uint)kernel_max_subgroup_size);
179             return -1;
180         }
181         if (result[i].numSubGroups != (cl_uint)kernel_subgroup_count)
182         {
183             log_error("ERROR: get_num_sub_groups() doesn't match result from "
184                       "clGetKernelSubGroupInfoKHR, %u vs %u\n",
185                       result[i].numSubGroups, (cl_uint)kernel_subgroup_count);
186             return -1;
187         }
188     }
189 
190     return 0;
191 }
192 
test_sub_group_info_core(cl_device_id device,cl_context context,cl_command_queue queue,int num_elements)193 int test_sub_group_info_core(cl_device_id device, cl_context context,
194                              cl_command_queue queue, int num_elements)
195 {
196     return test_sub_group_info(device, context, queue, num_elements, true);
197 }
198 
test_sub_group_info_ext(cl_device_id device,cl_context context,cl_command_queue queue,int num_elements)199 int test_sub_group_info_ext(cl_device_id device, cl_context context,
200                             cl_command_queue queue, int num_elements)
201 {
202     bool hasExtension = is_extension_available(device, "cl_khr_subgroups");
203 
204     if (!hasExtension)
205     {
206         log_info(
207             "Device does not support 'cl_khr_subgroups'. Skipping the test.\n");
208         return TEST_SKIPPED_ITSELF;
209     }
210 
211     return test_sub_group_info(device, context, queue, num_elements, false);
212 }
213