Skip to content

Commit

Permalink
[SYCL] Fix 'ignore-device-selectors' sycl-ls CLI option on windows (#…
Browse files Browse the repository at this point in the history
…13047)

Fixes LIT test failure in tools/sycl-ls.test.
  • Loading branch information
uditagarwal97 authored Mar 19, 2024
1 parent 9431225 commit 6e9a3dd
Showing 1 changed file with 72 additions and 1 deletion.
73 changes: 72 additions & 1 deletion sycl/tools/sycl-ls/sycl-ls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@
#include <stdlib.h>
#include <vector>

#ifdef _WIN32
#include <system_error>
#include <windows.h>
#endif

using namespace sycl;
using namespace std::literals;

Expand Down Expand Up @@ -196,6 +201,63 @@ static void unsetFilterEnvVars() {
}
}

/* On Windows, the sycl-ls executable and sycl DLL have different copies
* of environment variables. So, just unsetting device filter env. vars
* in sycl-ls won't reflect in sycl DLL. Therefore, on Windows, after
* unsetting env. variables in the parent process, we spawn a child
* sycl-ls process that inherits parents envirnonment.
*/
#ifdef _WIN32
static int unsetFilterEnvVarsAndFork() {
// Unset all device filter enviornment variable.
unsetFilterEnvVars();

// Create a new sycl-ls process.
STARTUPINFO si;
memset(&si, 0, sizeof(si));
si.cb = sizeof(si);
// Redirect child process's stdout and stderr outputs to parent process.
si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
si.dwFlags |= STARTF_USESTDHANDLES;

PROCESS_INFORMATION pi;
if (!CreateProcess(NULL, /* Applicatioon name. */
GetCommandLine(), /* Current process's CLI input. */
NULL, /* Inherit security attributes. */
NULL, /* Thread security attributes. */
TRUE, /* Inherit handles from parent proc.*/
0, /* Creation flags. */
NULL, /* Inherit env. block from parent.*/
NULL, /* Inherit current directory. */
&si, &pi)) {
// Unable to create a process. Print error message and abort.
std::string message = std::system_category().message(GetLastError());
std::cerr << message.c_str() << std::endl;

std::cerr << "Error creating a new sycl-ls process. Aborting!" << std::endl;
return EXIT_FAILURE;
}

// Wait for child process to finish.
WaitForSingleObject(pi.hProcess, INFINITE);

// Check child process's exit code and propagate it.
DWORD exitCode;
if (!GetExitCodeProcess(pi.hProcess, &exitCode)) {
std::cerr << "Error getting exit code. Aborting!" << std::endl;
return EXIT_FAILURE;
}

assert(exitCode != STILL_ACTIVE &&
"The child process should have already terminated");

CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return exitCode;
}
#endif

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

if (argc == 1) {
Expand All @@ -218,9 +280,18 @@ int main(int argc, char **argv) {
// the filter environment variable is set.
printWarningIfFiltersUsed(SuppressNumberPrinting);

// On Windows, to print all devices available on the system,
// we spawn a child sycl-ls process with all device filter
// environment variables unset.
#ifdef _WIN32
if (DiscardFilters && FilterEnvVars.size()) {
return unsetFilterEnvVarsAndFork();
}
#endif

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

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

0 comments on commit 6e9a3dd

Please sign in to comment.