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

Add platform discovery search paths #473

Merged
merged 6 commits into from
May 9, 2023

Conversation

kswiecicki
Copy link
Contributor

@kswiecicki kswiecicki commented Apr 26, 2023

This patch makes the loader search additional directories when searching for hardcoded adapter libraries.
Additional search paths can be added via UR_ADAPTERS_SEARCH_PATH environmental variable that holds a comma-separated list of directory paths (e.g. UR_ADAPTERS_SEARCH_PATH=/home/kswiecic/dev/sycl_workspace/libs/).
The loader now also searches the directory it was linked from.

Related issue: #128

for (const auto &path : knownPlatformNames) {
discovered_adapters.emplace_back(path);
auto searchPaths = getEnvAdapterSearchPaths();
auto loaderPath = getLoaderLibDirectory();
Copy link
Contributor

Choose a reason for hiding this comment

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

Would this result in adapter libraries in loader lib directory to take precedence over libraries discovered in LD_LIBRARY_PATH?

As a user I would expect LD_LIBRARY_PATH to have highest search precedence

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've set the highest search precedence to UR_ADAPTERS_SEARCH_PATH and made LD_LIBRARY_PATH a higher priority than the current loader lib directory.

@kswiecicki kswiecicki force-pushed the platform-discovery-win branch from 8784f6c to 48bad61 Compare April 28, 2023 14:51
@kswiecicki kswiecicki force-pushed the platform-discovery-win branch 2 times, most recently from aaf899c to f484512 Compare May 2, 2023 16:03
static std::optional<std::vector<fs::path>> getEnvOSSearchPaths() {
std::optional<std::string> pathStringsOpt;
try {
pathStringsOpt = ur_getenv("LD_LIBRARY_PATH");
Copy link
Member

Choose a reason for hiding this comment

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

I looked at the documentation for ld.so.8 (https://man7.org/linux/man-pages/man8/ld.so.8.html) and I'm actually not sure that interpreting LD_LIBRARY_PATH within UR is a good idea. There are a few special cases that we might not cover by interpreting it ourselves:

  • "This variable is ignored in secure-execution mode"
  • "Within the pathnames specified in LD_LIBRARY_PATH, the
    dynamic linker expands the tokens $ORIGIN, $LIB, and
    $PLATFORM (or the versions using curly braces around the
    names) as described above in Dynamic string tokens."
  • The directory lists can also be separated by using semicolons

I think it would be safer to let the linker handle LD_LIBRARY_PATH.

Copy link
Member

Choose a reason for hiding this comment

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

There might be something similiar on Windows as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Since that was the case, I've changed the adapter registry to store a sorted list of paths that should be searched when looking for each hardcoded adapter. Eg. 1. Paths from UR_ADAPTERS_SEARCH_PATH. 2. Hardcoded library name (in that case the OS searches for this library). 3. UR Loader directory (current binary/library directory).

*/

#include <dlfcn.h>
#include <filesystem>
Copy link
Contributor

Choose a reason for hiding this comment

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

See PR #440 for handling an alternative include:

#if __has_include(<filesystem>)
#include <filesystem>
namespace filesystem = std::filesystem;
#else
#include <experimental/filesystem>
namespace filesystem = std::experimental::filesystem;
#endif

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

std::back_inserter(searchPaths));
}

for (const auto &platformName : knownPlatformNames) {
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: platformName -> adapterName

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

# Copyright (C) 2023 Intel Corporation
# SPDX-License-Identifier: MIT

set(DUMMY_LIB_DIR ${CMAKE_BINARY_DIR}/bin/${CMAKE_BUILD_TYPE}/adapter-reg)
Copy link
Contributor

Choose a reason for hiding this comment

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

This has no effect as this variable is set again below.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't need this variable anymore.

set(DUMMY_LIB_PATH ${DUMMY_LIB_DIR}/libur_adapter_level_zero.so.0)
endif()

# Create a dummy adapter library in adapter the runtime output directory
Copy link
Contributor

Choose a reason for hiding this comment

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

in the adapter runtime output directory?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've removed this part.

set(DUMMY_LIB_DIR ${CMAKE_BINARY_DIR}/bin/${CMAKE_BUILD_TYPE}/adapter-reg)

if(MSVC)
set(DUMMY_LIB_DIR ${CMAKE_BINARY_DIR}/bin/${CMAKE_BUILD_TYPE}/adapter-reg)
Copy link
Contributor

Choose a reason for hiding this comment

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

Please, check if both MSVC and non-MSVC paths could be resolved with CMAKE_CURRENT_BINARY_DIR:

${CMAKE_CURRENT_BINARY_DIR}/adapter-reg

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's no longer relevant.

endif()

# Create a dummy adapter library in adapter the runtime output directory
file(WRITE ${DUMMY_LIB_PATH} "")
Copy link
Contributor

Choose a reason for hiding this comment

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

Since this will be created in the UR bin folder, consider removing it after tests finish. You might need to create a cmake script for 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.

It's no longer relevant.

@kswiecicki kswiecicki force-pushed the platform-discovery-win branch 5 times, most recently from 3a9d616 to db1d49d Compare May 8, 2023 14:54

#include "ur_loader.hpp"

#define MAX_PATH_LEN_WIN 1024
Copy link
Contributor

Choose a reason for hiding this comment

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

why 1024? MAX_PATH is 256 (default) or 32K (need changes in registry)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That was an arbitrary number that I was going to change in the future but forgot.
I've made the buffer bigger, equal to the maximum possible path length according to https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=registry.

@kswiecicki kswiecicki force-pushed the platform-discovery-win branch 2 times, most recently from 708efa9 to afb16a1 Compare May 8, 2023 15:46
[](const std::string &s) { return fs::path(s); });
paths.erase(std::remove_if(paths.begin(), paths.end(),
[](const fs::path &path) {
return !fs::exists(path);
Copy link
Contributor

Choose a reason for hiding this comment

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

warn("incorrect path...") ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

@@ -260,6 +260,15 @@ Specific environment variables can be set to control the behavior of unified run

This environment variable should be used for development and debugging only.
Copy link
Contributor

Choose a reason for hiding this comment

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

Add here that the search path is not considered when force load is used.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done. I've also added this information to the UR_ADAPTERS_SEARCH_PATH notes.

std::vector<fs::path> paths;
auto pathStrings = pathStringsOpt.value();

std::transform(pathStrings.cbegin(), pathStrings.cend(),
Copy link
Contributor

Choose a reason for hiding this comment

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

ditto

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

// 3. Loader library directory.
if (searchPathsEnvOpt.has_value()) {
auto searchPathsEnv = searchPathsEnvOpt.value();
std::transform(searchPathsEnv.cbegin(), searchPathsEnv.cend(),
Copy link
Contributor

Choose a reason for hiding this comment

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

    if (searchPathsEnvOpt) {
        for (const auto& p : searchPathsEnvOpt.value()) {
            loadPaths.emplace_back(p / adapterName);
        }
    }

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

}

private:
std::vector<std::string> discovered_adapters;
std::vector<std::vector<fs::path>> adaptersLoadPaths;
Copy link
Contributor

Choose a reason for hiding this comment

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

Add a comment that each entry in an outer vector is an adapter, and the inner vector contains candidate paths to load.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

kswiecicki added 5 commits May 9, 2023 14:09
Adapter registry now checks the UR_ADAPTERS_SEARCH_PATH env
variable for search paths and takes them into the account when
looking for hardcoded adapter libraries. It also searches the
location of the loader library.
getenv_to_vec now accepts values with colons ':' and semicolons
';' if the values are inside either single ' ' or double " "
quotation marks.
@kswiecicki kswiecicki force-pushed the platform-discovery-win branch from afb16a1 to 378293c Compare May 9, 2023 13:25
@pbalcer pbalcer merged commit abdd25c into oneapi-src:main May 9, 2023
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.

6 participants