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_check_mem_host_write_only__h
17 #define test_conformance_check_mem_host_write_only__h
18
19 #include "checker.h"
20
21 template <class T>
22 class cBuffer_check_mem_host_write_only : public cBuffer_checker<T> {
23 public:
cBuffer_check_mem_host_write_only(cl_device_id deviceID,cl_context context,cl_command_queue queue)24 cBuffer_check_mem_host_write_only(cl_device_id deviceID, cl_context context,
25 cl_command_queue queue)
26 : cBuffer_checker<T>(deviceID, context, queue)
27 {
28 this->m_nNumber_elements = 1000;
29 };
30
~cBuffer_check_mem_host_write_only()31 ~cBuffer_check_mem_host_write_only(){};
32
33 cl_program program;
34 cl_kernel kernel;
35
36 clMemWrapper m_buffer2;
37
38 cl_int Setup_Test_Environment();
39
40 cl_int SetupBuffer();
41 cl_int SetupASSubBuffer(cl_mem_flags flag_p);
42
43 cl_int verifyData(cl_int err, cl_event &event);
44 cl_int update_host_mem_2();
45
46 cl_int verify_RW_Buffer();
47 cl_int verify_RW_Buffer_rect();
48 cl_int verify_RW_Buffer_mapping();
49
50 C_host_memory_block<T> tmp_host_m;
51
52 virtual cl_int verify_Buffer_initialization();
53 };
54
SetupBuffer()55 template <class T> cl_int cBuffer_check_mem_host_write_only<T>::SetupBuffer()
56 {
57 T vv1 = 0;
58 this->host_m_1.Init(this->m_nNumber_elements, vv1); // zero out buffer
59
60 // init buffer to 0
61 cl_int err;
62 int block_size_in_byte = this->get_block_size_bytes();
63
64 this->m_buffer =
65 clCreateBuffer(this->m_context, this->buffer_mem_flag,
66 block_size_in_byte, this->host_m_1.pData, &err);
67 test_error(err, "clCreateBuffer error");
68
69 err = this->Check_GetMemObjectInfo(this->buffer_mem_flag);
70
71 if (this->buffer_mem_flag | CL_MEM_USE_HOST_PTR)
72 {
73 this->pHost_ptr = (void *)this->host_m_1.pData;
74 }
75
76 return err;
77 }
78
79 template <class T>
80 cl_int
SetupASSubBuffer(cl_mem_flags flag_p)81 cBuffer_check_mem_host_write_only<T>::SetupASSubBuffer(cl_mem_flags flag_p)
82 {
83 return cBuffer_checker<T>::SetupASSubBuffer(flag_p);
84 }
85
86 template <class T>
Setup_Test_Environment()87 cl_int cBuffer_check_mem_host_write_only<T>::Setup_Test_Environment()
88 {
89 cl_int err;
90 T vv2 = 0;
91 this->host_m_2.Init(this->m_nNumber_elements, vv2);
92
93 // init buffer2 to 0
94 cl_mem_flags buffer_mem_flag2 =
95 CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR | CL_MEM_HOST_READ_ONLY;
96 this->m_buffer2 = clCreateBuffer(this->m_context, buffer_mem_flag2,
97 this->get_block_size_bytes(),
98 this->host_m_2.pData, &err);
99 test_error(err, "clCreateBuffer error\n");
100
101 return err;
102 }
103
104 template <class T>
verify_Buffer_initialization()105 cl_int cBuffer_check_mem_host_write_only<T>::verify_Buffer_initialization()
106 {
107 cl_int err = CL_SUCCESS;
108
109 if (this->host_m_1.pData == NULL || this->host_m_2.pData == NULL)
110 {
111 log_error("Data not ready\n");
112 return FAILURE;
113 }
114
115 update_host_mem_2();
116
117 if (!this->host_m_1.Equal(this->host_m_2))
118 {
119 log_error("Buffer content difference found\n");
120 return FAILURE;
121 }
122
123 return err;
124 }
125
126 template <class T>
verify_RW_Buffer()127 cl_int cBuffer_check_mem_host_write_only<T>::verify_RW_Buffer()
128 {
129 T vv1 = TEST_VALUE;
130 T vv2 = 0;
131 this->host_m_2.Set_to(vv2);
132
133 tmp_host_m.Init(this->host_m_1.num_elements, vv1);
134
135 cl_event event;
136 cl_int err = CL_SUCCESS;
137 err = clEnqueueWriteBuffer(this->m_queue, this->m_buffer, this->m_blocking,
138 0, this->get_block_size_bytes(),
139 tmp_host_m.pData, 0, NULL, &event);
140 if (err != CL_SUCCESS)
141 {
142 test_error(err, "clEnqueueWriteBuffer error");
143 }
144
145 if (!this->m_blocking)
146 {
147 err = clWaitForEvents(1, &event);
148 test_error(err, "clWaitForEvents error")
149 }
150
151 err = clReleaseEvent(event);
152 test_error(err, "clReleaseEvent error");
153
154 if (tmp_host_m.Equal(this->host_m_2))
155 {
156 log_error("Test data should be different\n");
157 return FAILURE;
158 }
159
160 update_host_mem_2();
161
162 if (!tmp_host_m.Equal(this->host_m_2))
163 {
164 log_error("Buffer content difference found\n");
165 return FAILURE;
166 }
167
168 err = clEnqueueReadBuffer(this->m_queue, this->m_buffer, CL_TRUE, 0,
169 this->get_block_size_bytes(),
170 this->host_m_2.pData, 0, NULL, &event);
171
172 if (err == CL_SUCCESS)
173 {
174 log_error(
175 "Calling clEnqueueReadBuffer on a memory object created with the "
176 "CL_MEM_HOST_WRITE_ONLY flag should not return CL_SUCCESS\n");
177 err = FAILURE;
178 return FAILURE;
179 }
180 else
181 {
182 log_info("Test succeeded\n\n");
183 err = CL_SUCCESS;
184 }
185
186 return err;
187 }
188
189 template <class T>
verify_RW_Buffer_rect()190 cl_int cBuffer_check_mem_host_write_only<T>::verify_RW_Buffer_rect()
191 {
192 this->Init_rect();
193
194 T vv1 = TEST_VALUE;
195 this->host_m_1.Set_to(vv1);
196
197 T vv2 = 0;
198 this->host_m_2.Set_to(vv2);
199
200 cl_event event, event_1;
201
202 cl_int err = CL_SUCCESS;
203
204 vv1 = 0;
205 C_host_memory_block<T> tmp_host_m;
206 tmp_host_m.Init(this->host_m_1.num_elements, vv1); // zero out the buffer
207 err = clEnqueueWriteBuffer(this->m_queue, this->m_buffer, CL_TRUE, 0,
208 this->get_block_size_bytes(), tmp_host_m.pData,
209 0, NULL, &event_1);
210 test_error(err, "clEnqueueWriteBuffer error");
211
212 vv1 = TEST_VALUE;
213 tmp_host_m.Set_to(vv1);
214 err = clEnqueueWriteBufferRect(
215 this->m_queue, this->m_buffer, this->m_blocking,
216 this->buffer_origin_bytes, this->host_origin_bytes, this->region_bytes,
217 this->buffer_row_pitch_bytes, this->buffer_slice_pitch_bytes,
218 this->host_row_pitch_bytes, this->host_slice_pitch_bytes,
219 tmp_host_m.pData, 1, &event_1, &event);
220 test_error(err, "clEnqueueWriteBufferRect error");
221
222 if (!this->m_blocking)
223 {
224 err = clWaitForEvents(1, &event);
225 test_error(err, "clWaitForEvents error")
226 }
227
228 if (tmp_host_m.Equal(this->host_m_2))
229 {
230 log_error("Test data should be different\n");
231 return FAILURE;
232 }
233
234 err = clReleaseEvent(event_1);
235 test_error(err, "clReleaseEvent error");
236 err = clReleaseEvent(event);
237 test_error(err, "clReleaseEvent error");
238
239 update_host_mem_2();
240
241 size_t tot_in_reg = this->region[0] * this->region[1] * this->region[2];
242 if (!tmp_host_m.Equal_rect(this->host_m_2, this->host_origin, this->region,
243 this->host_row_pitch, this->host_slice_pitch))
244 {
245 log_error("Buffer rect content difference found\n");
246 return FAILURE;
247 }
248
249 if (this->host_m_2.Count(vv1) != tot_in_reg)
250 {
251 log_error("Buffer rect content difference found\n");
252 return FAILURE;
253 }
254
255 err = clEnqueueReadBufferRect(
256 this->m_queue, this->m_buffer, this->m_blocking,
257 this->buffer_origin_bytes, this->host_origin_bytes, this->region_bytes,
258 this->buffer_row_pitch_bytes, this->buffer_slice_pitch_bytes,
259 this->host_row_pitch_bytes, this->host_slice_pitch_bytes,
260 this->host_m_2.pData, 0, NULL, &event);
261
262 if (err == CL_SUCCESS)
263 {
264 log_error(
265 "Calling clEnqueueReadBufferRect on a memory object created with "
266 "the CL_MEM_HOST_WRITE_ONLY flag should not return CL_SUCCESS\n");
267 err = FAILURE;
268 return FAILURE;
269 }
270 else
271 {
272 log_info("Test succeeded\n\n");
273 err = CL_SUCCESS;
274 }
275
276 return err;
277 }
278
279 template <class T>
update_host_mem_2()280 cl_int cBuffer_check_mem_host_write_only<T>::update_host_mem_2()
281 {
282 cl_event event, event_2;
283 cl_int err = clEnqueueCopyBuffer(
284 this->m_queue, this->m_buffer, this->m_buffer2, 0, 0,
285 this->m_nNumber_elements * sizeof(T), 0, NULL, &event);
286 test_error(err, "clEnqueueCopyBuffer error");
287
288 this->host_m_2.Set_to_zero();
289 err = clEnqueueReadBuffer(this->m_queue, this->m_buffer2, CL_TRUE, 0,
290 this->get_block_size_bytes(),
291 this->host_m_2.pData, 1, &event, &event_2);
292 test_error(err, "clEnqueueReadBuffer error");
293
294 clWaitForEvents(1, &event_2);
295 test_error(err, "clWaitForEvents error");
296
297 err = clReleaseEvent(event_2);
298 test_error(err, "clReleaseEvent error");
299
300 err = clReleaseEvent(event);
301 test_error(err, "clReleaseEvent error");
302 return err;
303 }
304
305 template <class T>
verify_RW_Buffer_mapping()306 cl_int cBuffer_check_mem_host_write_only<T>::verify_RW_Buffer_mapping()
307 {
308 T vv2 = 0;
309 this->host_m_2.Set_to(vv2);
310
311 cl_event event;
312 cl_int err = CL_SUCCESS;
313
314 void *dataPtr;
315 int size = this->get_block_size_bytes();
316 dataPtr =
317 clEnqueueMapBuffer(this->m_queue, this->m_buffer, this->m_blocking,
318 CL_MAP_WRITE, 0, size, 0, NULL, &event, &err);
319 test_error(err, "clEnqueueMapBuffer error");
320
321 if (!this->m_blocking)
322 {
323 err = clWaitForEvents(1, &event);
324 test_error(err, "clWaitForEvents error");
325 }
326
327 err = clReleaseEvent(event);
328 test_error(err, "clReleaseEvent error");
329
330 update_host_mem_2();
331
332 if ((this->buffer_mem_flag & CL_MEM_USE_HOST_PTR)
333 && dataPtr != this->pHost_ptr)
334 {
335 log_error("Mapped host pointer difference found\n");
336 return FAILURE;
337 }
338
339 if (!this->host_m_2.Equal((T *)dataPtr, this->m_nNumber_elements))
340 {
341 log_error("Buffer content difference found\n");
342 return FAILURE;
343 }
344
345 err = clEnqueueUnmapMemObject(this->m_queue, this->m_buffer, dataPtr, 0,
346 nullptr, nullptr);
347 test_error(err, "clEnqueueUnmapMemObject error");
348
349 // test map read
350 clEnqueueMapBuffer(this->m_queue, this->m_buffer, this->m_blocking,
351 CL_MAP_READ, 0, this->get_block_size_bytes(), 0, NULL,
352 &event, &err);
353
354 if (err == CL_SUCCESS)
355 {
356 log_error("Calling clEnqueueMapBuffer (CL_MAP_READ) on a memory object "
357 "created with the MEM_HOST_WRITE_ONLY flag should not return "
358 "CL_SUCCESS\n");
359 err = FAILURE;
360 }
361 else
362 {
363 log_info("Test succeeded\n\n");
364 err = CL_SUCCESS;
365 }
366
367 return err;
368 }
369
370 #endif
371