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