| // |
| // Copyright (c) 2017 The Khronos Group Inc. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| // |
| #include "testBase.h" |
| |
| #ifndef _WIN32 |
| #include <unistd.h> |
| #endif |
| |
| #include "harness/conversions.h" |
| |
| static void CL_CALLBACK test_native_kernel_fn( void *userData ) |
| { |
| struct arg_struct { |
| cl_int * source; |
| cl_int * dest; |
| cl_int count; |
| } *args = (arg_struct *)userData; |
| |
| for( cl_int i = 0; i < args->count; i++ ) |
| args->dest[ i ] = args->source[ i ]; |
| } |
| |
| int test_native_kernel(cl_device_id device, cl_context context, cl_command_queue queue, int n_elems ) |
| { |
| int error; |
| RandomSeed seed( gRandomSeed ); |
| // Check if we support native kernels |
| cl_device_exec_capabilities capabilities; |
| error = clGetDeviceInfo(device, CL_DEVICE_EXECUTION_CAPABILITIES, sizeof(capabilities), &capabilities, NULL); |
| if (!(capabilities & CL_EXEC_NATIVE_KERNEL)) { |
| log_info("Device does not support CL_EXEC_NATIVE_KERNEL.\n"); |
| return 0; |
| } |
| |
| clMemWrapper streams[ 2 ]; |
| #if !(defined (_WIN32) && defined (_MSC_VER)) |
| cl_int inBuffer[ n_elems ], outBuffer[ n_elems ]; |
| #else |
| cl_int* inBuffer = (cl_int *)_malloca( n_elems * sizeof(cl_int) ); |
| cl_int* outBuffer = (cl_int *)_malloca( n_elems * sizeof(cl_int) ); |
| #endif |
| clEventWrapper finishEvent; |
| |
| struct arg_struct |
| { |
| cl_mem inputStream; |
| cl_mem outputStream; |
| cl_int count; |
| } args; |
| |
| |
| // Create some input values |
| generate_random_data( kInt, n_elems, seed, inBuffer ); |
| |
| |
| // Create I/O streams |
| streams[ 0 ] = clCreateBuffer( context, CL_MEM_COPY_HOST_PTR, n_elems * sizeof(cl_int), inBuffer, &error ); |
| test_error( error, "Unable to create I/O stream" ); |
| streams[ 1 ] = clCreateBuffer( context, 0, n_elems * sizeof(cl_int), NULL, &error ); |
| test_error( error, "Unable to create I/O stream" ); |
| |
| |
| // Set up the arrays to call with |
| args.inputStream = streams[ 0 ]; |
| args.outputStream = streams[ 1 ]; |
| args.count = n_elems; |
| |
| void * memLocs[ 2 ] = { &args.inputStream, &args.outputStream }; |
| |
| |
| // Run the kernel |
| error = clEnqueueNativeKernel( queue, test_native_kernel_fn, |
| &args, sizeof( args ), |
| 2, &streams[ 0 ], |
| (const void **)memLocs, |
| 0, NULL, &finishEvent ); |
| test_error( error, "Unable to queue native kernel" ); |
| |
| // Finish and wait for the kernel to complete |
| error = clFinish( queue ); |
| test_error(error, "clFinish failed"); |
| |
| error = clWaitForEvents( 1, &finishEvent ); |
| test_error(error, "clWaitForEvents failed"); |
| |
| // Now read the results and verify |
| error = clEnqueueReadBuffer( queue, streams[ 1 ], CL_TRUE, 0, n_elems * sizeof(cl_int), outBuffer, 0, NULL, NULL ); |
| test_error( error, "Unable to read results" ); |
| |
| for( int i = 0; i < n_elems; i++ ) |
| { |
| if( inBuffer[ i ] != outBuffer[ i ] ) |
| { |
| log_error( "ERROR: Data sample %d for native kernel did not validate (expected %d, got %d)\n", |
| i, (int)inBuffer[ i ], (int)outBuffer[ i ] ); |
| return 1; |
| } |
| } |
| |
| return 0; |
| } |
| |
| |
| |
| |
| |