Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SYCL] Add '--ignore-device-selectors' CLI option to sycl-ls and improve warning messages #12718

Merged
merged 7 commits into from
Feb 23, 2024
Merged
Show file tree
Hide file tree
Changes from 4 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
19 changes: 17 additions & 2 deletions sycl/test/tools/sycl-ls.test
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
-- Check that sycl-ls exits with 0 exit code.
-- Check that sycl-ls exits with 0 exit code.

Copy link
Contributor

Choose a reason for hiding this comment

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

That's slightly inaccurate - you're verifying the output as well.

RUN: sycl-ls --verbose
RUN: sycl-ls --verbose > vanilla_verbose.out
RUN: sycl-ls > vanilla.out

-- Check the functioning of 'discard-filters' CLI option.

RUN: env ONEAPI_DEVICE_SELECTOR="opencl:*" sycl-ls --discard-filters > ods_discard_filter.out
RUN: diff vanilla.out ods_discard_filter.out

RUN: env ONEAPI_DEVICE_SELECTOR="opencl:*" sycl-ls --discard-filters --verbose > ods_discard_filter_v.out
RUN: diff vanilla_verbose.out ods_discard_filter_v.out

RUN: env SYCL_DEVICE_ALLOWLIST="BackendName:opencl" sycl-ls --discard-filters > sda_discard_filter.out
RUN: diff vanilla.out sda_discard_filter.out

RUN: env SYCL_DEVICE_ALLOWLIST="BackendName:opencl" sycl-ls --discard-filters --verbose > sda_discard_filter_v.out
RUN: diff vanilla_verbose.out sda_discard_filter_v.out
137 changes: 113 additions & 24 deletions sycl/tools/sycl-ls/sycl-ls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ using namespace sycl;
// Controls verbose output vs. concise.
bool verbose;

// Controls whether to discard filter environment variables or not.
bool DiscardFilters;

// Map to store values of various filter environment variables.
std::map<std::string, std::string> FilterEnvVars;

// Trivial custom selector that selects a device of the given type.
class custom_selector : public device_selector {
info::device_type MType;
Expand Down Expand Up @@ -105,46 +111,129 @@ static void printSelectorChoice(const device_selector &Selector,
}
}

int main(int argc, char **argv) {
static int printUsageAndExit() {
std::cout << "Usage: sycl-ls [--verbose] [--discard-filters]" << std::endl;
std::cout << "This program lists all devices and backends discovered by SYCL."
<< 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."
<< std::endl;
std::cout
<< "\t --discard-filters "
<< "\t Lists all platforms available on the system irrespective "
<< "of the filter environment variables (like ONEAPI_DEVICE_SELECTOR)."
<< std::endl;

// See if verbose output is requested
if (argc == 1)
verbose = false;
else if (argc == 2 && std::string(argv[1]) == "--verbose")
verbose = true;
else {
std::cout << "Usage: sycl-ls [--verbose]" << std::endl;
return EXIT_FAILURE;
}
return EXIT_FAILURE;
}

bool SuppressNumberPrinting = false;
// Print warning and suppress printing device ids if any of
// the filter environment variable is set.
static void printWarningIfFiltersUsed(bool &SuppressNumberPrinting) {

#ifndef __INTEL_PREVIEW_BREAKING_CHANGES
const char *filter = std::getenv("SYCL_DEVICE_FILTER");
if (filter) {
std::cerr << "Warning: SYCL_DEVICE_FILTER environment variable is set to "
<< filter << "." << std::endl;
std::cerr << "To see device ids, please unset SYCL_DEVICE_FILTER."
<< std::endl
<< std::endl;
SuppressNumberPrinting = true;
if (!DiscardFilters) {
std::cerr << "INFO: Output filtered by SYCL_DEVICE_FILTER "
<< "environment variable, which is set to " << filter << "."
<< std::endl;
std::cerr << "To see device ids, use the --discard-filters CLI option."
<< std::endl
<< std::endl;
SuppressNumberPrinting = true;
} else
FilterEnvVars.insert({"SYCL_DEVICE_FILTER", filter});
}
#endif

const char *ods_targets = std::getenv("ONEAPI_DEVICE_SELECTOR");
if (ods_targets) {
std::cerr
<< "Warning: ONEAPI_DEVICE_SELECTOR environment variable is set to "
<< ods_targets << "." << std::endl;
std::cerr << "To see device ids, please unset ONEAPI_DEVICE_SELECTOR."
<< std::endl
<< std::endl;
SuppressNumberPrinting = true;
if (!DiscardFilters) {
std::cerr << "INFO: Output filtered by ONEAPI_DEVICE_SELECTOR "
<< "environment variable, which is set to " << ods_targets
<< "." << std::endl;
std::cerr << "To see device ids, use the --discard-filters CLI option."
<< std::endl
<< std::endl;
SuppressNumberPrinting = true;
} else
FilterEnvVars.insert({"ONEAPI_DEVICE_SELECTOR", ods_targets});
}

const char *sycl_dev_allow = std::getenv("SYCL_DEVICE_ALLOWLIST");
if (sycl_dev_allow) {
if (!DiscardFilters) {
std::cerr << "INFO: Output filtered by SYCL_DEVICE_ALLOWLIST "
<< "environment variable, which is set to " << sycl_dev_allow
<< "." << std::endl;
std::cerr << "To see device ids, use the --discard-filters CLI option."
<< std::endl
<< std::endl;
SuppressNumberPrinting = true;
} else
FilterEnvVars.insert({"SYCL_DEVICE_ALLOWLIST", sycl_dev_allow});
}
}

// Unset filter related environment variables namely, SYCL_DEVICE_FILTER,
// ONEAPI_DEVICE_SELECTOR, and SYCL_DEVICE_ALLOWLIST.
static void unsetFilterEnvVars() {
for (auto it : FilterEnvVars) {
#ifdef _WIN32
_putenv_s(it.first.c_str(), "");
#else
unsetenv(it.first.c_str());
#endif
}
}

// Restore filter related environment variables that we unset earlier.
static void restoreFilterEnvVars() {
for (auto it : FilterEnvVars) {
#ifdef _WIN32
_putenv_s(it.first.c_str(), it.second.c_str());
#else
setenv(it.first.c_str(), it.second.c_str(), 1);
#endif
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think we need to do that.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

IIUC, setenv is not supported by MSVC and that's why I used _putenv_s for windows. Some other tests also use a similar approach: https://github.com/intel/llvm/blob/sycl/sycl/include/sycl/ext/intel/fpga_device_selector.hpp#L38

Copy link
Contributor

Choose a reason for hiding this comment

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

What I meant is we don't need to restore at all. sycl-ls process is going to die anywhere and its environment won't affect anyone.


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

if (argc == 1) {
verbose = false;
DiscardFilters = false;
} else {
Comment on lines +201 to +204
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we use any command line options parsing libraries anywhere in sycl?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We do use LLVM's CLI support (https://llvm.org/docs/CommandLine.html) at a couple of places but I'm not sure if we should use that here because we just have two CLI options for sycl-ls and both of them are just boolean flags.

// Parse CLI options.
for (int i = 1; i < argc; i++) {
if (std::string(argv[i]) == "--verbose")
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd do

using namespace std::literals;
if (argv[i] == "--verbose"sv)

instead.

verbose = true;
else if (std::string(argv[i]) == "--discard-filters")
DiscardFilters = true;
else
return printUsageAndExit();
}
}

bool SuppressNumberPrinting = false;
// Print warning and suppress printing device ids if any of
// the filter environment variable is set.
printWarningIfFiltersUsed(SuppressNumberPrinting);

try {
// Unset all filter env. vars to get all available devices in the system.
if (DiscardFilters)
unsetFilterEnvVars();

const auto &Platforms = platform::get_platforms();

// Restore all filter env.
if (DiscardFilters)
restoreFilterEnvVars();

// Keep track of the number of devices per backend
std::map<backend, size_t> DeviceNums;

Expand Down
Loading