mirror of
https://github.com/KhronosGroup/OpenCL-CTS.git
synced 2026-03-19 14:09:03 +00:00
The maintenance of the conformance tests is moving to Github. This commit contains all the changes that have been done in Gitlab since the first public release of the conformance tests. Signed-off-by: Kevin Petit <kevin.petit@arm.com>
323 lines
14 KiB
C++
323 lines
14 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"
|
|
#include "action_classes.h"
|
|
|
|
|
|
extern const char *IGetStatusString( cl_int status );
|
|
|
|
#define PRINT_OPS 0
|
|
|
|
int test_waitlist( cl_device_id device, cl_context context, cl_command_queue queue, Action *actionToTest, bool multiple )
|
|
{
|
|
NDRangeKernelAction actions[ 2 ];
|
|
clEventWrapper events[ 3 ];
|
|
cl_int status[ 3 ];
|
|
cl_int error;
|
|
|
|
if (multiple)
|
|
log_info("\tExecuting reference event 0, then reference event 1 with reference event 0 in its waitlist, then test event 2 with reference events 0 and 1 in its waitlist.\n");
|
|
else
|
|
log_info("\tExecuting reference event 0, then test event 2 with reference event 0 in its waitlist.\n");
|
|
|
|
// Set up the first base action to wait against
|
|
error = actions[ 0 ].Setup( device, context, queue );
|
|
test_error( error, "Unable to setup base event to wait against" );
|
|
|
|
if( multiple )
|
|
{
|
|
// Set up a second event to wait against
|
|
error = actions[ 1 ].Setup( device, context, queue );
|
|
test_error( error, "Unable to setup second base event to wait against" );
|
|
}
|
|
|
|
// Now set up the actual action to test
|
|
error = actionToTest->Setup( device, context, queue );
|
|
test_error( error, "Unable to set up test event" );
|
|
|
|
// Execute all events now
|
|
if (PRINT_OPS) log_info("\tExecuting action 0...\n");
|
|
error = actions[ 0 ].Execute( queue, 0, NULL, &events[ 0 ] );
|
|
test_error( error, "Unable to execute first event" );
|
|
|
|
if( multiple )
|
|
{
|
|
if (PRINT_OPS) log_info("\tExecuting action 1...\n");
|
|
error = actions[ 1 ].Execute( queue, 1, &events[0], &events[ 1 ] );
|
|
test_error( error, "Unable to execute second event" );
|
|
}
|
|
|
|
// Sanity check
|
|
if( multiple ) {
|
|
if (PRINT_OPS) log_info("\tChecking status of action 1...\n");
|
|
error = clGetEventInfo( events[ 1 ], CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status[ 1 ] ), &status[ 1 ], NULL );
|
|
test_error( error, "Unable to get event status" );
|
|
}
|
|
if (PRINT_OPS) log_info("\tChecking status of action 0...\n");
|
|
error = clGetEventInfo( events[ 0 ], CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status[ 0 ] ), &status[ 0 ], NULL );
|
|
test_error( error, "Unable to get event status" );
|
|
|
|
log_info("\t\tEvent status after starting reference events: reference event 0: %s, reference event 1: %s, test event 2: %s.\n",
|
|
IGetStatusString( status[ 0 ] ), (multiple ? IGetStatusString( status[ 1 ] ) : "N/A"), "N/A");
|
|
|
|
if( ( status[ 0 ] == CL_COMPLETE ) || ( multiple && status[ 1 ] == CL_COMPLETE ) )
|
|
{
|
|
log_info( "WARNING: Reference event(s) already completed before we could execute test event! Possible that the reference event blocked (implicitly passing)\n" );
|
|
return 0;
|
|
}
|
|
|
|
if (PRINT_OPS) log_info("\tExecuting action to test...\n");
|
|
error = actionToTest->Execute( queue, ( multiple ) ? 2 : 1, &events[ 0 ], &events[ 2 ] );
|
|
test_error( error, "Unable to execute test event" );
|
|
|
|
// Hopefully, the first event is still running
|
|
if (PRINT_OPS) log_info("\tChecking status of action to test 2...\n");
|
|
error = clGetEventInfo( events[ 2 ], CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status[ 2 ] ), &status[ 2 ], NULL );
|
|
test_error( error, "Unable to get event status" );
|
|
if( multiple ) {
|
|
if (PRINT_OPS) log_info("\tChecking status of action 1...\n");
|
|
error = clGetEventInfo( events[ 1 ], CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status[ 1 ] ), &status[ 1 ], NULL );
|
|
test_error( error, "Unable to get event status" );
|
|
}
|
|
if (PRINT_OPS) log_info("\tChecking status of action 0...\n");
|
|
error = clGetEventInfo( events[ 0 ], CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status[ 0 ] ), &status[ 0 ], NULL );
|
|
test_error( error, "Unable to get event status" );
|
|
|
|
log_info("\t\tEvent status after starting test event: reference event 0: %s, reference event 1: %s, test event 2: %s.\n",
|
|
IGetStatusString( status[ 0 ] ), (multiple ? IGetStatusString( status[ 1 ] ) : "N/A"), IGetStatusString( status[ 2 ] ));
|
|
|
|
if( multiple )
|
|
{
|
|
if( status[ 0 ] == CL_COMPLETE && status[ 1 ] == CL_COMPLETE )
|
|
{
|
|
log_info( "WARNING: Both events completed, so unable to test further (implicitly passing).\n" );
|
|
clFinish( queue );
|
|
return 0;
|
|
}
|
|
|
|
if(status[1] == CL_COMPLETE && status[0] != CL_COMPLETE)
|
|
{
|
|
log_error("ERROR: Test failed because the second wait event is complete and the first is not.(status: 0: %s and 1: %s)\n", IGetStatusString( status[ 0 ] ), IGetStatusString( status[ 1 ] ) );
|
|
clFinish( queue );
|
|
return -1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( status[ 0 ] == CL_COMPLETE )
|
|
{
|
|
log_info( "WARNING: Reference event completed, so unable to test further (implicitly passing).\n" );
|
|
clFinish( queue );
|
|
return 0;
|
|
}
|
|
if( status[ 0 ] != CL_RUNNING && status[ 0 ] != CL_QUEUED && status[ 0 ] != CL_SUBMITTED )
|
|
{
|
|
log_error( "ERROR: Test failed because first wait event is not currently running, queued, or submitted! (status: 0: %s)\n", IGetStatusString( status[ 0 ] ) );
|
|
clFinish( queue );
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
if( status[ 2 ] != CL_QUEUED && status[ 2 ] != CL_SUBMITTED )
|
|
{
|
|
log_error( "ERROR: Test event is not waiting to run! (status: 2: %s)\n", IGetStatusString( status[ 2 ] ) );
|
|
clFinish( queue );
|
|
return -1;
|
|
}
|
|
|
|
// Now wait for the first reference event
|
|
if (PRINT_OPS) log_info("\tWaiting for action 1 to finish...\n");
|
|
error = clWaitForEvents( 1, &events[ 0 ] );
|
|
test_error( error, "Unable to wait for reference event" );
|
|
|
|
// Grab statuses again
|
|
if (PRINT_OPS) log_info("\tChecking status of action to test 2...\n");
|
|
error = clGetEventInfo( events[ 2 ], CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status[ 2 ] ), &status[ 2 ], NULL );
|
|
test_error( error, "Unable to get event status" );
|
|
if( multiple ) {
|
|
if (PRINT_OPS) log_info("\tChecking status of action 1...\n");
|
|
error = clGetEventInfo( events[ 1 ], CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status[ 1 ] ), &status[ 1 ], NULL );
|
|
test_error( error, "Unable to get event status" );
|
|
}
|
|
if (PRINT_OPS) log_info("\tChecking status of action 0...\n");
|
|
error = clGetEventInfo( events[ 0 ], CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status[ 0 ] ), &status[ 0 ], NULL );
|
|
test_error( error, "Unable to get event status" );
|
|
|
|
log_info("\t\tEvent status after waiting for reference event 0: reference event 0: %s, reference event 1: %s, test event 2: %s.\n",
|
|
IGetStatusString( status[ 0 ] ), (multiple ? IGetStatusString( status[ 1 ] ) : "N/A"), IGetStatusString( status[ 2 ] ));
|
|
|
|
// Sanity
|
|
if( status[ 0 ] != CL_COMPLETE )
|
|
{
|
|
log_error( "ERROR: Waited for first event but it's not complete (status: 0: %s)\n", IGetStatusString( status[ 0 ] ) );
|
|
clFinish( queue );
|
|
return -1;
|
|
}
|
|
|
|
// If we're multiple, and the second event isn't complete, then our test event should still be queued
|
|
if( multiple && status[ 1 ] != CL_COMPLETE )
|
|
{
|
|
if( status[ 1 ] == CL_RUNNING && status[ 2 ] == CL_RUNNING ) {
|
|
log_error("ERROR: Test event and second event are both running.\n");
|
|
clFinish( queue );
|
|
return -1;
|
|
}
|
|
if( status[ 2 ] != CL_QUEUED && status[ 2 ] != CL_SUBMITTED )
|
|
{
|
|
log_error( "ERROR: Test event did not wait for second event before starting! (status of ref: 1: %s, of test: 2: %s)\n", IGetStatusString( status[ 1 ] ), IGetStatusString( status[ 2 ] ) );
|
|
clFinish( queue );
|
|
return -1;
|
|
}
|
|
|
|
// Now wait for second event to complete, too
|
|
if (PRINT_OPS) log_info("\tWaiting for action 1 to finish...\n");
|
|
error = clWaitForEvents( 1, &events[ 1 ] );
|
|
test_error( error, "Unable to wait for second reference event" );
|
|
|
|
// Grab statuses again
|
|
if (PRINT_OPS) log_info("\tChecking status of action to test 2...\n");
|
|
error = clGetEventInfo( events[ 2 ], CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status[ 2 ] ), &status[ 2 ], NULL );
|
|
test_error( error, "Unable to get event status" );
|
|
if( multiple ) {
|
|
if (PRINT_OPS) log_info("\tChecking status of action 1...\n");
|
|
error = clGetEventInfo( events[ 1 ], CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status[ 1 ] ), &status[ 1 ], NULL );
|
|
test_error( error, "Unable to get event status" );
|
|
}
|
|
if (PRINT_OPS) log_info("\tChecking status of action 0...\n");
|
|
error = clGetEventInfo( events[ 0 ], CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status[ 0 ] ), &status[ 0 ], NULL );
|
|
test_error( error, "Unable to get event status" );
|
|
|
|
log_info("\t\tEvent status after waiting for reference event 1: reference event 0: %s, reference event 1: %s, test event 2: %s.\n",
|
|
IGetStatusString( status[ 0 ] ), (multiple ? IGetStatusString( status[ 1 ] ) : "N/A"), IGetStatusString( status[ 2 ] ));
|
|
|
|
// Sanity
|
|
if( status[ 1 ] != CL_COMPLETE )
|
|
{
|
|
log_error( "ERROR: Waited for second reference event but it didn't complete (status: 1: %s)\n", IGetStatusString( status[ 1 ] ) );
|
|
clFinish( queue );
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
// At this point, the test event SHOULD be running, but if it completed, we consider it a pass
|
|
if( status[ 2 ] == CL_COMPLETE )
|
|
{
|
|
log_info( "WARNING: Test event already completed. Assumed valid.\n" );
|
|
clFinish( queue );
|
|
return 0;
|
|
}
|
|
if( status[ 2 ] != CL_RUNNING && status[ 2 ] != CL_SUBMITTED && status[ 2 ] != CL_QUEUED)
|
|
{
|
|
log_error( "ERROR: Second event did not start running after reference event(s) completed! (status: 2: %s)\n", IGetStatusString( status[ 2 ] ) );
|
|
clFinish( queue );
|
|
return -1;
|
|
}
|
|
|
|
// Wait for the test event, then return
|
|
if (PRINT_OPS) log_info("\tWaiting for action 2 to test to finish...\n");
|
|
error = clWaitForEvents( 1, &events[ 2 ] );
|
|
test_error( error, "Unable to wait for test event" );
|
|
|
|
error |= clGetEventInfo( events[ 2 ], CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status[ 2 ] ), &status[ 2 ], NULL );
|
|
test_error( error, "Unable to get event status" );
|
|
|
|
log_info("\t\tEvent status after waiting for test event: reference event 0: %s, reference event 1: %s, test event 2: %s.\n",
|
|
IGetStatusString( status[ 0 ] ), (multiple ? IGetStatusString( status[ 1 ] ) : "N/A"), IGetStatusString( status[ 2 ] ));
|
|
|
|
// Sanity
|
|
if( status[ 2 ] != CL_COMPLETE )
|
|
{
|
|
log_error( "ERROR: Test event didn't complete (status: 2: %s)\n", IGetStatusString( status[ 2 ] ) );
|
|
clFinish( queue );
|
|
return -1;
|
|
}
|
|
|
|
clFinish(queue);
|
|
return 0;
|
|
}
|
|
|
|
#define TEST_ACTION( name ) \
|
|
{ \
|
|
name##Action action; \
|
|
log_info( "-- Testing " #name " (waiting on 1 event)...\n" ); \
|
|
if( ( error = test_waitlist( deviceID, context, queue, &action, false ) ) != CL_SUCCESS ) \
|
|
retVal++; \
|
|
clFinish( queue ); \
|
|
} \
|
|
if( error == CL_SUCCESS ) /* Only run multiples test if single test passed */ \
|
|
{ \
|
|
name##Action action; \
|
|
log_info( "-- Testing " #name " (waiting on 2 events)...\n" ); \
|
|
if( ( error = test_waitlist( deviceID, context, queue, &action, true ) ) != CL_SUCCESS ) \
|
|
retVal++; \
|
|
clFinish( queue ); \
|
|
}
|
|
|
|
int test_waitlists( cl_device_id deviceID, cl_context context, cl_command_queue oldQueue, int num_elements )
|
|
{
|
|
cl_int error;
|
|
int retVal = 0;
|
|
|
|
if( !checkDeviceForQueueSupport( deviceID, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE ) )
|
|
{
|
|
log_info( "WARNING: Device does not support out-of-order exec mode; skipping test.\n" );
|
|
return 0;
|
|
}
|
|
|
|
clCommandQueueWrapper queue = clCreateCommandQueue( context, deviceID,
|
|
(cl_command_queue_properties)CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, &error );
|
|
test_error(error, "Unable to create out-of-order queue");
|
|
|
|
log_info( "\n" );
|
|
|
|
TEST_ACTION( NDRangeKernel )
|
|
|
|
TEST_ACTION( ReadBuffer )
|
|
TEST_ACTION( WriteBuffer )
|
|
TEST_ACTION( MapBuffer )
|
|
TEST_ACTION( UnmapBuffer )
|
|
|
|
if( checkForImageSupport( deviceID ) == CL_IMAGE_FORMAT_NOT_SUPPORTED )
|
|
{
|
|
log_info( "\nNote: device does not support images. Skipping remainder of waitlist tests...\n" );
|
|
}
|
|
else
|
|
{
|
|
TEST_ACTION( ReadImage2D )
|
|
TEST_ACTION( WriteImage2D )
|
|
TEST_ACTION( CopyImage2Dto2D )
|
|
TEST_ACTION( Copy2DImageToBuffer )
|
|
TEST_ACTION( CopyBufferTo2DImage )
|
|
TEST_ACTION( MapImage )
|
|
|
|
if( checkFor3DImageSupport( deviceID ) == CL_IMAGE_FORMAT_NOT_SUPPORTED )
|
|
log_info("Device does not support 3D images. Skipping remainder of waitlist tests...\n");
|
|
else
|
|
{
|
|
TEST_ACTION( ReadImage3D )
|
|
TEST_ACTION( WriteImage3D )
|
|
TEST_ACTION( CopyImage2Dto3D )
|
|
TEST_ACTION( CopyImage3Dto2D )
|
|
TEST_ACTION( CopyImage3Dto3D )
|
|
TEST_ACTION( Copy3DImageToBuffer )
|
|
TEST_ACTION( CopyBufferTo3DImage )
|
|
}
|
|
}
|
|
|
|
return retVal;
|
|
}
|
|
|