Skip to content

Commit

Permalink
[SYCL] List unsupported platforms in sycl-ls verbose mode (#15166)
Browse files Browse the repository at this point in the history
The runtime is able to recognised [banned
platforms](https://intel.github.io/llvm-docs/doxygen/namespacesycl_1_1__V1_1_1detail.html#af47bb6df075ff6aa60fc6855d59f6fe6),
this patch provides a way to list them using `sycl-ls`' `verbose`
switch.
  • Loading branch information
jchlanda authored Sep 5, 2024
1 parent 603dcd6 commit 4443eff
Show file tree
Hide file tree
Showing 8 changed files with 148 additions and 58 deletions.
5 changes: 5 additions & 0 deletions sycl/include/sycl/platform.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,11 @@ class __SYCL_EXPORT platform : public detail::OwnerLessBase<platform> {
/// \return a vector of all available SYCL platforms.
static std::vector<platform> get_platforms();

/// Returns all unsupported (non-SYCL) platforms in the system.
///
/// \return a vector of all unsupported non-SYCL platforms.
static std::vector<platform> get_unsupported_platforms();

/// Returns the backend associated with this platform.
///
/// \return the backend associated with this platform
Expand Down
69 changes: 49 additions & 20 deletions sycl/source/detail/platform_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,40 +96,69 @@ static bool IsBannedPlatform(platform Platform) {
IsMatchingOpenCL(Platform, "AMD Accelerated Parallel Processing");
}

// This routine has the side effect of registering each platform's last device
// id into each plugin, which is used for device counting.
std::vector<platform> platform_impl::get_platforms() {
// Get the vector of platforms supported by a given UR plugin
// replace uses of this with a helper in plugin object, the plugin
// objects will own the ur adapter handles and they'll need to pass them to
// urPlatformsGet - so urPlatformsGet will need to be wrapped with a helper
std::vector<platform> platform_impl::getPluginPlatforms(PluginPtr &Plugin,
bool Supported) {
std::vector<platform> Platforms;

// Get the vector of platforms supported by a given UR plugin
// replace uses of this with with a helper in plugin object, the plugin
// objects will own the ur adapter handles and they'll need to pass them to
// urPlatformsGet - so urPlatformsGet will need to be wrapped with a helper
auto getPluginPlatforms = [](PluginPtr &Plugin) {
std::vector<platform> Platforms;
auto UrPlatforms = Plugin->getUrPlatforms();

auto UrPlatforms = Plugin->getUrPlatforms();
if (UrPlatforms.empty()) {
return Platforms;
}

if (UrPlatforms.empty()) {
return Platforms;
}
for (const auto &UrPlatform : UrPlatforms) {
platform Platform = detail::createSyclObjFromImpl<platform>(
getOrMakePlatformImpl(UrPlatform, Plugin));
const bool IsBanned = IsBannedPlatform(Platform);
const bool HasAnyDevices =
!Platform.get_devices(info::device_type::all).empty();

for (const auto &UrPlatform : UrPlatforms) {
platform Platform = detail::createSyclObjFromImpl<platform>(
getOrMakePlatformImpl(UrPlatform, Plugin));
if (IsBannedPlatform(Platform)) {
if (!Supported) {
if (IsBanned || !HasAnyDevices) {
Platforms.push_back(Platform);
}
} else {
if (IsBanned) {
continue; // bail as early as possible, otherwise banned platforms may
// mess up device counting
}

// The SYCL spec says that a platform has one or more devices. ( SYCL
// 2020 4.6.2 ) If we have an empty platform, we don't report it back
// from platform::get_platforms().
if (!Platform.get_devices(info::device_type::all).empty()) {
if (HasAnyDevices) {
Platforms.push_back(Platform);
}
}
return Platforms;
};
}
return Platforms;
}

std::vector<platform> platform_impl::get_unsupported_platforms() {
std::vector<platform> UnsupportedPlatforms;

std::vector<PluginPtr> &Plugins = sycl::detail::ur::initializeUr();
// Ignore UR as it has to be supported.
for (auto &Plugin : Plugins) {
if (Plugin->hasBackend(backend::all)) {
continue; // skip UR
}
std::vector<platform> PluginPlatforms =
getPluginPlatforms(Plugin, /*Supported=*/false);
std::copy(PluginPlatforms.begin(), PluginPlatforms.end(),
std::back_inserter(UnsupportedPlatforms));
}

return UnsupportedPlatforms;
}

// This routine has the side effect of registering each platform's last device
// id into each plugin, which is used for device counting.
std::vector<platform> platform_impl::get_platforms() {

// See which platform we want to be served by which plugin.
// There should be just one plugin serving each backend.
Expand Down
9 changes: 9 additions & 0 deletions sycl/source/detail/platform_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,11 @@ class platform_impl {
/// \return a vector of all available SYCL platforms.
static std::vector<platform> get_platforms();

/// Returns all unsupported (non-SYCL) platforms in the system.
///
/// \return a vector of all unsupported (non-SYCL) platforms.
static std::vector<platform> get_unsupported_platforms();

// \return the Plugin associated with this platform.
const PluginPtr &getPlugin() const { return MPlugin; }

Expand Down Expand Up @@ -200,6 +205,10 @@ class platform_impl {
private:
std::shared_ptr<device_impl> getDeviceImplHelper(ur_device_handle_t UrDevice);

// Helper to get the vector of platforms supported by a given UR plugin
static std::vector<platform> getPluginPlatforms(PluginPtr &Plugin,
bool Supported = true);

// Helper to filter reportable devices in the platform
template <typename ListT, typename FilterT>
std::vector<int>
Expand Down
4 changes: 4 additions & 0 deletions sycl/source/platform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ std::vector<platform> platform::get_platforms() {
return detail::platform_impl::get_platforms();
}

std::vector<platform> platform::get_unsupported_platforms() {
return detail::platform_impl::get_unsupported_platforms();
}

backend platform::get_backend() const noexcept { return impl->getBackend(); }

template <typename Param>
Expand Down
16 changes: 16 additions & 0 deletions sycl/test-e2e/Plugin/sycl-ls-banned.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// REQUIRES: cuda

// RUN: sycl-ls --verbose >%t.cuda.out
// RUN: FileCheck %s --input-file %t.cuda.out

//==---- sycl-ls-banned.cpp - Check sycl-ls output of banned platforms. --==//
//
// 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
//
//===----------------------------------------------------------------------===//

// CHECK: Unsupported Platforms:
// CHECK-NEXT: Platform [#1]:
// CHECK-NEXT: Version : OpenCL
1 change: 1 addition & 0 deletions sycl/test/abi/sycl_symbols_linux.dump
Original file line number Diff line number Diff line change
Expand Up @@ -3544,6 +3544,7 @@ _ZN4sycl3_V17samplerC1EP11_cl_samplerRKNS0_7contextE
_ZN4sycl3_V17samplerC2ENS0_29coordinate_normalization_modeENS0_15addressing_modeENS0_14filtering_modeERKNS0_13property_listE
_ZN4sycl3_V17samplerC2EP11_cl_samplerRKNS0_7contextE
_ZN4sycl3_V18platform13get_platformsEv
_ZN4sycl3_V18platform25get_unsupported_platformsEv
_ZN4sycl3_V18platformC1EP15_cl_platform_id
_ZN4sycl3_V18platformC1ERKNS0_15device_selectorE
_ZN4sycl3_V18platformC1ERKNS0_6deviceE
Expand Down
1 change: 1 addition & 0 deletions sycl/test/abi/sycl_symbols_windows.dump
Original file line number Diff line number Diff line change
Expand Up @@ -4032,6 +4032,7 @@
?get_platform@context@_V1@sycl@@QEBA?AVplatform@23@XZ
?get_platform@device@_V1@sycl@@QEBA?AVplatform@23@XZ
?get_platforms@platform@_V1@sycl@@SA?AV?$vector@Vplatform@_V1@sycl@@V?$allocator@Vplatform@_V1@sycl@@@std@@@std@@XZ
?get_unsupported_platforms@platform@_V1@sycl@@SA?AV?$vector@Vplatform@_V1@sycl@@V?$allocator@Vplatform@_V1@sycl@@@std@@@std@@XZ
?get_pointer_device@_V1@sycl@@YA?AVdevice@12@PEBXAEBVcontext@12@@Z
?get_pointer_type@_V1@sycl@@YA?AW4alloc@usm@12@PEBXAEBVcontext@12@@Z
?get_precision@stream@_V1@sycl@@QEBA_KXZ
Expand Down
101 changes: 63 additions & 38 deletions sycl/tools/sycl-ls/sycl-ls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
// verbose (enabled with --verbose).
//
// In verbose mode it also prints, which devices would be chosen by various SYCL
// device selectors.
// device selectors. If the system has unsupported platforms (for instance
// CUDA's OpenCL) those will also be listed in verbose mode, under "Unsupported
// Platforms".
//
#include <sycl/sycl.hpp>

Expand Down Expand Up @@ -122,7 +124,8 @@ std::array<int, 2> GetNumberOfSubAndSubSubDevices(const device &Device) {
}

static void printDeviceInfo(const device &Device, bool Verbose,
const std::string &Prepend) {
const std::string &Prepend,
bool IsUnsupported = false) {
auto DeviceVersion = Device.get_info<info::device::version>();
auto DeviceName = Device.get_info<info::device::name>();
auto DeviceVendor = Device.get_info<info::device::vendor>();
Expand Down Expand Up @@ -157,19 +160,23 @@ static void printDeviceInfo(const device &Device, bool Verbose,
<< std::endl;
}

std::cout << Prepend << "Aspects :";
// We don't expect to find info on aspects, device's sub-group size or
// architecture on non supported devices.
if (!IsUnsupported) {
std::cout << Prepend << "Aspects :";
#define __SYCL_ASPECT(ASPECT, ID) \
if (Device.has(aspect::ASPECT)) \
std::cout << " " << #ASPECT;
#include <sycl/info/aspects.def>
std::cout << std::endl;
auto sg_sizes = Device.get_info<info::device::sub_group_sizes>();
std::cout << Prepend << "info::device::sub_group_sizes:";
for (auto size : sg_sizes)
std::cout << " " << size;
std::cout << std::endl;
std::cout << Prepend << "Architecture: " << getArchName(Device)
<< std::endl;
std::cout << std::endl;
auto sg_sizes = Device.get_info<info::device::sub_group_sizes>();
std::cout << Prepend << "info::device::sub_group_sizes:";
for (auto size : sg_sizes)
std::cout << " " << size;
std::cout << std::endl;
std::cout << Prepend << "Architecture: " << getArchName(Device)
<< std::endl;
}
} else {
std::cout << Prepend << ", " << DeviceName << " " << DeviceVersion << " ["
<< DeviceDriverVersion << "]" << std::endl;
Expand Down Expand Up @@ -201,8 +208,11 @@ static int printUsageAndExit() {
<< std::endl;
std::cout << "\n Options:" << std::endl;
std::cout
<< "\t --verbose " << "\t Verbosely prints all the discovered platforms. "
<< "It also lists the device chosen by various SYCL device selectors."
<< "\t --verbose "
<< "\t Verbosely prints all the discovered platforms. "
<< "It also lists the device chosen by various SYCL device "
"selectors. If the system contains unsupported platforms, those will "
"also be listed in verbose mode, under \"Unsupported Platforms\"."
<< std::endl;
std::cout
<< "\t --ignore-device-selectors "
Expand Down Expand Up @@ -317,6 +327,38 @@ static int unsetFilterEnvVarsAndFork() {
}
#endif

// NOTE: This function can update DeviceNums.
static void printVerbosePlatformInfo(const std::vector<platform> &Platforms,
std::map<backend, size_t> &DeviceNums,
const bool SuppressNumberPrinting,
bool IsUnsupported = false) {
uint32_t PlatformNum = 0;
if (!SuppressNumberPrinting)
DeviceNums.clear();
for (const auto &Platform : Platforms) {
backend Backend = Platform.get_backend();
++PlatformNum;
auto PlatformVersion = Platform.get_info<info::platform::version>();
auto PlatformName = Platform.get_info<info::platform::name>();
auto PlatformVendor = Platform.get_info<info::platform::vendor>();
std::cout << "Platform [#" << PlatformNum << "]:" << std::endl;
std::cout << " Version : " << PlatformVersion << std::endl;
std::cout << " Name : " << PlatformName << std::endl;
std::cout << " Vendor : " << PlatformVendor << std::endl;

const auto &Devices = Platform.get_devices();
std::cout << " Devices : " << Devices.size() << std::endl;
for (const auto &Device : Devices) {
if (!SuppressNumberPrinting) {
std::cout << " Device [#" << DeviceNums[Backend]
<< "]:" << std::endl;
++DeviceNums[Backend];
}
printDeviceInfo(Device, true, " ", IsUnsupported);
}
}
}

int main(int argc, char **argv) {

if (argc == 1) {
Expand Down Expand Up @@ -386,31 +428,14 @@ int main(int argc, char **argv) {

if (verbose) {
std::cout << "\nPlatforms: " << Platforms.size() << std::endl;
uint32_t PlatformNum = 0;
if (!SuppressNumberPrinting)
DeviceNums.clear();
for (const auto &Platform : Platforms) {
backend Backend = Platform.get_backend();
++PlatformNum;
auto PlatformVersion = Platform.get_info<info::platform::version>();
auto PlatformName = Platform.get_info<info::platform::name>();
auto PlatformVendor = Platform.get_info<info::platform::vendor>();
std::cout << "Platform [#" << PlatformNum << "]:" << std::endl;
std::cout << " Version : " << PlatformVersion << std::endl;
std::cout << " Name : " << PlatformName << std::endl;
std::cout << " Vendor : " << PlatformVendor << std::endl;

const auto &Devices = Platform.get_devices();
std::cout << " Devices : " << Devices.size() << std::endl;
for (const auto &Device : Devices) {
if (!SuppressNumberPrinting) {
std::cout << " Device [#" << DeviceNums[Backend]
<< "]:" << std::endl;
++DeviceNums[Backend];
}
printDeviceInfo(Device, true, " ");
}
}
printVerbosePlatformInfo(Platforms, DeviceNums, SuppressNumberPrinting);

const auto &UnsupportedPlatforms = platform::get_unsupported_platforms();
std::cout << "\nUnsupported Platforms: " << UnsupportedPlatforms.size()
<< std::endl;
printVerbosePlatformInfo(UnsupportedPlatforms, DeviceNums,
SuppressNumberPrinting, true);
std::cout << std::endl;
} else {
return EXIT_SUCCESS;
}
Expand Down

0 comments on commit 4443eff

Please sign in to comment.