jhuber6 created this revision.
jhuber6 added reviewers: jdoerfert, tianshilei1992, tra, yaxunl, 
JonChesterfield, gregrodgers.
Herald added subscribers: kosarev, kerbowa, tpr, dstuttard, jvesely, kzhuravl.
Herald added a project: All.
jhuber6 requested review of this revision.
Herald added subscribers: cfe-commits, wdng.
Herald added a project: clang.

We use the `amdgpu-arch` tool to query the installed GPUs at runtime.
One problem is that this tool is currently not build if the person
building the LLVM binary does not have the HSA runtime on their system.
This means that if someone built and distrubted an installation of LLVM
without HSA, then the user will not be able to use it even if they have
it on their system.

This patch makes us build this tool unconditionally and adds extra logic
to dynamically load HSA if it's present.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D141859

Files:
  clang/tools/amdgpu-arch/AMDGPUArch.cpp
  clang/tools/amdgpu-arch/CMakeLists.txt

Index: clang/tools/amdgpu-arch/CMakeLists.txt
===================================================================
--- clang/tools/amdgpu-arch/CMakeLists.txt
+++ clang/tools/amdgpu-arch/CMakeLists.txt
@@ -6,14 +6,13 @@
 # //
 # //===----------------------------------------------------------------------===//
 
-find_package(hsa-runtime64 QUIET 1.2.0 HINTS ${CMAKE_INSTALL_PREFIX} PATHS /opt/rocm)
-if (NOT ${hsa-runtime64_FOUND})
-  message(STATUS "Not building amdgpu-arch: hsa-runtime64 not found")
-  return()
-endif()
+set(LLVM_LINK_COMPONENTS Support)
 
 add_clang_tool(amdgpu-arch AMDGPUArch.cpp)
 
-set_target_properties(amdgpu-arch PROPERTIES INSTALL_RPATH_USE_LINK_PATH ON)
-
-clang_target_link_libraries(amdgpu-arch PRIVATE hsa-runtime64::hsa-runtime64)
+# If we find the HSA runtime we link with it directly.
+find_package(hsa-runtime64 QUIET 1.2.0 HINTS ${CMAKE_INSTALL_PREFIX} PATHS /opt/rocm)
+if (${hsa-runtime64_FOUND})
+  set_target_properties(amdgpu-arch PROPERTIES INSTALL_RPATH_USE_LINK_PATH ON)
+  clang_target_link_libraries(amdgpu-arch PRIVATE hsa-runtime64::hsa-runtime64)
+endif()
Index: clang/tools/amdgpu-arch/AMDGPUArch.cpp
===================================================================
--- clang/tools/amdgpu-arch/AMDGPUArch.cpp
+++ clang/tools/amdgpu-arch/AMDGPUArch.cpp
@@ -11,6 +11,12 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "llvm/Support/DynamicLibrary.h"
+#include "llvm/Support/Error.h"
+#include <memory>
+#include <string>
+#include <vector>
+
 #if defined(__has_include)
 #if __has_include("hsa/hsa.h")
 #define HSA_HEADER_FOUND 1
@@ -26,11 +32,62 @@
 #endif
 
 #if !HSA_HEADER_FOUND
-int main() { return 1; }
-#else
+// Forward declaration of the status enumeration used by HSA.
+typedef enum {
+  HSA_STATUS_SUCCESS = 0x0,
+} hsa_status_t;
 
-#include <string>
-#include <vector>
+// Forward declaration of the device types used by HSA.
+typedef enum {
+  HSA_DEVICE_TYPE_CPU = 0,
+  HSA_DEVICE_TYPE_GPU = 1,
+} hsa_device_type_t;
+
+// Forward declaration of the agent information types we use.
+typedef enum {
+  HSA_AGENT_INFO_NAME = 0,
+  HSA_AGENT_INFO_DEVICE = 17,
+} hsa_agent_info_t;
+
+typedef struct hsa_agent_s {
+  uint64_t handle;
+} hsa_agent_t;
+
+hsa_status_t (*hsa_init)();
+hsa_status_t (*hsa_shut_down)();
+hsa_status_t (*hsa_agent_get_info)(hsa_agent_t, hsa_agent_info_t, void *);
+hsa_status_t (*hsa_iterate_agents)(hsa_status_t (*callback)(hsa_agent_t,
+                                                            void *),
+                                   void *);
+
+constexpr const char *DynamicHSAPath = "libhsa-runtime64.so";
+
+llvm::Error loadHSA() {
+  std::string ErrMsg;
+  auto DynlibHandle = std::make_unique<llvm::sys::DynamicLibrary>(
+      llvm::sys::DynamicLibrary::getPermanentLibrary(DynamicHSAPath, &ErrMsg));
+  if (!DynlibHandle->isValid()) {
+    return llvm::createStringError(llvm::inconvertibleErrorCode(),
+                                   "Failed to 'dlopen' %s\n", DynamicHSAPath);
+  }
+#define DYNAMIC_INIT(SYMBOL)                                                   \
+  {                                                                            \
+    void *SymbolPtr = DynlibHandle->getAddressOfSymbol(#SYMBOL);               \
+    if (!SymbolPtr)                                                            \
+      return llvm::createStringError(llvm::inconvertibleErrorCode(),           \
+                                     "Failed to 'dlsym' " #SYMBOL);            \
+    SYMBOL = reinterpret_cast<decltype(SYMBOL)>(SymbolPtr);                    \
+  }
+  DYNAMIC_INIT(hsa_init);
+  DYNAMIC_INIT(hsa_shut_down);
+  DYNAMIC_INIT(hsa_agent_get_info);
+  DYNAMIC_INIT(hsa_iterate_agents);
+#undef DYNAMIC_INIT
+  return llvm::Error::success();
+}
+#else
+llvm::Error loadHSA() { return llvm::Error::success(); }
+#endif
 
 static hsa_status_t iterateAgentsCallback(hsa_agent_t Agent, void *Data) {
   hsa_device_type_t DeviceType;
@@ -54,6 +111,12 @@
 }
 
 int main() {
+  // Attempt to load the HSA runtime.
+  if (llvm::Error Err = loadHSA()) {
+    logAllUnhandledErrors(std::move(Err), llvm::errs());
+    return 1;
+  }
+
   hsa_status_t Status = hsa_init();
   if (Status != HSA_STATUS_SUCCESS) {
     return 1;
@@ -74,5 +137,3 @@
   hsa_shut_down();
   return 0;
 }
-
-#endif
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to