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 #include "allocation_fill.h"
17
18 #define BUFFER_CHUNK_SIZE 8*1024*1024
19 #define IMAGE_LINES 8
20
21 #include "harness/compat.h"
22
fill_buffer_with_data(cl_context context,cl_device_id device_id,cl_command_queue * queue,cl_mem mem,size_t size,MTdata d,cl_bool blocking_write)23 int fill_buffer_with_data(cl_context context, cl_device_id device_id, cl_command_queue *queue, cl_mem mem, size_t size, MTdata d, cl_bool blocking_write) {
24 size_t i, j;
25 cl_uint *data;
26 int error, result;
27 cl_uint checksum_delta = 0;
28 cl_event event;
29
30 size_t size_to_use = BUFFER_CHUNK_SIZE;
31 if (size_to_use > size)
32 size_to_use = size;
33
34 data = (cl_uint*)malloc(size_to_use);
35 if (data == NULL) {
36 log_error("Failed to malloc host buffer for writing into buffer.\n");
37 return FAILED_ABORT;
38 }
39 for (i=0; i<size-size_to_use; i+=size_to_use) {
40 // Put values in the data, and keep a checksum as we go along.
41 for (j=0; j<size_to_use/sizeof(cl_uint); j++) {
42 data[j] = genrand_int32(d);
43 checksum_delta += data[j];
44 }
45 if (blocking_write) {
46 error = clEnqueueWriteBuffer(*queue, mem, CL_TRUE, i, size_to_use, data, 0, NULL, NULL);
47 result = check_allocation_error(context, device_id, error, queue);
48
49 if (result == FAILED_ABORT) {
50 print_error(error, "clEnqueueWriteBuffer failed.");
51 }
52
53 if (result != SUCCEEDED) {
54 clFinish(*queue);
55 free(data);
56 clReleaseMemObject(mem);
57 return result;
58 }
59 } else {
60 error = clEnqueueWriteBuffer(*queue, mem, CL_FALSE, i, size_to_use, data, 0, NULL, &event);
61 result = check_allocation_error(context, device_id, error, queue);
62
63 if (result == FAILED_ABORT) {
64 print_error(error, "clEnqueueWriteBuffer failed.");
65 }
66
67 if (result != SUCCEEDED) {
68 clFinish(*queue);
69 free(data);
70 clReleaseMemObject(mem);
71 return result;
72 }
73
74 error = clWaitForEvents(1, &event);
75 result = check_allocation_error(context, device_id, error, queue, &event);
76
77 if (result == FAILED_ABORT) {
78 print_error(error, "clWaitForEvents failed.");
79 }
80
81 if (result != SUCCEEDED) {
82 clFinish(*queue);
83 clReleaseEvent(event);
84 free(data);
85 clReleaseMemObject(mem);
86 return result;
87 }
88
89 clReleaseEvent(event);
90 }
91 }
92
93 // Deal with any leftover bits
94 if (i < size) {
95 // Put values in the data, and keep a checksum as we go along.
96 for (j=0; j<(size-i)/sizeof(cl_uint); j++) {
97 data[j] = (cl_uint)genrand_int32(d);
98 checksum_delta += data[j];
99 }
100
101 if (blocking_write) {
102 error = clEnqueueWriteBuffer(*queue, mem, CL_TRUE, i, size-i, data, 0, NULL, NULL);
103 result = check_allocation_error(context, device_id, error, queue);
104
105 if (result == FAILED_ABORT) {
106 print_error(error, "clEnqueueWriteBuffer failed.");
107 }
108
109 if (result != SUCCEEDED) {
110 clFinish(*queue);
111 clReleaseMemObject(mem);
112 free(data);
113 return result;
114 }
115 } else {
116 error = clEnqueueWriteBuffer(*queue, mem, CL_FALSE, i, size-i, data, 0, NULL, &event);
117 result = check_allocation_error(context, device_id, error, queue);
118
119 if (result == FAILED_ABORT) {
120 print_error(error, "clEnqueueWriteBuffer failed.");
121 }
122
123 if (result != SUCCEEDED) {
124 clFinish(*queue);
125 clReleaseMemObject(mem);
126 free(data);
127 return result;
128 }
129
130 error = clWaitForEvents(1, &event);
131 result = check_allocation_error(context, device_id, error, queue, &event);
132
133 if (result == FAILED_ABORT) {
134 print_error(error, "clWaitForEvents failed.");
135 }
136
137 if (result != SUCCEEDED) {
138 clFinish(*queue);
139 clReleaseEvent(event);
140 free(data);
141 clReleaseMemObject(mem);
142 return result;
143 }
144
145 clReleaseEvent(event);
146 }
147 }
148
149 free(data);
150 // Only update the checksum if this succeeded.
151 checksum += checksum_delta;
152 return SUCCEEDED;
153 }
154
155
fill_image_with_data(cl_context context,cl_device_id device_id,cl_command_queue * queue,cl_mem mem,size_t width,size_t height,MTdata d,cl_bool blocking_write)156 int fill_image_with_data(cl_context context, cl_device_id device_id, cl_command_queue *queue, cl_mem mem, size_t width, size_t height, MTdata d, cl_bool blocking_write) {
157 size_t origin[3], region[3], j;
158 int error, result;
159 cl_uint *data;
160 cl_uint checksum_delta = 0;
161 cl_event event;
162
163 size_t image_lines_to_use;
164 image_lines_to_use = IMAGE_LINES;
165 if (image_lines_to_use > height)
166 image_lines_to_use = height;
167
168 data = (cl_uint*)malloc(width*4*sizeof(cl_uint)*image_lines_to_use);
169 if (data == NULL) {
170 log_error("Failed to malloc host buffer for writing into image.\n");
171 return FAILED_ABORT;
172 }
173 origin[0] = 0;
174 origin[1] = 0;
175 origin[2] = 0;
176 region[0] = width;
177 region[1] = image_lines_to_use;
178 region[2] = 1;
179 for (origin[1] = 0; origin[1] < height - image_lines_to_use; origin[1] += image_lines_to_use) {
180 // Put values in the data, and keep a checksum as we go along.
181 for (j=0; j<width*4*image_lines_to_use; j++) {
182 data[j] = (cl_uint)genrand_int32(d);
183 checksum_delta += data[j];
184 }
185
186 if (blocking_write) {
187 error = clEnqueueWriteImage(*queue, mem, CL_TRUE, origin, region, 0, 0, data, 0, NULL, NULL);
188 result = check_allocation_error(context, device_id, error, queue);
189
190 if (result == FAILED_ABORT) {
191 print_error(error, "clEnqueueWriteImage failed.");
192 }
193
194 if (result != SUCCEEDED) {
195 clFinish(*queue);
196 clReleaseMemObject(mem);
197 free(data);
198 return result;
199 }
200 result = clFinish(*queue);
201 if (result != SUCCEEDED)
202 {
203 print_error(error,
204 "clFinish failed after successful enqueuing filling "
205 "buffer with data.");
206 return result;
207 }
208 } else {
209 error = clEnqueueWriteImage(*queue, mem, CL_FALSE, origin, region, 0, 0, data, 0, NULL, &event);
210 result = check_allocation_error(context, device_id, error, queue);
211
212 if (result == FAILED_ABORT) {
213 print_error(error, "clEnqueueWriteImage failed.");
214 }
215
216 if (result != SUCCEEDED) {
217 clFinish(*queue);
218 clReleaseMemObject(mem);
219 free(data);
220 return result;
221 }
222
223 error = clWaitForEvents(1, &event);
224 result = check_allocation_error(context, device_id, error, queue, &event);
225
226 if (result == FAILED_ABORT) {
227 print_error(error, "clWaitForEvents failed.");
228 }
229
230 if (result != SUCCEEDED) {
231 clReleaseEvent(event);
232 free(data);
233 clReleaseMemObject(mem);
234 return result;
235 }
236
237 clReleaseEvent(event);
238 }
239 }
240
241 // Deal with any leftover bits
242 if (origin[1] < height) {
243 // Put values in the data, and keep a checksum as we go along.
244 for (j=0; j<width*4*(height-origin[1]); j++) {
245 data[j] = (cl_uint)genrand_int32(d);
246 checksum_delta += data[j];
247 }
248
249 region[1] = height-origin[1];
250 if(blocking_write) {
251 error = clEnqueueWriteImage(*queue, mem, CL_TRUE, origin, region, 0, 0, data, 0, NULL, NULL);
252 result = check_allocation_error(context, device_id, error, queue);
253
254 if (result == FAILED_ABORT) {
255 print_error(error, "clEnqueueWriteImage failed.");
256 }
257
258 if (result != SUCCEEDED) {
259 clFinish(*queue);
260 clReleaseMemObject(mem);
261 free(data);
262 return result;
263 }
264 } else {
265 error = clEnqueueWriteImage(*queue, mem, CL_FALSE, origin, region, 0, 0, data, 0, NULL, &event);
266 result = check_allocation_error(context, device_id, error, queue);
267
268 if (result == FAILED_ABORT) {
269 print_error(error, "clEnqueueWriteImage failed.");
270 }
271
272 if (result != SUCCEEDED) {
273 clFinish(*queue);
274 clReleaseMemObject(mem);
275 free(data);
276 return result;
277 }
278
279 error = clWaitForEvents(1, &event);
280 result = check_allocation_error(context, device_id, error, queue, &event);
281
282 if (result == FAILED_ABORT) {
283 print_error(error, "clWaitForEvents failed.");
284 }
285
286 if (result != SUCCEEDED) {
287 clFinish(*queue);
288 clReleaseEvent(event);
289 free(data);
290 clReleaseMemObject(mem);
291 return result;
292 }
293
294 clReleaseEvent(event);
295 }
296 }
297
298 free(data);
299 // Only update the checksum if this succeeded.
300 checksum += checksum_delta;
301 return SUCCEEDED;
302 }
303
304
305
fill_mem_with_data(cl_context context,cl_device_id device_id,cl_command_queue * queue,cl_mem mem,MTdata d,cl_bool blocking_write)306 int fill_mem_with_data(cl_context context, cl_device_id device_id, cl_command_queue *queue, cl_mem mem, MTdata d, cl_bool blocking_write) {
307 int error;
308 cl_mem_object_type type;
309 size_t size, width, height;
310
311 error = clGetMemObjectInfo(mem, CL_MEM_TYPE, sizeof(type), &type, NULL);
312 test_error_abort(error, "clGetMemObjectInfo failed for CL_MEM_TYPE.");
313
314 if (type == CL_MEM_OBJECT_BUFFER) {
315 error = clGetMemObjectInfo(mem, CL_MEM_SIZE, sizeof(size), &size, NULL);
316 test_error_abort(error, "clGetMemObjectInfo failed for CL_MEM_SIZE.");
317 return fill_buffer_with_data(context, device_id, queue, mem, size, d, blocking_write);
318 } else if (type == CL_MEM_OBJECT_IMAGE2D) {
319 error = clGetImageInfo(mem, CL_IMAGE_WIDTH, sizeof(width), &width, NULL);
320 test_error_abort(error, "clGetImageInfo failed for CL_IMAGE_WIDTH.");
321 error = clGetImageInfo(mem, CL_IMAGE_HEIGHT, sizeof(height), &height, NULL);
322 test_error_abort(error, "clGetImageInfo failed for CL_IMAGE_HEIGHT.");
323 return fill_image_with_data(context, device_id, queue, mem, width, height, d, blocking_write);
324 }
325
326 log_error("Invalid CL_MEM_TYPE: %d\n", type);
327 return FAILED_ABORT;
328 }
329
330
331
332