Skip to content

Commit 078d46c

Browse files
kswiecickipbalcer
andauthored
[UR][L0v2] Introduce static linking option (#21845)
Co-authored-by: Piotr Balcer <piotr.balcer@intel.com>
1 parent 1d40d57 commit 078d46c

135 files changed

Lines changed: 12009 additions & 7133 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

sycl/cmake/modules/BuildUnifiedRuntime.cmake

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,8 @@ if(CMAKE_SYSTEM_NAME STREQUAL Windows)
223223
-DUR_BUILD_ADAPTER_HIP:BOOL=${UR_BUILD_ADAPTER_HIP}
224224
-DUR_BUILD_ADAPTER_NATIVE_CPU:BOOL=${UR_BUILD_ADAPTER_NATIVE_CPU}
225225
-DUR_STATIC_LOADER:BOOL=${UR_STATIC_LOADER}
226+
-DUR_STATIC_ADAPTER_L0:BOOL=${UR_STATIC_ADAPTER_L0}
227+
-DUR_STATIC_ADAPTER_L0_V2:BOOL=${UR_STATIC_ADAPTER_L0_V2}
226228
-DUR_STATIC_ADAPTER_OPENCL:BOOL=${UR_STATIC_ADAPTER_OPENCL}
227229
-DUMF_BUILD_EXAMPLES:BOOL=${UMF_BUILD_EXAMPLES}
228230
-DUMF_BUILD_SHARED_LIBRARY:BOOL=${UMF_BUILD_SHARED_LIBRARY}
@@ -272,16 +274,50 @@ if(CMAKE_SYSTEM_NAME STREQUAL Windows)
272274
${LLVM_BINARY_DIR}/lib/ur_loaderd.lib
273275
${LLVM_BINARY_DIR}/lib/ur_commond.lib
274276
dbghelp)
277+
set(_urd_static_l0 FALSE)
275278
# Link static adapters into the loader
276279
foreach(adapter ${SYCL_ENABLE_BACKENDS})
277280
ur_adapter_is_static(${adapter} adapter_is_static)
278-
set(build_var "UR_BUILD_ADAPTER_${adapter}")
279-
string(TOUPPER "${build_var}" build_var)
281+
# The Level Zero adapters use the abbreviated build flags
282+
# UR_BUILD_ADAPTER_L0 / _L0_V2 rather than the backend name.
283+
string(TOUPPER "${adapter}" adapter_upper)
284+
if(adapter_upper STREQUAL "LEVEL_ZERO")
285+
set(build_var "UR_BUILD_ADAPTER_L0")
286+
elseif(adapter_upper STREQUAL "LEVEL_ZERO_V2")
287+
set(build_var "UR_BUILD_ADAPTER_L0_V2")
288+
else()
289+
set(build_var "UR_BUILD_ADAPTER_${adapter_upper}")
290+
endif()
280291
if(adapter_is_static AND DEFINED ${build_var} AND ${build_var})
281292
target_link_libraries(UnifiedRuntimeLoaderDebug INTERFACE
282293
${LLVM_BINARY_DIR}/lib/ur_adapter_${adapter}d.lib)
294+
if(build_var STREQUAL "UR_BUILD_ADAPTER_L0" OR
295+
build_var STREQUAL "UR_BUILD_ADAPTER_L0_V2")
296+
set(_urd_static_l0 TRUE)
297+
endif()
283298
endif()
284299
endforeach()
300+
# A static umfd.lib does not absorb its private helper archives, so link
301+
# them too. umfd and the helpers are copied below.
302+
target_link_libraries(UnifiedRuntimeLoaderDebug INTERFACE
303+
${LLVM_BINARY_DIR}/lib/umfd.lib
304+
${LLVM_BINARY_DIR}/lib/umf_bad.lib
305+
${LLVM_BINARY_DIR}/lib/umf_utilsd.lib
306+
${LLVM_BINARY_DIR}/lib/umf_coarsed.lib)
307+
if(_urd_static_l0)
308+
# The static L0 adapters need ze_loader. Copy the debug-CRT ze_loader
309+
# from the debug sub-build under a 'd' name (it has no debug postfix, so
310+
# copying it as-is would collide with the release in-tree ze_loader.lib).
311+
list(APPEND URD_COPY_FILES ${LLVM_BINARY_DIR}/lib/ze_loaderd.lib)
312+
add_custom_command(
313+
OUTPUT ${LLVM_BINARY_DIR}/lib/ze_loaderd.lib
314+
COMMAND ${CMAKE_COMMAND} -E copy
315+
${URD_INSTALL_DIR}/lib/ze_loader.lib
316+
${LLVM_BINARY_DIR}/lib/ze_loaderd.lib
317+
)
318+
target_link_libraries(UnifiedRuntimeLoaderDebug INTERFACE
319+
${LLVM_BINARY_DIR}/lib/ze_loaderd.lib)
320+
endif()
285321
endif()
286322
foreach(adapter ${SYCL_ENABLE_BACKENDS})
287323
ur_adapter_is_static(${adapter} adapter_is_static)
@@ -294,6 +330,22 @@ if(CMAKE_SYSTEM_NAME STREQUAL Windows)
294330
endforeach()
295331
# Also copy umfd.dll/umfd.lib
296332
urd_copy_library_to_build(umfd ${UMF_BUILD_SHARED_LIBRARY})
333+
# A static umfd.lib doesn't absorb its private helper archives (umf_ba /
334+
# umf_utils / umf_coarse), so a consumer linking umfd.lib must link them too.
335+
# They aren't installed, but the debug sub-build produces them (debug CRT) at
336+
# ${URD_BINARY_DIR}/lib without a 'd' postfix, so copy them under a 'd' name.
337+
if(NOT UMF_BUILD_SHARED_LIBRARY)
338+
foreach(_umfd_helper umf_ba umf_utils umf_coarse)
339+
list(APPEND URD_COPY_FILES ${LLVM_BINARY_DIR}/lib/${_umfd_helper}d.lib)
340+
add_custom_command(
341+
OUTPUT ${LLVM_BINARY_DIR}/lib/${_umfd_helper}d.lib
342+
COMMAND ${CMAKE_COMMAND} -E copy
343+
${URD_BINARY_DIR}/lib/${_umfd_helper}.lib
344+
${LLVM_BINARY_DIR}/lib/${_umfd_helper}d.lib
345+
DEPENDS unified-runtimed
346+
)
347+
endforeach()
348+
endif()
297349

298350
add_custom_target(unified-runtimed-build ALL DEPENDS ${URD_COPY_FILES})
299351
add_dependencies(unified-runtimed-build unified-runtimed)

sycl/test-e2e/Adapters/dll-detach-order.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,5 @@
88

99
// whatever adapter THIS is
1010
// CHECK: ---> urAdapterRelease
11-
// CHECK: <LOADER>[INFO]: unloaded adapter
1211

1312
// CHECK: ---> urLoaderTearDown

sycl/ur_win_proxy_loader/ur_win_proxy_loader.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,8 @@ void preloadLibraries() {
151151
// unloaded prematurely. the Only trusted loader is the one that is loaded
152152
// from the system32 directory.
153153
LoadLibraryExW(L"ze_loader.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
154+
// Load the OpenCL ICD loader dynamic library, for the same reason as above.
155+
LoadLibraryExW(L"OpenCL.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
154156

155157
// Restore system error handling.
156158
(void)SetErrorMode(SavedMode);

unified-runtime/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,9 @@ option(UR_BUILD_ADAPTER_NATIVE_CPU "Build the Native-CPU adapter" OFF)
4747
option(UR_BUILD_ADAPTER_ALL "Build all currently supported adapters" OFF)
4848
option(UR_BUILD_ADAPTER_L0_V2 "Build the (experimental) Level-Zero v2 adapter" OFF)
4949
option(UR_BUILD_ADAPTER_OFFLOAD "Build the experimental Offload adapter" OFF)
50-
option(UR_STATIC_ADAPTER_L0 "Build the Level-Zero adapter as static and embed in the loader" OFF)
50+
option(UR_STATIC_ADAPTER_L0 "Build the Level-Zero adapter as static and embed in the loader" ON)
5151
option(UR_STATIC_ADAPTER_OPENCL "Build the OpenCL adapter as static library with dynamic OpenCL loading" ON)
52+
option(UR_STATIC_ADAPTER_L0_V2 "Build the Level-Zero v2 adapter as static and embed in the loader" ON)
5253
option(UR_BUILD_EXAMPLE_CODEGEN "Build the codegen example." OFF)
5354
option(VAL_USE_LIBBACKTRACE_BACKTRACE "enable libbacktrace validation backtrace for linux" OFF)
5455
option(UR_ENABLE_ASSERTIONS "Enable assertions for all build types" OFF)

unified-runtime/cmake/FetchLevelZero.cmake

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,16 @@ if(NOT LEVEL_ZERO_LIB_NAME AND NOT LEVEL_ZERO_LIBRARY)
9090

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

97105
add_library(LevelZeroLoader INTERFACE)

unified-runtime/cmake/helpers.cmake

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,9 +303,13 @@ function(ur_adapter_is_static adapter out_var)
303303
set(static_var "UR_STATIC_ADAPTER_${adapter}")
304304
string(TOUPPER "${static_var}" static_var)
305305
string(TOUPPER "${adapter}" adapter)
306-
# Special case: LEVEL_ZERO uses UR_STATIC_ADAPTER_L0
306+
# Special case: the Level Zero adapters use the abbreviated flag names
307+
# UR_STATIC_ADAPTER_L0 / UR_STATIC_ADAPTER_L0_V2 rather than the backend
308+
# name (LEVEL_ZERO / LEVEL_ZERO_V2).
307309
if(adapter STREQUAL "LEVEL_ZERO")
308310
set(static_var "UR_STATIC_ADAPTER_L0")
311+
elseif(adapter STREQUAL "LEVEL_ZERO_V2")
312+
set(static_var "UR_STATIC_ADAPTER_L0_V2")
309313
endif()
310314
if(DEFINED ${static_var} AND ${static_var})
311315
set(${out_var} TRUE PARENT_SCOPE)

unified-runtime/scripts/generate_code.py

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -417,10 +417,9 @@ def generate_loader(path, section, namespace, tags, version, specs, meta):
417417

418418

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

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

464+
level_zero_dstpath = os.path.join(path, "adapters", "level_zero")
465465
loc += _mako_interface_loader_api(
466-
dstpath, "level_zero", "cpp", namespace, tags, version, specs, meta
466+
level_zero_dstpath, "level_zero", "cpp", namespace, tags, version, specs, meta
467467
)
468468
loc += _mako_interface_loader_api(
469-
dstpath, "level_zero", "hpp", namespace, tags, version, specs, meta
469+
level_zero_dstpath, "level_zero", "hpp", namespace, tags, version, specs, meta
470+
)
471+
level_zero_v2_dstpath = os.path.join(level_zero_dstpath, "v2")
472+
loc += _mako_interface_loader_api(
473+
level_zero_v2_dstpath,
474+
"level_zero_v2",
475+
"cpp",
476+
namespace,
477+
tags,
478+
version,
479+
specs,
480+
meta,
481+
)
482+
loc += _mako_interface_loader_api(
483+
level_zero_v2_dstpath,
484+
"level_zero_v2",
485+
"hpp",
486+
namespace,
487+
tags,
488+
version,
489+
specs,
490+
meta,
470491
)
471492
loc += _mako_interface_loader_api(
472493
dstpath, "opencl", "cpp", namespace, tags, version, specs, meta

unified-runtime/scripts/templates/helper.py

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -967,6 +967,7 @@ def make_param_lines(
967967
format: List[str] = ["type", "name", "delim", "desc"],
968968
delim: str = ",",
969969
replacements: dict = {},
970+
global_handles: bool = False,
970971
):
971972
"""
972973
Public:
@@ -984,6 +985,12 @@ def make_param_lines(
984985

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

988+
# Qualify handle types with leading '::' so they resolve to the global
989+
# scope, not an enclosing adapter namespace's same-named internal type.
990+
if global_handles and type_traits.is_handle(tname):
991+
base = type_traits.base(tname) # strips const/* -> ur_X_handle_t
992+
tname = tname.replace(base, "::" + base, 1)
993+
987994
words = []
988995
if "type*" in format:
989996
ptname = tname + "*"
@@ -1707,22 +1714,44 @@ def get_queue_related_functions(specs: List[dict], namespace: str, tags) -> List
17071714
return funcs
17081715

17091716

1717+
# Handle types that have no adapter-internal alias: they resolve to the
1718+
# global type even inside an adapter namespace, so they are forwarded as-is
1719+
# (no cast) when bridging the public API into the internal queue interface.
1720+
_QUEUE_NO_CAST_HANDLES = ("native_handle_t", "external_semaphore_handle_t")
1721+
1722+
17101723
def transform_queue_related_function_name(
1711-
namespace, tags, obj, format=["name", "type"]
1724+
namespace, tags, obj, format=["name", "type"], cast_handles=False
17121725
) -> str:
17131726
"""
17141727
Public:
17151728
transform a queue related function using following rules:
17161729
- remove $x prefix
17171730
- make first letter lowercase
17181731
- remove first param (queue)
1732+
- if cast_handles, wrap each remaining handle argument in v2_cast()
1733+
so the global public-API handle is converted to the internal type
1734+
the queue interface method expects (native/external-semaphore
1735+
handles have no internal alias and are left as-is)
17191736
"""
17201737
function_name = make_func_name(namespace, tags, obj).replace(namespace, "")
17211738
function_name = function_name[0].lower() + function_name[1:]
17221739

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

1743+
if cast_handles:
1744+
args = []
1745+
for item in obj["params"][1:]:
1746+
name = _get_param_name(namespace, tags, item)
1747+
if type_traits.is_handle(item["type"]) and not any(
1748+
h in item["type"] for h in _QUEUE_NO_CAST_HANDLES
1749+
):
1750+
args.append("v2_cast(%s)" % name)
1751+
else:
1752+
args.append(name)
1753+
return "{}({})".format(function_name, ", ".join(args))
1754+
17261755
params = make_param_lines(namespace, tags, obj, format=format)
17271756
params = params[1:]
17281757

unified-runtime/scripts/templates/queue_api.cpp.mako

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,23 +25,24 @@ from templates import helper as th
2525
#include "queue_handle.hpp"
2626
#include "ur_util.hpp"
2727

28+
namespace ur::level_zero::v2 {
29+
2830
ur_queue_t_::~ur_queue_t_() {}
2931

3032
## FUNCTION ###################################################################
31-
namespace ${x}::level_zero {
3233
%for obj in th.get_queue_related_functions(specs, n, tags):
3334
%if not 'Release' in obj['name'] and not 'Retain' in obj['name']:
3435
%if 'guard' in obj:
3536
#if ${obj['guard']}
3637
%endif
3738
${x}_result_t
3839
${th.make_func_name(n, tags, obj)}(
39-
%for line in th.make_param_lines(n, tags, obj, format=["name", "type", "delim"]):
40+
%for line in th.make_param_lines(n, tags, obj, format=["name", "type", "delim"], global_handles=True):
4041
${line}
4142
%endfor
4243
)
4344
try {
44-
return ${obj['params'][0]['name']}->get().${th.transform_queue_related_function_name(n, tags, obj, format=["name"])};
45+
return v2_cast(${obj['params'][0]['name']})->get().${th.transform_queue_related_function_name(n, tags, obj, format=["name"], cast_handles=True)};
4546
} catch(...) {
4647
return exceptionToResult(std::current_exception());
4748
}
@@ -54,12 +55,12 @@ try {
5455
%endif
5556
${x}_result_t
5657
${th.make_func_name(n, tags, obj)}(
57-
%for line in th.make_param_lines(n, tags, obj, format=["name", "type", "delim"]):
58+
%for line in th.make_param_lines(n, tags, obj, format=["name", "type", "delim"], global_handles=True):
5859
${line}
5960
%endfor
6061
)
6162
try {
62-
return ${obj['params'][0]['name']}->${th.transform_queue_related_function_name(n, tags, obj, format=["name"])};
63+
return v2_cast(${obj['params'][0]['name']})->${th.transform_queue_related_function_name(n, tags, obj, format=["name"], cast_handles=True)};
6364
} catch(...) {
6465
return exceptionToResult(std::current_exception());
6566
}
@@ -68,4 +69,5 @@ try {
6869
%endif
6970
%endif
7071
%endfor
71-
}
72+
73+
} // namespace ur::level_zero::v2

unified-runtime/scripts/templates/queue_api.hpp.mako

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,11 @@ from templates import helper as th
2424
#pragma once
2525

2626
#include <unified-runtime/ur_api.h>
27+
#include "common.hpp"
2728
#include "queue_extensions.hpp"
2829

30+
namespace ur::level_zero::v2 {
31+
2932
struct ur_queue_t_ : ur_queue_extensions {
3033
virtual ~ur_queue_t_();
3134

@@ -41,3 +44,5 @@ struct ur_queue_t_ : ur_queue_extensions {
4144
%endif
4245
%endfor
4346
};
47+
48+
} // namespace ur::level_zero::v2

0 commit comments

Comments
 (0)