|
|
//
|
|
|
// 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)
|
|
|
{
|
|
|
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)
|
|
|
{
|
|
|
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
|