mirror of
https://github.com/KhronosGroup/OpenCL-CTS.git
synced 2026-03-19 06:09:01 +00:00
Added new cl_khr_semaphore tests to verify clEnqueueWaitSemaphoresKHR negative results (#1965)
According to work plan from https://github.com/KhronosGroup/OpenCL-CTS/issues/1691 After consultations with @bashbaug I skipped this case: `CL_INVALID_VALUE if any of the semaphore objects specified by sema_objects requires a semaphore payload and sema_payload_list is NULL`
This commit is contained in:
@@ -3,6 +3,8 @@ set(MODULE_NAME CL_KHR_SEMAPHORE)
|
||||
set(${MODULE_NAME}_SOURCES
|
||||
main.cpp
|
||||
test_semaphores.cpp
|
||||
test_semaphores_negative_wait.cpp
|
||||
semaphore_base.h
|
||||
)
|
||||
|
||||
include(../../CMakeCommon.txt)
|
||||
|
||||
@@ -35,6 +35,15 @@ test_definition test_list[] = {
|
||||
ADD_TEST_VERSION(semaphores_multi_wait, Version(1, 2)),
|
||||
ADD_TEST_VERSION(semaphores_queries, Version(1, 2)),
|
||||
ADD_TEST_VERSION(semaphores_import_export_fd, Version(1, 2)),
|
||||
ADD_TEST_VERSION(semaphores_negative_wait_invalid_command_queue,
|
||||
Version(1, 2)),
|
||||
ADD_TEST_VERSION(semaphores_negative_wait_invalid_value, Version(1, 2)),
|
||||
ADD_TEST_VERSION(semaphores_negative_wait_invalid_semaphore, Version(1, 2)),
|
||||
ADD_TEST_VERSION(semaphores_negative_wait_invalid_context, Version(1, 2)),
|
||||
ADD_TEST_VERSION(semaphores_negative_wait_invalid_event_wait_list,
|
||||
Version(1, 2)),
|
||||
ADD_TEST_VERSION(semaphores_negative_wait_invalid_event_status,
|
||||
Version(1, 2)),
|
||||
};
|
||||
|
||||
const int test_num = ARRAY_SIZE(test_list);
|
||||
|
||||
@@ -45,3 +45,23 @@ extern int test_semaphores_import_export_fd(cl_device_id deviceID,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements);
|
||||
extern int test_semaphores_negative_wait_invalid_command_queue(
|
||||
cl_device_id device, cl_context context, cl_command_queue queue,
|
||||
int num_elements);
|
||||
extern int test_semaphores_negative_wait_invalid_value(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements);
|
||||
extern int test_semaphores_negative_wait_invalid_semaphore(
|
||||
cl_device_id device, cl_context context, cl_command_queue queue,
|
||||
int num_elements);
|
||||
extern int test_semaphores_negative_wait_invalid_context(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements);
|
||||
extern int test_semaphores_negative_wait_invalid_event_wait_list(
|
||||
cl_device_id device, cl_context context, cl_command_queue queue,
|
||||
int num_elements);
|
||||
extern int test_semaphores_negative_wait_invalid_event_status(
|
||||
cl_device_id device, cl_context context, cl_command_queue queue,
|
||||
int num_elements);
|
||||
|
||||
202
test_conformance/extensions/cl_khr_semaphore/semaphore_base.h
Normal file
202
test_conformance/extensions/cl_khr_semaphore/semaphore_base.h
Normal file
@@ -0,0 +1,202 @@
|
||||
//
|
||||
// Copyright (c) 2024 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.
|
||||
|
||||
#ifndef CL_KHR_SEMAPHORE_BASE_H
|
||||
#define CL_KHR_SEMAPHORE_BASE_H
|
||||
|
||||
#include <CL/cl_ext.h>
|
||||
#include "harness/deviceInfo.h"
|
||||
#include "harness/testHarness.h"
|
||||
|
||||
#include "harness/typeWrappers.h"
|
||||
|
||||
struct SemaphoreBase
|
||||
{
|
||||
SemaphoreBase(cl_device_id device): device(device) {}
|
||||
|
||||
cl_int init_extension_functions()
|
||||
{
|
||||
cl_platform_id platform;
|
||||
cl_int error =
|
||||
clGetDeviceInfo(device, CL_DEVICE_PLATFORM, sizeof(cl_platform_id),
|
||||
&platform, nullptr);
|
||||
test_error(error, "clGetDeviceInfo for CL_DEVICE_PLATFORM failed");
|
||||
|
||||
// If it is supported get the addresses of all the APIs here.
|
||||
// clang-format off
|
||||
#define GET_EXTENSION_ADDRESS(FUNC) \
|
||||
FUNC = reinterpret_cast<FUNC##_fn>( \
|
||||
clGetExtensionFunctionAddressForPlatform(platform, #FUNC)); \
|
||||
if (FUNC == nullptr) \
|
||||
{ \
|
||||
log_error("ERROR: clGetExtensionFunctionAddressForPlatform failed" \
|
||||
" with " #FUNC "\n"); \
|
||||
return TEST_FAIL; \
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
GET_EXTENSION_ADDRESS(clCreateSemaphoreWithPropertiesKHR);
|
||||
GET_EXTENSION_ADDRESS(clEnqueueSignalSemaphoresKHR);
|
||||
GET_EXTENSION_ADDRESS(clEnqueueWaitSemaphoresKHR);
|
||||
GET_EXTENSION_ADDRESS(clReleaseSemaphoreKHR);
|
||||
GET_EXTENSION_ADDRESS(clGetSemaphoreInfoKHR);
|
||||
GET_EXTENSION_ADDRESS(clRetainSemaphoreKHR);
|
||||
GET_EXTENSION_ADDRESS(clGetSemaphoreHandleForTypeKHR);
|
||||
|
||||
#undef GET_EXTENSION_ADDRESS
|
||||
return CL_SUCCESS;
|
||||
}
|
||||
|
||||
clCreateSemaphoreWithPropertiesKHR_fn clCreateSemaphoreWithPropertiesKHR =
|
||||
nullptr;
|
||||
clEnqueueSignalSemaphoresKHR_fn clEnqueueSignalSemaphoresKHR = nullptr;
|
||||
clEnqueueWaitSemaphoresKHR_fn clEnqueueWaitSemaphoresKHR = nullptr;
|
||||
clReleaseSemaphoreKHR_fn clReleaseSemaphoreKHR = nullptr;
|
||||
clGetSemaphoreInfoKHR_fn clGetSemaphoreInfoKHR = nullptr;
|
||||
clRetainSemaphoreKHR_fn clRetainSemaphoreKHR = nullptr;
|
||||
clGetSemaphoreHandleForTypeKHR_fn clGetSemaphoreHandleForTypeKHR = nullptr;
|
||||
|
||||
cl_device_id device = nullptr;
|
||||
};
|
||||
|
||||
// Wrapper class based off generic typeWrappers.h wrappers. However, because
|
||||
// the release/retain functions are queried at runtime from the platform,
|
||||
// rather than known at compile time we cannot link the instantiated template.
|
||||
// Instead, pass an instance of `SemaphoreTestBase` on wrapper construction
|
||||
// to access the release/retain functions.
|
||||
class clSemaphoreWrapper {
|
||||
cl_semaphore_khr object = nullptr;
|
||||
|
||||
void retain()
|
||||
{
|
||||
if (!object) return;
|
||||
|
||||
auto err = base->clRetainSemaphoreKHR(object);
|
||||
if (err != CL_SUCCESS)
|
||||
{
|
||||
print_error(err, "clRetainCommandBufferKHR() failed");
|
||||
std::abort();
|
||||
}
|
||||
}
|
||||
|
||||
void release()
|
||||
{
|
||||
if (!object) return;
|
||||
|
||||
auto err = base->clReleaseSemaphoreKHR(object);
|
||||
if (err != CL_SUCCESS)
|
||||
{
|
||||
print_error(err, "clReleaseCommandBufferKHR() failed");
|
||||
std::abort();
|
||||
}
|
||||
}
|
||||
|
||||
// Used to access release/retain functions
|
||||
SemaphoreBase *base;
|
||||
|
||||
public:
|
||||
// We always want to have base available to dereference
|
||||
clSemaphoreWrapper() = delete;
|
||||
|
||||
clSemaphoreWrapper(SemaphoreBase *base): base(base) {}
|
||||
|
||||
// On assignment, assume the object has a refcount of one.
|
||||
clSemaphoreWrapper &operator=(cl_semaphore_khr rhs)
|
||||
{
|
||||
reset(rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Copy semantics, increase retain count.
|
||||
clSemaphoreWrapper(clSemaphoreWrapper const &w) { *this = w; }
|
||||
clSemaphoreWrapper &operator=(clSemaphoreWrapper const &w)
|
||||
{
|
||||
reset(w.object);
|
||||
retain();
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Move semantics, directly take ownership.
|
||||
clSemaphoreWrapper(clSemaphoreWrapper &&w) { *this = std::move(w); }
|
||||
clSemaphoreWrapper &operator=(clSemaphoreWrapper &&w)
|
||||
{
|
||||
reset(w.object);
|
||||
w.object = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
~clSemaphoreWrapper() { reset(); }
|
||||
|
||||
// Release the existing object, if any, and own the new one, if any.
|
||||
void reset(cl_semaphore_khr new_object = nullptr)
|
||||
{
|
||||
release();
|
||||
object = new_object;
|
||||
}
|
||||
|
||||
operator cl_semaphore_khr() const { return object; }
|
||||
operator const cl_semaphore_khr *() { return &object; }
|
||||
};
|
||||
|
||||
struct SemaphoreTestBase : public SemaphoreBase
|
||||
{
|
||||
SemaphoreTestBase(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue)
|
||||
: SemaphoreBase(device), context(context), semaphore(this)
|
||||
{
|
||||
cl_int error = init_extension_functions();
|
||||
if (error != CL_SUCCESS)
|
||||
throw std::runtime_error("init_extension_functions failed\n");
|
||||
|
||||
error = clRetainCommandQueue(queue);
|
||||
if (error != CL_SUCCESS)
|
||||
throw std::runtime_error("clRetainCommandQueue failed\n");
|
||||
this->queue = queue;
|
||||
}
|
||||
|
||||
virtual cl_int Run() = 0;
|
||||
|
||||
protected:
|
||||
cl_context context = nullptr;
|
||||
clCommandQueueWrapper queue = nullptr;
|
||||
clSemaphoreWrapper semaphore = nullptr;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
int MakeAndRunTest(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue)
|
||||
{
|
||||
if (!is_extension_available(device, "cl_khr_semaphore"))
|
||||
{
|
||||
log_info(
|
||||
"Device does not support 'cl_khr_semaphore'. Skipping the test.\n");
|
||||
return TEST_SKIPPED_ITSELF;
|
||||
}
|
||||
|
||||
cl_int status = TEST_PASS;
|
||||
try
|
||||
{
|
||||
auto test_fixture = T(device, context, queue);
|
||||
status = test_fixture.Run();
|
||||
} catch (const std::runtime_error &e)
|
||||
{
|
||||
log_error("%s", e.what());
|
||||
return TEST_FAIL;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
#endif // CL_KHR_SEMAPHORE_BASE_H
|
||||
@@ -0,0 +1,395 @@
|
||||
//
|
||||
// Copyright (c) 2024 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 "semaphore_base.h"
|
||||
|
||||
#include "harness/errorHelpers.h"
|
||||
#include <chrono>
|
||||
#include <system_error>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
namespace {
|
||||
|
||||
// the device associated with command_queue is not same as one of the devices
|
||||
// specified by CL_SEMAPHORE_DEVICE_HANDLE_LIST_KHR at the time of creating one
|
||||
// or more of sema_objects.
|
||||
|
||||
struct WaitInvalidCommandQueue : public SemaphoreTestBase
|
||||
{
|
||||
WaitInvalidCommandQueue(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue)
|
||||
: SemaphoreTestBase(device, context, queue)
|
||||
{}
|
||||
|
||||
cl_int Run() override
|
||||
{
|
||||
// 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),
|
||||
static_cast<cl_semaphore_properties_khr>(
|
||||
CL_SEMAPHORE_DEVICE_HANDLE_LIST_KHR),
|
||||
(cl_semaphore_properties_khr)device,
|
||||
CL_SEMAPHORE_DEVICE_HANDLE_LIST_END_KHR,
|
||||
0
|
||||
};
|
||||
|
||||
cl_int err = CL_SUCCESS;
|
||||
semaphore =
|
||||
clCreateSemaphoreWithPropertiesKHR(context, sema_props, &err);
|
||||
test_error(err, "Could not create semaphore");
|
||||
|
||||
// find other device
|
||||
cl_platform_id platform_id = 0;
|
||||
// find out what platform the harness is using.
|
||||
err = clGetDeviceInfo(device, CL_DEVICE_PLATFORM,
|
||||
sizeof(cl_platform_id), &platform_id, nullptr);
|
||||
test_error(err, "clGetDeviceInfo failed");
|
||||
|
||||
cl_uint num_platforms = 0;
|
||||
err = clGetPlatformIDs(16, nullptr, &num_platforms);
|
||||
test_error(err, "clGetPlatformIDs failed");
|
||||
|
||||
std::vector<cl_platform_id> platforms(num_platforms);
|
||||
|
||||
err = clGetPlatformIDs(num_platforms, platforms.data(), &num_platforms);
|
||||
test_error(err, "clGetPlatformIDs failed");
|
||||
|
||||
cl_device_id device_sec = nullptr;
|
||||
cl_uint num_devices = 0;
|
||||
for (int p = 0; p < (int)num_platforms; p++)
|
||||
{
|
||||
if (platform_id == platforms[p]) continue;
|
||||
|
||||
err = clGetDeviceIDs(platforms[p], CL_DEVICE_TYPE_ALL, 0, nullptr,
|
||||
&num_devices);
|
||||
test_error(err, "clGetDeviceIDs failed");
|
||||
|
||||
std::vector<cl_device_id> devices(num_devices);
|
||||
err = clGetDeviceIDs(platforms[p], CL_DEVICE_TYPE_ALL, num_devices,
|
||||
devices.data(), nullptr);
|
||||
test_error(err, "clGetDeviceIDs failed");
|
||||
|
||||
device_sec = devices.front();
|
||||
break;
|
||||
}
|
||||
|
||||
if (device_sec == nullptr)
|
||||
{
|
||||
log_info("Can't find needed resources. Skipping the test.\n");
|
||||
return TEST_SKIPPED_ITSELF;
|
||||
}
|
||||
|
||||
// Create secondary context
|
||||
clContextWrapper context_sec =
|
||||
clCreateContext(0, 1, &device_sec, nullptr, nullptr, &err);
|
||||
test_error(err, "Failed to create context");
|
||||
|
||||
// Create secondary queue
|
||||
clCommandQueueWrapper queue_sec =
|
||||
clCreateCommandQueue(context_sec, device_sec, 0, &err);
|
||||
test_error(err, "Could not create command queue");
|
||||
|
||||
// Signal semaphore
|
||||
err = clEnqueueSignalSemaphoresKHR(queue, 1, semaphore, nullptr, 0,
|
||||
nullptr, nullptr);
|
||||
test_error(err, "Could not signal semaphore");
|
||||
|
||||
// Wait semaphore
|
||||
err = clEnqueueWaitSemaphoresKHR(queue_sec, 1, semaphore, nullptr, 0,
|
||||
nullptr, nullptr);
|
||||
test_failure_error(err, CL_INVALID_COMMAND_QUEUE,
|
||||
"Unexpected clEnqueueWaitSemaphoresKHR return");
|
||||
|
||||
return TEST_PASS;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// num_sema_objects is 0.
|
||||
|
||||
struct WaitInvalidValue : public SemaphoreTestBase
|
||||
{
|
||||
WaitInvalidValue(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue)
|
||||
: SemaphoreTestBase(device, context, queue)
|
||||
{}
|
||||
|
||||
cl_int Run() override
|
||||
{
|
||||
// Wait semaphore
|
||||
cl_int err = CL_SUCCESS;
|
||||
err = clEnqueueWaitSemaphoresKHR(queue, 0, semaphore, nullptr, 0,
|
||||
nullptr, nullptr);
|
||||
test_failure_error(err, CL_INVALID_VALUE,
|
||||
"Unexpected clEnqueueWaitSemaphoresKHR return");
|
||||
|
||||
return CL_SUCCESS;
|
||||
}
|
||||
};
|
||||
|
||||
// any of the semaphore objects specified by sema_objects is not valid.
|
||||
|
||||
struct WaitInvalidSemaphore : public SemaphoreTestBase
|
||||
{
|
||||
WaitInvalidSemaphore(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue)
|
||||
: SemaphoreTestBase(device, context, queue)
|
||||
{}
|
||||
|
||||
cl_int Run() override
|
||||
{
|
||||
// Wait semaphore
|
||||
cl_semaphore_khr sema_objects[] = { nullptr, nullptr, nullptr };
|
||||
cl_int err = CL_SUCCESS;
|
||||
err = clEnqueueWaitSemaphoresKHR(
|
||||
queue, sizeof(sema_objects) / sizeof(sema_objects[0]), sema_objects,
|
||||
nullptr, 0, nullptr, nullptr);
|
||||
test_failure_error(err, CL_INVALID_SEMAPHORE_KHR,
|
||||
"Unexpected clEnqueueWaitSemaphoresKHR return");
|
||||
|
||||
return CL_SUCCESS;
|
||||
}
|
||||
};
|
||||
|
||||
// 1) the context associated with command_queue and any of the semaphore objects
|
||||
// in sema_objects are not the same, or
|
||||
// 2) the context associated with command_queue and that associated with events
|
||||
// in event_wait_list are not the same.
|
||||
|
||||
struct WaitInvalidContext : public SemaphoreTestBase
|
||||
{
|
||||
WaitInvalidContext(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue)
|
||||
: SemaphoreTestBase(device, context, queue)
|
||||
{}
|
||||
|
||||
cl_int Run() override
|
||||
{
|
||||
// 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_int err = CL_SUCCESS;
|
||||
semaphore =
|
||||
clCreateSemaphoreWithPropertiesKHR(context, sema_props, &err);
|
||||
test_error(err, "Could not create semaphore");
|
||||
|
||||
// Create secondary context
|
||||
clContextWrapper context_sec =
|
||||
clCreateContext(0, 1, &device, nullptr, nullptr, &err);
|
||||
test_error(err, "Failed to create context");
|
||||
|
||||
// Create secondary queue
|
||||
clCommandQueueWrapper queue_sec =
|
||||
clCreateCommandQueue(context_sec, device, 0, &err);
|
||||
test_error(err, "Could not create command queue");
|
||||
|
||||
// Signal semaphore
|
||||
err = clEnqueueSignalSemaphoresKHR(queue, 1, semaphore, nullptr, 0,
|
||||
nullptr, nullptr);
|
||||
test_error(err, "Could not signal semaphore");
|
||||
|
||||
// (1) Wait semaphore
|
||||
err = clEnqueueWaitSemaphoresKHR(queue_sec, 1, semaphore, nullptr, 0,
|
||||
nullptr, nullptr);
|
||||
test_failure_error(err, CL_INVALID_CONTEXT,
|
||||
"Unexpected clEnqueueWaitSemaphoresKHR return");
|
||||
|
||||
// Create user event
|
||||
clEventWrapper user_event = clCreateUserEvent(context_sec, &err);
|
||||
test_error(err, "Could not create user event");
|
||||
|
||||
// (2) Wait semaphore
|
||||
err = clEnqueueWaitSemaphoresKHR(queue, 1, semaphore, nullptr, 1,
|
||||
&user_event, nullptr);
|
||||
|
||||
cl_int signal_error = clSetUserEventStatus(user_event, CL_COMPLETE);
|
||||
test_error(signal_error, "clSetUserEventStatus failed");
|
||||
|
||||
test_failure_error(err, CL_INVALID_CONTEXT,
|
||||
"Unexpected clEnqueueWaitSemaphoresKHR return");
|
||||
|
||||
return TEST_PASS;
|
||||
}
|
||||
};
|
||||
|
||||
// (1) event_wait_list is NULL and num_events_in_wait_list is not 0, or
|
||||
// (2) event_wait_list is not NULL and num_events_in_wait_list is 0, or
|
||||
// (3) event objects in event_wait_list are not valid events.
|
||||
|
||||
struct WaitInvalidEventWaitList : public SemaphoreTestBase
|
||||
{
|
||||
WaitInvalidEventWaitList(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue)
|
||||
: SemaphoreTestBase(device, context, queue)
|
||||
{}
|
||||
|
||||
cl_int Run() override
|
||||
{
|
||||
// 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_int err = CL_SUCCESS;
|
||||
semaphore =
|
||||
clCreateSemaphoreWithPropertiesKHR(context, sema_props, &err);
|
||||
test_error(err, "Could not create semaphore");
|
||||
|
||||
|
||||
// Signal semaphore
|
||||
err = clEnqueueSignalSemaphoresKHR(queue, 1, semaphore, nullptr, 0,
|
||||
nullptr, nullptr);
|
||||
test_error(err, "Could not signal semaphore");
|
||||
|
||||
// (1) Wait semaphore
|
||||
err = clEnqueueWaitSemaphoresKHR(queue, 1, semaphore, nullptr, 1,
|
||||
nullptr, nullptr);
|
||||
test_failure_error(err, CL_INVALID_EVENT_WAIT_LIST,
|
||||
"Unexpected clEnqueueWaitSemaphoresKHR return");
|
||||
|
||||
// Create user event
|
||||
clEventWrapper user_event = clCreateUserEvent(context, &err);
|
||||
test_error(err, "Could not create user event");
|
||||
|
||||
// (2) Wait semaphore
|
||||
err = clEnqueueWaitSemaphoresKHR(queue, 1, semaphore, nullptr, 0,
|
||||
&user_event, nullptr);
|
||||
|
||||
cl_int signal_error = clSetUserEventStatus(user_event, CL_COMPLETE);
|
||||
test_error(signal_error, "clSetUserEventStatus failed");
|
||||
|
||||
test_failure_error(err, CL_INVALID_EVENT_WAIT_LIST,
|
||||
"Unexpected clEnqueueWaitSemaphoresKHR return");
|
||||
|
||||
// (3) Wait semaphore
|
||||
cl_event wait_list[] = { nullptr, nullptr, nullptr };
|
||||
err = clEnqueueWaitSemaphoresKHR(
|
||||
queue, 1, semaphore, nullptr,
|
||||
sizeof(wait_list) / sizeof(wait_list[0]), wait_list, nullptr);
|
||||
test_failure_error(err, CL_INVALID_EVENT_WAIT_LIST,
|
||||
"Unexpected clEnqueueWaitSemaphoresKHR return");
|
||||
|
||||
return CL_SUCCESS;
|
||||
}
|
||||
};
|
||||
|
||||
// the execution status of any of the events in event_wait_list is a negative
|
||||
// integer value.
|
||||
|
||||
struct WaitInvalidEventStatus : public SemaphoreTestBase
|
||||
{
|
||||
WaitInvalidEventStatus(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue)
|
||||
: SemaphoreTestBase(device, context, queue)
|
||||
{}
|
||||
|
||||
cl_int Run() override
|
||||
{
|
||||
// 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_int err = CL_SUCCESS;
|
||||
semaphore =
|
||||
clCreateSemaphoreWithPropertiesKHR(context, sema_props, &err);
|
||||
test_error(err, "Could not create semaphore");
|
||||
|
||||
// Signal semaphore
|
||||
err = clEnqueueSignalSemaphoresKHR(queue, 1, semaphore, nullptr, 0,
|
||||
nullptr, nullptr);
|
||||
test_error(err, "Could not signal semaphore");
|
||||
|
||||
// Create user event
|
||||
clEventWrapper user_event = clCreateUserEvent(context, &err);
|
||||
test_error(err, "Could not create user event");
|
||||
|
||||
// Now release the user event, which will allow our actual action to run
|
||||
err = clSetUserEventStatus(user_event, -1);
|
||||
test_error(err, "Unable to set event status");
|
||||
|
||||
// Wait semaphore
|
||||
err = clEnqueueWaitSemaphoresKHR(queue, 1, semaphore, nullptr, 1,
|
||||
&user_event, nullptr);
|
||||
test_failure_error(err, CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST,
|
||||
"Unexpected clEnqueueWaitSemaphoresKHR return");
|
||||
|
||||
return CL_SUCCESS;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
int test_semaphores_negative_wait_invalid_command_queue(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements)
|
||||
{
|
||||
return MakeAndRunTest<WaitInvalidCommandQueue>(device, context, queue);
|
||||
}
|
||||
|
||||
int test_semaphores_negative_wait_invalid_value(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements)
|
||||
{
|
||||
return MakeAndRunTest<WaitInvalidValue>(device, context, queue);
|
||||
}
|
||||
|
||||
int test_semaphores_negative_wait_invalid_semaphore(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements)
|
||||
{
|
||||
return MakeAndRunTest<WaitInvalidSemaphore>(device, context, queue);
|
||||
}
|
||||
|
||||
int test_semaphores_negative_wait_invalid_context(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements)
|
||||
{
|
||||
return MakeAndRunTest<WaitInvalidContext>(device, context, queue);
|
||||
}
|
||||
|
||||
int test_semaphores_negative_wait_invalid_event_wait_list(
|
||||
cl_device_id device, cl_context context, cl_command_queue queue,
|
||||
int num_elements)
|
||||
{
|
||||
return MakeAndRunTest<WaitInvalidEventWaitList>(device, context, queue);
|
||||
}
|
||||
|
||||
int test_semaphores_negative_wait_invalid_event_status(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements)
|
||||
{
|
||||
return MakeAndRunTest<WaitInvalidEventStatus>(device, context, queue);
|
||||
}
|
||||
Reference in New Issue
Block a user