24 #include <unordered_set>
28 inline namespace _V1 {
44 const std::lock_guard<std::mutex> Guard(
47 std::vector<PlatformImplPtr> &PlatformCache =
51 for (
const auto &PlatImpl : PlatformCache) {
57 Result = std::make_shared<platform_impl>(
PiPlatform, Plugin);
58 PlatformCache.emplace_back(Result);
71 sizeof(Plt), &Plt,
nullptr);
87 auto IsMatchingOpenCL = [](
platform Platform,
const std::string_view name) {
91 const bool HasNameMatch = Platform.
get_info<info::platform::name>().find(
92 name) != std::string::npos;
94 const bool IsMatchingOCL = (HasNameMatch && Backend ==
backend::opencl);
97 std::cout <<
"SYCL_PI_TRACE[all]: " << name
98 <<
" OpenCL platform found but is not compatible." << std::endl;
100 return IsMatchingOCL;
102 return IsMatchingOpenCL(Platform,
"NVIDIA CUDA") ||
103 IsMatchingOpenCL(Platform,
"AMD Accelerated Parallel Processing");
111 auto getPluginPlatforms = [](
PluginPtr &Plugin) {
112 std::vector<platform> Platforms;
115 0,
nullptr, &NumPlatforms) != PI_SUCCESS)
119 std::vector<sycl::detail::pi::PiPlatform> PiPlatforms(NumPlatforms);
121 NumPlatforms, PiPlatforms.data(),
nullptr) != PI_SUCCESS)
125 platform Platform = detail::createSyclObjFromImpl<platform>(
136 Platforms.push_back(Platform);
143 static const bool PreferUR = [] {
144 const char *PreferURStr = std::getenv(
"SYCL_PREFER_UR");
145 return (PreferURStr && (std::stoi(PreferURStr) != 0));
151 std::vector<std::pair<platform, PluginPtr>> PlatformsWithPlugin;
155 std::unordered_set<backend> BackendsUR;
165 for (
const auto &P : getPluginPlatforms(*PluginUR)) {
166 PlatformsWithPlugin.push_back({P, *PluginUR});
173 for (
auto &Plugin : Plugins) {
177 const auto &PluginPlatforms = getPluginPlatforms(Plugin);
178 for (
const auto &P : PluginPlatforms) {
182 PlatformsWithPlugin.push_back({P, Plugin});
188 std::vector<platform> Platforms;
189 for (
auto &Platform : PlatformsWithPlugin) {
190 auto &Plugin = Platform.second;
191 std::lock_guard<std::mutex> Guard(*Plugin->getPluginMutex());
192 Plugin->getPlatformId(
getSyclObjImpl(Platform.first)->getHandleRef());
193 Platforms.push_back(Platform.first);
215 template <
typename ListT,
typename FilterT>
216 std::vector<int> platform_impl::filterDeviceFilter(
217 std::vector<sycl::detail::pi::PiDevice> &PiDevices,
218 ListT *FilterList)
const {
220 constexpr
bool is_ods_target = std::is_same_v<FilterT, ods_target>;
222 if constexpr (is_ods_target) {
230 std::sort(FilterList->get().begin(), FilterList->get().end(),
232 return filter1.IsNegativeTarget && !filter2.IsNegativeTarget;
240 std::map<int, bool> Blacklist;
243 std::vector<int> original_indices;
255 std::lock_guard<std::mutex> Guard(*MPlugin->getPluginMutex());
256 int DeviceNum = MPlugin->getStartingDeviceId(MPlatform);
261 &PiDevType,
nullptr);
266 for (
const FilterT &Filter : FilterList->get()) {
269 if (FilterBackend != Backend && FilterBackend !=
backend::all)
275 if (Filter.DeviceNum && DeviceNum != Filter.DeviceNum.value())
279 FilterDevType != DeviceType)
282 if constexpr (is_ods_target) {
284 if (Blacklist[DeviceNum])
287 if (Filter.IsNegativeTarget) {
290 Blacklist[DeviceNum] =
true;
295 PiDevices[InsertIDx++] = Device;
296 original_indices.push_back(DeviceNum);
301 PiDevices.resize(InsertIDx);
305 MPlugin->setLastDeviceId(MPlatform, DeviceNum);
306 return original_indices;
309 std::shared_ptr<device_impl>
311 const std::lock_guard<std::mutex> Guard(MDeviceMapMutex);
312 return getDeviceImplHelper(
PiDevice);
317 const std::shared_ptr<platform_impl> &PlatformImpl) {
318 const std::lock_guard<std::mutex> Guard(MDeviceMapMutex);
320 std::shared_ptr<device_impl> Result = getDeviceImplHelper(
PiDevice);
325 Result = std::make_shared<device_impl>(
PiDevice, PlatformImpl);
326 MDeviceCache.emplace_back(Result);
337 auto supported = dev.
get_info<info::device::partition_affinity_domains>();
338 auto It = std::find(std::begin(supported), std::end(supported), domain);
339 return It != std::end(supported);
344 auto supported = dev.
get_info<info::device::partition_properties>();
346 std::find(std::begin(supported), std::end(supported), partitionProp);
347 return It != std::end(supported);
351 backend PlatformBackend, std::vector<device> &DeviceList,
352 ods_target_list *OdsTargetList,
const std::vector<int> &original_indices,
359 std::vector<device> FinalResult;
364 for (
unsigned i = 0; i < DeviceList.size(); i++) {
367 device &dev = DeviceList[i];
368 bool deviceAdded =
false;
371 if (PlatformBackend != TargetBackend && TargetBackend !=
backend::all)
374 bool deviceMatch =
target.HasDeviceWildCard;
380 }
else if (
target.DeviceNum) {
381 deviceMatch = (
target.DeviceNum.value() == original_indices[i]);
388 bool wantSubDevice =
target.SubDeviceNum ||
target.HasSubDeviceWildCard;
389 bool supportsSubPartitioning =
392 bool wantSubSubDevice =
393 target.SubSubDeviceNum ||
target.HasSubSubDeviceWildCard;
395 if (!wantSubDevice) {
398 FinalResult.push_back(dev);
404 if (!supportsSubPartitioning) {
418 if (
target.SubDeviceNum) {
419 if (subDevices.size() <=
target.SubDeviceNum.value()) {
423 subDevices[0] = subDevices[
target.SubDeviceNum.value()];
424 subDevices.resize(1);
427 if (!wantSubSubDevice) {
429 FinalResult.insert(FinalResult.end(), subDevices.begin(),
435 for (
device subDev : subDevices) {
436 bool supportsSubSubPartitioning =
439 if (!supportsSubSubPartitioning) {
440 if (
target.SubDeviceNum) {
451 subDev.create_sub_devices<partitionProperty>(affinityDomain);
452 if (
target.SubSubDeviceNum) {
453 if (subSubDevices.size() <=
target.SubSubDeviceNum.value()) {
458 subSubDevices[0] = subSubDevices[
target.SubSubDeviceNum.value()];
459 subSubDevices.resize(1);
461 FinalResult.insert(FinalResult.end(), subSubDevices.begin(),
462 subSubDevices.end());
471 std::vector<device> Res;
488 MPlatform, pi::cast<sycl::detail::pi::PiDeviceType>(DeviceType),
490 pi::cast<sycl::detail::pi::PiDevice *>(
nullptr), &NumDevices);
493 if (NumDevices == 0) {
500 auto It = std::find_if(Plugins.begin(), Plugins.end(),
501 [&Platform = MPlatform](
PluginPtr &Plugin) {
502 return Plugin->containsPiPlatform(Platform);
504 if (It != Plugins.end()) {
506 std::lock_guard<std::mutex> Guard(*Plugin->getPluginMutex());
507 Plugin->adjustLastDeviceId(MPlatform);
512 std::vector<sycl::detail::pi::PiDevice> PiDevices(NumDevices);
516 pi::cast<sycl::detail::pi::PiDeviceType>(
518 NumDevices, PiDevices.data(),
nullptr);
522 std::vector<sycl::detail::pi::PiDevice> PiDevicesToCleanUp = PiDevices;
531 std::vector<int> PlatformDeviceIndices;
533 PlatformDeviceIndices = filterDeviceFilter<ods_target_list, ods_target>(
534 PiDevices, OdsTargetList);
541 PiDevices.begin(), PiDevices.end(), std::back_inserter(Res),
543 return detail::createSyclObjFromImpl<device>(
544 PlatformImpl->getOrMakeDeviceImpl(PiDevice, PlatformImpl));
555 if (!OdsTargetList || Res.size() == 0)
561 PlatformDeviceIndices, PlatformImpl);
571 return (AllExtensionNames.find(ExtensionName) != std::string::npos);
587 template <
typename Param>
590 return get_platform_info_host<Param>();
596 typename info::platform::version::return_type
597 platform_impl::get_backend_info<info::platform::version>()
const {
600 "the info::platform::version info descriptor can "
601 "only be queried with an OpenCL backend");
603 return get_info<info::platform::version>();
607 std::vector<device> &Devices);
610 typename info::device::version::return_type
611 platform_impl::get_backend_info<info::device::version>()
const {
614 "the info::device::version info descriptor can only "
615 "be queried with an OpenCL backend");
617 auto Devices = get_devices();
618 if (Devices.empty()) {
619 return "No available device";
627 typename info::device::backend_version::return_type
628 platform_impl::get_backend_info<info::device::backend_version>()
const {
631 "the info::device::backend_version info descriptor "
632 "can only be queried with a Level Zero backend");
643 if (dev.has(Aspect) ==
false) {
650 std::shared_ptr<device_impl>
652 for (
const std::weak_ptr<device_impl> &DeviceWP : MDeviceCache) {
653 if (std::shared_ptr<device_impl> Device = DeviceWP.lock()) {
654 if (Device->getHandleRef() ==
PiDevice)
661 #define __SYCL_PARAM_TRAITS_SPEC(DescType, Desc, ReturnT, PiCode) \
662 template ReturnT platform_impl::get_info<info::platform::Desc>() const;
664 #include <sycl/info/platform_traits.def>
665 #undef __SYCL_PARAM_TRAITS_SPEC
static void registerDefaultContextReleaseHandler()
std::vector< PlatformImplPtr > & getPlatformCache()
static GlobalHandler & instance()
static const char * get()
static std::shared_ptr< device_impl > getHostDeviceImpl()
Gets the single instance of the Host Device.
std::vector< ods_target > & get()
The SYCL device class encapsulates a single SYCL device on which kernels may be executed.
std::vector< device > create_sub_devices(size_t ComputeUnits) const
Partition device into sub devices.
detail::is_device_info_desc< Param >::return_type get_info() const
Queries this SYCL device for information requested by the template parameter param.
class __SYCL2020_DEPRECATED("Host device is no longer supported.") host_selector int default_selector_v(const device &dev)
Selects SYCL host device.
__SYCL_EXTERN_STREAM_ATTRS ostream cout
Linked to standard output.
std::vector< PluginPtr > & initialize()
::pi_device_type PiDeviceType
bool trace(TraceLevel level)
::pi_platform_backend PiPlatformBackend
backend convertBackend(pi_platform_backend PiBackend)
static std::vector< device > amendDeviceAndSubDevices(backend PlatformBackend, std::vector< device > &DeviceList, ods_target_list *OdsTargetList, const std::vector< int > &original_indices, PlatformImplPtr PlatformImpl)
static bool supportsPartitionProperty(const device &dev, info::partition_property partitionProp)
decltype(Obj::impl) getSyclObjImpl(const Obj &SyclObject)
std::string get_platform_info_string_impl(sycl::detail::pi::PiPlatform Plt, const PluginPtr &Plugin, pi_platform_info PiCode)
std::function< int(const sycl::device &)> DSelectorInvocableType
device select_device(const DSelectorInvocableType &DeviceSelectorInvocable)
std::shared_ptr< plugin > PluginPtr
std::shared_ptr< detail::platform_impl > PlatformImplPtr
static bool supportsAffinityDomain(const device &dev, info::partition_property partitionProp, info::partition_affinity_domain domain)
void applyAllowList(std::vector< sycl::detail::pi::PiDevice > &PiDevices, sycl::detail::pi::PiPlatform PiPlatform, const PluginPtr &Plugin)
static bool IsBannedPlatform(platform Platform)
partition_affinity_domain
@ partition_by_affinity_domain
uintptr_t pi_native_handle
@ PI_DEVICE_INFO_PLATFORM
pi_result piextPlatformGetNativeHandle(pi_platform platform, pi_native_handle *nativeHandle)
Gets the native handle of a PI platform object.
@ PI_EXT_PLATFORM_INFO_BACKEND
pi_result piDeviceGetInfo(pi_device device, pi_device_info param_name, size_t param_value_size, void *param_value, size_t *param_value_size_ret)
Returns requested info for provided native device Return PI_DEVICE_INFO_EXTENSION_DEVICELIB_ASSERT fo...
pi_result piPlatformsGet(pi_uint32 num_entries, pi_platform *platforms, pi_uint32 *num_platforms)
pi_result piDevicesGet(pi_platform platform, pi_device_type device_type, pi_uint32 num_entries, pi_device *devices, pi_uint32 *num_devices)
pi_result piDeviceRelease(pi_device device)
pi_result piPlatformGetInfo(pi_platform platform, pi_platform_info param_name, size_t param_value_size, void *param_value, size_t *param_value_size_ret)