Skip to content

Commit

Permalink
tidy up semaphore emulation (#117)
Browse files Browse the repository at this point in the history
* minor semaphore emulation updates

Updates the emulated extension version number.
Formatting updates for consistency.

* fix semaphore extension version

* a few more minor fixes
  • Loading branch information
bashbaug committed Jun 22, 2024
1 parent 3d95b21 commit 7f1ebe9
Show file tree
Hide file tree
Showing 2 changed files with 121 additions and 67 deletions.
171 changes: 105 additions & 66 deletions layers/11_semaemu/emulate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,34 +27,47 @@
#endif

static constexpr cl_version version_cl_khr_semaphore =
CL_MAKE_VERSION(0, 9, 1);
CL_MAKE_VERSION(1, 0, 0);

SLayerContext& getLayerContext(void)
{
static SLayerContext c;
return c;
}

static bool isDeviceWithinContext(const cl_context context,
const cl_device_id device) {
cl_uint numDevices = 0;
cl_int error = g_pNextDispatch->clGetContextInfo(
context, CL_CONTEXT_NUM_DEVICES, sizeof(cl_uint), &numDevices, NULL);
if (error != CL_SUCCESS || numDevices == 0)
return false;
static bool isDeviceWithinContext(
const cl_context context,
const cl_device_id device)
{
cl_uint numDevices = 0;
cl_int error = g_pNextDispatch->clGetContextInfo(
context,
CL_CONTEXT_NUM_DEVICES,
sizeof(cl_uint),
&numDevices,
nullptr);
if (error != CL_SUCCESS || numDevices == 0) {
return false;
}

std::vector<cl_device_id> devices(numDevices, 0);
error = g_pNextDispatch->clGetContextInfo(context, CL_CONTEXT_DEVICES,
numDevices * sizeof(cl_device_id),
devices.data(), NULL);
if (error != CL_SUCCESS)
return false;
std::vector<cl_device_id> devices(numDevices);
error = g_pNextDispatch->clGetContextInfo(
context,
CL_CONTEXT_DEVICES,
numDevices * sizeof(cl_device_id),
devices.data(),
nullptr);
if (error != CL_SUCCESS) {
return false;
}

for (auto dev : devices)
if (dev == device)
return true;
for (auto check : devices) {
if (check == device) {
return true;
}
}

return false;
return false;
}

typedef struct _cl_semaphore_khr
Expand All @@ -64,21 +77,24 @@ typedef struct _cl_semaphore_khr
const cl_semaphore_properties_khr* properties,
cl_int* errcode_ret)
{
cl_semaphore_khr semaphore = NULL;
cl_semaphore_khr semaphore = nullptr;
cl_int errorCode = CL_SUCCESS;

ptrdiff_t numProperties = 0;
cl_semaphore_type_khr type = ~0;

std::vector<cl_device_id> devices;

if ( properties == nullptr )
if( properties == nullptr )
{
errorCode = CL_INVALID_VALUE;
}

if ( context == nullptr )
if( context == nullptr )
{
errorCode = CL_INVALID_CONTEXT;
}

if( errorCode == CL_SUCCESS && properties )
if( errorCode == CL_SUCCESS )
{
const cl_semaphore_properties_khr* check = properties;
bool found_CL_SEMAPHORE_TYPE_KHR = false;
Expand All @@ -98,6 +114,15 @@ typedef struct _cl_semaphore_khr
found_CL_SEMAPHORE_TYPE_KHR = true;
type = ((const cl_semaphore_type_khr*)(check + 1))[0];
check += 2;

switch( type )
{
case CL_SEMAPHORE_TYPE_BINARY_KHR:
break;
default:
errorCode = CL_INVALID_PROPERTY;
break;
}
}
break;
case CL_SEMAPHORE_DEVICE_HANDLE_LIST_KHR:
Expand All @@ -111,7 +136,8 @@ typedef struct _cl_semaphore_khr
check++;
while(*check != CL_SEMAPHORE_DEVICE_HANDLE_LIST_END_KHR)
{
devices.push_back(((cl_device_id*)check)[0]);
cl_device_id device = ((cl_device_id*)check)[0];
devices.push_back(device);
check++;
}
check++;
Expand All @@ -124,41 +150,55 @@ typedef struct _cl_semaphore_khr
}
numProperties = check - properties + 1;

if ( errorCode == CL_SUCCESS && type == ~0)
// The semaphore type must be included in the property list.
if( !found_CL_SEMAPHORE_TYPE_KHR )
{
errorCode = CL_INVALID_VALUE;
}

// validate device handles.
if (!devices.empty()) {
// for now - if CL_SEMAPHORE_DEVICE_HANDLE_LIST_KHR is specified
// as part of sema_props, but it does not identify exactly one
// valid device
if (devices.size() > 1) {
errorCode = CL_INVALID_DEVICE;
} else {
// if a device identified by CL_SEMAPHORE_DEVICE_HANDLE_LIST_KHR
// is not one of the devices within context
std::vector<cl_semaphore_type_khr> types;
for (auto device : devices) {
if (device == nullptr ||
!isDeviceWithinContext(context, device)) {
if( devices.empty() )
{
// If the device handle list is empty, the semaphore is
// accessible to all devices in the context, and the context
// must be a single-device context.
cl_uint numDevices = 0;
g_pNextDispatch->clGetContextInfo(
context,
CL_CONTEXT_NUM_DEVICES,
sizeof(cl_uint),
&numDevices,
nullptr);
if( numDevices != 1 )
{
errorCode = CL_INVALID_PROPERTY;
}
}
else
{
// If the device handle list is present, it must contain
// exactly one device.
if( devices.size() != 1 )
{
errorCode = CL_INVALID_DEVICE;
break;
}
}
}
else
{
// Additionally, the device must be within the context.
for( auto device : devices )
{
if( device == nullptr ||
!isDeviceWithinContext(context, device) )
{
errorCode = CL_INVALID_DEVICE;
break;
}
}
}
}
}

if (errorCode == CL_SUCCESS) {
switch (type) {
case CL_SEMAPHORE_TYPE_BINARY_KHR:
break;
default:
errorCode = CL_INVALID_PROPERTY;
}
}
if (errcode_ret) {
errcode_ret[0] = errorCode;
if( errcode_ret )
{
errcode_ret[0] = errorCode;
}
if( errorCode == CL_SUCCESS )
{
Expand All @@ -168,7 +208,6 @@ typedef struct _cl_semaphore_khr
semaphore->Properties.begin(),
properties,
properties + numProperties );

semaphore->Devices=devices;
}
return semaphore;
Expand Down Expand Up @@ -196,7 +235,7 @@ typedef struct _cl_semaphore_khr
Context(context),
Type(type),
RefCount(1),
Event(NULL) {}
Event(nullptr) {}
} cli_semaphore;

cl_semaphore_khr CL_API_CALL clCreateSemaphoreWithPropertiesKHR_EMU(
Expand Down Expand Up @@ -236,7 +275,7 @@ cl_int CL_API_CALL clEnqueueWaitSemaphoresKHR_EMU(
{
return CL_INVALID_SEMAPHORE_KHR;
}
if( semaphores[i]->Event == NULL )
if( semaphores[i]->Event == nullptr )
{
// This is a semaphore that is not in a pending signal
// or signaled state. What should happen here?
Expand All @@ -256,7 +295,7 @@ cl_int CL_API_CALL clEnqueueWaitSemaphoresKHR_EMU(
{
g_pNextDispatch->clReleaseEvent(
semaphores[i]->Event);
semaphores[i]->Event = NULL;
semaphores[i]->Event = nullptr;
}

if( event )
Expand Down Expand Up @@ -287,16 +326,16 @@ cl_int CL_API_CALL clEnqueueSignalSemaphoresKHR_EMU(
{
return CL_INVALID_SEMAPHORE_KHR;
}
if( semaphores[i]->Event != NULL )
if( semaphores[i]->Event != nullptr )
{
// This is a semaphore that is in a pending signal or signaled
// state. What should happen here?
return CL_INVALID_OPERATION;
}
}

cl_event local_event = NULL;
if( event == NULL )
cl_event local_event = nullptr;
if( event == nullptr )
{
event = &local_event;
}
Expand All @@ -314,11 +353,11 @@ cl_int CL_API_CALL clEnqueueSignalSemaphoresKHR_EMU(
semaphores[i]->Event );
}

if( local_event != NULL )
if( local_event != nullptr )
{
g_pNextDispatch->clReleaseEvent(
local_event );
local_event = NULL;
local_event = nullptr;
}
else
{
Expand Down Expand Up @@ -386,15 +425,15 @@ cl_int CL_API_CALL clGetSemaphoreInfoKHR_EMU(
// semaphore is in the unsignaled state and one if it is in
// the signaled state.
cl_semaphore_payload_khr payload = 0;
if( semaphore->Event != NULL )
if( semaphore->Event != nullptr )
{
cl_int eventStatus = 0;
g_pNextDispatch->clGetEventInfo(
semaphore->Event,
CL_EVENT_COMMAND_EXECUTION_STATUS,
sizeof( eventStatus ),
&eventStatus,
NULL );
nullptr );
if( eventStatus == CL_COMPLETE )
{
payload = 1;
Expand Down Expand Up @@ -555,7 +594,7 @@ bool clGetDeviceInfo_override(
memset(extension.name, 0, CL_NAME_VERSION_MAX_NAME_SIZE);
strcpy(extension.name, CL_KHR_SEMAPHORE_EXTENSION_NAME);

extension.version = CL_MAKE_VERSION(0, 9, 0);
extension.version = version_cl_khr_semaphore;

auto ptr = (cl_name_version*)param_value;
cl_int errorCode = writeVectorToMemory(
Expand Down Expand Up @@ -734,7 +773,7 @@ bool clGetPlatformInfo_override(
memset(extension.name, 0, CL_NAME_VERSION_MAX_NAME_SIZE);
strcpy(extension.name, CL_KHR_SEMAPHORE_EXTENSION_NAME);

extension.version = CL_MAKE_VERSION(0, 9, 0);
extension.version = version_cl_khr_semaphore;

auto ptr = (cl_name_version*)param_value;
cl_int errorCode = writeVectorToMemory(
Expand Down
17 changes: 16 additions & 1 deletion layers/11_semaemu/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,17 @@ clGetEventInfo_layer(

return errorCode;
}

static cl_int CL_API_CALL
clGetSemaphoreHandleForTypeKHR_EMU(
cl_semaphore_khr sema_object,
cl_device_id device,
cl_external_semaphore_handle_type_khr handle_type,
size_t handle_size,
void* handle_ptr,
size_t* handle_size_ret)
{
return CL_INVALID_OPERATION;
}

#define CHECK_RETURN_EXTENSION_FUNCTION( _funcname ) \
if (strcmp(func_name, #_funcname) == 0) { \
Expand All @@ -109,6 +119,11 @@ clGetExtensionFunctionAddressForPlatform_layer(
CHECK_RETURN_EXTENSION_FUNCTION( clRetainSemaphoreKHR );
CHECK_RETURN_EXTENSION_FUNCTION( clReleaseSemaphoreKHR );

// This is currently required to run the semaphore conformance tests,
// although it is part of cl_khr_external_semaphore, and not part of
// cl_khr_semaphore.
CHECK_RETURN_EXTENSION_FUNCTION( clGetSemaphoreHandleForTypeKHR );

return g_pNextDispatch->clGetExtensionFunctionAddressForPlatform(
platform,
func_name);
Expand Down

0 comments on commit 7f1ebe9

Please sign in to comment.