Skip to content
Closed
Show file tree
Hide file tree
Changes from 4 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
41 changes: 41 additions & 0 deletions .github/workflows/libsycl-build-and-test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# This file defines pre-commit CI for libsycl++.
name: Build libsycl
on:
pull_request:
paths:
- 'libsycl/**'
- '.github/workflows/libsycl-build-and-test.yaml'

permissions:
contents: read # Default everything to read-only

concurrency:
# Cancel a currently running workflow from the same PR
group: ${{ github.workflow }}-${{ github.event.pull_request.number }}
cancel-in-progress: true

jobs:
build_ubuntu2204:
# sergey-semenov repo is set is for test purposes
if: github.repository_owner == 'sergey-semenov'
# github runner
runs-on: ubuntu-22.04
# reuse libcxx container for now
container: ghcr.io/llvm/libcxx-linux-builder:2b57ebb50b6d418e70382e655feaa619b558e254
continue-on-error: false

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't that the default?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't seen this explicitly stated anywhere. https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax#jobsjob_idcontinue-on-error
it sounds like it should be the default but nothing bad will happen if I explicitly specify my intention here.

steps:
- uses: actions/checkout@v4
- name: Register cleanup after job is finished
uses: ./libsycl/utils/ci/actions/cleanup

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need any of that here. AFAIK, cleanup is necessary in our syclos CI because we use self-hosted runners and the working directory isn't cleaned up between tasks. With GH-provided runner that isn't an issue.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I requested system for self-hosted runner. So I do expect us to need this in future. Although you are right about current state, I will remove it then.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done in 918ba92

- name: Compile
env:
CC: 'clang-21'
CXX: 'clang++-21'
run: |
mkdir -p $GITHUB_WORKSPACE/build
mkdir -p $GITHUB_WORKSPACE/install
cmake -G Ninja -S $GITHUB_WORKSPACE/runtimes -B $GITHUB_WORKSPACE/build \
-DCMAKE_INSTALL_PREFIX=$GITHUB_WORKSPACE/install \
-DLLVM_ENABLE_RUNTIMES="libsycl" \
-DCMAKE_BUILD_TYPE=Release
ninja -C $GITHUB_WORKSPACE/build install --verbose
14 changes: 14 additions & 0 deletions libsycl/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ endif()
option(LIBSYCL_ENABLE_WERROR "Treat all warnings as errors in the libsycl project" OFF)
option(LIBSYCL_ENABLE_PEDANTIC "Compile with pedantic enabled." OFF)

# If LIBSYCL_ENABLE_BACKENDS is undefined, we default to enabling OpenCL and Level
# Zero backends.
if (NOT DEFINED LIBSYCL_ENABLE_BACKENDS)
set(LIBSYCL_ENABLE_BACKENDS "opencl;level_zero" CACHE STRING "Backends enabled for SYCL")
endif()

#===============================================================================
# Configure System
#===============================================================================
Expand Down Expand Up @@ -77,6 +83,14 @@ if (NOT LIBSYCL_ABI_NAMESPACE MATCHES "__V.*")
message(FATAL_ERROR "LIBSYCL_ABI_NAMESPACE must be a reserved identifier, got '${LIBSYCL_ABI_NAMESPACE}'.")
endif()

#===============================================================================
# Dependencies
#===============================================================================

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules")
# Download & build dependency for kernel offloading
include(FetchUnifiedRuntime)

#===============================================================================
# Setup build & install rules
#===============================================================================
Expand Down
212 changes: 212 additions & 0 deletions libsycl/cmake/Modules/FetchUnifiedRuntime.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
#===============================================================================
# Fetches Unified Runtime used by SYCL language runtime to abstract SYCL open
# standard and vendor heterogeneous offload interfaces.
#
# This will in time be replaced by the new LLVM Offload interface.
#
# Unified Runtime is Apache 2.0 license with LLVM exceptions.
#
#===============================================================================

# Options to override the default behaviour of the FetchContent to include UR
# source code.
set(LIBSYCL_UR_OVERRIDE_FETCH_CONTENT_REPO
Copy link

@sarnex sarnex Aug 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the current pattern we aren't having any variables for repo override, tag override, or to use FetchContent. The only way a user can specify anything is by overriding the FetchContent automatically generated variable which is FETCHCONTENT_SOURCE_DIR_<uppercaseName> which will tell CMake to use that directory instead of downloading anything, we don't need to do anything to handle it.

So right now I've been doing:

  1. if(NOT FETCHCONTENT_SOURCE_DIR_(converttouppsersomehow(${fetch-name}))
    Ideally find_package, if not find_path
    else()
    FetchContent_Declare
    ...
    ...
    endif()

Basically, assuming the user didn't explicitly specify a custom directory to use, search the system and if it's found use that, otherwise fall back to FetchContent which will either actually git clone or will use the user specified directory.

Example PR here

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sarnex what do you mean under "we don't have any variables for repo override... The only way a user can specify anything is by overriding..."?
we can easily override all present variables with:
for example -DLIBSYCL_UR_OVERRIDE_FETCH_CONTENT_REPO=something in the build command line.

Copy link

@sarnex sarnex Aug 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I mean 'the standard way it is being done for other dependencies is ...', so I was trying to say all other dependenices don't have user-settable variables for the repo url/tag but this one does, so I recommend removing them to simplify and align with how we handle other deps. Thanks

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done in 9daa5a7
I also removed fetch_adapter_source since it brings extra detalization (comes from intel/llvm) which is unlikely to be used.

Copy link
Collaborator Author

@KseniyaTikhomirova KseniyaTikhomirova Aug 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also used find_package since UR has proper configs to use it.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

music to my ears!

"" CACHE STRING "Override the Unified Runtime FetchContent repository")
set(LIBSYCL_UR_OVERRIDE_FETCH_CONTENT_TAG
"" CACHE STRING "Override the Unified Runtime FetchContent tag")

# Options to disable use of FetchContent to include Unified Runtime source code
# to improve developer workflow.
option(LIBSYCL_UR_USE_FETCH_CONTENT
"Use FetchContent to acquire the Unified Runtime source code" ON)
set(LIBSYCL_UR_SOURCE_DIR
"" CACHE PATH "Path to root of Unified Runtime repository")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sarnex, I think you're our CMake expert, can you take a look at the CMake part in this PR, please?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you're our CMake expert

Oh god please no


option(LIBSYCL_UR_BUILD_TESTS "Build tests for UR" OFF)
set(UR_BUILD_TESTS "${LIBSYCL_UR_BUILD_TESTS}" CACHE BOOL "" FORCE)
# UR tests require the examples to be built
set(UR_BUILD_EXAMPLES "${LIBSYCL_UR_BUILD_TESTS}" CACHE BOOL "" FORCE)

set(UR_EXTERNAL_DEPENDENCIES "sycl-headers" CACHE STRING
"List of external CMake targets for executables/libraries to depend on" FORCE)

if("level_zero" IN_LIST LIBSYCL_ENABLE_BACKENDS)
set(UR_BUILD_ADAPTER_L0 ON)
endif()
if("cuda" IN_LIST LIBSYCL_ENABLE_BACKENDS)
set(UR_BUILD_ADAPTER_CUDA ON)
endif()
if("hip" IN_LIST LIBSYCL_ENABLE_BACKENDS)
set(UR_BUILD_ADAPTER_HIP ON)
endif()
if("opencl" IN_LIST LIBSYCL_ENABLE_BACKENDS)
set(UR_BUILD_ADAPTER_OPENCL ON)
endif()

# Disable errors from warnings while building the UR.
# And remember origin flags before doing that.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit

Suggested change
# And remember origin flags before doing that.
# And remember the original flags before doing that.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

set(CMAKE_CXX_FLAGS_BAK "${CMAKE_CXX_FLAGS}")
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need to backup/restore CFLAGS as well?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

libsycl will be warning free while UR build fails with Werror enabled. So yes, we can't use LLVM top level warning strategy for this dependency.

Copy link

@sarnex sarnex Aug 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry i mean right now we are only backing up and restoring CMAKE_CXX_FLAGS, do we need to do CMAKE_C_FLAGS as well?

if(WIN32)
append("/WX-" CMAKE_CXX_FLAGS)
append("/WX-" CMAKE_C_FLAGS)
# Unified runtime build fails with /DUNICODE
append("/UUNICODE" CMAKE_CXX_FLAGS)
append("/UUNICODE" CMAKE_C_FLAGS)
else()
append("-Wno-error" CMAKE_CXX_FLAGS)
append("-Wno-error" CMAKE_C_FLAGS)
endif()

if(LIBSYCL_UR_USE_FETCH_CONTENT)
include(FetchContent)

# The fetch_adapter_source function can be used to perform a separate content
# fetch for a UR adapter (backend), this allows development of adapters to be decoupled
# from each other.
#
# A separate content fetch will not be performed if:
# * The adapter name is not present in the LIBSYCL_ENABLE_BACKENDS variable.
# * The repo and tag provided match the values of the
# UNIFIED_RUNTIME_REPO/UNIFIED_RUNTIME_TAG variables
#
# Args:
# * name - Must be the directory name of the adapter
# * repo - A valid Git URL of a Unified Runtime repo
# * tag - A valid Git branch/tag/commit in the Unified Runtime repo
function(fetch_adapter_source name repo tag)
if(NOT ${name} IN_LIST LIBSYCL_ENABLE_BACKENDS)
return()
endif()
if(repo STREQUAL UNIFIED_RUNTIME_REPO AND
tag STREQUAL UNIFIED_RUNTIME_TAG)
# If the adapter sources are taken from the main checkout, reset the
# adapter specific source path.
string(TOUPPER ${name} NAME)
set(UR_ADAPTER_${NAME}_SOURCE_DIR ""
CACHE PATH "Path to external '${name}' adapter source dir" FORCE)
return()
endif()
message(STATUS
"Will fetch Unified Runtime ${name} adapter from ${repo} at ${tag}")
set(fetch-name ur-${name})
FetchContent_Declare(${fetch-name}
GIT_REPOSITORY ${repo} GIT_TAG ${tag})
# We don't want to add this repo to the build, only fetch its source.
FetchContent_Populate(${fetch-name})
# Get the path to the source directory
string(TOUPPER ${name} NAME)
set(source_dir_var UR_ADAPTER_${NAME}_SOURCE_DIR)
FetchContent_GetProperties(${fetch-name} SOURCE_DIR UR_ADAPTER_${NAME}_SOURCE_DIR)
# Set the variable which informs UR where to get the adapter source from.
set(UR_ADAPTER_${NAME}_SOURCE_DIR
"${UR_ADAPTER_${NAME}_SOURCE_DIR}/source/adapters/${name}"
CACHE PATH "Path to external '${name}' adapter source dir" FORCE)
endfunction()

set(UNIFIED_RUNTIME_REPO "https://github.com/oneapi-src/unified-runtime.git")
set(UNIFIED_RUNTIME_TAG 851ee6a2bb5f5c34c6e48a00e0b06255044e0f03)

set(UMF_BUILD_EXAMPLES OFF CACHE INTERNAL "EXAMPLES")
# Due to the use of dependentloadflag and no installer for UMF and hwloc we need
# to link statically on windows
if(WIN32)
set(UMF_BUILD_SHARED_LIBRARY OFF CACHE INTERNAL "Build UMF shared library")
set(UMF_LINK_HWLOC_STATICALLY ON CACHE INTERNAL "static HWLOC")
endif()

fetch_adapter_source(level_zero
${UNIFIED_RUNTIME_REPO}
${UNIFIED_RUNTIME_TAG}
)

fetch_adapter_source(opencl
${UNIFIED_RUNTIME_REPO}
${UNIFIED_RUNTIME_TAG}
)

fetch_adapter_source(cuda
${UNIFIED_RUNTIME_REPO}
${UNIFIED_RUNTIME_TAG}
)

fetch_adapter_source(hip
${UNIFIED_RUNTIME_REPO}
${UNIFIED_RUNTIME_TAG}
)

if(LIBSYCL_UR_OVERRIDE_FETCH_CONTENT_REPO)
set(UNIFIED_RUNTIME_REPO "${LIBSYCL_UR_OVERRIDE_FETCH_CONTENT_REPO}")
endif()
if(LIBSYCL_UR_OVERRIDE_FETCH_CONTENT_TAG)
set(UNIFIED_RUNTIME_TAG "${LIBSYCL_UR_OVERRIDE_FETCH_CONTENT_TAG}")
endif()

message(STATUS "Will fetch Unified Runtime from ${UNIFIED_RUNTIME_REPO}")
FetchContent_Declare(unified-runtime
GIT_REPOSITORY ${UNIFIED_RUNTIME_REPO}
GIT_TAG ${UNIFIED_RUNTIME_TAG}
)

FetchContent_GetProperties(unified-runtime)
FetchContent_MakeAvailable(unified-runtime)

set(UNIFIED_RUNTIME_SOURCE_DIR
"${unified-runtime_SOURCE_DIR}" CACHE PATH
"Path to Unified Runtime Headers" FORCE)
elseif(LIBSYCL_UR_SOURCE_DIR)
# LIBSYCL_UR_USE_FETCH_CONTENT is OFF and LIBSYCL_UR_SOURCE_DIR has been set,
# use the external Unified Runtime source directory.
set(UNIFIED_RUNTIME_SOURCE_DIR
"${LIBSYCL_UR_SOURCE_DIR}" CACHE PATH
"Path to Unified Runtime Headers" FORCE)
add_subdirectory(
${UNIFIED_RUNTIME_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}/unified-runtime)
else()
message(FATAL_ERROR
"LIBSYCL_UR_USE_FETCH_CONTENT is disabled but no alternative Unified \
Runtime source directory has been provided, either:

* Set -DLIBSYCL_UR_SOURCE_DIR=/path/to/unified-runtime
* Clone the UR repo in ${CMAKE_CURRENT_SOURCE_DIR}/unified-runtime")
endif()

# Restore original flags
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_BAK}")

message(STATUS
"Using Unified Runtime source directory: ${UNIFIED_RUNTIME_SOURCE_DIR}")

set(UNIFIED_RUNTIME_INCLUDE_DIR "${UNIFIED_RUNTIME_SOURCE_DIR}/include")
set(UNIFIED_RUNTIME_SRC_INCLUDE_DIR "${UNIFIED_RUNTIME_SOURCE_DIR}/source")
set(UNIFIED_RUNTIME_COMMON_INCLUDE_DIR "${UNIFIED_RUNTIME_SOURCE_DIR}/source/common")

add_library(UnifiedRuntimeLoader ALIAS ur_loader)
add_library(UnifiedRuntime-Headers INTERFACE)

target_include_directories(UnifiedRuntime-Headers
INTERFACE
"${UNIFIED_RUNTIME_INCLUDE_DIR}"
)

add_custom_target(UnifiedRuntimeAdapters)

function(add_sycl_ur_adapter NAME)
add_dependencies(UnifiedRuntimeAdapters ur_adapter_${NAME})
endfunction()

if("level_zero" IN_LIST LIBSYCL_ENABLE_BACKENDS)
add_sycl_ur_adapter(level_zero)
endif()

if("cuda" IN_LIST LIBSYCL_ENABLE_BACKENDS)
add_sycl_ur_adapter(cuda)
endif()

if("hip" IN_LIST LIBSYCL_ENABLE_BACKENDS)
add_sycl_ur_adapter(hip)
endif()

if("opencl" IN_LIST LIBSYCL_ENABLE_BACKENDS)
add_sycl_ur_adapter(opencl)
endif()
23 changes: 23 additions & 0 deletions libsycl/docs/DesignDocs/UnifiedRuntime.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
=====================
Unified Runtime
=====================

.. contents::
:local:

.. _unified runtime:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was highlighted in the discussion of #2 that UR is a temporary solution. Can this be described here in this document noting what the permanent solution will be and how to try it out (and work on it) instead?

The Unified Runtime (UR) project serves as an interface layer between the SYCL
runtime and the device-specific runtime layers which control execution on
devices. SYCL RT utilizes its C API, loader library, and the adapter libraries
that implement the API for various backends.

The SYCL runtime accesses the UR API via the Adapter object. Each Adapter
object owns a ``ur_adapter_handle_t``, which represents a UR backend (e.g. OpenCL,
Level Zero, etc).

For detailed information about the UR project including
the API specification see the `Unified Runtime Documentation
<https://oneapi-src.github.io/unified-runtime/core/INTRO.html>`__. You
can find the Unified Runtime repo `here
<https://github.com/oneapi-src/unified-runtime>`__.
14 changes: 9 additions & 5 deletions libsycl/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../runtimes/cmake/
include(WarningFlags)

function(add_sycl_rt_library LIB_TARGET_NAME LIB_OBJ_NAME LIB_OUTPUT_NAME)
if (NOT LLVM_ENABLE_PIC)
message( FATAL_ERROR "Position-Independent Code generation is required for libsycl shared library" )
endif()

cmake_parse_arguments(ARG "" "" "COMPILE_OPTIONS;SOURCES" ${ARGN})

add_library(${LIB_OBJ_NAME} OBJECT ${ARG_SOURCES})
Expand All @@ -22,6 +18,13 @@ function(add_sycl_rt_library LIB_TARGET_NAME LIB_OBJ_NAME LIB_OUTPUT_NAME)
${LIBSYCL_BUILD_INCLUDE_DIR}
)

# Object libraries are not linked, so these "libraries" are in fact include
# directories
target_link_libraries(${LIB_OBJ_NAME}
PRIVATE
UnifiedRuntime-Headers
)

add_library(${LIB_TARGET_NAME} SHARED
$<TARGET_OBJECTS:${LIB_OBJ_NAME}>)

Expand Down Expand Up @@ -49,7 +52,7 @@ function(add_sycl_rt_library LIB_TARGET_NAME LIB_OBJ_NAME LIB_OUTPUT_NAME)
target_compile_options(${LIB_OBJ_NAME} PUBLIC /EHsc)
else()
target_compile_options(${LIB_OBJ_NAME} PUBLIC
-fvisibility=hidden -fvisibility-inlines-hidden)
-fvisibility=hidden -fvisibility-inlines-hidden -fPIC)

if (UNIX AND NOT APPLE)
set(linker_script "${CMAKE_CURRENT_SOURCE_DIR}/ld-version-script.txt")
Expand All @@ -65,6 +68,7 @@ function(add_sycl_rt_library LIB_TARGET_NAME LIB_OBJ_NAME LIB_OUTPUT_NAME)
PRIVATE
${CMAKE_DL_LIBS}
${CMAKE_THREAD_LIBS_INIT}
UnifiedRuntimeLoader
)

set_target_properties(${LIB_TARGET_NAME} PROPERTIES
Expand Down
7 changes: 7 additions & 0 deletions libsycl/utils/ci/actions/cleanup/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
name: 'Cleanup'

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All three files here can be dropped, IMO, see my earlier comment.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done in 918ba92

description: 'Cleanup work directory upon job finish'

runs:
using: 'node16'
main: 'dummy.js'
post: 'cleanup.js'
4 changes: 4 additions & 0 deletions libsycl/utils/ci/actions/cleanup/cleanup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
const path = process.env.GITHUB_WORKSPACE + '/*';
console.log('Cleaning ' + path)
require('child_process').execSync('rm -rf ' + path);
require('child_process').execSync('rm -rf ' + process.env.GITHUB_WORKSPACE + '/.git');
1 change: 1 addition & 0 deletions libsycl/utils/ci/actions/cleanup/dummy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console.log('setup cleanup');