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
18 #ifndef _WIN32
19 #include <unistd.h>
20 #endif
21
22 #include "harness/conversions.h"
23
test_native_kernel_fn(void * userData)24 static void CL_CALLBACK test_native_kernel_fn( void *userData )
25 {
26 struct arg_struct {
27 cl_int * source;
28 cl_int * dest;
29 cl_int count;
30 } *args = (arg_struct *)userData;
31
32 for( cl_int i = 0; i < args->count; i++ )
33 args->dest[ i ] = args->source[ i ];
34 }
35
test_native_kernel(cl_device_id device,cl_context context,cl_command_queue queue,int n_elems)36 int test_native_kernel(cl_device_id device, cl_context context, cl_command_queue queue, int n_elems )
37 {
38 int error;
39 RandomSeed seed( gRandomSeed );
40 // Check if we support native kernels
41 cl_device_exec_capabilities capabilities;
42 error = clGetDeviceInfo(device, CL_DEVICE_EXECUTION_CAPABILITIES, sizeof(capabilities), &capabilities, NULL);
43 if (!(capabilities & CL_EXEC_NATIVE_KERNEL)) {
44 log_info("Device does not support CL_EXEC_NATIVE_KERNEL.\n");
45 return 0;
46 }
47
48 clMemWrapper streams[ 2 ];
49 #if !(defined (_WIN32) && defined (_MSC_VER))
50 cl_int inBuffer[ n_elems ], outBuffer[ n_elems ];
51 #else
52 cl_int* inBuffer = (cl_int *)_malloca( n_elems * sizeof(cl_int) );
53 cl_int* outBuffer = (cl_int *)_malloca( n_elems * sizeof(cl_int) );
54 #endif
55 clEventWrapper finishEvent;
56
57 struct arg_struct
58 {
59 cl_mem inputStream;
60 cl_mem outputStream;
61 cl_int count;
62 } args;
63
64
65 // Create some input values
66 generate_random_data( kInt, n_elems, seed, inBuffer );
67
68
69 // Create I/O streams
70 streams[ 0 ] = clCreateBuffer( context, CL_MEM_COPY_HOST_PTR, n_elems * sizeof(cl_int), inBuffer, &error );
71 test_error( error, "Unable to create I/O stream" );
72 streams[ 1 ] = clCreateBuffer( context, 0, n_elems * sizeof(cl_int), NULL, &error );
73 test_error( error, "Unable to create I/O stream" );
74
75
76 // Set up the arrays to call with
77 args.inputStream = streams[ 0 ];
78 args.outputStream = streams[ 1 ];
79 args.count = n_elems;
80
81 void * memLocs[ 2 ] = { &args.inputStream, &args.outputStream };
82
83
84 // Run the kernel
85 error = clEnqueueNativeKernel( queue, test_native_kernel_fn,
86 &args, sizeof( args ),
87 2, &streams[ 0 ],
88 (const void **)memLocs,
89 0, NULL, &finishEvent );
90 test_error( error, "Unable to queue native kernel" );
91
92 // Finish and wait for the kernel to complete
93 error = clFinish( queue );
94 test_error(error, "clFinish failed");
95
96 error = clWaitForEvents( 1, &finishEvent );
97 test_error(error, "clWaitForEvents failed");
98
99 // Now read the results and verify
100 error = clEnqueueReadBuffer( queue, streams[ 1 ], CL_TRUE, 0, n_elems * sizeof(cl_int), outBuffer, 0, NULL, NULL );
101 test_error( error, "Unable to read results" );
102
103 for( int i = 0; i < n_elems; i++ )
104 {
105 if( inBuffer[ i ] != outBuffer[ i ] )
106 {
107 log_error( "ERROR: Data sample %d for native kernel did not validate (expected %d, got %d)\n",
108 i, (int)inBuffer[ i ], (int)outBuffer[ i ] );
109 return 1;
110 }
111 }
112
113 return 0;
114 }
115
116
117
118
119
120