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