• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <string.h>
20 #include <sys/types.h>
21 #include <sys/stat.h>
22 
23 #include "procs.h"
24 
25 static int
26 test_sign_double(cl_device_id device, cl_context context, cl_command_queue queue, int n_elems);
27 
28 
29 const char *sign_kernel_code =
30 "__kernel void test_sign(__global float *src, __global float *dst)\n"
31 "{\n"
32 "    int  tid = get_global_id(0);\n"
33 "\n"
34 "    dst[tid] = sign(src[tid]);\n"
35 "}\n";
36 
37 const char *sign2_kernel_code =
38 "__kernel void test_sign2(__global float2 *src, __global float2 *dst)\n"
39 "{\n"
40 "    int  tid = get_global_id(0);\n"
41 "\n"
42 "    dst[tid] = sign(src[tid]);\n"
43 "}\n";
44 
45 const char *sign4_kernel_code =
46 "__kernel void test_sign4(__global float4 *src, __global float4 *dst)\n"
47 "{\n"
48 "    int  tid = get_global_id(0);\n"
49 "\n"
50 "    dst[tid] = sign(src[tid]);\n"
51 "}\n";
52 
53 const char *sign8_kernel_code =
54 "__kernel void test_sign8(__global float8 *src, __global float8 *dst)\n"
55 "{\n"
56 "    int  tid = get_global_id(0);\n"
57 "\n"
58 "    dst[tid] = sign(src[tid]);\n"
59 "}\n";
60 
61 const char *sign16_kernel_code =
62 "__kernel void test_sign16(__global float16 *src, __global float16 *dst)\n"
63 "{\n"
64 "    int  tid = get_global_id(0);\n"
65 "\n"
66 "    dst[tid] = sign(src[tid]);\n"
67 "}\n";
68 
69 const char *sign3_kernel_code =
70 "__kernel void test_sign3(__global float *src, __global float *dst)\n"
71 "{\n"
72 "    int  tid = get_global_id(0);\n"
73 "\n"
74 "    vstore3(sign(vload3(tid,src)), tid, dst);\n"
75 "}\n";
76 
77 
78 
79 static int
verify_sign(float * inptr,float * outptr,int n)80 verify_sign(float *inptr, float *outptr, int n)
81 {
82   float       r;
83   int         i;
84 
85   for (i=0; i<n; i++)
86   {
87     if (inptr[i] > 0.0f)
88       r = 1.0f;
89     else if (inptr[i] < 0.0f)
90       r = -1.0f;
91     else
92       r = 0.0f;
93     if (r != outptr[i])
94       return -1;
95   }
96 
97   return 0;
98 }
99 
100 static const char *fn_names[] = { "SIGN float", "SIGN float2", "SIGN float4", "SIGN float8", "SIGN float16", "SIGN float3" };
101 
102 int
test_sign(cl_device_id device,cl_context context,cl_command_queue queue,int n_elems)103 test_sign(cl_device_id device, cl_context context, cl_command_queue queue, int n_elems)
104 {
105   cl_mem      streams[2];
106   cl_float    *input_ptr[1], *output_ptr, *p;
107   cl_program  program[kTotalVecCount];
108   cl_kernel   kernel[kTotalVecCount];
109   void        *values[2];
110   size_t  threads[1];
111   int num_elements;
112   int err;
113   int i;
114   MTdata    d;
115 
116   num_elements = n_elems * 16;
117 
118   input_ptr[0] = (cl_float*)malloc(sizeof(cl_float) * num_elements);
119   output_ptr = (cl_float*)malloc(sizeof(cl_float) * num_elements);
120   streams[0] = clCreateBuffer(context, CL_MEM_READ_WRITE,
121                               sizeof(cl_float) * num_elements, NULL, NULL);
122   if (!streams[0])
123   {
124     log_error("clCreateBuffer failed\n");
125     return -1;
126   }
127 
128   streams[1] = clCreateBuffer(context, CL_MEM_READ_WRITE,
129                               sizeof(cl_float) * num_elements, NULL, NULL);
130   if (!streams[1])
131   {
132     log_error("clCreateBuffer failed\n");
133     return -1;
134   }
135 
136   d = init_genrand( gRandomSeed );
137   p = input_ptr[0];
138   for (i=0; i<num_elements; i++)
139   {
140     p[i] = get_random_float(-0x20000000, 0x20000000, d);
141   }
142   free_mtdata(d);   d = NULL;
143 
144 
145   err = clEnqueueWriteBuffer( queue, streams[0], true, 0, sizeof(cl_float)*num_elements, (void *)input_ptr[0], 0, NULL, NULL );
146   if (err != CL_SUCCESS)
147   {
148     log_error("clWriteArray failed\n");
149     return -1;
150   }
151 
152   err = create_single_kernel_helper( context, &program[0], &kernel[0], 1, &sign_kernel_code, "test_sign" );
153   if (err)
154     return -1;
155   err = create_single_kernel_helper( context, &program[1], &kernel[1], 1, &sign2_kernel_code, "test_sign2" );
156   if (err)
157     return -1;
158   err = create_single_kernel_helper( context, &program[2], &kernel[2], 1, &sign4_kernel_code, "test_sign4" );
159   if (err)
160     return -1;
161   err = create_single_kernel_helper( context, &program[3], &kernel[3], 1, &sign8_kernel_code, "test_sign8" );
162   if (err)
163     return -1;
164   err = create_single_kernel_helper( context, &program[4], &kernel[4], 1, &sign16_kernel_code, "test_sign16" );
165   if (err)
166     return -1;
167   err = create_single_kernel_helper( context, &program[5], &kernel[5], 1, &sign3_kernel_code, "test_sign3" );
168   if (err)
169     return -1;
170 
171   values[0] = streams[0];
172   values[1] = streams[1];
173   for (i=0; i<kTotalVecCount; i++)
174   {
175       err = clSetKernelArg(kernel[i], 0, sizeof streams[0], &streams[0] );
176       err |= clSetKernelArg(kernel[i], 1, sizeof streams[1], &streams[1] );
177       if (err != CL_SUCCESS)
178     {
179       log_error("clSetKernelArgs failed\n");
180       return -1;
181     }
182   }
183 
184   threads[0] = (size_t)n_elems;
185   for (i=0; i<kTotalVecCount; i++) // change this so we test all
186   {
187     err = clEnqueueNDRangeKernel( queue, kernel[i], 1, NULL, threads, NULL, 0, NULL, NULL );
188     if (err != CL_SUCCESS)
189     {
190       log_error("clEnqueueNDRangeKernel failed\n");
191       return -1;
192     }
193 
194     err = clEnqueueReadBuffer( queue, streams[1], true, 0, sizeof(cl_float)*num_elements, (void *)output_ptr, 0, NULL, NULL );
195     if (err != CL_SUCCESS)
196     {
197       log_error("clEnqueueReadBuffer failed\n");
198       return -1;
199     }
200 
201     if (verify_sign(input_ptr[0], output_ptr, n_elems*(i+1)))
202     {
203       log_error("%s test failed\n", fn_names[i]);
204       err = -1;
205     }
206     else
207     {
208       log_info("%s test passed\n", fn_names[i]);
209       err = 0;
210     }
211 
212     if (err)
213       break;
214   }
215 
216   clReleaseMemObject(streams[0]);
217   clReleaseMemObject(streams[1]);
218   for (i=0; i<kTotalVecCount; i++)
219   {
220     clReleaseKernel(kernel[i]);
221     clReleaseProgram(program[i]);
222   }
223   free(input_ptr[0]);
224   free(output_ptr);
225 
226   if(err)
227     return err;
228 
229     if( ! is_extension_available( device, "cl_khr_fp64"))
230     {
231         log_info( "skipping double test -- cl_khr_fp64 not supported.\n" );
232         return 0;
233     }
234 
235     return test_sign_double( device, context, queue, n_elems);
236 }
237 
238 #pragma mark -
239 
240 const char *sign_kernel_code_double =
241 "#pragma OPENCL EXTENSION cl_khr_fp64 : enable\n"
242 "__kernel void test_sign_double(__global double *src, __global double *dst)\n"
243 "{\n"
244 "    int  tid = get_global_id(0);\n"
245 "\n"
246 "    dst[tid] = sign(src[tid]);\n"
247 "}\n";
248 
249 const char *sign2_kernel_code_double =
250 "#pragma OPENCL EXTENSION cl_khr_fp64 : enable\n"
251 "__kernel void test_sign2_double(__global double2 *src, __global double2 *dst)\n"
252 "{\n"
253 "    int  tid = get_global_id(0);\n"
254 "\n"
255 "    dst[tid] = sign(src[tid]);\n"
256 "}\n";
257 
258 const char *sign4_kernel_code_double =
259 "#pragma OPENCL EXTENSION cl_khr_fp64 : enable\n"
260 "__kernel void test_sign4_double(__global double4 *src, __global double4 *dst)\n"
261 "{\n"
262 "    int  tid = get_global_id(0);\n"
263 "\n"
264 "    dst[tid] = sign(src[tid]);\n"
265 "}\n";
266 
267 const char *sign8_kernel_code_double =
268 "#pragma OPENCL EXTENSION cl_khr_fp64 : enable\n"
269 "__kernel void test_sign8_double(__global double8 *src, __global double8 *dst)\n"
270 "{\n"
271 "    int  tid = get_global_id(0);\n"
272 "\n"
273 "    dst[tid] = sign(src[tid]);\n"
274 "}\n";
275 
276 const char *sign16_kernel_code_double =
277 "#pragma OPENCL EXTENSION cl_khr_fp64 : enable\n"
278 "__kernel void test_sign16_double(__global double16 *src, __global double16 *dst)\n"
279 "{\n"
280 "    int  tid = get_global_id(0);\n"
281 "\n"
282 "    dst[tid] = sign(src[tid]);\n"
283 "}\n";
284 
285 const char *sign3_kernel_code_double =
286 "#pragma OPENCL EXTENSION cl_khr_fp64 : enable\n"
287 "__kernel void test_sign3_double(__global double *src, __global double *dst)\n"
288 "{\n"
289 "    int  tid = get_global_id(0);\n"
290 "\n"
291 "    vstore3(sign(vload3(tid,src)), tid, dst);\n"
292 "}\n";
293 
294 
295 static int
verify_sign_double(double * inptr,double * outptr,int n)296 verify_sign_double(double *inptr, double *outptr, int n)
297 {
298   double       r;
299   int         i;
300 
301   for (i=0; i<n; i++)
302   {
303     if (inptr[i] > 0.0)
304       r = 1.0;
305     else if (inptr[i] < 0.0)
306       r = -1.0;
307     else
308       r = 0.0f;
309     if (r != outptr[i])
310       return -1;
311   }
312 
313   return 0;
314 }
315 
316 static const char *fn_names_double[] = { "SIGN double", "SIGN double2", "SIGN double4", "SIGN double8", "SIGN double16", "SIGN double3" };
317 
318 int
test_sign_double(cl_device_id device,cl_context context,cl_command_queue queue,int n_elems)319 test_sign_double(cl_device_id device, cl_context context, cl_command_queue queue, int n_elems)
320 {
321   cl_mem      streams[2];
322   cl_double    *input_ptr[1], *output_ptr, *p;
323   cl_program  program[kTotalVecCount];
324   cl_kernel   kernel[kTotalVecCount];
325   void        *values[2];
326   size_t  threads[1];
327   int num_elements;
328   int err;
329   int i;
330   MTdata    d;
331 
332   num_elements = n_elems * 16;
333 
334   input_ptr[0] = (cl_double*)malloc(sizeof(cl_double) * num_elements);
335   output_ptr = (cl_double*)malloc(sizeof(cl_double) * num_elements);
336   streams[0] = clCreateBuffer(context, CL_MEM_READ_WRITE,
337                               sizeof(cl_double) * num_elements, NULL, NULL);
338   if (!streams[0])
339   {
340     log_error("clCreateBuffer failed\n");
341     return -1;
342   }
343 
344   streams[1] = clCreateBuffer(context, CL_MEM_READ_WRITE,
345                               sizeof(cl_double) * num_elements, NULL, NULL);
346   if (!streams[1])
347   {
348     log_error("clCreateBuffer failed\n");
349     return -1;
350   }
351 
352   d = init_genrand( gRandomSeed );
353   p = input_ptr[0];
354   for (i=0; i<num_elements; i++)
355     p[i] = get_random_double(-0x20000000, 0x20000000, d);
356 
357   free_mtdata(d);   d = NULL;
358 
359 
360   err = clEnqueueWriteBuffer( queue, streams[0], true, 0, sizeof(cl_double)*num_elements, (void *)input_ptr[0], 0, NULL, NULL );
361   if (err != CL_SUCCESS)
362   {
363     log_error("clWriteArray failed\n");
364     return -1;
365   }
366 
367   err = create_single_kernel_helper( context, &program[0], &kernel[0], 1, &sign_kernel_code_double, "test_sign_double" );
368   if (err)
369     return -1;
370   err = create_single_kernel_helper( context, &program[1], &kernel[1], 1, &sign2_kernel_code_double, "test_sign2_double" );
371   if (err)
372     return -1;
373   err = create_single_kernel_helper( context, &program[2], &kernel[2], 1, &sign4_kernel_code_double, "test_sign4_double" );
374   if (err)
375     return -1;
376   err = create_single_kernel_helper( context, &program[3], &kernel[3], 1, &sign8_kernel_code_double, "test_sign8_double" );
377   if (err)
378     return -1;
379   err = create_single_kernel_helper( context, &program[4], &kernel[4], 1, &sign16_kernel_code_double, "test_sign16_double" );
380   if (err)
381     return -1;
382   err = create_single_kernel_helper( context, &program[5], &kernel[5], 1, &sign3_kernel_code_double, "test_sign3_double" );
383   if (err)
384     return -1;
385 
386   values[0] = streams[0];
387   values[1] = streams[1];
388   for (i=0; i<kTotalVecCount; i++)
389   {
390       err = clSetKernelArg(kernel[i], 0, sizeof streams[0], &streams[0] );
391       err |= clSetKernelArg(kernel[i], 1, sizeof streams[1], &streams[1] );
392       if (err != CL_SUCCESS)
393     {
394       log_error("clSetKernelArgs failed\n");
395       return -1;
396     }
397   }
398 
399   threads[0] = (size_t)n_elems;
400   for (i=0; i<kTotalVecCount; i++) // this hsould be changed
401   {
402     err = clEnqueueNDRangeKernel( queue, kernel[i], 1, NULL, threads, NULL, 0, NULL, NULL );
403     if (err != CL_SUCCESS)
404     {
405       log_error("clEnqueueNDRangeKernel failed\n");
406       return -1;
407     }
408 
409     err = clEnqueueReadBuffer( queue, streams[1], true, 0, sizeof(cl_double)*num_elements, (void *)output_ptr, 0, NULL, NULL );
410     if (err != CL_SUCCESS)
411     {
412       log_error("clEnqueueReadBuffer failed\n");
413       return -1;
414     }
415 
416     if (verify_sign_double(input_ptr[0], output_ptr, n_elems*(i+1)))
417     {
418       log_error("%s test failed\n", fn_names_double[i]);
419       err = -1;
420     }
421     else
422     {
423       log_info("%s test passed\n", fn_names_double[i]);
424       err = 0;
425     }
426 
427     if (err)
428       break;
429   }
430 
431   clReleaseMemObject(streams[0]);
432   clReleaseMemObject(streams[1]);
433   for (i=0; i<kTotalVecCount; i++)
434   {
435     clReleaseKernel(kernel[i]);
436     clReleaseProgram(program[i]);
437   }
438   free(input_ptr[0]);
439   free(output_ptr);
440 
441   return err;
442 }
443 
444 
445