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 "harness/compat.h"
17
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <sys/types.h>
22 #include <sys/stat.h>
23
24
25 #include "procs.h"
26 #include "harness/conversions.h"
27 #include "harness/typeWrappers.h"
28
29 // clang-format off
30 const cl_mem_flags flag_set[] = {
31 CL_MEM_ALLOC_HOST_PTR,
32 CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
33 CL_MEM_USE_HOST_PTR,
34 CL_MEM_COPY_HOST_PTR,
35 0
36 };
37
38 const char *flag_set_names[] = {
39 "CL_MEM_ALLOC_HOST_PTR",
40 "CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR",
41 "CL_MEM_USE_HOST_PTR",
42 "CL_MEM_COPY_HOST_PTR",
43 "0"
44 };
45 // clang-format on
46
test_enqueue_map_buffer(cl_device_id deviceID,cl_context context,cl_command_queue queue,int num_elements)47 int test_enqueue_map_buffer(cl_device_id deviceID, cl_context context,
48 cl_command_queue queue, int num_elements)
49 {
50 int error;
51 const size_t bufferSize = 256 * 256;
52 MTdataHolder d{ gRandomSeed };
53 BufferOwningPtr<cl_char> hostPtrData{ malloc(bufferSize) };
54 BufferOwningPtr<cl_char> referenceData{ malloc(bufferSize) };
55 BufferOwningPtr<cl_char> finalData{ malloc(bufferSize) };
56
57 for (size_t src_flag_id = 0; src_flag_id < ARRAY_SIZE(flag_set);
58 src_flag_id++)
59 {
60 clMemWrapper memObject;
61 log_info("Testing with cl_mem_flags src: %s\n",
62 flag_set_names[src_flag_id]);
63
64 generate_random_data(kChar, (unsigned int)bufferSize, d, hostPtrData);
65 memcpy(referenceData, hostPtrData, bufferSize);
66
67 void *hostPtr = nullptr;
68 cl_mem_flags flags = flag_set[src_flag_id];
69 bool hasHostPtr =
70 (flags & CL_MEM_USE_HOST_PTR) || (flags & CL_MEM_COPY_HOST_PTR);
71 if (hasHostPtr) hostPtr = hostPtrData;
72 memObject = clCreateBuffer(context, flags, bufferSize, hostPtr, &error);
73 test_error(error, "Unable to create testing buffer");
74
75 if (!hasHostPtr)
76 {
77 error =
78 clEnqueueWriteBuffer(queue, memObject, CL_TRUE, 0, bufferSize,
79 hostPtrData, 0, NULL, NULL);
80 test_error(error, "clEnqueueWriteBuffer failed");
81 }
82
83 for (int i = 0; i < 128; i++)
84 {
85
86 size_t offset = (size_t)random_in_range(0, (int)bufferSize - 1, d);
87 size_t length =
88 (size_t)random_in_range(1, (int)(bufferSize - offset), d);
89
90 cl_char *mappedRegion = (cl_char *)clEnqueueMapBuffer(
91 queue, memObject, CL_TRUE, CL_MAP_READ | CL_MAP_WRITE, offset,
92 length, 0, NULL, NULL, &error);
93 if (error != CL_SUCCESS)
94 {
95 print_error(error, "clEnqueueMapBuffer call failed");
96 log_error("\tOffset: %d Length: %d\n", (int)offset,
97 (int)length);
98 return -1;
99 }
100
101 // Write into the region
102 for (size_t j = 0; j < length; j++)
103 {
104 cl_char spin = (cl_char)genrand_int32(d);
105
106 // Test read AND write in one swipe
107 cl_char value = mappedRegion[j];
108 value = spin - value;
109 mappedRegion[j] = value;
110
111 // Also update the initial data array
112 value = referenceData[offset + j];
113 value = spin - value;
114 referenceData[offset + j] = value;
115 }
116
117 // Unmap
118 error = clEnqueueUnmapMemObject(queue, memObject, mappedRegion, 0,
119 NULL, NULL);
120 test_error(error, "Unable to unmap buffer");
121 }
122
123 // Final validation: read actual values of buffer and compare against
124 // our reference
125 error = clEnqueueReadBuffer(queue, memObject, CL_TRUE, 0, bufferSize,
126 finalData, 0, NULL, NULL);
127 test_error(error, "Unable to read results");
128
129 for (size_t q = 0; q < bufferSize; q++)
130 {
131 if (referenceData[q] != finalData[q])
132 {
133 log_error(
134 "ERROR: Sample %d did not validate! Got %d, expected %d\n",
135 (int)q, (int)finalData[q], (int)referenceData[q]);
136 return -1;
137 }
138 }
139 } // cl_mem flags
140
141 return 0;
142 }
143
test_enqueue_map_image(cl_device_id deviceID,cl_context context,cl_command_queue queue,int num_elements)144 int test_enqueue_map_image(cl_device_id deviceID, cl_context context,
145 cl_command_queue queue, int num_elements)
146 {
147 int error;
148 cl_image_format format = { CL_RGBA, CL_UNSIGNED_INT32 };
149 const size_t imageSize = 256;
150 const size_t imageDataSize = imageSize * imageSize * 4 * sizeof(cl_uint);
151
152 PASSIVE_REQUIRE_IMAGE_SUPPORT(deviceID)
153
154 BufferOwningPtr<cl_uint> hostPtrData{ malloc(imageDataSize) };
155 BufferOwningPtr<cl_uint> referenceData{ malloc(imageDataSize) };
156 BufferOwningPtr<cl_uint> finalData{ malloc(imageDataSize) };
157
158 MTdataHolder d{ gRandomSeed };
159 for (size_t src_flag_id = 0; src_flag_id < ARRAY_SIZE(flag_set);
160 src_flag_id++)
161 {
162 clMemWrapper memObject;
163 log_info("Testing with cl_mem_flags src: %s\n",
164 flag_set_names[src_flag_id]);
165
166 generate_random_data(kUInt, (unsigned int)(imageSize * imageSize * 4),
167 d, hostPtrData);
168 memcpy(referenceData, hostPtrData, imageDataSize);
169
170 cl_mem_flags flags = flag_set[src_flag_id];
171 bool hasHostPtr =
172 (flags & CL_MEM_USE_HOST_PTR) || (flags & CL_MEM_COPY_HOST_PTR);
173 void *hostPtr = nullptr;
174 if (hasHostPtr) hostPtr = hostPtrData;
175 memObject = create_image_2d(context, CL_MEM_READ_WRITE | flags, &format,
176 imageSize, imageSize, 0, hostPtr, &error);
177 test_error(error, "Unable to create testing buffer");
178
179 if (!hasHostPtr)
180 {
181 size_t write_origin[3] = { 0, 0, 0 },
182 write_region[3] = { imageSize, imageSize, 1 };
183 error = clEnqueueWriteImage(queue, memObject, CL_TRUE, write_origin,
184 write_region, 0, 0, hostPtrData, 0,
185 NULL, NULL);
186 test_error(error, "Unable to write to testing buffer");
187 }
188
189 for (int i = 0; i < 128; i++)
190 {
191
192 size_t offset[3], region[3];
193 size_t rowPitch;
194
195 offset[0] = (size_t)random_in_range(0, (int)imageSize - 1, d);
196 region[0] =
197 (size_t)random_in_range(1, (int)(imageSize - offset[0] - 1), d);
198 offset[1] = (size_t)random_in_range(0, (int)imageSize - 1, d);
199 region[1] =
200 (size_t)random_in_range(1, (int)(imageSize - offset[1] - 1), d);
201 offset[2] = 0;
202 region[2] = 1;
203 cl_uint *mappedRegion = (cl_uint *)clEnqueueMapImage(
204 queue, memObject, CL_TRUE, CL_MAP_READ | CL_MAP_WRITE, offset,
205 region, &rowPitch, NULL, 0, NULL, NULL, &error);
206 if (error != CL_SUCCESS)
207 {
208 print_error(error, "clEnqueueMapImage call failed");
209 log_error("\tOffset: %d,%d Region: %d,%d\n", (int)offset[0],
210 (int)offset[1], (int)region[0], (int)region[1]);
211 return -1;
212 }
213
214 // Write into the region
215 cl_uint *mappedPtr = mappedRegion;
216 for (size_t y = 0; y < region[1]; y++)
217 {
218 for (size_t x = 0; x < region[0] * 4; x++)
219 {
220 cl_int spin = (cl_int)random_in_range(16, 1024, d);
221
222 cl_int value;
223 // Test read AND write in one swipe
224 value = mappedPtr[(y * rowPitch / sizeof(cl_uint)) + x];
225 value = spin - value;
226 mappedPtr[(y * rowPitch / sizeof(cl_uint)) + x] = value;
227
228 // Also update the initial data array
229 value =
230 referenceData[((offset[1] + y) * imageSize + offset[0])
231 * 4
232 + x];
233 value = spin - value;
234 referenceData[((offset[1] + y) * imageSize + offset[0]) * 4
235 + x] = value;
236 }
237 }
238
239 // Unmap
240 error = clEnqueueUnmapMemObject(queue, memObject, mappedRegion, 0,
241 NULL, NULL);
242 test_error(error, "Unable to unmap buffer");
243 }
244
245 // Final validation: read actual values of buffer and compare against
246 // our reference
247 size_t finalOrigin[3] = { 0, 0, 0 },
248 finalRegion[3] = { imageSize, imageSize, 1 };
249 error = clEnqueueReadImage(queue, memObject, CL_TRUE, finalOrigin,
250 finalRegion, 0, 0, finalData, 0, NULL, NULL);
251 test_error(error, "Unable to read results");
252
253 for (size_t q = 0; q < imageSize * imageSize * 4; q++)
254 {
255 if (referenceData[q] != finalData[q])
256 {
257 log_error(
258 "ERROR: Sample %d (coord %d,%d) did not validate! Got "
259 "%d, expected %d\n",
260 (int)q, (int)((q / 4) % imageSize),
261 (int)((q / 4) / imageSize), (int)finalData[q],
262 (int)referenceData[q]);
263 return -1;
264 }
265 }
266 } // cl_mem_flags
267
268 return 0;
269 }
270