[llvm-branch-commits] [llvm] [libsycl] add sycl::context stub (PR #182483)

Kseniya Tikhomirova via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Fri Feb 20 04:12:03 PST 2026


https://github.com/KseniyaTikhomirova created https://github.com/llvm/llvm-project/pull/182483

None

>From 211571b6064fb15188b6da56558d9a1622530819 Mon Sep 17 00:00:00 2001
From: "Tikhomirova, Kseniya" <kseniya.tikhomirova at intel.com>
Date: Fri, 13 Feb 2026 04:21:03 -0800
Subject: [PATCH] [libsycl] add sycl::context stub

Signed-off-by: Tikhomirova, Kseniya <kseniya.tikhomirova at intel.com>
---
 libsycl/docs/index.rst                       |  2 +-
 libsycl/include/sycl/__impl/context.hpp      | 99 ++++++++++++++++++++
 libsycl/include/sycl/__impl/device.hpp       |  2 +-
 libsycl/include/sycl/sycl.hpp                |  1 +
 libsycl/src/CMakeLists.txt                   |  2 +
 libsycl/src/context.cpp                      | 33 +++++++
 libsycl/src/detail/context_impl.cpp          | 27 ++++++
 libsycl/src/detail/context_impl.hpp          | 75 +++++++++++++++
 libsycl/src/detail/device_impl.cpp           |  6 +-
 libsycl/src/detail/device_impl.hpp           |  4 +-
 libsycl/src/detail/offload/offload_utils.hpp |  6 +-
 libsycl/src/detail/platform_impl.cpp         |  9 ++
 libsycl/src/detail/platform_impl.hpp         | 24 ++++-
 libsycl/src/device.cpp                       |  4 -
 14 files changed, 278 insertions(+), 16 deletions(-)
 create mode 100644 libsycl/include/sycl/__impl/context.hpp
 create mode 100644 libsycl/src/context.cpp
 create mode 100644 libsycl/src/detail/context_impl.cpp
 create mode 100644 libsycl/src/detail/context_impl.hpp

diff --git a/libsycl/docs/index.rst b/libsycl/docs/index.rst
index 03e083227ace4..01bfb19b3d432 100644
--- a/libsycl/docs/index.rst
+++ b/libsycl/docs/index.rst
@@ -105,4 +105,4 @@ TODO for added SYCL classes
   * ``has_extension``: deprecated API, to implement on RT level with ``device::has``
 
 * device selection: to add compatibility with old SYCL 1.2.1 device selectors, still part of SYCL 2020 specification
-
+* ``context``: to implement get_info, properties & public constructors once context support is added to liboffload
diff --git a/libsycl/include/sycl/__impl/context.hpp b/libsycl/include/sycl/__impl/context.hpp
new file mode 100644
index 0000000000000..70cd1fbaf55f8
--- /dev/null
+++ b/libsycl/include/sycl/__impl/context.hpp
@@ -0,0 +1,99 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 context class, which
+/// represents the runtime data structures and state required by a SYCL backend
+/// API to interact with a group of devices associated with a platform.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBSYCL___IMPL_CONTEXT_HPP
+#define _LIBSYCL___IMPL_CONTEXT_HPP
+
+#include <sycl/__impl/backend.hpp>
+#include <sycl/__impl/info/desc_base.hpp>
+
+#include <sycl/__impl/detail/config.hpp>
+#include <sycl/__impl/detail/obj_utils.hpp>
+
+#include <memory>
+#include <vector>
+
+_LIBSYCL_BEGIN_NAMESPACE_SYCL
+
+class context;
+class device;
+class platform;
+
+namespace detail {
+class ContextImpl;
+template <typename T>
+using is_context_info_desc_t = typename is_info_desc<T, context>::return_type;
+} // namespace detail
+
+// SYCL 2020 4.6.3. Context class
+class _LIBSYCL_EXPORT context {
+public:
+  context(const context &rhs) = default;
+
+  context(context &&rhs) = default;
+
+  context &operator=(const context &rhs) = default;
+
+  context &operator=(context &&rhs) = default;
+
+  friend bool operator==(const context &lhs, const context &rhs) {
+    return lhs.impl == rhs.impl;
+  }
+
+  friend bool operator!=(const context &lhs, const context &rhs) {
+    return !(lhs == rhs);
+  }
+
+  /// Returns the backend associated with this context.
+  ///
+  /// \return the backend associated with this context.
+  backend get_backend() const noexcept;
+
+  /// Gets platform associated with this SYCL context.
+  ///
+  /// \return a valid instance of SYCL platform.
+  platform get_platform() const;
+
+  /// Gets devices associated with this SYCL context.
+  ///
+  /// \return a vector of valid SYCL device instances.
+  std::vector<device> get_devices() const;
+
+  /// Queries this SYCL context for information.
+  ///
+  /// The return type depends on information being queried.
+  template <typename Param>
+  detail::is_context_info_desc_t<Param> get_info() const;
+
+  /// Queries this SYCL context for SYCL backend-specific information.
+  ///
+  /// The return type depends on information being queried.
+  template <typename Param>
+  typename Param::return_type get_backend_info() const;
+
+private:
+  context(const std::shared_ptr<detail::ContextImpl> &Impl) : impl(Impl) {}
+  std::shared_ptr<detail::ContextImpl> impl;
+
+  friend sycl::detail::ImplUtils;
+}; // class context
+
+_LIBSYCL_END_NAMESPACE_SYCL
+
+template <>
+struct std::hash<sycl::context> : public sycl::detail::HashBase<sycl::context> {
+};
+
+#endif // _LIBSYCL___IMPL_CONTEXT_HPP
diff --git a/libsycl/include/sycl/__impl/device.hpp b/libsycl/include/sycl/__impl/device.hpp
index 55b624f8fcbd5..fa4c888d66582 100644
--- a/libsycl/include/sycl/__impl/device.hpp
+++ b/libsycl/include/sycl/__impl/device.hpp
@@ -52,7 +52,7 @@ class _LIBSYCL_EXPORT device {
 
   /// Constructs a SYCL device instance using the default device (device chosen
   /// by default device selector).
-  device();
+  device() : device(default_selector_v) {}
 
   /// Constructs a SYCL device instance using the device
   /// identified by the provided device selector.
diff --git a/libsycl/include/sycl/sycl.hpp b/libsycl/include/sycl/sycl.hpp
index 3e7f81092256c..5823f29268567 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 <sycl/__impl/context.hpp>
 #include <sycl/__impl/device.hpp>
 #include <sycl/__impl/device_selector.hpp>
 #include <sycl/__impl/exception.hpp>
diff --git a/libsycl/src/CMakeLists.txt b/libsycl/src/CMakeLists.txt
index 0a83f2ef36443..fa3bf81e17d2a 100644
--- a/libsycl/src/CMakeLists.txt
+++ b/libsycl/src/CMakeLists.txt
@@ -81,11 +81,13 @@ function(add_sycl_rt_library LIB_TARGET_NAME LIB_OBJ_NAME LIB_OUTPUT_NAME)
 endfunction(add_sycl_rt_library)
 
 set(LIBSYCL_SOURCES
+    "context.cpp"
     "exception.cpp"
     "exception_list.cpp"
     "device.cpp"
     "device_selector.cpp"
     "platform.cpp"
+    "detail/context_impl.cpp"
     "detail/device_impl.cpp"
     "detail/global_objects.cpp"
     "detail/platform_impl.cpp"
diff --git a/libsycl/src/context.cpp b/libsycl/src/context.cpp
new file mode 100644
index 0000000000000..e50c8bde98c48
--- /dev/null
+++ b/libsycl/src/context.cpp
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+#include <sycl/__impl/device.hpp>
+
+#include <detail/context_impl.hpp>
+#include <detail/platform_impl.hpp>
+
+_LIBSYCL_BEGIN_NAMESPACE_SYCL
+
+backend context::get_backend() const noexcept { return impl->getBackend(); }
+
+platform context::get_platform() const {
+  return detail::createSyclObjFromImpl<platform>(impl->getPlatformImpl());
+}
+
+std::vector<device> context::get_devices() const {
+  std::vector<device> Devices;
+
+  impl->iterateDevices([&Devices](detail::DeviceImpl *DevImpl) {
+    assert(DevImpl && "Device impl can't be nullptr");
+    Devices.push_back(detail::createSyclObjFromImpl<device>(*DevImpl));
+  });
+
+  return Devices;
+}
+
+_LIBSYCL_END_NAMESPACE_SYCL
diff --git a/libsycl/src/detail/context_impl.cpp b/libsycl/src/detail/context_impl.cpp
new file mode 100644
index 0000000000000..a3353e9304c44
--- /dev/null
+++ b/libsycl/src/detail/context_impl.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
+//
+//===----------------------------------------------------------------------===//
+
+#include <detail/context_impl.hpp>
+#include <detail/platform_impl.hpp>
+
+_LIBSYCL_BEGIN_NAMESPACE_SYCL
+
+namespace detail {
+
+void ContextImpl::iterateDevices(
+    const std::function<void(DeviceImpl *)> &callback) const {
+  // Intentionally don't store devices in context now. This class should be
+  // reimplemented once liboffload adds context support. Treat context as
+  // default context that is associated with all devices in the platform.
+  return MPlatform.iterateDevices(info::device_type::all, callback);
+}
+
+backend ContextImpl::getBackend() const { return MPlatform.getBackend(); }
+
+} // namespace detail
+_LIBSYCL_END_NAMESPACE_SYCL
diff --git a/libsycl/src/detail/context_impl.hpp b/libsycl/src/detail/context_impl.hpp
new file mode 100644
index 0000000000000..0e58e61d080bf
--- /dev/null
+++ b/libsycl/src/detail/context_impl.hpp
@@ -0,0 +1,75 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_CONTEXT_IMPL
+#define _LIBSYCL_CONTEXT_IMPL
+
+#include <sycl/__impl/context.hpp>
+#include <sycl/__impl/detail/config.hpp>
+
+#include <OffloadAPI.h>
+
+#include <functional>
+
+_LIBSYCL_BEGIN_NAMESPACE_SYCL
+namespace detail {
+
+class PlatformImpl;
+class DeviceImpl;
+
+/// Context dummy (w/o liboffload handle) that represents all devices
+/// in platform.
+///
+/// Presence of context object is essential for many APIs. This dummy is a way
+/// to support them in case of absence of context support in liboffload. For
+/// backends where context exists and participates in operations liboffload
+/// plugins create and use default context that represents all devices in that
+/// platform. Duplicating this logic here.
+class ContextImpl : public std::enable_shared_from_this<ContextImpl> {
+  struct Private {
+    explicit Private() = default;
+  };
+
+public:
+  /// Constructs a ContextImpl using a platform.
+  ///
+  /// Newly created instance represents all devices in platform.
+  ///
+  /// \param Platform is a platform to associate this context with.
+  ContextImpl(PlatformImpl &Platform, Private) : MPlatform(Platform) {}
+
+  /// Constructs a ContextImpl with a provided arguments. Variadic helper.
+  /// Restrics ways of ContextImpl creation.
+  template <typename... Ts>
+  static std::shared_ptr<ContextImpl> create(Ts &&...args) {
+    return std::make_shared<ContextImpl>(std::forward<Ts>(args)..., Private{});
+  }
+
+  /// Returns associated platform
+  ///
+  /// \return platform implementation object this context is associated with.
+  PlatformImpl &getPlatformImpl() const { return MPlatform; }
+
+  /// Calls "callback" with every device associated
+  /// with this context.
+  void iterateDevices(const std::function<void(DeviceImpl *)> &callback) const;
+
+  /// Returns backend of the platform this context is associated with.
+  ///
+  /// \return SYCL backend.
+  backend getBackend() const;
+
+private:
+  PlatformImpl &MPlatform;
+};
+
+} // namespace detail
+
+_LIBSYCL_END_NAMESPACE_SYCL
+
+#endif // _LIBSYCL_CONTEXT_IMPL
diff --git a/libsycl/src/detail/device_impl.cpp b/libsycl/src/detail/device_impl.cpp
index de702cc4b7839..d12f97d0db864 100644
--- a/libsycl/src/detail/device_impl.cpp
+++ b/libsycl/src/detail/device_impl.cpp
@@ -22,9 +22,7 @@ bool DeviceImpl::has(aspect Aspect) const {
   case (aspect::accelerator):
     return isAccelerator();
   case (aspect::custom):
-    return false;
   case (aspect::emulated):
-    return false;
   case (aspect::host_debuggable):
     return false;
   default:
@@ -49,7 +47,9 @@ bool DeviceImpl::isAccelerator() const {
   return getDeviceType() == info::device_type::accelerator;
 }
 
-backend DeviceImpl::getBackend() const { return MPlatform.getBackend(); }
+backend DeviceImpl::getBackend() const noexcept {
+  return MPlatform.getBackend();
+}
 
 } // namespace detail
 _LIBSYCL_END_NAMESPACE_SYCL
diff --git a/libsycl/src/detail/device_impl.hpp b/libsycl/src/detail/device_impl.hpp
index 5fd0893c99125..c83b767aad02f 100644
--- a/libsycl/src/detail/device_impl.hpp
+++ b/libsycl/src/detail/device_impl.hpp
@@ -65,7 +65,7 @@ class DeviceImpl {
   /// Returns the backend associated with this device.
   ///
   /// \return the sycl::backend associated with this device.
-  backend getBackend() const;
+  backend getBackend() const noexcept;
 
   /// Returns the implementation class object of platform associated with this
   /// device.
@@ -115,6 +115,8 @@ class DeviceImpl {
       static_assert(false && "Info descriptor is not properly supported");
   }
 
+  ol_device_handle_t getOLHandle() { return MOffloadDevice; }
+
 private:
   ol_device_handle_t MOffloadDevice = {};
   PlatformImpl &MPlatform;
diff --git a/libsycl/src/detail/offload/offload_utils.hpp b/libsycl/src/detail/offload/offload_utils.hpp
index f32326fb87fc9..e1795094f26a4 100644
--- a/libsycl/src/detail/offload/offload_utils.hpp
+++ b/libsycl/src/detail/offload/offload_utils.hpp
@@ -37,6 +37,10 @@ inline std::string formatCodeString(ol_result_t Result) {
          std::string(stringifyErrorCode(Result->Code)) + ") " + Result->Details;
 }
 
+inline bool isSuccess(const ol_result_t &Result) {
+  return Result == OL_SUCCESS;
+}
+
 /// Checks liboffload API call result.
 ///
 /// Used after calling the API without check.
@@ -48,7 +52,7 @@ inline std::string formatCodeString(ol_result_t Result) {
 /// \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) {
+  if (!isSuccess(Result)) {
     throw sycl::exception(sycl::make_error_code(errc),
                           detail::formatCodeString(Result));
   }
diff --git a/libsycl/src/detail/platform_impl.cpp b/libsycl/src/detail/platform_impl.cpp
index 0116ad68d4bdd..a09f9068a9dfd 100644
--- a/libsycl/src/detail/platform_impl.cpp
+++ b/libsycl/src/detail/platform_impl.cpp
@@ -9,6 +9,7 @@
 #include <sycl/__impl/detail/config.hpp>
 #include <sycl/__impl/detail/obj_utils.hpp>
 
+#include <detail/context_impl.hpp>
 #include <detail/device_impl.hpp>
 #include <detail/global_objects.hpp>
 #include <detail/platform_impl.hpp>
@@ -75,6 +76,8 @@ PlatformImpl::PlatformImpl(ol_platform_handle_t Platform, size_t PlatformIndex,
                   MRootDevices.emplace_back(std::make_unique<DeviceImpl>(
                       Device, *this, DeviceImpl::PrivateTag{}));
                 });
+
+  MDefaultContext = ContextImpl::create(*this);
 }
 
 const std::vector<DeviceImplUPtr> &PlatformImpl::getRootDevices() const {
@@ -119,5 +122,11 @@ void PlatformImpl::iterateDevices(
   }
 }
 
+ContextImpl &PlatformImpl::getDefaultContext() {
+  assert(MDefaultContext &&
+         "Default context for platform must be created in platform ctor");
+  return *MDefaultContext.get();
+}
+
 } // namespace detail
 _LIBSYCL_END_NAMESPACE_SYCL
diff --git a/libsycl/src/detail/platform_impl.hpp b/libsycl/src/detail/platform_impl.hpp
index e23ce6a492281..538bcc05dbc22 100644
--- a/libsycl/src/detail/platform_impl.hpp
+++ b/libsycl/src/detail/platform_impl.hpp
@@ -29,6 +29,7 @@ _LIBSYCL_BEGIN_NAMESPACE_SYCL
 namespace detail {
 
 class DeviceImpl;
+class ContextImpl;
 
 using PlatformImplUPtr = std::unique_ptr<PlatformImpl>;
 using DeviceImplUPtr = std::unique_ptr<DeviceImpl>;
@@ -121,15 +122,28 @@ class PlatformImpl {
   void iterateDevices(info::device_type DeviceType,
                       std::function<void(DeviceImpl *)> callback) const;
 
-private:
+  /// Returns all root devices for platform
+  ///
+  /// \return reference to collection of root devices
   const std::vector<DeviceImplUPtr> &getRootDevices() const;
 
-  ol_platform_handle_t MOffloadPlatform{};
-  size_t MOffloadPlatformIndex{};
-  ol_platform_backend_t MOffloadBackend{OL_PLATFORM_BACKEND_UNKNOWN};
-  backend MBackend{};
+  /// Returns context dummy (w/o liboffload handle) that represents all devices
+  /// in platform.
+  ///
+  /// \return context implementation object
+  ContextImpl &getDefaultContext();
+
+private:
+  const ol_platform_handle_t MOffloadPlatform{};
+  const size_t MOffloadPlatformIndex{};
+
+  ol_platform_backend_t MOffloadBackend;
+  backend MBackend;
 
   std::vector<DeviceImplUPtr> MRootDevices;
+
+  // To be redesigned  once liboffload supports context
+  std::shared_ptr<ContextImpl> MDefaultContext;
 };
 
 } // namespace detail
diff --git a/libsycl/src/device.cpp b/libsycl/src/device.cpp
index db61d2ff3a22e..a499919190db2 100644
--- a/libsycl/src/device.cpp
+++ b/libsycl/src/device.cpp
@@ -6,8 +6,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include <sycl/__impl/device.hpp>
-
 #include <detail/device_impl.hpp>
 #include <detail/platform_impl.hpp>
 
@@ -15,8 +13,6 @@
 
 _LIBSYCL_BEGIN_NAMESPACE_SYCL
 
-device::device() : device(default_selector_v) {}
-
 bool device::is_cpu() const { return impl->isCPU(); }
 
 bool device::is_gpu() const { return impl->isGPU(); }



More information about the llvm-branch-commits mailing list