blob: f5012fe84c069bc75dba2999875af75b6e79a50c [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 DeviceImpl class, which implements
/// sycl::device functionality.
///
//===----------------------------------------------------------------------===//
#ifndef _LIBSYCL_DEVICE_IMPL
#define _LIBSYCL_DEVICE_IMPL
#include <sycl/__impl/detail/config.hpp>
#include <sycl/__impl/device.hpp>
#include <detail/offload/offload_utils.hpp>
#include <detail/platform_impl.hpp>
#include <OffloadAPI.h>
_LIBSYCL_BEGIN_NAMESPACE_SYCL
namespace detail {
class DeviceImpl {
// Helper to limit DeviceImpl creation. It must be created in platform ctor
// only. Using tag instead of private ctor + friend class to allow make_unique
// usage and to align with classes which impl is shared_ptr<>.
struct PrivateTag {
explicit PrivateTag() = default;
};
friend class PlatformImpl;
public:
/// Constructs a SYCL device instance using the provided
/// offload device instance.
///
/// \param Device is a raw offload library handle representing device.
/// \param Platform is a platform this device belongs to.
/// All device impls must be created in corresponding platform ctor.
explicit DeviceImpl(ol_device_handle_t Device, PlatformImpl &Platform,
PrivateTag)
: MOffloadDevice(Device), MPlatform(Platform) {}
~DeviceImpl() = default;
/// Queries device type from offloading runtime
///
/// \return device type of the device
info::device_type getDeviceType() const;
/// Check if device is a CPU device
///
/// \return true if SYCL device is a CPU device
bool isCPU() const;
/// Check if device is a GPU device
///
/// \return true if SYCL device is a GPU device
bool isGPU() const;
/// Check if device is an accelerator device
///
/// \return true if SYCL device is an accelerator device
bool isAccelerator() const;
/// Returns the backend associated with this device.
///
/// \return the sycl::backend associated with this device.
backend getBackend() const noexcept;
/// Returns the implementation class object of platform associated with this
/// device.
///
/// \return platform implementation object this device belongs to.
PlatformImpl &getPlatformImpl() const { return MPlatform; }
/// Checks if this device supports aspect.
///
/// \param Aspect to perform a check of.
/// \return true if this device has the given aspect.
bool has(aspect Aspect) const;
/// Queries this device for information requested by the template parameter
/// param.
/// The return type depends on information being queried.
template <typename Param> typename Param::return_type getInfo() const {
using namespace info::device;
using Map = info_ol_mapping<ol_device_info_t>;
constexpr ol_device_info_t olInfo = map_info_desc<Param, ol_device_info_t>(
Map::M<device_type>{OL_DEVICE_INFO_TYPE},
Map::M<name>{OL_DEVICE_INFO_NAME},
Map::M<vendor>{OL_DEVICE_INFO_VENDOR},
Map::M<driver_version>{OL_DEVICE_INFO_DRIVER_VERSION});
size_t ExpectedSize = 0;
callAndThrow(olGetDeviceInfoSize, MOffloadDevice, olInfo, &ExpectedSize);
if constexpr (std::is_same_v<typename Param::return_type, std::string>) {
std::string Result;
// liboffload counts null terminator in the size while std::string
// doesn't.
Result.resize(ExpectedSize - 1);
callAndThrow(olGetDeviceInfo, MOffloadDevice, olInfo, ExpectedSize,
Result.data());
return Result;
} else if constexpr (olInfo == OL_DEVICE_INFO_TYPE) {
assert((sizeof(typename Param::return_type) == ExpectedSize) &&
"Size of info descriptor reported by backend doesn't match with "
"expected.");
ol_device_type_t olType{};
callAndThrow(olGetDeviceInfo, MOffloadDevice, olInfo, sizeof(olType),
&olType);
return convertDeviceTypeToSYCL(olType);
} else
static_assert(false && "Info descriptor is not properly supported");
}
/// \return the corresponding liboffload device handle.
ol_device_handle_t getOLHandle() const { return MOffloadDevice; }
private:
ol_device_handle_t MOffloadDevice = {};
PlatformImpl &MPlatform;
};
} // namespace detail
_LIBSYCL_END_NAMESPACE_SYCL
#endif // _LIBSYCL_DEVICE_IMPL