Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 54 additions & 2 deletions sycl/cmake/modules/BuildUnifiedRuntime.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,8 @@ if(CMAKE_SYSTEM_NAME STREQUAL Windows)
-DUR_BUILD_ADAPTER_HIP:BOOL=${UR_BUILD_ADAPTER_HIP}
-DUR_BUILD_ADAPTER_NATIVE_CPU:BOOL=${UR_BUILD_ADAPTER_NATIVE_CPU}
-DUR_STATIC_LOADER:BOOL=${UR_STATIC_LOADER}
-DUR_STATIC_ADAPTER_L0:BOOL=${UR_STATIC_ADAPTER_L0}
-DUR_STATIC_ADAPTER_L0_V2:BOOL=${UR_STATIC_ADAPTER_L0_V2}
-DUR_STATIC_ADAPTER_OPENCL:BOOL=${UR_STATIC_ADAPTER_OPENCL}
-DUMF_BUILD_EXAMPLES:BOOL=${UMF_BUILD_EXAMPLES}
-DUMF_BUILD_SHARED_LIBRARY:BOOL=${UMF_BUILD_SHARED_LIBRARY}
Expand Down Expand Up @@ -272,16 +274,50 @@ if(CMAKE_SYSTEM_NAME STREQUAL Windows)
${LLVM_BINARY_DIR}/lib/ur_loaderd.lib
${LLVM_BINARY_DIR}/lib/ur_commond.lib
dbghelp)
set(_urd_static_l0 FALSE)
# Link static adapters into the loader
foreach(adapter ${SYCL_ENABLE_BACKENDS})
ur_adapter_is_static(${adapter} adapter_is_static)
set(build_var "UR_BUILD_ADAPTER_${adapter}")
string(TOUPPER "${build_var}" build_var)
# The Level Zero adapters use the abbreviated build flags
# UR_BUILD_ADAPTER_L0 / _L0_V2 rather than the backend name.
string(TOUPPER "${adapter}" adapter_upper)
if(adapter_upper STREQUAL "LEVEL_ZERO")
set(build_var "UR_BUILD_ADAPTER_L0")
elseif(adapter_upper STREQUAL "LEVEL_ZERO_V2")
set(build_var "UR_BUILD_ADAPTER_L0_V2")
else()
set(build_var "UR_BUILD_ADAPTER_${adapter_upper}")
endif()
if(adapter_is_static AND DEFINED ${build_var} AND ${build_var})
target_link_libraries(UnifiedRuntimeLoaderDebug INTERFACE
${LLVM_BINARY_DIR}/lib/ur_adapter_${adapter}d.lib)
if(build_var STREQUAL "UR_BUILD_ADAPTER_L0" OR
build_var STREQUAL "UR_BUILD_ADAPTER_L0_V2")
set(_urd_static_l0 TRUE)
endif()
endif()
endforeach()
# A static umfd.lib does not absorb its private helper archives, so link
# them too. umfd and the helpers are copied below.
target_link_libraries(UnifiedRuntimeLoaderDebug INTERFACE
${LLVM_BINARY_DIR}/lib/umfd.lib
${LLVM_BINARY_DIR}/lib/umf_bad.lib
${LLVM_BINARY_DIR}/lib/umf_utilsd.lib
${LLVM_BINARY_DIR}/lib/umf_coarsed.lib)
if(_urd_static_l0)
# The static L0 adapters need ze_loader. Copy the debug-CRT ze_loader
# from the debug sub-build under a 'd' name (it has no debug postfix, so
# copying it as-is would collide with the release in-tree ze_loader.lib).
list(APPEND URD_COPY_FILES ${LLVM_BINARY_DIR}/lib/ze_loaderd.lib)
add_custom_command(
OUTPUT ${LLVM_BINARY_DIR}/lib/ze_loaderd.lib
COMMAND ${CMAKE_COMMAND} -E copy
${URD_INSTALL_DIR}/lib/ze_loader.lib
${LLVM_BINARY_DIR}/lib/ze_loaderd.lib
)
target_link_libraries(UnifiedRuntimeLoaderDebug INTERFACE
${LLVM_BINARY_DIR}/lib/ze_loaderd.lib)
endif()
endif()
foreach(adapter ${SYCL_ENABLE_BACKENDS})
ur_adapter_is_static(${adapter} adapter_is_static)
Expand All @@ -294,6 +330,22 @@ if(CMAKE_SYSTEM_NAME STREQUAL Windows)
endforeach()
# Also copy umfd.dll/umfd.lib
urd_copy_library_to_build(umfd ${UMF_BUILD_SHARED_LIBRARY})
# A static umfd.lib doesn't absorb its private helper archives (umf_ba /
# umf_utils / umf_coarse), so a consumer linking umfd.lib must link them too.
# They aren't installed, but the debug sub-build produces them (debug CRT) at
# ${URD_BINARY_DIR}/lib without a 'd' postfix, so copy them under a 'd' name.
if(NOT UMF_BUILD_SHARED_LIBRARY)
foreach(_umfd_helper umf_ba umf_utils umf_coarse)
list(APPEND URD_COPY_FILES ${LLVM_BINARY_DIR}/lib/${_umfd_helper}d.lib)
add_custom_command(
OUTPUT ${LLVM_BINARY_DIR}/lib/${_umfd_helper}d.lib
COMMAND ${CMAKE_COMMAND} -E copy
${URD_BINARY_DIR}/lib/${_umfd_helper}.lib
${LLVM_BINARY_DIR}/lib/${_umfd_helper}d.lib
DEPENDS unified-runtimed
)
endforeach()
endif()

add_custom_target(unified-runtimed-build ALL DEPENDS ${URD_COPY_FILES})
add_dependencies(unified-runtimed-build unified-runtimed)
Expand Down
3 changes: 2 additions & 1 deletion sycl/test-e2e/Adapters/dll-detach-order.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

// whatever adapter THIS is
// CHECK: ---> urAdapterRelease
// CHECK: <LOADER>[INFO]: unloaded adapter
// Statically-linked adapters have no library to unload, so the loader's
// "unloaded adapter" message is only emitted for dynamically-loaded adapters.

// CHECK: ---> urLoaderTearDown
2 changes: 2 additions & 0 deletions sycl/ur_win_proxy_loader/ur_win_proxy_loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,8 @@ void preloadLibraries() {
// unloaded prematurely. the Only trusted loader is the one that is loaded
// from the system32 directory.
LoadLibraryExW(L"ze_loader.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
// Load the OpenCL ICD loader dynamic library, for the same reason as above.
LoadLibraryExW(L"OpenCL.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);

// Restore system error handling.
(void)SetErrorMode(SavedMode);
Expand Down
3 changes: 2 additions & 1 deletion unified-runtime/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,9 @@ option(UR_BUILD_ADAPTER_NATIVE_CPU "Build the Native-CPU adapter" OFF)
option(UR_BUILD_ADAPTER_ALL "Build all currently supported adapters" OFF)
option(UR_BUILD_ADAPTER_L0_V2 "Build the (experimental) Level-Zero v2 adapter" OFF)
option(UR_BUILD_ADAPTER_OFFLOAD "Build the experimental Offload adapter" OFF)
option(UR_STATIC_ADAPTER_L0 "Build the Level-Zero adapter as static and embed in the loader" OFF)
option(UR_STATIC_ADAPTER_L0 "Build the Level-Zero adapter as static and embed in the loader" ON)
option(UR_STATIC_ADAPTER_OPENCL "Build the OpenCL adapter as static library with dynamic OpenCL loading" ON)
option(UR_STATIC_ADAPTER_L0_V2 "Build the Level-Zero v2 adapter as static and embed in the loader" ON)
option(UR_BUILD_EXAMPLE_CODEGEN "Build the codegen example." OFF)
option(VAL_USE_LIBBACKTRACE_BACKTRACE "enable libbacktrace validation backtrace for linux" OFF)
option(UR_ENABLE_ASSERTIONS "Enable assertions for all build types" OFF)
Expand Down
10 changes: 9 additions & 1 deletion unified-runtime/cmake/FetchLevelZero.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,16 @@ if(NOT LEVEL_ZERO_LIB_NAME AND NOT LEVEL_ZERO_LIBRARY)

target_compile_options(ze_loader PRIVATE
$<$<IN_LIST:$<CXX_COMPILER_ID>,GNU;Clang;Intel;IntelLLVM>:-Wno-error>
$<$<CXX_COMPILER_ID:MSVC>:/WX- /UUNICODE>
$<$<CXX_COMPILER_ID:MSVC>:/WX- /UUNICODE /GL->
)
# Neutralize the dllexport macros so a consuming DLL doesn't re-export the
# ze*/zes*/zel* symbols from this statically-linked loader.
if(WIN32 AND (UR_STATIC_ADAPTER_L0 OR UR_STATIC_ADAPTER_L0_V2))
target_compile_definitions(ze_loader PRIVATE
ZE_APIEXPORT=
ZE_DLLEXPORT=
)
endif()
endif()

add_library(LevelZeroLoader INTERFACE)
Expand Down
6 changes: 5 additions & 1 deletion unified-runtime/cmake/helpers.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -303,9 +303,13 @@ function(ur_adapter_is_static adapter out_var)
set(static_var "UR_STATIC_ADAPTER_${adapter}")
string(TOUPPER "${static_var}" static_var)
string(TOUPPER "${adapter}" adapter)
# Special case: LEVEL_ZERO uses UR_STATIC_ADAPTER_L0
# Special case: the Level Zero adapters use the abbreviated flag names
# UR_STATIC_ADAPTER_L0 / UR_STATIC_ADAPTER_L0_V2 rather than the backend
# name (LEVEL_ZERO / LEVEL_ZERO_V2).
if(adapter STREQUAL "LEVEL_ZERO")
set(static_var "UR_STATIC_ADAPTER_L0")
elseif(adapter STREQUAL "LEVEL_ZERO_V2")
set(static_var "UR_STATIC_ADAPTER_L0_V2")
endif()
if(DEFINED ${static_var} AND ${static_var})
set(${out_var} TRUE PARENT_SCOPE)
Expand Down
29 changes: 25 additions & 4 deletions unified-runtime/scripts/generate_code.py
Original file line number Diff line number Diff line change
Expand Up @@ -417,10 +417,9 @@ def generate_loader(path, section, namespace, tags, version, specs, meta):


def _mako_interface_loader_api(
path, adapter, ext, namespace, tags, version, specs, meta
dstpath, adapter, ext, namespace, tags, version, specs, meta
):
"""generates c/c++ files from the specification documents"""
dstpath = os.path.join(path, adapter)
os.makedirs(dstpath, exist_ok=True)

template = f"ur_interface_loader.{ext}.mako"
Expand Down Expand Up @@ -462,11 +461,33 @@ def generate_adapters(path, section, namespace, tags, version, specs, meta):
dstpath, "adapter", "def", namespace, tags, version, specs, meta
)

level_zero_dstpath = os.path.join(path, "adapters", "level_zero")
loc += _mako_interface_loader_api(
dstpath, "level_zero", "cpp", namespace, tags, version, specs, meta
level_zero_dstpath, "level_zero", "cpp", namespace, tags, version, specs, meta
)
loc += _mako_interface_loader_api(
dstpath, "level_zero", "hpp", namespace, tags, version, specs, meta
level_zero_dstpath, "level_zero", "hpp", namespace, tags, version, specs, meta
)
level_zero_v2_dstpath = os.path.join(level_zero_dstpath, "v2")
loc += _mako_interface_loader_api(
level_zero_v2_dstpath,
"level_zero_v2",
"cpp",
namespace,
tags,
version,
specs,
meta,
)
loc += _mako_interface_loader_api(
level_zero_v2_dstpath,
"level_zero_v2",
"hpp",
namespace,
tags,
version,
specs,
meta,
)
loc += _mako_interface_loader_api(
dstpath, "opencl", "cpp", namespace, tags, version, specs, meta
Expand Down
31 changes: 30 additions & 1 deletion unified-runtime/scripts/templates/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -967,6 +967,7 @@ def make_param_lines(
format: List[str] = ["type", "name", "delim", "desc"],
delim: str = ",",
replacements: dict = {},
global_handles: bool = False,
):
"""
Public:
Expand All @@ -984,6 +985,12 @@ def make_param_lines(

tname = _get_type_name(namespace, tags, obj, item)

# Qualify handle types with leading '::' so they resolve to the global
# scope, not an enclosing adapter namespace's same-named internal type.
if global_handles and type_traits.is_handle(tname):
base = type_traits.base(tname) # strips const/* -> ur_X_handle_t
tname = tname.replace(base, "::" + base, 1)

words = []
if "type*" in format:
ptname = tname + "*"
Expand Down Expand Up @@ -1707,22 +1714,44 @@ def get_queue_related_functions(specs: List[dict], namespace: str, tags) -> List
return funcs


# Handle types that have no adapter-internal alias: they resolve to the
# global type even inside an adapter namespace, so they are forwarded as-is
# (no cast) when bridging the public API into the internal queue interface.
_QUEUE_NO_CAST_HANDLES = ("native_handle_t", "external_semaphore_handle_t")


def transform_queue_related_function_name(
namespace, tags, obj, format=["name", "type"]
namespace, tags, obj, format=["name", "type"], cast_handles=False
) -> str:
"""
Public:
transform a queue related function using following rules:
- remove $x prefix
- make first letter lowercase
- remove first param (queue)
- if cast_handles, wrap each remaining handle argument in v2_cast()
so the global public-API handle is converted to the internal type
the queue interface method expects (native/external-semaphore
handles have no internal alias and are left as-is)
"""
function_name = make_func_name(namespace, tags, obj).replace(namespace, "")
function_name = function_name[0].lower() + function_name[1:]

if obj["params"][0]["type"] != "$x_queue_handle_t":
raise ValueError("First parameter is not a queue handle.")

if cast_handles:
args = []
for item in obj["params"][1:]:
name = _get_param_name(namespace, tags, item)
if type_traits.is_handle(item["type"]) and not any(
h in item["type"] for h in _QUEUE_NO_CAST_HANDLES
):
args.append("v2_cast(%s)" % name)
else:
args.append(name)
return "{}({})".format(function_name, ", ".join(args))

params = make_param_lines(namespace, tags, obj, format=format)
params = params[1:]

Expand Down
14 changes: 8 additions & 6 deletions unified-runtime/scripts/templates/queue_api.cpp.mako
Original file line number Diff line number Diff line change
Expand Up @@ -25,23 +25,24 @@ from templates import helper as th
#include "queue_handle.hpp"
#include "ur_util.hpp"

namespace ur::level_zero::v2 {

ur_queue_t_::~ur_queue_t_() {}

## FUNCTION ###################################################################
namespace ${x}::level_zero {
%for obj in th.get_queue_related_functions(specs, n, tags):
%if not 'Release' in obj['name'] and not 'Retain' in obj['name']:
%if 'guard' in obj:
#if ${obj['guard']}
%endif
${x}_result_t
${th.make_func_name(n, tags, obj)}(
%for line in th.make_param_lines(n, tags, obj, format=["name", "type", "delim"]):
%for line in th.make_param_lines(n, tags, obj, format=["name", "type", "delim"], global_handles=True):
${line}
%endfor
)
try {
return ${obj['params'][0]['name']}->get().${th.transform_queue_related_function_name(n, tags, obj, format=["name"])};
return v2_cast(${obj['params'][0]['name']})->get().${th.transform_queue_related_function_name(n, tags, obj, format=["name"], cast_handles=True)};
} catch(...) {
return exceptionToResult(std::current_exception());
}
Expand All @@ -54,12 +55,12 @@ try {
%endif
${x}_result_t
${th.make_func_name(n, tags, obj)}(
%for line in th.make_param_lines(n, tags, obj, format=["name", "type", "delim"]):
%for line in th.make_param_lines(n, tags, obj, format=["name", "type", "delim"], global_handles=True):
${line}
%endfor
)
try {
return ${obj['params'][0]['name']}->${th.transform_queue_related_function_name(n, tags, obj, format=["name"])};
return v2_cast(${obj['params'][0]['name']})->${th.transform_queue_related_function_name(n, tags, obj, format=["name"], cast_handles=True)};
} catch(...) {
return exceptionToResult(std::current_exception());
}
Expand All @@ -68,4 +69,5 @@ try {
%endif
%endif
%endfor
}

} // namespace ur::level_zero::v2
5 changes: 5 additions & 0 deletions unified-runtime/scripts/templates/queue_api.hpp.mako
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,11 @@ from templates import helper as th
#pragma once

#include <unified-runtime/ur_api.h>
#include "common.hpp"
#include "queue_extensions.hpp"

namespace ur::level_zero::v2 {

struct ur_queue_t_ : ur_queue_extensions {
virtual ~ur_queue_t_();

Expand All @@ -41,3 +44,5 @@ struct ur_queue_t_ : ur_queue_extensions {
%endif
%endfor
};

} // namespace ur::level_zero::v2
21 changes: 15 additions & 6 deletions unified-runtime/scripts/templates/ur_interface_loader.cpp.mako
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ from templates import helper as th
x=tags['$x']
X=x.upper()
Adapter=adapter.upper()
adapter_namespace={
'level_zero': 'ur::level_zero::v1',
'level_zero_v2': 'ur::level_zero::v2',
}.get(adapter, 'ur::'+adapter)
is_level_zero = adapter in ('level_zero', 'level_zero_v2')

%>//===--------- ${n}_interface_loader.cpp - Level Zero Adapter ------------===//
//
//
Expand Down Expand Up @@ -35,8 +41,11 @@ static ur_result_t validateProcInputs(ur_api_version_t version, void *pDdiTable)
return UR_RESULT_SUCCESS;
}

%if is_level_zero:
#include "ur_interface_loader_common_forwarders.hpp"
%endif
#ifdef UR_STATIC_ADAPTER_${Adapter}
namespace ${n}::${adapter} {
namespace ${adapter_namespace} {
#else
extern "C" {
#endif
Expand All @@ -60,7 +69,7 @@ ${X}_APIEXPORT ${x}_result_t ${X}_APICALL ${tbl['export']['name']}(
%if 'guard' in obj and 'guard' not in tbl:
#if ${obj['guard']}
%endif
pDdiTable->${th.append_ws(th.make_pfn_name(n, tags, obj), 43)} = ${n}::${adapter}::${th.make_func_name(n, tags, obj)};
pDdiTable->${th.append_ws(th.make_pfn_name(n, tags, obj), 43)} = ${adapter_namespace + '::' if is_level_zero else ''}${th.make_func_name(n, tags, obj)};
%if 'guard' in obj and 'guard' not in tbl:
#endif // ${obj['guard']}
%endif
Expand All @@ -75,7 +84,7 @@ ${X}_APIEXPORT ${x}_result_t ${X}_APICALL ${tbl['export']['name']}(
%endfor

#ifdef UR_STATIC_ADAPTER_${Adapter}
} // namespace ur::${adapter}
} // namespace ${adapter_namespace}
#else
} // extern "C"
#endif
Expand All @@ -89,7 +98,7 @@ ur_result_t populateDdiTable(ur_dditable_t *ddi) {
ur_result_t result;

#ifdef UR_STATIC_ADAPTER_${Adapter}
#define NAMESPACE_ ::ur::${adapter}
#define NAMESPACE_ ::${adapter_namespace}
#else
#define NAMESPACE_
#endif
Expand All @@ -113,7 +122,7 @@ ur_result_t populateDdiTable(ur_dditable_t *ddi) {
}


namespace ur::${adapter} {
namespace ${adapter_namespace} {
const ${x}_dditable_t *ddi_getter::value() {
static std::once_flag flag;
static ${x}_dditable_t table;
Expand All @@ -127,4 +136,4 @@ ur_result_t urAdapterGetDdiTables(${x}_dditable_t *ddi) {
return populateDdiTable(ddi);
}
#endif
}
} // namespace ${adapter_namespace}
Loading
Loading