Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions sycl/gdb/libsycl.so-gdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -374,14 +374,14 @@ def range_common_array(self):
class SYCLDevice(SYCLValue):
"""Provides information about a sycl::device from a gdb.Value."""

IMPL_OFFSET_TO_PLATFORM = 0x18
IMPL_OFFSET_TO_PLATFORM = 0x8
PLATFORM_OFFSET_TO_BACKEND = 0x20

def __init__(self, gdb_value):
super().__init__(gdb_value)

def impl_ptr(self):
return self.gdb_value()["impl"]["_M_ptr"]
return self.gdb_value()["impl"]

def backend(self):
char_ptr = SYCLType.char_type().pointer()
Expand Down
23 changes: 18 additions & 5 deletions sycl/include/sycl/device.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,14 @@ enum class peer_access {
access_supported = 0x0,
atomics_supported = 0x1,
};

template <typename SYCLObjT> class weak_object;
} // namespace ext::oneapi

/// The SYCL device class encapsulates a single SYCL device on which kernels
/// may be executed.
///
/// \ingroup sycl_api
class __SYCL_STANDALONE_DEBUG __SYCL_EXPORT device
: public detail::OwnerLessBase<device> {
class __SYCL_STANDALONE_DEBUG __SYCL_EXPORT device {
friend sycl::detail::ImplUtils;

public:
Expand Down Expand Up @@ -93,6 +92,12 @@ class __SYCL_STANDALONE_DEBUG __SYCL_EXPORT device
/// \param DeviceSelector is SYCL 2020 Device Selector, a simple callable that
/// takes a device and returns an int
template <typename DeviceSelector,
// `device_impl` (used as a parameter in private ctor) is incomplete
// so would result in a error trying to instantiate
// `EnableIfSYCL2020DeviceSelectorInvocable` below. Filter it out
// before trying to do that.
typename = std::enable_if_t<
!std::is_same_v<DeviceSelector, detail::device_impl>>,
typename =
detail::EnableIfSYCL2020DeviceSelectorInvocable<DeviceSelector>>
explicit device(const DeviceSelector &deviceSelector)
Expand Down Expand Up @@ -361,14 +366,22 @@ class __SYCL_STANDALONE_DEBUG __SYCL_EXPORT device
/// \return the default context
context ext_oneapi_get_default_context();

// Definitions are in `<sycl/ext/oneapi/weak_object.hpp>` to avoid circular
// dependencies:
inline bool ext_oneapi_owner_before(const device &Other) const noexcept;
inline bool ext_oneapi_owner_before(
const ext::oneapi::weak_object<device> &Other) const noexcept;

// TODO: Remove this diagnostics when __SYCL_WARN_IMAGE_ASPECT is removed.
#if defined(__clang__)
#pragma clang diagnostic pop
#endif // defined(__clang__)

private:
std::shared_ptr<detail::device_impl> impl;
device(std::shared_ptr<detail::device_impl> Impl) : impl(std::move(Impl)) {}
// `device_impl`s are owned by the parent platform, user-visible
// `sycl::device` is non-owning and thus very cheap.
detail::device_impl *impl = nullptr;
device(detail::device_impl &impl) : impl(&impl) {}

ur_native_handle_t getNative() const;

Expand Down
3 changes: 2 additions & 1 deletion sycl/include/sycl/ext/oneapi/backend/level_zero.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,8 @@ inline device make_device<backend::ext_oneapi_level_zero>(
continue;

for (auto &d : p.get_devices()) {
if (auto maybe_device = find_matching_descendent_device(d, BackendObject))
if (auto maybe_device =
detail::find_matching_descendent_device(d, BackendObject))
return *maybe_device;
}
}
Expand Down
11 changes: 3 additions & 8 deletions sycl/include/sycl/ext/oneapi/experimental/current_device.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,8 @@ namespace ext::oneapi::experimental::this_thread {

namespace detail {
using namespace sycl::detail;
// Underlying `std::shared_ptr<device_impl>`'s lifetime is tied to the
// `global_handler`, so a subsequent `lock()` is expected to be successful when
// used from user app. We still go through `std::weak_ptr` here because our own
// unittests are linked statically against SYCL RT objects and have to implement
// some hacks to emulate the lifetime management done by the `global_handler`.
inline std::weak_ptr<device_impl> &get_current_device_impl() {
static thread_local std::weak_ptr<device_impl> current_device{
inline device_impl *&get_current_device_impl() {
static thread_local device_impl *current_device{
getSyclObjImpl(sycl::device{sycl::default_selector_v})};
return current_device;
}
Expand All @@ -36,7 +31,7 @@ inline std::weak_ptr<device_impl> &get_current_device_impl() {
/// task or an asynchronous error handler.
inline sycl::device get_current_device() {
return detail::createSyclObjFromImpl<device>(
detail::get_current_device_impl().lock());
*detail::get_current_device_impl());
}

/// @brief Sets the current default device to `dev` for the calling host thread.
Expand Down
61 changes: 61 additions & 0 deletions sycl/include/sycl/ext/oneapi/weak_object.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,67 @@ class weak_object<stream> : public detail::weak_object_base<stream> {
weak_object<detail::GlobalBufAccessorT> MWeakGlobalFlushBuf;
};

template <> class weak_object<device> {
friend sycl::device;

detail::device_impl *dev_impl = nullptr;

public:
using object_type = device;

constexpr weak_object() noexcept = default;
weak_object(const device &dev) noexcept
: dev_impl(detail::getSyclObjImpl(dev)) {}
weak_object(const weak_object &Other) noexcept = default;
weak_object(weak_object &&Other) noexcept = default;

weak_object &operator=(const device &Other) noexcept {
this->dev_impl = detail::getSyclObjImpl(Other);
return *this;
}
weak_object &operator=(const weak_object &Other) noexcept = default;
weak_object &operator=(weak_object &&Other) noexcept = default;

bool expired() const noexcept { return dev_impl == nullptr; }

void reset() noexcept { dev_impl = nullptr; }

#ifndef __SYCL_DEVICE_ONLY__
std::optional<device> try_lock() const noexcept {
if (!dev_impl)
return std::nullopt;
return sycl::detail::createSyclObjFromImpl<device>(*dev_impl);
}
device lock() const {
std::optional<device> OptionalObj = try_lock();
if (!OptionalObj)
throw sycl::exception(sycl::make_error_code(sycl::errc::invalid),
"Referenced object has expired.");
return *OptionalObj;
}
bool owner_before(const device &Other) const noexcept {
return dev_impl < detail::getSyclObjImpl(Other);
}
bool owner_before(const weak_object &Other) const noexcept {
return dev_impl < Other.dev_impl;
}
#else
// On device calls to these functions are disallowed, so declare them but
// don't define them to avoid compilation failures.
std::optional<device> try_lock() const noexcept;
device lock() const;
bool owner_before(const device &Other) const noexcept;
bool owner_before(const weak_object &Other) const noexcept;
#endif // __SYCL_DEVICE_ONLY__
};
} // namespace ext::oneapi
inline bool
device::ext_oneapi_owner_before(const device &Other) const noexcept {
return impl < Other.impl;
}
inline bool device::ext_oneapi_owner_before(
const ext::oneapi::weak_object<device> &Other) const noexcept {
return impl < Other.dev_impl;
}
} // namespace _V1
} // namespace sycl
4 changes: 2 additions & 2 deletions sycl/include/sycl/interop_handle.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ class interop_handle {
#endif
interop_handle(std::vector<ReqToMem> MemObjs,
const std::shared_ptr<detail::queue_impl> &Queue,
const std::shared_ptr<detail::device_impl> &Device,
detail::device_impl &Device,
const std::shared_ptr<detail::context_impl> &Context,
ur_exp_command_buffer_handle_t Graph = nullptr)
: MQueue(Queue), MDevice(Device), MContext(Context), MGraph(Graph),
Expand Down Expand Up @@ -243,7 +243,7 @@ class interop_handle {
__SYCL_EXPORT ur_native_handle_t getNativeGraph() const;

std::shared_ptr<detail::queue_impl> MQueue;
std::shared_ptr<detail::device_impl> MDevice;
detail::device_impl &MDevice;
std::shared_ptr<detail::context_impl> MContext;
ur_exp_command_buffer_handle_t MGraph;

Expand Down
3 changes: 1 addition & 2 deletions sycl/source/detail/context_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,7 @@ class context_impl : public std::enable_shared_from_this<context_impl> {
return false;
}
CurrDevice = detail::getSyclObjImpl(
CurrDevice->get_info<info::device::parent_device>())
.get();
CurrDevice->get_info<info::device::parent_device>());
}

return true;
Expand Down
2 changes: 1 addition & 1 deletion sycl/source/detail/device_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ template <ur_device_info_t Desc>
using ur_ret_type = decltype(ur_ret_type_impl<Desc>());

// TODO: Make code thread-safe
class device_impl : public std::enable_shared_from_this<device_impl> {
class device_impl {
struct private_tag {
explicit private_tag() = default;
};
Expand Down
18 changes: 16 additions & 2 deletions sycl/source/detail/platform_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,20 @@ namespace sycl {
inline namespace _V1 {
namespace detail {

platform_impl::platform_impl(ur_platform_handle_t APlatform,
adapter_impl &Adapter)
: MPlatform(APlatform), MAdapter(&Adapter) {

// Find out backend of the platform
ur_backend_t UrBackend = UR_BACKEND_UNKNOWN;
Adapter.call_nocheck<UrApiKind::urPlatformGetInfo>(
APlatform, UR_PLATFORM_INFO_BACKEND, sizeof(ur_backend_t), &UrBackend,
nullptr);
MBackend = convertUrBackend(UrBackend);
}

platform_impl::~platform_impl() = default;

Comment on lines +33 to +46
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needed to move to .cpp because it now needs a "complete" device_impl type for MDevices.

platform_impl &
platform_impl::getOrMakePlatformImpl(ur_platform_handle_t UrPlatform,
adapter_impl &Adapter) {
Expand Down Expand Up @@ -266,7 +280,7 @@ device_impl &platform_impl::getOrMakeDeviceImpl(ur_device_handle_t UrDevice) {
return *Result;

// Otherwise make the impl
MDevices.emplace_back(std::make_shared<device_impl>(
MDevices.emplace_back(std::make_unique<device_impl>(
UrDevice, *this, device_impl::private_tag{}));

return *MDevices.back();
Expand Down Expand Up @@ -568,7 +582,7 @@ bool platform_impl::has(aspect Aspect) const {
}

device_impl *platform_impl::getDeviceImplHelper(ur_device_handle_t UrDevice) {
for (const std::shared_ptr<device_impl> &Device : MDevices) {
for (const std::unique_ptr<device_impl> &Device : MDevices) {
if (Device->getHandleRef() == UrDevice)
return Device.get();
}
Expand Down
15 changes: 3 additions & 12 deletions sycl/source/detail/platform_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,9 @@ class platform_impl : public std::enable_shared_from_this<platform_impl> {
//
// Platforms can only be created under `GlobalHandler`'s ownership via
// `platform_impl::getOrMakePlatformImpl` method.
explicit platform_impl(ur_platform_handle_t APlatform, adapter_impl &Adapter)
: MPlatform(APlatform), MAdapter(&Adapter) {

// Find out backend of the platform
ur_backend_t UrBackend = UR_BACKEND_UNKNOWN;
Adapter.call_nocheck<UrApiKind::urPlatformGetInfo>(
APlatform, UR_PLATFORM_INFO_BACKEND, sizeof(ur_backend_t), &UrBackend,
nullptr);
MBackend = convertUrBackend(UrBackend);
}
explicit platform_impl(ur_platform_handle_t APlatform, adapter_impl &Adapter);

~platform_impl() = default;
~platform_impl();

public:
/// Checks if this platform supports extension.
Expand Down Expand Up @@ -221,7 +212,7 @@ class platform_impl : public std::enable_shared_from_this<platform_impl> {

adapter_impl *MAdapter;

std::vector<std::shared_ptr<device_impl>> MDevices;
std::vector<std::unique_ptr<device_impl>> MDevices;
friend class GlobalHandler;
std::mutex MDeviceMapMutex;
};
Expand Down
2 changes: 1 addition & 1 deletion sycl/source/detail/program_manager/program_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2470,7 +2470,7 @@ device_image_plain ProgramManager::getDeviceImageFromBinaryImage(
const device &Dev) {
const bundle_state ImgState = getBinImageState(BinImage);

assert(compatibleWithDevice(BinImage, *getSyclObjImpl(Dev).get()));
assert(compatibleWithDevice(BinImage, *getSyclObjImpl(Dev)));

std::shared_ptr<std::vector<sycl::kernel_id>> KernelIDs;
// Collect kernel names for the image.
Expand Down
7 changes: 3 additions & 4 deletions sycl/source/detail/scheduler/commands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,7 @@ class DispatchHostTask {
assert(HostTask.MQueue &&
"Host task submissions should have an associated queue");
interop_handle IH{MReqToMem, HostTask.MQueue,
HostTask.MQueue->getDeviceImpl().shared_from_this(),
HostTask.MQueue->getDeviceImpl(),
HostTask.MQueue->getContextImpl().shared_from_this()};
// TODO: should all the backends that support this entry point use this
// for host task?
Expand Down Expand Up @@ -3163,8 +3163,7 @@ ur_result_t ExecCGCommand::enqueueImpCommandBuffer() {

ur_exp_command_buffer_handle_t InteropCommandBuffer =
ChildCommandBuffer ? ChildCommandBuffer : MCommandBuffer;
interop_handle IH{std::move(ReqToMem), MQueue,
DeviceImpl.shared_from_this(),
interop_handle IH{std::move(ReqToMem), MQueue, DeviceImpl,
ContextImpl.shared_from_this(), InteropCommandBuffer};
CommandBufferNativeCommandData CustomOpData{
std::move(IH), HostTask->MHostTask->MInteropTask};
Expand Down Expand Up @@ -3539,7 +3538,7 @@ ur_result_t ExecCGCommand::enqueueImpQueue() {

EnqueueNativeCommandData CustomOpData{
interop_handle{std::move(ReqToMem), HostTask->MQueue,
HostTask->MQueue->getDeviceImpl().shared_from_this(),
HostTask->MQueue->getDeviceImpl(),
HostTask->MQueue->getContextImpl().shared_from_this()},
HostTask->MHostTask->MInteropTask};

Expand Down
2 changes: 1 addition & 1 deletion sycl/source/detail/usm/usm_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ void *alignedAlloc(size_t Alignment, size_t Size, const context &Ctxt,
#endif
void *RetVal =
alignedAllocInternal(Alignment, Size, getSyclObjImpl(Ctxt).get(),
getSyclObjImpl(Dev).get(), Kind, PropList);
getSyclObjImpl(Dev), Kind, PropList);
#ifdef XPTI_ENABLE_INSTRUMENTATION
// Once the allocation is complete, update metadata with the memory pointer
// before the mem_alloc_end event is sent
Expand Down
9 changes: 6 additions & 3 deletions sycl/source/device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@
#include <sycl/device_selector.hpp>
#include <sycl/info/info_desc.hpp>

// Trying to force MSVC to generate the symbol/export for the inline function
// that it needs on the import (because the class itself is being exported):
#include <sycl/ext/oneapi/weak_object.hpp>

namespace sycl {
inline namespace _V1 {
namespace detail {
Expand All @@ -41,9 +45,8 @@ device::device(cl_device_id DeviceId) {
Adapter.call<detail::UrApiKind::urDeviceCreateWithNativeHandle>(
detail::ur::cast<ur_native_handle_t>(DeviceId), Adapter.getUrAdapter(),
nullptr, &Device);
impl = detail::platform_impl::getPlatformFromUrDevice(Device, Adapter)
.getOrMakeDeviceImpl(Device)
.shared_from_this();
impl = &detail::platform_impl::getPlatformFromUrDevice(Device, Adapter)
.getOrMakeDeviceImpl(Device);
__SYCL_OCL_CALL(clRetainDevice, DeviceId);
}

Expand Down
2 changes: 1 addition & 1 deletion sycl/source/device_selector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ namespace detail {
// itself, so only matching devices will be scored.
static int getDevicePreference(const device &Device) {
int Score = 0;
const device_impl &DeviceImpl = *getSyclObjImpl(Device).get();
const device_impl &DeviceImpl = *getSyclObjImpl(Device);
// Strongly prefer devices with available images.
auto &program_manager = sycl::detail::ProgramManager::getInstance();
if (program_manager.hasCompatibleImage(DeviceImpl))
Expand Down
4 changes: 2 additions & 2 deletions sycl/source/interop_handle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,12 @@ interop_handle::getNativeMem(detail::Requirement *Req) const {
detail::adapter_impl &Adapter = MQueue->getAdapter();
ur_native_handle_t Handle;
Adapter.call<detail::UrApiKind::urMemGetNativeHandle>(
Iter->second, MDevice->getHandleRef(), &Handle);
Iter->second, MDevice.getHandleRef(), &Handle);
return Handle;
}

ur_native_handle_t interop_handle::getNativeDevice() const {
return MDevice->getNative();
return MDevice.getNative();
}

ur_native_handle_t interop_handle::getNativeContext() const {
Expand Down
2 changes: 1 addition & 1 deletion sycl/source/kernel_bundle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ std::vector<kernel_id> get_kernel_ids() {
}

bool is_compatible(const std::vector<kernel_id> &KernelIDs, const device &Dev) {
return detail::is_compatible(KernelIDs, *getSyclObjImpl(Dev));
return detail::is_compatible(KernelIDs, *detail::getSyclObjImpl(Dev));
}

/////////////////////////
Expand Down
2 changes: 1 addition & 1 deletion sycl/source/physical_mem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ physical_mem::physical_mem(const device &SyclDevice, const context &SyclContext,
"Device does not support aspect::ext_oneapi_virtual_mem.");

impl = std::make_shared<sycl::detail::physical_mem_impl>(
*getSyclObjImpl(SyclDevice), SyclContext, NumBytes);
*detail::getSyclObjImpl(SyclDevice), SyclContext, NumBytes);
}

void *physical_mem::map(uintptr_t Ptr, size_t NumBytes,
Expand Down
Loading