This patch fixes: clang/tools/offload-arch/LevelZeroArch.cpp:94:1: error: extra ';' outside of a function is incompatible with C++98 [-Werror,-Wc++98-compat-extra-semi] clang/tools/offload-arch/LevelZeroArch.cpp:95:1: error: extra ';' outside of a function is incompatible with C++98 [-Werror,-Wc++98-compat-extra-semi] clang/tools/offload-arch/LevelZeroArch.cpp:96:1: error: extra ';' outside of a function is incompatible with C++98 [-Werror,-Wc++98-compat-extra-semi] clang/tools/offload-arch/LevelZeroArch.cpp:173:55: error: missing field 'type' initializer [-Werror,-Wmissing-field-initializers]
182 lines
6.0 KiB
C++
182 lines
6.0 KiB
C++
//===- LevelZeroArch.cpp - list installed Level Zero devices ---*- C++ -*--===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file implements a tool for detecting Level Zero devices installed in the
|
|
// system
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/Support/CommandLine.h"
|
|
#include "llvm/Support/DynamicLibrary.h"
|
|
#include "llvm/Support/Error.h"
|
|
#include <cstdio>
|
|
|
|
#define ZE_MAX_DEVICE_NAME 256
|
|
#define ZE_MAX_DEVICE_UUID_SIZE 16
|
|
|
|
using ze_driver_handle_t = void *;
|
|
using ze_device_handle_t = void *;
|
|
|
|
enum ze_result_t {
|
|
ZE_RESULT_SUCCESS = 0,
|
|
ZE_RESULT_ERROR_UNKNOWN = 0x7ffffffe
|
|
};
|
|
|
|
enum ze_structure_type_t {
|
|
ZE_STRUCTURE_TYPE_INIT_DRIVER_TYPE_DESC = 0x00020021,
|
|
ZE_STRUCTURE_TYPE_DEVICE_PROPERTIES = 0x3,
|
|
ZE_STRUCTURE_TYPE_FORCE_UINT32 = 0x7fffffff
|
|
};
|
|
|
|
enum ze_init_driver_type_flags_t { ZE_INIT_DRIVER_TYPE_FLAG_GPU = 1 };
|
|
|
|
using ze_device_type_t = uint32_t;
|
|
using ze_device_property_flags_t = uint32_t;
|
|
|
|
struct ze_init_driver_type_desc_t {
|
|
ze_structure_type_t stype;
|
|
const void *pNext;
|
|
ze_init_driver_type_flags_t flags;
|
|
};
|
|
|
|
struct ze_device_uuid_t {
|
|
uint8_t id[ZE_MAX_DEVICE_UUID_SIZE];
|
|
};
|
|
|
|
struct ze_device_properties_t {
|
|
ze_structure_type_t stype;
|
|
void *pNext;
|
|
ze_device_type_t type;
|
|
uint32_t vendorId;
|
|
uint32_t deviceId;
|
|
ze_device_property_flags_t flags;
|
|
uint32_t subdeviceId;
|
|
uint32_t coreClockRate;
|
|
uint64_t maxMemAllocSize;
|
|
uint32_t maxHardwareContexts;
|
|
uint32_t maxCommandQueuePriority;
|
|
uint32_t numThreadsPerEU;
|
|
uint32_t physicalEUSimdWidth;
|
|
uint32_t numEUsPerSubslice;
|
|
uint32_t numSubslicesPerSlice;
|
|
uint32_t numSlices;
|
|
uint64_t timerResolution;
|
|
uint32_t timestampValidBits;
|
|
uint32_t kernelTimestampValidBits;
|
|
ze_device_uuid_t uuid;
|
|
char name[ZE_MAX_DEVICE_NAME];
|
|
};
|
|
|
|
ze_result_t zeInitDrivers(uint32_t *pCount, ze_driver_handle_t *phDrivers,
|
|
ze_init_driver_type_desc_t *desc);
|
|
ze_result_t zeDeviceGet(ze_driver_handle_t hDriver, uint32_t *pCount,
|
|
void *phDevices);
|
|
ze_result_t zeDeviceGetProperties(void *hDevice, void *pProperties);
|
|
|
|
using namespace llvm;
|
|
extern cl::opt<bool> Verbose;
|
|
|
|
#define DEFINE_WRAPPER(NAME) \
|
|
using NAME##_ty = decltype(NAME); \
|
|
void *NAME##Ptr = nullptr; \
|
|
template <class... Ts> ze_result_t NAME##Wrapper(Ts... args) { \
|
|
if (!NAME##Ptr) { \
|
|
return ZE_RESULT_ERROR_UNKNOWN; \
|
|
} \
|
|
return reinterpret_cast<NAME##_ty *>(NAME##Ptr)(args...); \
|
|
}
|
|
|
|
DEFINE_WRAPPER(zeInitDrivers)
|
|
DEFINE_WRAPPER(zeDeviceGet)
|
|
DEFINE_WRAPPER(zeDeviceGetProperties)
|
|
|
|
static bool loadLevelZero() {
|
|
constexpr const char *L0Library = "libze_loader.so";
|
|
std::string ErrMsg;
|
|
|
|
auto DynlibHandle = std::make_unique<llvm::sys::DynamicLibrary>(
|
|
llvm::sys::DynamicLibrary::getPermanentLibrary(L0Library, &ErrMsg));
|
|
if (!DynlibHandle->isValid()) {
|
|
if (ErrMsg.empty())
|
|
ErrMsg = "unknown error";
|
|
if (Verbose)
|
|
llvm::errs() << "Unable to load library '" << L0Library << "': " << ErrMsg
|
|
<< "\n";
|
|
return false;
|
|
}
|
|
|
|
constexpr struct {
|
|
const char *Name;
|
|
void **FuncPtr;
|
|
} Wrappers[] = {
|
|
{"zeInitDrivers", &zeInitDriversPtr},
|
|
{"zeDeviceGet", &zeDeviceGetPtr},
|
|
{"zeDeviceGetProperties", &zeDeviceGetPropertiesPtr},
|
|
};
|
|
|
|
for (auto Entry : Wrappers) {
|
|
void *P = DynlibHandle->getAddressOfSymbol(Entry.Name);
|
|
if (P == nullptr) {
|
|
if (Verbose)
|
|
llvm::errs() << "Unable to find '" << Entry.Name << "' in '"
|
|
<< L0Library << "'\n";
|
|
return false;
|
|
}
|
|
*(Entry.FuncPtr) = P;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
#define CALL_ZE_AND_CHECK(Fn, ...) \
|
|
do { \
|
|
ze_result_t Rc = Fn##Wrapper(__VA_ARGS__); \
|
|
if (Rc != ZE_RESULT_SUCCESS) { \
|
|
if (Verbose) \
|
|
llvm::errs() << "Error: " << __func__ << ":" << #Fn \
|
|
<< " failed with error code " << Rc << "\n"; \
|
|
return 1; \
|
|
} \
|
|
} while (0)
|
|
|
|
int printGPUsByLevelZero() {
|
|
if (!loadLevelZero())
|
|
return 1;
|
|
|
|
ze_init_driver_type_desc_t DriverType = {};
|
|
DriverType.stype = ZE_STRUCTURE_TYPE_INIT_DRIVER_TYPE_DESC;
|
|
DriverType.flags = ZE_INIT_DRIVER_TYPE_FLAG_GPU;
|
|
DriverType.pNext = nullptr;
|
|
uint32_t DriverCount{0};
|
|
|
|
// Initialize and find all drivers.
|
|
CALL_ZE_AND_CHECK(zeInitDrivers, &DriverCount, nullptr, &DriverType);
|
|
|
|
llvm::SmallVector<ze_driver_handle_t> Drivers(DriverCount);
|
|
CALL_ZE_AND_CHECK(zeInitDrivers, &DriverCount, Drivers.data(), &DriverType);
|
|
|
|
for (auto Driver : Drivers) {
|
|
// Discover all the devices for a given driver.
|
|
uint32_t DeviceCount = 0;
|
|
CALL_ZE_AND_CHECK(zeDeviceGet, Driver, &DeviceCount, nullptr);
|
|
|
|
llvm::SmallVector<ze_device_handle_t> Devices(DeviceCount);
|
|
CALL_ZE_AND_CHECK(zeDeviceGet, Driver, &DeviceCount, Devices.data());
|
|
|
|
for (auto Device : Devices) {
|
|
ze_device_properties_t DeviceProperties = {};
|
|
DeviceProperties.stype = ZE_STRUCTURE_TYPE_DEVICE_PROPERTIES;
|
|
DeviceProperties.pNext = nullptr;
|
|
CALL_ZE_AND_CHECK(zeDeviceGetProperties, Device, &DeviceProperties);
|
|
llvm::outs() << DeviceProperties.name << '\n';
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|