From b22192afdcbda7441e7a8fe7cbc9a06903e9e6ea Mon Sep 17 00:00:00 2001 From: Kseniya Tikhomirova Date: Fri, 7 Nov 2025 12:36:59 +0100 Subject: [PATCH 01/22] [SYCL] Add platform enumeration and info query using liboffload (#2) This is part of the SYCL support upstreaming effort. The relevant RFCs can be found here: https://discourse.llvm.org/t/rfc-add-full-support-for-the-sycl-programming-model/74080 https://discourse.llvm.org/t/rfc-sycl-runtime-upstreaming/74479 The SYCL runtime is device-agnostic and uses liboffload for offloading to GPU. This commit adds a dependency on liboffload, implementation of platform::get_platforms, platform::get_backend and platform::get_info methods, initial implementation of sycl-ls tool for manual testing of added functionality. Plan for next PR: device/context impl, rest of platform test infrastructure (depends on L0 liboffload plugin CI, our effort is joined) ABI tests --- libsycl/CMakeLists.txt | 18 ++- libsycl/docs/index.rst | 12 +- libsycl/include/sycl/__impl/backend.hpp | 70 +++++++++++ libsycl/include/sycl/__impl/detail/config.hpp | 4 +- .../sycl/__impl/detail/macro_definitions.hpp | 52 ++++++++ .../include/sycl/__impl/detail/obj_base.hpp | 64 ++++++++++ libsycl/include/sycl/__impl/exception.hpp | 116 ++++++++++++++++++ libsycl/include/sycl/__impl/info/platform.def | 8 ++ libsycl/include/sycl/__impl/info/platform.hpp | 54 ++++++++ libsycl/include/sycl/__impl/platform.hpp | 87 ++++++++++++- libsycl/include/sycl/sycl.hpp | 1 + libsycl/src/CMakeLists.txt | 29 ++--- libsycl/src/detail/global_objects.cpp | 73 +++++++++++ libsycl/src/detail/global_objects.hpp | 33 +++++ libsycl/src/detail/offload/info_code.hpp | 30 +++++ .../src/detail/offload/offload_topology.cpp | 79 ++++++++++++ .../src/detail/offload/offload_topology.hpp | 101 +++++++++++++++ libsycl/src/detail/offload/offload_utils.cpp | 65 ++++++++++ libsycl/src/detail/offload/offload_utils.hpp | 59 +++++++++ libsycl/src/detail/platform_impl.cpp | 65 ++++++++++ libsycl/src/detail/platform_impl.hpp | 102 +++++++++++++++ libsycl/src/exception.cpp | 57 +++++++++ libsycl/src/exception_list.cpp | 27 ++++ libsycl/src/platform.cpp | 21 +++- libsycl/tools/CMakeLists.txt | 1 + libsycl/tools/sycl-ls/CMakeLists.txt | 25 ++++ libsycl/tools/sycl-ls/sycl-ls.cpp | 70 +++++++++++ 27 files changed, 1292 insertions(+), 31 deletions(-) create mode 100644 libsycl/include/sycl/__impl/backend.hpp create mode 100644 libsycl/include/sycl/__impl/detail/macro_definitions.hpp create mode 100644 libsycl/include/sycl/__impl/detail/obj_base.hpp create mode 100644 libsycl/include/sycl/__impl/exception.hpp create mode 100644 libsycl/include/sycl/__impl/info/platform.def create mode 100644 libsycl/include/sycl/__impl/info/platform.hpp create mode 100644 libsycl/src/detail/global_objects.cpp create mode 100644 libsycl/src/detail/global_objects.hpp create mode 100644 libsycl/src/detail/offload/info_code.hpp create mode 100644 libsycl/src/detail/offload/offload_topology.cpp create mode 100644 libsycl/src/detail/offload/offload_topology.hpp create mode 100644 libsycl/src/detail/offload/offload_utils.cpp create mode 100644 libsycl/src/detail/offload/offload_utils.hpp create mode 100644 libsycl/src/detail/platform_impl.cpp create mode 100644 libsycl/src/detail/platform_impl.hpp create mode 100644 libsycl/src/exception.cpp create mode 100644 libsycl/src/exception_list.cpp create mode 100644 libsycl/tools/CMakeLists.txt create mode 100644 libsycl/tools/sycl-ls/CMakeLists.txt create mode 100644 libsycl/tools/sycl-ls/sycl-ls.cpp diff --git a/libsycl/CMakeLists.txt b/libsycl/CMakeLists.txt index fe08a4249bada..54ef3d4b1878a 100644 --- a/libsycl/CMakeLists.txt +++ b/libsycl/CMakeLists.txt @@ -37,8 +37,6 @@ option(LIBSYCL_ENABLE_PEDANTIC "Compile with pedantic enabled." OFF) set_property(GLOBAL PROPERTY USE_FOLDERS ON) -set(LIBSYCL_SHARED_OUTPUT_NAME "sycl" CACHE STRING "Output name for the shared libsycl runtime library.") - if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE) set(LIBSYCL_TARGET_SUBDIR ${LLVM_DEFAULT_TARGET_TRIPLE}) if(LIBSYCL_LIBDIR_SUBDIR) @@ -65,7 +63,7 @@ set(LIBSYCL_SOURCE_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${LIBSYCL_LIBRARY_DIR}) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${LIBSYCL_LIBRARY_DIR}) -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${LIBSYCL_LIBRARY_DIR}) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${LLVM_TOOLS_BINARY_DIR}) set(LIBSYCL_MAJOR_VERSION 0) set(LIBSYCL_MINOR_VERSION 1) @@ -117,10 +115,22 @@ add_custom_command( install(DIRECTORY "${LIBSYCL_SOURCE_INCLUDE_DIR}/sycl" DESTINATION ${LIBSYCL_INCLUDE_DIR} COMPONENT sycl-headers) install(DIRECTORY "${LIBSYCL_SOURCE_INCLUDE_DIR}/CL" DESTINATION ${LIBSYCL_INCLUDE_DIR} COMPONENT sycl-headers) -set(LIBSYCL_RT_LIBS ${LIBSYCL_SHARED_OUTPUT_NAME}) +set(LIBSYCL_LIB_NAME "sycl") +set(LIBSYCL_SHARED_OUTPUT_NAME "${LIBSYCL_LIB_NAME}") +if (CMAKE_SYSTEM_NAME STREQUAL Windows) + if (CMAKE_MSVC_RUNTIME_LIBRARY AND (NOT CMAKE_MSVC_RUNTIME_LIBRARY MATCHES "DLL$")) + message(FATAL_ERROR "libsycl requires a DLL version of the MSVC CRT.") + endif() + if ((NOT CMAKE_MSVC_RUNTIME_LIBRARY AND uppercase_CMAKE_BUILD_TYPE STREQUAL "DEBUG") + OR (CMAKE_MSVC_RUNTIME_LIBRARY STREQUAL "MultiThreadedDebugDLL")) + set(LIBSYCL_SHARED_OUTPUT_NAME "${LIBSYCL_SHARED_OUTPUT_NAME}d") + endif() +endif() add_subdirectory(src) +set(LIBSYCL_RT_LIBS ${LIBSYCL_SHARED_OUTPUT_NAME}) add_custom_target(libsycl-runtime-libraries DEPENDS ${LIBSYCL_RT_LIBS} ) +add_subdirectory(tools) diff --git a/libsycl/docs/index.rst b/libsycl/docs/index.rst index 78e76e73284d3..83df7807c9df9 100644 --- a/libsycl/docs/index.rst +++ b/libsycl/docs/index.rst @@ -69,11 +69,17 @@ To build LLVM with libsycl runtime enabled the following script can be used. mkdir -p $installprefix cmake -G Ninja -S $llvm/llvm -B $build_llvm \ - -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra" \ + -DLLVM_ENABLE_PROJECTS="clang" \ -DLLVM_INSTALL_UTILS=ON \ -DCMAKE_INSTALL_PREFIX=$installprefix \ - -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libsycl;libunwind" \ + -DLLVM_ENABLE_RUNTIMES="offload;openmp;libsycl" \ -DCMAKE_BUILD_TYPE=Release ninja -C $build_llvm install - \ No newline at end of file + + +Limitations +======== + +SYCL runtime is not tested and is not guaranteed to work on Windows because offloading runtime (liboffload) used by SYCL runtime doesn't currently support Windows. +The limitation to be revised once liboffload will add support for Windows. diff --git a/libsycl/include/sycl/__impl/backend.hpp b/libsycl/include/sycl/__impl/backend.hpp new file mode 100644 index 0000000000000..bc361e487af69 --- /dev/null +++ b/libsycl/include/sycl/__impl/backend.hpp @@ -0,0 +1,70 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// This file contains the declaration of the SYCL enum class backend that is +/// implementation-defined and is populated with a unique identifier for each +/// SYCL backend that the SYCL implementation can support. +/// +//===----------------------------------------------------------------------===// + +#ifndef _LIBSYCL___IMPL_BACKEND_HPP +#define _LIBSYCL___IMPL_BACKEND_HPP + +#include + +#include +#include + +_LIBSYCL_BEGIN_NAMESPACE_SYCL + +// 4.1. Backends +enum class backend : char { + opencl = 1, + level_zero = 2, + cuda = 3, + hip = 4, + all = 5, +}; + +namespace detail { +template struct is_backend_info_desc : std::false_type {}; +} // namespace detail + +// 4.5.1.1. Type traits backend_traits +template class backend_traits; + +template +using backend_input_t = + typename backend_traits::template input_type; +template +using backend_return_t = + typename backend_traits::template return_type; + +namespace detail { +inline std::string_view get_backend_name(const backend &Backend) { + switch (Backend) { + case backend::opencl: + return "opencl"; + case backend::level_zero: + return "level_zero"; + case backend::cuda: + return "cuda"; + case backend::hip: + return "hip"; + case backend::all: + return "all"; + } + + return ""; +} +} // namespace detail + +_LIBSYCL_END_NAMESPACE_SYCL + +#endif // _LIBSYCL___IMPL_BACKEND_HPP diff --git a/libsycl/include/sycl/__impl/detail/config.hpp b/libsycl/include/sycl/__impl/detail/config.hpp index cc9059762af1b..ea7a8530a8cfe 100644 --- a/libsycl/include/sycl/__impl/detail/config.hpp +++ b/libsycl/include/sycl/__impl/detail/config.hpp @@ -41,8 +41,8 @@ # else // _WIN32 -# define _LIBSYCL_DLL_LOCAL [[__gnu__::__visibility__("hidden")]] -# define _LIBSYCL_EXPORT [[__gnu__::__visibility__("default")]] +# define _LIBSYCL_DLL_LOCAL __attribute__((visibility("hidden"))) +# define _LIBSYCL_EXPORT __attribute__((visibility("default"))) # endif // _WIN32 # endif // _LIBSYCL_EXPORT diff --git a/libsycl/include/sycl/__impl/detail/macro_definitions.hpp b/libsycl/include/sycl/__impl/detail/macro_definitions.hpp new file mode 100644 index 0000000000000..c9e148709d721 --- /dev/null +++ b/libsycl/include/sycl/__impl/detail/macro_definitions.hpp @@ -0,0 +1,52 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// This file contains macro definitions used in SYCL implementation. +/// +//===----------------------------------------------------------------------===// + +#ifndef _LIBSYCL___IMPL_DETAIL_MACRO_DEFINITIONS_HPP +#define _LIBSYCL___IMPL_DETAIL_MACRO_DEFINITIONS_HPP + +#ifndef __SYCL2020_DEPRECATED +# if SYCL_LANGUAGE_VERSION == 202012L && \ + !defined(SYCL2020_DISABLE_DEPRECATION_WARNINGS) +# define __SYCL2020_DEPRECATED(message) [[deprecated(message)]] +# else +# define __SYCL2020_DEPRECATED(message) +# endif +#endif // __SYCL2020_DEPRECATED + +static_assert(__cplusplus >= 201703L, + "SYCL RT does not support C++ version earlier than C++17."); + +#if defined(_WIN32) && !defined(_DLL) && !defined(__SYCL_DEVICE_ONLY__) +// SYCL library is designed such a way that STL objects cross DLL boundary, +// which is guaranteed to work properly only when the application uses the same +// C++ runtime that SYCL library uses. +// The appplications using sycl.dll must be linked with dynamic/release C++ MSVC +// runtime, i.e. be compiled with /MD switch. Similarly, the applications using +// sycld.dll must be linked with dynamic/debug C++ runtime and be compiled with +// /MDd switch. +// Compiler automatically adds /MD or /MDd when -fsycl switch is used. +// The options /MD and /MDd that make the code to use dynamic runtime also +// define the _DLL macro. +# define ERROR_MESSAGE \ + "SYCL library is designed to work safely with dynamic C++ runtime." \ + "Please use /MD switch with sycl.dll, /MDd switch with sycld.dll, " \ + "or -fsycl switch to set C++ runtime automatically." +# if defined(_MSC_VER) +# pragma message(ERROR_MESSAGE) +# else +# warning ERROR_MESSAGE +# endif +# undef ERROR_MESSAGE +#endif // defined(_WIN32) && !defined(_DLL) && !defined(__SYCL_DEVICE_ONLY__) + +#endif //_LIBSYCL___IMPL_DETAIL_MACRO_DEFINITIONS_HPP diff --git a/libsycl/include/sycl/__impl/detail/obj_base.hpp b/libsycl/include/sycl/__impl/detail/obj_base.hpp new file mode 100644 index 0000000000000..d0314bbdbf767 --- /dev/null +++ b/libsycl/include/sycl/__impl/detail/obj_base.hpp @@ -0,0 +1,64 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// This file contains helper functions for tranformation between implementation +/// and SYCL's interface objects. +/// +//===----------------------------------------------------------------------===// + +#ifndef _LIBSYCL___IMPL_DETAIL_OBJ_BASE_HPP +#define _LIBSYCL___IMPL_DETAIL_OBJ_BASE_HPP + +#include + +#include +#include +#include + +_LIBSYCL_BEGIN_NAMESPACE_SYCL + +namespace detail { + +template class ObjBase { +public: + using ImplType = Impl; + using Base = ObjBase; + +protected: + ImplType &impl; + + explicit ObjBase(ImplType &pImpl) : impl(pImpl) {} + ObjBase() = default; + + static SyclObject createSyclProxy(ImplType &impl) { return SyclObject(impl); } + + template + friend const typename Obj::ImplType &getSyclObjImpl(const Obj &Object); + + template + friend Obj createSyclObjFromImpl( + std::add_lvalue_reference_t ImplObj); +}; + +template +const typename Obj::ImplType &getSyclObjImpl(const Obj &Object) { + return Object.impl; +} + +template +Obj createSyclObjFromImpl( + std::add_lvalue_reference_t ImplObj) { + return Obj::Base::createSyclProxy(ImplObj); +} + +} // namespace detail + +_LIBSYCL_END_NAMESPACE_SYCL + +#endif // _LIBSYCL___IMPL_DETAIL_OBJ_BASE_HPP diff --git a/libsycl/include/sycl/__impl/exception.hpp b/libsycl/include/sycl/__impl/exception.hpp new file mode 100644 index 0000000000000..d41a833e1bc10 --- /dev/null +++ b/libsycl/include/sycl/__impl/exception.hpp @@ -0,0 +1,116 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// This file contains the declaration of the SYCL 2020 Exception class +/// interface (4.13.2.) +/// +//===----------------------------------------------------------------------===// + +#ifndef _LIBSYCL___IMPL_EXCEPTION_HPP +#define _LIBSYCL___IMPL_EXCEPTION_HPP + +#include + +#include +#include +#include +#include +#include +#include + +_LIBSYCL_BEGIN_NAMESPACE_SYCL + +class context; + +enum class errc : int { + success = 0, + runtime = 1, + kernel = 2, + accessor = 3, + nd_range = 4, + event = 5, + kernel_argument = 6, + build = 7, + invalid = 8, + memory_allocation = 9, + platform = 10, + profiling = 11, + feature_not_supported = 12, + kernel_not_supported = 13, + backend_mismatch = 14, +}; + +/// Constructs an error code using E and sycl_category() +_LIBSYCL_EXPORT std::error_code make_error_code(sycl::errc E) noexcept; + +/// Obtains a reference to the static error category object for SYCL errors. +_LIBSYCL_EXPORT const std::error_category &sycl_category() noexcept; + +// Derive from std::exception so uncaught exceptions are printed in c++ default +// exception handler. +// Virtual inheritance is mandated by SYCL 2020. +// 4.13.2. Exception class interface +class _LIBSYCL_EXPORT exception : public virtual std::exception { +public: + exception(std::error_code, const char *); + exception(std::error_code Ec, const std::string &Msg) + : exception(Ec, Msg.c_str()) {} + + exception(std::error_code EC) : exception(EC, "") {} + exception(int EV, const std::error_category &ECat, const std::string &WhatArg) + : exception(EV, ECat, WhatArg.c_str()) {} + exception(int EV, const std::error_category &ECat, const char *WhatArg) + : exception({EV, ECat}, WhatArg) {} + exception(int EV, const std::error_category &ECat) + : exception({EV, ECat}, "") {} + + virtual ~exception(); + + const std::error_code &code() const noexcept; + const std::error_category &category() const noexcept; + + const char *what() const noexcept final; + + bool has_context() const noexcept; + +private: + // Exceptions must be noexcept copy constructible, so cannot use std::string + // directly. + std::shared_ptr MMessage; + std::error_code MErrC = make_error_code(sycl::errc::invalid); +}; + +/// Used as a container for a list of asynchronous exceptions +/// +class _LIBSYCL_EXPORT exception_list { +public: + using value_type = std::exception_ptr; + using reference = value_type &; + using const_reference = const value_type &; + using size_type = std::size_t; + using iterator = std::vector::const_iterator; + using const_iterator = std::vector::const_iterator; + + size_type size() const; + // first asynchronous exception + iterator begin() const; + // refer to past-the-end last asynchronous exception + iterator end() const; + +private: + std::vector MList; +}; + +_LIBSYCL_END_NAMESPACE_SYCL + +namespace std { +template <> struct is_error_code_enum : true_type {}; +} // namespace std + +#endif // _LIBSYCL___IMPL_EXCEPTION_HPP diff --git a/libsycl/include/sycl/__impl/info/platform.def b/libsycl/include/sycl/__impl/info/platform.def new file mode 100644 index 0000000000000..68835fc3e3640 --- /dev/null +++ b/libsycl/include/sycl/__impl/info/platform.def @@ -0,0 +1,8 @@ +#ifndef __SYCL_PARAM_TRAITS_SPEC +static_assert(false, "__SYCL_PARAM_TRAITS_SPEC is required but not defined"); +#endif + +// 4.6.2.4. Information descriptors +__SYCL_PARAM_TRAITS_SPEC(platform, version, std::string, OL_PLATFORM_INFO_VERSION) +__SYCL_PARAM_TRAITS_SPEC(platform, name, std::string, OL_PLATFORM_INFO_NAME) +__SYCL_PARAM_TRAITS_SPEC(platform, vendor, std::string, OL_PLATFORM_INFO_VENDOR_NAME) diff --git a/libsycl/include/sycl/__impl/info/platform.hpp b/libsycl/include/sycl/__impl/info/platform.hpp new file mode 100644 index 0000000000000..d175b66adf570 --- /dev/null +++ b/libsycl/include/sycl/__impl/info/platform.hpp @@ -0,0 +1,54 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// This file contains the declaration of SYCL 2020 platform info types. +/// +//===----------------------------------------------------------------------===// + +#ifndef _LIBSYCL___IMPL_INFO_PLATFORM_HPP +#define _LIBSYCL___IMPL_INFO_PLATFORM_HPP + +#include + +#include + +_LIBSYCL_BEGIN_NAMESPACE_SYCL + +// A.1. Platform information descriptors +namespace info { +namespace platform { +#define __SYCL_PARAM_TRAITS_SPEC(DescType, Desc, ReturnT, OffloadCode) \ + struct Desc { \ + using return_type = ReturnT; \ + }; + +// 4.6.2.4. Information descriptors +#include + +#undef __SYCL_PARAM_TRAITS_SPEC +} // namespace platform +} // namespace info + +namespace detail { +template struct is_platform_info_desc : std::false_type {}; + +#define __SYCL_PARAM_TRAITS_SPEC(DescType, Desc, ReturnT, OffloadCode) \ + template <> \ + struct is_##DescType##_info_desc : std::true_type { \ + using return_type = info::DescType::Desc::return_type; \ + }; + +#include + +#undef __SYCL_PARAM_TRAITS_SPEC +} // namespace detail + +_LIBSYCL_END_NAMESPACE_SYCL + +#endif // _LIBSYCL___IMPL_INFO_PLATFORM_HPP diff --git a/libsycl/include/sycl/__impl/platform.hpp b/libsycl/include/sycl/__impl/platform.hpp index bac59ac93d3dd..b54c339208e84 100644 --- a/libsycl/include/sycl/__impl/platform.hpp +++ b/libsycl/include/sycl/__impl/platform.hpp @@ -15,15 +15,96 @@ #ifndef _LIBSYCL___IMPL_PLATFORM_HPP #define _LIBSYCL___IMPL_PLATFORM_HPP +#include #include +#include +#include + +#include +#include _LIBSYCL_BEGIN_NAMESPACE_SYCL -class _LIBSYCL_EXPORT platform { +namespace detail { +class platform_impl; +} // namespace detail + +// 4.6.2. Platform class +class _LIBSYCL_EXPORT platform + : public detail::ObjBase { public: - /// Constructs a SYCL platform which contains the default device. - platform(); + /// Constructs a platform object that is a copy of the platform which contains + /// the device returned by default_selector_v. + // platform(); + + /// Constructs a platform object that is a copy of the platform which contains + /// the device that is selected by selector. + /// \param DeviceSelectorInstance is SYCL 2020 Device Selector, a simple + /// callable taking a device reference and returning an integer rank. + // template + // explicit platform(const DeviceSelector& DeviceSelectorInstance); + + /// Returns the backend associated with this platform. + /// + /// \return the backend associated with this platform + backend get_backend() const noexcept; + + /// Returns all SYCL devices associated with this platform. + /// + /// If there are no devices that match given device + /// type, resulting vector is empty. + /// + /// \param DeviceType is a SYCL device type. + /// \return a vector of SYCL devices. + // std::vector + // get_devices(info::device_type DeviceType = info::device_type::all) + // const; + + /// Queries this SYCL platform for info. + /// + /// The return type depends on information being queried. + template + typename detail::is_platform_info_desc::return_type get_info() const { + return get_info_impl(); + } + + // template + // typename detail::is_backend_info_desc::return_type + // get_backend_info() const; + + /// Indicates if all of the SYCL devices on this platform have the + /// given feature. + /// + /// \param Aspect is one of the values in Table 4.20 of the SYCL 2020 + /// Provisional Spec. + /// + /// \return true if all of the SYCL devices on this platform have the + /// given feature. + // bool has(aspect Aspect) const; + + /// Checks if platform supports specified extension. + /// + /// \param ExtensionName is a string containing extension name. + /// \return true if specified extension is supported by this SYCL platform. + // __SYCL2020_DEPRECATED( + // "use platform::has() function with aspects APIs instead") + // bool has_extension(const std::string& ExtensionName) const; // Deprecated + + /// Returns all SYCL platforms from all backends that are available in the + /// system. + /// + /// \return A std::vector containing all of the platforms from all backends + /// that are available in the system. + static std::vector get_platforms(); + +private: + platform(detail::platform_impl &Impl) : ObjBase(Impl) {} + + template + typename detail::is_platform_info_desc::return_type + get_info_impl() const; + friend detail::ObjBase; }; // class platform _LIBSYCL_END_NAMESPACE_SYCL diff --git a/libsycl/include/sycl/sycl.hpp b/libsycl/include/sycl/sycl.hpp index 76399eba758d2..ef91ab2381770 100644 --- a/libsycl/include/sycl/sycl.hpp +++ b/libsycl/include/sycl/sycl.hpp @@ -14,6 +14,7 @@ #ifndef _LIBSYCL_SYCL_HPP #define _LIBSYCL_SYCL_HPP +#include #include #endif // _LIBSYCL_SYCL_HPP diff --git a/libsycl/src/CMakeLists.txt b/libsycl/src/CMakeLists.txt index 206b85681cb84..5c8010801f231 100644 --- a/libsycl/src/CMakeLists.txt +++ b/libsycl/src/CMakeLists.txt @@ -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}) @@ -20,6 +16,7 @@ function(add_sycl_rt_library LIB_TARGET_NAME LIB_OBJ_NAME LIB_OUTPUT_NAME) PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${LIBSYCL_BUILD_INCLUDE_DIR} + ${CMAKE_CURRENT_BINARY_DIR}/../../offload/liboffload/API ) add_library(${LIB_TARGET_NAME} SHARED @@ -27,6 +24,7 @@ function(add_sycl_rt_library LIB_TARGET_NAME LIB_OBJ_NAME LIB_OUTPUT_NAME) add_dependencies(${LIB_OBJ_NAME} sycl-headers + LLVMOffload ) set_target_properties(${LIB_TARGET_NAME} PROPERTIES LINKER_LANGUAGE CXX) @@ -49,7 +47,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") @@ -65,6 +63,7 @@ function(add_sycl_rt_library LIB_TARGET_NAME LIB_OBJ_NAME LIB_OUTPUT_NAME) PRIVATE ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT} + LLVMOffload ) set_target_properties(${LIB_TARGET_NAME} PROPERTIES @@ -74,22 +73,16 @@ function(add_sycl_rt_library LIB_TARGET_NAME LIB_OBJ_NAME LIB_OUTPUT_NAME) endfunction(add_sycl_rt_library) set(LIBSYCL_SOURCES + "exception.cpp" + "exception_list.cpp" "platform.cpp" + "detail/global_objects.cpp" + "detail/platform_impl.cpp" + "detail/offload/offload_utils.cpp" + "detail/offload/offload_topology.cpp" ) -set(LIB_NAME "sycl") -set(LIB_OUTPUT_NAME "${LIB_NAME}") -if (CMAKE_SYSTEM_NAME STREQUAL Windows) - if (CMAKE_MSVC_RUNTIME_LIBRARY AND (NOT CMAKE_MSVC_RUNTIME_LIBRARY MATCHES "DLL$")) - message(FATAL_ERROR "libsycl requires a DLL version of the MSVC CRT.") - endif() - if ((NOT CMAKE_MSVC_RUNTIME_LIBRARY AND uppercase_CMAKE_BUILD_TYPE STREQUAL "DEBUG") - OR (CMAKE_MSVC_RUNTIME_LIBRARY STREQUAL "MultiThreadedDebugDLL")) - set(LIB_OUTPUT_NAME "${LIB_OUTPUT_NAME}d") - endif() -endif() - -add_sycl_rt_library(${LIB_NAME} sycl_object ${LIB_OUTPUT_NAME} +add_sycl_rt_library(${LIBSYCL_LIB_NAME} sycl_object ${LIBSYCL_SHARED_OUTPUT_NAME} SOURCES ${LIBSYCL_SOURCES}) install(TARGETS ${LIBSYCL_RT_LIBS} diff --git a/libsycl/src/detail/global_objects.cpp b/libsycl/src/detail/global_objects.cpp new file mode 100644 index 0000000000000..1dbb7074ed453 --- /dev/null +++ b/libsycl/src/detail/global_objects.cpp @@ -0,0 +1,73 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include +#include + +#ifdef _WIN32 +# include +#endif + +#include + +_LIBSYCL_BEGIN_NAMESPACE_SYCL +namespace detail { + +std::vector &getOffloadTopologies() { + static std::vector Topologies( + OL_PLATFORM_BACKEND_LAST); + return Topologies; +} + +std::vector> &getPlatformCache() { + static std::vector> PlatformCache{}; + return PlatformCache; +} + +std::mutex &getPlatformMapMutex() { + static std::mutex PlatformMapMutex{}; + return PlatformMapMutex; +} + +void shutdown() { + // No error reporting in shutdown + std::ignore = olShutDown(); +} + +#ifdef _WIN32 +extern "C" _LIBSYCL_EXPORT BOOL WINAPI DllMain(HINSTANCE hinstDLL, + DWORD fdwReason, + LPVOID lpReserved) { + // Perform actions based on the reason for calling. + switch (fdwReason) { + case DLL_PROCESS_DETACH: + try { + shutdown(); + } catch (std::exception &e) { + // report + } + + break; + case DLL_PROCESS_ATTACH: + break; + case DLL_THREAD_ATTACH: + break; + case DLL_THREAD_DETACH: + break; + } + return TRUE; // Successful DLL_PROCESS_ATTACH. +} +#else +// Setting low priority on destructor ensures it runs after all other global +// destructors. Priorities 0-100 are reserved by the compiler. The priority +// value 110 allows SYCL users to run their destructors after runtime library +// deinitialization. +__attribute__((destructor(110))) static void syclUnload() { shutdown(); } +#endif +} // namespace detail +_LIBSYCL_END_NAMESPACE_SYCL diff --git a/libsycl/src/detail/global_objects.hpp b/libsycl/src/detail/global_objects.hpp new file mode 100644 index 0000000000000..57deee4e5529b --- /dev/null +++ b/libsycl/src/detail/global_objects.hpp @@ -0,0 +1,33 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBSYCL_GLOBAL_OBJECTS +#define _LIBSYCL_GLOBAL_OBJECTS + +#include +#include + +#include +#include +#include + +_LIBSYCL_BEGIN_NAMESPACE_SYCL + +namespace detail { +class platform_impl; + +// Offload topologies (one per backend) discovered from liboffload. +std::vector &getOffloadTopologies(); + +std::mutex &getPlatformMapMutex(); +std::vector> &getPlatformCache(); + +} // namespace detail +_LIBSYCL_END_NAMESPACE_SYCL + +#endif // _LIBSYCL_GLOBAL_OBJECTS diff --git a/libsycl/src/detail/offload/info_code.hpp b/libsycl/src/detail/offload/info_code.hpp new file mode 100644 index 0000000000000..a9734d380a7c4 --- /dev/null +++ b/libsycl/src/detail/offload/info_code.hpp @@ -0,0 +1,30 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBSYCL_INFO_CODE +#define _LIBSYCL_INFO_CODE + +_LIBSYCL_BEGIN_NAMESPACE_SYCL + +#include + +namespace detail { +template struct OffloadInfoCode; + +#define __SYCL_PARAM_TRAITS_SPEC(DescType, Desc, ReturnT, OffloadCode) \ + template <> struct OffloadInfoCode { \ + static constexpr auto value = OffloadCode; \ + }; +#include +#undef __SYCL_PARAM_TRAITS_SPEC + +} // namespace detail + +_LIBSYCL_END_NAMESPACE_SYCL + +#endif // _LIBSYCL_INFO_CODE diff --git a/libsycl/src/detail/offload/offload_topology.cpp b/libsycl/src/detail/offload/offload_topology.cpp new file mode 100644 index 0000000000000..8a85ab477b885 --- /dev/null +++ b/libsycl/src/detail/offload/offload_topology.cpp @@ -0,0 +1,79 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include +#include +#include + +#include +#include + +_LIBSYCL_BEGIN_NAMESPACE_SYCL + +namespace detail { + +void discoverOffloadDevices() { + [[maybe_unused]] static auto DiscoverOnce = [&]() { + call_and_throw(olInit); + + using PerBackendDataType = + std::array, + OL_PLATFORM_BACKEND_LAST>; + + PerBackendDataType Mapping; + // olIterateDevices calls lambda for every device. + // Returning early means jump to next iteration/next device. + call_nocheck( + olIterateDevices, + [](ol_device_handle_t Dev, void *User) -> bool { + auto *Data = static_cast(User); + ol_platform_handle_t Plat = nullptr; + ol_result_t Res = + call_nocheck(olGetDeviceInfo, Dev, OL_DEVICE_INFO_PLATFORM, + sizeof(Plat), &Plat); + // If error occures, ignore platform and continue iteration + if (Res != OL_SUCCESS) + return true; + + ol_platform_backend_t OlBackend = OL_PLATFORM_BACKEND_UNKNOWN; + Res = call_nocheck(olGetPlatformInfo, Plat, OL_PLATFORM_INFO_BACKEND, + sizeof(OlBackend), &OlBackend); + // If error occures, ignore platform and continue iteration + if (Res != OL_SUCCESS) + return true; + + // Skip host & unknown backends + if (OL_PLATFORM_BACKEND_HOST == OlBackend || + OL_PLATFORM_BACKEND_UNKNOWN == OlBackend) + return true; + + // Ensure backend index fits into array size + if (OlBackend >= OL_PLATFORM_BACKEND_LAST) + return true; + + auto &[Map, DevCount] = (*Data)[static_cast(OlBackend)]; + Map[Plat].push_back(Dev); + DevCount++; + return true; + }, + &Mapping); + // Now register all platforms and devices into the topologies + auto &OffloadTopologies = getOffloadTopologies(); + for (size_t I = 0; I < OL_PLATFORM_BACKEND_LAST; ++I) { + OffloadTopology &Topo = OffloadTopologies[I]; + Topo.set_backend(static_cast(I)); + Topo.registerNewPlatformsAndDevices(Mapping[I].first, Mapping[I].second); + } + + return true; + }(); +} + +} // namespace detail + +_LIBSYCL_END_NAMESPACE_SYCL diff --git a/libsycl/src/detail/offload/offload_topology.hpp b/libsycl/src/detail/offload/offload_topology.hpp new file mode 100644 index 0000000000000..3bf2e78c10050 --- /dev/null +++ b/libsycl/src/detail/offload/offload_topology.hpp @@ -0,0 +1,101 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBSYCL_OFFLOAD_TOPOLOGY +#define _LIBSYCL_OFFLOAD_TOPOLOGY + +#include + +#include + +#include +#include +#include + +_LIBSYCL_BEGIN_NAMESPACE_SYCL + +namespace detail { + +// Minimal span-like view +template struct range_view { + const T *ptr{}; + size_t len{}; + const T *begin() const { return ptr; } + const T *end() const { return ptr + len; } + const T &operator[](size_t i) const { return ptr[i]; } + size_t size() const { return len; } +}; + +using PlatformWithDevStorageType = + std::unordered_map>; + +// Contiguous global storage of platform handlers and device handles (grouped by +// platform) for a backend. +struct OffloadTopology { + OffloadTopology() : MBackend(OL_PLATFORM_BACKEND_UNKNOWN) {} + OffloadTopology(ol_platform_backend_t OlBackend) : MBackend(OlBackend) {} + + void set_backend(ol_platform_backend_t B) { MBackend = B; } + + // Platforms for this backend + range_view platforms() const { + return {MPlatforms.data(), MPlatforms.size()}; + } + + // Devices for a specific platform (platform_id is index into Platforms) + range_view devicesForPlatform(size_t PlatformId) const { + if (PlatformId >= MDevRangePerPlatformId.size()) + return {nullptr, 0}; + return MDevRangePerPlatformId[PlatformId]; + } + + // Register new platform and devices into this topology under that platform. + void + registerNewPlatformsAndDevices(PlatformWithDevStorageType &PlatformsAndDev, + size_t TotalDevCount) { + if (!PlatformsAndDev.size()) + return; + + MPlatforms.reserve(PlatformsAndDev.size()); + MDevRangePerPlatformId.reserve(MPlatforms.size()); + MDevices.reserve(TotalDevCount); + + for (auto &[NewPlatform, NewDevs] : PlatformsAndDev) { + MPlatforms.push_back(NewPlatform); + range_view R{MDevices.data() + MDevices.size(), + NewDevs.size()}; + MDevices.insert(MDevices.end(), NewDevs.begin(), NewDevs.end()); + MDevRangePerPlatformId.push_back(R); + } + + assert(TotalDevCount == MDevices.size()); + } + + ol_platform_backend_t backend() { return MBackend; } + +private: + ol_platform_backend_t MBackend = OL_PLATFORM_BACKEND_UNKNOWN; + + // Platforms and devices belonging to this backend (flattened) + std::vector MPlatforms; + std::vector MDevices; // sorted by platform + + // Vector holding range of devices for each platform (index is platform index + // within Platforms) + std::vector> + MDevRangePerPlatformId; // PlatformDevices.size() == Platforms.size() +}; + +// Initialize the topologies by calling olIterateDevices. +void discoverOffloadDevices(); + +} // namespace detail + +_LIBSYCL_END_NAMESPACE_SYCL + +#endif // _LIBSYCL_OFFLOAD_TOPOLOGY diff --git a/libsycl/src/detail/offload/offload_utils.cpp b/libsycl/src/detail/offload/offload_utils.cpp new file mode 100644 index 0000000000000..2ccb27a9acf44 --- /dev/null +++ b/libsycl/src/detail/offload/offload_utils.cpp @@ -0,0 +1,65 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include + +_LIBSYCL_BEGIN_NAMESPACE_SYCL +namespace detail { + +const char *stringifyErrorCode(int32_t error) { + switch (error) { +#define _OFFLOAD_ERRC(NAME) \ + case NAME: \ + return #NAME; + _OFFLOAD_ERRC(OL_ERRC_UNKNOWN) + _OFFLOAD_ERRC(OL_ERRC_HOST_IO) + _OFFLOAD_ERRC(OL_ERRC_INVALID_BINARY) + _OFFLOAD_ERRC(OL_ERRC_INVALID_NULL_POINTER) + _OFFLOAD_ERRC(OL_ERRC_INVALID_ARGUMENT) + _OFFLOAD_ERRC(OL_ERRC_NOT_FOUND) + _OFFLOAD_ERRC(OL_ERRC_OUT_OF_RESOURCES) + _OFFLOAD_ERRC(OL_ERRC_INVALID_SIZE) + _OFFLOAD_ERRC(OL_ERRC_INVALID_ENUMERATION) + _OFFLOAD_ERRC(OL_ERRC_HOST_TOOL_NOT_FOUND) + _OFFLOAD_ERRC(OL_ERRC_INVALID_VALUE) + _OFFLOAD_ERRC(OL_ERRC_UNIMPLEMENTED) + _OFFLOAD_ERRC(OL_ERRC_UNSUPPORTED) + _OFFLOAD_ERRC(OL_ERRC_ASSEMBLE_FAILURE) + _OFFLOAD_ERRC(OL_ERRC_COMPILE_FAILURE) + _OFFLOAD_ERRC(OL_ERRC_LINK_FAILURE) + _OFFLOAD_ERRC(OL_ERRC_BACKEND_FAILURE) + _OFFLOAD_ERRC(OL_ERRC_UNINITIALIZED) + _OFFLOAD_ERRC(OL_ERRC_INVALID_NULL_HANDLE) + _OFFLOAD_ERRC(OL_ERRC_INVALID_PLATFORM) + _OFFLOAD_ERRC(OL_ERRC_INVALID_DEVICE) + _OFFLOAD_ERRC(OL_ERRC_INVALID_QUEUE) + _OFFLOAD_ERRC(OL_ERRC_INVALID_EVENT) + _OFFLOAD_ERRC(OL_ERRC_SYMBOL_KIND) +#undef _OFFLOAD_ERRC + + default: + return "Unknown error code"; + } +} + +backend convertBackend(ol_platform_backend_t Backend) { + switch (Backend) { + // case OL_PLATFORM_BACKEND_LEVEL_ZERO: + // return backend::level_zero; + case OL_PLATFORM_BACKEND_CUDA: + return backend::cuda; + case OL_PLATFORM_BACKEND_AMDGPU: + return backend::hip; + default: + throw exception(make_error_code(errc::runtime), + "convertBackend: Unsupported backend"); + } +} + +} // namespace detail +_LIBSYCL_END_NAMESPACE_SYCL diff --git a/libsycl/src/detail/offload/offload_utils.hpp b/libsycl/src/detail/offload/offload_utils.hpp new file mode 100644 index 0000000000000..b48a6b49d2fd6 --- /dev/null +++ b/libsycl/src/detail/offload/offload_utils.hpp @@ -0,0 +1,59 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBSYCL_OFFLOAD_UTILS +#define _LIBSYCL_OFFLOAD_UTILS + +#include +#include +#include + +#include + +_LIBSYCL_BEGIN_NAMESPACE_SYCL + +namespace detail { + +const char *stringifyErrorCode(int32_t error); + +inline std::string formatCodeString(int32_t code) { + return std::to_string(code) + " (" + std::string(stringifyErrorCode(code)) + + ")"; +} + +template +void checkAndThrow(ol_result_t Result) { + if (Result != OL_SUCCESS) { + throw sycl::exception(sycl::make_error_code(errc), + detail::formatCodeString(Result->Code)); + } +} + +/// Calls the API, doesn't check result. To be called when specific handling is +/// needed and explicitly done by developer after. +template +ol_result_t call_nocheck(FunctionType &Function, ArgsT &&...Args) { + return Function(std::forward(Args)...); +} + +/// Calls the API & checks the result +/// +/// \throw sycl::runtime_exception if the call was not successful. +template +void call_and_throw(FunctionType &Function, ArgsT &&...Args) { + auto Err = call_nocheck(Function, std::forward(Args)...); + checkAndThrow(Err); +} + +backend convertBackend(ol_platform_backend_t Backend); + +} // namespace detail + +_LIBSYCL_END_NAMESPACE_SYCL + +#endif // _LIBSYCL_OFFLOAD_UTILS diff --git a/libsycl/src/detail/platform_impl.cpp b/libsycl/src/detail/platform_impl.cpp new file mode 100644 index 0000000000000..324ec369cfcec --- /dev/null +++ b/libsycl/src/detail/platform_impl.cpp @@ -0,0 +1,65 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include +#include + +#include +#include + +_LIBSYCL_BEGIN_NAMESPACE_SYCL + +namespace detail { + +platform_impl * +platform_impl::getOrMakePlatformImpl(ol_platform_handle_t Platform, + size_t PlatformIndex) { + const std::lock_guard Guard(getPlatformMapMutex()); + + std::vector> &PlatformCache = + getPlatformCache(); + + // If we've already seen this platform, return the impl + for (const auto &PlatImpl : PlatformCache) { + if (PlatImpl->getHandleRef() == Platform) + return PlatImpl.get(); + } + + // Otherwise make the impl. + std::unique_ptr Result; + Result = std::make_unique(Platform, PlatformIndex); + PlatformCache.emplace_back(std::move(Result)); + + return PlatformCache.back().get(); +} + +std::vector platform_impl::getPlatforms() { + discoverOffloadDevices(); + std::vector Platforms; + for (const auto &Topo : getOffloadTopologies()) { + size_t PlatformIndex = 0; + for (const auto &OffloadPlatform : Topo.platforms()) { + platform Platform = detail::createSyclObjFromImpl( + *getOrMakePlatformImpl(OffloadPlatform, PlatformIndex++)); + Platforms.push_back(std::move(Platform)); + } + } + return Platforms; +} + +platform_impl::platform_impl(ol_platform_handle_t Platform, + size_t PlatformIndex) + : MOffloadPlatform(Platform), MOffloadPlatformIndex(PlatformIndex) { + ol_platform_backend_t Backend = OL_PLATFORM_BACKEND_UNKNOWN; + call_and_throw(olGetPlatformInfo, MOffloadPlatform, OL_PLATFORM_INFO_BACKEND, + sizeof(Backend), &Backend); + MBackend = convertBackend(Backend); + MOffloadBackend = Backend; +} +} // namespace detail +_LIBSYCL_END_NAMESPACE_SYCL diff --git a/libsycl/src/detail/platform_impl.hpp b/libsycl/src/detail/platform_impl.hpp new file mode 100644 index 0000000000000..45a1cf37c1d3b --- /dev/null +++ b/libsycl/src/detail/platform_impl.hpp @@ -0,0 +1,102 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBSYCL_PLATFORM_IMPL +#define _LIBSYCL_PLATFORM_IMPL + +#include +#include +#include + +#include "detail/offload/info_code.hpp" +#include "detail/offload/offload_utils.hpp" + +#include + +#include +#include +#include +#include + +_LIBSYCL_BEGIN_NAMESPACE_SYCL + +namespace detail { + +class platform_impl { +public: + /// Constructs platform_impl from a platform handle. + /// + /// \param Platform is a raw offload library handle representing platform. + /// \param PlatformIndex is a platform index in a backend (needed for a proper + /// indexing in device selector). + // + // Platforms can only be created under `GlobalHandler`'s ownership via + // `platform_impl::getOrMakePlatformImpl` method. + explicit platform_impl(ol_platform_handle_t Platform, size_t PlatformIndex); + + ~platform_impl() = default; + + /// Returns the backend associated with this platform. + backend getBackend() const noexcept { return MBackend; } + + /// Returns all SYCL platforms from all backends that are available in the + /// system. + static std::vector getPlatforms(); + + /// Returns raw underlying offload platform handle. + /// + /// It does not retain handle. It is caller responsibility to make sure that + /// platform stays alive while raw handle is in use. + /// + /// \return a raw plug-in platform handle. + const ol_platform_handle_t &getHandleRef() const { return MOffloadPlatform; } + + /// Returns platform index in a backend (needed for a proper indexing in + /// device selector). + size_t getPlatformIndex() const { return MOffloadPlatformIndex; } + + /// Queries the cache to see if the specified offloading RT platform has been + /// seen before. If so, return the cached platform_impl, otherwise create a + /// new one and cache it. + /// + /// \param Platform is the offloading RT Platform handle representing the + /// platform + /// \param PlatformIndex is a platform index in a backend (needed for a proper + /// indexing in device selector). + /// \return the platform_impl representing the offloading RT platform + static platform_impl *getOrMakePlatformImpl(ol_platform_handle_t Platform, + size_t PlatformIndex); + + /// Queries this SYCL platform for info. + /// + /// The return type depends on information being queried. + template typename Param::return_type get_info() const { + // for now we have only std::string properties + static_assert(std::is_same_v); + size_t ExpectedSize = 0; + call_and_throw(olGetPlatformInfoSize, MOffloadPlatform, + detail::OffloadInfoCode::value, &ExpectedSize); + std::string Result; + Result.resize(ExpectedSize - 1); + call_and_throw(olGetPlatformInfo, MOffloadPlatform, + detail::OffloadInfoCode::value, ExpectedSize, + Result.data()); + return Result; + } + +private: + ol_platform_handle_t MOffloadPlatform{}; + size_t MOffloadPlatformIndex{}; + ol_platform_backend_t MOffloadBackend{OL_PLATFORM_BACKEND_UNKNOWN}; + backend MBackend{}; +}; + +} // namespace detail +_LIBSYCL_END_NAMESPACE_SYCL + +#endif // _LIBSYCL_PLATFORM_IMPL diff --git a/libsycl/src/exception.cpp b/libsycl/src/exception.cpp new file mode 100644 index 0000000000000..38fd8816934b9 --- /dev/null +++ b/libsycl/src/exception.cpp @@ -0,0 +1,57 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// This file contains the definition of the SYCL 2020 exception class interface +/// (4.13.2.) +/// +//===----------------------------------------------------------------------===// + +// 4.9.2 Exception Class Interface +#include +#include + +_LIBSYCL_BEGIN_NAMESPACE_SYCL + +namespace detail { +class SYCLCategory : public std::error_category { +public: + const char *name() const noexcept override { return "sycl"; } + std::string message(int) const override { return "SYCL Error"; } +}; +} // namespace detail + +// Free functions +const std::error_category &sycl_category() noexcept { + static const detail::SYCLCategory SYCLCategoryObj; + return SYCLCategoryObj; +} + +std::error_code make_error_code(sycl::errc Err) noexcept { + return std::error_code(static_cast(Err), sycl_category()); +} + +// Exception methods implementation +exception::exception(std::error_code EC, const char *Msg) + : MMessage(std::make_shared(Msg)), MErrC(EC) {} + +exception::~exception() {} + +const std::error_code &exception::code() const noexcept { return MErrC; } + +const std::error_category &exception::category() const noexcept { + return code().category(); +} + +const char *exception::what() const noexcept { return MMessage->c_str(); } + +bool exception::has_context() const noexcept { /*return (MContext != nullptr);*/ + return false; +} + +_LIBSYCL_END_NAMESPACE_SYCL diff --git a/libsycl/src/exception_list.cpp b/libsycl/src/exception_list.cpp new file mode 100644 index 0000000000000..3eaf213deaaec --- /dev/null +++ b/libsycl/src/exception_list.cpp @@ -0,0 +1,27 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// This file contains the definition of the SYCL 2020 exception_list class +/// interface (4.13.2.) +/// +//===----------------------------------------------------------------------===// + +// 4.13.2. Exception class interface +#include +#include + +_LIBSYCL_BEGIN_NAMESPACE_SYCL + +exception_list::size_type exception_list::size() const { return MList.size(); } + +exception_list::iterator exception_list::begin() const { return MList.begin(); } + +exception_list::iterator exception_list::end() const { return MList.cend(); } + +_LIBSYCL_END_NAMESPACE_SYCL diff --git a/libsycl/src/platform.cpp b/libsycl/src/platform.cpp index b5d6517ee2120..1dc42a3f39b87 100644 --- a/libsycl/src/platform.cpp +++ b/libsycl/src/platform.cpp @@ -8,10 +8,29 @@ #include +#include + #include _LIBSYCL_BEGIN_NAMESPACE_SYCL -platform::platform() { throw std::runtime_error("Unimplemented"); } +backend platform::get_backend() const noexcept { return impl.getBackend(); } + +std::vector platform::get_platforms() { + return detail::platform_impl::getPlatforms(); +} + +template +typename detail::is_platform_info_desc::return_type +platform::get_info_impl() const { + return impl.template get_info(); +} + +#define __SYCL_PARAM_TRAITS_SPEC(DescType, Desc, ReturnT, OffloadCode) \ + template _LIBSYCL_EXPORT ReturnT \ + platform::get_info_impl() const; + +#include +#undef __SYCL_PARAM_TRAITS_SPEC _LIBSYCL_END_NAMESPACE_SYCL diff --git a/libsycl/tools/CMakeLists.txt b/libsycl/tools/CMakeLists.txt new file mode 100644 index 0000000000000..74cfa653232c7 --- /dev/null +++ b/libsycl/tools/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(sycl-ls) diff --git a/libsycl/tools/sycl-ls/CMakeLists.txt b/libsycl/tools/sycl-ls/CMakeLists.txt new file mode 100644 index 0000000000000..302ed43248007 --- /dev/null +++ b/libsycl/tools/sycl-ls/CMakeLists.txt @@ -0,0 +1,25 @@ +add_executable(sycl-ls sycl-ls.cpp) + +target_include_directories(sycl-ls SYSTEM PRIVATE ${LLVM_MAIN_INCLUDE_DIR}) +target_link_libraries(sycl-ls PRIVATE LLVMSupport LLVMObject) + +add_dependencies(sycl-ls sycl) +target_include_directories(sycl-ls PRIVATE ${LIBSYCL_BUILD_INCLUDE_DIR}) + +target_link_libraries(sycl-ls + PRIVATE + ${LIBSYCL_SHARED_OUTPUT_NAME} +) + +include(CheckCXXCompilerFlag) +check_cxx_compiler_flag(-fno-rtti COMPILER_HAS_NORTTI_FLAG) +if (COMPILER_HAS_NORTTI_FLAG) + target_compile_options(sycl-ls PRIVATE -fno-rtti) +endif() + +if (WIN32) + # 0x900: Search for the dependency DLLs only in the System32 directory and in the directory with sycl-ls.exe + target_link_options(sycl-ls PRIVATE LINKER:/DEPENDENTLOADFLAG:0x900) +endif() +install(TARGETS sycl-ls + RUNTIME DESTINATION "bin" COMPONENT sycl-ls) diff --git a/libsycl/tools/sycl-ls/sycl-ls.cpp b/libsycl/tools/sycl-ls/sycl-ls.cpp new file mode 100644 index 0000000000000..d611a98af8063 --- /dev/null +++ b/libsycl/tools/sycl-ls/sycl-ls.cpp @@ -0,0 +1,70 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// The "sycl-ls" utility lists all platforms discovered by SYCL. +// +// There are two types of output: +// concise (default) and +// verbose (enabled with --verbose). +// +#include + +#include "llvm/Support/CommandLine.h" + +#include + +using namespace sycl; +using namespace std::literals; + +int main(int argc, char **argv) { + llvm::cl::opt Verbose( + "verbose", + llvm::cl::desc("Verbosely prints all the discovered platforms")); + llvm::cl::alias VerboseShort("v", llvm::cl::desc("Alias for -verbose"), + llvm::cl::aliasopt(Verbose)); + llvm::cl::ParseCommandLineOptions( + argc, argv, "This program lists all backends discovered by SYCL"); + + try { + const auto &Platforms = platform::get_platforms(); + + if (Platforms.size() == 0) { + std::cout << "No platforms found." << std::endl; + } + + for (const auto &Platform : Platforms) { + backend Backend = Platform.get_backend(); + std::cout << "[" << detail::get_backend_name(Backend) << ":" + << "unknown" << "]" << std::endl; + } + + if (Verbose) { + std::cout << "\nPlatforms: " << Platforms.size() << std::endl; + uint32_t PlatformNum = 0; + for (const auto &Platform : Platforms) { + ++PlatformNum; + auto PlatformVersion = Platform.get_info(); + auto PlatformName = Platform.get_info(); + auto PlatformVendor = Platform.get_info(); + std::cout << "Platform [#" << PlatformNum << "]:" << std::endl; + std::cout << " Version : " << PlatformVersion << std::endl; + std::cout << " Name : " << PlatformName << std::endl; + std::cout << " Vendor : " << PlatformVendor << std::endl; + + std::cout << " Devices : " << "unknown" << std::endl; + } + } else { + return EXIT_SUCCESS; + } + } catch (sycl::exception &e) { + std::cerr << "SYCL Exception encountered: " << e.what() << std::endl + << std::endl; + } + + return EXIT_SUCCESS; +} From bcb27113006043db629942ce7cd6eb9afbe593ff Mon Sep 17 00:00:00 2001 From: "Tikhomirova, Kseniya" Date: Tue, 18 Nov 2025 05:03:39 -0800 Subject: [PATCH 02/22] add partial spec and base for std::hash support Signed-off-by: Tikhomirova, Kseniya --- .../include/sycl/__impl/detail/obj_base.hpp | 20 +++++++++++++++++-- libsycl/include/sycl/__impl/platform.hpp | 8 ++++++-- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/libsycl/include/sycl/__impl/detail/obj_base.hpp b/libsycl/include/sycl/__impl/detail/obj_base.hpp index d0314bbdbf767..0ccbde1de6059 100644 --- a/libsycl/include/sycl/__impl/detail/obj_base.hpp +++ b/libsycl/include/sycl/__impl/detail/obj_base.hpp @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -25,10 +26,12 @@ _LIBSYCL_BEGIN_NAMESPACE_SYCL namespace detail { -template class ObjBase { +template class ObjBase; +template +class ObjBase { public: using ImplType = Impl; - using Base = ObjBase; + using Base = ObjBase; protected: ImplType &impl; @@ -57,6 +60,19 @@ Obj createSyclObjFromImpl( return Obj::Base::createSyclProxy(ImplObj); } +// std::hash support (4.5.2. Common reference semantics) +template struct HashBase { + size_t operator()(const T &Obj) const { +#ifdef __SYCL_DEVICE_ONLY__ + (void)Obj; + return 0; +#else + auto &Impl = sycl::detail::getSyclObjImpl(Obj); + return std::hash>{}(Impl); +#endif + } +}; + } // namespace detail _LIBSYCL_END_NAMESPACE_SYCL diff --git a/libsycl/include/sycl/__impl/platform.hpp b/libsycl/include/sycl/__impl/platform.hpp index b54c339208e84..85182e7d52a68 100644 --- a/libsycl/include/sycl/__impl/platform.hpp +++ b/libsycl/include/sycl/__impl/platform.hpp @@ -31,7 +31,7 @@ class platform_impl; // 4.6.2. Platform class class _LIBSYCL_EXPORT platform - : public detail::ObjBase { + : public detail::ObjBase { public: /// Constructs a platform object that is a copy of the platform which contains /// the device returned by default_selector_v. @@ -104,9 +104,13 @@ class _LIBSYCL_EXPORT platform typename detail::is_platform_info_desc::return_type get_info_impl() const; - friend detail::ObjBase; + friend detail::ObjBase; }; // class platform _LIBSYCL_END_NAMESPACE_SYCL +template <> +struct std::hash + : public sycl::detail::HashBase {}; + #endif // _LIBSYCL___IMPL_PLATFORM_HPP From b15b6c09f1090f53deef483a8cf41cdcd173ec51 Mon Sep 17 00:00:00 2001 From: "Tikhomirova, Kseniya" Date: Wed, 19 Nov 2025 05:43:55 -0800 Subject: [PATCH 03/22] fix comments Signed-off-by: Tikhomirova, Kseniya --- libsycl/include/sycl/__impl/backend.hpp | 1 + libsycl/include/sycl/__impl/platform.hpp | 8 +------- libsycl/src/detail/platform_impl.hpp | 4 ++-- libsycl/src/platform.cpp | 11 +++++------ 4 files changed, 9 insertions(+), 15 deletions(-) diff --git a/libsycl/include/sycl/__impl/backend.hpp b/libsycl/include/sycl/__impl/backend.hpp index bc361e487af69..4b467f50cce5f 100644 --- a/libsycl/include/sycl/__impl/backend.hpp +++ b/libsycl/include/sycl/__impl/backend.hpp @@ -47,6 +47,7 @@ using backend_return_t = typename backend_traits::template return_type; namespace detail { +// Used by SYCL tools inline std::string_view get_backend_name(const backend &Backend) { switch (Backend) { case backend::opencl: diff --git a/libsycl/include/sycl/__impl/platform.hpp b/libsycl/include/sycl/__impl/platform.hpp index 85182e7d52a68..3e3fb3fb9facf 100644 --- a/libsycl/include/sycl/__impl/platform.hpp +++ b/libsycl/include/sycl/__impl/platform.hpp @@ -64,9 +64,7 @@ class _LIBSYCL_EXPORT platform /// /// The return type depends on information being queried. template - typename detail::is_platform_info_desc::return_type get_info() const { - return get_info_impl(); - } + typename detail::is_platform_info_desc::return_type get_info() const; // template // typename detail::is_backend_info_desc::return_type @@ -100,10 +98,6 @@ class _LIBSYCL_EXPORT platform private: platform(detail::platform_impl &Impl) : ObjBase(Impl) {} - template - typename detail::is_platform_info_desc::return_type - get_info_impl() const; - friend detail::ObjBase; }; // class platform diff --git a/libsycl/src/detail/platform_impl.hpp b/libsycl/src/detail/platform_impl.hpp index 45a1cf37c1d3b..1d7301d4687df 100644 --- a/libsycl/src/detail/platform_impl.hpp +++ b/libsycl/src/detail/platform_impl.hpp @@ -13,8 +13,8 @@ #include #include -#include "detail/offload/info_code.hpp" -#include "detail/offload/offload_utils.hpp" +#include +#include #include diff --git a/libsycl/src/platform.cpp b/libsycl/src/platform.cpp index 1dc42a3f39b87..48d19148beb58 100644 --- a/libsycl/src/platform.cpp +++ b/libsycl/src/platform.cpp @@ -22,14 +22,13 @@ std::vector platform::get_platforms() { template typename detail::is_platform_info_desc::return_type -platform::get_info_impl() const { - return impl.template get_info(); +platform::get_info() const { + return impl.get_info(); } -#define __SYCL_PARAM_TRAITS_SPEC(DescType, Desc, ReturnT, OffloadCode) \ - template _LIBSYCL_EXPORT ReturnT \ - platform::get_info_impl() const; - +#define __SYCL_PARAM_TRAITS_SPEC(DescType, Desc, ReturnT, PiCode) \ + template _LIBSYCL_EXPORT ReturnT platform::get_info() \ + const; #include #undef __SYCL_PARAM_TRAITS_SPEC From 88d313c48f009086708ebba03ae989825c7b3e2d Mon Sep 17 00:00:00 2001 From: "Tikhomirova, Kseniya" Date: Wed, 19 Nov 2025 11:31:37 -0800 Subject: [PATCH 04/22] early init of platforms Signed-off-by: Tikhomirova, Kseniya --- libsycl/src/detail/common.hpp | 34 +++++++ libsycl/src/detail/global_objects.cpp | 5 -- libsycl/src/detail/global_objects.hpp | 1 - .../src/detail/offload/offload_topology.cpp | 89 +++++++++---------- .../src/detail/offload/offload_topology.hpp | 12 +-- libsycl/src/detail/platform_impl.cpp | 46 ++++------ libsycl/src/detail/platform_impl.hpp | 10 +-- libsycl/src/platform.cpp | 9 +- 8 files changed, 110 insertions(+), 96 deletions(-) create mode 100644 libsycl/src/detail/common.hpp diff --git a/libsycl/src/detail/common.hpp b/libsycl/src/detail/common.hpp new file mode 100644 index 0000000000000..e47c231f9ab81 --- /dev/null +++ b/libsycl/src/detail/common.hpp @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBSYCL_COMMON +#define _LIBSYCL_COMMON + +#include + +#include + +_LIBSYCL_BEGIN_NAMESPACE_SYCL + +namespace detail { + +// Minimal span-like view +template struct range_view { + const T *ptr{}; + size_t len{}; + const T *begin() const { return ptr; } + const T *end() const { return ptr + len; } + const T &operator[](size_t i) const { return ptr[i]; } + size_t size() const { return len; } +}; + +} // namespace detail + +_LIBSYCL_END_NAMESPACE_SYCL + +#endif // _LIBSYCL_COMMON diff --git a/libsycl/src/detail/global_objects.cpp b/libsycl/src/detail/global_objects.cpp index 1dbb7074ed453..e48eb9d9d0ae9 100644 --- a/libsycl/src/detail/global_objects.cpp +++ b/libsycl/src/detail/global_objects.cpp @@ -29,11 +29,6 @@ std::vector> &getPlatformCache() { return PlatformCache; } -std::mutex &getPlatformMapMutex() { - static std::mutex PlatformMapMutex{}; - return PlatformMapMutex; -} - void shutdown() { // No error reporting in shutdown std::ignore = olShutDown(); diff --git a/libsycl/src/detail/global_objects.hpp b/libsycl/src/detail/global_objects.hpp index 57deee4e5529b..81899623aed68 100644 --- a/libsycl/src/detail/global_objects.hpp +++ b/libsycl/src/detail/global_objects.hpp @@ -24,7 +24,6 @@ class platform_impl; // Offload topologies (one per backend) discovered from liboffload. std::vector &getOffloadTopologies(); -std::mutex &getPlatformMapMutex(); std::vector> &getPlatformCache(); } // namespace detail diff --git a/libsycl/src/detail/offload/offload_topology.cpp b/libsycl/src/detail/offload/offload_topology.cpp index 8a85ab477b885..c1509a39263e0 100644 --- a/libsycl/src/detail/offload/offload_topology.cpp +++ b/libsycl/src/detail/offload/offload_topology.cpp @@ -18,60 +18,55 @@ _LIBSYCL_BEGIN_NAMESPACE_SYCL namespace detail { void discoverOffloadDevices() { - [[maybe_unused]] static auto DiscoverOnce = [&]() { - call_and_throw(olInit); + call_and_throw(olInit); - using PerBackendDataType = - std::array, - OL_PLATFORM_BACKEND_LAST>; + using PerBackendDataType = + std::array, + OL_PLATFORM_BACKEND_LAST>; - PerBackendDataType Mapping; - // olIterateDevices calls lambda for every device. - // Returning early means jump to next iteration/next device. - call_nocheck( - olIterateDevices, - [](ol_device_handle_t Dev, void *User) -> bool { - auto *Data = static_cast(User); - ol_platform_handle_t Plat = nullptr; - ol_result_t Res = - call_nocheck(olGetDeviceInfo, Dev, OL_DEVICE_INFO_PLATFORM, - sizeof(Plat), &Plat); - // If error occures, ignore platform and continue iteration - if (Res != OL_SUCCESS) - return true; - - ol_platform_backend_t OlBackend = OL_PLATFORM_BACKEND_UNKNOWN; - Res = call_nocheck(olGetPlatformInfo, Plat, OL_PLATFORM_INFO_BACKEND, - sizeof(OlBackend), &OlBackend); - // If error occures, ignore platform and continue iteration - if (Res != OL_SUCCESS) - return true; + PerBackendDataType Mapping; + // olIterateDevices calls lambda for every device. + // Returning early means jump to next iteration/next device. + call_nocheck( + olIterateDevices, + [](ol_device_handle_t Dev, void *User) -> bool { + auto *Data = static_cast(User); + ol_platform_handle_t Plat = nullptr; + ol_result_t Res = call_nocheck( + olGetDeviceInfo, Dev, OL_DEVICE_INFO_PLATFORM, sizeof(Plat), &Plat); + // If error occures, ignore platform and continue iteration + if (Res != OL_SUCCESS) + return true; - // Skip host & unknown backends - if (OL_PLATFORM_BACKEND_HOST == OlBackend || - OL_PLATFORM_BACKEND_UNKNOWN == OlBackend) - return true; + ol_platform_backend_t OlBackend = OL_PLATFORM_BACKEND_UNKNOWN; + Res = call_nocheck(olGetPlatformInfo, Plat, OL_PLATFORM_INFO_BACKEND, + sizeof(OlBackend), &OlBackend); + // If error occures, ignore platform and continue iteration + if (Res != OL_SUCCESS) + return true; - // Ensure backend index fits into array size - if (OlBackend >= OL_PLATFORM_BACKEND_LAST) - return true; + // Skip host & unknown backends + if (OL_PLATFORM_BACKEND_HOST == OlBackend || + OL_PLATFORM_BACKEND_UNKNOWN == OlBackend) + return true; - auto &[Map, DevCount] = (*Data)[static_cast(OlBackend)]; - Map[Plat].push_back(Dev); - DevCount++; + // Ensure backend index fits into array size + if (OlBackend >= OL_PLATFORM_BACKEND_LAST) return true; - }, - &Mapping); - // Now register all platforms and devices into the topologies - auto &OffloadTopologies = getOffloadTopologies(); - for (size_t I = 0; I < OL_PLATFORM_BACKEND_LAST; ++I) { - OffloadTopology &Topo = OffloadTopologies[I]; - Topo.set_backend(static_cast(I)); - Topo.registerNewPlatformsAndDevices(Mapping[I].first, Mapping[I].second); - } - return true; - }(); + auto &[Map, DevCount] = (*Data)[static_cast(OlBackend)]; + Map[Plat].push_back(Dev); + DevCount++; + return true; + }, + &Mapping); + // Now register all platforms and devices into the topologies + auto &OffloadTopologies = getOffloadTopologies(); + for (size_t I = 0; I < OL_PLATFORM_BACKEND_LAST; ++I) { + OffloadTopology &Topo = OffloadTopologies[I]; + Topo.set_backend(static_cast(I)); + Topo.registerNewPlatformsAndDevices(Mapping[I].first, Mapping[I].second); + } } } // namespace detail diff --git a/libsycl/src/detail/offload/offload_topology.hpp b/libsycl/src/detail/offload/offload_topology.hpp index 3bf2e78c10050..211f6a88a18e6 100644 --- a/libsycl/src/detail/offload/offload_topology.hpp +++ b/libsycl/src/detail/offload/offload_topology.hpp @@ -11,6 +11,8 @@ #include +#include + #include #include @@ -21,16 +23,6 @@ _LIBSYCL_BEGIN_NAMESPACE_SYCL namespace detail { -// Minimal span-like view -template struct range_view { - const T *ptr{}; - size_t len{}; - const T *begin() const { return ptr; } - const T *end() const { return ptr + len; } - const T &operator[](size_t i) const { return ptr[i]; } - size_t size() const { return len; } -}; - using PlatformWithDevStorageType = std::unordered_map>; diff --git a/libsycl/src/detail/platform_impl.cpp b/libsycl/src/detail/platform_impl.cpp index 324ec369cfcec..e282a8bb12912 100644 --- a/libsycl/src/detail/platform_impl.cpp +++ b/libsycl/src/detail/platform_impl.cpp @@ -16,40 +16,32 @@ _LIBSYCL_BEGIN_NAMESPACE_SYCL namespace detail { -platform_impl * -platform_impl::getOrMakePlatformImpl(ol_platform_handle_t Platform, - size_t PlatformIndex) { - const std::lock_guard Guard(getPlatformMapMutex()); - - std::vector> &PlatformCache = - getPlatformCache(); - - // If we've already seen this platform, return the impl +platform_impl *platform_impl::getPlatformImpl(ol_platform_handle_t Platform) { + auto &PlatformCache = getPlatformCache(); for (const auto &PlatImpl : PlatformCache) { if (PlatImpl->getHandleRef() == Platform) return PlatImpl.get(); } - - // Otherwise make the impl. - std::unique_ptr Result; - Result = std::make_unique(Platform, PlatformIndex); - PlatformCache.emplace_back(std::move(Result)); - - return PlatformCache.back().get(); + assert(false && "All platform_impl objects must be created during initial " + "device & platform discovery"); + return nullptr; } -std::vector platform_impl::getPlatforms() { - discoverOffloadDevices(); - std::vector Platforms; - for (const auto &Topo : getOffloadTopologies()) { - size_t PlatformIndex = 0; - for (const auto &OffloadPlatform : Topo.platforms()) { - platform Platform = detail::createSyclObjFromImpl( - *getOrMakePlatformImpl(OffloadPlatform, PlatformIndex++)); - Platforms.push_back(std::move(Platform)); +range_view> platform_impl::getPlatforms() { + [[maybe_unused]] static auto InitPlatformsOnce = []() { + discoverOffloadDevices(); + auto &PlatformCache = getPlatformCache(); + for (const auto &Topo : getOffloadTopologies()) { + size_t PlatformIndex = 0; + for (const auto &OffloadPlatform : Topo.platforms()) { + PlatformCache.emplace_back( + std::make_unique(OffloadPlatform, PlatformIndex++)); + } } - } - return Platforms; + return true; + }(); + auto &PlatformCache = getPlatformCache(); + return {PlatformCache.data(), PlatformCache.size()}; } platform_impl::platform_impl(ol_platform_handle_t Platform, diff --git a/libsycl/src/detail/platform_impl.hpp b/libsycl/src/detail/platform_impl.hpp index 1d7301d4687df..4681cc69799d9 100644 --- a/libsycl/src/detail/platform_impl.hpp +++ b/libsycl/src/detail/platform_impl.hpp @@ -13,6 +13,7 @@ #include #include +#include #include #include @@ -44,9 +45,9 @@ class platform_impl { /// Returns the backend associated with this platform. backend getBackend() const noexcept { return MBackend; } - /// Returns all SYCL platforms from all backends that are available in the - /// system. - static std::vector getPlatforms(); + /// Returns range-view to all SYCL platforms from all backends that are + /// available in the system. + static range_view> getPlatforms(); /// Returns raw underlying offload platform handle. /// @@ -69,8 +70,7 @@ class platform_impl { /// \param PlatformIndex is a platform index in a backend (needed for a proper /// indexing in device selector). /// \return the platform_impl representing the offloading RT platform - static platform_impl *getOrMakePlatformImpl(ol_platform_handle_t Platform, - size_t PlatformIndex); + static platform_impl *getPlatformImpl(ol_platform_handle_t Platform); /// Queries this SYCL platform for info. /// diff --git a/libsycl/src/platform.cpp b/libsycl/src/platform.cpp index 48d19148beb58..f2acb7b2afcab 100644 --- a/libsycl/src/platform.cpp +++ b/libsycl/src/platform.cpp @@ -17,7 +17,14 @@ _LIBSYCL_BEGIN_NAMESPACE_SYCL backend platform::get_backend() const noexcept { return impl.getBackend(); } std::vector platform::get_platforms() { - return detail::platform_impl::getPlatforms(); + auto PlatformsView = detail::platform_impl::getPlatforms(); + std::vector Platforms; + for (size_t i = 0; i < PlatformsView.len; i++) { + platform Platform = + detail::createSyclObjFromImpl(*PlatformsView.ptr[i].get()); + Platforms.push_back(std::move(Platform)); + } + return Platforms; } template From 849fed99b6b2f603b23faeff0b6fbf3e2f93299c Mon Sep 17 00:00:00 2001 From: "Tikhomirova, Kseniya" Date: Thu, 20 Nov 2025 03:13:37 -0800 Subject: [PATCH 05/22] remove unique_ptr, make ref const, add operator== Signed-off-by: Tikhomirova, Kseniya --- .../include/sycl/__impl/detail/obj_base.hpp | 10 +++++----- libsycl/include/sycl/__impl/platform.hpp | 14 +++++++++++++- libsycl/src/detail/global_objects.cpp | 4 ++-- libsycl/src/detail/global_objects.hpp | 2 +- libsycl/src/detail/platform_impl.cpp | 19 +++++++++---------- libsycl/src/detail/platform_impl.hpp | 4 ++-- libsycl/src/platform.cpp | 5 +++-- 7 files changed, 35 insertions(+), 23 deletions(-) diff --git a/libsycl/include/sycl/__impl/detail/obj_base.hpp b/libsycl/include/sycl/__impl/detail/obj_base.hpp index 0ccbde1de6059..eb5af900c1584 100644 --- a/libsycl/include/sycl/__impl/detail/obj_base.hpp +++ b/libsycl/include/sycl/__impl/detail/obj_base.hpp @@ -34,19 +34,19 @@ class ObjBase { using Base = ObjBase; protected: - ImplType &impl; + const ImplType &impl; - explicit ObjBase(ImplType &pImpl) : impl(pImpl) {} + explicit ObjBase(const ImplType &pImpl) : impl(pImpl) {} ObjBase() = default; - static SyclObject createSyclProxy(ImplType &impl) { return SyclObject(impl); } + static SyclObject createSyclProxy(const ImplType &impl) { return SyclObject(impl); } template friend const typename Obj::ImplType &getSyclObjImpl(const Obj &Object); template friend Obj createSyclObjFromImpl( - std::add_lvalue_reference_t ImplObj); + std::add_lvalue_reference_t ImplObj); }; template @@ -56,7 +56,7 @@ const typename Obj::ImplType &getSyclObjImpl(const Obj &Object) { template Obj createSyclObjFromImpl( - std::add_lvalue_reference_t ImplObj) { + std::add_lvalue_reference_t ImplObj) { return Obj::Base::createSyclProxy(ImplObj); } diff --git a/libsycl/include/sycl/__impl/platform.hpp b/libsycl/include/sycl/__impl/platform.hpp index 3e3fb3fb9facf..ba30fdcd809c3 100644 --- a/libsycl/include/sycl/__impl/platform.hpp +++ b/libsycl/include/sycl/__impl/platform.hpp @@ -37,6 +37,18 @@ class _LIBSYCL_EXPORT platform /// the device returned by default_selector_v. // platform(); + platform(const platform &rhs) = default; + + platform(platform &&rhs) = default; + + platform &operator=(const platform &rhs) = default; + + platform &operator=(platform &&rhs) = default; + + bool operator==(const platform &rhs) const { return &impl == &rhs.impl; } + + bool operator!=(const platform &rhs) const { return !(*this == rhs); } + /// Constructs a platform object that is a copy of the platform which contains /// the device that is selected by selector. /// \param DeviceSelectorInstance is SYCL 2020 Device Selector, a simple @@ -96,7 +108,7 @@ class _LIBSYCL_EXPORT platform static std::vector get_platforms(); private: - platform(detail::platform_impl &Impl) : ObjBase(Impl) {} + platform(const detail::platform_impl &Impl) : ObjBase(Impl) {} friend detail::ObjBase; }; // class platform diff --git a/libsycl/src/detail/global_objects.cpp b/libsycl/src/detail/global_objects.cpp index e48eb9d9d0ae9..9990b4d27824a 100644 --- a/libsycl/src/detail/global_objects.cpp +++ b/libsycl/src/detail/global_objects.cpp @@ -24,8 +24,8 @@ std::vector &getOffloadTopologies() { return Topologies; } -std::vector> &getPlatformCache() { - static std::vector> PlatformCache{}; +std::vector &getPlatformCache() { + static std::vector PlatformCache{}; return PlatformCache; } diff --git a/libsycl/src/detail/global_objects.hpp b/libsycl/src/detail/global_objects.hpp index 81899623aed68..0b5ac246692bf 100644 --- a/libsycl/src/detail/global_objects.hpp +++ b/libsycl/src/detail/global_objects.hpp @@ -24,7 +24,7 @@ class platform_impl; // Offload topologies (one per backend) discovered from liboffload. std::vector &getOffloadTopologies(); -std::vector> &getPlatformCache(); +std::vector &getPlatformCache(); } // namespace detail _LIBSYCL_END_NAMESPACE_SYCL diff --git a/libsycl/src/detail/platform_impl.cpp b/libsycl/src/detail/platform_impl.cpp index e282a8bb12912..37a8be00a5a9d 100644 --- a/libsycl/src/detail/platform_impl.cpp +++ b/libsycl/src/detail/platform_impl.cpp @@ -16,26 +16,25 @@ _LIBSYCL_BEGIN_NAMESPACE_SYCL namespace detail { -platform_impl *platform_impl::getPlatformImpl(ol_platform_handle_t Platform) { +platform_impl& platform_impl::getPlatformImpl(ol_platform_handle_t Platform) { auto &PlatformCache = getPlatformCache(); - for (const auto &PlatImpl : PlatformCache) { - if (PlatImpl->getHandleRef() == Platform) - return PlatImpl.get(); + for (auto &PlatImpl : PlatformCache) { + if (PlatImpl.getHandleRef() == Platform) + return PlatImpl; } - assert(false && "All platform_impl objects must be created during initial " - "device & platform discovery"); - return nullptr; + + throw sycl::exception(sycl::make_error_code(sycl::errc::runtime), + "Platform for requested handle can't be created. This handle is not in the list of platforms discovered by liboffload"); } -range_view> platform_impl::getPlatforms() { +range_view platform_impl::getPlatforms() { [[maybe_unused]] static auto InitPlatformsOnce = []() { discoverOffloadDevices(); auto &PlatformCache = getPlatformCache(); for (const auto &Topo : getOffloadTopologies()) { size_t PlatformIndex = 0; for (const auto &OffloadPlatform : Topo.platforms()) { - PlatformCache.emplace_back( - std::make_unique(OffloadPlatform, PlatformIndex++)); + PlatformCache.emplace_back(platform_impl(OffloadPlatform, PlatformIndex++)); } } return true; diff --git a/libsycl/src/detail/platform_impl.hpp b/libsycl/src/detail/platform_impl.hpp index 4681cc69799d9..f794f791d6295 100644 --- a/libsycl/src/detail/platform_impl.hpp +++ b/libsycl/src/detail/platform_impl.hpp @@ -47,7 +47,7 @@ class platform_impl { /// Returns range-view to all SYCL platforms from all backends that are /// available in the system. - static range_view> getPlatforms(); + static range_view getPlatforms(); /// Returns raw underlying offload platform handle. /// @@ -70,7 +70,7 @@ class platform_impl { /// \param PlatformIndex is a platform index in a backend (needed for a proper /// indexing in device selector). /// \return the platform_impl representing the offloading RT platform - static platform_impl *getPlatformImpl(ol_platform_handle_t Platform); + static platform_impl& getPlatformImpl(ol_platform_handle_t Platform); /// Queries this SYCL platform for info. /// diff --git a/libsycl/src/platform.cpp b/libsycl/src/platform.cpp index f2acb7b2afcab..66c76d1c6bd73 100644 --- a/libsycl/src/platform.cpp +++ b/libsycl/src/platform.cpp @@ -19,9 +19,10 @@ backend platform::get_backend() const noexcept { return impl.getBackend(); } std::vector platform::get_platforms() { auto PlatformsView = detail::platform_impl::getPlatforms(); std::vector Platforms; - for (size_t i = 0; i < PlatformsView.len; i++) { + Platforms.reserve(PlatformsView.size()); + for (size_t i = 0; i < PlatformsView.size(); i++) { platform Platform = - detail::createSyclObjFromImpl(*PlatformsView.ptr[i].get()); + detail::createSyclObjFromImpl(PlatformsView[i]); Platforms.push_back(std::move(Platform)); } return Platforms; From 7f62590c2b830b83c81e59d95186565a12bd7072 Mon Sep 17 00:00:00 2001 From: "Tikhomirova, Kseniya" Date: Thu, 20 Nov 2025 03:29:50 -0800 Subject: [PATCH 06/22] fix installation Signed-off-by: Tikhomirova, Kseniya --- libsycl/CMakeLists.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libsycl/CMakeLists.txt b/libsycl/CMakeLists.txt index 54ef3d4b1878a..f25f51def0cc7 100644 --- a/libsycl/CMakeLists.txt +++ b/libsycl/CMakeLists.txt @@ -127,10 +127,11 @@ if (CMAKE_SYSTEM_NAME STREQUAL Windows) endif() endif() -add_subdirectory(src) - set(LIBSYCL_RT_LIBS ${LIBSYCL_SHARED_OUTPUT_NAME}) add_custom_target(libsycl-runtime-libraries DEPENDS ${LIBSYCL_RT_LIBS} ) + +add_subdirectory(src) + add_subdirectory(tools) From f081eeaf758558533582b6ba119dcca72b9f0d75 Mon Sep 17 00:00:00 2001 From: "Tikhomirova, Kseniya" Date: Thu, 20 Nov 2025 03:31:07 -0800 Subject: [PATCH 07/22] fix format Signed-off-by: Tikhomirova, Kseniya --- libsycl/include/sycl/__impl/detail/obj_base.hpp | 4 +++- libsycl/src/detail/platform_impl.cpp | 11 +++++++---- libsycl/src/detail/platform_impl.hpp | 2 +- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/libsycl/include/sycl/__impl/detail/obj_base.hpp b/libsycl/include/sycl/__impl/detail/obj_base.hpp index eb5af900c1584..fbeb47a70ebdd 100644 --- a/libsycl/include/sycl/__impl/detail/obj_base.hpp +++ b/libsycl/include/sycl/__impl/detail/obj_base.hpp @@ -39,7 +39,9 @@ class ObjBase { explicit ObjBase(const ImplType &pImpl) : impl(pImpl) {} ObjBase() = default; - static SyclObject createSyclProxy(const ImplType &impl) { return SyclObject(impl); } + static SyclObject createSyclProxy(const ImplType &impl) { + return SyclObject(impl); + } template friend const typename Obj::ImplType &getSyclObjImpl(const Obj &Object); diff --git a/libsycl/src/detail/platform_impl.cpp b/libsycl/src/detail/platform_impl.cpp index 37a8be00a5a9d..6bdb9188732d4 100644 --- a/libsycl/src/detail/platform_impl.cpp +++ b/libsycl/src/detail/platform_impl.cpp @@ -16,15 +16,17 @@ _LIBSYCL_BEGIN_NAMESPACE_SYCL namespace detail { -platform_impl& platform_impl::getPlatformImpl(ol_platform_handle_t Platform) { +platform_impl &platform_impl::getPlatformImpl(ol_platform_handle_t Platform) { auto &PlatformCache = getPlatformCache(); for (auto &PlatImpl : PlatformCache) { if (PlatImpl.getHandleRef() == Platform) return PlatImpl; } - throw sycl::exception(sycl::make_error_code(sycl::errc::runtime), - "Platform for requested handle can't be created. This handle is not in the list of platforms discovered by liboffload"); + throw sycl::exception( + sycl::make_error_code(sycl::errc::runtime), + "Platform for requested handle can't be created. This handle is not in " + "the list of platforms discovered by liboffload"); } range_view platform_impl::getPlatforms() { @@ -34,7 +36,8 @@ range_view platform_impl::getPlatforms() { for (const auto &Topo : getOffloadTopologies()) { size_t PlatformIndex = 0; for (const auto &OffloadPlatform : Topo.platforms()) { - PlatformCache.emplace_back(platform_impl(OffloadPlatform, PlatformIndex++)); + PlatformCache.emplace_back( + platform_impl(OffloadPlatform, PlatformIndex++)); } } return true; diff --git a/libsycl/src/detail/platform_impl.hpp b/libsycl/src/detail/platform_impl.hpp index f794f791d6295..41ca27ab34b94 100644 --- a/libsycl/src/detail/platform_impl.hpp +++ b/libsycl/src/detail/platform_impl.hpp @@ -70,7 +70,7 @@ class platform_impl { /// \param PlatformIndex is a platform index in a backend (needed for a proper /// indexing in device selector). /// \return the platform_impl representing the offloading RT platform - static platform_impl& getPlatformImpl(ol_platform_handle_t Platform); + static platform_impl &getPlatformImpl(ol_platform_handle_t Platform); /// Queries this SYCL platform for info. /// From 2224ab81d3f045b1f4daf9feb64ab0bb7b7a5d8b Mon Sep 17 00:00:00 2001 From: "Tikhomirova, Kseniya" Date: Wed, 26 Nov 2025 04:50:06 -0800 Subject: [PATCH 08/22] remove offload codes from distributed headers Signed-off-by: Tikhomirova, Kseniya --- libsycl/include/sycl/__impl/info/platform.def | 6 ++-- libsycl/include/sycl/__impl/info/platform.hpp | 4 +-- libsycl/src/detail/offload/info_code.hpp | 30 ------------------- libsycl/src/detail/platform_impl.hpp | 23 ++++++++++---- libsycl/src/platform.cpp | 2 +- 5 files changed, 23 insertions(+), 42 deletions(-) delete mode 100644 libsycl/src/detail/offload/info_code.hpp diff --git a/libsycl/include/sycl/__impl/info/platform.def b/libsycl/include/sycl/__impl/info/platform.def index 68835fc3e3640..f4198b610715c 100644 --- a/libsycl/include/sycl/__impl/info/platform.def +++ b/libsycl/include/sycl/__impl/info/platform.def @@ -3,6 +3,6 @@ static_assert(false, "__SYCL_PARAM_TRAITS_SPEC is required but not defined"); #endif // 4.6.2.4. Information descriptors -__SYCL_PARAM_TRAITS_SPEC(platform, version, std::string, OL_PLATFORM_INFO_VERSION) -__SYCL_PARAM_TRAITS_SPEC(platform, name, std::string, OL_PLATFORM_INFO_NAME) -__SYCL_PARAM_TRAITS_SPEC(platform, vendor, std::string, OL_PLATFORM_INFO_VENDOR_NAME) +__SYCL_PARAM_TRAITS_SPEC(platform, version, std::string) +__SYCL_PARAM_TRAITS_SPEC(platform, name, std::string) +__SYCL_PARAM_TRAITS_SPEC(platform, vendor, std::string) diff --git a/libsycl/include/sycl/__impl/info/platform.hpp b/libsycl/include/sycl/__impl/info/platform.hpp index d175b66adf570..ceaa818b5ebe4 100644 --- a/libsycl/include/sycl/__impl/info/platform.hpp +++ b/libsycl/include/sycl/__impl/info/platform.hpp @@ -23,7 +23,7 @@ _LIBSYCL_BEGIN_NAMESPACE_SYCL // A.1. Platform information descriptors namespace info { namespace platform { -#define __SYCL_PARAM_TRAITS_SPEC(DescType, Desc, ReturnT, OffloadCode) \ +#define __SYCL_PARAM_TRAITS_SPEC(DescType, Desc, ReturnT) \ struct Desc { \ using return_type = ReturnT; \ }; @@ -38,7 +38,7 @@ namespace platform { namespace detail { template struct is_platform_info_desc : std::false_type {}; -#define __SYCL_PARAM_TRAITS_SPEC(DescType, Desc, ReturnT, OffloadCode) \ +#define __SYCL_PARAM_TRAITS_SPEC(DescType, Desc, ReturnT) \ template <> \ struct is_##DescType##_info_desc : std::true_type { \ using return_type = info::DescType::Desc::return_type; \ diff --git a/libsycl/src/detail/offload/info_code.hpp b/libsycl/src/detail/offload/info_code.hpp deleted file mode 100644 index a9734d380a7c4..0000000000000 --- a/libsycl/src/detail/offload/info_code.hpp +++ /dev/null @@ -1,30 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef _LIBSYCL_INFO_CODE -#define _LIBSYCL_INFO_CODE - -_LIBSYCL_BEGIN_NAMESPACE_SYCL - -#include - -namespace detail { -template struct OffloadInfoCode; - -#define __SYCL_PARAM_TRAITS_SPEC(DescType, Desc, ReturnT, OffloadCode) \ - template <> struct OffloadInfoCode { \ - static constexpr auto value = OffloadCode; \ - }; -#include -#undef __SYCL_PARAM_TRAITS_SPEC - -} // namespace detail - -_LIBSYCL_END_NAMESPACE_SYCL - -#endif // _LIBSYCL_INFO_CODE diff --git a/libsycl/src/detail/platform_impl.hpp b/libsycl/src/detail/platform_impl.hpp index 41ca27ab34b94..ebb9ff7fc1e77 100644 --- a/libsycl/src/detail/platform_impl.hpp +++ b/libsycl/src/detail/platform_impl.hpp @@ -14,7 +14,6 @@ #include #include -#include #include #include @@ -72,20 +71,32 @@ class platform_impl { /// \return the platform_impl representing the offloading RT platform static platform_impl &getPlatformImpl(ol_platform_handle_t Platform); + template + static constexpr ol_platform_info_t getOffloadInfo() { + if constexpr (std::is_same_v) + return OL_PLATFORM_INFO_VERSION; + else if constexpr (std::is_same_v) + return OL_PLATFORM_INFO_NAME; + else if constexpr (std::is_same_v) + return OL_PLATFORM_INFO_VENDOR_NAME; + else + static_assert(false && "Convertion list for platform info is not full."); + } /// Queries this SYCL platform for info. /// /// The return type depends on information being queried. template typename Param::return_type get_info() const { // for now we have only std::string properties static_assert(std::is_same_v); + constexpr ol_platform_info_t OffloadCode = getOffloadInfo(); + size_t ExpectedSize = 0; - call_and_throw(olGetPlatformInfoSize, MOffloadPlatform, - detail::OffloadInfoCode::value, &ExpectedSize); + call_and_throw(olGetPlatformInfoSize, MOffloadPlatform, OffloadCode, + &ExpectedSize); std::string Result; Result.resize(ExpectedSize - 1); - call_and_throw(olGetPlatformInfo, MOffloadPlatform, - detail::OffloadInfoCode::value, ExpectedSize, - Result.data()); + call_and_throw(olGetPlatformInfo, MOffloadPlatform, OffloadCode, + ExpectedSize, Result.data()); return Result; } diff --git a/libsycl/src/platform.cpp b/libsycl/src/platform.cpp index 66c76d1c6bd73..e275d1d299777 100644 --- a/libsycl/src/platform.cpp +++ b/libsycl/src/platform.cpp @@ -34,7 +34,7 @@ platform::get_info() const { return impl.get_info(); } -#define __SYCL_PARAM_TRAITS_SPEC(DescType, Desc, ReturnT, PiCode) \ +#define __SYCL_PARAM_TRAITS_SPEC(DescType, Desc, ReturnT) \ template _LIBSYCL_EXPORT ReturnT platform::get_info() \ const; #include From 71dcdf971846cf50f90f9c4bfc79e6b685828745 Mon Sep 17 00:00:00 2001 From: "Tikhomirova, Kseniya" Date: Thu, 27 Nov 2025 04:00:58 -0800 Subject: [PATCH 09/22] change ref to impl to raw ptr Signed-off-by: Tikhomirova, Kseniya --- .../include/sycl/__impl/detail/obj_base.hpp | 19 +++++++++++-------- libsycl/include/sycl/__impl/platform.hpp | 6 +++--- libsycl/src/detail/common.hpp | 8 ++++---- .../src/detail/offload/offload_topology.hpp | 13 +++++++------ libsycl/src/platform.cpp | 8 +++++--- 5 files changed, 30 insertions(+), 24 deletions(-) diff --git a/libsycl/include/sycl/__impl/detail/obj_base.hpp b/libsycl/include/sycl/__impl/detail/obj_base.hpp index fbeb47a70ebdd..66598dc461e31 100644 --- a/libsycl/include/sycl/__impl/detail/obj_base.hpp +++ b/libsycl/include/sycl/__impl/detail/obj_base.hpp @@ -28,37 +28,40 @@ namespace detail { template class ObjBase; template -class ObjBase { +class ObjBase { public: using ImplType = Impl; - using Base = ObjBase; + using ImplPtrType = Impl *; + using Base = ObjBase; protected: - const ImplType &impl; + ImplPtrType impl; - explicit ObjBase(const ImplType &pImpl) : impl(pImpl) {} + explicit ObjBase(ImplPtrType pImpl) : impl(pImpl) {} ObjBase() = default; - static SyclObject createSyclProxy(const ImplType &impl) { + static SyclObject createSyclProxy(ImplPtrType impl) { return SyclObject(impl); } + ImplType &getImpl() const { return *impl; } + template friend const typename Obj::ImplType &getSyclObjImpl(const Obj &Object); template friend Obj createSyclObjFromImpl( - std::add_lvalue_reference_t ImplObj); + std::add_lvalue_reference_t ImplObj); }; template const typename Obj::ImplType &getSyclObjImpl(const Obj &Object) { - return Object.impl; + return *Object.impl; } template Obj createSyclObjFromImpl( - std::add_lvalue_reference_t ImplObj) { + std::add_lvalue_reference_t ImplObj) { return Obj::Base::createSyclProxy(ImplObj); } diff --git a/libsycl/include/sycl/__impl/platform.hpp b/libsycl/include/sycl/__impl/platform.hpp index ba30fdcd809c3..9bba6c6897b7c 100644 --- a/libsycl/include/sycl/__impl/platform.hpp +++ b/libsycl/include/sycl/__impl/platform.hpp @@ -31,7 +31,7 @@ class platform_impl; // 4.6.2. Platform class class _LIBSYCL_EXPORT platform - : public detail::ObjBase { + : public detail::ObjBase { public: /// Constructs a platform object that is a copy of the platform which contains /// the device returned by default_selector_v. @@ -108,9 +108,9 @@ class _LIBSYCL_EXPORT platform static std::vector get_platforms(); private: - platform(const detail::platform_impl &Impl) : ObjBase(Impl) {} + platform(detail::platform_impl *Impl) : ObjBase(Impl) {} - friend detail::ObjBase; + friend detail::ObjBase; }; // class platform _LIBSYCL_END_NAMESPACE_SYCL diff --git a/libsycl/src/detail/common.hpp b/libsycl/src/detail/common.hpp index e47c231f9ab81..43bee0560e2e8 100644 --- a/libsycl/src/detail/common.hpp +++ b/libsycl/src/detail/common.hpp @@ -19,11 +19,11 @@ namespace detail { // Minimal span-like view template struct range_view { - const T *ptr{}; + T *ptr{}; size_t len{}; - const T *begin() const { return ptr; } - const T *end() const { return ptr + len; } - const T &operator[](size_t i) const { return ptr[i]; } + T *begin() const { return ptr; } + T *end() const { return ptr + len; } + T &operator[](size_t i) const { return ptr[i]; } size_t size() const { return len; } }; diff --git a/libsycl/src/detail/offload/offload_topology.hpp b/libsycl/src/detail/offload/offload_topology.hpp index 211f6a88a18e6..36a488e486fe3 100644 --- a/libsycl/src/detail/offload/offload_topology.hpp +++ b/libsycl/src/detail/offload/offload_topology.hpp @@ -35,12 +35,13 @@ struct OffloadTopology { void set_backend(ol_platform_backend_t B) { MBackend = B; } // Platforms for this backend - range_view platforms() const { + range_view platforms() const { return {MPlatforms.data(), MPlatforms.size()}; } // Devices for a specific platform (platform_id is index into Platforms) - range_view devicesForPlatform(size_t PlatformId) const { + range_view + devicesForPlatform(size_t PlatformId) const { if (PlatformId >= MDevRangePerPlatformId.size()) return {nullptr, 0}; return MDevRangePerPlatformId[PlatformId]; @@ -59,8 +60,8 @@ struct OffloadTopology { for (auto &[NewPlatform, NewDevs] : PlatformsAndDev) { MPlatforms.push_back(NewPlatform); - range_view R{MDevices.data() + MDevices.size(), - NewDevs.size()}; + range_view R{MDevices.data() + MDevices.size(), + NewDevs.size()}; MDevices.insert(MDevices.end(), NewDevs.begin(), NewDevs.end()); MDevRangePerPlatformId.push_back(R); } @@ -68,7 +69,7 @@ struct OffloadTopology { assert(TotalDevCount == MDevices.size()); } - ol_platform_backend_t backend() { return MBackend; } + ol_platform_backend_t backend() const { return MBackend; } private: ol_platform_backend_t MBackend = OL_PLATFORM_BACKEND_UNKNOWN; @@ -79,7 +80,7 @@ struct OffloadTopology { // Vector holding range of devices for each platform (index is platform index // within Platforms) - std::vector> + std::vector> MDevRangePerPlatformId; // PlatformDevices.size() == Platforms.size() }; diff --git a/libsycl/src/platform.cpp b/libsycl/src/platform.cpp index e275d1d299777..79d83e4c957c0 100644 --- a/libsycl/src/platform.cpp +++ b/libsycl/src/platform.cpp @@ -14,7 +14,9 @@ _LIBSYCL_BEGIN_NAMESPACE_SYCL -backend platform::get_backend() const noexcept { return impl.getBackend(); } +backend platform::get_backend() const noexcept { + return getImpl().getBackend(); +} std::vector platform::get_platforms() { auto PlatformsView = detail::platform_impl::getPlatforms(); @@ -22,7 +24,7 @@ std::vector platform::get_platforms() { Platforms.reserve(PlatformsView.size()); for (size_t i = 0; i < PlatformsView.size(); i++) { platform Platform = - detail::createSyclObjFromImpl(PlatformsView[i]); + detail::createSyclObjFromImpl(&PlatformsView[i]); Platforms.push_back(std::move(Platform)); } return Platforms; @@ -31,7 +33,7 @@ std::vector platform::get_platforms() { template typename detail::is_platform_info_desc::return_type platform::get_info() const { - return impl.get_info(); + return getImpl().get_info(); } #define __SYCL_PARAM_TRAITS_SPEC(DescType, Desc, ReturnT) \ From 51529c19bca2480c21c75f1b7b17a01ba114c09f Mon Sep 17 00:00:00 2001 From: "Tikhomirova, Kseniya" Date: Thu, 27 Nov 2025 04:07:34 -0800 Subject: [PATCH 10/22] add asserts for impl Signed-off-by: Tikhomirova, Kseniya --- libsycl/include/sycl/__impl/detail/obj_base.hpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/libsycl/include/sycl/__impl/detail/obj_base.hpp b/libsycl/include/sycl/__impl/detail/obj_base.hpp index 66598dc461e31..8248791ac9ab7 100644 --- a/libsycl/include/sycl/__impl/detail/obj_base.hpp +++ b/libsycl/include/sycl/__impl/detail/obj_base.hpp @@ -37,14 +37,19 @@ class ObjBase { protected: ImplPtrType impl; - explicit ObjBase(ImplPtrType pImpl) : impl(pImpl) {} + explicit ObjBase(ImplPtrType pImpl) : impl(pImpl) { + assert(impl && "Impl can not be nullptr"); + } ObjBase() = default; static SyclObject createSyclProxy(ImplPtrType impl) { return SyclObject(impl); } - ImplType &getImpl() const { return *impl; } + ImplType &getImpl() const { + assert(impl && "Impl can not be nullptr"); + return *impl; + } template friend const typename Obj::ImplType &getSyclObjImpl(const Obj &Object); @@ -56,6 +61,7 @@ class ObjBase { template const typename Obj::ImplType &getSyclObjImpl(const Obj &Object) { + assert(Object.impl && "Impl can not be nullptr"); return *Object.impl; } From 821a30646717d6dfb49ff499bfb9bce080a6e0ff Mon Sep 17 00:00:00 2001 From: "Tikhomirova, Kseniya" Date: Mon, 1 Dec 2025 03:40:29 -0800 Subject: [PATCH 11/22] apply proposed impl of get_info Signed-off-by: Tikhomirova, Kseniya --- .../include/sycl/__impl/info/desc_base.hpp | 38 ++++++++++++++++++ libsycl/include/sycl/__impl/info/platform.def | 8 ---- libsycl/include/sycl/__impl/info/platform.hpp | 39 ++++++++----------- libsycl/include/sycl/__impl/platform.hpp | 2 +- libsycl/src/detail/offload/offload_utils.hpp | 21 ++++++++++ libsycl/src/detail/platform_impl.hpp | 16 ++++++-- libsycl/src/platform.cpp | 16 ++++---- 7 files changed, 98 insertions(+), 42 deletions(-) create mode 100644 libsycl/include/sycl/__impl/info/desc_base.hpp delete mode 100644 libsycl/include/sycl/__impl/info/platform.def diff --git a/libsycl/include/sycl/__impl/info/desc_base.hpp b/libsycl/include/sycl/__impl/info/desc_base.hpp new file mode 100644 index 0000000000000..930555db80e0b --- /dev/null +++ b/libsycl/include/sycl/__impl/info/desc_base.hpp @@ -0,0 +1,38 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// This file contains helpers for info descriptors +/// +//===----------------------------------------------------------------------===// + +#ifndef _LIBSYCL___IMPL_INFO_DESC_BASE_HPP +#define _LIBSYCL___IMPL_INFO_DESC_BASE_HPP + +#include + +_LIBSYCL_BEGIN_NAMESPACE_SYCL + +namespace detail { + +template struct info_desc_tag {}; +template +struct is_info_desc : std::false_type {}; +template +struct is_info_desc< + Desc, DescOf, + std::enable_if_t, Desc>>> + : std::true_type { + using return_type = typename Desc::return_type; +}; + +} // namespace detail + +_LIBSYCL_END_NAMESPACE_SYCL + +#endif // _LIBSYCL___IMPL_INFO_DESC_BASE_HPP diff --git a/libsycl/include/sycl/__impl/info/platform.def b/libsycl/include/sycl/__impl/info/platform.def deleted file mode 100644 index f4198b610715c..0000000000000 --- a/libsycl/include/sycl/__impl/info/platform.def +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef __SYCL_PARAM_TRAITS_SPEC -static_assert(false, "__SYCL_PARAM_TRAITS_SPEC is required but not defined"); -#endif - -// 4.6.2.4. Information descriptors -__SYCL_PARAM_TRAITS_SPEC(platform, version, std::string) -__SYCL_PARAM_TRAITS_SPEC(platform, name, std::string) -__SYCL_PARAM_TRAITS_SPEC(platform, vendor, std::string) diff --git a/libsycl/include/sycl/__impl/info/platform.hpp b/libsycl/include/sycl/__impl/info/platform.hpp index ceaa818b5ebe4..9e7dd061a8a6c 100644 --- a/libsycl/include/sycl/__impl/info/platform.hpp +++ b/libsycl/include/sycl/__impl/info/platform.hpp @@ -15,40 +15,35 @@ #define _LIBSYCL___IMPL_INFO_PLATFORM_HPP #include +#include #include _LIBSYCL_BEGIN_NAMESPACE_SYCL +class platform; + +namespace detail { +template +using is_platform_info_desc_t = typename is_info_desc::return_type; +} // namespace detail + // A.1. Platform information descriptors namespace info { namespace platform { -#define __SYCL_PARAM_TRAITS_SPEC(DescType, Desc, ReturnT) \ - struct Desc { \ - using return_type = ReturnT; \ - }; - // 4.6.2.4. Information descriptors -#include - -#undef __SYCL_PARAM_TRAITS_SPEC +struct version : detail::info_desc_tag { + using return_type = std::string; +}; +struct name : detail::info_desc_tag { + using return_type = std::string; +}; +struct vendor : detail::info_desc_tag { + using return_type = std::string; +}; } // namespace platform } // namespace info -namespace detail { -template struct is_platform_info_desc : std::false_type {}; - -#define __SYCL_PARAM_TRAITS_SPEC(DescType, Desc, ReturnT) \ - template <> \ - struct is_##DescType##_info_desc : std::true_type { \ - using return_type = info::DescType::Desc::return_type; \ - }; - -#include - -#undef __SYCL_PARAM_TRAITS_SPEC -} // namespace detail - _LIBSYCL_END_NAMESPACE_SYCL #endif // _LIBSYCL___IMPL_INFO_PLATFORM_HPP diff --git a/libsycl/include/sycl/__impl/platform.hpp b/libsycl/include/sycl/__impl/platform.hpp index 9bba6c6897b7c..681eb68eacaf8 100644 --- a/libsycl/include/sycl/__impl/platform.hpp +++ b/libsycl/include/sycl/__impl/platform.hpp @@ -76,7 +76,7 @@ class _LIBSYCL_EXPORT platform /// /// The return type depends on information being queried. template - typename detail::is_platform_info_desc::return_type get_info() const; + detail::is_platform_info_desc_t get_info() const; // template // typename detail::is_backend_info_desc::return_type diff --git a/libsycl/src/detail/offload/offload_utils.hpp b/libsycl/src/detail/offload/offload_utils.hpp index b48a6b49d2fd6..5f02feea98e3b 100644 --- a/libsycl/src/detail/offload/offload_utils.hpp +++ b/libsycl/src/detail/offload/offload_utils.hpp @@ -52,6 +52,27 @@ void call_and_throw(FunctionType &Function, ArgsT &&...Args) { backend convertBackend(ol_platform_backend_t Backend); +/// Helper to map SYCL information descriptors to OL__INFO_. To be +/// used like: +/// +/// using Map = info_ol_mapping; +/// constexpr auto olInfo = map_info_desc( +/// Map::M{OL_FOO_INFO_VAL0}, +/// Map::M{OL_FOO_INFO_VAL1}, +/// ...) +template struct info_ol_mapping { + template struct M { + To value; + constexpr M(To value) : value(value) {} + }; +}; +template +constexpr To map_info_desc(typename info_ol_mapping::template M... ms) { + return std::get::template M>( + std::tuple{ms...}) + .value; +} + } // namespace detail _LIBSYCL_END_NAMESPACE_SYCL diff --git a/libsycl/src/detail/platform_impl.hpp b/libsycl/src/detail/platform_impl.hpp index ebb9ff7fc1e77..8fbf76ce8e330 100644 --- a/libsycl/src/detail/platform_impl.hpp +++ b/libsycl/src/detail/platform_impl.hpp @@ -88,15 +88,23 @@ class platform_impl { template typename Param::return_type get_info() const { // for now we have only std::string properties static_assert(std::is_same_v); - constexpr ol_platform_info_t OffloadCode = getOffloadInfo(); + + using namespace info::platform; + using Map = info_ol_mapping; + + constexpr ol_platform_info_t olInfo = + map_info_desc( + Map::M{OL_PLATFORM_INFO_VERSION}, + Map::M{OL_PLATFORM_INFO_NAME}, + Map::M{OL_PLATFORM_INFO_VENDOR_NAME}); size_t ExpectedSize = 0; - call_and_throw(olGetPlatformInfoSize, MOffloadPlatform, OffloadCode, + call_and_throw(olGetPlatformInfoSize, MOffloadPlatform, olInfo, &ExpectedSize); std::string Result; Result.resize(ExpectedSize - 1); - call_and_throw(olGetPlatformInfo, MOffloadPlatform, OffloadCode, - ExpectedSize, Result.data()); + call_and_throw(olGetPlatformInfo, MOffloadPlatform, olInfo, ExpectedSize, + Result.data()); return Result; } diff --git a/libsycl/src/platform.cpp b/libsycl/src/platform.cpp index 79d83e4c957c0..6d35c8534f2a3 100644 --- a/libsycl/src/platform.cpp +++ b/libsycl/src/platform.cpp @@ -31,15 +31,17 @@ std::vector platform::get_platforms() { } template -typename detail::is_platform_info_desc::return_type -platform::get_info() const { +detail::is_platform_info_desc_t platform::get_info() const { return getImpl().get_info(); } -#define __SYCL_PARAM_TRAITS_SPEC(DescType, Desc, ReturnT) \ - template _LIBSYCL_EXPORT ReturnT platform::get_info() \ - const; -#include -#undef __SYCL_PARAM_TRAITS_SPEC +#define _LIBSYCL_EXPORT_GET_INFO(Desc) \ + template _LIBSYCL_EXPORT \ + detail::is_platform_info_desc_t \ + platform::get_info() const; +_LIBSYCL_EXPORT_GET_INFO(version) +_LIBSYCL_EXPORT_GET_INFO(name) +_LIBSYCL_EXPORT_GET_INFO(vendor) +#undef _LIBSYCL_EXPORT_GET_INFO _LIBSYCL_END_NAMESPACE_SYCL From 87442d1a48c48be0e511b6f200bd36e4c37f7a80 Mon Sep 17 00:00:00 2001 From: "Tikhomirova, Kseniya" Date: Tue, 2 Dec 2025 04:06:41 -0800 Subject: [PATCH 12/22] fix leftover of base class impl w/o friend funcs Signed-off-by: Tikhomirova, Kseniya --- libsycl/include/sycl/__impl/detail/obj_base.hpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libsycl/include/sycl/__impl/detail/obj_base.hpp b/libsycl/include/sycl/__impl/detail/obj_base.hpp index 8248791ac9ab7..16c383beb1f46 100644 --- a/libsycl/include/sycl/__impl/detail/obj_base.hpp +++ b/libsycl/include/sycl/__impl/detail/obj_base.hpp @@ -29,12 +29,11 @@ namespace detail { template class ObjBase; template class ObjBase { -public: +protected: using ImplType = Impl; using ImplPtrType = Impl *; using Base = ObjBase; -protected: ImplPtrType impl; explicit ObjBase(ImplPtrType pImpl) : impl(pImpl) { From e4e6fd234fd88b40b2858bb18cc7dda627dd3b03 Mon Sep 17 00:00:00 2001 From: "Tikhomirova, Kseniya" Date: Fri, 5 Dec 2025 04:10:49 -0800 Subject: [PATCH 13/22] fix comments Signed-off-by: Tikhomirova, Kseniya --- .../include/sycl/__impl/detail/obj_base.hpp | 90 ------------------- .../include/sycl/__impl/detail/obj_utils.hpp | 81 +++++++++++++++++ libsycl/include/sycl/__impl/platform.hpp | 10 +-- libsycl/src/detail/global_objects.cpp | 4 +- libsycl/src/detail/global_objects.hpp | 2 +- libsycl/src/detail/offload/offload_utils.cpp | 2 +- libsycl/src/detail/offload/offload_utils.hpp | 10 +-- libsycl/src/detail/platform_impl.cpp | 17 ++-- libsycl/src/detail/platform_impl.hpp | 17 ++-- libsycl/src/exception.cpp | 4 +- libsycl/src/platform.cpp | 15 ++-- libsycl/tools/sycl-ls/sycl-ls.cpp | 3 +- 12 files changed, 122 insertions(+), 133 deletions(-) delete mode 100644 libsycl/include/sycl/__impl/detail/obj_base.hpp create mode 100644 libsycl/include/sycl/__impl/detail/obj_utils.hpp diff --git a/libsycl/include/sycl/__impl/detail/obj_base.hpp b/libsycl/include/sycl/__impl/detail/obj_base.hpp deleted file mode 100644 index 16c383beb1f46..0000000000000 --- a/libsycl/include/sycl/__impl/detail/obj_base.hpp +++ /dev/null @@ -1,90 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -/// -/// \file -/// This file contains helper functions for tranformation between implementation -/// and SYCL's interface objects. -/// -//===----------------------------------------------------------------------===// - -#ifndef _LIBSYCL___IMPL_DETAIL_OBJ_BASE_HPP -#define _LIBSYCL___IMPL_DETAIL_OBJ_BASE_HPP - -#include - -#include -#include -#include -#include - -_LIBSYCL_BEGIN_NAMESPACE_SYCL - -namespace detail { - -template class ObjBase; -template -class ObjBase { -protected: - using ImplType = Impl; - using ImplPtrType = Impl *; - using Base = ObjBase; - - ImplPtrType impl; - - explicit ObjBase(ImplPtrType pImpl) : impl(pImpl) { - assert(impl && "Impl can not be nullptr"); - } - ObjBase() = default; - - static SyclObject createSyclProxy(ImplPtrType impl) { - return SyclObject(impl); - } - - ImplType &getImpl() const { - assert(impl && "Impl can not be nullptr"); - return *impl; - } - - template - friend const typename Obj::ImplType &getSyclObjImpl(const Obj &Object); - - template - friend Obj createSyclObjFromImpl( - std::add_lvalue_reference_t ImplObj); -}; - -template -const typename Obj::ImplType &getSyclObjImpl(const Obj &Object) { - assert(Object.impl && "Impl can not be nullptr"); - return *Object.impl; -} - -template -Obj createSyclObjFromImpl( - std::add_lvalue_reference_t ImplObj) { - return Obj::Base::createSyclProxy(ImplObj); -} - -// std::hash support (4.5.2. Common reference semantics) -template struct HashBase { - size_t operator()(const T &Obj) const { -#ifdef __SYCL_DEVICE_ONLY__ - (void)Obj; - return 0; -#else - auto &Impl = sycl::detail::getSyclObjImpl(Obj); - return std::hash>{}(Impl); -#endif - } -}; - -} // namespace detail - -_LIBSYCL_END_NAMESPACE_SYCL - -#endif // _LIBSYCL___IMPL_DETAIL_OBJ_BASE_HPP diff --git a/libsycl/include/sycl/__impl/detail/obj_utils.hpp b/libsycl/include/sycl/__impl/detail/obj_utils.hpp new file mode 100644 index 0000000000000..abbf9039856d0 --- /dev/null +++ b/libsycl/include/sycl/__impl/detail/obj_utils.hpp @@ -0,0 +1,81 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// This file contains helper functions for tranformation between implementation +/// and SYCL's interface objects. +/// +//===----------------------------------------------------------------------===// + +#ifndef _LIBSYCL___IMPL_DETAIL_OBJ_UTILS_HPP +#define _LIBSYCL___IMPL_DETAIL_OBJ_UTILS_HPP + +#include + +#include +#include +#include +#include +#include + +_LIBSYCL_BEGIN_NAMESPACE_SYCL + +namespace detail { + +// Note! This class relies on the fact that all SYCL interface +// classes contain "impl" field that points to implementation object. "impl" +// field should be accessible from this class. +struct ImplUtils { + // Helper function for extracting implementation from SYCL's interface + // objects. + template + static const decltype(Obj::impl) &getSyclObjImpl(const Obj &SyclObj) { + assert(SyclObj.impl && "every constructor should create an impl"); + return SyclObj.impl; + } + + // Helper function for creation SYCL interface objects from implementations. + template + static SyclObject createSyclObjFromImpl(From &&from) { + if constexpr (std::is_same_v>>) + return SyclObject{from.shared_from_this()}; + else + return SyclObject{std::forward(from)}; + } +}; + +template +auto getSyclObjImpl(const Obj &SyclObj) + -> decltype(ImplUtils::getSyclObjImpl(SyclObj)) { + return ImplUtils::getSyclObjImpl(SyclObj); +} + +template +SyclObject createSyclObjFromImpl(From &&from) { + return ImplUtils::createSyclObjFromImpl(std::forward(from)); +} + +// std::hash support (4.5.2. Common reference semantics) +template struct HashBase { + size_t operator()(const T &Obj) const { +#ifdef __SYCL_DEVICE_ONLY__ + (void)Obj; + return 0; +#else + auto &Impl = sycl::detail::getSyclObjImpl(Obj); + return std::hash>{}(Impl); +#endif + } +}; + +} // namespace detail + +_LIBSYCL_END_NAMESPACE_SYCL + +#endif // _LIBSYCL___IMPL_DETAIL_OBJ_UTILS_HPP diff --git a/libsycl/include/sycl/__impl/platform.hpp b/libsycl/include/sycl/__impl/platform.hpp index 681eb68eacaf8..431b01fc7278d 100644 --- a/libsycl/include/sycl/__impl/platform.hpp +++ b/libsycl/include/sycl/__impl/platform.hpp @@ -17,7 +17,7 @@ #include #include -#include +#include #include #include @@ -30,8 +30,7 @@ class platform_impl; } // namespace detail // 4.6.2. Platform class -class _LIBSYCL_EXPORT platform - : public detail::ObjBase { +class _LIBSYCL_EXPORT platform { public: /// Constructs a platform object that is a copy of the platform which contains /// the device returned by default_selector_v. @@ -108,9 +107,10 @@ class _LIBSYCL_EXPORT platform static std::vector get_platforms(); private: - platform(detail::platform_impl *Impl) : ObjBase(Impl) {} + platform(detail::platform_impl &Impl) : impl(&Impl) {} + detail::platform_impl *impl; - friend detail::ObjBase; + friend sycl::detail::ImplUtils; }; // class platform _LIBSYCL_END_NAMESPACE_SYCL diff --git a/libsycl/src/detail/global_objects.cpp b/libsycl/src/detail/global_objects.cpp index 9990b4d27824a..7998c2965bc2e 100644 --- a/libsycl/src/detail/global_objects.cpp +++ b/libsycl/src/detail/global_objects.cpp @@ -24,8 +24,8 @@ std::vector &getOffloadTopologies() { return Topologies; } -std::vector &getPlatformCache() { - static std::vector PlatformCache{}; +std::vector &getPlatformCache() { + static std::vector PlatformCache{}; return PlatformCache; } diff --git a/libsycl/src/detail/global_objects.hpp b/libsycl/src/detail/global_objects.hpp index 0b5ac246692bf..81899623aed68 100644 --- a/libsycl/src/detail/global_objects.hpp +++ b/libsycl/src/detail/global_objects.hpp @@ -24,7 +24,7 @@ class platform_impl; // Offload topologies (one per backend) discovered from liboffload. std::vector &getOffloadTopologies(); -std::vector &getPlatformCache(); +std::vector> &getPlatformCache(); } // namespace detail _LIBSYCL_END_NAMESPACE_SYCL diff --git a/libsycl/src/detail/offload/offload_utils.cpp b/libsycl/src/detail/offload/offload_utils.cpp index 2ccb27a9acf44..ccef4e582015b 100644 --- a/libsycl/src/detail/offload/offload_utils.cpp +++ b/libsycl/src/detail/offload/offload_utils.cpp @@ -11,7 +11,7 @@ _LIBSYCL_BEGIN_NAMESPACE_SYCL namespace detail { -const char *stringifyErrorCode(int32_t error) { +const char *stringifyErrorCode(ol_errc_t error) { switch (error) { #define _OFFLOAD_ERRC(NAME) \ case NAME: \ diff --git a/libsycl/src/detail/offload/offload_utils.hpp b/libsycl/src/detail/offload/offload_utils.hpp index 5f02feea98e3b..537fc6d80d505 100644 --- a/libsycl/src/detail/offload/offload_utils.hpp +++ b/libsycl/src/detail/offload/offload_utils.hpp @@ -19,18 +19,18 @@ _LIBSYCL_BEGIN_NAMESPACE_SYCL namespace detail { -const char *stringifyErrorCode(int32_t error); +const char *stringifyErrorCode(ol_errc_t error); -inline std::string formatCodeString(int32_t code) { - return std::to_string(code) + " (" + std::string(stringifyErrorCode(code)) + - ")"; +inline std::string formatCodeString(ol_result_t Result) { + return std::to_string(Result->Code) + " (" + + std::string(stringifyErrorCode(Result->Code)) + ")" + Result->Details; } template void checkAndThrow(ol_result_t Result) { if (Result != OL_SUCCESS) { throw sycl::exception(sycl::make_error_code(errc), - detail::formatCodeString(Result->Code)); + detail::formatCodeString(Result)); } } diff --git a/libsycl/src/detail/platform_impl.cpp b/libsycl/src/detail/platform_impl.cpp index 6bdb9188732d4..d44d54b3a871c 100644 --- a/libsycl/src/detail/platform_impl.cpp +++ b/libsycl/src/detail/platform_impl.cpp @@ -7,7 +7,7 @@ //===----------------------------------------------------------------------===// #include -#include +#include #include #include @@ -19,8 +19,8 @@ namespace detail { platform_impl &platform_impl::getPlatformImpl(ol_platform_handle_t Platform) { auto &PlatformCache = getPlatformCache(); for (auto &PlatImpl : PlatformCache) { - if (PlatImpl.getHandleRef() == Platform) - return PlatImpl; + if (PlatImpl->getHandleRef() == Platform) + return *PlatImpl; } throw sycl::exception( @@ -29,25 +29,24 @@ platform_impl &platform_impl::getPlatformImpl(ol_platform_handle_t Platform) { "the list of platforms discovered by liboffload"); } -range_view platform_impl::getPlatforms() { +const std::vector &platform_impl::getPlatforms() { [[maybe_unused]] static auto InitPlatformsOnce = []() { discoverOffloadDevices(); auto &PlatformCache = getPlatformCache(); for (const auto &Topo : getOffloadTopologies()) { size_t PlatformIndex = 0; for (const auto &OffloadPlatform : Topo.platforms()) { - PlatformCache.emplace_back( - platform_impl(OffloadPlatform, PlatformIndex++)); + PlatformCache.emplace_back(std::make_unique( + OffloadPlatform, PlatformIndex++, private_tag{})); } } return true; }(); - auto &PlatformCache = getPlatformCache(); - return {PlatformCache.data(), PlatformCache.size()}; + return getPlatformCache(); } platform_impl::platform_impl(ol_platform_handle_t Platform, - size_t PlatformIndex) + size_t PlatformIndex, private_tag) : MOffloadPlatform(Platform), MOffloadPlatformIndex(PlatformIndex) { ol_platform_backend_t Backend = OL_PLATFORM_BACKEND_UNKNOWN; call_and_throw(olGetPlatformInfo, MOffloadPlatform, OL_PLATFORM_INFO_BACKEND, diff --git a/libsycl/src/detail/platform_impl.hpp b/libsycl/src/detail/platform_impl.hpp index 8fbf76ce8e330..7d3090550f103 100644 --- a/libsycl/src/detail/platform_impl.hpp +++ b/libsycl/src/detail/platform_impl.hpp @@ -27,26 +27,31 @@ _LIBSYCL_BEGIN_NAMESPACE_SYCL namespace detail { +using PlatformImplUPtr = std::unique_ptr; + class platform_impl { + struct private_tag { + explicit private_tag() = default; + }; + public: /// Constructs platform_impl from a platform handle. /// /// \param Platform is a raw offload library handle representing platform. /// \param PlatformIndex is a platform index in a backend (needed for a proper /// indexing in device selector). - // - // Platforms can only be created under `GlobalHandler`'s ownership via - // `platform_impl::getOrMakePlatformImpl` method. - explicit platform_impl(ol_platform_handle_t Platform, size_t PlatformIndex); + /// All platform impls are created during first getPlatforms() call. + explicit platform_impl(ol_platform_handle_t Platform, size_t PlatformIndex, + private_tag); ~platform_impl() = default; /// Returns the backend associated with this platform. backend getBackend() const noexcept { return MBackend; } - /// Returns range-view to all SYCL platforms from all backends that are + /// Returns all SYCL platforms from all backends that are /// available in the system. - static range_view getPlatforms(); + static const std::vector &getPlatforms(); /// Returns raw underlying offload platform handle. /// diff --git a/libsycl/src/exception.cpp b/libsycl/src/exception.cpp index 38fd8816934b9..88ffb527f4bef 100644 --- a/libsycl/src/exception.cpp +++ b/libsycl/src/exception.cpp @@ -50,8 +50,6 @@ const std::error_category &exception::category() const noexcept { const char *exception::what() const noexcept { return MMessage->c_str(); } -bool exception::has_context() const noexcept { /*return (MContext != nullptr);*/ - return false; -} +bool exception::has_context() const noexcept { return false; } _LIBSYCL_END_NAMESPACE_SYCL diff --git a/libsycl/src/platform.cpp b/libsycl/src/platform.cpp index 6d35c8534f2a3..d47af135dae3d 100644 --- a/libsycl/src/platform.cpp +++ b/libsycl/src/platform.cpp @@ -14,17 +14,14 @@ _LIBSYCL_BEGIN_NAMESPACE_SYCL -backend platform::get_backend() const noexcept { - return getImpl().getBackend(); -} +backend platform::get_backend() const noexcept { return impl->getBackend(); } std::vector platform::get_platforms() { - auto PlatformsView = detail::platform_impl::getPlatforms(); + auto &PlatformImpls = detail::platform_impl::getPlatforms(); std::vector Platforms; - Platforms.reserve(PlatformsView.size()); - for (size_t i = 0; i < PlatformsView.size(); i++) { - platform Platform = - detail::createSyclObjFromImpl(&PlatformsView[i]); + Platforms.reserve(PlatformImpls.size()); + for (auto &PlatformImpl : PlatformImpls) { + platform Platform = detail::createSyclObjFromImpl(*PlatformImpl); Platforms.push_back(std::move(Platform)); } return Platforms; @@ -32,7 +29,7 @@ std::vector platform::get_platforms() { template detail::is_platform_info_desc_t platform::get_info() const { - return getImpl().get_info(); + return impl->get_info(); } #define _LIBSYCL_EXPORT_GET_INFO(Desc) \ diff --git a/libsycl/tools/sycl-ls/sycl-ls.cpp b/libsycl/tools/sycl-ls/sycl-ls.cpp index d611a98af8063..fe49fa1bd50c2 100644 --- a/libsycl/tools/sycl-ls/sycl-ls.cpp +++ b/libsycl/tools/sycl-ls/sycl-ls.cpp @@ -35,6 +35,7 @@ int main(int argc, char **argv) { if (Platforms.size() == 0) { std::cout << "No platforms found." << std::endl; + return EXIT_SUCCESS; } for (const auto &Platform : Platforms) { @@ -58,8 +59,6 @@ int main(int argc, char **argv) { std::cout << " Devices : " << "unknown" << std::endl; } - } else { - return EXIT_SUCCESS; } } catch (sycl::exception &e) { std::cerr << "SYCL Exception encountered: " << e.what() << std::endl From e8e28110ea51dcf358e7c9f582b43cfea0b5d5ae Mon Sep 17 00:00:00 2001 From: "Tikhomirova, Kseniya" Date: Fri, 5 Dec 2025 04:21:51 -0800 Subject: [PATCH 14/22] remove file common.hpp Signed-off-by: Tikhomirova, Kseniya --- libsycl/src/detail/common.hpp | 34 ------------------- .../src/detail/offload/offload_topology.hpp | 12 +++++-- libsycl/src/detail/platform_impl.hpp | 1 - 3 files changed, 10 insertions(+), 37 deletions(-) delete mode 100644 libsycl/src/detail/common.hpp diff --git a/libsycl/src/detail/common.hpp b/libsycl/src/detail/common.hpp deleted file mode 100644 index 43bee0560e2e8..0000000000000 --- a/libsycl/src/detail/common.hpp +++ /dev/null @@ -1,34 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef _LIBSYCL_COMMON -#define _LIBSYCL_COMMON - -#include - -#include - -_LIBSYCL_BEGIN_NAMESPACE_SYCL - -namespace detail { - -// Minimal span-like view -template struct range_view { - T *ptr{}; - size_t len{}; - T *begin() const { return ptr; } - T *end() const { return ptr + len; } - T &operator[](size_t i) const { return ptr[i]; } - size_t size() const { return len; } -}; - -} // namespace detail - -_LIBSYCL_END_NAMESPACE_SYCL - -#endif // _LIBSYCL_COMMON diff --git a/libsycl/src/detail/offload/offload_topology.hpp b/libsycl/src/detail/offload/offload_topology.hpp index 36a488e486fe3..b8b5e9c94bd87 100644 --- a/libsycl/src/detail/offload/offload_topology.hpp +++ b/libsycl/src/detail/offload/offload_topology.hpp @@ -11,8 +11,6 @@ #include -#include - #include #include @@ -23,6 +21,16 @@ _LIBSYCL_BEGIN_NAMESPACE_SYCL namespace detail { +// Minimal span-like view +template struct range_view { + T *ptr{}; + size_t len{}; + T *begin() const { return ptr; } + T *end() const { return ptr + len; } + T &operator[](size_t i) const { return ptr[i]; } + size_t size() const { return len; } +}; + using PlatformWithDevStorageType = std::unordered_map>; diff --git a/libsycl/src/detail/platform_impl.hpp b/libsycl/src/detail/platform_impl.hpp index 7d3090550f103..a877ac5751389 100644 --- a/libsycl/src/detail/platform_impl.hpp +++ b/libsycl/src/detail/platform_impl.hpp @@ -13,7 +13,6 @@ #include #include -#include #include #include From 9ce769553bcebd83c0a8327e5c5390d22d7844d0 Mon Sep 17 00:00:00 2001 From: "Tikhomirova, Kseniya" Date: Thu, 11 Dec 2025 06:14:40 -0800 Subject: [PATCH 15/22] fix code-review comments Signed-off-by: Tikhomirova, Kseniya --- libsycl/README.md | 2 +- libsycl/docs/index.rst | 16 ++++--- libsycl/include/sycl/__impl/backend.hpp | 44 +++++-------------- .../sycl/__impl/detail/macro_definitions.hpp | 23 +++++----- .../include/sycl/__impl/detail/obj_utils.hpp | 2 +- libsycl/include/sycl/__impl/exception.hpp | 4 +- libsycl/include/sycl/__impl/info/platform.hpp | 4 +- libsycl/include/sycl/__impl/platform.hpp | 2 +- libsycl/src/exception.cpp | 1 - libsycl/src/version.hpp.in | 2 +- libsycl/tools/sycl-ls/sycl-ls.cpp | 19 +++++++- 11 files changed, 57 insertions(+), 62 deletions(-) diff --git a/libsycl/README.md b/libsycl/README.md index 9fed3fdc4efa1..1452c158ca9d4 100644 --- a/libsycl/README.md +++ b/libsycl/README.md @@ -3,7 +3,7 @@ The libsycl subproject is an implementation of the SYCL runtime library as defined by the [SYCL 2020 specification](https://registry.khronos.org/SYCL/specs/sycl-2020/html/sycl-2020.html). -Subproject documentation is available at: [SYCL RT documentation](./docs). +Subproject documentation is available at: [Libsycl documentation](./docs). libsycl runtime library and headers require C++17 support or higher. diff --git a/libsycl/docs/index.rst b/libsycl/docs/index.rst index 83df7807c9df9..6b7b0d23a8119 100644 --- a/libsycl/docs/index.rst +++ b/libsycl/docs/index.rst @@ -10,8 +10,10 @@ SYCL runtime implementation Current Status ======== -The implementation is in the very early stages of upstreaming. The first milestone is to get -support for a simple SYCL application with device code using Unified Shared Memory: +The implementation is in the very early stages of upstreaming. The first +milestone is to get +support for a simple SYCL application with device code using Unified Shared +Memory: .. code-block:: c++ @@ -43,7 +45,8 @@ support for a simple SYCL application with device code using Unified Shared Memo return error; } -This requires at least partial support of the following functionality on the libsycl side: +This requires at least partial support of the following functionality on the +libsycl side: * ``sycl::platform`` class * ``sycl::device`` class * ``sycl::context`` class @@ -51,7 +54,8 @@ This requires at least partial support of the following functionality on the lib * ``sycl::handler`` class * ``sycl::id`` and ``sycl::range`` classes * Unified shared memory allocation/deallocation - * Program manager, an internal component for retrieving and using device images from the multi-architectural binaries + * Program manager, an internal component for retrieving and using device +images from the multi-architectural binaries Build steps ======== @@ -81,5 +85,5 @@ To build LLVM with libsycl runtime enabled the following script can be used. Limitations ======== -SYCL runtime is not tested and is not guaranteed to work on Windows because offloading runtime (liboffload) used by SYCL runtime doesn't currently support Windows. -The limitation to be revised once liboffload will add support for Windows. +Libsycl is not currently supported on Windows because it depends on liboffload +which doesn't currently support Windows. diff --git a/libsycl/include/sycl/__impl/backend.hpp b/libsycl/include/sycl/__impl/backend.hpp index 4b467f50cce5f..3f1bd13c4e55d 100644 --- a/libsycl/include/sycl/__impl/backend.hpp +++ b/libsycl/include/sycl/__impl/backend.hpp @@ -23,48 +23,28 @@ _LIBSYCL_BEGIN_NAMESPACE_SYCL -// 4.1. Backends -enum class backend : char { - opencl = 1, - level_zero = 2, - cuda = 3, - hip = 4, - all = 5, +// SYCL 2020 4.1. Backends +enum class backend : unsigned char { + opencl = 0, + level_zero, + cuda, + hip, + all, }; namespace detail { template struct is_backend_info_desc : std::false_type {}; } // namespace detail -// 4.5.1.1. Type traits backend_traits +// SYCL 2020 4.5.1.1. Type traits backend_traits template class backend_traits; -template +template using backend_input_t = - typename backend_traits::template input_type; -template + typename backend_traits::template input_type; +template using backend_return_t = - typename backend_traits::template return_type; - -namespace detail { -// Used by SYCL tools -inline std::string_view get_backend_name(const backend &Backend) { - switch (Backend) { - case backend::opencl: - return "opencl"; - case backend::level_zero: - return "level_zero"; - case backend::cuda: - return "cuda"; - case backend::hip: - return "hip"; - case backend::all: - return "all"; - } - - return ""; -} -} // namespace detail + typename backend_traits::template return_type; _LIBSYCL_END_NAMESPACE_SYCL diff --git a/libsycl/include/sycl/__impl/detail/macro_definitions.hpp b/libsycl/include/sycl/__impl/detail/macro_definitions.hpp index c9e148709d721..0938f4f88f67b 100644 --- a/libsycl/include/sycl/__impl/detail/macro_definitions.hpp +++ b/libsycl/include/sycl/__impl/detail/macro_definitions.hpp @@ -23,22 +23,19 @@ # endif #endif // __SYCL2020_DEPRECATED -static_assert(__cplusplus >= 201703L, - "SYCL RT does not support C++ version earlier than C++17."); +static_assert(__cplusplus >= 201703L, "Libsycl requires C++17 or later."); #if defined(_WIN32) && !defined(_DLL) && !defined(__SYCL_DEVICE_ONLY__) -// SYCL library is designed such a way that STL objects cross DLL boundary, -// which is guaranteed to work properly only when the application uses the same -// C++ runtime that SYCL library uses. -// The appplications using sycl.dll must be linked with dynamic/release C++ MSVC -// runtime, i.e. be compiled with /MD switch. Similarly, the applications using -// sycld.dll must be linked with dynamic/debug C++ runtime and be compiled with -// /MDd switch. -// Compiler automatically adds /MD or /MDd when -fsycl switch is used. -// The options /MD and /MDd that make the code to use dynamic runtime also -// define the _DLL macro. +// When built for use with the MSVC C++ standard library, libsycl requires +// use of the DLL versions of the MSVC run-time (RT) library. This requirement +// extends to applications that link with libsycl since the same MSVC run-time +// library must be used to ensure ABI compatibility for objects of C++ standard +// library types like std::vector that are passed to or returned from SYCL +// interfaces. Applications must therefore compile and link with the /MD option +// when linking to a release build of libsycl and with the /MDd option when +// linking to a debug build. # define ERROR_MESSAGE \ - "SYCL library is designed to work safely with dynamic C++ runtime." \ + "Libsycl is designed to work safely with dynamic C++ runtime." \ "Please use /MD switch with sycl.dll, /MDd switch with sycld.dll, " \ "or -fsycl switch to set C++ runtime automatically." # if defined(_MSC_VER) diff --git a/libsycl/include/sycl/__impl/detail/obj_utils.hpp b/libsycl/include/sycl/__impl/detail/obj_utils.hpp index abbf9039856d0..ccf14a58ee8be 100644 --- a/libsycl/include/sycl/__impl/detail/obj_utils.hpp +++ b/libsycl/include/sycl/__impl/detail/obj_utils.hpp @@ -61,7 +61,7 @@ SyclObject createSyclObjFromImpl(From &&from) { return ImplUtils::createSyclObjFromImpl(std::forward(from)); } -// std::hash support (4.5.2. Common reference semantics) +// SYCL 2020 4.5.2. Common reference semantics (std::hash support) template struct HashBase { size_t operator()(const T &Obj) const { #ifdef __SYCL_DEVICE_ONLY__ diff --git a/libsycl/include/sycl/__impl/exception.hpp b/libsycl/include/sycl/__impl/exception.hpp index d41a833e1bc10..95ca02be6d09d 100644 --- a/libsycl/include/sycl/__impl/exception.hpp +++ b/libsycl/include/sycl/__impl/exception.hpp @@ -26,8 +26,6 @@ _LIBSYCL_BEGIN_NAMESPACE_SYCL -class context; - enum class errc : int { success = 0, runtime = 1, @@ -55,7 +53,7 @@ _LIBSYCL_EXPORT const std::error_category &sycl_category() noexcept; // Derive from std::exception so uncaught exceptions are printed in c++ default // exception handler. // Virtual inheritance is mandated by SYCL 2020. -// 4.13.2. Exception class interface +// SYCL 2020 4.13.2. Exception class interface class _LIBSYCL_EXPORT exception : public virtual std::exception { public: exception(std::error_code, const char *); diff --git a/libsycl/include/sycl/__impl/info/platform.hpp b/libsycl/include/sycl/__impl/info/platform.hpp index 9e7dd061a8a6c..0f3477fe1d711 100644 --- a/libsycl/include/sycl/__impl/info/platform.hpp +++ b/libsycl/include/sycl/__impl/info/platform.hpp @@ -28,10 +28,10 @@ template using is_platform_info_desc_t = typename is_info_desc::return_type; } // namespace detail -// A.1. Platform information descriptors +// SYCL 2020 A.1. Platform information descriptors namespace info { namespace platform { -// 4.6.2.4. Information descriptors +// SYCL 2020 4.6.2.4. Information descriptors struct version : detail::info_desc_tag { using return_type = std::string; }; diff --git a/libsycl/include/sycl/__impl/platform.hpp b/libsycl/include/sycl/__impl/platform.hpp index 431b01fc7278d..f1d2f17cc54aa 100644 --- a/libsycl/include/sycl/__impl/platform.hpp +++ b/libsycl/include/sycl/__impl/platform.hpp @@ -29,7 +29,7 @@ namespace detail { class platform_impl; } // namespace detail -// 4.6.2. Platform class +// SYCL 2020 4.6.2. Platform class class _LIBSYCL_EXPORT platform { public: /// Constructs a platform object that is a copy of the platform which contains diff --git a/libsycl/src/exception.cpp b/libsycl/src/exception.cpp index 88ffb527f4bef..43fb6e41da78a 100644 --- a/libsycl/src/exception.cpp +++ b/libsycl/src/exception.cpp @@ -12,7 +12,6 @@ /// //===----------------------------------------------------------------------===// -// 4.9.2 Exception Class Interface #include #include diff --git a/libsycl/src/version.hpp.in b/libsycl/src/version.hpp.in index a7215761e9d4c..e4a4f957e3eca 100644 --- a/libsycl/src/version.hpp.in +++ b/libsycl/src/version.hpp.in @@ -7,7 +7,7 @@ //===----------------------------------------------------------------------===// /// /// \file -/// This file contains the declaration of SYCL RT version macro. +/// This file contains the declaration of libsycl version macro. /// //===----------------------------------------------------------------------===// #define _LIBSYCL_MAJOR_VERSION ${LIBSYCL_MAJOR_VERSION} diff --git a/libsycl/tools/sycl-ls/sycl-ls.cpp b/libsycl/tools/sycl-ls/sycl-ls.cpp index fe49fa1bd50c2..b2dec7da16449 100644 --- a/libsycl/tools/sycl-ls/sycl-ls.cpp +++ b/libsycl/tools/sycl-ls/sycl-ls.cpp @@ -21,6 +21,23 @@ using namespace sycl; using namespace std::literals; +inline std::string_view getBackendName(const backend &Backend) { + switch (Backend) { + case backend::opencl: + return "opencl"; + case backend::level_zero: + return "level_zero"; + case backend::cuda: + return "cuda"; + case backend::hip: + return "hip"; + case backend::all: + return "all"; + } + + return ""; +} + int main(int argc, char **argv) { llvm::cl::opt Verbose( "verbose", @@ -40,7 +57,7 @@ int main(int argc, char **argv) { for (const auto &Platform : Platforms) { backend Backend = Platform.get_backend(); - std::cout << "[" << detail::get_backend_name(Backend) << ":" + std::cout << "[" << getBackendName(Backend) << ":" << "unknown" << "]" << std::endl; } From 9653e23c2fbdf011fecddfcafe1227eda59eb376 Mon Sep 17 00:00:00 2001 From: "Tikhomirova, Kseniya" Date: Fri, 12 Dec 2025 06:29:51 -0800 Subject: [PATCH 16/22] fix more comments Signed-off-by: Tikhomirova, Kseniya --- libsycl/include/sycl/__impl/detail/macro_definitions.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libsycl/include/sycl/__impl/detail/macro_definitions.hpp b/libsycl/include/sycl/__impl/detail/macro_definitions.hpp index 0938f4f88f67b..38ab6b1e45479 100644 --- a/libsycl/include/sycl/__impl/detail/macro_definitions.hpp +++ b/libsycl/include/sycl/__impl/detail/macro_definitions.hpp @@ -35,9 +35,9 @@ static_assert(__cplusplus >= 201703L, "Libsycl requires C++17 or later."); // when linking to a release build of libsycl and with the /MDd option when // linking to a debug build. # define ERROR_MESSAGE \ - "Libsycl is designed to work safely with dynamic C++ runtime." \ - "Please use /MD switch with sycl.dll, /MDd switch with sycld.dll, " \ - "or -fsycl switch to set C++ runtime automatically." + "Libsycl requires use of a DLL version of the MSVC RT library. " \ + "Please use /MD to link with a release build of libsycl or /MDd to link" \ + " with a debug build." # if defined(_MSC_VER) # pragma message(ERROR_MESSAGE) # else From 885947b29406bda87c74683a6ab8b4299fc32f67 Mon Sep 17 00:00:00 2001 From: "Tikhomirova, Kseniya" Date: Mon, 15 Dec 2025 02:00:39 -0800 Subject: [PATCH 17/22] fix doc Signed-off-by: Tikhomirova, Kseniya --- libsycl/docs/index.rst | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/libsycl/docs/index.rst b/libsycl/docs/index.rst index 6b7b0d23a8119..ea037837ab720 100644 --- a/libsycl/docs/index.rst +++ b/libsycl/docs/index.rst @@ -47,15 +47,16 @@ Memory: This requires at least partial support of the following functionality on the libsycl side: - * ``sycl::platform`` class - * ``sycl::device`` class - * ``sycl::context`` class - * ``sycl::queue`` class - * ``sycl::handler`` class - * ``sycl::id`` and ``sycl::range`` classes - * Unified shared memory allocation/deallocation - * Program manager, an internal component for retrieving and using device -images from the multi-architectural binaries + +* ``sycl::platform`` class +* ``sycl::device`` class +* ``sycl::context`` class +* ``sycl::queue`` class +* ``sycl::handler`` class +* ``sycl::id`` and ``sycl::range`` classes +* Unified shared memory allocation/deallocation +* Program manager, an internal component for retrieving and using device images + from the multi-architectural binaries Build steps ======== From 656227bddb09dcbc3b3c3f1179213cc5d994b768 Mon Sep 17 00:00:00 2001 From: "Tikhomirova, Kseniya" Date: Mon, 15 Dec 2025 02:13:54 -0800 Subject: [PATCH 18/22] fix comments Signed-off-by: Tikhomirova, Kseniya --- .../sycl/__impl/detail/macro_definitions.hpp | 4 +- .../include/sycl/__impl/info/desc_base.hpp | 2 + libsycl/include/sycl/__impl/platform.hpp | 44 ------------------- libsycl/src/detail/offload/offload_utils.hpp | 18 ++++---- libsycl/tools/sycl-ls/CMakeLists.txt | 2 +- 5 files changed, 14 insertions(+), 56 deletions(-) diff --git a/libsycl/include/sycl/__impl/detail/macro_definitions.hpp b/libsycl/include/sycl/__impl/detail/macro_definitions.hpp index 38ab6b1e45479..079fd7fec1adf 100644 --- a/libsycl/include/sycl/__impl/detail/macro_definitions.hpp +++ b/libsycl/include/sycl/__impl/detail/macro_definitions.hpp @@ -14,6 +14,8 @@ #ifndef _LIBSYCL___IMPL_DETAIL_MACRO_DEFINITIONS_HPP #define _LIBSYCL___IMPL_DETAIL_MACRO_DEFINITIONS_HPP +static_assert(__cplusplus >= 201703L, "Libsycl requires C++17 or later."); + #ifndef __SYCL2020_DEPRECATED # if SYCL_LANGUAGE_VERSION == 202012L && \ !defined(SYCL2020_DISABLE_DEPRECATION_WARNINGS) @@ -23,8 +25,6 @@ # endif #endif // __SYCL2020_DEPRECATED -static_assert(__cplusplus >= 201703L, "Libsycl requires C++17 or later."); - #if defined(_WIN32) && !defined(_DLL) && !defined(__SYCL_DEVICE_ONLY__) // When built for use with the MSVC C++ standard library, libsycl requires // use of the DLL versions of the MSVC run-time (RT) library. This requirement diff --git a/libsycl/include/sycl/__impl/info/desc_base.hpp b/libsycl/include/sycl/__impl/info/desc_base.hpp index 930555db80e0b..340a10d69caa9 100644 --- a/libsycl/include/sycl/__impl/info/desc_base.hpp +++ b/libsycl/include/sycl/__impl/info/desc_base.hpp @@ -21,8 +21,10 @@ _LIBSYCL_BEGIN_NAMESPACE_SYCL namespace detail { template struct info_desc_tag {}; + template struct is_info_desc : std::false_type {}; + template struct is_info_desc< Desc, DescOf, diff --git a/libsycl/include/sycl/__impl/platform.hpp b/libsycl/include/sycl/__impl/platform.hpp index f1d2f17cc54aa..b19c529a89900 100644 --- a/libsycl/include/sycl/__impl/platform.hpp +++ b/libsycl/include/sycl/__impl/platform.hpp @@ -32,10 +32,6 @@ class platform_impl; // SYCL 2020 4.6.2. Platform class class _LIBSYCL_EXPORT platform { public: - /// Constructs a platform object that is a copy of the platform which contains - /// the device returned by default_selector_v. - // platform(); - platform(const platform &rhs) = default; platform(platform &&rhs) = default; @@ -48,57 +44,17 @@ class _LIBSYCL_EXPORT platform { bool operator!=(const platform &rhs) const { return !(*this == rhs); } - /// Constructs a platform object that is a copy of the platform which contains - /// the device that is selected by selector. - /// \param DeviceSelectorInstance is SYCL 2020 Device Selector, a simple - /// callable taking a device reference and returning an integer rank. - // template - // explicit platform(const DeviceSelector& DeviceSelectorInstance); - /// Returns the backend associated with this platform. /// /// \return the backend associated with this platform backend get_backend() const noexcept; - /// Returns all SYCL devices associated with this platform. - /// - /// If there are no devices that match given device - /// type, resulting vector is empty. - /// - /// \param DeviceType is a SYCL device type. - /// \return a vector of SYCL devices. - // std::vector - // get_devices(info::device_type DeviceType = info::device_type::all) - // const; - /// Queries this SYCL platform for info. /// /// The return type depends on information being queried. template detail::is_platform_info_desc_t get_info() const; - // template - // typename detail::is_backend_info_desc::return_type - // get_backend_info() const; - - /// Indicates if all of the SYCL devices on this platform have the - /// given feature. - /// - /// \param Aspect is one of the values in Table 4.20 of the SYCL 2020 - /// Provisional Spec. - /// - /// \return true if all of the SYCL devices on this platform have the - /// given feature. - // bool has(aspect Aspect) const; - - /// Checks if platform supports specified extension. - /// - /// \param ExtensionName is a string containing extension name. - /// \return true if specified extension is supported by this SYCL platform. - // __SYCL2020_DEPRECATED( - // "use platform::has() function with aspects APIs instead") - // bool has_extension(const std::string& ExtensionName) const; // Deprecated - /// Returns all SYCL platforms from all backends that are available in the /// system. /// diff --git a/libsycl/src/detail/offload/offload_utils.hpp b/libsycl/src/detail/offload/offload_utils.hpp index 537fc6d80d505..e74cd27d2e133 100644 --- a/libsycl/src/detail/offload/offload_utils.hpp +++ b/libsycl/src/detail/offload/offload_utils.hpp @@ -23,7 +23,7 @@ const char *stringifyErrorCode(ol_errc_t error); inline std::string formatCodeString(ol_result_t Result) { return std::to_string(Result->Code) + " (" + - std::string(stringifyErrorCode(Result->Code)) + ")" + Result->Details; + std::string(stringifyErrorCode(Result->Code)) + ") " + Result->Details; } template @@ -52,14 +52,14 @@ void call_and_throw(FunctionType &Function, ArgsT &&...Args) { backend convertBackend(ol_platform_backend_t Backend); -/// Helper to map SYCL information descriptors to OL__INFO_. To be -/// used like: -/// -/// using Map = info_ol_mapping; -/// constexpr auto olInfo = map_info_desc( -/// Map::M{OL_FOO_INFO_VAL0}, -/// Map::M{OL_FOO_INFO_VAL1}, -/// ...) +// Helper to map SYCL information descriptors to OL__INFO_. To be +// used like: +// +// using Map = info_ol_mapping; +// constexpr auto olInfo = map_info_desc( +// Map::M{OL_FOO_INFO_VAL0}, +// Map::M{OL_FOO_INFO_VAL1}, +// ...) template struct info_ol_mapping { template struct M { To value; diff --git a/libsycl/tools/sycl-ls/CMakeLists.txt b/libsycl/tools/sycl-ls/CMakeLists.txt index 302ed43248007..e0d9d349d9e98 100644 --- a/libsycl/tools/sycl-ls/CMakeLists.txt +++ b/libsycl/tools/sycl-ls/CMakeLists.txt @@ -13,7 +13,7 @@ target_link_libraries(sycl-ls include(CheckCXXCompilerFlag) check_cxx_compiler_flag(-fno-rtti COMPILER_HAS_NORTTI_FLAG) -if (COMPILER_HAS_NORTTI_FLAG) +if (NOT LLVM_ENABLE_RTTI AND COMPILER_HAS_NORTTI_FLAG) target_compile_options(sycl-ls PRIVATE -fno-rtti) endif() From 002eeb3a3c75d5b1e5fd08c8b0fdbae47b602314 Mon Sep 17 00:00:00 2001 From: "Tikhomirova, Kseniya" Date: Mon, 15 Dec 2025 02:37:02 -0800 Subject: [PATCH 19/22] remove device macro from hash impl Signed-off-by: Tikhomirova, Kseniya --- libsycl/include/sycl/__impl/detail/obj_utils.hpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/libsycl/include/sycl/__impl/detail/obj_utils.hpp b/libsycl/include/sycl/__impl/detail/obj_utils.hpp index ccf14a58ee8be..aff40956d3c20 100644 --- a/libsycl/include/sycl/__impl/detail/obj_utils.hpp +++ b/libsycl/include/sycl/__impl/detail/obj_utils.hpp @@ -64,13 +64,8 @@ SyclObject createSyclObjFromImpl(From &&from) { // SYCL 2020 4.5.2. Common reference semantics (std::hash support) template struct HashBase { size_t operator()(const T &Obj) const { -#ifdef __SYCL_DEVICE_ONLY__ - (void)Obj; - return 0; -#else auto &Impl = sycl::detail::getSyclObjImpl(Obj); return std::hash>{}(Impl); -#endif } }; From fb91c2beb34efd396d77b96be3e05dc2826f8f94 Mon Sep 17 00:00:00 2001 From: "Tikhomirova, Kseniya" Date: Mon, 15 Dec 2025 08:52:48 -0800 Subject: [PATCH 20/22] remove from backend enum Signed-off-by: Tikhomirova, Kseniya --- libsycl/include/sycl/__impl/backend.hpp | 1 - libsycl/tools/sycl-ls/sycl-ls.cpp | 2 -- 2 files changed, 3 deletions(-) diff --git a/libsycl/include/sycl/__impl/backend.hpp b/libsycl/include/sycl/__impl/backend.hpp index 3f1bd13c4e55d..bc29573126de5 100644 --- a/libsycl/include/sycl/__impl/backend.hpp +++ b/libsycl/include/sycl/__impl/backend.hpp @@ -29,7 +29,6 @@ enum class backend : unsigned char { level_zero, cuda, hip, - all, }; namespace detail { diff --git a/libsycl/tools/sycl-ls/sycl-ls.cpp b/libsycl/tools/sycl-ls/sycl-ls.cpp index b2dec7da16449..366a3d767121d 100644 --- a/libsycl/tools/sycl-ls/sycl-ls.cpp +++ b/libsycl/tools/sycl-ls/sycl-ls.cpp @@ -31,8 +31,6 @@ inline std::string_view getBackendName(const backend &Backend) { return "cuda"; case backend::hip: return "hip"; - case backend::all: - return "all"; } return ""; From c90c2a76d9170bdae6ed6dd31011e8263bbde6a8 Mon Sep 17 00:00:00 2001 From: "Tikhomirova, Kseniya" Date: Tue, 16 Dec 2025 04:01:26 -0800 Subject: [PATCH 21/22] fix comments Signed-off-by: Tikhomirova, Kseniya --- libsycl/include/sycl/__impl/backend.hpp | 4 +- .../include/sycl/__impl/detail/obj_utils.hpp | 2 +- libsycl/include/sycl/__impl/exception.hpp | 56 +++++++++++++++--- .../include/sycl/__impl/info/desc_base.hpp | 2 +- libsycl/include/sycl/__impl/info/platform.hpp | 4 +- libsycl/include/sycl/__impl/platform.hpp | 5 +- libsycl/src/detail/global_objects.hpp | 12 +++- .../src/detail/offload/offload_topology.cpp | 4 +- .../src/detail/offload/offload_topology.hpp | 29 +++++++-- libsycl/src/detail/offload/offload_utils.cpp | 4 +- libsycl/src/detail/offload/offload_utils.hpp | 59 +++++++++++++++---- libsycl/src/detail/platform_impl.hpp | 37 ++++-------- libsycl/src/exception.cpp | 6 -- libsycl/src/exception_list.cpp | 8 +-- 14 files changed, 154 insertions(+), 78 deletions(-) diff --git a/libsycl/include/sycl/__impl/backend.hpp b/libsycl/include/sycl/__impl/backend.hpp index bc29573126de5..8dc5711d16b3d 100644 --- a/libsycl/include/sycl/__impl/backend.hpp +++ b/libsycl/include/sycl/__impl/backend.hpp @@ -23,7 +23,7 @@ _LIBSYCL_BEGIN_NAMESPACE_SYCL -// SYCL 2020 4.1. Backends +// SYCL 2020 4.1. Backends. enum class backend : unsigned char { opencl = 0, level_zero, @@ -35,7 +35,7 @@ namespace detail { template struct is_backend_info_desc : std::false_type {}; } // namespace detail -// SYCL 2020 4.5.1.1. Type traits backend_traits +// SYCL 2020 4.5.1.1. Type traits backend_traits. template class backend_traits; template diff --git a/libsycl/include/sycl/__impl/detail/obj_utils.hpp b/libsycl/include/sycl/__impl/detail/obj_utils.hpp index aff40956d3c20..b4c1250e298c4 100644 --- a/libsycl/include/sycl/__impl/detail/obj_utils.hpp +++ b/libsycl/include/sycl/__impl/detail/obj_utils.hpp @@ -61,7 +61,7 @@ SyclObject createSyclObjFromImpl(From &&from) { return ImplUtils::createSyclObjFromImpl(std::forward(from)); } -// SYCL 2020 4.5.2. Common reference semantics (std::hash support) +// SYCL 2020 4.5.2. Common reference semantics (std::hash support). template struct HashBase { size_t operator()(const T &Obj) const { auto &Impl = sycl::detail::getSyclObjImpl(Obj); diff --git a/libsycl/include/sycl/__impl/exception.hpp b/libsycl/include/sycl/__impl/exception.hpp index 95ca02be6d09d..c2c1e7706a88a 100644 --- a/libsycl/include/sycl/__impl/exception.hpp +++ b/libsycl/include/sycl/__impl/exception.hpp @@ -44,16 +44,29 @@ enum class errc : int { backend_mismatch = 14, }; -/// Constructs an error code using E and sycl_category() +/// Constructs an error code using sycl::errc and sycl_category(). +/// +/// \param E SYCL 2020 error code. +/// +/// \returns constructed error code. _LIBSYCL_EXPORT std::error_code make_error_code(sycl::errc E) noexcept; /// Obtains a reference to the static error category object for SYCL errors. +/// +/// This object overrides the virtual function error_category::name() to return +/// a pointer to the string "sycl". When the implementation throws an +/// sycl::exception object Ex with this category, the error code value contained +/// by the exception (Ex.code().value()) is one of the enumerated values in +/// sycl::errc. +/// +/// \returns the error category object for SYCL errors. _LIBSYCL_EXPORT const std::error_category &sycl_category() noexcept; -// Derive from std::exception so uncaught exceptions are printed in c++ default -// exception handler. -// Virtual inheritance is mandated by SYCL 2020. -// SYCL 2020 4.13.2. Exception class interface +/// \brief SYCL 2020 exception class (4.13.2.) for sync and async error handling +/// in a SYCL application (host code). +/// +/// Derived from std::exception so uncaught exceptions are printed in c++ +/// default exception handler. Virtual inheritance is mandated by SYCL 2020. class _LIBSYCL_EXPORT exception : public virtual std::exception { public: exception(std::error_code, const char *); @@ -70,11 +83,26 @@ class _LIBSYCL_EXPORT exception : public virtual std::exception { virtual ~exception(); + /// Returns the error code stored inside the exception. + /// + /// \returns the error code stored inside the exception. const std::error_code &code() const noexcept; + + /// Returns the error category of the error code stored inside the exception. + /// + /// \returns the error category of the error code stored inside the exception. const std::error_category &category() const noexcept; + /// Returns string that describes the error that triggered the exception. + /// + /// \returns an implementation-defined non-null constant C-style string that + /// describes the error that triggered the exception. const char *what() const noexcept final; + /// Checks if the exception has an associated SYCL context. + /// + /// \returns true if this SYCL exception has an associated SYCL context and + /// false if it does not. bool has_context() const noexcept; private: @@ -84,8 +112,7 @@ class _LIBSYCL_EXPORT exception : public virtual std::exception { std::error_code MErrC = make_error_code(sycl::errc::invalid); }; -/// Used as a container for a list of asynchronous exceptions -/// +/// \brief Used as a container for a list of asynchronous exceptions. class _LIBSYCL_EXPORT exception_list { public: using value_type = std::exception_ptr; @@ -95,10 +122,21 @@ class _LIBSYCL_EXPORT exception_list { using iterator = std::vector::const_iterator; using const_iterator = std::vector::const_iterator; + /// Returns the size of the list. + /// + /// \returns the size of the list. size_type size() const; - // first asynchronous exception + + /// Returns an iterator to the beginning of the list of asynchronous + /// exceptions. + /// + /// \returns an iterator to the beginning of the list of asynchronous + /// exceptions. iterator begin() const; - // refer to past-the-end last asynchronous exception + + /// Returns an iterator to the end of the list of asynchronous exceptions. + /// + /// \returns an iterator to the end of the list of asynchronous exceptions. iterator end() const; private: diff --git a/libsycl/include/sycl/__impl/info/desc_base.hpp b/libsycl/include/sycl/__impl/info/desc_base.hpp index 340a10d69caa9..0fc4284d60b68 100644 --- a/libsycl/include/sycl/__impl/info/desc_base.hpp +++ b/libsycl/include/sycl/__impl/info/desc_base.hpp @@ -7,7 +7,7 @@ //===----------------------------------------------------------------------===// /// /// \file -/// This file contains helpers for info descriptors +/// This file contains helpers for info descriptors. /// //===----------------------------------------------------------------------===// diff --git a/libsycl/include/sycl/__impl/info/platform.hpp b/libsycl/include/sycl/__impl/info/platform.hpp index 0f3477fe1d711..8a4b071fae6b6 100644 --- a/libsycl/include/sycl/__impl/info/platform.hpp +++ b/libsycl/include/sycl/__impl/info/platform.hpp @@ -28,10 +28,10 @@ template using is_platform_info_desc_t = typename is_info_desc::return_type; } // namespace detail -// SYCL 2020 A.1. Platform information descriptors +// SYCL 2020 A.1. Platform information descriptors. namespace info { namespace platform { -// SYCL 2020 4.6.2.4. Information descriptors +// SYCL 2020 4.6.2.4. Information descriptors. struct version : detail::info_desc_tag { using return_type = std::string; }; diff --git a/libsycl/include/sycl/__impl/platform.hpp b/libsycl/include/sycl/__impl/platform.hpp index b19c529a89900..ac1a07a983a4a 100644 --- a/libsycl/include/sycl/__impl/platform.hpp +++ b/libsycl/include/sycl/__impl/platform.hpp @@ -29,7 +29,8 @@ namespace detail { class platform_impl; } // namespace detail -// SYCL 2020 4.6.2. Platform class +/// \brief SYCL 2020 platform class (4.6.2.) encapsulating a single SYCL +/// platform on which kernel functions may be executed. class _LIBSYCL_EXPORT platform { public: platform(const platform &rhs) = default; @@ -46,7 +47,7 @@ class _LIBSYCL_EXPORT platform { /// Returns the backend associated with this platform. /// - /// \return the backend associated with this platform + /// \return the backend associated with this platform. backend get_backend() const noexcept; /// Queries this SYCL platform for info. diff --git a/libsycl/src/detail/global_objects.hpp b/libsycl/src/detail/global_objects.hpp index 81899623aed68..d826fcedefd45 100644 --- a/libsycl/src/detail/global_objects.hpp +++ b/libsycl/src/detail/global_objects.hpp @@ -21,9 +21,19 @@ _LIBSYCL_BEGIN_NAMESPACE_SYCL namespace detail { class platform_impl; -// Offload topologies (one per backend) discovered from liboffload. +/// Returns offload topologies (one per backend) discovered from liboffload. +/// +/// This vector is populated only once at the first call of get_platforms(). +/// +/// \returns std::vector of all offload topologies. std::vector &getOffloadTopologies(); +/// Returns implementation class objects for all platforms discovered from +/// liboffload. +/// +/// This vector is populated only once at the first call of get_platforms(). +/// +/// \returns std::vector of implementation objects for all platforms. std::vector> &getPlatformCache(); } // namespace detail diff --git a/libsycl/src/detail/offload/offload_topology.cpp b/libsycl/src/detail/offload/offload_topology.cpp index c1509a39263e0..8749530389f04 100644 --- a/libsycl/src/detail/offload/offload_topology.cpp +++ b/libsycl/src/detail/offload/offload_topology.cpp @@ -34,14 +34,14 @@ void discoverOffloadDevices() { ol_platform_handle_t Plat = nullptr; ol_result_t Res = call_nocheck( olGetDeviceInfo, Dev, OL_DEVICE_INFO_PLATFORM, sizeof(Plat), &Plat); - // If error occures, ignore platform and continue iteration + // If error occurs, ignore platform and continue iteration if (Res != OL_SUCCESS) return true; ol_platform_backend_t OlBackend = OL_PLATFORM_BACKEND_UNKNOWN; Res = call_nocheck(olGetPlatformInfo, Plat, OL_PLATFORM_INFO_BACKEND, sizeof(OlBackend), &OlBackend); - // If error occures, ignore platform and continue iteration + // If error occurs, ignore platform and continue iteration if (Res != OL_SUCCESS) return true; diff --git a/libsycl/src/detail/offload/offload_topology.hpp b/libsycl/src/detail/offload/offload_topology.hpp index b8b5e9c94bd87..a1a320dd5f622 100644 --- a/libsycl/src/detail/offload/offload_topology.hpp +++ b/libsycl/src/detail/offload/offload_topology.hpp @@ -21,7 +21,7 @@ _LIBSYCL_BEGIN_NAMESPACE_SYCL namespace detail { -// Minimal span-like view +// Minimal span-like view. template struct range_view { T *ptr{}; size_t len{}; @@ -34,20 +34,31 @@ template struct range_view { using PlatformWithDevStorageType = std::unordered_map>; -// Contiguous global storage of platform handlers and device handles (grouped by -// platform) for a backend. +/// Contiguous global storage of platform handlers and device handles (grouped +/// by platform) for a backend. struct OffloadTopology { OffloadTopology() : MBackend(OL_PLATFORM_BACKEND_UNKNOWN) {} OffloadTopology(ol_platform_backend_t OlBackend) : MBackend(OlBackend) {} + /// Updates backend for this topology. + /// + /// \param B new backend value. void set_backend(ol_platform_backend_t B) { MBackend = B; } - // Platforms for this backend + /// Returns all platforms associated with this topology. + /// + /// \returns minimal span-like view to platforms associated with this + /// topology. range_view platforms() const { return {MPlatforms.data(), MPlatforms.size()}; } - // Devices for a specific platform (platform_id is index into Platforms) + /// Returns all devices associated with specific platform. + /// + /// \param PlatformId platform_id is index into Platforms. + /// + /// \returns minimal span-like view to devices associated with specified + /// platform. range_view devicesForPlatform(size_t PlatformId) const { if (PlatformId >= MDevRangePerPlatformId.size()) @@ -55,7 +66,10 @@ struct OffloadTopology { return MDevRangePerPlatformId[PlatformId]; } - // Register new platform and devices into this topology under that platform. + /// Register new platform and devices into this topology. + /// + /// \param PlatformsAndDev associative container with platforms & devices. + /// \param TotalDevCount total device count for the platform. void registerNewPlatformsAndDevices(PlatformWithDevStorageType &PlatformsAndDev, size_t TotalDevCount) { @@ -77,6 +91,9 @@ struct OffloadTopology { assert(TotalDevCount == MDevices.size()); } + /// Queries backend of this topology. + /// + /// \returns backend of this topology. ol_platform_backend_t backend() const { return MBackend; } private: diff --git a/libsycl/src/detail/offload/offload_utils.cpp b/libsycl/src/detail/offload/offload_utils.cpp index ccef4e582015b..a2aa45e7102c1 100644 --- a/libsycl/src/detail/offload/offload_utils.cpp +++ b/libsycl/src/detail/offload/offload_utils.cpp @@ -11,8 +11,8 @@ _LIBSYCL_BEGIN_NAMESPACE_SYCL namespace detail { -const char *stringifyErrorCode(ol_errc_t error) { - switch (error) { +const char *stringifyErrorCode(ol_errc_t Error) { + switch (Error) { #define _OFFLOAD_ERRC(NAME) \ case NAME: \ return #NAME; diff --git a/libsycl/src/detail/offload/offload_utils.hpp b/libsycl/src/detail/offload/offload_utils.hpp index e74cd27d2e133..73fcf485b9c59 100644 --- a/libsycl/src/detail/offload/offload_utils.hpp +++ b/libsycl/src/detail/offload/offload_utils.hpp @@ -19,13 +19,32 @@ _LIBSYCL_BEGIN_NAMESPACE_SYCL namespace detail { -const char *stringifyErrorCode(ol_errc_t error); +/// Converts liboffload error code to C-string. +/// +/// \param Error liboffload error code. +/// +/// \returns C-string representing the name of Error as specified in enum. +const char *stringifyErrorCode(ol_errc_t Error); +/// Contructs C++-string with information about liboffload error. +/// +/// \param Error liboffload result of calling API. +/// +/// \returns C++-string containing all available data of failure. inline std::string formatCodeString(ol_result_t Result) { return std::to_string(Result->Code) + " (" + std::string(stringifyErrorCode(Result->Code)) + ") " + Result->Details; } +/// Checks liboffload API call result. +/// +/// Used after calling the API without check. +/// To be called when specific handling is needed and explicitly done by +/// developer before throwing exception. +/// +/// \param Error liboffload result of calling API. +/// +/// \throw sycl::runtime_exception if the call was not successful. template void checkAndThrow(ol_result_t Result) { if (Result != OL_SUCCESS) { @@ -34,14 +53,23 @@ void checkAndThrow(ol_result_t Result) { } } -/// Calls the API, doesn't check result. To be called when specific handling is -/// needed and explicitly done by developer after. +/// Calls the API, doesn't check result. +/// To be called when specific handling is needed and explicitly done by +/// developer after. +/// +/// \param Function liboffload API function to be called. +/// \param Args arguments to be passed to the liboffload API function. +/// +/// \returns liboffload error code returned by API call. template ol_result_t call_nocheck(FunctionType &Function, ArgsT &&...Args) { return Function(std::forward(Args)...); } -/// Calls the API & checks the result +/// Calls the API and checks result. +/// +/// \param Function liboffload API function to be called. +/// \param Args arguments to be passed to the liboffload API function. /// /// \throw sycl::runtime_exception if the call was not successful. template @@ -50,16 +78,23 @@ void call_and_throw(FunctionType &Function, ArgsT &&...Args) { checkAndThrow(Err); } +/// Converts liboffload backend to SYCL backend. +/// +/// \param Backend liboffload backend. +/// +/// \returns sycl::backend matching specified liboffload backend. backend convertBackend(ol_platform_backend_t Backend); -// Helper to map SYCL information descriptors to OL__INFO_. To be -// used like: -// -// using Map = info_ol_mapping; -// constexpr auto olInfo = map_info_desc( -// Map::M{OL_FOO_INFO_VAL0}, -// Map::M{OL_FOO_INFO_VAL1}, -// ...) +/// Helper to map SYCL information descriptors to OL__INFO_. +/// +/// Typical usage: +/// \code +/// using Map = info_ol_mapping; +/// constexpr auto olInfo = map_info_desc( +/// Map::M{OL_FOO_INFO_VAL0}, +/// Map::M{OL_FOO_INFO_VAL1}, +/// ...) +/// \endcode template struct info_ol_mapping { template struct M { To value; diff --git a/libsycl/src/detail/platform_impl.hpp b/libsycl/src/detail/platform_impl.hpp index a877ac5751389..b3aa5730cc1e3 100644 --- a/libsycl/src/detail/platform_impl.hpp +++ b/libsycl/src/detail/platform_impl.hpp @@ -46,10 +46,14 @@ class platform_impl { ~platform_impl() = default; /// Returns the backend associated with this platform. + /// + /// \returns sycl::backend associated with this platform. backend getBackend() const noexcept { return MBackend; } /// Returns all SYCL platforms from all backends that are /// available in the system. + /// + /// \returns std::vector of all platforms that are available in the system. static const std::vector &getPlatforms(); /// Returns raw underlying offload platform handle. @@ -57,40 +61,23 @@ class platform_impl { /// It does not retain handle. It is caller responsibility to make sure that /// platform stays alive while raw handle is in use. /// - /// \return a raw plug-in platform handle. + /// \return a raw offload platform handle. const ol_platform_handle_t &getHandleRef() const { return MOffloadPlatform; } - /// Returns platform index in a backend (needed for a proper indexing in - /// device selector). - size_t getPlatformIndex() const { return MOffloadPlatformIndex; } - - /// Queries the cache to see if the specified offloading RT platform has been - /// seen before. If so, return the cached platform_impl, otherwise create a - /// new one and cache it. + /// Queries the cache to get the implementation for specified offloading RT + /// platform. All platform implementation objects are created at first + /// get_platforms call. /// /// \param Platform is the offloading RT Platform handle representing the - /// platform - /// \param PlatformIndex is a platform index in a backend (needed for a proper - /// indexing in device selector). - /// \return the platform_impl representing the offloading RT platform + /// platform. + /// \return the platform_impl representing the offloading RT platform. static platform_impl &getPlatformImpl(ol_platform_handle_t Platform); - template - static constexpr ol_platform_info_t getOffloadInfo() { - if constexpr (std::is_same_v) - return OL_PLATFORM_INFO_VERSION; - else if constexpr (std::is_same_v) - return OL_PLATFORM_INFO_NAME; - else if constexpr (std::is_same_v) - return OL_PLATFORM_INFO_VENDOR_NAME; - else - static_assert(false && "Convertion list for platform info is not full."); - } - /// Queries this SYCL platform for info. + /// Queries this platform for info. /// /// The return type depends on information being queried. template typename Param::return_type get_info() const { - // for now we have only std::string properties + // For now we have only std::string properties static_assert(std::is_same_v); using namespace info::platform; diff --git a/libsycl/src/exception.cpp b/libsycl/src/exception.cpp index 43fb6e41da78a..0b69c2a217fdc 100644 --- a/libsycl/src/exception.cpp +++ b/libsycl/src/exception.cpp @@ -5,12 +5,6 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// -/// -/// \file -/// This file contains the definition of the SYCL 2020 exception class interface -/// (4.13.2.) -/// -//===----------------------------------------------------------------------===// #include #include diff --git a/libsycl/src/exception_list.cpp b/libsycl/src/exception_list.cpp index 3eaf213deaaec..1c0a78bd33681 100644 --- a/libsycl/src/exception_list.cpp +++ b/libsycl/src/exception_list.cpp @@ -5,14 +5,8 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// -/// -/// \file -/// This file contains the definition of the SYCL 2020 exception_list class -/// interface (4.13.2.) -/// -//===----------------------------------------------------------------------===// -// 4.13.2. Exception class interface +// SYCL 2020 4.13.2. Exception class interface. #include #include From 9b4b7794189e148b6887286e2f196cd482f4ea69 Mon Sep 17 00:00:00 2001 From: "Tikhomirova, Kseniya" Date: Thu, 18 Dec 2025 05:59:34 -0800 Subject: [PATCH 22/22] fix comments Signed-off-by: Tikhomirova, Kseniya --- .../sycl/__impl/detail/macro_definitions.hpp | 4 ++++ libsycl/include/sycl/__impl/platform.hpp | 10 +++++++-- libsycl/src/CMakeLists.txt | 22 ++++++++++--------- libsycl/src/detail/global_objects.cpp | 2 +- .../src/detail/offload/offload_topology.hpp | 10 +++++---- 5 files changed, 31 insertions(+), 17 deletions(-) diff --git a/libsycl/include/sycl/__impl/detail/macro_definitions.hpp b/libsycl/include/sycl/__impl/detail/macro_definitions.hpp index 079fd7fec1adf..f436cea522fe1 100644 --- a/libsycl/include/sycl/__impl/detail/macro_definitions.hpp +++ b/libsycl/include/sycl/__impl/detail/macro_definitions.hpp @@ -14,7 +14,11 @@ #ifndef _LIBSYCL___IMPL_DETAIL_MACRO_DEFINITIONS_HPP #define _LIBSYCL___IMPL_DETAIL_MACRO_DEFINITIONS_HPP +#if defined(_MSC_VER) +static_assert(_MSVC_LANG >= 201703L, "Libsycl requires C++17 or later."); +#else static_assert(__cplusplus >= 201703L, "Libsycl requires C++17 or later."); +#endif #ifndef __SYCL2020_DEPRECATED # if SYCL_LANGUAGE_VERSION == 202012L && \ diff --git a/libsycl/include/sycl/__impl/platform.hpp b/libsycl/include/sycl/__impl/platform.hpp index ac1a07a983a4a..9811ef2a341d1 100644 --- a/libsycl/include/sycl/__impl/platform.hpp +++ b/libsycl/include/sycl/__impl/platform.hpp @@ -33,6 +33,8 @@ class platform_impl; /// platform on which kernel functions may be executed. class _LIBSYCL_EXPORT platform { public: + // The platform class provides the common reference semantics (SYCL + // 2020 4.5.2). platform(const platform &rhs) = default; platform(platform &&rhs) = default; @@ -41,9 +43,13 @@ class _LIBSYCL_EXPORT platform { platform &operator=(platform &&rhs) = default; - bool operator==(const platform &rhs) const { return &impl == &rhs.impl; } + friend bool operator==(const platform &lhs, const platform &rhs) { + return lhs.impl == rhs.impl; + } - bool operator!=(const platform &rhs) const { return !(*this == rhs); } + friend bool operator!=(const platform &lhs, const platform &rhs) { + return !(lhs == rhs); + } /// Returns the backend associated with this platform. /// diff --git a/libsycl/src/CMakeLists.txt b/libsycl/src/CMakeLists.txt index 5c8010801f231..5f4be546de38f 100644 --- a/libsycl/src/CMakeLists.txt +++ b/libsycl/src/CMakeLists.txt @@ -11,14 +11,6 @@ function(add_sycl_rt_library LIB_TARGET_NAME LIB_OBJ_NAME LIB_OUTPUT_NAME) $<$:_LIBSYCL_BUILDING_LIBRARY>) cxx_add_warning_flags(${LIB_OBJ_NAME} ${LIBSYCL_ENABLE_WERROR} ${LIBSYCL_ENABLE_PEDANTIC}) - target_include_directories( - ${LIB_OBJ_NAME} - PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR} - ${LIBSYCL_BUILD_INCLUDE_DIR} - ${CMAKE_CURRENT_BINARY_DIR}/../../offload/liboffload/API - ) - add_library(${LIB_TARGET_NAME} SHARED $) @@ -27,7 +19,17 @@ function(add_sycl_rt_library LIB_TARGET_NAME LIB_OBJ_NAME LIB_OUTPUT_NAME) LLVMOffload ) - set_target_properties(${LIB_TARGET_NAME} PROPERTIES LINKER_LANGUAGE CXX) + target_include_directories( + ${LIB_OBJ_NAME} + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${LIBSYCL_BUILD_INCLUDE_DIR} + $ + ) + + set_target_properties(${LIB_TARGET_NAME} PROPERTIES + LINKER_LANGUAGE CXX + POSITION_INDEPENDENT_CODE TRUE) if (CMAKE_SYSTEM_NAME STREQUAL Windows) # Install stripped PDB @@ -47,7 +49,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 -fPIC) + -fvisibility=hidden -fvisibility-inlines-hidden) if (UNIX AND NOT APPLE) set(linker_script "${CMAKE_CURRENT_SOURCE_DIR}/ld-version-script.txt") diff --git a/libsycl/src/detail/global_objects.cpp b/libsycl/src/detail/global_objects.cpp index 7998c2965bc2e..bf7a33ccf7a54 100644 --- a/libsycl/src/detail/global_objects.cpp +++ b/libsycl/src/detail/global_objects.cpp @@ -60,7 +60,7 @@ extern "C" _LIBSYCL_EXPORT BOOL WINAPI DllMain(HINSTANCE hinstDLL, #else // Setting low priority on destructor ensures it runs after all other global // destructors. Priorities 0-100 are reserved by the compiler. The priority -// value 110 allows SYCL users to run their destructors after runtime library +// value 110 allows SYCL users to run their destructors after libsycl // deinitialization. __attribute__((destructor(110))) static void syclUnload() { shutdown(); } #endif diff --git a/libsycl/src/detail/offload/offload_topology.hpp b/libsycl/src/detail/offload/offload_topology.hpp index a1a320dd5f622..86717b8a06c6c 100644 --- a/libsycl/src/detail/offload/offload_topology.hpp +++ b/libsycl/src/detail/offload/offload_topology.hpp @@ -55,14 +55,15 @@ struct OffloadTopology { /// Returns all devices associated with specific platform. /// - /// \param PlatformId platform_id is index into Platforms. + /// \param PlatformId platform_id is index into MPlatforms. /// /// \returns minimal span-like view to devices associated with specified /// platform. range_view devicesForPlatform(size_t PlatformId) const { - if (PlatformId >= MDevRangePerPlatformId.size()) + if (PlatformId >= MDevRangePerPlatformId.size()) { return {nullptr, 0}; + } return MDevRangePerPlatformId[PlatformId]; } @@ -104,9 +105,10 @@ struct OffloadTopology { std::vector MDevices; // sorted by platform // Vector holding range of devices for each platform (index is platform index - // within Platforms) + // within MPlatforms) std::vector> - MDevRangePerPlatformId; // PlatformDevices.size() == Platforms.size() + MDevRangePerPlatformId; // MDevRangePerPlatformId.size() == + // MPlatforms.size() }; // Initialize the topologies by calling olIterateDevices.