From b22192afdcbda7441e7a8fe7cbc9a06903e9e6ea Mon Sep 17 00:00:00 2001 From: Kseniya Tikhomirova Date: Fri, 7 Nov 2025 12:36:59 +0100 Subject: [PATCH 01/10] [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/10] 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/10] 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/10] 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/10] 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/10] 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/10] 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/10] 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/10] 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/10] 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; }