Skip to content

Commit

Permalink
Merge pull request #1116 from pbalcer/fix-loader-getinfo-handles
Browse files Browse the repository at this point in the history
[loader] perform handle conversion after info queries
  • Loading branch information
pbalcer committed Jan 23, 2024
2 parents b05c5b5 + 81c8b1b commit 2a82754
Show file tree
Hide file tree
Showing 14 changed files with 931 additions and 55 deletions.
2 changes: 1 addition & 1 deletion include/ur_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -5103,7 +5103,7 @@ urKernelCreateWithNativeHandle(
///////////////////////////////////////////////////////////////////////////////
/// @brief Query queue info
typedef enum ur_queue_info_t {
UR_QUEUE_INFO_CONTEXT = 0, ///< [::ur_queue_handle_t] context associated with this queue.
UR_QUEUE_INFO_CONTEXT = 0, ///< [::ur_context_handle_t] context associated with this queue.
UR_QUEUE_INFO_DEVICE = 1, ///< [::ur_device_handle_t] device associated with this queue.
UR_QUEUE_INFO_DEVICE_DEFAULT = 2, ///< [::ur_queue_handle_t] the current default queue of the underlying
///< device.
Expand Down
6 changes: 3 additions & 3 deletions include/ur_print.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8018,9 +8018,9 @@ inline ur_result_t printTagged(std::ostream &os, const void *ptr, ur_queue_info_

switch (value) {
case UR_QUEUE_INFO_CONTEXT: {
const ur_queue_handle_t *tptr = (const ur_queue_handle_t *)ptr;
if (sizeof(ur_queue_handle_t) > size) {
os << "invalid size (is: " << size << ", expected: >=" << sizeof(ur_queue_handle_t) << ")";
const ur_context_handle_t *tptr = (const ur_context_handle_t *)ptr;
if (sizeof(ur_context_handle_t) > size) {
os << "invalid size (is: " << size << ", expected: >=" << sizeof(ur_context_handle_t) << ")";
return UR_RESULT_ERROR_INVALID_SIZE;
}
os << (const void *)(tptr) << " (";
Expand Down
2 changes: 1 addition & 1 deletion scripts/core/queue.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ name: $x_queue_info_t
typed_etors: True
etors:
- name: CONTEXT
desc: "[$x_queue_handle_t] context associated with this queue."
desc: "[$x_context_handle_t] context associated with this queue."
- name: DEVICE
desc: "[$x_device_handle_t] device associated with this queue."
- name: DEVICE_DEFAULT
Expand Down
85 changes: 78 additions & 7 deletions scripts/templates/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@ def is_handle(obj):
except:
return False

@staticmethod
def is_enum(obj):
try:
return True if re.match(r"enum", obj['type']) else False
except:
return False

@staticmethod
def is_experimental(obj):
try:
Expand Down Expand Up @@ -449,6 +456,13 @@ def is_release(cls, item):
except:
return False

@classmethod
def is_typename(cls, item):
try:
return True if re.match(cls.RE_TYPENAME, item['desc']) else False
except:
return False

@classmethod
def typename(cls, item):
match = re.match(cls.RE_TYPENAME, item['desc'])
Expand Down Expand Up @@ -1241,24 +1255,43 @@ def get_loader_prologue(namespace, tags, obj, meta):

return prologue

"""
Public:
returns an enum object with the given name
"""
def get_enum_by_name(specs, namespace, tags, name, only_typed):
for s in specs:
for obj in s['objects']:
if obj_traits.is_enum(obj) and make_enum_name(namespace, tags, obj) == name:
typed = obj.get('typed_etors', False) is True
if only_typed:
if typed:
return obj
else:
return None
else:
return obj
return None

"""
Public:
returns a list of dict for converting loader output parameters
"""
def get_loader_epilogue(namespace, tags, obj, meta):
def get_loader_epilogue(specs, namespace, tags, obj, meta):
epilogue = []

for i, item in enumerate(obj['params']):
if param_traits.is_mbz(item):
continue
if param_traits.is_release(item) or param_traits.is_output(item) or param_traits.is_inoutput(item):
if type_traits.is_class_handle(item['type'], meta):
name = subt(namespace, tags, item['name'])
tname = _remove_const_ptr(subt(namespace, tags, item['type']))

obj_name = re.sub(r"(\w+)_handle_t", r"\1_object_t", tname)
fty_name = re.sub(r"(\w+)_handle_t", r"\1_factory", tname)
name = subt(namespace, tags, item['name'])
tname = _remove_const_ptr(subt(namespace, tags, item['type']))

obj_name = re.sub(r"(\w+)_handle_t", r"\1_object_t", tname)
fty_name = re.sub(r"(\w+)_handle_t", r"\1_factory", tname)

if param_traits.is_release(item) or param_traits.is_output(item) or param_traits.is_inoutput(item):
if type_traits.is_class_handle(item['type'], meta):
if param_traits.is_range(item):
range_start = param_traits.range_start(item)
range_end = param_traits.range_end(item)
Expand All @@ -1279,6 +1312,44 @@ def get_loader_epilogue(namespace, tags, obj, meta):
'release': param_traits.is_release(item),
'optional': param_traits.is_optional(item)
})
elif param_traits.is_typename(item):
typename = param_traits.typename(item)
underlying_type = None
for inner in obj['params']:
iname = _get_param_name(namespace, tags, inner)
if iname == typename:
underlying_type = _get_type_name(namespace, tags, obj, inner)
if underlying_type is None:
continue

prop_size = param_traits.typename_size(item)
enum = get_enum_by_name(specs, namespace, tags, underlying_type, True)
handle_etors = []
for etor in enum['etors']:
associated_type = etor_get_associated_type(namespace, tags, etor)
if 'handle' in associated_type:
is_array = False
if value_traits.is_array(associated_type):
associated_type = value_traits.get_array_name(associated_type)
is_array = True

etor_name = make_etor_name(namespace, tags, enum['name'], etor['name'])
obj_name = re.sub(r"(\w+)_handle_t", r"\1_object_t", associated_type)
fty_name = re.sub(r"(\w+)_handle_t", r"\1_factory", associated_type)
handle_etors.append({'name': etor_name,
'type': associated_type,
'obj': obj_name,
'factory': fty_name,
'is_array': is_array})

if handle_etors:
epilogue.append({
'name': name,
'obj': obj_name,
'release': False,
'typename': typename,
'size': prop_size,
'etors': handle_etors})

return epilogue

Expand Down
42 changes: 39 additions & 3 deletions scripts/templates/ldrddi.cpp.mako
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,23 @@ namespace ur_loader
%endif
%endfor
<%
epilogue = th.get_loader_epilogue(specs, n, tags, obj, meta)
has_typename = False
for item in epilogue:
if 'typename' in item:
has_typename = True
break
%>
%if has_typename:
// this value is needed for converting adapter handles to loader handles
size_t sizeret = 0;
if (pPropSizeRet == NULL)
pPropSizeRet = &sizeret;
%endif
// forward to device-platform
%if add_local:
result = ${th.make_pfn_name(n, tags, obj)}( ${", ".join(th.make_param_lines(n, tags, obj, format=["name", "local"], replacements=param_replacements))} );
Expand All @@ -168,8 +185,9 @@ namespace ur_loader
%endif
<%
del param_replacements
del add_local%>
%for i, item in enumerate(th.get_loader_epilogue(n, tags, obj, meta)):
del add_local
%>
%for i, item in enumerate(epilogue):
%if 0 == i:
if( ${X}_RESULT_SUCCESS != result )
return result;
Expand All @@ -181,7 +199,25 @@ namespace ur_loader
%elif not '_native_object_' in item['obj'] or th.make_func_name(n, tags, obj) == 'urPlatformCreateWithNativeHandle':
try
{
%if 'range' in item:
%if 'typename' in item:
if (${item['name']} != nullptr) {
switch (${item['typename']}) {
%for etor in item['etors']:
case ${etor['name']}: {
${etor['type']} *handles = reinterpret_cast<${etor['type']} *>(${item['name']});
size_t nelements = *pPropSizeRet / sizeof(${etor['type']});
for (size_t i = 0; i < nelements; ++i) {
if (handles[i] != nullptr) {
handles[i] = reinterpret_cast<${etor['type']}>(
${etor['factory']}.getInstance( handles[i], dditable ) );
}
}
} break;
%endfor
default: {} break;
}
}
%elif 'range' in item:
// convert platform handles to loader handles
for( size_t i = ${item['range'][0]}; ( nullptr != ${item['name']} ) && ( i < ${item['range'][1]} ); ++i )
${item['name']}[ i ] = reinterpret_cast<${item['type']}>(
Expand Down
19 changes: 17 additions & 2 deletions scripts/templates/nullddi.cpp.mako
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,23 @@ namespace driver
else
{
// generic implementation
%for item in th.get_loader_epilogue(n, tags, obj, meta):
%if 'range' in item:
%for item in th.get_loader_epilogue(specs, n, tags, obj, meta):
%if 'typename' in item:
if (${item['name']} != nullptr) {
switch (${item['typename']}) {
%for etor in item['etors']:
case ${etor['name']}: {
${etor['type']} *handles = reinterpret_cast<${etor['type']} *>(${item['name']});
size_t nelements = ${item['size']} / sizeof(${etor['type']});
for (size_t i = 0; i < nelements; ++i) {
handles[i] = reinterpret_cast<${etor['type']}>( d_context.get() );
}
} break;
%endfor
default: {} break;
}
}
%elif 'range' in item:
for( size_t i = ${item['range'][0]}; ( nullptr != ${item['name']} ) && ( i < ${item['range'][1]} ); ++i )
${item['name']}[ i ] = reinterpret_cast<${item['type']}>( d_context.get() );
%elif not item['release']:
Expand Down
88 changes: 50 additions & 38 deletions source/adapters/null/ur_null.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ context_t d_context;

//////////////////////////////////////////////////////////////////////////
context_t::context_t() {
platform = get();
//////////////////////////////////////////////////////////////////////////
urDdiTable.Global.pfnAdapterGet = [](uint32_t NumAdapters,
ur_adapter_handle_t *phAdapters,
Expand All @@ -28,7 +29,7 @@ context_t::context_t() {
*pNumAdapters = 1;
}
if (nullptr != phAdapters) {
*reinterpret_cast<void **>(phAdapters) = d_context.get();
*reinterpret_cast<void **>(phAdapters) = d_context.platform;
}

return UR_RESULT_SUCCESS;
Expand All @@ -48,7 +49,7 @@ context_t::context_t() {
*pNumPlatforms = 1;
}
if (nullptr != phPlatforms) {
*reinterpret_cast<void **>(phPlatforms) = d_context.get();
*reinterpret_cast<void **>(phPlatforms) = d_context.platform;
}
return UR_RESULT_SUCCESS;
};
Expand Down Expand Up @@ -120,48 +121,59 @@ context_t::context_t() {
};

//////////////////////////////////////////////////////////////////////////
urDdiTable.Device.pfnGetInfo =
[](ur_device_handle_t, ur_device_info_t infoType, size_t propSize,
void *pDeviceInfo, size_t *pPropSizeRet) {
switch (infoType) {
case UR_DEVICE_INFO_TYPE:
if (pDeviceInfo && propSize != sizeof(ur_device_type_t)) {
return UR_RESULT_ERROR_INVALID_SIZE;
}
urDdiTable.Device.pfnGetInfo = [](ur_device_handle_t,
ur_device_info_t infoType,
size_t propSize, void *pDeviceInfo,
size_t *pPropSizeRet) {
switch (infoType) {
case UR_DEVICE_INFO_TYPE:
if (pDeviceInfo && propSize != sizeof(ur_device_type_t)) {
return UR_RESULT_ERROR_INVALID_SIZE;
}

if (pDeviceInfo != nullptr) {
*reinterpret_cast<ur_device_type_t *>(pDeviceInfo) =
UR_DEVICE_TYPE_GPU;
}
if (pPropSizeRet != nullptr) {
*pPropSizeRet = sizeof(ur_device_type_t);
}
break;
if (pDeviceInfo != nullptr) {
*reinterpret_cast<ur_device_type_t *>(pDeviceInfo) =
UR_DEVICE_TYPE_GPU;
}
if (pPropSizeRet != nullptr) {
*pPropSizeRet = sizeof(ur_device_type_t);
}
break;

case UR_DEVICE_INFO_NAME: {
char deviceName[] = "Null Device";
if (pDeviceInfo && propSize < sizeof(deviceName)) {
return UR_RESULT_ERROR_INVALID_SIZE;
}
if (pDeviceInfo != nullptr) {
case UR_DEVICE_INFO_NAME: {
char deviceName[] = "Null Device";
if (pDeviceInfo && propSize < sizeof(deviceName)) {
return UR_RESULT_ERROR_INVALID_SIZE;
}
if (pDeviceInfo != nullptr) {
#if defined(_WIN32)
strncpy_s(reinterpret_cast<char *>(pDeviceInfo), propSize,
deviceName, sizeof(deviceName));
strncpy_s(reinterpret_cast<char *>(pDeviceInfo), propSize,
deviceName, sizeof(deviceName));
#else
strncpy(reinterpret_cast<char *>(pDeviceInfo), deviceName,
propSize);
strncpy(reinterpret_cast<char *>(pDeviceInfo), deviceName,
propSize);
#endif
}
if (pPropSizeRet != nullptr) {
*pPropSizeRet = sizeof(deviceName);
}
} break;

default:
return UR_RESULT_ERROR_INVALID_ARGUMENT;
}
return UR_RESULT_SUCCESS;
};
if (pPropSizeRet != nullptr) {
*pPropSizeRet = sizeof(deviceName);
}
} break;
case UR_DEVICE_INFO_PLATFORM: {
if (pDeviceInfo && propSize < sizeof(pDeviceInfo)) {
return UR_RESULT_ERROR_INVALID_SIZE;
}
if (pDeviceInfo != nullptr) {
*reinterpret_cast<void **>(pDeviceInfo) = d_context.platform;
}
if (pPropSizeRet != nullptr) {
*pPropSizeRet = sizeof(intptr_t);
}
} break;
default:
return UR_RESULT_ERROR_INVALID_ARGUMENT;
}
return UR_RESULT_SUCCESS;
};

//////////////////////////////////////////////////////////////////////////
urDdiTable.USM.pfnHostAlloc = [](ur_context_handle_t, const ur_usm_desc_t *,
Expand Down
3 changes: 3 additions & 0 deletions source/adapters/null/ur_null.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
* @file ur_null.hpp
*
*/
#include "ur_api.h"
#ifndef UR_ADAPTER_NULL_H
#define UR_ADAPTER_NULL_H 1

Expand All @@ -27,6 +28,8 @@ class __urdlllocal context_t {
context_t();
~context_t() = default;

void *platform;

void *get() {
static uint64_t count = 0x80800000;
return reinterpret_cast<void *>(++count);
Expand Down
Loading

0 comments on commit 2a82754

Please sign in to comment.