24 #include <unordered_set>
28 inline namespace _V1 {
38 const std::lock_guard<std::mutex> Guard(
41 std::vector<PlatformImplPtr> &PlatformCache =
45 for (
const auto &PlatImpl : PlatformCache) {
51 Result = std::make_shared<platform_impl>(
PiPlatform, Plugin);
52 PlatformCache.emplace_back(Result);
65 sizeof(Plt), &Plt,
nullptr);
81 auto IsMatchingOpenCL = [](
platform Platform,
const std::string_view name) {
82 const bool HasNameMatch = Platform.get_info<info::platform::name>().find(
83 name) != std::string::npos;
85 const bool IsMatchingOCL = (HasNameMatch && Backend ==
backend::opencl);
88 std::cout <<
"SYCL_PI_TRACE[all]: " << name
89 <<
" OpenCL platform found but is not compatible." << std::endl;
93 return IsMatchingOpenCL(Platform,
"NVIDIA CUDA") ||
94 IsMatchingOpenCL(Platform,
"AMD Accelerated Parallel Processing");
102 auto getPluginPlatforms = [](
PluginPtr &Plugin) {
103 std::vector<platform> Platforms;
106 0,
nullptr, &NumPlatforms) != PI_SUCCESS)
110 std::vector<sycl::detail::pi::PiPlatform> PiPlatforms(NumPlatforms);
112 NumPlatforms, PiPlatforms.data(),
nullptr) != PI_SUCCESS)
116 platform Platform = detail::createSyclObjFromImpl<platform>(
127 Platforms.push_back(Platform);
134 static const bool PreferUR = [] {
135 const char *PreferURStr = std::getenv(
"SYCL_PREFER_UR");
136 return (PreferURStr && (std::stoi(PreferURStr) != 0));
142 std::vector<std::pair<platform, PluginPtr>> PlatformsWithPlugin;
146 std::unordered_set<backend> BackendsUR;
156 for (
const auto &P : getPluginPlatforms(*PluginUR)) {
157 PlatformsWithPlugin.push_back({P, *PluginUR});
164 for (
auto &Plugin : Plugins) {
168 const auto &PluginPlatforms = getPluginPlatforms(Plugin);
169 for (
const auto &P : PluginPlatforms) {
173 PlatformsWithPlugin.push_back({P, Plugin});
179 std::vector<platform> Platforms;
180 for (
auto &Platform : PlatformsWithPlugin) {
181 auto &Plugin = Platform.second;
182 std::lock_guard<std::mutex> Guard(*Plugin->getPluginMutex());
183 Plugin->getPlatformId(
getSyclObjImpl(Platform.first)->getHandleRef());
184 Platforms.push_back(Platform.first);
200 template <
typename ListT,
typename FilterT>
201 std::vector<int> platform_impl::filterDeviceFilter(
202 std::vector<sycl::detail::pi::PiDevice> &PiDevices,
203 ListT *FilterList)
const {
205 constexpr
bool is_ods_target = std::is_same_v<FilterT, ods_target>;
207 if constexpr (is_ods_target) {
215 std::sort(FilterList->get().begin(), FilterList->get().end(),
217 return filter1.IsNegativeTarget && !filter2.IsNegativeTarget;
225 std::map<int, bool> Blacklist;
228 std::vector<int> original_indices;
240 std::lock_guard<std::mutex> Guard(*MPlugin->getPluginMutex());
241 int DeviceNum = MPlugin->getStartingDeviceId(MPlatform);
246 &PiDevType,
nullptr);
251 for (
const FilterT &Filter : FilterList->get()) {
254 if (FilterBackend != Backend && FilterBackend !=
backend::all)
260 if (Filter.DeviceNum && DeviceNum != Filter.DeviceNum.value())
264 FilterDevType != DeviceType)
267 if constexpr (is_ods_target) {
269 if (Blacklist[DeviceNum])
272 if (Filter.IsNegativeTarget) {
275 Blacklist[DeviceNum] =
true;
280 PiDevices[InsertIDx++] = Device;
281 original_indices.push_back(DeviceNum);
286 PiDevices.resize(InsertIDx);
290 MPlugin->setLastDeviceId(MPlatform, DeviceNum);
291 return original_indices;
294 std::shared_ptr<device_impl>
296 const std::lock_guard<std::mutex> Guard(MDeviceMapMutex);
297 return getDeviceImplHelper(
PiDevice);
302 const std::shared_ptr<platform_impl> &PlatformImpl) {
303 const std::lock_guard<std::mutex> Guard(MDeviceMapMutex);
305 std::shared_ptr<device_impl> Result = getDeviceImplHelper(
PiDevice);
310 Result = std::make_shared<device_impl>(
PiDevice, PlatformImpl);
311 MDeviceCache.emplace_back(Result);
322 auto supported = dev.
get_info<info::device::partition_affinity_domains>();
323 auto It = std::find(std::begin(supported), std::end(supported), domain);
324 return It != std::end(supported);
329 auto supported = dev.
get_info<info::device::partition_properties>();
331 std::find(std::begin(supported), std::end(supported), partitionProp);
332 return It != std::end(supported);
336 backend PlatformBackend, std::vector<device> &DeviceList,
337 ods_target_list *OdsTargetList,
const std::vector<int> &original_indices,
344 std::vector<device> FinalResult;
349 for (
unsigned i = 0; i < DeviceList.size(); i++) {
352 device &dev = DeviceList[i];
353 bool deviceAdded =
false;
356 if (PlatformBackend != TargetBackend && TargetBackend !=
backend::all)
359 bool deviceMatch =
target.HasDeviceWildCard;
365 }
else if (
target.DeviceNum) {
366 deviceMatch = (
target.DeviceNum.value() == original_indices[i]);
373 bool wantSubDevice =
target.SubDeviceNum ||
target.HasSubDeviceWildCard;
374 bool supportsSubPartitioning =
377 bool wantSubSubDevice =
378 target.SubSubDeviceNum ||
target.HasSubSubDeviceWildCard;
380 if (!wantSubDevice) {
383 FinalResult.push_back(dev);
389 if (!supportsSubPartitioning) {
403 if (
target.SubDeviceNum) {
404 if (subDevices.size() <=
target.SubDeviceNum.value()) {
408 subDevices[0] = subDevices[
target.SubDeviceNum.value()];
409 subDevices.resize(1);
412 if (!wantSubSubDevice) {
414 FinalResult.insert(FinalResult.end(), subDevices.begin(),
420 for (
device subDev : subDevices) {
421 bool supportsSubSubPartitioning =
424 if (!supportsSubSubPartitioning) {
425 if (
target.SubDeviceNum) {
436 subDev.create_sub_devices<partitionProperty>(affinityDomain);
437 if (
target.SubSubDeviceNum) {
438 if (subSubDevices.size() <=
target.SubSubDeviceNum.value()) {
443 subSubDevices[0] = subSubDevices[
target.SubSubDeviceNum.value()];
444 subSubDevices.resize(1);
446 FinalResult.insert(FinalResult.end(), subSubDevices.begin(),
447 subSubDevices.end());
456 std::vector<device> Res;
464 MPlatform, pi::cast<sycl::detail::pi::PiDeviceType>(DeviceType),
466 pi::cast<sycl::detail::pi::PiDevice *>(
nullptr), &NumDevices);
469 if (NumDevices == 0) {
476 auto It = std::find_if(Plugins.begin(), Plugins.end(),
477 [&Platform = MPlatform](
PluginPtr &Plugin) {
478 return Plugin->containsPiPlatform(Platform);
480 if (It != Plugins.end()) {
482 std::lock_guard<std::mutex> Guard(*Plugin->getPluginMutex());
483 Plugin->adjustLastDeviceId(MPlatform);
488 std::vector<sycl::detail::pi::PiDevice> PiDevices(NumDevices);
492 pi::cast<sycl::detail::pi::PiDeviceType>(
494 NumDevices, PiDevices.data(),
nullptr);
498 std::vector<sycl::detail::pi::PiDevice> PiDevicesToCleanUp = PiDevices;
507 std::vector<int> PlatformDeviceIndices;
509 PlatformDeviceIndices = filterDeviceFilter<ods_target_list, ods_target>(
510 PiDevices, OdsTargetList);
517 PiDevices.begin(), PiDevices.end(), std::back_inserter(Res),
519 return detail::createSyclObjFromImpl<device>(
520 PlatformImpl->getOrMakeDeviceImpl(PiDevice, PlatformImpl));
531 if (!OdsTargetList || Res.size() == 0)
537 PlatformDeviceIndices, PlatformImpl);
544 return (AllExtensionNames.find(ExtensionName) != std::string::npos);
560 template <
typename Param>
566 typename info::platform::version::return_type
567 platform_impl::get_backend_info<info::platform::version>()
const {
570 "the info::platform::version info descriptor can "
571 "only be queried with an OpenCL backend");
573 return get_info<info::platform::version>();
577 std::vector<device> &Devices);
580 typename info::device::version::return_type
581 platform_impl::get_backend_info<info::device::version>()
const {
584 "the info::device::version info descriptor can only "
585 "be queried with an OpenCL backend");
587 auto Devices = get_devices();
588 if (Devices.empty()) {
589 return "No available device";
597 typename info::device::backend_version::return_type
598 platform_impl::get_backend_info<info::device::backend_version>()
const {
601 "the info::device::backend_version info descriptor "
602 "can only be queried with a Level Zero backend");
613 if (dev.has(Aspect) ==
false) {
620 std::shared_ptr<device_impl>
622 for (
const std::weak_ptr<device_impl> &DeviceWP : MDeviceCache) {
623 if (std::shared_ptr<device_impl> Device = DeviceWP.lock()) {
624 if (Device->getHandleRef() ==
PiDevice)
631 #define __SYCL_PARAM_TRAITS_SPEC(DescType, Desc, ReturnT, PiCode) \
632 template ReturnT platform_impl::get_info<info::platform::Desc>() const;
634 #include <sycl/info/platform_traits.def>
635 #undef __SYCL_PARAM_TRAITS_SPEC
static void registerEarlyShutdownHandler()
std::vector< PlatformImplPtr > & getPlatformCache()
static GlobalHandler & instance()
static const char * get()
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.
__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)
decltype(Obj::impl) const & getSyclObjImpl(const Obj &SyclObject)
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)
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
int default_selector_v(const device &dev)
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)