Skip to content
Merged
Changes from all 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
27 changes: 22 additions & 5 deletions src/xccl/xccl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

#ifndef _WIN32
#include <dlfcn.h>
#include <link.h>
#endif

namespace {
Expand All @@ -23,10 +24,13 @@ namespace {
// does not inherit the search path of whoever pulled it in, so in the flat
// PyPI/venv layout libccl.so.1 is looked up only in /etc/ld.so.cache, /lib and
// /usr/lib; it is not found and oneCCL fails with "Could not load any plugin",
// taking down every process group creation. Loading it here resolves it
// through this library's RPATH -- the same one that already locates
// libccl.so.2 -- and leaves it in the global scope for the plugin to bind
// against.
// taking down every process group creation. Pulling it into the global scope
// here lets the plugin bind against the already-loaded object.
//
// Our own RPATH is no help: libtorch_xpu.so is only an indirect dependency, so
// glibc resolves dlopen() against the RPATH of whatever was dlopen'd directly
// (libtorch_global_deps.so), never ours. Derive the location from the already
// mapped libccl.so.2 instead -- oneCCL always ships the two side by side.
//
// A failure here is expected on a full oneAPI/DLE layout, where the plugin
// resolves its own dependencies, so it is deliberately not reported.
Expand All @@ -35,7 +39,20 @@ namespace {
// is the minimum supported version.
[[maybe_unused]] const bool preloaded_oneccl_legacy_dep = []() {
#ifndef _WIN32
(void)dlopen("libccl.so.1", RTLD_NOW | RTLD_GLOBAL);
// libccl.so.2 is DT_NEEDED, so it is already mapped by the time this runs.
if (void* v2 = dlopen("libccl.so.2", RTLD_LAZY | RTLD_NOLOAD)) {
link_map* lm = nullptr;
if (dlinfo(v2, RTLD_DI_LINKMAP, static_cast<void*>(&lm)) == 0 &&
lm != nullptr && lm->l_name != nullptr && lm->l_name[0] != '\0') {
std::string path(lm->l_name);
const size_t slash = path.rfind('/');
if (slash != std::string::npos) {
path.replace(slash + 1, std::string::npos, "libccl.so.1");
(void)dlopen(path.c_str(), RTLD_NOW | RTLD_GLOBAL);
}
}
dlclose(v2);
}
#endif
return true;
}();
Expand Down
Loading