brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.0 KiB · 5e543e3 Raw
182 lines · cpp
1//===- LevelZeroArch.cpp - list installed Level Zero devices ---*- 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-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements a tool for detecting Level Zero devices installed in the10// system11//12//===----------------------------------------------------------------------===//13 14#include "llvm/Support/CommandLine.h"15#include "llvm/Support/DynamicLibrary.h"16#include "llvm/Support/Error.h"17#include <cstdio>18 19#define ZE_MAX_DEVICE_NAME 25620#define ZE_MAX_DEVICE_UUID_SIZE 1621 22using ze_driver_handle_t = void *;23using ze_device_handle_t = void *;24 25enum ze_result_t {26  ZE_RESULT_SUCCESS = 0,27  ZE_RESULT_ERROR_UNKNOWN = 0x7ffffffe28};29 30enum ze_structure_type_t {31  ZE_STRUCTURE_TYPE_INIT_DRIVER_TYPE_DESC = 0x00020021,32  ZE_STRUCTURE_TYPE_DEVICE_PROPERTIES = 0x3,33  ZE_STRUCTURE_TYPE_FORCE_UINT32 = 0x7fffffff34};35 36enum ze_init_driver_type_flags_t { ZE_INIT_DRIVER_TYPE_FLAG_GPU = 1 };37 38using ze_device_type_t = uint32_t;39using ze_device_property_flags_t = uint32_t;40 41struct ze_init_driver_type_desc_t {42  ze_structure_type_t stype;43  const void *pNext;44  ze_init_driver_type_flags_t flags;45};46 47struct ze_device_uuid_t {48  uint8_t id[ZE_MAX_DEVICE_UUID_SIZE];49};50 51struct ze_device_properties_t {52  ze_structure_type_t stype;53  void *pNext;54  ze_device_type_t type;55  uint32_t vendorId;56  uint32_t deviceId;57  ze_device_property_flags_t flags;58  uint32_t subdeviceId;59  uint32_t coreClockRate;60  uint64_t maxMemAllocSize;61  uint32_t maxHardwareContexts;62  uint32_t maxCommandQueuePriority;63  uint32_t numThreadsPerEU;64  uint32_t physicalEUSimdWidth;65  uint32_t numEUsPerSubslice;66  uint32_t numSubslicesPerSlice;67  uint32_t numSlices;68  uint64_t timerResolution;69  uint32_t timestampValidBits;70  uint32_t kernelTimestampValidBits;71  ze_device_uuid_t uuid;72  char name[ZE_MAX_DEVICE_NAME];73};74 75ze_result_t zeInitDrivers(uint32_t *pCount, ze_driver_handle_t *phDrivers,76                          ze_init_driver_type_desc_t *desc);77ze_result_t zeDeviceGet(ze_driver_handle_t hDriver, uint32_t *pCount,78                        void *phDevices);79ze_result_t zeDeviceGetProperties(void *hDevice, void *pProperties);80 81using namespace llvm;82extern cl::opt<bool> Verbose;83 84#define DEFINE_WRAPPER(NAME)                                                   \85  using NAME##_ty = decltype(NAME);                                            \86  void *NAME##Ptr = nullptr;                                                   \87  template <class... Ts> ze_result_t NAME##Wrapper(Ts... args) {               \88    if (!NAME##Ptr) {                                                          \89      return ZE_RESULT_ERROR_UNKNOWN;                                          \90    }                                                                          \91    return reinterpret_cast<NAME##_ty *>(NAME##Ptr)(args...);                  \92  }93 94DEFINE_WRAPPER(zeInitDrivers)95DEFINE_WRAPPER(zeDeviceGet)96DEFINE_WRAPPER(zeDeviceGetProperties)97 98static bool loadLevelZero() {99  constexpr const char *L0Library = "libze_loader.so";100  std::string ErrMsg;101 102  auto DynlibHandle = std::make_unique<llvm::sys::DynamicLibrary>(103      llvm::sys::DynamicLibrary::getPermanentLibrary(L0Library, &ErrMsg));104  if (!DynlibHandle->isValid()) {105    if (ErrMsg.empty())106      ErrMsg = "unknown error";107    if (Verbose)108      llvm::errs() << "Unable to load library '" << L0Library << "': " << ErrMsg109                   << "\n";110    return false;111  }112 113  constexpr struct {114    const char *Name;115    void **FuncPtr;116  } Wrappers[] = {117      {"zeInitDrivers", &zeInitDriversPtr},118      {"zeDeviceGet", &zeDeviceGetPtr},119      {"zeDeviceGetProperties", &zeDeviceGetPropertiesPtr},120  };121 122  for (auto Entry : Wrappers) {123    void *P = DynlibHandle->getAddressOfSymbol(Entry.Name);124    if (P == nullptr) {125      if (Verbose)126        llvm::errs() << "Unable to find '" << Entry.Name << "' in '"127                     << L0Library << "'\n";128      return false;129    }130    *(Entry.FuncPtr) = P;131  }132 133  return true;134}135 136#define CALL_ZE_AND_CHECK(Fn, ...)                                             \137  do {                                                                         \138    ze_result_t Rc = Fn##Wrapper(__VA_ARGS__);                                 \139    if (Rc != ZE_RESULT_SUCCESS) {                                             \140      if (Verbose)                                                             \141        llvm::errs() << "Error: " << __func__ << ":" << #Fn                    \142                     << " failed with error code " << Rc << "\n";              \143      return 1;                                                                \144    }                                                                          \145  } while (0)146 147int printGPUsByLevelZero() {148  if (!loadLevelZero())149    return 1;150 151  ze_init_driver_type_desc_t DriverType = {};152  DriverType.stype = ZE_STRUCTURE_TYPE_INIT_DRIVER_TYPE_DESC;153  DriverType.flags = ZE_INIT_DRIVER_TYPE_FLAG_GPU;154  DriverType.pNext = nullptr;155  uint32_t DriverCount{0};156 157  // Initialize and find all drivers.158  CALL_ZE_AND_CHECK(zeInitDrivers, &DriverCount, nullptr, &DriverType);159 160  llvm::SmallVector<ze_driver_handle_t> Drivers(DriverCount);161  CALL_ZE_AND_CHECK(zeInitDrivers, &DriverCount, Drivers.data(), &DriverType);162 163  for (auto Driver : Drivers) {164    // Discover all the devices for a given driver.165    uint32_t DeviceCount = 0;166    CALL_ZE_AND_CHECK(zeDeviceGet, Driver, &DeviceCount, nullptr);167 168    llvm::SmallVector<ze_device_handle_t> Devices(DeviceCount);169    CALL_ZE_AND_CHECK(zeDeviceGet, Driver, &DeviceCount, Devices.data());170 171    for (auto Device : Devices) {172      ze_device_properties_t DeviceProperties = {};173      DeviceProperties.stype = ZE_STRUCTURE_TYPE_DEVICE_PROPERTIES;174      DeviceProperties.pNext = nullptr;175      CALL_ZE_AND_CHECK(zeDeviceGetProperties, Device, &DeviceProperties);176      llvm::outs() << DeviceProperties.name << '\n';177    }178  }179 180  return 0;181}182