• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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