[SYCL] Add platform enumeration and info query using liboffload (#166927)
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 --------- Signed-off-by: Tikhomirova, Kseniya <kseniya.tikhomirova@intel.com>
This commit is contained in:
parent
3d009a7b0d
commit
4f7c733293
@ -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,23 @@ 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_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()
|
||||
|
||||
set(LIBSYCL_RT_LIBS ${LIBSYCL_SHARED_OUTPUT_NAME})
|
||||
|
||||
add_subdirectory(src)
|
||||
|
||||
add_custom_target(libsycl-runtime-libraries
|
||||
DEPENDS ${LIBSYCL_RT_LIBS}
|
||||
)
|
||||
|
||||
add_subdirectory(src)
|
||||
|
||||
add_subdirectory(tools)
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
The libsycl subproject is an implementation of the SYCL runtime library as defined by the
|
||||
[SYCL 2020 specification](https://registry.khronos.org/SYCL/specs/sycl-2020/html/sycl-2020.html).
|
||||
|
||||
Subproject documentation is available at: [SYCL RT documentation](./docs).
|
||||
Subproject documentation is available at: [Libsycl documentation](./docs).
|
||||
|
||||
libsycl runtime library and headers require C++17 support or higher.
|
||||
|
||||
|
||||
@ -10,8 +10,10 @@ SYCL runtime implementation
|
||||
Current Status
|
||||
========
|
||||
|
||||
The implementation is in the very early stages of upstreaming. The first milestone is to get
|
||||
support for a simple SYCL application with device code using Unified Shared Memory:
|
||||
The implementation is in the very early stages of upstreaming. The first
|
||||
milestone is to get
|
||||
support for a simple SYCL application with device code using Unified Shared
|
||||
Memory:
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
@ -43,15 +45,18 @@ support for a simple SYCL application with device code using Unified Shared Memo
|
||||
return error;
|
||||
}
|
||||
|
||||
This requires at least partial support of the following functionality on the libsycl side:
|
||||
* ``sycl::platform`` class
|
||||
* ``sycl::device`` class
|
||||
* ``sycl::context`` class
|
||||
* ``sycl::queue`` class
|
||||
* ``sycl::handler`` class
|
||||
* ``sycl::id`` and ``sycl::range`` classes
|
||||
* Unified shared memory allocation/deallocation
|
||||
* Program manager, an internal component for retrieving and using device images from the multi-architectural binaries
|
||||
This requires at least partial support of the following functionality on the
|
||||
libsycl side:
|
||||
|
||||
* ``sycl::platform`` class
|
||||
* ``sycl::device`` class
|
||||
* ``sycl::context`` class
|
||||
* ``sycl::queue`` class
|
||||
* ``sycl::handler`` class
|
||||
* ``sycl::id`` and ``sycl::range`` classes
|
||||
* Unified shared memory allocation/deallocation
|
||||
* Program manager, an internal component for retrieving and using device images
|
||||
from the multi-architectural binaries
|
||||
|
||||
Build steps
|
||||
========
|
||||
@ -69,11 +74,20 @@ 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" \
|
||||
-DCMAKE_BUILD_TYPE=Release
|
||||
-DLLVM_ENABLE_RUNTIMES="offload;openmp;libsycl" \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
# must be default and configured in liboffload,
|
||||
# requires level zero, see offload/cmake/Modules/LibomptargetGetDependencies.cmake
|
||||
-DLIBOMPTARGET_PLUGINS_TO_BUILD=level_zero
|
||||
|
||||
ninja -C $build_llvm install
|
||||
|
||||
|
||||
|
||||
Limitations
|
||||
========
|
||||
|
||||
Libsycl is not currently supported on Windows because it depends on liboffload
|
||||
which doesn't currently support Windows.
|
||||
|
||||
50
libsycl/include/sycl/__impl/backend.hpp
Normal file
50
libsycl/include/sycl/__impl/backend.hpp
Normal file
@ -0,0 +1,50 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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 <sycl/__impl/detail/config.hpp>
|
||||
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
|
||||
_LIBSYCL_BEGIN_NAMESPACE_SYCL
|
||||
|
||||
// SYCL 2020 4.1. Backends.
|
||||
enum class backend : unsigned char {
|
||||
opencl = 0,
|
||||
level_zero,
|
||||
cuda,
|
||||
hip,
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
template <typename T> struct is_backend_info_desc : std::false_type {};
|
||||
} // namespace detail
|
||||
|
||||
// SYCL 2020 4.5.1.1. Type traits backend_traits.
|
||||
template <backend Backend> class backend_traits;
|
||||
|
||||
template <backend Backend, typename SyclType>
|
||||
using backend_input_t =
|
||||
typename backend_traits<Backend>::template input_type<SyclType>;
|
||||
template <backend Backend, typename SyclType>
|
||||
using backend_return_t =
|
||||
typename backend_traits<Backend>::template return_type<SyclType>;
|
||||
|
||||
_LIBSYCL_END_NAMESPACE_SYCL
|
||||
|
||||
#endif // _LIBSYCL___IMPL_BACKEND_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
|
||||
@ -56,4 +56,40 @@
|
||||
|
||||
#endif // __SYCL_DEVICE_ONLY__
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
static_assert(_MSVC_LANG >= 201703L, "Libsycl requires C++17 or later.");
|
||||
#else
|
||||
static_assert(__cplusplus >= 201703L, "Libsycl requires C++17 or later.");
|
||||
#endif
|
||||
|
||||
#ifndef __SYCL2020_DEPRECATED
|
||||
# if SYCL_LANGUAGE_VERSION == 202012L && \
|
||||
!defined(SYCL2020_DISABLE_DEPRECATION_WARNINGS)
|
||||
# define __SYCL2020_DEPRECATED(message) [[deprecated(message)]]
|
||||
# else
|
||||
# define __SYCL2020_DEPRECATED(message)
|
||||
# endif
|
||||
#endif // __SYCL2020_DEPRECATED
|
||||
|
||||
#if defined(_WIN32) && !defined(_DLL) && !defined(__SYCL_DEVICE_ONLY__)
|
||||
// When built for use with the MSVC C++ standard library, libsycl requires
|
||||
// use of the DLL versions of the MSVC run-time (RT) library. This requirement
|
||||
// extends to applications that link with libsycl since the same MSVC run-time
|
||||
// library must be used to ensure ABI compatibility for objects of C++ standard
|
||||
// library types like std::vector that are passed to or returned from SYCL
|
||||
// interfaces. Applications must therefore compile and link with the /MD option
|
||||
// when linking to a release build of libsycl and with the /MDd option when
|
||||
// linking to a debug build.
|
||||
# define ERROR_MESSAGE \
|
||||
"Libsycl requires use of a DLL version of the MSVC RT library. " \
|
||||
"Please use /MD to link with a release build of libsycl or /MDd to link" \
|
||||
" with a debug build."
|
||||
# if defined(_MSC_VER)
|
||||
# pragma message(ERROR_MESSAGE)
|
||||
# else
|
||||
# warning ERROR_MESSAGE
|
||||
# endif
|
||||
# undef ERROR_MESSAGE
|
||||
#endif // defined(_WIN32) && !defined(_DLL) && !defined(__SYCL_DEVICE_ONLY__)
|
||||
|
||||
#endif // _LIBSYCL___IMPL_DETAIL_CONFIG_HPP
|
||||
|
||||
80
libsycl/include/sycl/__impl/detail/obj_utils.hpp
Normal file
80
libsycl/include/sycl/__impl/detail/obj_utils.hpp
Normal file
@ -0,0 +1,80 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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 used to navigate between SYCL interface
|
||||
/// objects and their corresponding implementation objects.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBSYCL___IMPL_DETAIL_OBJ_UTILS_HPP
|
||||
#define _LIBSYCL___IMPL_DETAIL_OBJ_UTILS_HPP
|
||||
|
||||
#include <sycl/__impl/detail/config.hpp>
|
||||
|
||||
#include <cassert>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
_LIBSYCL_BEGIN_NAMESPACE_SYCL
|
||||
|
||||
namespace detail {
|
||||
|
||||
// SYCL interface classes are required to contain an `impl` data member
|
||||
// which points to the corresponding implementation object. The data
|
||||
// member is required to be accessible by the `ImpUtils` class. SYCL
|
||||
// interface classes that declare the data member private or protected
|
||||
// are required to befriend the `ImpUtils` class.
|
||||
struct ImplUtils {
|
||||
// Helper function to access an implementation object from a SYCL interface
|
||||
// object.
|
||||
template <typename SyclObject>
|
||||
static const decltype(SyclObject::impl) &
|
||||
getSyclObjImpl(const SyclObject &Obj) {
|
||||
assert(Obj.impl && "every constructor should create an impl");
|
||||
return Obj.impl;
|
||||
}
|
||||
|
||||
// Helper function to create a SYCL interface object from an implementation.
|
||||
template <typename SyclObject, typename Impl>
|
||||
static SyclObject createSyclObjFromImpl(Impl &&ImplObj) {
|
||||
if constexpr (std::is_same_v<decltype(SyclObject::impl),
|
||||
std::shared_ptr<std::decay_t<Impl>>>)
|
||||
return SyclObject{ImplObj.shared_from_this()};
|
||||
else
|
||||
return SyclObject{std::forward<Impl>(ImplObj)};
|
||||
}
|
||||
};
|
||||
|
||||
template <typename SyclObject>
|
||||
auto getSyclObjImpl(const SyclObject &Obj)
|
||||
-> decltype(ImplUtils::getSyclObjImpl(Obj)) {
|
||||
return ImplUtils::getSyclObjImpl(Obj);
|
||||
}
|
||||
|
||||
template <typename SyclObject, typename Impl>
|
||||
SyclObject createSyclObjFromImpl(Impl &&ImplObj) {
|
||||
return ImplUtils::createSyclObjFromImpl<SyclObject>(
|
||||
std::forward<Impl>(ImplObj));
|
||||
}
|
||||
|
||||
// SYCL 2020 4.5.2. Common reference semantics (std::hash support).
|
||||
template <typename T> struct HashBase {
|
||||
size_t operator()(const T &Obj) const {
|
||||
auto &Impl = sycl::detail::getSyclObjImpl(Obj);
|
||||
return std::hash<std::decay_t<decltype(Impl)>>{}(Impl);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
_LIBSYCL_END_NAMESPACE_SYCL
|
||||
|
||||
#endif // _LIBSYCL___IMPL_DETAIL_OBJ_UTILS_HPP
|
||||
153
libsycl/include/sycl/__impl/exception.hpp
Normal file
153
libsycl/include/sycl/__impl/exception.hpp
Normal file
@ -0,0 +1,153 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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 <sycl/__impl/detail/config.hpp>
|
||||
|
||||
#include <exception>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <system_error>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
_LIBSYCL_BEGIN_NAMESPACE_SYCL
|
||||
|
||||
// int is used as the underlying type for consistency with std::error_code.
|
||||
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 sycl::errc and sycl_category().
|
||||
///
|
||||
/// \param E SYCL 2020 error code.
|
||||
///
|
||||
/// \returns constructed error code.
|
||||
_LIBSYCL_EXPORT std::error_code make_error_code(sycl::errc E) noexcept;
|
||||
|
||||
/// Obtains a reference to the static error category object for SYCL errors.
|
||||
///
|
||||
/// This object overrides the virtual function error_category::name() to return
|
||||
/// a pointer to the string "sycl". When the implementation throws an
|
||||
/// sycl::exception object Ex with this category, the error code value contained
|
||||
/// by the exception (Ex.code().value()) is one of the enumerated values in
|
||||
/// sycl::errc.
|
||||
///
|
||||
/// \returns the error category object for SYCL errors.
|
||||
_LIBSYCL_EXPORT const std::error_category &sycl_category() noexcept;
|
||||
|
||||
/// \brief SYCL 2020 exception class (4.13.2.) for sync and async error handling
|
||||
/// in a SYCL application (host code).
|
||||
///
|
||||
/// Derived from std::exception so uncaught exceptions are printed in c++
|
||||
/// default exception handler. Virtual inheritance is mandated by SYCL 2020.
|
||||
class _LIBSYCL_EXPORT exception : public virtual std::exception {
|
||||
public:
|
||||
exception(std::error_code, const char *);
|
||||
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();
|
||||
|
||||
/// Returns the error code stored inside the exception.
|
||||
///
|
||||
/// \returns the error code stored inside the exception.
|
||||
const std::error_code &code() const noexcept;
|
||||
|
||||
/// Returns the error category of the error code stored inside the exception.
|
||||
///
|
||||
/// \returns the error category of the error code stored inside the exception.
|
||||
const std::error_category &category() const noexcept;
|
||||
|
||||
/// Returns string that describes the error that triggered the exception.
|
||||
///
|
||||
/// \returns an implementation-defined non-null constant C-style string that
|
||||
/// describes the error that triggered the exception.
|
||||
const char *what() const noexcept final;
|
||||
|
||||
/// Checks if the exception has an associated SYCL context.
|
||||
///
|
||||
/// \returns true if this SYCL exception has an associated SYCL context and
|
||||
/// false if it does not.
|
||||
bool has_context() const noexcept;
|
||||
|
||||
private:
|
||||
// Exceptions must be noexcept copy constructible, so cannot use std::string
|
||||
// directly.
|
||||
std::shared_ptr<std::string> MMessage;
|
||||
std::error_code MErrC = make_error_code(sycl::errc::invalid);
|
||||
};
|
||||
|
||||
/// \brief 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<std::exception_ptr>::const_iterator;
|
||||
using const_iterator = std::vector<std::exception_ptr>::const_iterator;
|
||||
|
||||
/// Returns the size of the list.
|
||||
///
|
||||
/// \returns the size of the list.
|
||||
size_type size() const;
|
||||
|
||||
/// Returns an iterator to the beginning of the list of asynchronous
|
||||
/// exceptions.
|
||||
///
|
||||
/// \returns an iterator to the beginning of the list of asynchronous
|
||||
/// exceptions.
|
||||
iterator begin() const;
|
||||
|
||||
/// Returns an iterator to the end of the list of asynchronous exceptions.
|
||||
///
|
||||
/// \returns an iterator to the end of the list of asynchronous exceptions.
|
||||
iterator end() const;
|
||||
|
||||
private:
|
||||
std::vector<std::exception_ptr> MList;
|
||||
};
|
||||
|
||||
_LIBSYCL_END_NAMESPACE_SYCL
|
||||
|
||||
namespace std {
|
||||
template <> struct is_error_code_enum<sycl::errc> : true_type {};
|
||||
} // namespace std
|
||||
|
||||
#endif // _LIBSYCL___IMPL_EXCEPTION_HPP
|
||||
40
libsycl/include/sycl/__impl/info/desc_base.hpp
Normal file
40
libsycl/include/sycl/__impl/info/desc_base.hpp
Normal file
@ -0,0 +1,40 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// This file contains helpers for info descriptors.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBSYCL___IMPL_INFO_DESC_BASE_HPP
|
||||
#define _LIBSYCL___IMPL_INFO_DESC_BASE_HPP
|
||||
|
||||
#include <sycl/__impl/detail/config.hpp>
|
||||
|
||||
_LIBSYCL_BEGIN_NAMESPACE_SYCL
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename Desc, typename DescOf> struct info_desc_tag {};
|
||||
|
||||
template <typename Desc, typename DescOf, typename = void>
|
||||
struct is_info_desc : std::false_type {};
|
||||
|
||||
template <typename Desc, typename DescOf>
|
||||
struct is_info_desc<
|
||||
Desc, DescOf,
|
||||
std::enable_if_t<std::is_base_of_v<info_desc_tag<Desc, DescOf>, Desc>>>
|
||||
: std::true_type {
|
||||
using return_type = typename Desc::return_type;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
_LIBSYCL_END_NAMESPACE_SYCL
|
||||
|
||||
#endif // _LIBSYCL___IMPL_INFO_DESC_BASE_HPP
|
||||
49
libsycl/include/sycl/__impl/info/platform.hpp
Normal file
49
libsycl/include/sycl/__impl/info/platform.hpp
Normal file
@ -0,0 +1,49 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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 <sycl/__impl/detail/config.hpp>
|
||||
#include <sycl/__impl/info/desc_base.hpp>
|
||||
|
||||
#include <string>
|
||||
|
||||
_LIBSYCL_BEGIN_NAMESPACE_SYCL
|
||||
|
||||
class platform;
|
||||
|
||||
namespace detail {
|
||||
template <typename T>
|
||||
using is_platform_info_desc_t = typename is_info_desc<T, platform>::return_type;
|
||||
} // namespace detail
|
||||
|
||||
// SYCL 2020 A.1. Platform information descriptors.
|
||||
namespace info {
|
||||
namespace platform {
|
||||
// SYCL 2020 4.6.2.4. Information descriptors.
|
||||
struct version : detail::info_desc_tag<version, sycl::platform> {
|
||||
using return_type = std::string;
|
||||
};
|
||||
struct name : detail::info_desc_tag<name, sycl::platform> {
|
||||
using return_type = std::string;
|
||||
};
|
||||
struct vendor : detail::info_desc_tag<vendor, sycl::platform> {
|
||||
using return_type = std::string;
|
||||
};
|
||||
} // namespace platform
|
||||
} // namespace info
|
||||
|
||||
_LIBSYCL_END_NAMESPACE_SYCL
|
||||
|
||||
#endif // _LIBSYCL___IMPL_INFO_PLATFORM_HPP
|
||||
@ -15,17 +15,78 @@
|
||||
#ifndef _LIBSYCL___IMPL_PLATFORM_HPP
|
||||
#define _LIBSYCL___IMPL_PLATFORM_HPP
|
||||
|
||||
#include <sycl/__impl/backend.hpp>
|
||||
#include <sycl/__impl/detail/config.hpp>
|
||||
#include <sycl/__impl/detail/obj_utils.hpp>
|
||||
#include <sycl/__impl/info/platform.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
_LIBSYCL_BEGIN_NAMESPACE_SYCL
|
||||
|
||||
namespace detail {
|
||||
class PlatformImpl;
|
||||
} // namespace detail
|
||||
|
||||
/// \brief SYCL 2020 platform class (4.6.2.) encapsulating a single SYCL
|
||||
/// platform on which kernel functions may be executed.
|
||||
class _LIBSYCL_EXPORT platform {
|
||||
public:
|
||||
/// Constructs a SYCL platform which contains the default device.
|
||||
platform();
|
||||
// The platform class provides the common reference semantics (SYCL
|
||||
// 2020 4.5.2).
|
||||
platform(const platform &rhs) = default;
|
||||
|
||||
platform(platform &&rhs) = default;
|
||||
|
||||
platform &operator=(const platform &rhs) = default;
|
||||
|
||||
platform &operator=(platform &&rhs) = default;
|
||||
|
||||
friend bool operator==(const platform &lhs, const platform &rhs) {
|
||||
return lhs.impl == rhs.impl;
|
||||
}
|
||||
|
||||
friend bool operator!=(const platform &lhs, const platform &rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
/// Returns the backend associated with this platform.
|
||||
///
|
||||
/// \return the backend associated with this platform.
|
||||
backend get_backend() const noexcept;
|
||||
|
||||
/// Queries this SYCL platform for info.
|
||||
///
|
||||
/// The return type depends on information being queried.
|
||||
template <typename Param>
|
||||
detail::is_platform_info_desc_t<Param> get_info() const;
|
||||
|
||||
/// Queries this SYCL platform for SYCL backend-specific information.
|
||||
///
|
||||
/// The return type depends on information being queried.
|
||||
template <typename Param>
|
||||
typename detail::is_backend_info_desc<Param>::return_type
|
||||
get_backend_info() const;
|
||||
|
||||
/// 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<platform> get_platforms();
|
||||
|
||||
private:
|
||||
platform(detail::PlatformImpl &Impl) : impl(&Impl) {}
|
||||
detail::PlatformImpl *impl;
|
||||
|
||||
friend sycl::detail::ImplUtils;
|
||||
}; // class platform
|
||||
|
||||
_LIBSYCL_END_NAMESPACE_SYCL
|
||||
|
||||
template <>
|
||||
struct std::hash<sycl::platform>
|
||||
: public sycl::detail::HashBase<sycl::platform> {};
|
||||
|
||||
#endif // _LIBSYCL___IMPL_PLATFORM_HPP
|
||||
|
||||
@ -14,6 +14,7 @@
|
||||
#ifndef _LIBSYCL_SYCL_HPP
|
||||
#define _LIBSYCL_SYCL_HPP
|
||||
|
||||
#include <sycl/__impl/exception.hpp>
|
||||
#include <sycl/__impl/platform.hpp>
|
||||
|
||||
#endif // _LIBSYCL_SYCL_HPP
|
||||
|
||||
@ -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})
|
||||
@ -15,21 +11,25 @@ function(add_sycl_rt_library LIB_TARGET_NAME LIB_OBJ_NAME LIB_OUTPUT_NAME)
|
||||
$<$<STREQUAL:${CMAKE_SYSTEM_NAME},Windows>:_LIBSYCL_BUILDING_LIBRARY>)
|
||||
cxx_add_warning_flags(${LIB_OBJ_NAME} ${LIBSYCL_ENABLE_WERROR} ${LIBSYCL_ENABLE_PEDANTIC})
|
||||
|
||||
target_include_directories(
|
||||
${LIB_OBJ_NAME}
|
||||
PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${LIBSYCL_BUILD_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
add_library(${LIB_TARGET_NAME} SHARED
|
||||
$<TARGET_OBJECTS:${LIB_OBJ_NAME}>)
|
||||
|
||||
add_dependencies(${LIB_OBJ_NAME}
|
||||
sycl-headers
|
||||
LLVMOffload
|
||||
)
|
||||
|
||||
set_target_properties(${LIB_TARGET_NAME} PROPERTIES LINKER_LANGUAGE CXX)
|
||||
target_include_directories(${LIB_OBJ_NAME}
|
||||
PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${LIBSYCL_BUILD_INCLUDE_DIR}
|
||||
$<TARGET_PROPERTY:LLVMOffload,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
)
|
||||
|
||||
set_target_properties(${LIB_TARGET_NAME}
|
||||
PROPERTIES
|
||||
LINKER_LANGUAGE CXX
|
||||
POSITION_INDEPENDENT_CODE TRUE)
|
||||
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL Windows)
|
||||
# Install stripped PDB
|
||||
@ -53,9 +53,11 @@ function(add_sycl_rt_library LIB_TARGET_NAME LIB_OBJ_NAME LIB_OUTPUT_NAME)
|
||||
|
||||
if (UNIX AND NOT APPLE)
|
||||
set(linker_script "${CMAKE_CURRENT_SOURCE_DIR}/ld-version-script.txt")
|
||||
target_link_libraries(
|
||||
${LIB_TARGET_NAME} PRIVATE "-Wl,--version-script=${linker_script}")
|
||||
set_target_properties(${LIB_TARGET_NAME} PROPERTIES LINK_DEPENDS ${linker_script})
|
||||
target_link_libraries(${LIB_TARGET_NAME}
|
||||
PRIVATE "-Wl,--version-script=${linker_script}")
|
||||
set_target_properties(${LIB_TARGET_NAME}
|
||||
PROPERTIES
|
||||
LINK_DEPENDS ${linker_script})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@ -65,32 +67,34 @@ 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
|
||||
VERSION ${LIBSYCL_VERSION_STRING}
|
||||
SOVERSION ${LIBSYCL_VERSION_STRING})
|
||||
set_target_properties(${LIB_TARGET_NAME} PROPERTIES OUTPUT_NAME ${LIB_OUTPUT_NAME})
|
||||
set_target_properties(${LIB_TARGET_NAME}
|
||||
PROPERTIES
|
||||
VERSION ${LIBSYCL_VERSION_STRING}
|
||||
SOVERSION ${LIBSYCL_VERSION_STRING})
|
||||
set_target_properties(${LIB_TARGET_NAME}
|
||||
PROPERTIES
|
||||
OUTPUT_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}
|
||||
SOURCES ${LIBSYCL_SOURCES})
|
||||
add_sycl_rt_library(${LIBSYCL_LIB_NAME}
|
||||
sycl_object
|
||||
${LIBSYCL_SHARED_OUTPUT_NAME}
|
||||
SOURCES
|
||||
${LIBSYCL_SOURCES})
|
||||
|
||||
install(TARGETS ${LIBSYCL_RT_LIBS}
|
||||
ARCHIVE DESTINATION "lib${LLVM_LIBDIR_SUFFIX}" COMPONENT libsycl
|
||||
|
||||
71
libsycl/src/detail/global_objects.cpp
Normal file
71
libsycl/src/detail/global_objects.cpp
Normal file
@ -0,0 +1,71 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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 <detail/global_objects.hpp>
|
||||
#include <detail/platform_impl.hpp>
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
|
||||
_LIBSYCL_BEGIN_NAMESPACE_SYCL
|
||||
namespace detail {
|
||||
|
||||
std::vector<detail::OffloadTopology> &getOffloadTopologies() {
|
||||
static std::vector<detail::OffloadTopology> Topologies(
|
||||
OL_PLATFORM_BACKEND_LAST);
|
||||
return Topologies;
|
||||
}
|
||||
|
||||
std::vector<PlatformImplUPtr> &getPlatformCache() {
|
||||
static std::vector<PlatformImplUPtr> PlatformCache{};
|
||||
return PlatformCache;
|
||||
}
|
||||
|
||||
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) {
|
||||
// TODO: Investigate how to handle and report errors that occur during
|
||||
// shutdown.
|
||||
}
|
||||
|
||||
break;
|
||||
case DLL_PROCESS_ATTACH:
|
||||
break;
|
||||
case DLL_THREAD_ATTACH:
|
||||
break;
|
||||
case DLL_THREAD_DETACH:
|
||||
break;
|
||||
}
|
||||
return TRUE; // Successful DLL_PROCESS_ATTACH.
|
||||
}
|
||||
#else
|
||||
|
||||
// `syclUnload()` is declared as a low priority destructor to ensure it runs
|
||||
// after all other global destructors. Priorities 0-100 are reserved for use
|
||||
// by the compiler and C and C++ standard libraries. SYCL applications may use
|
||||
// priorities in the range 101-109 to schedule destructors to run after libsycl
|
||||
// finalization.
|
||||
__attribute__((destructor(110))) static void syclUnload() { shutdown(); }
|
||||
#endif
|
||||
} // namespace detail
|
||||
_LIBSYCL_END_NAMESPACE_SYCL
|
||||
42
libsycl/src/detail/global_objects.hpp
Normal file
42
libsycl/src/detail/global_objects.hpp
Normal file
@ -0,0 +1,42 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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 <detail/offload/offload_topology.hpp>
|
||||
#include <sycl/__impl/detail/config.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
|
||||
_LIBSYCL_BEGIN_NAMESPACE_SYCL
|
||||
|
||||
namespace detail {
|
||||
class PlatformImpl;
|
||||
|
||||
/// Returns offload topologies (one per backend) discovered from liboffload.
|
||||
///
|
||||
/// This vector is populated only once at the first call of get_platforms().
|
||||
///
|
||||
/// \returns std::vector of all offload topologies.
|
||||
std::vector<detail::OffloadTopology> &getOffloadTopologies();
|
||||
|
||||
/// Returns implementation class objects for all platforms discovered from
|
||||
/// liboffload.
|
||||
///
|
||||
/// This vector is populated only once at the first call of get_platforms().
|
||||
///
|
||||
/// \returns std::vector of implementation objects for all platforms.
|
||||
std::vector<std::unique_ptr<PlatformImpl>> &getPlatformCache();
|
||||
|
||||
} // namespace detail
|
||||
_LIBSYCL_END_NAMESPACE_SYCL
|
||||
|
||||
#endif // _LIBSYCL_GLOBAL_OBJECTS
|
||||
78
libsycl/src/detail/offload/offload_topology.cpp
Normal file
78
libsycl/src/detail/offload/offload_topology.cpp
Normal file
@ -0,0 +1,78 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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 <detail/global_objects.hpp>
|
||||
#include <detail/offload/offload_topology.hpp>
|
||||
#include <detail/offload/offload_utils.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <unordered_map>
|
||||
|
||||
_LIBSYCL_BEGIN_NAMESPACE_SYCL
|
||||
|
||||
namespace detail {
|
||||
|
||||
void discoverOffloadDevices() {
|
||||
callAndThrow(olInit);
|
||||
|
||||
using PerBackendDataType =
|
||||
std::array<std::pair<PlatformWithDevStorageType, size_t /*DevCount*/>,
|
||||
OL_PLATFORM_BACKEND_LAST>;
|
||||
|
||||
PerBackendDataType Mapping;
|
||||
// olIterateDevices() calls the lambda for each device. Devices that fail
|
||||
// probes or that report unknown backends are silently ignored.
|
||||
// TODO for debug purposes env variable can be added to report error at the
|
||||
// first failure and interrupt iteration.
|
||||
callNoCheck(
|
||||
olIterateDevices,
|
||||
[](ol_device_handle_t Dev, void *User) -> bool {
|
||||
auto *Data = static_cast<PerBackendDataType *>(User);
|
||||
ol_platform_handle_t Plat = nullptr;
|
||||
ol_result_t Res = callNoCheck(
|
||||
olGetDeviceInfo, Dev, OL_DEVICE_INFO_PLATFORM, sizeof(Plat), &Plat);
|
||||
// If an error occurs, ignore the device and continue iteration.
|
||||
if (Res != OL_SUCCESS)
|
||||
return true;
|
||||
|
||||
ol_platform_backend_t OlBackend = OL_PLATFORM_BACKEND_UNKNOWN;
|
||||
Res = callNoCheck(olGetPlatformInfo, Plat, OL_PLATFORM_INFO_BACKEND,
|
||||
sizeof(OlBackend), &OlBackend);
|
||||
// If an error occurs, ignore the device and continue iteration.
|
||||
if (Res != OL_SUCCESS)
|
||||
return true;
|
||||
|
||||
// Ignore host and unknown backends
|
||||
if (OL_PLATFORM_BACKEND_HOST == OlBackend ||
|
||||
OL_PLATFORM_BACKEND_UNKNOWN == OlBackend)
|
||||
return true;
|
||||
|
||||
// Ignore the device if the backend index exceeds the number of backends
|
||||
// known at compile time. This should only happen when running with a
|
||||
// newer version of liboffload than libsycl was compiled with.
|
||||
if (OlBackend >= OL_PLATFORM_BACKEND_LAST)
|
||||
return true;
|
||||
|
||||
auto &[Map, DevCount] = (*Data)[static_cast<size_t>(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.setBackend(static_cast<ol_platform_backend_t>(I));
|
||||
Topo.registerNewPlatformsAndDevices(Mapping[I].first, Mapping[I].second);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
_LIBSYCL_END_NAMESPACE_SYCL
|
||||
122
libsycl/src/detail/offload/offload_topology.hpp
Normal file
122
libsycl/src/detail/offload/offload_topology.hpp
Normal file
@ -0,0 +1,122 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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 <sycl/__impl/detail/config.hpp>
|
||||
|
||||
#include <OffloadAPI.h>
|
||||
|
||||
#include <cassert>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
_LIBSYCL_BEGIN_NAMESPACE_SYCL
|
||||
|
||||
namespace detail {
|
||||
|
||||
// Minimal span-like view.
|
||||
template <class T> struct range_view {
|
||||
T *ptr{};
|
||||
size_t len{};
|
||||
T *begin() const { return ptr; }
|
||||
T *end() const { return ptr + len; }
|
||||
T &operator[](size_t i) const { return ptr[i]; }
|
||||
size_t size() const { return len; }
|
||||
};
|
||||
|
||||
using PlatformWithDevStorageType =
|
||||
std::unordered_map<ol_platform_handle_t, std::vector<ol_device_handle_t>>;
|
||||
|
||||
/// Contiguous global storage of platform handlers and device handles (grouped
|
||||
/// by platform) for a backend.
|
||||
struct OffloadTopology {
|
||||
OffloadTopology() : MBackend(OL_PLATFORM_BACKEND_UNKNOWN) {}
|
||||
OffloadTopology(ol_platform_backend_t OlBackend) : MBackend(OlBackend) {}
|
||||
|
||||
/// Updates backend for this topology.
|
||||
///
|
||||
/// \param B new backend value.
|
||||
void setBackend(ol_platform_backend_t B) { MBackend = B; }
|
||||
|
||||
/// Returns all platforms associated with this topology.
|
||||
///
|
||||
/// \returns minimal span-like view to platforms associated with this
|
||||
/// topology.
|
||||
range_view<const ol_platform_handle_t> platforms() const {
|
||||
return {MPlatforms.data(), MPlatforms.size()};
|
||||
}
|
||||
|
||||
/// Returns all devices associated with specific platform.
|
||||
///
|
||||
/// \param PlatformId platform_id is index into MPlatforms.
|
||||
///
|
||||
/// \returns minimal span-like view to devices associated with specified
|
||||
/// platform.
|
||||
range_view<const ol_device_handle_t>
|
||||
devicesForPlatform(size_t PlatformId) const {
|
||||
if (PlatformId >= MDevRangePerPlatformId.size()) {
|
||||
assert(false && "Platform index exceeds number of platforms.");
|
||||
return {nullptr, 0};
|
||||
}
|
||||
return MDevRangePerPlatformId[PlatformId];
|
||||
}
|
||||
|
||||
/// Register new platform and devices into this topology.
|
||||
///
|
||||
/// \param PlatformsAndDev associative container with platforms & devices.
|
||||
/// \param TotalDevCount total device count for the platform.
|
||||
void
|
||||
registerNewPlatformsAndDevices(PlatformWithDevStorageType &PlatformsAndDev,
|
||||
size_t TotalDevCount) {
|
||||
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<const ol_device_handle_t> R{MDevices.data() + MDevices.size(),
|
||||
NewDevs.size()};
|
||||
MDevices.insert(MDevices.end(), NewDevs.begin(), NewDevs.end());
|
||||
MDevRangePerPlatformId.push_back(R);
|
||||
}
|
||||
|
||||
assert(TotalDevCount == MDevices.size());
|
||||
}
|
||||
|
||||
/// Queries backend of this topology.
|
||||
///
|
||||
/// \returns backend of this topology.
|
||||
ol_platform_backend_t backend() const { return MBackend; }
|
||||
|
||||
private:
|
||||
ol_platform_backend_t MBackend = OL_PLATFORM_BACKEND_UNKNOWN;
|
||||
|
||||
// Platforms and devices belonging to this backend (flattened)
|
||||
std::vector<ol_platform_handle_t> MPlatforms;
|
||||
std::vector<ol_device_handle_t> MDevices; // sorted by platform
|
||||
|
||||
// Vector holding range of devices for each platform (index is platform index
|
||||
// within MPlatforms)
|
||||
std::vector<range_view<const ol_device_handle_t>>
|
||||
MDevRangePerPlatformId; // MDevRangePerPlatformId.size() ==
|
||||
// MPlatforms.size()
|
||||
};
|
||||
|
||||
// Initialize the topologies by calling olIterateDevices.
|
||||
void discoverOffloadDevices();
|
||||
|
||||
} // namespace detail
|
||||
|
||||
_LIBSYCL_END_NAMESPACE_SYCL
|
||||
|
||||
#endif // _LIBSYCL_OFFLOAD_TOPOLOGY
|
||||
65
libsycl/src/detail/offload/offload_utils.cpp
Normal file
65
libsycl/src/detail/offload/offload_utils.cpp
Normal file
@ -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 <detail/offload/offload_utils.hpp>
|
||||
|
||||
_LIBSYCL_BEGIN_NAMESPACE_SYCL
|
||||
namespace detail {
|
||||
|
||||
const char *stringifyErrorCode(ol_errc_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
|
||||
115
libsycl/src/detail/offload/offload_utils.hpp
Normal file
115
libsycl/src/detail/offload/offload_utils.hpp
Normal file
@ -0,0 +1,115 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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 <sycl/__impl/backend.hpp>
|
||||
#include <sycl/__impl/detail/config.hpp>
|
||||
#include <sycl/__impl/exception.hpp>
|
||||
|
||||
#include <OffloadAPI.h>
|
||||
|
||||
_LIBSYCL_BEGIN_NAMESPACE_SYCL
|
||||
|
||||
namespace detail {
|
||||
|
||||
/// Converts liboffload error code to C-string.
|
||||
///
|
||||
/// \param Error liboffload error code.
|
||||
///
|
||||
/// \returns C-string representing the name of Error as specified in enum.
|
||||
const char *stringifyErrorCode(ol_errc_t Error);
|
||||
|
||||
/// Contructs C++-string with information about liboffload error.
|
||||
///
|
||||
/// \param Error liboffload result of calling API.
|
||||
///
|
||||
/// \returns C++-string containing all available data of failure.
|
||||
inline std::string formatCodeString(ol_result_t Result) {
|
||||
return std::to_string(Result->Code) + " (" +
|
||||
std::string(stringifyErrorCode(Result->Code)) + ") " + Result->Details;
|
||||
}
|
||||
|
||||
/// Checks liboffload API call result.
|
||||
///
|
||||
/// Used after calling the API without check.
|
||||
/// To be called when specific handling is needed and explicitly done by
|
||||
/// developer before throwing exception.
|
||||
///
|
||||
/// \param Error liboffload result of calling API.
|
||||
///
|
||||
/// \throw sycl::runtime_exception if the call was not successful.
|
||||
template <sycl::errc errc = sycl::errc::runtime>
|
||||
void checkAndThrow(ol_result_t Result) {
|
||||
if (Result != OL_SUCCESS) {
|
||||
throw sycl::exception(sycl::make_error_code(errc),
|
||||
detail::formatCodeString(Result));
|
||||
}
|
||||
}
|
||||
|
||||
/// Calls the API, doesn't check result.
|
||||
/// To be called when specific handling is needed and explicitly done by
|
||||
/// developer after.
|
||||
///
|
||||
/// \param Function liboffload API function to be called.
|
||||
/// \param Args arguments to be passed to the liboffload API function.
|
||||
///
|
||||
/// \returns liboffload error code returned by API call.
|
||||
template <typename FunctionType, typename... ArgsT>
|
||||
ol_result_t callNoCheck(FunctionType &Function, ArgsT &&...Args) {
|
||||
return Function(std::forward<ArgsT>(Args)...);
|
||||
}
|
||||
|
||||
/// Calls the API and checks result.
|
||||
///
|
||||
/// \param Function liboffload API function to be called.
|
||||
/// \param Args arguments to be passed to the liboffload API function.
|
||||
///
|
||||
/// \throw sycl::runtime_exception if the call was not successful.
|
||||
template <typename FunctionType, typename... ArgsT>
|
||||
void callAndThrow(FunctionType &Function, ArgsT &&...Args) {
|
||||
auto Err = callNoCheck(Function, std::forward<ArgsT>(Args)...);
|
||||
checkAndThrow(Err);
|
||||
}
|
||||
|
||||
/// Converts liboffload backend to SYCL backend.
|
||||
///
|
||||
/// \param Backend liboffload backend.
|
||||
///
|
||||
/// \returns sycl::backend matching specified liboffload backend.
|
||||
backend convertBackend(ol_platform_backend_t Backend);
|
||||
|
||||
/// Helper to map SYCL information descriptors to OL_<HANDLE>_INFO_<SMTH>.
|
||||
///
|
||||
/// Typical usage:
|
||||
/// \code
|
||||
/// using Map = info_ol_mapping<ol_foo_info_t>;
|
||||
/// constexpr auto olInfo = map_info_desc<FromDesc, ol_foo_info_t>(
|
||||
/// Map::M<DescVal0>{OL_FOO_INFO_VAL0},
|
||||
/// Map::M<DescVal1>{OL_FOO_INFO_VAL1},
|
||||
/// ...)
|
||||
/// \endcode
|
||||
template <typename To> struct info_ol_mapping {
|
||||
template <typename From> struct M {
|
||||
To value;
|
||||
constexpr M(To value) : value(value) {}
|
||||
};
|
||||
};
|
||||
template <typename From, typename To, typename... Ts>
|
||||
constexpr To map_info_desc(typename info_ol_mapping<To>::template M<Ts>... ms) {
|
||||
return std::get<typename info_ol_mapping<To>::template M<From>>(
|
||||
std::tuple{ms...})
|
||||
.value;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
_LIBSYCL_END_NAMESPACE_SYCL
|
||||
|
||||
#endif // _LIBSYCL_OFFLOAD_UTILS
|
||||
58
libsycl/src/detail/platform_impl.cpp
Normal file
58
libsycl/src/detail/platform_impl.cpp
Normal file
@ -0,0 +1,58 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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 <sycl/__impl/detail/config.hpp>
|
||||
#include <sycl/__impl/detail/obj_utils.hpp>
|
||||
|
||||
#include <detail/global_objects.hpp>
|
||||
#include <detail/platform_impl.hpp>
|
||||
|
||||
_LIBSYCL_BEGIN_NAMESPACE_SYCL
|
||||
|
||||
namespace detail {
|
||||
|
||||
PlatformImpl &PlatformImpl::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");
|
||||
}
|
||||
|
||||
const std::vector<PlatformImplUPtr> &PlatformImpl::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<PlatformImpl>(
|
||||
OffloadPlatform, PlatformIndex++, PrivateTag{}));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}();
|
||||
return getPlatformCache();
|
||||
}
|
||||
|
||||
PlatformImpl::PlatformImpl(ol_platform_handle_t Platform, size_t PlatformIndex,
|
||||
PrivateTag)
|
||||
: MOffloadPlatform(Platform), MOffloadPlatformIndex(PlatformIndex) {
|
||||
ol_platform_backend_t Backend = OL_PLATFORM_BACKEND_UNKNOWN;
|
||||
callAndThrow(olGetPlatformInfo, MOffloadPlatform, OL_PLATFORM_INFO_BACKEND,
|
||||
sizeof(Backend), &Backend);
|
||||
MBackend = convertBackend(Backend);
|
||||
MOffloadBackend = Backend;
|
||||
}
|
||||
} // namespace detail
|
||||
_LIBSYCL_END_NAMESPACE_SYCL
|
||||
112
libsycl/src/detail/platform_impl.hpp
Normal file
112
libsycl/src/detail/platform_impl.hpp
Normal file
@ -0,0 +1,112 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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 <sycl/__impl/backend.hpp>
|
||||
#include <sycl/__impl/detail/config.hpp>
|
||||
#include <sycl/__impl/platform.hpp>
|
||||
|
||||
#include <detail/offload/offload_utils.hpp>
|
||||
|
||||
#include <OffloadAPI.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
_LIBSYCL_BEGIN_NAMESPACE_SYCL
|
||||
|
||||
namespace detail {
|
||||
|
||||
using PlatformImplUPtr = std::unique_ptr<PlatformImpl>;
|
||||
|
||||
class PlatformImpl {
|
||||
struct PrivateTag {
|
||||
explicit PrivateTag() = default;
|
||||
};
|
||||
|
||||
public:
|
||||
/// Constructs PlatformImpl 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).
|
||||
/// All platform impls are created during first getPlatforms() call.
|
||||
PlatformImpl(ol_platform_handle_t Platform, size_t PlatformIndex, PrivateTag);
|
||||
|
||||
~PlatformImpl() = default;
|
||||
|
||||
/// Returns the backend associated with this platform.
|
||||
///
|
||||
/// \returns sycl::backend associated with this platform.
|
||||
backend getBackend() const noexcept { return MBackend; }
|
||||
|
||||
/// Returns all SYCL platforms from all backends that are
|
||||
/// available in the system.
|
||||
///
|
||||
/// \returns std::vector of all platforms that are available in the system.
|
||||
static const std::vector<PlatformImplUPtr> &getPlatforms();
|
||||
|
||||
/// Returns the raw underlying offload platform handle.
|
||||
///
|
||||
/// The caller is responsible for ensuring that the returned handle is only
|
||||
/// used while the PlatformImpl object from which it was obtained is still
|
||||
/// within its lifetime.
|
||||
///
|
||||
/// \return a raw offload platform handle.
|
||||
const ol_platform_handle_t &getHandleRef() const { return MOffloadPlatform; }
|
||||
|
||||
/// Queries the cache to get the implementation for specified offloading RT
|
||||
/// platform. All platform implementation objects are created at first
|
||||
/// get_platforms call.
|
||||
///
|
||||
/// \param Platform is the offloading RT Platform handle representing the
|
||||
/// platform.
|
||||
/// \return the PlatformImpl representing the offloading RT platform.
|
||||
static PlatformImpl &getPlatformImpl(ol_platform_handle_t Platform);
|
||||
|
||||
/// Queries this platform for info.
|
||||
///
|
||||
/// The return type depends on information being queried.
|
||||
template <typename Param> typename Param::return_type getInfo() const {
|
||||
// For now we have only std::string properties
|
||||
static_assert(std::is_same_v<typename Param::return_type, std::string>);
|
||||
|
||||
using namespace info::platform;
|
||||
using Map = info_ol_mapping<ol_platform_info_t>;
|
||||
|
||||
constexpr ol_platform_info_t olInfo =
|
||||
map_info_desc<Param, ol_platform_info_t>(
|
||||
Map::M<version>{OL_PLATFORM_INFO_VERSION},
|
||||
Map::M<name>{OL_PLATFORM_INFO_NAME},
|
||||
Map::M<vendor>{OL_PLATFORM_INFO_VENDOR_NAME});
|
||||
|
||||
size_t ExpectedSize = 0;
|
||||
callAndThrow(olGetPlatformInfoSize, MOffloadPlatform, olInfo,
|
||||
&ExpectedSize);
|
||||
std::string Result;
|
||||
Result.resize(ExpectedSize - 1);
|
||||
callAndThrow(olGetPlatformInfo, MOffloadPlatform, olInfo, 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
|
||||
48
libsycl/src/exception.cpp
Normal file
48
libsycl/src/exception.cpp
Normal file
@ -0,0 +1,48 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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 <sycl/__impl/detail/config.hpp>
|
||||
#include <sycl/__impl/exception.hpp>
|
||||
|
||||
_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<int>(Err), sycl_category());
|
||||
}
|
||||
|
||||
// Exception methods implementation
|
||||
exception::exception(std::error_code EC, const char *Msg)
|
||||
: MMessage(std::make_shared<std::string>(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 false; }
|
||||
|
||||
_LIBSYCL_END_NAMESPACE_SYCL
|
||||
21
libsycl/src/exception_list.cpp
Normal file
21
libsycl/src/exception_list.cpp
Normal file
@ -0,0 +1,21 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// SYCL 2020 4.13.2. Exception class interface.
|
||||
#include <sycl/__impl/detail/config.hpp>
|
||||
#include <sycl/__impl/exception.hpp>
|
||||
|
||||
_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
|
||||
@ -8,10 +8,37 @@
|
||||
|
||||
#include <sycl/__impl/platform.hpp>
|
||||
|
||||
#include <detail/platform_impl.hpp>
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
_LIBSYCL_BEGIN_NAMESPACE_SYCL
|
||||
|
||||
platform::platform() { throw std::runtime_error("Unimplemented"); }
|
||||
backend platform::get_backend() const noexcept { return impl->getBackend(); }
|
||||
|
||||
std::vector<platform> platform::get_platforms() {
|
||||
auto &PlatformImpls = detail::PlatformImpl::getPlatforms();
|
||||
std::vector<platform> Platforms;
|
||||
Platforms.reserve(PlatformImpls.size());
|
||||
for (auto &PlatformImpl : PlatformImpls) {
|
||||
platform Platform = detail::createSyclObjFromImpl<platform>(*PlatformImpl);
|
||||
Platforms.push_back(std::move(Platform));
|
||||
}
|
||||
return Platforms;
|
||||
}
|
||||
|
||||
template <typename Param>
|
||||
detail::is_platform_info_desc_t<Param> platform::get_info() const {
|
||||
return impl->getInfo<Param>();
|
||||
}
|
||||
|
||||
#define _LIBSYCL_EXPORT_GET_INFO(Desc) \
|
||||
template _LIBSYCL_EXPORT \
|
||||
detail::is_platform_info_desc_t<info::platform::Desc> \
|
||||
platform::get_info<info::platform::Desc>() const;
|
||||
_LIBSYCL_EXPORT_GET_INFO(version)
|
||||
_LIBSYCL_EXPORT_GET_INFO(name)
|
||||
_LIBSYCL_EXPORT_GET_INFO(vendor)
|
||||
#undef _LIBSYCL_EXPORT_GET_INFO
|
||||
|
||||
_LIBSYCL_END_NAMESPACE_SYCL
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// This file contains the declaration of SYCL RT version macro.
|
||||
/// This file contains the declaration of libsycl version macro.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
#define _LIBSYCL_MAJOR_VERSION ${LIBSYCL_MAJOR_VERSION}
|
||||
|
||||
1
libsycl/tools/CMakeLists.txt
Normal file
1
libsycl/tools/CMakeLists.txt
Normal file
@ -0,0 +1 @@
|
||||
add_subdirectory(sycl-ls)
|
||||
29
libsycl/tools/sycl-ls/CMakeLists.txt
Normal file
29
libsycl/tools/sycl-ls/CMakeLists.txt
Normal file
@ -0,0 +1,29 @@
|
||||
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 (NOT LLVM_ENABLE_RTTI AND COMPILER_HAS_NORTTI_FLAG)
|
||||
target_compile_options(sycl-ls PRIVATE -fno-rtti)
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
# For security purposes, searches for dependent libraries are limited to
|
||||
# the combination of directories specified by the following flags of
|
||||
# LoadLibraryEx().
|
||||
# - LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR (0x100)
|
||||
# - LOAD_LIBRARY_SEARCH_SYSTEM32 (0x800)
|
||||
target_link_options(sycl-ls PRIVATE LINKER:/DEPENDENTLOADFLAG:0x900)
|
||||
endif()
|
||||
install(TARGETS sycl-ls
|
||||
RUNTIME DESTINATION "bin" COMPONENT sycl-ls)
|
||||
84
libsycl/tools/sycl-ls/sycl-ls.cpp
Normal file
84
libsycl/tools/sycl-ls/sycl-ls.cpp
Normal file
@ -0,0 +1,84 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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 <sycl/sycl.hpp>
|
||||
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using namespace sycl;
|
||||
using namespace std::literals;
|
||||
|
||||
inline std::string_view getBackendName(const backend &Backend) {
|
||||
switch (Backend) {
|
||||
case backend::opencl:
|
||||
return "opencl";
|
||||
case backend::level_zero:
|
||||
return "level_zero";
|
||||
case backend::cuda:
|
||||
return "cuda";
|
||||
case backend::hip:
|
||||
return "hip";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
llvm::cl::opt<bool> 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;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
for (const auto &Platform : Platforms) {
|
||||
backend Backend = Platform.get_backend();
|
||||
std::cout << "[" << getBackendName(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<info::platform::version>();
|
||||
auto PlatformName = Platform.get_info<info::platform::name>();
|
||||
auto PlatformVendor = Platform.get_info<info::platform::vendor>();
|
||||
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;
|
||||
}
|
||||
}
|
||||
} catch (sycl::exception &e) {
|
||||
std::cerr << "SYCL Exception encountered: " << e.what() << std::endl
|
||||
<< std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user