================ @@ -31,16 +44,118 @@ typedef hipError_t (*hipGetDeviceCount_t)(int *); typedef hipError_t (*hipDeviceGet_t)(int *, int); typedef hipError_t (*hipGetDeviceProperties_t)(hipDeviceProp_t *, int); -int printGPUsByHIP() { +extern cl::opt<bool> Verbose; + #ifdef _WIN32 - constexpr const char *DynamicHIPPath = "amdhip64.dll"; +static std::vector<std::string> getSearchPaths() { + std::vector<std::string> Paths; + + // Get the directory of the current executable + if (auto MainExe = sys::fs::getMainExecutable(nullptr, nullptr); + !MainExe.empty()) + Paths.push_back(sys::path::parent_path(MainExe).str()); + + // Get the system directory + wchar_t SystemDirectory[MAX_PATH]; + if (GetSystemDirectoryW(SystemDirectory, MAX_PATH) > 0) { + std::string Utf8SystemDir; + if (convertUTF16ToUTF8String( + ArrayRef<UTF16>(reinterpret_cast<const UTF16 *>(SystemDirectory), + wcslen(SystemDirectory)), + Utf8SystemDir)) + Paths.push_back(Utf8SystemDir); + } + + // Get the Windows directory + wchar_t WindowsDirectory[MAX_PATH]; + if (GetWindowsDirectoryW(WindowsDirectory, MAX_PATH) > 0) { + std::string Utf8WindowsDir; + if (convertUTF16ToUTF8String( + ArrayRef<UTF16>(reinterpret_cast<const UTF16 *>(WindowsDirectory), + wcslen(WindowsDirectory)), + Utf8WindowsDir)) + Paths.push_back(Utf8WindowsDir); + } + + // Get the current working directory + SmallVector<char, 256> CWD; + if (sys::fs::current_path(CWD)) + Paths.push_back(std::string(CWD.begin(), CWD.end())); + + // Get the PATH environment variable + if (auto PathEnv = sys::Process::GetEnv("PATH")) { + SmallVector<StringRef, 16> PathList; + StringRef(*PathEnv).split(PathList, sys::EnvPathSeparator); + for (auto &Path : PathList) + Paths.push_back(Path.str()); + } + + return Paths; +} + +// Custom comparison function for dll name +static bool compareVersions(const std::string &a, const std::string &b) { + // Extract version numbers + int versionA = std::stoi(a.substr(a.find_last_of('_') + 1)); + int versionB = std::stoi(b.substr(b.find_last_of('_') + 1)); + return versionA > versionB; +} + +#endif + +// On Windows, prefer amdhip64_n.dll where n is ROCm major version and greater +// value of n takes precedence. If amdhip64_n.dll is not found, fall back to +// amdhip64.dll. The reason is that a normal driver installation only has +// amdhip64_n.dll but we do not know what n is since this progrm may be used +// with a future version of HIP runtime. +// +// On Linux, always use default libamdhip64.so. +static std::pair<std::string, bool> findNewestHIPDLL() { +#ifdef _WIN32 + StringRef HipDLLPrefix = "amdhip64_"; + StringRef HipDLLSuffix = ".dll"; + + std::vector<std::string> SearchPaths = getSearchPaths(); + std::vector<std::string> DLLNames; + + for (const auto &Dir : SearchPaths) { + std::error_code EC; + for (sys::fs::directory_iterator DirIt(Dir, EC), DirEnd; + DirIt != DirEnd && !EC; DirIt.increment(EC)) { + StringRef Filename = sys::path::filename(DirIt->path()); + if (Filename.starts_with(HipDLLPrefix) && + Filename.ends_with(HipDLLSuffix)) + DLLNames.push_back(sys::path::convert_to_slash(DirIt->path())); + } + if (!DLLNames.empty()) + break; + } + + if (DLLNames.empty()) + return {"amdhip64.dll", true}; + + std::sort(DLLNames.begin(), DLLNames.end(), compareVersions); + return {DLLNames[0], false}; #else - constexpr const char *DynamicHIPPath = "libamdhip64.so"; + // On Linux, fallback to default shared object + return {"libamdhip64.so", true}; #endif +} + +int printGPUsByHIP() { + auto [DynamicHIPPath, IsFallback] = findNewestHIPDLL(); + + if (Verbose) { + if (IsFallback) + outs() << "Using default HIP runtime: " << DynamicHIPPath << "\n"; + else + outs() << "Found HIP runtime: " << DynamicHIPPath << "\n"; ---------------- yxsamliu wrote:
will fix https://github.com/llvm/llvm-project/pull/101350 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits