Skip to content

Commit 809158f

Browse files
[UR][Offload] Add initial Offload adapter (#18271)
Add the initial implementation of the Offload adapter for UR. The adapter targets the new [liboffload](https://github.com/llvm/llvm-project/tree/main/offload/liboffload) library in LLVM. The adapter is **experimental** and is currently only maintained to drive development of liboffload by identifying and closing gaps with UR. --------- Co-authored-by: Ross Brunton <[email protected]>
1 parent 351f161 commit 809158f

34 files changed

+1805
-9
lines changed

unified-runtime/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ option(UR_BUILD_ADAPTER_HIP "Build the HIP adapter" OFF)
4747
option(UR_BUILD_ADAPTER_NATIVE_CPU "Build the Native-CPU adapter" OFF)
4848
option(UR_BUILD_ADAPTER_ALL "Build all currently supported adapters" OFF)
4949
option(UR_BUILD_ADAPTER_L0_V2 "Build the (experimental) Level-Zero v2 adapter" OFF)
50+
option(UR_BUILD_ADAPTER_OFFLOAD "Build the experimental Offload adapter" OFF)
5051
option(UR_STATIC_ADAPTER_L0 "Build the Level-Zero adapter as static and embed in the loader" OFF)
5152
option(UR_BUILD_EXAMPLE_CODEGEN "Build the codegen example." OFF)
5253
option(VAL_USE_LIBBACKTRACE_BACKTRACE "enable libbacktrace validation backtrace for linux" OFF)

unified-runtime/include/ur_api.h

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

unified-runtime/include/ur_print.hpp

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

unified-runtime/scripts/core/common.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,3 +362,6 @@ etors:
362362
- name: NATIVE_CPU
363363
value: "5"
364364
desc: "The backend is Native CPU"
365+
- name: OFFLOAD
366+
value: "0x100"
367+
desc: "The backend is liboffload"

unified-runtime/scripts/core/manifests.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,10 @@ name: native_cpu
6161
backend: $X_BACKEND_NATIVE_CPU
6262
device_types:
6363
- $X_DEVICE_TYPE_CPU
64+
--- #--------------------------------------------------------------------------
65+
type: manifest
66+
name: offload
67+
backend: $X_BACKEND_OFFLOAD
68+
device_types:
69+
- $X_DEVICE_TYPE_CPU
70+
- $X_DEVICE_TYPE_GPU

unified-runtime/source/adapters/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,15 @@ if(UR_BUILD_ADAPTER_OPENCL OR UR_BUILD_ADAPTER_ALL)
7676
add_ur_adapter_subdirectory(opencl)
7777
list(APPEND TEMP_LIST "opencl")
7878
endif()
79+
7980
if(UR_BUILD_ADAPTER_NATIVE_CPU OR UR_BUILD_ADAPTER_ALL)
8081
add_ur_adapter_subdirectory(native_cpu)
8182
list(APPEND TEMP_LIST "native_cpu")
8283
endif()
8384

85+
if(UR_BUILD_ADAPTER_OFFLOAD)
86+
add_ur_adapter_subdirectory(offload)
87+
list(APPEND TEMP_LIST "offload")
88+
endif()
89+
8490
set(UR_ADAPTERS_LIST "${TEMP_LIST}" CACHE STRING "" FORCE)
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# Copyright (C) 2025 Intel Corporation
2+
# Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM Exceptions.
3+
# See LICENSE.TXT
4+
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5+
6+
set(TARGET_NAME ur_adapter_offload)
7+
8+
set(UR_OFFLOAD_INSTALL_DIR "" CACHE PATH "Path to the directory containing libomptarget.so etc")
9+
if (UR_OFFLOAD_INSTALL_DIR STREQUAL "")
10+
message(FATAL_ERROR "UR_OFFLOAD_INSTALL_DIR must be defined for the Offload adapter")
11+
endif()
12+
13+
set(UR_OFFLOAD_INCLUDE_DIR "" CACHE PATH "Path to the directory containing LLVM headers")
14+
if (UR_OFFLOAD_INCLUDE_DIR STREQUAL "")
15+
message(FATAL_ERROR "UR_OFFLOAD_INCLUDE_DIR must be defined for the Offload adapter")
16+
endif()
17+
18+
# When targetting CUDA devices, we need a workaround to avoid sending PTX to
19+
# liboffload as the CUDA plugin doesn't support it yet. The workaround is to
20+
# simply always link the incoming program so it ends up as CUBIN. Try to find
21+
# the cuda driver so we can enable this where possible.
22+
if (NOT TARGET cudadrv)
23+
find_package(CUDA 10.1)
24+
add_library(cudadrv SHARED IMPORTED GLOBAL)
25+
set_target_properties(
26+
cudadrv PROPERTIES
27+
IMPORTED_LOCATION ${CUDA_cuda_driver_LIBRARY}
28+
INTERFACE_INCLUDE_DIRECTORIES ${CUDAToolkit_INCLUDE_DIRS}
29+
)
30+
endif()
31+
32+
add_ur_adapter(${TARGET_NAME}
33+
SHARED
34+
${CMAKE_CURRENT_SOURCE_DIR}/adapter.cpp
35+
${CMAKE_CURRENT_SOURCE_DIR}/context.cpp
36+
${CMAKE_CURRENT_SOURCE_DIR}/device.cpp
37+
${CMAKE_CURRENT_SOURCE_DIR}/enqueue.cpp
38+
${CMAKE_CURRENT_SOURCE_DIR}/event.cpp
39+
${CMAKE_CURRENT_SOURCE_DIR}/kernel.cpp
40+
${CMAKE_CURRENT_SOURCE_DIR}/platform.cpp
41+
${CMAKE_CURRENT_SOURCE_DIR}/program.cpp
42+
${CMAKE_CURRENT_SOURCE_DIR}/queue.cpp
43+
${CMAKE_CURRENT_SOURCE_DIR}/ur2offload.hpp
44+
${CMAKE_CURRENT_SOURCE_DIR}/ur_interface_loader.cpp
45+
${CMAKE_CURRENT_SOURCE_DIR}/usm.cpp
46+
)
47+
48+
set_target_properties(${TARGET_NAME} PROPERTIES
49+
VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}"
50+
SOVERSION "${PROJECT_VERSION_MAJOR}"
51+
)
52+
53+
set(ADDITIONAL_LINK_LIBS "")
54+
if (CUDA_cuda_driver_LIBRARY)
55+
list(APPEND ADDITIONAL_LINK_LIBS cudadrv)
56+
target_compile_definitions(${TARGET_NAME} PRIVATE UR_CUDA_ENABLED)
57+
endif()
58+
59+
target_link_libraries(${TARGET_NAME} PRIVATE
60+
${PROJECT_NAME}::headers
61+
${PROJECT_NAME}::common
62+
${PROJECT_NAME}::umf
63+
${UR_OFFLOAD_INSTALL_DIR}/lib/libLLVMOffload.so
64+
${ADDITIONAL_LINK_LIBS}
65+
)
66+
67+
target_include_directories(${TARGET_NAME} PRIVATE
68+
"${UR_OFFLOAD_INCLUDE_DIR}/offload"
69+
"${CMAKE_CURRENT_SOURCE_DIR}/../../"
70+
)
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
//===----------- adapter.cpp - LLVM Offload Adapter ----------------------===//
2+
//
3+
// Copyright (C) 2024 Intel Corporation
4+
//
5+
// Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM
6+
// Exceptions. See LICENSE.TXT
7+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8+
//
9+
//===----------------------------------------------------------------------===//
10+
11+
#include <OffloadAPI.h>
12+
#include <atomic>
13+
#include <cstdint>
14+
#include <unordered_set>
15+
16+
#include "adapter.hpp"
17+
#include "device.hpp"
18+
#include "platform.hpp"
19+
#include "ur/ur.hpp"
20+
#include "ur_api.h"
21+
22+
ur_adapter_handle_t_ Adapter{};
23+
24+
// Initialize liboffload and perform the initial platform and device discovery
25+
ur_result_t ur_adapter_handle_t_::init() {
26+
auto Res = olInit();
27+
(void)Res;
28+
29+
// Discover every platform and device
30+
Res = olIterateDevices(
31+
[](ol_device_handle_t D, void *UserData) {
32+
auto *Platforms =
33+
reinterpret_cast<decltype(Adapter.Platforms) *>(UserData);
34+
35+
ol_platform_handle_t Platform;
36+
olGetDeviceInfo(D, OL_DEVICE_INFO_PLATFORM, sizeof(Platform),
37+
&Platform);
38+
ol_platform_backend_t Backend;
39+
olGetPlatformInfo(Platform, OL_PLATFORM_INFO_BACKEND, sizeof(Backend),
40+
&Backend);
41+
if (Backend == OL_PLATFORM_BACKEND_HOST) {
42+
Adapter.HostDevice = D;
43+
} else if (Backend != OL_PLATFORM_BACKEND_UNKNOWN) {
44+
auto URPlatform =
45+
std::find_if(Platforms->begin(), Platforms->end(), [&](auto &P) {
46+
return P.OffloadPlatform == Platform;
47+
});
48+
49+
if (URPlatform == Platforms->end()) {
50+
URPlatform =
51+
Platforms->insert(URPlatform, ur_platform_handle_t_(Platform));
52+
}
53+
54+
URPlatform->Devices.push_back(ur_device_handle_t_{&*URPlatform, D});
55+
}
56+
return false;
57+
},
58+
&Adapter.Platforms);
59+
60+
(void)Res;
61+
62+
return UR_RESULT_SUCCESS;
63+
}
64+
65+
UR_APIEXPORT ur_result_t UR_APICALL urAdapterGet(
66+
uint32_t, ur_adapter_handle_t *phAdapters, uint32_t *pNumAdapters) {
67+
if (phAdapters) {
68+
if (++Adapter.RefCount == 1) {
69+
Adapter.init();
70+
}
71+
*phAdapters = &Adapter;
72+
}
73+
if (pNumAdapters) {
74+
*pNumAdapters = 1;
75+
}
76+
return UR_RESULT_SUCCESS;
77+
}
78+
79+
UR_APIEXPORT ur_result_t UR_APICALL urAdapterRelease(ur_adapter_handle_t) {
80+
if (--Adapter.RefCount == 0) {
81+
// This can crash when tracing is enabled.
82+
// olShutDown();
83+
};
84+
return UR_RESULT_SUCCESS;
85+
}
86+
87+
UR_APIEXPORT ur_result_t UR_APICALL urAdapterRetain(ur_adapter_handle_t) {
88+
Adapter.RefCount++;
89+
return UR_RESULT_SUCCESS;
90+
}
91+
92+
UR_APIEXPORT ur_result_t UR_APICALL urAdapterGetInfo(ur_adapter_handle_t,
93+
ur_adapter_info_t propName,
94+
size_t propSize,
95+
void *pPropValue,
96+
size_t *pPropSizeRet) {
97+
UrReturnHelper ReturnValue(propSize, pPropValue, pPropSizeRet);
98+
99+
switch (propName) {
100+
case UR_ADAPTER_INFO_BACKEND:
101+
return ReturnValue(UR_BACKEND_OFFLOAD);
102+
case UR_ADAPTER_INFO_REFERENCE_COUNT:
103+
return ReturnValue(Adapter.RefCount.load());
104+
default:
105+
return UR_RESULT_ERROR_INVALID_ENUMERATION;
106+
}
107+
108+
return UR_RESULT_SUCCESS;
109+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//===----------- adapter.hpp - LLVM Offload Adapter ----------------------===//
2+
//
3+
// Copyright (C) 2025 Intel Corporation
4+
//
5+
// Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM
6+
// Exceptions. See LICENSE.TXT
7+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8+
//
9+
//===----------------------------------------------------------------------===//
10+
11+
#pragma once
12+
13+
#include <atomic>
14+
#include <cstdint>
15+
#include <unordered_set>
16+
17+
#include <OffloadAPI.h>
18+
19+
#include "common.hpp"
20+
#include "logger/ur_logger.hpp"
21+
#include "platform.hpp"
22+
23+
struct ur_adapter_handle_t_ : ur::offload::handle_base {
24+
std::atomic_uint32_t RefCount = 0;
25+
logger::Logger &Logger = logger::get_logger("offload");
26+
ol_device_handle_t HostDevice = nullptr;
27+
std::vector<ur_platform_handle_t_> Platforms;
28+
29+
ur_result_t init();
30+
};
31+
32+
extern ur_adapter_handle_t_ Adapter;
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//===----------- common.hpp - LLVM Offload Adapter -----------------------===//
2+
//
3+
// Copyright (C) 2024 Intel Corporation
4+
//
5+
// Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM
6+
// Exceptions. See LICENSE.TXT
7+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8+
//
9+
//===----------------------------------------------------------------------===//
10+
11+
#pragma once
12+
13+
#include "ur/ur.hpp"
14+
#include <atomic>
15+
16+
namespace ur::offload {
17+
struct ddi_getter {
18+
const static ur_dditable_t *value();
19+
};
20+
using handle_base = ur::handle_base<ur::offload::ddi_getter>;
21+
} // namespace ur::offload
22+
23+
struct RefCounted : ur::offload::handle_base {
24+
std::atomic_uint32_t RefCount = 1;
25+
};

0 commit comments

Comments
 (0)