xref: /aosp_15_r20/external/OpenCL-CTS/test_conformance/basic/test_enqueue_map.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 "harness/compat.h"
17 
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <sys/types.h>
22 #include <sys/stat.h>
23 
24 
25 #include "procs.h"
26 #include "harness/conversions.h"
27 #include "harness/typeWrappers.h"
28 
29 // clang-format off
30 const cl_mem_flags flag_set[] = {
31   CL_MEM_ALLOC_HOST_PTR,
32   CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
33   CL_MEM_USE_HOST_PTR,
34   CL_MEM_COPY_HOST_PTR,
35   0
36 };
37 
38 const char *flag_set_names[] = {
39   "CL_MEM_ALLOC_HOST_PTR",
40   "CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR",
41   "CL_MEM_USE_HOST_PTR",
42   "CL_MEM_COPY_HOST_PTR",
43   "0"
44 };
45 // clang-format on
46 
test_enqueue_map_buffer(cl_device_id deviceID,cl_context context,cl_command_queue queue,int num_elements)47 int test_enqueue_map_buffer(cl_device_id deviceID, cl_context context,
48                             cl_command_queue queue, int num_elements)
49 {
50     int error;
51     const size_t bufferSize = 256 * 256;
52     MTdataHolder d{ gRandomSeed };
53     BufferOwningPtr<cl_char> hostPtrData{ malloc(bufferSize) };
54     BufferOwningPtr<cl_char> referenceData{ malloc(bufferSize) };
55     BufferOwningPtr<cl_char> finalData{ malloc(bufferSize) };
56 
57     for (size_t src_flag_id = 0; src_flag_id < ARRAY_SIZE(flag_set);
58          src_flag_id++)
59     {
60         clMemWrapper memObject;
61         log_info("Testing with cl_mem_flags src: %s\n",
62                  flag_set_names[src_flag_id]);
63 
64         generate_random_data(kChar, (unsigned int)bufferSize, d, hostPtrData);
65         memcpy(referenceData, hostPtrData, bufferSize);
66 
67         void *hostPtr = nullptr;
68         cl_mem_flags flags = flag_set[src_flag_id];
69         bool hasHostPtr =
70             (flags & CL_MEM_USE_HOST_PTR) || (flags & CL_MEM_COPY_HOST_PTR);
71         if (hasHostPtr) hostPtr = hostPtrData;
72         memObject = clCreateBuffer(context, flags, bufferSize, hostPtr, &error);
73         test_error(error, "Unable to create testing buffer");
74 
75         if (!hasHostPtr)
76         {
77             error =
78                 clEnqueueWriteBuffer(queue, memObject, CL_TRUE, 0, bufferSize,
79                                      hostPtrData, 0, NULL, NULL);
80             test_error(error, "clEnqueueWriteBuffer failed");
81         }
82 
83         for (int i = 0; i < 128; i++)
84         {
85 
86             size_t offset = (size_t)random_in_range(0, (int)bufferSize - 1, d);
87             size_t length =
88                 (size_t)random_in_range(1, (int)(bufferSize - offset), d);
89 
90             cl_char *mappedRegion = (cl_char *)clEnqueueMapBuffer(
91                 queue, memObject, CL_TRUE, CL_MAP_READ | CL_MAP_WRITE, offset,
92                 length, 0, NULL, NULL, &error);
93             if (error != CL_SUCCESS)
94             {
95                 print_error(error, "clEnqueueMapBuffer call failed");
96                 log_error("\tOffset: %d  Length: %d\n", (int)offset,
97                           (int)length);
98                 return -1;
99             }
100 
101             // Write into the region
102             for (size_t j = 0; j < length; j++)
103             {
104                 cl_char spin = (cl_char)genrand_int32(d);
105 
106                 // Test read AND write in one swipe
107                 cl_char value = mappedRegion[j];
108                 value = spin - value;
109                 mappedRegion[j] = value;
110 
111                 // Also update the initial data array
112                 value = referenceData[offset + j];
113                 value = spin - value;
114                 referenceData[offset + j] = value;
115             }
116 
117             // Unmap
118             error = clEnqueueUnmapMemObject(queue, memObject, mappedRegion, 0,
119                                             NULL, NULL);
120             test_error(error, "Unable to unmap buffer");
121         }
122 
123         // Final validation: read actual values of buffer and compare against
124         // our reference
125         error = clEnqueueReadBuffer(queue, memObject, CL_TRUE, 0, bufferSize,
126                                     finalData, 0, NULL, NULL);
127         test_error(error, "Unable to read results");
128 
129         for (size_t q = 0; q < bufferSize; q++)
130         {
131             if (referenceData[q] != finalData[q])
132             {
133                 log_error(
134                     "ERROR: Sample %d did not validate! Got %d, expected %d\n",
135                     (int)q, (int)finalData[q], (int)referenceData[q]);
136                 return -1;
137             }
138         }
139     } // cl_mem flags
140 
141     return 0;
142 }
143 
test_enqueue_map_image(cl_device_id deviceID,cl_context context,cl_command_queue queue,int num_elements)144 int test_enqueue_map_image(cl_device_id deviceID, cl_context context,
145                            cl_command_queue queue, int num_elements)
146 {
147     int error;
148     cl_image_format format = { CL_RGBA, CL_UNSIGNED_INT32 };
149     const size_t imageSize = 256;
150     const size_t imageDataSize = imageSize * imageSize * 4 * sizeof(cl_uint);
151 
152     PASSIVE_REQUIRE_IMAGE_SUPPORT(deviceID)
153 
154     BufferOwningPtr<cl_uint> hostPtrData{ malloc(imageDataSize) };
155     BufferOwningPtr<cl_uint> referenceData{ malloc(imageDataSize) };
156     BufferOwningPtr<cl_uint> finalData{ malloc(imageDataSize) };
157 
158     MTdataHolder d{ gRandomSeed };
159     for (size_t src_flag_id = 0; src_flag_id < ARRAY_SIZE(flag_set);
160          src_flag_id++)
161     {
162         clMemWrapper memObject;
163         log_info("Testing with cl_mem_flags src: %s\n",
164                  flag_set_names[src_flag_id]);
165 
166         generate_random_data(kUInt, (unsigned int)(imageSize * imageSize * 4),
167                              d, hostPtrData);
168         memcpy(referenceData, hostPtrData, imageDataSize);
169 
170         cl_mem_flags flags = flag_set[src_flag_id];
171         bool hasHostPtr =
172             (flags & CL_MEM_USE_HOST_PTR) || (flags & CL_MEM_COPY_HOST_PTR);
173         void *hostPtr = nullptr;
174         if (hasHostPtr) hostPtr = hostPtrData;
175         memObject = create_image_2d(context, CL_MEM_READ_WRITE | flags, &format,
176                                     imageSize, imageSize, 0, hostPtr, &error);
177         test_error(error, "Unable to create testing buffer");
178 
179         if (!hasHostPtr)
180         {
181             size_t write_origin[3] = { 0, 0, 0 },
182                    write_region[3] = { imageSize, imageSize, 1 };
183             error = clEnqueueWriteImage(queue, memObject, CL_TRUE, write_origin,
184                                         write_region, 0, 0, hostPtrData, 0,
185                                         NULL, NULL);
186             test_error(error, "Unable to write to testing buffer");
187         }
188 
189         for (int i = 0; i < 128; i++)
190         {
191 
192             size_t offset[3], region[3];
193             size_t rowPitch;
194 
195             offset[0] = (size_t)random_in_range(0, (int)imageSize - 1, d);
196             region[0] =
197                 (size_t)random_in_range(1, (int)(imageSize - offset[0] - 1), d);
198             offset[1] = (size_t)random_in_range(0, (int)imageSize - 1, d);
199             region[1] =
200                 (size_t)random_in_range(1, (int)(imageSize - offset[1] - 1), d);
201             offset[2] = 0;
202             region[2] = 1;
203             cl_uint *mappedRegion = (cl_uint *)clEnqueueMapImage(
204                 queue, memObject, CL_TRUE, CL_MAP_READ | CL_MAP_WRITE, offset,
205                 region, &rowPitch, NULL, 0, NULL, NULL, &error);
206             if (error != CL_SUCCESS)
207             {
208                 print_error(error, "clEnqueueMapImage call failed");
209                 log_error("\tOffset: %d,%d  Region: %d,%d\n", (int)offset[0],
210                           (int)offset[1], (int)region[0], (int)region[1]);
211                 return -1;
212             }
213 
214             // Write into the region
215             cl_uint *mappedPtr = mappedRegion;
216             for (size_t y = 0; y < region[1]; y++)
217             {
218                 for (size_t x = 0; x < region[0] * 4; x++)
219                 {
220                     cl_int spin = (cl_int)random_in_range(16, 1024, d);
221 
222                     cl_int value;
223                     // Test read AND write in one swipe
224                     value = mappedPtr[(y * rowPitch / sizeof(cl_uint)) + x];
225                     value = spin - value;
226                     mappedPtr[(y * rowPitch / sizeof(cl_uint)) + x] = value;
227 
228                     // Also update the initial data array
229                     value =
230                         referenceData[((offset[1] + y) * imageSize + offset[0])
231                                           * 4
232                                       + x];
233                     value = spin - value;
234                     referenceData[((offset[1] + y) * imageSize + offset[0]) * 4
235                                   + x] = value;
236                 }
237             }
238 
239             // Unmap
240             error = clEnqueueUnmapMemObject(queue, memObject, mappedRegion, 0,
241                                             NULL, NULL);
242             test_error(error, "Unable to unmap buffer");
243         }
244 
245         // Final validation: read actual values of buffer and compare against
246         // our reference
247         size_t finalOrigin[3] = { 0, 0, 0 },
248                finalRegion[3] = { imageSize, imageSize, 1 };
249         error = clEnqueueReadImage(queue, memObject, CL_TRUE, finalOrigin,
250                                    finalRegion, 0, 0, finalData, 0, NULL, NULL);
251         test_error(error, "Unable to read results");
252 
253         for (size_t q = 0; q < imageSize * imageSize * 4; q++)
254         {
255             if (referenceData[q] != finalData[q])
256             {
257                 log_error(
258                     "ERROR: Sample %d (coord %d,%d) did not validate! Got "
259                     "%d, expected %d\n",
260                     (int)q, (int)((q / 4) % imageSize),
261                     (int)((q / 4) / imageSize), (int)finalData[q],
262                     (int)referenceData[q]);
263                 return -1;
264             }
265         }
266     } // cl_mem_flags
267 
268     return 0;
269 }
270