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