mirror of
https://github.com/KhronosGroup/OpenCL-CTS.git
synced 2026-03-19 06:09:01 +00:00
Semaphore test: Use blocking semaphores (#1675)
Semaphore spec has been updated to reflect the fact that semaphores will be in the appropriate - pending signal or pending wait - state when returning from clEnqueueSignalSemaphore or clEnqueueWaitSemaphore commands: KhronosGroup/OpenCL-Docs#882 Deleted the following tests to match the updated spec: semaphores_order_1 - Test calls EnqueueWaitSemaphore before calling EnqueueSignalSemaphore and expects this wait to succeed. This behavior is not compatible with the recent spec updates to semaphores. semaphores_order_2 & semaphores_order_3 - Calling clEnqueueSignalSemaphoresKHR with a dependency on a user event may cause the implementation to block until the user event is complete. This is unsafe usage of clEnqueueSignalSemaphoresKHR and may lead to deadlock. semaphores_invalid_command - This test checks for specific behavior when waiting on a semaphore in an invalid state. According to the spec, this is undefined behavior, and therefore cannot be tested directly. Co-authored-by: Joshua Kelly <joshkell@qti.qualcomm.com>
This commit is contained in:
committed by
GitHub
parent
4cb39b8c14
commit
9692380505
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// Copyright (c) 2017 The Khronos Group Inc.
|
// Copyright (c) 2023 The Khronos Group Inc.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
@@ -34,11 +34,7 @@ test_definition test_list[] = {
|
|||||||
ADD_TEST_VERSION(semaphores_multi_signal, Version(1, 2)),
|
ADD_TEST_VERSION(semaphores_multi_signal, Version(1, 2)),
|
||||||
ADD_TEST_VERSION(semaphores_multi_wait, Version(1, 2)),
|
ADD_TEST_VERSION(semaphores_multi_wait, Version(1, 2)),
|
||||||
ADD_TEST_VERSION(semaphores_queries, Version(1, 2)),
|
ADD_TEST_VERSION(semaphores_queries, Version(1, 2)),
|
||||||
ADD_TEST_VERSION(semaphores_order_1, Version(1, 2)),
|
|
||||||
ADD_TEST_VERSION(semaphores_order_2, Version(1, 2)),
|
|
||||||
ADD_TEST_VERSION(semaphores_order_3, Version(1, 2)),
|
|
||||||
ADD_TEST_VERSION(semaphores_import_export_fd, Version(1, 2)),
|
ADD_TEST_VERSION(semaphores_import_export_fd, Version(1, 2)),
|
||||||
ADD_TEST_VERSION(semaphores_invalid_command, Version(1, 2)),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const int test_num = ARRAY_SIZE(test_list);
|
const int test_num = ARRAY_SIZE(test_list);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// Copyright (c) 2017 The Khronos Group Inc.
|
// Copyright (c) 2023 The Khronos Group Inc.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
@@ -41,17 +41,7 @@ extern int test_semaphores_multi_wait(cl_device_id deviceID, cl_context context,
|
|||||||
cl_command_queue queue, int num_elements);
|
cl_command_queue queue, int num_elements);
|
||||||
extern int test_semaphores_queries(cl_device_id deviceID, cl_context context,
|
extern int test_semaphores_queries(cl_device_id deviceID, cl_context context,
|
||||||
cl_command_queue queue, int num_elements);
|
cl_command_queue queue, int num_elements);
|
||||||
extern int test_semaphores_order_1(cl_device_id deviceID, cl_context context,
|
|
||||||
cl_command_queue queue, int num_elements);
|
|
||||||
extern int test_semaphores_order_2(cl_device_id deviceID, cl_context context,
|
|
||||||
cl_command_queue queue, int num_elements);
|
|
||||||
extern int test_semaphores_order_3(cl_device_id deviceID, cl_context context,
|
|
||||||
cl_command_queue queue, int num_elements);
|
|
||||||
extern int test_semaphores_import_export_fd(cl_device_id deviceID,
|
extern int test_semaphores_import_export_fd(cl_device_id deviceID,
|
||||||
cl_context context,
|
cl_context context,
|
||||||
cl_command_queue queue,
|
cl_command_queue queue,
|
||||||
int num_elements);
|
int num_elements);
|
||||||
extern int test_semaphores_invalid_command(cl_device_id deviceID,
|
|
||||||
cl_context context,
|
|
||||||
cl_command_queue queue,
|
|
||||||
int num_elements);
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// Copyright (c) 2022 The Khronos Group Inc.
|
// Copyright (c) 2023 The Khronos Group Inc.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
@@ -646,303 +646,6 @@ int test_semaphores_queries(cl_device_id deviceID, cl_context context,
|
|||||||
return TEST_PASS;
|
return TEST_PASS;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Confirm that it is possible to enqueue a signal of wait and signal in any
|
|
||||||
// order as soon as the submission order (after deferred dependencies) is
|
|
||||||
// correct. Case: first one deferred wait, then one non deferred signal.
|
|
||||||
int test_semaphores_order_1(cl_device_id deviceID, cl_context context,
|
|
||||||
cl_command_queue defaultQueue, int num_elements)
|
|
||||||
{
|
|
||||||
cl_int err;
|
|
||||||
|
|
||||||
if (!is_extension_available(deviceID, "cl_khr_semaphore"))
|
|
||||||
{
|
|
||||||
log_info("cl_khr_semaphore is not supported on this platoform. "
|
|
||||||
"Skipping test.\n");
|
|
||||||
return TEST_SKIPPED_ITSELF;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Obtain pointers to semaphore's API
|
|
||||||
GET_PFN(deviceID, clCreateSemaphoreWithPropertiesKHR);
|
|
||||||
GET_PFN(deviceID, clEnqueueSignalSemaphoresKHR);
|
|
||||||
GET_PFN(deviceID, clEnqueueWaitSemaphoresKHR);
|
|
||||||
GET_PFN(deviceID, clReleaseSemaphoreKHR);
|
|
||||||
|
|
||||||
// Create ooo queue
|
|
||||||
clCommandQueueWrapper queue = clCreateCommandQueue(
|
|
||||||
context, deviceID, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, &err);
|
|
||||||
test_error(err, "Could not create command queue");
|
|
||||||
|
|
||||||
// Create semaphore
|
|
||||||
cl_semaphore_properties_khr sema_props[] = {
|
|
||||||
static_cast<cl_semaphore_properties_khr>(CL_SEMAPHORE_TYPE_KHR),
|
|
||||||
static_cast<cl_semaphore_properties_khr>(CL_SEMAPHORE_TYPE_BINARY_KHR),
|
|
||||||
0
|
|
||||||
};
|
|
||||||
cl_semaphore_khr sema =
|
|
||||||
clCreateSemaphoreWithPropertiesKHR(context, sema_props, &err);
|
|
||||||
test_error(err, "Could not create semaphore");
|
|
||||||
|
|
||||||
// Create user event
|
|
||||||
clEventWrapper user_event = clCreateUserEvent(context, &err);
|
|
||||||
test_error(err, "Could not create user event");
|
|
||||||
|
|
||||||
// Wait semaphore (dependency on user_event)
|
|
||||||
clEventWrapper wait_event;
|
|
||||||
err = clEnqueueWaitSemaphoresKHR(queue, 1, &sema, nullptr, 1, &user_event,
|
|
||||||
&wait_event);
|
|
||||||
test_error(err, "Could not wait semaphore");
|
|
||||||
|
|
||||||
// Signal semaphore
|
|
||||||
clEventWrapper signal_event;
|
|
||||||
err = clEnqueueSignalSemaphoresKHR(queue, 1, &sema, nullptr, 0, nullptr,
|
|
||||||
&signal_event);
|
|
||||||
test_error(err, "Could not signal semaphore");
|
|
||||||
|
|
||||||
// Flush and delay
|
|
||||||
err = clFlush(queue);
|
|
||||||
test_error(err, "Could not flush queue");
|
|
||||||
std::this_thread::sleep_for(std::chrono::seconds(FLUSH_DELAY_S));
|
|
||||||
|
|
||||||
// Ensure signal event is completed while wait event is not
|
|
||||||
test_assert_event_complete(signal_event);
|
|
||||||
test_assert_event_inprogress(wait_event);
|
|
||||||
|
|
||||||
// Complete user_event
|
|
||||||
err = clSetUserEventStatus(user_event, CL_COMPLETE);
|
|
||||||
test_error(err, "Could not set user event to CL_COMPLETE");
|
|
||||||
|
|
||||||
// Finish
|
|
||||||
err = clFinish(queue);
|
|
||||||
test_error(err, "Could not finish queue");
|
|
||||||
|
|
||||||
// Ensure all events are completed
|
|
||||||
test_assert_event_complete(signal_event);
|
|
||||||
test_assert_event_complete(wait_event);
|
|
||||||
|
|
||||||
// Release semaphore
|
|
||||||
err = clReleaseSemaphoreKHR(sema);
|
|
||||||
test_error(err, "Could not release semaphore");
|
|
||||||
|
|
||||||
return TEST_PASS;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Confirm that it is possible to enqueue a signal of wait and signal in any
|
|
||||||
// order as soon as the submission order (after deferred dependencies) is
|
|
||||||
// correct. Case: first two deferred signals, then one deferred wait. Unblock
|
|
||||||
// signal, then unblock wait. When wait completes, unblock the other signal.
|
|
||||||
int test_semaphores_order_2(cl_device_id deviceID, cl_context context,
|
|
||||||
cl_command_queue defaultQueue, int num_elements)
|
|
||||||
{
|
|
||||||
cl_int err;
|
|
||||||
|
|
||||||
if (!is_extension_available(deviceID, "cl_khr_semaphore"))
|
|
||||||
{
|
|
||||||
log_info("cl_khr_semaphore is not supported on this platoform. "
|
|
||||||
"Skipping test.\n");
|
|
||||||
return TEST_SKIPPED_ITSELF;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Obtain pointers to semaphore's API
|
|
||||||
GET_PFN(deviceID, clCreateSemaphoreWithPropertiesKHR);
|
|
||||||
GET_PFN(deviceID, clEnqueueSignalSemaphoresKHR);
|
|
||||||
GET_PFN(deviceID, clEnqueueWaitSemaphoresKHR);
|
|
||||||
GET_PFN(deviceID, clReleaseSemaphoreKHR);
|
|
||||||
|
|
||||||
// Create ooo queue
|
|
||||||
clCommandQueueWrapper queue = clCreateCommandQueue(
|
|
||||||
context, deviceID, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, &err);
|
|
||||||
test_error(err, "Could not create command queue");
|
|
||||||
|
|
||||||
// Create semaphore
|
|
||||||
cl_semaphore_properties_khr sema_props[] = {
|
|
||||||
static_cast<cl_semaphore_properties_khr>(CL_SEMAPHORE_TYPE_KHR),
|
|
||||||
static_cast<cl_semaphore_properties_khr>(CL_SEMAPHORE_TYPE_BINARY_KHR),
|
|
||||||
0
|
|
||||||
};
|
|
||||||
cl_semaphore_khr sema =
|
|
||||||
clCreateSemaphoreWithPropertiesKHR(context, sema_props, &err);
|
|
||||||
test_error(err, "Could not create semaphore");
|
|
||||||
|
|
||||||
// Create user events
|
|
||||||
clEventWrapper user_event_1 = clCreateUserEvent(context, &err);
|
|
||||||
test_error(err, "Could not create user event");
|
|
||||||
|
|
||||||
clEventWrapper user_event_2 = clCreateUserEvent(context, &err);
|
|
||||||
test_error(err, "Could not create user event");
|
|
||||||
|
|
||||||
clEventWrapper user_event_3 = clCreateUserEvent(context, &err);
|
|
||||||
test_error(err, "Could not create user event");
|
|
||||||
|
|
||||||
// Signal semaphore (dependency on user_event_1)
|
|
||||||
clEventWrapper signal_1_event;
|
|
||||||
err = clEnqueueSignalSemaphoresKHR(queue, 1, &sema, nullptr, 1,
|
|
||||||
&user_event_1, &signal_1_event);
|
|
||||||
test_error(err, "Could not signal semaphore");
|
|
||||||
|
|
||||||
// Signal semaphore (dependency on user_event_2)
|
|
||||||
clEventWrapper signal_2_event;
|
|
||||||
err = clEnqueueSignalSemaphoresKHR(queue, 1, &sema, nullptr, 1,
|
|
||||||
&user_event_2, &signal_2_event);
|
|
||||||
test_error(err, "Could not signal semaphore");
|
|
||||||
|
|
||||||
// Wait semaphore (dependency on user_event_3)
|
|
||||||
clEventWrapper wait_event;
|
|
||||||
err = clEnqueueWaitSemaphoresKHR(queue, 1, &sema, nullptr, 1, &user_event_3,
|
|
||||||
&wait_event);
|
|
||||||
test_error(err, "Could not wait semaphore");
|
|
||||||
|
|
||||||
// Complete user_event_1
|
|
||||||
err = clSetUserEventStatus(user_event_1, CL_COMPLETE);
|
|
||||||
test_error(err, "Could not set user event to CL_COMPLETE");
|
|
||||||
|
|
||||||
// Complete user_event_3
|
|
||||||
err = clSetUserEventStatus(user_event_3, CL_COMPLETE);
|
|
||||||
test_error(err, "Could not set user event to CL_COMPLETE");
|
|
||||||
|
|
||||||
// Flush and delay
|
|
||||||
err = clFlush(queue);
|
|
||||||
test_error(err, "Could not flush queue");
|
|
||||||
std::this_thread::sleep_for(std::chrono::seconds(FLUSH_DELAY_S));
|
|
||||||
|
|
||||||
// Ensure all events are completed except for second signal
|
|
||||||
test_assert_event_complete(signal_1_event);
|
|
||||||
test_assert_event_inprogress(signal_2_event);
|
|
||||||
test_assert_event_complete(wait_event);
|
|
||||||
|
|
||||||
// Complete user_event_2
|
|
||||||
err = clSetUserEventStatus(user_event_2, CL_COMPLETE);
|
|
||||||
test_error(err, "Could not set user event to CL_COMPLETE");
|
|
||||||
|
|
||||||
// Finish
|
|
||||||
err = clFinish(queue);
|
|
||||||
test_error(err, "Could not finish queue");
|
|
||||||
|
|
||||||
// Ensure all events are completed
|
|
||||||
test_assert_event_complete(signal_1_event);
|
|
||||||
test_assert_event_complete(signal_2_event);
|
|
||||||
test_assert_event_complete(wait_event);
|
|
||||||
|
|
||||||
// Release semaphore
|
|
||||||
err = clReleaseSemaphoreKHR(sema);
|
|
||||||
test_error(err, "Could not release semaphore");
|
|
||||||
|
|
||||||
return TEST_PASS;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Confirm that it is possible to enqueue a signal of wait and signal in any
|
|
||||||
// order as soon as the submission order (after deferred dependencies) is
|
|
||||||
// correct. Case: first two deferred signals, then two deferred waits. Unblock
|
|
||||||
// one signal and one wait (both blocked by the same user event). When wait
|
|
||||||
// completes, unblock the other signal. Then unblock the other wait.
|
|
||||||
int test_semaphores_order_3(cl_device_id deviceID, cl_context context,
|
|
||||||
cl_command_queue defaultQueue, int num_elements)
|
|
||||||
{
|
|
||||||
cl_int err;
|
|
||||||
|
|
||||||
if (!is_extension_available(deviceID, "cl_khr_semaphore"))
|
|
||||||
{
|
|
||||||
log_info("cl_khr_semaphore is not supported on this platoform. "
|
|
||||||
"Skipping test.\n");
|
|
||||||
return TEST_SKIPPED_ITSELF;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Obtain pointers to semaphore's API
|
|
||||||
GET_PFN(deviceID, clCreateSemaphoreWithPropertiesKHR);
|
|
||||||
GET_PFN(deviceID, clEnqueueSignalSemaphoresKHR);
|
|
||||||
GET_PFN(deviceID, clEnqueueWaitSemaphoresKHR);
|
|
||||||
GET_PFN(deviceID, clReleaseSemaphoreKHR);
|
|
||||||
|
|
||||||
// Create ooo queue
|
|
||||||
clCommandQueueWrapper queue = clCreateCommandQueue(
|
|
||||||
context, deviceID, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, &err);
|
|
||||||
test_error(err, "Could not create command queue");
|
|
||||||
|
|
||||||
// Create semaphore
|
|
||||||
cl_semaphore_properties_khr sema_props[] = {
|
|
||||||
static_cast<cl_semaphore_properties_khr>(CL_SEMAPHORE_TYPE_KHR),
|
|
||||||
static_cast<cl_semaphore_properties_khr>(CL_SEMAPHORE_TYPE_BINARY_KHR),
|
|
||||||
0
|
|
||||||
};
|
|
||||||
cl_semaphore_khr sema =
|
|
||||||
clCreateSemaphoreWithPropertiesKHR(context, sema_props, &err);
|
|
||||||
test_error(err, "Could not create semaphore");
|
|
||||||
|
|
||||||
// Create user events
|
|
||||||
clEventWrapper user_event_1 = clCreateUserEvent(context, &err);
|
|
||||||
test_error(err, "Could not create user event");
|
|
||||||
|
|
||||||
clEventWrapper user_event_2 = clCreateUserEvent(context, &err);
|
|
||||||
test_error(err, "Could not create user event");
|
|
||||||
|
|
||||||
clEventWrapper user_event_3 = clCreateUserEvent(context, &err);
|
|
||||||
test_error(err, "Could not create user event");
|
|
||||||
|
|
||||||
// Signal semaphore (dependency on user_event_1)
|
|
||||||
clEventWrapper signal_1_event;
|
|
||||||
err = clEnqueueSignalSemaphoresKHR(queue, 1, &sema, nullptr, 1,
|
|
||||||
&user_event_1, &signal_1_event);
|
|
||||||
test_error(err, "Could not signal semaphore");
|
|
||||||
|
|
||||||
// Signal semaphore (dependency on user_event_2)
|
|
||||||
clEventWrapper signal_2_event;
|
|
||||||
err = clEnqueueSignalSemaphoresKHR(queue, 1, &sema, nullptr, 1,
|
|
||||||
&user_event_2, &signal_2_event);
|
|
||||||
test_error(err, "Could not signal semaphore");
|
|
||||||
|
|
||||||
// Wait semaphore (dependency on user_event_3)
|
|
||||||
clEventWrapper wait_1_event;
|
|
||||||
err = clEnqueueWaitSemaphoresKHR(queue, 1, &sema, nullptr, 1, &user_event_3,
|
|
||||||
&wait_1_event);
|
|
||||||
test_error(err, "Could not wait semaphore");
|
|
||||||
|
|
||||||
// Wait semaphore (dependency on user_event_2)
|
|
||||||
clEventWrapper wait_2_event;
|
|
||||||
err = clEnqueueWaitSemaphoresKHR(queue, 1, &sema, nullptr, 1, &user_event_2,
|
|
||||||
&wait_2_event);
|
|
||||||
test_error(err, "Could not wait semaphore");
|
|
||||||
|
|
||||||
// Complete user_event_2
|
|
||||||
err = clSetUserEventStatus(user_event_2, CL_COMPLETE);
|
|
||||||
test_error(err, "Could not set user event to CL_COMPLETE");
|
|
||||||
|
|
||||||
// Flush and delay
|
|
||||||
err = clFlush(queue);
|
|
||||||
test_error(err, "Could not flush queue");
|
|
||||||
std::this_thread::sleep_for(std::chrono::seconds(FLUSH_DELAY_S));
|
|
||||||
|
|
||||||
// Ensure only second signal and second wait completed
|
|
||||||
cl_event event_list[] = { signal_2_event, wait_2_event };
|
|
||||||
err = clWaitForEvents(2, event_list);
|
|
||||||
test_error(err, "Could not wait for events");
|
|
||||||
|
|
||||||
test_assert_event_inprogress(signal_1_event);
|
|
||||||
test_assert_event_inprogress(wait_1_event);
|
|
||||||
|
|
||||||
// Complete user_event_1
|
|
||||||
err = clSetUserEventStatus(user_event_1, CL_COMPLETE);
|
|
||||||
test_error(err, "Could not set user event to CL_COMPLETE");
|
|
||||||
|
|
||||||
// Complete user_event_3
|
|
||||||
err = clSetUserEventStatus(user_event_3, CL_COMPLETE);
|
|
||||||
test_error(err, "Could not set user event to CL_COMPLETE");
|
|
||||||
|
|
||||||
// Finish
|
|
||||||
err = clFinish(queue);
|
|
||||||
test_error(err, "Could not finish queue");
|
|
||||||
|
|
||||||
// Ensure all events are completed
|
|
||||||
test_assert_event_complete(signal_1_event);
|
|
||||||
test_assert_event_complete(signal_2_event);
|
|
||||||
test_assert_event_complete(wait_1_event);
|
|
||||||
test_assert_event_complete(wait_2_event);
|
|
||||||
|
|
||||||
// Release semaphore
|
|
||||||
err = clReleaseSemaphoreKHR(sema);
|
|
||||||
test_error(err, "Could not release semaphore");
|
|
||||||
|
|
||||||
return TEST_PASS;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test it is possible to export a semaphore to a sync fd and import the same
|
// Test it is possible to export a semaphore to a sync fd and import the same
|
||||||
// sync fd to a new semaphore
|
// sync fd to a new semaphore
|
||||||
int test_semaphores_import_export_fd(cl_device_id deviceID, cl_context context,
|
int test_semaphores_import_export_fd(cl_device_id deviceID, cl_context context,
|
||||||
@@ -985,6 +688,8 @@ int test_semaphores_import_export_fd(cl_device_id deviceID, cl_context context,
|
|||||||
CL_SEMAPHORE_EXPORT_HANDLE_TYPES_KHR),
|
CL_SEMAPHORE_EXPORT_HANDLE_TYPES_KHR),
|
||||||
static_cast<cl_semaphore_properties_khr>(
|
static_cast<cl_semaphore_properties_khr>(
|
||||||
CL_SEMAPHORE_HANDLE_SYNC_FD_KHR),
|
CL_SEMAPHORE_HANDLE_SYNC_FD_KHR),
|
||||||
|
static_cast<cl_semaphore_properties_khr>(
|
||||||
|
CL_SEMAPHORE_EXPORT_HANDLE_TYPES_LIST_END_KHR),
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
cl_semaphore_khr sema_1 =
|
cl_semaphore_khr sema_1 =
|
||||||
@@ -1039,107 +744,5 @@ int test_semaphores_import_export_fd(cl_device_id deviceID, cl_context context,
|
|||||||
|
|
||||||
err = clReleaseSemaphoreKHR(sema_2);
|
err = clReleaseSemaphoreKHR(sema_2);
|
||||||
test_error(err, "Could not release semaphore");
|
test_error(err, "Could not release semaphore");
|
||||||
return TEST_PASS;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test that an invalid semaphore command results in the invalidation of the
|
|
||||||
// command's event and the dependencies' events
|
|
||||||
int test_semaphores_invalid_command(cl_device_id deviceID, cl_context context,
|
|
||||||
cl_command_queue defaultQueue,
|
|
||||||
int num_elements)
|
|
||||||
{
|
|
||||||
cl_int err;
|
|
||||||
|
|
||||||
if (!is_extension_available(deviceID, "cl_khr_semaphore"))
|
|
||||||
{
|
|
||||||
log_info("cl_khr_semaphore is not supported on this platoform. "
|
|
||||||
"Skipping test.\n");
|
|
||||||
return TEST_SKIPPED_ITSELF;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Obtain pointers to semaphore's API
|
|
||||||
GET_PFN(deviceID, clCreateSemaphoreWithPropertiesKHR);
|
|
||||||
GET_PFN(deviceID, clEnqueueSignalSemaphoresKHR);
|
|
||||||
GET_PFN(deviceID, clEnqueueWaitSemaphoresKHR);
|
|
||||||
GET_PFN(deviceID, clReleaseSemaphoreKHR);
|
|
||||||
|
|
||||||
// Create ooo queue
|
|
||||||
clCommandQueueWrapper queue = clCreateCommandQueue(
|
|
||||||
context, deviceID, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, &err);
|
|
||||||
test_error(err, "Could not create command queue");
|
|
||||||
|
|
||||||
// Create semaphores
|
|
||||||
cl_semaphore_properties_khr sema_props[] = {
|
|
||||||
static_cast<cl_semaphore_properties_khr>(CL_SEMAPHORE_TYPE_KHR),
|
|
||||||
static_cast<cl_semaphore_properties_khr>(CL_SEMAPHORE_TYPE_BINARY_KHR),
|
|
||||||
0
|
|
||||||
};
|
|
||||||
cl_semaphore_khr sema_1 =
|
|
||||||
clCreateSemaphoreWithPropertiesKHR(context, sema_props, &err);
|
|
||||||
test_error(err, "Could not create semaphore");
|
|
||||||
|
|
||||||
cl_semaphore_khr sema_2 =
|
|
||||||
clCreateSemaphoreWithPropertiesKHR(context, sema_props, &err);
|
|
||||||
test_error(err, "Could not create semaphore");
|
|
||||||
|
|
||||||
// Create user events
|
|
||||||
clEventWrapper user_event_1 = clCreateUserEvent(context, &err);
|
|
||||||
test_error(err, "Could not create user event");
|
|
||||||
|
|
||||||
clEventWrapper user_event_2 = clCreateUserEvent(context, &err);
|
|
||||||
test_error(err, "Could not create user event");
|
|
||||||
|
|
||||||
// Signal semaphore_1 (dependency on user_event_1)
|
|
||||||
clEventWrapper signal_1_event;
|
|
||||||
err = clEnqueueSignalSemaphoresKHR(queue, 1, &sema_1, nullptr, 1,
|
|
||||||
&user_event_1, &signal_1_event);
|
|
||||||
test_error(err, "Could not signal semaphore");
|
|
||||||
|
|
||||||
// Wait semaphore_1 and semaphore_2 (dependency on user_event_1)
|
|
||||||
clEventWrapper wait_event;
|
|
||||||
cl_semaphore_khr sema_list[] = { sema_1, sema_2 };
|
|
||||||
err = clEnqueueWaitSemaphoresKHR(queue, 2, sema_list, nullptr, 1,
|
|
||||||
&user_event_1, &wait_event);
|
|
||||||
test_error(err, "Could not wait semaphore");
|
|
||||||
|
|
||||||
// Signal semaphore_1 (dependency on wait_event and user_event_2)
|
|
||||||
clEventWrapper signal_2_event;
|
|
||||||
cl_event wait_list[] = { user_event_2, wait_event };
|
|
||||||
err = clEnqueueSignalSemaphoresKHR(queue, 1, &sema_1, nullptr, 2, wait_list,
|
|
||||||
&signal_2_event);
|
|
||||||
test_error(err, "Could not signal semaphore");
|
|
||||||
|
|
||||||
// Flush and delay
|
|
||||||
err = clFlush(queue);
|
|
||||||
test_error(err, "Could not flush queue");
|
|
||||||
std::this_thread::sleep_for(std::chrono::seconds(FLUSH_DELAY_S));
|
|
||||||
|
|
||||||
// Ensure all events are not completed
|
|
||||||
test_assert_event_inprogress(signal_1_event);
|
|
||||||
test_assert_event_inprogress(signal_2_event);
|
|
||||||
test_assert_event_inprogress(wait_event);
|
|
||||||
|
|
||||||
// Complete user_event_1 (expect failure as waiting on semaphore_2 is not
|
|
||||||
// allowed (unsignaled)
|
|
||||||
err = clSetUserEventStatus(user_event_1, CL_COMPLETE);
|
|
||||||
test_assert_error(err != CL_SUCCESS,
|
|
||||||
"signal_2_event completed unexpectedly");
|
|
||||||
|
|
||||||
// Ensure signal_1 is completed while others failed (the second signal
|
|
||||||
// should fail as it depends on wait)
|
|
||||||
err = clFinish(queue);
|
|
||||||
test_error(err, "Could not finish queue");
|
|
||||||
|
|
||||||
test_assert_event_complete(signal_1_event);
|
|
||||||
test_assert_event_terminated(wait_event);
|
|
||||||
test_assert_event_terminated(signal_2_event);
|
|
||||||
|
|
||||||
// Release semaphore
|
|
||||||
err = clReleaseSemaphoreKHR(sema_1);
|
|
||||||
test_error(err, "Could not release semaphore");
|
|
||||||
|
|
||||||
err = clReleaseSemaphoreKHR(sema_2);
|
|
||||||
test_error(err, "Could not release semaphore");
|
|
||||||
|
|
||||||
return TEST_PASS;
|
return TEST_PASS;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user