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 "testBase.h"
17 #if !defined(_WIN32)
18 #include <unistd.h>
19 #endif // !_WIN32
20
21 // Note: According to spec, the various functions to get instance counts should return an error when passed in an object
22 // that has already been released. However, the spec is out of date. If it gets re-updated to allow such action, re-enable
23 // this define.
24 //#define VERIFY_AFTER_RELEASE 1
25
26 #define GET_QUEUE_INSTANCE_COUNT(p) numInstances = ( (err = clGetCommandQueueInfo(p, CL_QUEUE_REFERENCE_COUNT, sizeof( numInstances ), &numInstances, NULL)) == CL_SUCCESS ? numInstances : 0 )
27 #define GET_MEM_INSTANCE_COUNT(p) numInstances = ( (err = clGetMemObjectInfo(p, CL_MEM_REFERENCE_COUNT, sizeof( numInstances ), &numInstances, NULL)) == CL_SUCCESS ? numInstances : 0 )
28
29 #define VERIFY_INSTANCE_COUNT(c,rightValue) if( c != rightValue ) { \
30 log_error( "ERROR: Instance count for test object is not valid! (should be %d, really is %d)\n", rightValue, c ); \
31 return -1; }
32
test_retain_queue_single(cl_device_id deviceID,cl_context context,cl_command_queue queueNotUsed,int num_elements)33 int test_retain_queue_single(cl_device_id deviceID, cl_context context, cl_command_queue queueNotUsed, int num_elements)
34 {
35 cl_command_queue queue;
36 cl_uint numInstances;
37 int err;
38
39
40 /* Create a test queue */
41 queue = clCreateCommandQueue( context, deviceID, 0, &err );
42 test_error( err, "Unable to create command queue to test with" );
43
44 /* Test the instance count */
45 GET_QUEUE_INSTANCE_COUNT( queue );
46 test_error( err, "Unable to get queue instance count" );
47 VERIFY_INSTANCE_COUNT( numInstances, 1 );
48
49 /* Now release the program */
50 clReleaseCommandQueue( queue );
51 #ifdef VERIFY_AFTER_RELEASE
52 /* We're not allowed to get the instance count after the object has been completely released. But that's
53 exactly how we can tell the release worked--by making sure getting the instance count fails! */
54 GET_QUEUE_INSTANCE_COUNT( queue );
55 if( err != CL_INVALID_COMMAND_QUEUE )
56 {
57 print_error( err, "Command queue was not properly released" );
58 return -1;
59 }
60 #endif
61
62 return 0;
63 }
64
test_retain_queue_multiple(cl_device_id deviceID,cl_context context,cl_command_queue queueNotUsed,int num_elements)65 int test_retain_queue_multiple(cl_device_id deviceID, cl_context context, cl_command_queue queueNotUsed, int num_elements)
66 {
67 cl_command_queue queue;
68 unsigned int numInstances, i;
69 int err;
70
71
72 /* Create a test program */
73 queue = clCreateCommandQueue( context, deviceID, 0, &err );
74 test_error( err, "Unable to create command queue to test with" );
75
76 /* Increment 9 times, which should bring the count to 10 */
77 for( i = 0; i < 9; i++ )
78 {
79 clRetainCommandQueue( queue );
80 }
81
82 /* Test the instance count */
83 GET_QUEUE_INSTANCE_COUNT( queue );
84 test_error( err, "Unable to get queue instance count" );
85 VERIFY_INSTANCE_COUNT( numInstances, 10 );
86
87 /* Now release 5 times, which should take us to 5 */
88 for( i = 0; i < 5; i++ )
89 {
90 clReleaseCommandQueue( queue );
91 }
92
93 GET_QUEUE_INSTANCE_COUNT( queue );
94 test_error( err, "Unable to get queue instance count" );
95 VERIFY_INSTANCE_COUNT( numInstances, 5 );
96
97 /* Retain again three times, which should take us to 8 */
98 for( i = 0; i < 3; i++ )
99 {
100 clRetainCommandQueue( queue );
101 }
102
103 GET_QUEUE_INSTANCE_COUNT( queue );
104 test_error( err, "Unable to get queue instance count" );
105 VERIFY_INSTANCE_COUNT( numInstances, 8 );
106
107 /* Release 7 times, which should take it to 1 */
108 for( i = 0; i < 7; i++ )
109 {
110 clReleaseCommandQueue( queue );
111 }
112
113 GET_QUEUE_INSTANCE_COUNT( queue );
114 test_error( err, "Unable to get queue instance count" );
115 VERIFY_INSTANCE_COUNT( numInstances, 1 );
116
117 /* And one last one */
118 clReleaseCommandQueue( queue );
119
120 #ifdef VERIFY_AFTER_RELEASE
121 /* We're not allowed to get the instance count after the object has been completely released. But that's
122 exactly how we can tell the release worked--by making sure getting the instance count fails! */
123 GET_QUEUE_INSTANCE_COUNT( queue );
124 if( err != CL_INVALID_COMMAND_QUEUE )
125 {
126 print_error( err, "Command queue was not properly released" );
127 return -1;
128 }
129 #endif
130
131 return 0;
132 }
133
test_retain_mem_object_single(cl_device_id deviceID,cl_context context,cl_command_queue queue,int num_elements)134 int test_retain_mem_object_single(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
135 {
136 cl_mem object;
137 cl_uint numInstances;
138 int err;
139
140
141 /* Create a test object */
142 object = clCreateBuffer( context, CL_MEM_READ_ONLY, 32, NULL, &err );
143 test_error( err, "Unable to create buffer to test with" );
144
145 /* Test the instance count */
146 GET_MEM_INSTANCE_COUNT( object );
147 test_error( err, "Unable to get mem object count" );
148 VERIFY_INSTANCE_COUNT( numInstances, 1 );
149
150 /* Now release the program */
151 clReleaseMemObject( object );
152 #ifdef VERIFY_AFTER_RELEASE
153 /* We're not allowed to get the instance count after the object has been completely released. But that's
154 exactly how we can tell the release worked--by making sure getting the instance count fails! */
155 GET_MEM_INSTANCE_COUNT( object );
156 if( err != CL_INVALID_MEM_OBJECT )
157 {
158 print_error( err, "Mem object was not properly released" );
159 return -1;
160 }
161 #endif
162
163 return 0;
164 }
165
test_retain_mem_object_multiple(cl_device_id deviceID,cl_context context,cl_command_queue queue,int num_elements)166 int test_retain_mem_object_multiple(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
167 {
168 cl_mem object;
169 unsigned int numInstances, i;
170 int err;
171
172
173 /* Create a test object */
174 object = clCreateBuffer( context, CL_MEM_READ_ONLY, 32, NULL, &err );
175 test_error( err, "Unable to create buffer to test with" );
176
177 /* Increment 9 times, which should bring the count to 10 */
178 for( i = 0; i < 9; i++ )
179 {
180 clRetainMemObject( object );
181 }
182
183 /* Test the instance count */
184 GET_MEM_INSTANCE_COUNT( object );
185 test_error( err, "Unable to get mem object count" );
186 VERIFY_INSTANCE_COUNT( numInstances, 10 );
187
188 /* Now release 5 times, which should take us to 5 */
189 for( i = 0; i < 5; i++ )
190 {
191 clReleaseMemObject( object );
192 }
193
194 GET_MEM_INSTANCE_COUNT( object );
195 test_error( err, "Unable to get mem object count" );
196 VERIFY_INSTANCE_COUNT( numInstances, 5 );
197
198 /* Retain again three times, which should take us to 8 */
199 for( i = 0; i < 3; i++ )
200 {
201 clRetainMemObject( object );
202 }
203
204 GET_MEM_INSTANCE_COUNT( object );
205 test_error( err, "Unable to get mem object count" );
206 VERIFY_INSTANCE_COUNT( numInstances, 8 );
207
208 /* Release 7 times, which should take it to 1 */
209 for( i = 0; i < 7; i++ )
210 {
211 clReleaseMemObject( object );
212 }
213
214 GET_MEM_INSTANCE_COUNT( object );
215 test_error( err, "Unable to get mem object count" );
216 VERIFY_INSTANCE_COUNT( numInstances, 1 );
217
218 /* And one last one */
219 clReleaseMemObject( object );
220
221 #ifdef VERIFY_AFTER_RELEASE
222 /* We're not allowed to get the instance count after the object has been completely released. But that's
223 exactly how we can tell the release worked--by making sure getting the instance count fails! */
224 GET_MEM_INSTANCE_COUNT( object );
225 if( err != CL_INVALID_MEM_OBJECT )
226 {
227 print_error( err, "Mem object was not properly released" );
228 return -1;
229 }
230 #endif
231
232 return 0;
233 }
234
test_retain_mem_object_set_kernel_arg(cl_device_id deviceID,cl_context context,cl_command_queue queue,int num_elements)235 int test_retain_mem_object_set_kernel_arg(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
236 {
237 int err;
238 cl_mem buffer = nullptr;
239 cl_program program;
240 cl_kernel kernel;
241 static volatile uint32_t sValue;
242 sValue = 0;
243 auto callback = []( cl_mem, void * ) {
244 ++sValue;
245 };
246 const char *testProgram[] = { "__kernel void sample_test(__global int *data){}" };
247
248 buffer = clCreateBuffer( context, CL_MEM_READ_ONLY, 32, NULL, &err );
249 test_error( err, "Unable to create buffer to test with" );
250
251 err = clSetMemObjectDestructorCallback( buffer, callback, nullptr );
252 test_error( err, "Unable to set destructor callback" );
253
254 err = create_single_kernel_helper(context, &program, &kernel, 1,
255 testProgram, "sample_test");
256 test_error(err, "Unable to build sample program and sample_test kernel");
257
258 err = clSetKernelArg( kernel, 0, sizeof(cl_mem), &buffer );
259 test_error( err, "Unable to set kernel argument" );
260
261 err = clReleaseMemObject( buffer );
262 test_error( err, "Unable to release buffer" );
263
264 // Spin waiting for the release to finish. If you don't call the mem_destructor_callback, you will not
265 // pass the test. bugzilla 6316
266 while (sValue == 0) { }
267
268 clReleaseKernel( kernel );
269 clReleaseProgram( program );
270
271 // If we got this far, we succeeded.
272 return 0;
273 }
274