120 lines
3.7 KiB
C++
120 lines
3.7 KiB
C++
//
|
|
// 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;
|
|
}
|
|
|
|
|
|
|
|
|
|
|