|
|
//
|
|
|
// 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"
|
|
|
|
|
|
#if ! defined( _WIN32 )
|
|
|
#include "unistd.h" // for "sleep" used in the "while (1)" busy wait loop in
|
|
|
#endif
|
|
|
// test_event_flush
|
|
|
|
|
|
const char *sample_long_test_kernel[] = {
|
|
|
"__kernel void sample_test(__global float *src, __global int *dst)\n"
|
|
|
"{\n"
|
|
|
" int tid = get_global_id(0);\n"
|
|
|
" int i;\n"
|
|
|
"\n"
|
|
|
" for( i = 0; i < 10000; i++ )\n"
|
|
|
" {\n"
|
|
|
" dst[tid] = (int)src[tid] * 3;\n"
|
|
|
" }\n"
|
|
|
"\n"
|
|
|
"}\n" };
|
|
|
|
|
|
int create_and_execute_kernel( cl_context inContext, cl_command_queue inQueue, cl_program *outProgram, cl_kernel *outKernel, cl_mem *streams,
|
|
|
unsigned int lineCount, const char **lines, const char *kernelName, cl_event *outEvent )
|
|
|
{
|
|
|
size_t threads[1] = { 1000 }, localThreads[1];
|
|
|
int error;
|
|
|
|
|
|
if( create_single_kernel_helper( inContext, outProgram, outKernel, lineCount, lines, kernelName ) )
|
|
|
{
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
error = get_max_common_work_group_size( inContext, *outKernel, threads[0], &localThreads[0] );
|
|
|
test_error( error, "Unable to get work group size to use" );
|
|
|
|
|
|
streams[0] = clCreateBuffer(inContext, CL_MEM_READ_WRITE,
|
|
|
sizeof(cl_float) * 1000, NULL, &error);
|
|
|
test_error( error, "Creating test array failed" );
|
|
|
streams[1] = clCreateBuffer(inContext, CL_MEM_READ_WRITE,
|
|
|
sizeof(cl_int) * 1000, NULL, &error);
|
|
|
test_error( error, "Creating test array failed" );
|
|
|
|
|
|
/* Set the arguments */
|
|
|
error = clSetKernelArg( *outKernel, 0, sizeof( streams[0] ), &streams[0] );
|
|
|
test_error( error, "Unable to set kernel arguments" );
|
|
|
error = clSetKernelArg( *outKernel, 1, sizeof( streams[1] ), &streams[1] );
|
|
|
test_error( error, "Unable to set kernel arguments" );
|
|
|
|
|
|
error = clEnqueueNDRangeKernel(inQueue, *outKernel, 1, NULL, threads, localThreads, 0, NULL, outEvent);
|
|
|
test_error( error, "Unable to execute test kernel" );
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
#define SETUP_EVENT( c, q ) \
|
|
|
clProgramWrapper program; \
|
|
|
clKernelWrapper kernel; \
|
|
|
clMemWrapper streams[2]; \
|
|
|
clEventWrapper event; \
|
|
|
int error; \
|
|
|
if( create_and_execute_kernel( c, q, &program, &kernel, &streams[0], 1, sample_long_test_kernel, "sample_test", &event ) ) return -1;
|
|
|
|
|
|
#define FINISH_EVENT(_q) clFinish(_q)
|
|
|
|
|
|
const char *IGetStatusString( cl_int status )
|
|
|
{
|
|
|
static char tempString[ 128 ];
|
|
|
switch( status )
|
|
|
{
|
|
|
case CL_COMPLETE: return "CL_COMPLETE";
|
|
|
case CL_RUNNING: return "CL_RUNNING";
|
|
|
case CL_QUEUED: return "CL_QUEUED";
|
|
|
case CL_SUBMITTED: return "CL_SUBMITTED";
|
|
|
default:
|
|
|
sprintf( tempString, "<unknown: %d>", (int)status );
|
|
|
return tempString;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* Note: tests clGetEventStatus and clReleaseEvent (implicitly) */
|
|
|
int test_event_get_execute_status( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
|
|
{
|
|
|
cl_int status;
|
|
|
SETUP_EVENT( context, queue );
|
|
|
|
|
|
/* Now wait for it to be done */
|
|
|
error = clWaitForEvents( 1, &event );
|
|
|
test_error( error, "Unable to wait for event" );
|
|
|
|
|
|
error = clGetEventInfo( event, CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status ), &status, NULL );
|
|
|
test_error( error, "Calling clGetEventStatus to wait for event completion failed" );
|
|
|
if( status != CL_COMPLETE )
|
|
|
{
|
|
|
log_error( "ERROR: Incorrect status returned from clGetErrorStatus after event complete (%d:%s)\n", status, IGetStatusString( status ) );
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
FINISH_EVENT(queue);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int test_event_get_info( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
|
|
{
|
|
|
SETUP_EVENT( context, queue );
|
|
|
|
|
|
/* Verify parameters of clGetEventInfo not already tested by other tests */
|
|
|
cl_command_queue otherQueue;
|
|
|
size_t size;
|
|
|
|
|
|
error = clGetEventInfo( event, CL_EVENT_COMMAND_QUEUE, sizeof( otherQueue ), &otherQueue, &size );
|
|
|
test_error( error, "Unable to get event info!" );
|
|
|
// We can not check if this is the right queue because this is an opaque object.
|
|
|
if( size != sizeof( queue ) )
|
|
|
{
|
|
|
log_error( "ERROR: Returned command queue size does not validate (expected %d, got %d)\n", (int)sizeof( queue ), (int)size );
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
cl_command_type type;
|
|
|
error = clGetEventInfo( event, CL_EVENT_COMMAND_TYPE, sizeof( type ), &type, &size );
|
|
|
test_error( error, "Unable to get event info!" );
|
|
|
if( type != CL_COMMAND_NDRANGE_KERNEL )
|
|
|
{
|
|
|
log_error( "ERROR: Returned command type does not validate (expected %d, got %d)\n", (int)CL_COMMAND_NDRANGE_KERNEL, (int)type );
|
|
|
return -1;
|
|
|
}
|
|
|
if( size != sizeof( type ) )
|
|
|
{
|
|
|
log_error( "ERROR: Returned command type size does not validate (expected %d, got %d)\n", (int)sizeof( type ), (int)size );
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
cl_uint count;
|
|
|
error = clGetEventInfo( event, CL_EVENT_REFERENCE_COUNT, sizeof( count ), &count, &size );
|
|
|
test_error( error, "Unable to get event info for CL_EVENT_REFERENCE_COUNT!" );
|
|
|
if( size != sizeof( count ) )
|
|
|
{
|
|
|
log_error( "ERROR: Returned command type size does not validate (expected %d, got %d)\n", (int)sizeof( type ), (int)size );
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
cl_context testCtx;
|
|
|
error = clGetEventInfo( event, CL_EVENT_CONTEXT, sizeof( testCtx ), &testCtx, &size );
|
|
|
test_error( error, "Unable to get event context info!" );
|
|
|
if( size != sizeof( context ) )
|
|
|
{
|
|
|
log_error( "ERROR: Returned context size does not validate (expected %d, got %d)\n", (int)sizeof( context ), (int)size );
|
|
|
return -1;
|
|
|
}
|
|
|
if( testCtx != context )
|
|
|
{
|
|
|
log_error( "ERROR: Returned context does not match (expected %p, got %p)\n", (void *)context, (void *)testCtx );
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
FINISH_EVENT(queue);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int test_event_get_write_array_status( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
|
|
{
|
|
|
cl_mem stream;
|
|
|
cl_float testArray[ 1024 * 32 ];
|
|
|
cl_event event;
|
|
|
int error;
|
|
|
cl_int status;
|
|
|
|
|
|
|
|
|
stream = clCreateBuffer(context, CL_MEM_READ_WRITE,
|
|
|
sizeof(cl_float) * 1024 * 32, NULL, &error);
|
|
|
test_error( error, "Creating test array failed" );
|
|
|
|
|
|
error = clEnqueueWriteBuffer(queue, stream, CL_FALSE, 0, sizeof(cl_float)*1024*32, (void *)testArray, 0, NULL, &event);
|
|
|
test_error( error, "Unable to set testing kernel data" );
|
|
|
|
|
|
/* Now wait for it to be done */
|
|
|
error = clWaitForEvents( 1, &event );
|
|
|
test_error( error, "Unable to wait for event" );
|
|
|
|
|
|
error = clGetEventInfo( event, CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status ), &status, NULL );
|
|
|
test_error( error, "Calling clGetEventStatus to wait for event completion failed" );
|
|
|
if( status != CL_COMPLETE )
|
|
|
{
|
|
|
log_error( "ERROR: Incorrect status returned from clGetErrorStatus after array write complete (%d:%s)\n", status, IGetStatusString( status ) );
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
|
|
|
clReleaseMemObject( stream );
|
|
|
clReleaseEvent( event );
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int test_event_get_read_array_status( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
|
|
{
|
|
|
cl_mem stream;
|
|
|
cl_float testArray[ 1024 * 32 ];
|
|
|
cl_event event;
|
|
|
int error;
|
|
|
cl_int status;
|
|
|
|
|
|
|
|
|
stream = clCreateBuffer(context, CL_MEM_READ_WRITE,
|
|
|
sizeof(cl_float) * 1024 * 32, NULL, &error);
|
|
|
test_error( error, "Creating test array failed" );
|
|
|
|
|
|
error = clEnqueueReadBuffer(queue, stream, CL_FALSE, 0, sizeof(cl_float)*1024*32, (void *)testArray, 0, NULL, &event);
|
|
|
test_error( error, "Unable to get testing kernel data" );
|
|
|
|
|
|
|
|
|
/* It should still be running... */
|
|
|
error = clGetEventInfo( event, CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status ), &status, NULL );
|
|
|
test_error( error, "Calling clGetEventStatus didn't work!" );
|
|
|
|
|
|
if( status != CL_RUNNING && status != CL_QUEUED && status != CL_SUBMITTED && status != CL_COMPLETE)
|
|
|
{
|
|
|
log_error( "ERROR: Incorrect status returned from clGetErrorStatus during array read (%d:%s)\n", status, IGetStatusString( status ) );
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
/* Now wait for it to be done */
|
|
|
error = clWaitForEvents( 1, &event );
|
|
|
test_error( error, "Unable to wait for event" );
|
|
|
|
|
|
error = clGetEventInfo( event, CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status ), &status, NULL );
|
|
|
test_error( error, "Calling clGetEventStatus to wait for event completion failed" );
|
|
|
if( status != CL_COMPLETE )
|
|
|
{
|
|
|
log_error( "ERROR: Incorrect status returned from clGetErrorStatus after array read complete (%d:%s)\n", status, IGetStatusString( status ) );
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
|
|
|
clReleaseMemObject( stream );
|
|
|
clReleaseEvent( event );
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
/* clGetEventStatus not implemented yet */
|
|
|
|
|
|
int test_event_wait_for_execute( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
|
|
{
|
|
|
cl_int status;
|
|
|
SETUP_EVENT( context, queue );
|
|
|
|
|
|
/* Now we wait for it to be done, then test the status again */
|
|
|
error = clWaitForEvents( 1, &event );
|
|
|
test_error( error, "Unable to wait for execute event" );
|
|
|
|
|
|
/* Make sure it worked */
|
|
|
error = clGetEventInfo( event, CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status ), &status, NULL );
|
|
|
test_error( error, "Calling clGetEventStatus didn't work!" );
|
|
|
if( status != CL_COMPLETE )
|
|
|
{
|
|
|
log_error( "ERROR: Incorrect status returned from clGetErrorStatus after event complete (%d:%s)\n", status, IGetStatusString( status ) );
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
FINISH_EVENT(queue);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int test_event_wait_for_array( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
|
|
{
|
|
|
cl_mem streams[2];
|
|
|
cl_float readArray[ 1024 * 32 ];
|
|
|
cl_float writeArray[ 1024 * 32 ];
|
|
|
cl_event events[2];
|
|
|
int error;
|
|
|
cl_int status;
|
|
|
|
|
|
|
|
|
streams[0] = clCreateBuffer(context, CL_MEM_READ_WRITE,
|
|
|
sizeof(cl_float) * 1024 * 32, NULL, &error);
|
|
|
test_error( error, "Creating test array failed" );
|
|
|
streams[1] = clCreateBuffer(context, CL_MEM_READ_WRITE,
|
|
|
sizeof(cl_float) * 1024 * 32, NULL, &error);
|
|
|
test_error( error, "Creating test array failed" );
|
|
|
|
|
|
error = clEnqueueReadBuffer(queue, streams[0], CL_FALSE, 0, sizeof(cl_float)*1024*32, (void *)readArray, 0, NULL, &events[0]);
|
|
|
test_error( error, "Unable to read testing kernel data" );
|
|
|
|
|
|
error = clEnqueueWriteBuffer(queue, streams[1], CL_FALSE, 0, sizeof(cl_float)*1024*32, (void *)writeArray, 0, NULL, &events[1]);
|
|
|
test_error( error, "Unable to write testing kernel data" );
|
|
|
|
|
|
/* Both should still be running */
|
|
|
error = clGetEventInfo( events[0], CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status ), &status, NULL );
|
|
|
test_error( error, "Calling clGetEventStatus didn't work!" );
|
|
|
if( status != CL_RUNNING && status != CL_QUEUED && status != CL_SUBMITTED && status != CL_COMPLETE)
|
|
|
{
|
|
|
log_error( "ERROR: Incorrect status returned from clGetErrorStatus during array read (%d:%s)\n", status, IGetStatusString( status ) );
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
error = clGetEventInfo( events[1], CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status ), &status, NULL );
|
|
|
test_error( error, "Calling clGetEventStatus didn't work!" );
|
|
|
if( status != CL_RUNNING && status != CL_QUEUED && status != CL_SUBMITTED && status != CL_COMPLETE)
|
|
|
{
|
|
|
log_error( "ERROR: Incorrect status returned from clGetErrorStatus during array write (%d:%s)\n", status, IGetStatusString( status ) );
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
/* Now try waiting for both */
|
|
|
error = clWaitForEvents( 2, events );
|
|
|
test_error( error, "Unable to wait for array events" );
|
|
|
|
|
|
/* Double check status on both */
|
|
|
error = clGetEventInfo( events[0], CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status ), &status, NULL );
|
|
|
test_error( error, "Calling clGetEventStatus didn't work!" );
|
|
|
if( status != CL_COMPLETE )
|
|
|
{
|
|
|
log_error( "ERROR: Incorrect status returned from clGetErrorStatus after array read complete (%d:%s)\n", status, IGetStatusString( status ) );
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
error = clGetEventInfo( events[1], CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status ), &status, NULL );
|
|
|
test_error( error, "Calling clGetEventStatus didn't work!" );
|
|
|
if( status != CL_COMPLETE )
|
|
|
{
|
|
|
log_error( "ERROR: Incorrect status returned from clGetErrorStatus after array write complete (%d:%s)\n", status, IGetStatusString( status ) );
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
clReleaseMemObject( streams[0] );
|
|
|
clReleaseMemObject( streams[1] );
|
|
|
clReleaseEvent( events[0] );
|
|
|
clReleaseEvent( events[1] );
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int test_event_flush( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
|
|
{
|
|
|
int loopCount = 0;
|
|
|
cl_int status;
|
|
|
SETUP_EVENT( context, queue );
|
|
|
|
|
|
/* Now flush. Note that we can't guarantee this actually lets the op finish, but we can guarantee it's no longer queued */
|
|
|
error = clFlush( queue );
|
|
|
test_error( error, "Unable to flush events" );
|
|
|
|
|
|
/* Make sure it worked */
|
|
|
while (1) {
|
|
|
error = clGetEventInfo( event, CL_EVENT_COMMAND_EXECUTION_STATUS,
|
|
|
sizeof( status ), &status, NULL );
|
|
|
test_error( error, "Calling clGetEventStatus didn't work!" );
|
|
|
|
|
|
if( status != CL_QUEUED )
|
|
|
break;
|
|
|
|
|
|
#if ! defined( _WIN32 )
|
|
|
sleep(1); // give it some time here.
|
|
|
#else // _WIN32
|
|
|
Sleep(1000);
|
|
|
#endif
|
|
|
++loopCount;
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
CL_QUEUED (command has been enqueued in the command-queue),
|
|
|
CL_SUBMITTED (enqueued command has been submitted by the host to the device associated with the command-queue),
|
|
|
CL_RUNNING (device is currently executing this command),
|
|
|
CL_COMPLETE (the command has completed), or
|
|
|
Error code given by a negative integer value. (command was abnormally terminated – this may be caused by a bad memory access etc.).
|
|
|
*/
|
|
|
if(status != CL_COMPLETE && status != CL_SUBMITTED &&
|
|
|
status != CL_RUNNING && status != CL_COMPLETE)
|
|
|
{
|
|
|
log_error( "ERROR: Incorrect status returned from clGetErrorStatus after event flush (%d:%s)\n", status, IGetStatusString( status ) );
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
/* Now wait */
|
|
|
error = clFinish( queue );
|
|
|
test_error( error, "Unable to finish events" );
|
|
|
|
|
|
FINISH_EVENT(queue);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
|
|
|
int test_event_finish_execute( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
|
|
{
|
|
|
cl_int status;
|
|
|
SETUP_EVENT( context, queue );
|
|
|
|
|
|
/* Now flush and finish all ops */
|
|
|
error = clFinish( queue );
|
|
|
test_error( error, "Unable to finish all events" );
|
|
|
|
|
|
/* Make sure it worked */
|
|
|
error = clGetEventInfo( event, CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status ), &status, NULL );
|
|
|
test_error( error, "Calling clGetEventStatus didn't work!" );
|
|
|
if( status != CL_COMPLETE )
|
|
|
{
|
|
|
log_error( "ERROR: Incorrect status returned from clGetErrorStatus after event complete (%d:%s)\n", status, IGetStatusString( status ) );
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
FINISH_EVENT(queue);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int test_event_finish_array( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
|
|
{
|
|
|
cl_mem streams[2];
|
|
|
cl_float readArray[ 1024 * 32 ];
|
|
|
cl_float writeArray[ 1024 * 32 ];
|
|
|
cl_event events[2];
|
|
|
int error;
|
|
|
cl_int status;
|
|
|
|
|
|
|
|
|
streams[0] = clCreateBuffer(context, CL_MEM_READ_WRITE,
|
|
|
sizeof(cl_float) * 1024 * 32, NULL, &error);
|
|
|
test_error( error, "Creating test array failed" );
|
|
|
streams[1] = clCreateBuffer(context, CL_MEM_READ_WRITE,
|
|
|
sizeof(cl_float) * 1024 * 32, NULL, &error);
|
|
|
test_error( error, "Creating test array failed" );
|
|
|
|
|
|
error = clEnqueueReadBuffer(queue, streams[0], CL_FALSE, 0, sizeof(cl_float)*1024*32, (void *)readArray, 0, NULL, &events[0]);
|
|
|
test_error( error, "Unable to read testing kernel data" );
|
|
|
|
|
|
error = clEnqueueWriteBuffer(queue, streams[1], CL_FALSE, 0, sizeof(cl_float)*1024*32, (void *)writeArray, 0, NULL, &events[1]);
|
|
|
test_error( error, "Unable to write testing kernel data" );
|
|
|
|
|
|
/* Both should still be running */
|
|
|
error = clGetEventInfo( events[0], CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status ), &status, NULL );
|
|
|
test_error( error, "Calling clGetEventStatus didn't work!" );
|
|
|
if( status != CL_RUNNING && status != CL_QUEUED && status != CL_SUBMITTED && status != CL_COMPLETE)
|
|
|
{
|
|
|
log_error( "ERROR: Incorrect status returned from clGetErrorStatus during array read (%d:%s)\n", status, IGetStatusString( status ) );
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
error = clGetEventInfo( events[1], CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status ), &status, NULL );
|
|
|
test_error( error, "Calling clGetEventStatus didn't work!" );
|
|
|
if( status != CL_RUNNING && status != CL_QUEUED && status != CL_SUBMITTED && status != CL_COMPLETE)
|
|
|
{
|
|
|
log_error( "ERROR: Incorrect status returned from clGetErrorStatus during array write (%d:%s)\n", status, IGetStatusString( status ) );
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
/* Now try finishing all ops */
|
|
|
error = clFinish( queue );
|
|
|
test_error( error, "Unable to finish all events" );
|
|
|
|
|
|
/* Double check status on both */
|
|
|
error = clGetEventInfo( events[0], CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status ), &status, NULL );
|
|
|
test_error( error, "Calling clGetEventStatus didn't work!" );
|
|
|
if( status != CL_COMPLETE )
|
|
|
{
|
|
|
log_error( "ERROR: Incorrect status returned from clGetErrorStatus after array read complete (%d:%s)\n", status, IGetStatusString( status ) );
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
error = clGetEventInfo( events[1], CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status ), &status, NULL );
|
|
|
test_error( error, "Calling clGetEventStatus didn't work!" );
|
|
|
if( status != CL_COMPLETE )
|
|
|
{
|
|
|
log_error( "ERROR: Incorrect status returned from clGetErrorStatus after array write complete (%d:%s)\n", status, IGetStatusString( status ) );
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
clReleaseMemObject( streams[0] );
|
|
|
clReleaseMemObject( streams[1] );
|
|
|
clReleaseEvent( events[0] );
|
|
|
clReleaseEvent( events[1] );
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
|
|
|
#define NUM_EVENT_RUNS 100
|
|
|
|
|
|
int test_event_release_before_done( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
|
|
{
|
|
|
// Create a kernel to run
|
|
|
clProgramWrapper program;
|
|
|
clKernelWrapper kernel[NUM_EVENT_RUNS];
|
|
|
size_t threads[1] = { 1000 };
|
|
|
cl_event events[NUM_EVENT_RUNS];
|
|
|
cl_int status;
|
|
|
clMemWrapper streams[NUM_EVENT_RUNS][2];
|
|
|
int error, i;
|
|
|
|
|
|
// Create a kernel
|
|
|
if( create_single_kernel_helper( context, &program, &kernel[0], 1, sample_long_test_kernel, "sample_test" ) )
|
|
|
{
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
for( i = 1; i < NUM_EVENT_RUNS; i++ ) {
|
|
|
kernel[i] = clCreateKernel(program, "sample_test", &error);
|
|
|
test_error(error, "Unable to create kernel");
|
|
|
}
|
|
|
|
|
|
error = get_max_common_work_group_size( context, kernel[0], 1024, &threads[0] );
|
|
|
test_error( error, "Unable to get work group size to use" );
|
|
|
|
|
|
// Create a set of streams to use as arguments
|
|
|
for( i = 0; i < NUM_EVENT_RUNS; i++ )
|
|
|
{
|
|
|
streams[i][0] =
|
|
|
clCreateBuffer(context, CL_MEM_READ_WRITE,
|
|
|
sizeof(cl_float) * threads[0], NULL, &error);
|
|
|
streams[i][1] =
|
|
|
clCreateBuffer(context, CL_MEM_READ_WRITE,
|
|
|
sizeof(cl_int) * threads[0], NULL, &error);
|
|
|
if( ( streams[i][0] == NULL ) || ( streams[i][1] == NULL ) )
|
|
|
{
|
|
|
log_error( "ERROR: Unable to allocate testing streams" );
|
|
|
return -1;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// Execute the kernels one by one, hopefully making sure they won't be done by the time we get to the end
|
|
|
for( i = 0; i < NUM_EVENT_RUNS; i++ )
|
|
|
{
|
|
|
error = clSetKernelArg( kernel[i], 0, sizeof( cl_mem ), &streams[i][0] );
|
|
|
error |= clSetKernelArg( kernel[i], 1, sizeof( cl_mem ), &streams[i][1] );
|
|
|
test_error( error, "Unable to set kernel arguments" );
|
|
|
|
|
|
error = clEnqueueNDRangeKernel( queue, kernel[i], 1, NULL, threads, threads, 0, NULL, &events[i]);
|
|
|
test_error( error, "Unable to execute test kernel" );
|
|
|
}
|
|
|
|
|
|
// Free all but the last event
|
|
|
for( i = 0; i < NUM_EVENT_RUNS - 1; i++ )
|
|
|
{
|
|
|
clReleaseEvent( events[ i ] );
|
|
|
}
|
|
|
|
|
|
// Get status on the last one, then free it
|
|
|
error = clGetEventInfo( events[ NUM_EVENT_RUNS - 1 ], CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status ), &status, NULL );
|
|
|
test_error( error, "Unable to get event status" );
|
|
|
|
|
|
clReleaseEvent( events[ NUM_EVENT_RUNS - 1 ] );
|
|
|
|
|
|
// Was the status still-running?
|
|
|
if( status == CL_COMPLETE )
|
|
|
{
|
|
|
log_info( "WARNING: Events completed before they could be released, so test is a null-op. Increase workload and try again." );
|
|
|
}
|
|
|
else if( status == CL_RUNNING || status == CL_QUEUED || status == CL_SUBMITTED )
|
|
|
{
|
|
|
log_info( "Note: Event status was running or queued when released, so test was good.\n" );
|
|
|
}
|
|
|
|
|
|
// If we didn't crash by now, the test succeeded
|
|
|
clFinish( queue );
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int test_event_enqueue_marker( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
|
|
{
|
|
|
cl_int status;
|
|
|
SETUP_EVENT( context, queue );
|
|
|
|
|
|
/* Now we queue a marker and wait for that, which--since it queues afterwards--should guarantee the execute finishes too */
|
|
|
clEventWrapper markerEvent;
|
|
|
//error = clEnqueueMarker( queue, &markerEvent );
|
|
|
|
|
|
#ifdef CL_VERSION_1_2
|
|
|
error = clEnqueueMarkerWithWaitList(queue, 0, NULL, &markerEvent );
|
|
|
#else
|
|
|
error = clEnqueueMarker( queue, &markerEvent );
|
|
|
#endif
|
|
|
test_error( error, "Unable to queue marker" );
|
|
|
/* Now we wait for it to be done, then test the status again */
|
|
|
error = clWaitForEvents( 1, &markerEvent );
|
|
|
test_error( error, "Unable to wait for marker event" );
|
|
|
|
|
|
/* Check the status of the first event */
|
|
|
error = clGetEventInfo( event, CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status ), &status, NULL );
|
|
|
test_error( error, "Calling clGetEventInfo didn't work!" );
|
|
|
if( status != CL_COMPLETE )
|
|
|
{
|
|
|
log_error( "ERROR: Incorrect status returned from clGetEventInfo after event complete (%d:%s)\n", status, IGetStatusString( status ) );
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
FINISH_EVENT(queue);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
#ifdef CL_VERSION_1_2
|
|
|
int test_event_enqueue_marker_with_event_list( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
|
|
{
|
|
|
|
|
|
cl_int status;
|
|
|
SETUP_EVENT( context, queue );
|
|
|
cl_event event_list[3]={ NULL, NULL, NULL};
|
|
|
|
|
|
size_t threads[1] = { 10 }, localThreads[1]={1};
|
|
|
cl_uint event_count=2;
|
|
|
error= clEnqueueNDRangeKernel( queue,kernel,1,NULL, threads, localThreads, 0, NULL, &event_list[0]);
|
|
|
test_error( error, " clEnqueueMarkerWithWaitList 1 " );
|
|
|
|
|
|
error= clEnqueueNDRangeKernel( queue,kernel,1,NULL, threads, localThreads, 0, NULL, &event_list[1]);
|
|
|
test_error( error, " clEnqueueMarkerWithWaitList 2" );
|
|
|
|
|
|
error= clEnqueueNDRangeKernel( queue,kernel,1,NULL, threads, localThreads, 0, NULL, NULL);
|
|
|
test_error( error, " clEnqueueMarkerWithWaitList 3" );
|
|
|
|
|
|
// test the case event returned
|
|
|
error =clEnqueueMarkerWithWaitList(queue, event_count, event_list, &event_list[2]);
|
|
|
test_error( error, " clEnqueueMarkerWithWaitList " );
|
|
|
|
|
|
error = clReleaseEvent(event_list[0]);
|
|
|
error |= clReleaseEvent(event_list[1]);
|
|
|
test_error( error, "clReleaseEvent" );
|
|
|
|
|
|
error= clEnqueueNDRangeKernel( queue,kernel,1,NULL, threads, localThreads, 0, NULL, &event_list[0]);
|
|
|
test_error( error, " clEnqueueMarkerWithWaitList 1 -1 " );
|
|
|
|
|
|
error= clEnqueueNDRangeKernel( queue,kernel,1,NULL, threads, localThreads, 0, NULL, &event_list[1]);
|
|
|
test_error( error, " clEnqueueMarkerWithWaitList 2-2" );
|
|
|
|
|
|
// test the case event =NULL, caused [CL_INVALID_VALUE] : OpenCL Error : clEnqueueMarkerWithWaitList failed: event is a NULL value
|
|
|
error =clEnqueueMarkerWithWaitList(queue, event_count, event_list, NULL);
|
|
|
test_error( error, " clEnqueueMarkerWithWaitList " );
|
|
|
|
|
|
error = clReleaseEvent(event_list[0]);
|
|
|
error |= clReleaseEvent(event_list[1]);
|
|
|
error |= clReleaseEvent(event_list[2]);
|
|
|
test_error( error, "clReleaseEvent" );
|
|
|
|
|
|
FINISH_EVENT(queue);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int test_event_enqueue_barrier_with_event_list( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
|
|
{
|
|
|
|
|
|
cl_int status;
|
|
|
SETUP_EVENT( context, queue );
|
|
|
cl_event event_list[3]={ NULL, NULL, NULL};
|
|
|
|
|
|
size_t threads[1] = { 10 }, localThreads[1]={1};
|
|
|
cl_uint event_count=2;
|
|
|
error= clEnqueueNDRangeKernel( queue,kernel,1,NULL, threads, localThreads, 0, NULL, &event_list[0]);
|
|
|
test_error( error, " clEnqueueBarrierWithWaitList 1 " );
|
|
|
|
|
|
error= clEnqueueNDRangeKernel( queue,kernel,1,NULL, threads, localThreads, 0, NULL, &event_list[1]);
|
|
|
test_error( error, " clEnqueueBarrierWithWaitList 2" );
|
|
|
|
|
|
error= clEnqueueNDRangeKernel( queue,kernel,1,NULL, threads, localThreads, 0, NULL, NULL);
|
|
|
test_error( error, " clEnqueueBarrierWithWaitList 20" );
|
|
|
|
|
|
// test the case event returned
|
|
|
error =clEnqueueBarrierWithWaitList(queue, event_count, event_list, &event_list[2]);
|
|
|
test_error( error, " clEnqueueBarrierWithWaitList " );
|
|
|
|
|
|
clReleaseEvent(event_list[0]);
|
|
|
clReleaseEvent(event_list[1]);
|
|
|
|
|
|
error= clEnqueueNDRangeKernel( queue,kernel,1,NULL, threads, localThreads, 0, NULL, &event_list[0]);
|
|
|
test_error( error, " clEnqueueBarrierWithWaitList 1 " );
|
|
|
|
|
|
error= clEnqueueNDRangeKernel( queue,kernel,1,NULL, threads, localThreads, 0, NULL, &event_list[1]);
|
|
|
test_error( error, " clEnqueueBarrierWithWaitList 2" );
|
|
|
|
|
|
// test the case event =NULL, caused [CL_INVALID_VALUE] : OpenCL Error : clEnqueueMarkerWithWaitList failed: event is a NULL value
|
|
|
error = clEnqueueBarrierWithWaitList(queue, event_count, event_list, NULL);
|
|
|
test_error( error, " clEnqueueBarrierWithWaitList " );
|
|
|
|
|
|
clReleaseEvent(event_list[0]);
|
|
|
clReleaseEvent(event_list[1]);
|
|
|
clReleaseEvent(event_list[2]);
|
|
|
|
|
|
FINISH_EVENT(queue);
|
|
|
return 0;
|
|
|
}
|
|
|
#endif
|