Skip to content

[SYCL] Don't use legacy ANSI-only Windows API for loading plugins #10943

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

Merged
merged 16 commits into from
Aug 25, 2023

Conversation

againull
Copy link
Contributor

@againull againull commented Aug 23, 2023

Currently to load PI plugins we use legacy ANSI-only versions of Windows API like GetModuleFileNameA, PathRemoveFileSpecA etc. Problem is that if path containing PI plugins has any non-ANSI symbols then PI plugins are not found and not loaded.

In this patch get rid of legacy API calls, for example, use GetModuleFileName instead of GetModuleFileNameA. GetModuleFileName is an alias which automatically selects the ANSI or Unicode version of this function.

Another difference is that GetModuleFileName and other similar aliases work with wchar_t to be able to handle unicode on Windows (in contrast to legacy GetModuleFileNameA which works with char_t).
So, use std::filesystem:path to work with library paths for convenience (instead of storing path in std::string or std::wstring) because it allows to handle paths without caring about format, can be constructed from string/wstring/.. and can be converted to string/wstring ...
DPCPP is supported on some linux systems where default compiler is gcc 7.5 which doesn't provide <filesystem> support. On Windows, minimal supported version of Visual Studio is 2019 where <filesystem> is available (supported since Visual Studio 2017 version 15.7).
That's why use filesystem::path only on Windows for now, added TODO to do the same on Linux when matrix support changes.

Copy link
Contributor

@bader bader left a comment

Choose a reason for hiding this comment

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

This most likely conflicts with #10914.

@againull againull changed the title [SYCL] Use filesystem::path on Windows to handle utf-16 [SYCL] Don't use legacy ANSI-only Windows API for loading plugins Aug 24, 2023
@againull againull marked this pull request as ready for review August 24, 2023 18:20
@againull againull requested a review from a team as a code owner August 24, 2023 18:20
Copy link
Contributor

@bader bader left a comment

Choose a reason for hiding this comment

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

@againull, this looks much better. Thanks a lot for addressing my concerns.

@againull
Copy link
Contributor Author

Failing testing jobs are present in the main branch in post-commit testing. i.e. not caused by this PR.

reinterpret_cast<HMODULE>(ExeModuleHandle == Handle ? 0 : Handle),
reinterpret_cast<LPSTR>(&Path), sizeof(Path));
reinterpret_cast<LPWSTR>(&Path), sizeof(Path));
Copy link
Contributor

Choose a reason for hiding this comment

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

Do you really need this cast?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Indeed, redundant. Removed.

(void)Ret;

BOOL RetCode = PathRemoveFileSpecA(reinterpret_cast<LPSTR>(&Path));
assert(RetCode && "PathRemoveFileSpecA failed");
BOOL RetCode = PathRemoveFileSpec(reinterpret_cast<LPWSTR>(&Path));
Copy link
Contributor

Choose a reason for hiding this comment

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

Likewise.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed.


using OSModuleHandle = intptr_t;
static constexpr OSModuleHandle ExeModuleHandle = -1;
static OSModuleHandle getOSModuleHandle(const void *VirtAddr) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
static OSModuleHandle getOSModuleHandle(const void *VirtAddr) {
inline OSModuleHandle getOSModuleHandle(const void *VirtAddr) {

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed.

#include <shlwapi.h>

using OSModuleHandle = intptr_t;
static constexpr OSModuleHandle ExeModuleHandle = -1;
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
static constexpr OSModuleHandle ExeModuleHandle = -1;
constexpr OSModuleHandle ExeModuleHandle = -1;

or inline conxtexpr if necessary (I think it's inline by default).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed.

Comment on lines +439 to +444
// Implementation of this function is OS specific. Please see windows_pi.cpp and
// posix_pi.cpp.
// TODO: refactor code when support matrix for DPCPP changes and <filesystem> is
// available on all supported systems.
std::vector<std::tuple<std::string, backend, void *>>
loadPlugins(const std::vector<std::pair<std::string, backend>> &&PluginNames);
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not in pi.hpp?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As @bader noticed, currently pi.hpp is in sycl/include/detail directory which means that it is exposed to the user. It seems like some of the functions from there need to be moved to the sycl/source/detail, because no need to expose them to the user, they used only internally.
This function is also used only internally, so I was trying to avoid adding this function to pi.hpp. And since it's only single usage, I didn't create header for it in sycl/source/detail.

void *Library = getPreloadedPlugin(LibSYCLDir / PluginName.first);
LoadedPlugins.push_back(std::make_tuple(std::move(PluginName.first),
std::move(PluginName.second),
std::move(Library)));
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
std::move(Library)));
Library));

Moving a pointer is overcomplicated a little bit :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed:)

@againull againull closed this Aug 25, 2023
@againull againull reopened this Aug 25, 2023
@againull againull closed this Aug 25, 2023
@againull againull reopened this Aug 25, 2023
@againull againull merged commit 5c30815 into intel:sycl Aug 25, 2023
@againull againull deleted the path_windows_only branch December 22, 2023 04:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants