xref: /llvm-project/clang/tools/amdgpu-arch/AMDGPUArchByHIP.cpp (revision 0a15574eec7715e09b6fd52d3cd9a4f6e2b797e9)
1*0a15574eSJacob Lambert //===- AMDGPUArchByHIP.cpp - list AMDGPU installed ----------*- C++ -*-----===//
2661d91a0SYaxun (Sam) Liu //
3661d91a0SYaxun (Sam) Liu // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4661d91a0SYaxun (Sam) Liu // See https://llvm.org/LICENSE.txt for license information.
5661d91a0SYaxun (Sam) Liu // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6661d91a0SYaxun (Sam) Liu //
7661d91a0SYaxun (Sam) Liu //===----------------------------------------------------------------------===//
8661d91a0SYaxun (Sam) Liu //
9661d91a0SYaxun (Sam) Liu // This file implements a tool for detecting name of AMDGPU installed in system
10661d91a0SYaxun (Sam) Liu // using HIP runtime. This tool is used by AMDGPU OpenMP and HIP driver.
11661d91a0SYaxun (Sam) Liu //
12661d91a0SYaxun (Sam) Liu //===----------------------------------------------------------------------===//
13661d91a0SYaxun (Sam) Liu 
14661d91a0SYaxun (Sam) Liu #include "llvm/Support/DynamicLibrary.h"
15661d91a0SYaxun (Sam) Liu #include "llvm/Support/Error.h"
16661d91a0SYaxun (Sam) Liu #include "llvm/Support/raw_ostream.h"
17661d91a0SYaxun (Sam) Liu 
18661d91a0SYaxun (Sam) Liu using namespace llvm;
19661d91a0SYaxun (Sam) Liu 
20661d91a0SYaxun (Sam) Liu typedef struct {
21661d91a0SYaxun (Sam) Liu   char padding[396];
22661d91a0SYaxun (Sam) Liu   char gcnArchName[256];
23661d91a0SYaxun (Sam) Liu   char padding2[1024];
24661d91a0SYaxun (Sam) Liu } hipDeviceProp_t;
25661d91a0SYaxun (Sam) Liu 
26661d91a0SYaxun (Sam) Liu typedef enum {
27661d91a0SYaxun (Sam) Liu   hipSuccess = 0,
28661d91a0SYaxun (Sam) Liu } hipError_t;
29661d91a0SYaxun (Sam) Liu 
30661d91a0SYaxun (Sam) Liu typedef hipError_t (*hipGetDeviceCount_t)(int *);
31661d91a0SYaxun (Sam) Liu typedef hipError_t (*hipDeviceGet_t)(int *, int);
32661d91a0SYaxun (Sam) Liu typedef hipError_t (*hipGetDeviceProperties_t)(hipDeviceProp_t *, int);
33661d91a0SYaxun (Sam) Liu 
printGPUsByHIP()34661d91a0SYaxun (Sam) Liu int printGPUsByHIP() {
35661d91a0SYaxun (Sam) Liu #ifdef _WIN32
36661d91a0SYaxun (Sam) Liu   constexpr const char *DynamicHIPPath = "amdhip64.dll";
37661d91a0SYaxun (Sam) Liu #else
38661d91a0SYaxun (Sam) Liu   constexpr const char *DynamicHIPPath = "libamdhip64.so";
39661d91a0SYaxun (Sam) Liu #endif
40661d91a0SYaxun (Sam) Liu 
41661d91a0SYaxun (Sam) Liu   std::string ErrMsg;
42661d91a0SYaxun (Sam) Liu   auto DynlibHandle = std::make_unique<llvm::sys::DynamicLibrary>(
43661d91a0SYaxun (Sam) Liu       llvm::sys::DynamicLibrary::getPermanentLibrary(DynamicHIPPath, &ErrMsg));
44661d91a0SYaxun (Sam) Liu   if (!DynlibHandle->isValid()) {
45661d91a0SYaxun (Sam) Liu     llvm::errs() << "Failed to load " << DynamicHIPPath << ": " << ErrMsg
46661d91a0SYaxun (Sam) Liu                  << '\n';
47661d91a0SYaxun (Sam) Liu     return 1;
48661d91a0SYaxun (Sam) Liu   }
49661d91a0SYaxun (Sam) Liu 
50661d91a0SYaxun (Sam) Liu #define DYNAMIC_INIT_HIP(SYMBOL)                                               \
51661d91a0SYaxun (Sam) Liu   {                                                                            \
52661d91a0SYaxun (Sam) Liu     void *SymbolPtr = DynlibHandle->getAddressOfSymbol(#SYMBOL);               \
53661d91a0SYaxun (Sam) Liu     if (!SymbolPtr) {                                                          \
54661d91a0SYaxun (Sam) Liu       llvm::errs() << "Failed to find symbol " << #SYMBOL << '\n';             \
55661d91a0SYaxun (Sam) Liu       return 1;                                                                \
56661d91a0SYaxun (Sam) Liu     }                                                                          \
57661d91a0SYaxun (Sam) Liu     SYMBOL = reinterpret_cast<decltype(SYMBOL)>(SymbolPtr);                    \
58661d91a0SYaxun (Sam) Liu   }
59661d91a0SYaxun (Sam) Liu 
60661d91a0SYaxun (Sam) Liu   hipGetDeviceCount_t hipGetDeviceCount;
61661d91a0SYaxun (Sam) Liu   hipDeviceGet_t hipDeviceGet;
62661d91a0SYaxun (Sam) Liu   hipGetDeviceProperties_t hipGetDeviceProperties;
63661d91a0SYaxun (Sam) Liu 
64661d91a0SYaxun (Sam) Liu   DYNAMIC_INIT_HIP(hipGetDeviceCount);
65661d91a0SYaxun (Sam) Liu   DYNAMIC_INIT_HIP(hipDeviceGet);
66661d91a0SYaxun (Sam) Liu   DYNAMIC_INIT_HIP(hipGetDeviceProperties);
67661d91a0SYaxun (Sam) Liu 
68661d91a0SYaxun (Sam) Liu #undef DYNAMIC_INIT_HIP
69661d91a0SYaxun (Sam) Liu 
70661d91a0SYaxun (Sam) Liu   int deviceCount;
71661d91a0SYaxun (Sam) Liu   hipError_t err = hipGetDeviceCount(&deviceCount);
72661d91a0SYaxun (Sam) Liu   if (err != hipSuccess) {
73661d91a0SYaxun (Sam) Liu     llvm::errs() << "Failed to get device count\n";
74661d91a0SYaxun (Sam) Liu     return 1;
75661d91a0SYaxun (Sam) Liu   }
76661d91a0SYaxun (Sam) Liu 
77661d91a0SYaxun (Sam) Liu   for (int i = 0; i < deviceCount; ++i) {
78661d91a0SYaxun (Sam) Liu     int deviceId;
79661d91a0SYaxun (Sam) Liu     err = hipDeviceGet(&deviceId, i);
80661d91a0SYaxun (Sam) Liu     if (err != hipSuccess) {
81661d91a0SYaxun (Sam) Liu       llvm::errs() << "Failed to get device id for ordinal " << i << '\n';
82661d91a0SYaxun (Sam) Liu       return 1;
83661d91a0SYaxun (Sam) Liu     }
84661d91a0SYaxun (Sam) Liu 
85661d91a0SYaxun (Sam) Liu     hipDeviceProp_t prop;
86661d91a0SYaxun (Sam) Liu     err = hipGetDeviceProperties(&prop, deviceId);
87661d91a0SYaxun (Sam) Liu     if (err != hipSuccess) {
88661d91a0SYaxun (Sam) Liu       llvm::errs() << "Failed to get device properties for device " << deviceId
89661d91a0SYaxun (Sam) Liu                    << '\n';
90661d91a0SYaxun (Sam) Liu       return 1;
91661d91a0SYaxun (Sam) Liu     }
92661d91a0SYaxun (Sam) Liu     llvm::outs() << prop.gcnArchName << '\n';
93661d91a0SYaxun (Sam) Liu   }
94661d91a0SYaxun (Sam) Liu 
95661d91a0SYaxun (Sam) Liu   return 0;
96661d91a0SYaxun (Sam) Liu }
97