blob: 2b01e911aa603cb0bdcf3592075685bde8797853 [file] [edit]
//===----------------------------------------------------------------------===//
//
// 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 ContextImpl class, which
/// implements sycl::context functionality.
///
//===----------------------------------------------------------------------===//
#ifndef _LIBSYCL_CONTEXT_IMPL
#define _LIBSYCL_CONTEXT_IMPL
#include <sycl/__impl/async_handler.hpp>
#include <sycl/__impl/context.hpp>
#include <sycl/__impl/detail/config.hpp>
#include <detail/device_image_wrapper.hpp>
#include <OffloadAPI.h>
#include <functional>
#include <mutex>
#include <string_view>
#include <unordered_map>
_LIBSYCL_BEGIN_NAMESPACE_SYCL
class property_list;
namespace detail {
class PlatformImpl;
class DeviceImpl;
/// Context represents the runtime data structures and state required by a SYCL
/// backend API to interact with a group of devices associated with a platform.
class ContextImpl : public std::enable_shared_from_this<ContextImpl> {
struct Private {
explicit Private() = default;
};
public:
/// Constructs a context implementation for the provided devices.
///
/// \param DeviceList is the list of devices associated with this context.
/// \param AsyncHandler is a SYCL asynchronous exception handler.
/// \param PropList is a list of context properties.
ContextImpl(std::vector<DeviceImpl *> &&DeviceList,
const async_handler &AsyncHandler, const property_list &PropList,
Private);
/// Releases the underlying offload context handle.
~ContextImpl();
/// Gets asynchronous exception handler.
///
/// \return an instance of SYCL async_handler.
const async_handler &get_async_handler() const { return MAsyncHandler; }
/// 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 the raw underlying offload context handle.
///
/// The caller is responsible for ensuring that the returned handle is only
/// used while this ContextImpl object is alive.
///
/// \return the raw offload context handle.
const ol_context_handle_t &getOLHandleRef() const { return MOffloadContext; }
/// \return the platform this context is associated with.
PlatformImpl &getPlatformImpl() const;
/// Calls "callback" with every device associated
/// with this context.
void iterateDevices(const std::function<void(DeviceImpl *)> &callback) const;
/// \return backend of the platform this context is associated with.
backend getBackend() const;
/// Returns the liboffload kernel symbol for the specified kernel, taken from
/// the program built in this context from the specified device image for the
/// specified device. Creates the program on first use.
/// This method is thread-safe.
/// \param DeviceImage the device image containing the kernel's device code.
/// \param DeviceHandle the liboffload handle of the device the program must
/// be compatible with.
/// \param KernelName the name of the kernel to look up.
/// \throw sycl::exception with sycl::errc::runtime when program creation or
/// symbol lookup fails.
/// \return the liboffload symbol handle of the kernel.
ol_symbol_handle_t getOrCreateKernel(const DeviceImageManager &DeviceImage,
ol_device_handle_t DeviceHandle,
std::string_view KernelName);
/// Destroys every program in this context that was created from the specified
/// device image, together with the kernel symbols taken from them. Called
/// while the image is being unregistered, before it is destroyed.
/// This method is thread-safe.
/// \param DeviceImage the device image whose programs must be released.
void releaseProgramsForImage(const DeviceImageManager &DeviceImage);
/// Destroys every program in this context, together with the kernel symbols
/// taken from them.
/// This method is thread-safe.
void releaseAllPrograms();
private:
const async_handler MAsyncHandler;
const std::vector<DeviceImpl *> MDevices;
ol_context_handle_t MOffloadContext{};
// TODO: later to replace with efficient kernel & program cache impl.
std::mutex MProgramCacheMutex;
using ProgramsByDeviceT =
std::unordered_map<ol_device_handle_t, ProgramWrapper>;
std::unordered_map<const DeviceImageManager *, ProgramsByDeviceT> MPrograms;
};
} // namespace detail
_LIBSYCL_END_NAMESPACE_SYCL
#endif // _LIBSYCL_CONTEXT_IMPL