xref: /aosp_15_r20/external/OpenCL-CTS/test_conformance/mem_host_flags/checker.h (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 #ifndef test_conformance_checkers_h
17 #define test_conformance_checkers_h
18 
19 #include "harness/compat.h"
20 
21 #include <stdio.h>
22 #include <string.h>
23 
24 #include "procs.h"
25 #include "C_host_memory_block.h"
26 
27 #define TEST_VALUE 5
28 typedef cl_char TEST_ELEMENT_TYPE;
29 
30 enum
31 {
32     SUCCESS,
33     FAILURE = -1000
34 };
35 
36 extern const char *buffer_write_kernel_code[];
37 
38 enum BUFFER_TYPE
39 {
40     _BUFFER,
41     _Sub_BUFFER
42 };
43 
44 template <class T> class cBuffer_checker {
45 public:
46     cBuffer_checker(cl_device_id deviceID, cl_context context,
47                     cl_command_queue queue);
48     ~cBuffer_checker();
49 
50     cl_device_id m_deviceID;
51     cl_context m_context;
52     cl_command_queue m_queue;
53 
54     clMemWrapper m_buffer, m_buffer_parent;
55     enum BUFFER_TYPE m_buffer_type;
56 
57     cl_buffer_region m_sub_buffer_region;
58 
59     cl_int err;
60     cl_bool m_blocking;
61     cl_mem_flags buffer_mem_flag;
62 
63     C_host_memory_block<T> host_m_0, host_m_1, host_m_2;
64     int m_nNumber_elements;
65 
66     void *pData, *pData2;
67 
68     void *pHost_ptr; // the host ptr at creation
69 
70     size_t buffer_origin[3];
71     size_t host_origin[3];
72     size_t region[3];
73     size_t buffer_row_pitch;
74     size_t buffer_slice_pitch;
75     size_t host_row_pitch;
76     size_t host_slice_pitch;
77 
78     size_t buffer_origin_bytes[3];
79     size_t host_origin_bytes[3];
80     size_t region_bytes[3];
81     size_t buffer_row_pitch_bytes;
82     size_t buffer_slice_pitch_bytes;
83     size_t host_row_pitch_bytes;
84     size_t host_slice_pitch_bytes;
85 
86     cl_int CreateBuffer(cl_mem_flags buffer_mem_flag, void *pdata);
get_block_size_bytes()87     int get_block_size_bytes()
88     {
89         return (int)(m_nNumber_elements * sizeof(T));
90     };
91     virtual cl_int SetupBuffer() = 0;
92 
93     virtual cl_int Setup_Test_Environment();
94 
95     virtual cl_int SetupASSubBuffer(cl_mem_flags parent_buffer_flag);
96 
97     virtual cl_int verify(cl_int err, cl_event &event);
98 
99     virtual cl_int Check_GetMemObjectInfo(cl_mem_flags buffer_mem_flag);
100 
101     void Init_rect(int bufforg[3], int host_org[3], int region[3],
102                    int buffer_pitch[2], int host_pitch[2]);
103 
104     void Init_rect();
105 
106     virtual cl_int verify_RW_Buffer() = 0;
107     virtual cl_int verify_RW_Buffer_rect() = 0;
108     virtual cl_int verify_RW_Buffer_mapping() = 0;
109 };
110 
111 template <class T>
cBuffer_checker(cl_device_id deviceID,cl_context context,cl_command_queue queue)112 cBuffer_checker<T>::cBuffer_checker(cl_device_id deviceID, cl_context context,
113                                     cl_command_queue queue)
114 {
115     m_nNumber_elements = 0;
116 
117     m_deviceID = deviceID;
118     m_context = context;
119     m_queue = queue;
120 
121     m_blocking = false;
122 
123     buffer_mem_flag = CL_MEM_READ_WRITE;
124     pData = pData2 = NULL;
125 
126     buffer_origin[0] = buffer_origin[1] = buffer_origin[2] = 0;
127     host_origin[0] = host_origin[1] = host_origin[2] = 0;
128     region[0] = region[1] = region[2] = 0;
129     buffer_row_pitch = buffer_slice_pitch = host_row_pitch = host_slice_pitch =
130         0;
131 
132     buffer_origin_bytes[0] = buffer_origin_bytes[1] = buffer_origin_bytes[2] =
133         0;
134     host_origin_bytes[0] = host_origin_bytes[1] = host_origin_bytes[2] = 0;
135     region_bytes[0] = region_bytes[1] = region_bytes[2] = 0;
136     buffer_row_pitch_bytes = buffer_slice_pitch_bytes = 0;
137     host_row_pitch_bytes = host_slice_pitch_bytes = 0;
138 
139     pHost_ptr = NULL;
140 }
141 
~cBuffer_checker()142 template <class T> cBuffer_checker<T>::~cBuffer_checker() {}
143 
144 
SetupBuffer()145 template <class T> cl_int cBuffer_checker<T>::SetupBuffer()
146 {
147     m_buffer_type = _BUFFER;
148     return CL_SUCCESS;
149 }
150 
Setup_Test_Environment()151 template <class T> cl_int cBuffer_checker<T>::Setup_Test_Environment()
152 {
153     return CL_SUCCESS;
154 }
155 
156 template <class T>
SetupASSubBuffer(cl_mem_flags parent_buffer_flag)157 cl_int cBuffer_checker<T>::SetupASSubBuffer(cl_mem_flags parent_buffer_flag)
158 {
159     m_buffer_type = _Sub_BUFFER;
160 
161     int supersize = 8000;
162     this->m_nNumber_elements = 1000;
163     T vv1 = TEST_VALUE;
164 
165     int block_size_in_byte = (int)(supersize * sizeof(T));
166 
167     this->host_m_0.Init(supersize);
168 
169     m_buffer_parent =
170         clCreateBuffer(this->m_context, parent_buffer_flag, block_size_in_byte,
171                        this->host_m_0.pData, &err);
172     test_error(err, "clCreateBuffer error");
173 
174     int size = this->m_nNumber_elements; // the size of subbuffer in elements
175 
176     cl_uint base_addr_align_bits;
177     err = clGetDeviceInfo(m_deviceID, CL_DEVICE_MEM_BASE_ADDR_ALIGN,
178                           sizeof base_addr_align_bits, &base_addr_align_bits,
179                           NULL);
180     test_error(err, "clGetDeviceInfo for CL_DEVICE_MEM_BASE_ADDR_ALIGN");
181 
182     int base_addr_align_bytes = base_addr_align_bits / 8;
183 
184     int buffer_origin[3] = { base_addr_align_bytes, 0, 0 };
185     int host_origin[3] = { 0, 0, 0 };
186     int region[3] = { size, 1, 1 };
187     int buffer_pitch[2] = { 0, 0 };
188     int host_pitch[2] = { 0, 0 };
189     this->Init_rect(buffer_origin, host_origin, region, buffer_pitch,
190                     host_pitch);
191 
192     this->m_nNumber_elements = size; // the size of subbuffer in elements
193     this->host_m_1.Init(this->m_nNumber_elements, vv1);
194 
195     this->m_sub_buffer_region.origin = this->buffer_origin_bytes[0]; // in bytes
196     this->m_sub_buffer_region.size = this->region_bytes[0];
197 
198     cl_int err = CL_SUCCESS;
199     err = clEnqueueReadBufferRect(
200         this->m_queue, m_buffer_parent, CL_TRUE, this->buffer_origin_bytes,
201         this->host_origin_bytes, this->region_bytes,
202         this->buffer_row_pitch_bytes, this->buffer_slice_pitch_bytes,
203         this->host_row_pitch_bytes, this->host_slice_pitch_bytes,
204         this->host_m_1.pData, 0, NULL,
205         NULL); // update the mem_1
206 
207     if (err == CL_SUCCESS
208         && (parent_buffer_flag
209             & (CL_MEM_HOST_WRITE_ONLY | CL_MEM_HOST_NO_ACCESS)))
210     {
211         log_error("Calling clEnqueueReadBufferRect on a memory object created "
212                   "with the CL_MEM_HOST_WRITE_ONLY flag or the "
213                   "CL_MEM_HOST_NO_ACCESS flag should not return CL_SUCCESS\n");
214         err = FAILURE;
215         return err;
216     }
217     else
218     {
219         err = CL_SUCCESS;
220     }
221 
222     cl_mem_flags f = 0;
223     if (parent_buffer_flag & CL_MEM_HOST_READ_ONLY)
224         f = CL_MEM_HOST_READ_ONLY;
225     else if (parent_buffer_flag & CL_MEM_HOST_WRITE_ONLY)
226         f = CL_MEM_HOST_WRITE_ONLY;
227     else if (parent_buffer_flag & CL_MEM_HOST_NO_ACCESS)
228         f = CL_MEM_HOST_NO_ACCESS;
229 
230     m_buffer =
231         clCreateSubBuffer(m_buffer_parent, f, CL_BUFFER_CREATE_TYPE_REGION,
232                           &(this->m_sub_buffer_region), &err);
233     test_error(err, "clCreateSubBuffer error");
234 
235     if (parent_buffer_flag | CL_MEM_USE_HOST_PTR)
236     {
237         this->pHost_ptr = (this->host_m_0.pData
238                            + this->m_sub_buffer_region.origin / sizeof(T));
239     }
240 
241     T vv2 = 0;
242     this->host_m_2.Init(this->m_nNumber_elements, vv2);
243 
244     return err;
245 }
246 
247 template <class T>
verify(cl_int err,cl_event & event)248 cl_int cBuffer_checker<T>::verify(cl_int err, cl_event &event)
249 {
250     return CL_SUCCESS;
251 }
252 
253 template <class T>
CreateBuffer(cl_mem_flags buffer_mem_flag,void * pdata)254 cl_int cBuffer_checker<T>::CreateBuffer(cl_mem_flags buffer_mem_flag,
255                                         void *pdata)
256 {
257     cl_int err = CL_SUCCESS;
258     int block_size_in_byte = m_nNumber_elements * sizeof(T);
259 
260     m_buffer = clCreateBuffer(m_context, buffer_mem_flag, block_size_in_byte,
261                               pdata, &err);
262 
263     return err;
264 };
265 
266 template <class T>
Check_GetMemObjectInfo(cl_mem_flags buffer_mem_flag)267 cl_int cBuffer_checker<T>::Check_GetMemObjectInfo(cl_mem_flags buffer_mem_flag)
268 {
269     cl_int err = CL_SUCCESS;
270     cl_mem_flags buffer_mem_flag_Check;
271     err = clGetMemObjectInfo(this->m_buffer, CL_MEM_FLAGS, sizeof(cl_mem_flags),
272                              &buffer_mem_flag_Check, NULL);
273 
274     if (buffer_mem_flag_Check != buffer_mem_flag)
275     {
276         log_error(
277             "clGetMemObjectInfo result differs from the specified result\n");
278         return err;
279     }
280 
281     cl_uint count = 0;
282     err = clGetMemObjectInfo(this->m_buffer, CL_MEM_REFERENCE_COUNT,
283                              sizeof(cl_uint), &count, NULL);
284 
285     if (count > 1) log_info("========= buffer count %d\n", count);
286 
287     test_error(err, "clGetMemObjectInfo failed");
288 
289     return err;
290 }
291 
Init_rect()292 template <class T> void cBuffer_checker<T>::Init_rect()
293 {
294     int buffer_origin[3] = { 10, 0, 0 };
295     int host_origin[3] = { 10, 0, 0 };
296     int region[3] = { 8, 1, 1 };
297     int buffer_pitch[2] = { 0, 0 };
298     int host_pitch[2] = { 0, 0 };
299 
300     this->Init_rect(buffer_origin, host_origin, region, buffer_pitch,
301                     host_pitch);
302 }
303 
304 template <class T>
Init_rect(int bufforg[3],int host_org[3],int region_in[3],int buffer_pitch[2],int host_pitch[2])305 void cBuffer_checker<T>::Init_rect(int bufforg[3], int host_org[3],
306                                    int region_in[3], int buffer_pitch[2],
307                                    int host_pitch[2])
308 {
309     buffer_origin[0] = bufforg[0];
310     buffer_origin[1] = bufforg[1];
311     buffer_origin[2] = bufforg[2];
312 
313     host_origin[0] = host_org[0];
314     host_origin[1] = host_org[1];
315     host_origin[2] = host_org[2];
316 
317     region[0] = region_in[0];
318     region[1] = region_in[1];
319     region[2] = region_in[2];
320 
321     buffer_row_pitch = buffer_pitch[0];
322     buffer_slice_pitch = buffer_pitch[1];
323     host_row_pitch = host_pitch[0];
324     host_slice_pitch = host_pitch[1];
325 
326     int sizeof_element = sizeof(T);
327     for (int k = 0; k < 3; k++)
328     {
329         buffer_origin_bytes[k] = buffer_origin[k] * sizeof_element;
330         host_origin_bytes[k] = host_origin[k] * sizeof_element;
331     }
332 
333     region_bytes[0] = region[0] * sizeof_element;
334     region_bytes[1] = region[1];
335     region_bytes[2] = region[2];
336     buffer_row_pitch_bytes = buffer_row_pitch * sizeof_element;
337     buffer_slice_pitch_bytes = buffer_slice_pitch * sizeof_element;
338     host_row_pitch_bytes = host_row_pitch * sizeof_element;
339     host_slice_pitch_bytes = host_slice_pitch * sizeof_element;
340 }
341 
342 #endif
343