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) Liuint 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