mirror of
https://github.com/KhronosGroup/OpenCL-CTS.git
synced 2026-03-19 06:09:01 +00:00
393 lines
15 KiB
C++
393 lines
15 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
|
|
|
|
static 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(device, context, test_queue, &action, false)) \
|
|
!= CL_SUCCESS) \
|
|
retVal++; \
|
|
clFinish(test_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(device, context, test_queue, &action, true)) \
|
|
!= CL_SUCCESS) \
|
|
retVal++; \
|
|
clFinish(test_queue); \
|
|
}
|
|
|
|
REGISTER_TEST(waitlists)
|
|
{
|
|
cl_int error;
|
|
int retVal = 0;
|
|
cl_command_queue_properties props = CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE;
|
|
|
|
if (!checkDeviceForQueueSupport(device, props))
|
|
{
|
|
log_info("WARNING: Device does not support out-of-order exec mode; "
|
|
"skipping test.\n");
|
|
return 0;
|
|
}
|
|
|
|
clCommandQueueWrapper test_queue =
|
|
clCreateCommandQueue(context, device, props, &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(device) == 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(device) == 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;
|
|
}
|