xref: /aosp_15_r20/external/OpenCL-CTS/test_common/harness/typeWrappers.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 "typeWrappers.h"
17 #include "kernelHelpers.h"
18 #include "errorHelpers.h"
19 #include <stdlib.h>
20 #include "clImageHelper.h"
21 
22 #define ROUND_SIZE_UP(_size, _align)                                           \
23     (((size_t)(_size) + (size_t)(_align)-1) & -((size_t)(_align)))
24 
25 #if defined(__APPLE__)
26 #define kPageSize 4096
27 #include <sys/mman.h>
28 #include <stdlib.h>
29 #elif defined(__linux__)
30 #include <unistd.h>
31 #define kPageSize (getpagesize())
32 #endif
33 
clProtectedImage(cl_context context,cl_mem_flags mem_flags,const cl_image_format * fmt,size_t width,cl_int * errcode_ret)34 clProtectedImage::clProtectedImage(cl_context context, cl_mem_flags mem_flags,
35                                    const cl_image_format *fmt, size_t width,
36                                    cl_int *errcode_ret)
37 {
38     cl_int err = Create(context, mem_flags, fmt, width);
39     if (errcode_ret != NULL) *errcode_ret = err;
40 }
41 
Create(cl_context context,cl_mem_flags mem_flags,const cl_image_format * fmt,size_t width)42 cl_int clProtectedImage::Create(cl_context context, cl_mem_flags mem_flags,
43                                 const cl_image_format *fmt, size_t width)
44 {
45     cl_int error;
46 #if defined(__APPLE__)
47     int protect_pages = 1;
48     cl_device_id devices[16];
49     size_t number_of_devices;
50     error = clGetContextInfo(context, CL_CONTEXT_DEVICES, sizeof(devices),
51                              devices, &number_of_devices);
52     test_error(error, "clGetContextInfo for CL_CONTEXT_DEVICES failed");
53 
54     number_of_devices /= sizeof(cl_device_id);
55     for (int i = 0; i < (int)number_of_devices; i++)
56     {
57         cl_device_type type;
58         error = clGetDeviceInfo(devices[i], CL_DEVICE_TYPE, sizeof(type), &type,
59                                 NULL);
60         test_error(error, "clGetDeviceInfo for CL_DEVICE_TYPE failed");
61         if (type == CL_DEVICE_TYPE_GPU)
62         {
63             protect_pages = 0;
64             break;
65         }
66     }
67 
68     if (protect_pages)
69     {
70         size_t pixelBytes = get_pixel_bytes(fmt);
71         size_t rowBytes = ROUND_SIZE_UP(width * pixelBytes, kPageSize);
72         size_t rowStride = rowBytes + kPageSize;
73 
74         // create backing store
75         backingStoreSize = rowStride + 8 * rowStride;
76         backingStore = mmap(0, backingStoreSize, PROT_READ | PROT_WRITE,
77                             MAP_ANON | MAP_PRIVATE, 0, 0);
78 
79         // add guard pages
80         size_t row;
81         char *p = (char *)backingStore;
82         char *imagePtr = (char *)backingStore + 4 * rowStride;
83         for (row = 0; row < 4; row++)
84         {
85             mprotect(p, rowStride, PROT_NONE);
86             p += rowStride;
87         }
88         p += rowBytes;
89         mprotect(p, kPageSize, PROT_NONE);
90         p += rowStride;
91         p -= rowBytes;
92         for (row = 0; row < 4; row++)
93         {
94             mprotect(p, rowStride, PROT_NONE);
95             p += rowStride;
96         }
97 
98         if (getenv("CL_ALIGN_RIGHT"))
99         {
100             static int spewEnv = 1;
101             if (spewEnv)
102             {
103                 log_info("***CL_ALIGN_RIGHT is set. Aligning images at right "
104                          "edge of page\n");
105                 spewEnv = 0;
106             }
107             imagePtr += rowBytes - pixelBytes * width;
108         }
109 
110         image = create_image_1d(context, mem_flags | CL_MEM_USE_HOST_PTR, fmt,
111                                 width, rowStride, imagePtr, NULL, &error);
112     }
113     else
114     {
115         backingStore = NULL;
116         image = create_image_1d(context, mem_flags, fmt, width, 0, NULL, NULL,
117                                 &error);
118     }
119 #else
120 
121     backingStore = NULL;
122     image =
123         create_image_1d(context, mem_flags, fmt, width, 0, NULL, NULL, &error);
124 
125 #endif
126     return error;
127 }
128 
129 
clProtectedImage(cl_context context,cl_mem_flags mem_flags,const cl_image_format * fmt,size_t width,size_t height,cl_int * errcode_ret)130 clProtectedImage::clProtectedImage(cl_context context, cl_mem_flags mem_flags,
131                                    const cl_image_format *fmt, size_t width,
132                                    size_t height, cl_int *errcode_ret)
133 {
134     cl_int err = Create(context, mem_flags, fmt, width, height);
135     if (errcode_ret != NULL) *errcode_ret = err;
136 }
137 
Create(cl_context context,cl_mem_flags mem_flags,const cl_image_format * fmt,size_t width,size_t height)138 cl_int clProtectedImage::Create(cl_context context, cl_mem_flags mem_flags,
139                                 const cl_image_format *fmt, size_t width,
140                                 size_t height)
141 {
142     cl_int error;
143 #if defined(__APPLE__)
144     int protect_pages = 1;
145     cl_device_id devices[16];
146     size_t number_of_devices;
147     error = clGetContextInfo(context, CL_CONTEXT_DEVICES, sizeof(devices),
148                              devices, &number_of_devices);
149     test_error(error, "clGetContextInfo for CL_CONTEXT_DEVICES failed");
150 
151     number_of_devices /= sizeof(cl_device_id);
152     for (int i = 0; i < (int)number_of_devices; i++)
153     {
154         cl_device_type type;
155         error = clGetDeviceInfo(devices[i], CL_DEVICE_TYPE, sizeof(type), &type,
156                                 NULL);
157         test_error(error, "clGetDeviceInfo for CL_DEVICE_TYPE failed");
158         if (type == CL_DEVICE_TYPE_GPU)
159         {
160             protect_pages = 0;
161             break;
162         }
163     }
164 
165     if (protect_pages)
166     {
167         size_t pixelBytes = get_pixel_bytes(fmt);
168         size_t rowBytes = ROUND_SIZE_UP(width * pixelBytes, kPageSize);
169         size_t rowStride = rowBytes + kPageSize;
170 
171         // create backing store
172         backingStoreSize = height * rowStride + 8 * rowStride;
173         backingStore = mmap(0, backingStoreSize, PROT_READ | PROT_WRITE,
174                             MAP_ANON | MAP_PRIVATE, 0, 0);
175 
176         // add guard pages
177         size_t row;
178         char *p = (char *)backingStore;
179         char *imagePtr = (char *)backingStore + 4 * rowStride;
180         for (row = 0; row < 4; row++)
181         {
182             mprotect(p, rowStride, PROT_NONE);
183             p += rowStride;
184         }
185         p += rowBytes;
186         for (row = 0; row < height; row++)
187         {
188             mprotect(p, kPageSize, PROT_NONE);
189             p += rowStride;
190         }
191         p -= rowBytes;
192         for (row = 0; row < 4; row++)
193         {
194             mprotect(p, rowStride, PROT_NONE);
195             p += rowStride;
196         }
197 
198         if (getenv("CL_ALIGN_RIGHT"))
199         {
200             static int spewEnv = 1;
201             if (spewEnv)
202             {
203                 log_info("***CL_ALIGN_RIGHT is set. Aligning images at right "
204                          "edge of page\n");
205                 spewEnv = 0;
206             }
207             imagePtr += rowBytes - pixelBytes * width;
208         }
209 
210         image = create_image_2d(context, mem_flags | CL_MEM_USE_HOST_PTR, fmt,
211                                 width, height, rowStride, imagePtr, &error);
212     }
213     else
214     {
215         backingStore = NULL;
216         image = create_image_2d(context, mem_flags, fmt, width, height, 0, NULL,
217                                 &error);
218     }
219 #else
220 
221     backingStore = NULL;
222     image = create_image_2d(context, mem_flags, fmt, width, height, 0, NULL,
223                             &error);
224 
225 #endif
226     return error;
227 }
228 
clProtectedImage(cl_context context,cl_mem_flags mem_flags,const cl_image_format * fmt,size_t width,size_t height,size_t depth,cl_int * errcode_ret)229 clProtectedImage::clProtectedImage(cl_context context, cl_mem_flags mem_flags,
230                                    const cl_image_format *fmt, size_t width,
231                                    size_t height, size_t depth,
232                                    cl_int *errcode_ret)
233 {
234     cl_int err = Create(context, mem_flags, fmt, width, height, depth);
235     if (errcode_ret != NULL) *errcode_ret = err;
236 }
237 
Create(cl_context context,cl_mem_flags mem_flags,const cl_image_format * fmt,size_t width,size_t height,size_t depth)238 cl_int clProtectedImage::Create(cl_context context, cl_mem_flags mem_flags,
239                                 const cl_image_format *fmt, size_t width,
240                                 size_t height, size_t depth)
241 {
242     cl_int error;
243 
244 #if defined(__APPLE__)
245     int protect_pages = 1;
246     cl_device_id devices[16];
247     size_t number_of_devices;
248     error = clGetContextInfo(context, CL_CONTEXT_DEVICES, sizeof(devices),
249                              devices, &number_of_devices);
250     test_error(error, "clGetContextInfo for CL_CONTEXT_DEVICES failed");
251 
252     number_of_devices /= sizeof(cl_device_id);
253     for (int i = 0; i < (int)number_of_devices; i++)
254     {
255         cl_device_type type;
256         error = clGetDeviceInfo(devices[i], CL_DEVICE_TYPE, sizeof(type), &type,
257                                 NULL);
258         test_error(error, "clGetDeviceInfo for CL_DEVICE_TYPE failed");
259         if (type == CL_DEVICE_TYPE_GPU)
260         {
261             protect_pages = 0;
262             break;
263         }
264     }
265 
266     if (protect_pages)
267     {
268         size_t pixelBytes = get_pixel_bytes(fmt);
269         size_t rowBytes = ROUND_SIZE_UP(width * pixelBytes, kPageSize);
270         size_t rowStride = rowBytes + kPageSize;
271 
272         // create backing store
273         backingStoreSize = height * depth * rowStride + 8 * rowStride;
274         backingStore = mmap(0, backingStoreSize, PROT_READ | PROT_WRITE,
275                             MAP_ANON | MAP_PRIVATE, 0, 0);
276 
277         // add guard pages
278         size_t row;
279         char *p = (char *)backingStore;
280         char *imagePtr = (char *)backingStore + 4 * rowStride;
281         for (row = 0; row < 4; row++)
282         {
283             mprotect(p, rowStride, PROT_NONE);
284             p += rowStride;
285         }
286         p += rowBytes;
287         for (row = 0; row < height * depth; row++)
288         {
289             mprotect(p, kPageSize, PROT_NONE);
290             p += rowStride;
291         }
292         p -= rowBytes;
293         for (row = 0; row < 4; row++)
294         {
295             mprotect(p, rowStride, PROT_NONE);
296             p += rowStride;
297         }
298 
299         if (getenv("CL_ALIGN_RIGHT"))
300         {
301             static int spewEnv = 1;
302             if (spewEnv)
303             {
304                 log_info("***CL_ALIGN_RIGHT is set. Aligning images at right "
305                          "edge of page\n");
306                 spewEnv = 0;
307             }
308             imagePtr += rowBytes - pixelBytes * width;
309         }
310 
311         image = create_image_3d(context, mem_flags | CL_MEM_USE_HOST_PTR, fmt,
312                                 width, height, depth, rowStride,
313                                 height * rowStride, imagePtr, &error);
314     }
315     else
316     {
317         backingStore = NULL;
318         image = create_image_3d(context, mem_flags, fmt, width, height, depth,
319                                 0, 0, NULL, &error);
320     }
321 #else
322 
323     backingStore = NULL;
324     image = create_image_3d(context, mem_flags, fmt, width, height, depth, 0, 0,
325                             NULL, &error);
326 
327 #endif
328 
329     return error;
330 }
331 
332 
clProtectedImage(cl_context context,cl_mem_object_type imageType,cl_mem_flags mem_flags,const cl_image_format * fmt,size_t width,size_t height,size_t depth,size_t arraySize,cl_int * errcode_ret)333 clProtectedImage::clProtectedImage(cl_context context,
334                                    cl_mem_object_type imageType,
335                                    cl_mem_flags mem_flags,
336                                    const cl_image_format *fmt, size_t width,
337                                    size_t height, size_t depth,
338                                    size_t arraySize, cl_int *errcode_ret)
339 {
340     cl_int err = Create(context, imageType, mem_flags, fmt, width, height,
341                         depth, arraySize);
342     if (errcode_ret != NULL) *errcode_ret = err;
343 }
344 
Create(cl_context context,cl_mem_object_type imageType,cl_mem_flags mem_flags,const cl_image_format * fmt,size_t width,size_t height,size_t depth,size_t arraySize)345 cl_int clProtectedImage::Create(cl_context context,
346                                 cl_mem_object_type imageType,
347                                 cl_mem_flags mem_flags,
348                                 const cl_image_format *fmt, size_t width,
349                                 size_t height, size_t depth, size_t arraySize)
350 {
351     cl_int error;
352 #if defined(__APPLE__)
353     int protect_pages = 1;
354     cl_device_id devices[16];
355     size_t number_of_devices;
356     error = clGetContextInfo(context, CL_CONTEXT_DEVICES, sizeof(devices),
357                              devices, &number_of_devices);
358     test_error(error, "clGetContextInfo for CL_CONTEXT_DEVICES failed");
359 
360     number_of_devices /= sizeof(cl_device_id);
361     for (int i = 0; i < (int)number_of_devices; i++)
362     {
363         cl_device_type type;
364         error = clGetDeviceInfo(devices[i], CL_DEVICE_TYPE, sizeof(type), &type,
365                                 NULL);
366         test_error(error, "clGetDeviceInfo for CL_DEVICE_TYPE failed");
367         if (type == CL_DEVICE_TYPE_GPU)
368         {
369             protect_pages = 0;
370             break;
371         }
372     }
373 
374     if (protect_pages)
375     {
376         size_t pixelBytes = get_pixel_bytes(fmt);
377         size_t rowBytes = ROUND_SIZE_UP(width * pixelBytes, kPageSize);
378         size_t rowStride = rowBytes + kPageSize;
379 
380         // create backing store
381         switch (imageType)
382         {
383             case CL_MEM_OBJECT_IMAGE1D:
384                 backingStoreSize = rowStride + 8 * rowStride;
385                 break;
386             case CL_MEM_OBJECT_IMAGE2D:
387                 backingStoreSize = height * rowStride + 8 * rowStride;
388                 break;
389             case CL_MEM_OBJECT_IMAGE3D:
390                 backingStoreSize = height * depth * rowStride + 8 * rowStride;
391                 break;
392             case CL_MEM_OBJECT_IMAGE1D_ARRAY:
393                 backingStoreSize = arraySize * rowStride + 8 * rowStride;
394                 break;
395             case CL_MEM_OBJECT_IMAGE2D_ARRAY:
396                 backingStoreSize =
397                     height * arraySize * rowStride + 8 * rowStride;
398                 break;
399         }
400         backingStore = mmap(0, backingStoreSize, PROT_READ | PROT_WRITE,
401                             MAP_ANON | MAP_PRIVATE, 0, 0);
402 
403         // add guard pages
404         size_t row;
405         char *p = (char *)backingStore;
406         char *imagePtr = (char *)backingStore + 4 * rowStride;
407         for (row = 0; row < 4; row++)
408         {
409             mprotect(p, rowStride, PROT_NONE);
410             p += rowStride;
411         }
412         p += rowBytes;
413         size_t sz = (height > 0 ? height : 1) * (depth > 0 ? depth : 1)
414             * (arraySize > 0 ? arraySize : 1);
415         for (row = 0; row < sz; row++)
416         {
417             mprotect(p, kPageSize, PROT_NONE);
418             p += rowStride;
419         }
420         p -= rowBytes;
421         for (row = 0; row < 4; row++)
422         {
423             mprotect(p, rowStride, PROT_NONE);
424             p += rowStride;
425         }
426 
427         if (getenv("CL_ALIGN_RIGHT"))
428         {
429             static int spewEnv = 1;
430             if (spewEnv)
431             {
432                 log_info("***CL_ALIGN_RIGHT is set. Aligning images at right "
433                          "edge of page\n");
434                 spewEnv = 0;
435             }
436             imagePtr += rowBytes - pixelBytes * width;
437         }
438 
439         switch (imageType)
440         {
441             case CL_MEM_OBJECT_IMAGE1D:
442                 image = create_image_1d(
443                     context, mem_flags | CL_MEM_USE_HOST_PTR, fmt, width,
444                     rowStride, imagePtr, NULL, &error);
445                 break;
446             case CL_MEM_OBJECT_IMAGE2D:
447                 image = create_image_2d(
448                     context, mem_flags | CL_MEM_USE_HOST_PTR, fmt, width,
449                     height, rowStride, imagePtr, &error);
450                 break;
451             case CL_MEM_OBJECT_IMAGE3D:
452                 image =
453                     create_image_3d(context, mem_flags | CL_MEM_USE_HOST_PTR,
454                                     fmt, width, height, depth, rowStride,
455                                     height * rowStride, imagePtr, &error);
456                 break;
457             case CL_MEM_OBJECT_IMAGE1D_ARRAY:
458                 image = create_image_1d_array(
459                     context, mem_flags | CL_MEM_USE_HOST_PTR, fmt, width,
460                     arraySize, rowStride, rowStride, imagePtr, &error);
461                 break;
462             case CL_MEM_OBJECT_IMAGE2D_ARRAY:
463                 image = create_image_2d_array(
464                     context, mem_flags | CL_MEM_USE_HOST_PTR, fmt, width,
465                     height, arraySize, rowStride, height * rowStride, imagePtr,
466                     &error);
467                 break;
468         }
469     }
470     else
471     {
472         backingStore = NULL;
473         switch (imageType)
474         {
475             case CL_MEM_OBJECT_IMAGE1D:
476                 image = create_image_1d(context, mem_flags, fmt, width, 0, NULL,
477                                         NULL, &error);
478                 break;
479             case CL_MEM_OBJECT_IMAGE2D:
480                 image = create_image_2d(context, mem_flags, fmt, width, height,
481                                         0, NULL, &error);
482                 break;
483             case CL_MEM_OBJECT_IMAGE3D:
484                 image = create_image_3d(context, mem_flags, fmt, width, height,
485                                         depth, 0, 0, NULL, &error);
486                 break;
487             case CL_MEM_OBJECT_IMAGE1D_ARRAY:
488                 image = create_image_1d_array(context, mem_flags, fmt, width,
489                                               arraySize, 0, 0, NULL, &error);
490                 break;
491             case CL_MEM_OBJECT_IMAGE2D_ARRAY:
492                 image = create_image_2d_array(context, mem_flags, fmt, width,
493                                               height, arraySize, 0, 0, NULL,
494                                               &error);
495                 break;
496         }
497     }
498 #else
499 
500     backingStore = NULL;
501     switch (imageType)
502     {
503         case CL_MEM_OBJECT_IMAGE1D:
504             image = create_image_1d(context, mem_flags, fmt, width, 0, NULL,
505                                     NULL, &error);
506             break;
507         case CL_MEM_OBJECT_IMAGE2D:
508             image = create_image_2d(context, mem_flags, fmt, width, height, 0,
509                                     NULL, &error);
510             break;
511         case CL_MEM_OBJECT_IMAGE3D:
512             image = create_image_3d(context, mem_flags, fmt, width, height,
513                                     depth, 0, 0, NULL, &error);
514             break;
515         case CL_MEM_OBJECT_IMAGE1D_ARRAY:
516             image = create_image_1d_array(context, mem_flags, fmt, width,
517                                           arraySize, 0, 0, NULL, &error);
518             break;
519         case CL_MEM_OBJECT_IMAGE2D_ARRAY:
520             image =
521                 create_image_2d_array(context, mem_flags, fmt, width, height,
522                                       arraySize, 0, 0, NULL, &error);
523             break;
524     }
525 #endif
526     return error;
527 }
528 
529 
530 /*******
531  * clProtectedArray implementation
532  *******/
clProtectedArray()533 clProtectedArray::clProtectedArray() { mBuffer = mValidBuffer = NULL; }
534 
clProtectedArray(size_t sizeInBytes)535 clProtectedArray::clProtectedArray(size_t sizeInBytes)
536 {
537     mBuffer = mValidBuffer = NULL;
538     Allocate(sizeInBytes);
539 }
540 
~clProtectedArray()541 clProtectedArray::~clProtectedArray()
542 {
543     if (mBuffer != NULL)
544     {
545 #if defined(__APPLE__)
546         int error = munmap(mBuffer, mRealSize);
547         if (error) log_error("WARNING: munmap failed in clProtectedArray.\n");
548 #else
549         free(mBuffer);
550 #endif
551     }
552 }
553 
Allocate(size_t sizeInBytes)554 void clProtectedArray::Allocate(size_t sizeInBytes)
555 {
556 
557 #if defined(__APPLE__)
558 
559     // Allocate enough space to: round up our actual allocation to an even
560     // number of pages and allocate two pages on either side
561     mRoundedSize = ROUND_SIZE_UP(sizeInBytes, kPageSize);
562     mRealSize = mRoundedSize + kPageSize * 2;
563 
564     // Use mmap here to ensure we start on a page boundary, so the mprotect
565     // calls will work OK
566     mBuffer = (char *)mmap(0, mRealSize, PROT_READ | PROT_WRITE,
567                            MAP_ANON | MAP_PRIVATE, 0, 0);
568 
569     mValidBuffer = mBuffer + kPageSize;
570 
571     // Protect guard area from access
572     mprotect(mValidBuffer - kPageSize, kPageSize, PROT_NONE);
573     mprotect(mValidBuffer + mRoundedSize, kPageSize, PROT_NONE);
574 #else
575     mRoundedSize = mRealSize = sizeInBytes;
576     mBuffer = mValidBuffer = (char *)calloc(1, mRealSize);
577 #endif
578 }
579