1 //===- AMDGPUArch.cpp - list AMDGPU installed ----------*- C++ -*---------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file implements a tool for detecting name of AMDGPU installed in system 10 // using HIP runtime. This tool is used by AMDGPU OpenMP and HIP driver. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "llvm/Support/DynamicLibrary.h" 15 #include "llvm/Support/Error.h" 16 #include "llvm/Support/raw_ostream.h" 17 18 using namespace llvm; 19 20 typedef struct { 21 char padding[396]; 22 char gcnArchName[256]; 23 char padding2[1024]; 24 } hipDeviceProp_t; 25 26 typedef enum { 27 hipSuccess = 0, 28 } hipError_t; 29 30 typedef hipError_t (*hipGetDeviceCount_t)(int *); 31 typedef hipError_t (*hipDeviceGet_t)(int *, int); 32 typedef hipError_t (*hipGetDeviceProperties_t)(hipDeviceProp_t *, int); 33 34 int printGPUsByHIP() { 35 #ifdef _WIN32 36 constexpr const char *DynamicHIPPath = "amdhip64.dll"; 37 #else 38 constexpr const char *DynamicHIPPath = "libamdhip64.so"; 39 #endif 40 41 std::string ErrMsg; 42 auto DynlibHandle = std::make_unique<llvm::sys::DynamicLibrary>( 43 llvm::sys::DynamicLibrary::getPermanentLibrary(DynamicHIPPath, &ErrMsg)); 44 if (!DynlibHandle->isValid()) { 45 llvm::errs() << "Failed to load " << DynamicHIPPath << ": " << ErrMsg 46 << '\n'; 47 return 1; 48 } 49 50 #define DYNAMIC_INIT_HIP(SYMBOL) \ 51 { \ 52 void *SymbolPtr = DynlibHandle->getAddressOfSymbol(#SYMBOL); \ 53 if (!SymbolPtr) { \ 54 llvm::errs() << "Failed to find symbol " << #SYMBOL << '\n'; \ 55 return 1; \ 56 } \ 57 SYMBOL = reinterpret_cast<decltype(SYMBOL)>(SymbolPtr); \ 58 } 59 60 hipGetDeviceCount_t hipGetDeviceCount; 61 hipDeviceGet_t hipDeviceGet; 62 hipGetDeviceProperties_t hipGetDeviceProperties; 63 64 DYNAMIC_INIT_HIP(hipGetDeviceCount); 65 DYNAMIC_INIT_HIP(hipDeviceGet); 66 DYNAMIC_INIT_HIP(hipGetDeviceProperties); 67 68 #undef DYNAMIC_INIT_HIP 69 70 int deviceCount; 71 hipError_t err = hipGetDeviceCount(&deviceCount); 72 if (err != hipSuccess) { 73 llvm::errs() << "Failed to get device count\n"; 74 return 1; 75 } 76 77 for (int i = 0; i < deviceCount; ++i) { 78 int deviceId; 79 err = hipDeviceGet(&deviceId, i); 80 if (err != hipSuccess) { 81 llvm::errs() << "Failed to get device id for ordinal " << i << '\n'; 82 return 1; 83 } 84 85 hipDeviceProp_t prop; 86 err = hipGetDeviceProperties(&prop, deviceId); 87 if (err != hipSuccess) { 88 llvm::errs() << "Failed to get device properties for device " << deviceId 89 << '\n'; 90 return 1; 91 } 92 llvm::outs() << prop.gcnArchName << '\n'; 93 } 94 95 return 0; 96 } 97