llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Alex Duran (adurang) <details> <summary>Changes</summary> --- Full diff: https://github.com/llvm/llvm-project/pull/160570.diff 3 Files Affected: - (modified) clang/tools/offload-arch/CMakeLists.txt (+9-1) - (added) clang/tools/offload-arch/LevelZeroArch.cpp (+133) - (modified) clang/tools/offload-arch/OffloadArch.cpp (+15-4) ``````````diff diff --git a/clang/tools/offload-arch/CMakeLists.txt b/clang/tools/offload-arch/CMakeLists.txt index cb50b9c1d6dde..187c4d9517551 100644 --- a/clang/tools/offload-arch/CMakeLists.txt +++ b/clang/tools/offload-arch/CMakeLists.txt @@ -1,8 +1,16 @@ set(LLVM_LINK_COMPONENTS Support) -add_clang_tool(offload-arch OffloadArch.cpp NVPTXArch.cpp AMDGPUArchByKFD.cpp AMDGPUArchByHIP.cpp) +add_clang_tool(offload-arch OffloadArch.cpp NVPTXArch.cpp AMDGPUArchByKFD.cpp + AMDGPUArchByHIP.cpp LevelZeroArch.cpp) + +find_path(OFFLOAD_ARCH_LEVEL_ZERO_INCLUDE_DIR NAMES level_zero/ze_api.h) +if (OFFLOAD_ARCH_LEVEL_ZERO_INCLUDE_DIR) + target_include_directories(offload-arch PRIVATE ${OFFLOAD_ARCH_LEVEL_ZERO_INCLUDE_DIR}) + target_compile_definitions(offload-arch PRIVATE HAVE_LEVEL_ZERO_HEADERS) +endif() add_clang_symlink(amdgpu-arch offload-arch) add_clang_symlink(nvptx-arch offload-arch) +add_clang_symlink(intelgpu-arch offload-arch) target_link_libraries(offload-arch PRIVATE clangBasic) diff --git a/clang/tools/offload-arch/LevelZeroArch.cpp b/clang/tools/offload-arch/LevelZeroArch.cpp new file mode 100644 index 0000000000000..8b6b393f6f9f6 --- /dev/null +++ b/clang/tools/offload-arch/LevelZeroArch.cpp @@ -0,0 +1,133 @@ +//===- 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 +// +//===----------------------------------------------------------------------===// + +#ifndef HAVE_LEVEL_ZERO_HEADERS + +int printGPUsByLevelZero() { + return 0; +} + +#else + +#include "clang/Basic/Version.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/DynamicLibrary.h" +#include "llvm/Support/Error.h" +#include <cstdint> +#include <cstdio> +#include <memory> +#include <level_zero/ze_api.h> + +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##_wrap(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() { + 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 **fptr; + } dlwrap[] = { + {"zeInitDrivers", &zeInitDriversPtr}, + {"zeDeviceGet", &zeDeviceGetPtr}, + {"zeDeviceGetProperties", &zeDeviceGetPropertiesPtr}, + }; + + for (auto entry : dlwrap) { + void *P = DynlibHandle->getAddressOfSymbol(entry.name); + if (P == nullptr) { + if (Verbose) + llvm::errs() << "Unable to find '" << entry.name << "' in '" << L0Library + << "'!\n"; + return false; + } + *(entry.fptr) = P; + } + + return true; +} + +#define CALL_ZE_AND_CHECK(Fn, ...) \ + do { \ + ze_result_t Rc = Fn##_wrap(__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 driver_type = {}; + driver_type.stype = ZE_STRUCTURE_TYPE_INIT_DRIVER_TYPE_DESC; + driver_type.flags = ZE_INIT_DRIVER_TYPE_FLAG_GPU; + driver_type.pNext = nullptr; + uint32_t driverCount{0}; + + // Initialize and find all drivers + CALL_ZE_AND_CHECK(zeInitDrivers, &driverCount, nullptr, &driver_type); + + llvm::SmallVector<ze_driver_handle_t> drivers(driverCount); + CALL_ZE_AND_CHECK(zeInitDrivers, &driverCount, drivers.data(), &driver_type); + + 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) { + // Get device properties + ze_device_properties_t deviceProperties; + CALL_ZE_AND_CHECK(zeDeviceGetProperties, device, &deviceProperties); + // Print device name + llvm::outs() << deviceProperties.name << '\n'; + } + } + + return 0; +} + +#endif // HAVE_LEVEL_ZERO_HEADERS diff --git a/clang/tools/offload-arch/OffloadArch.cpp b/clang/tools/offload-arch/OffloadArch.cpp index 74be40214a0ec..5043c00986a9b 100644 --- a/clang/tools/offload-arch/OffloadArch.cpp +++ b/clang/tools/offload-arch/OffloadArch.cpp @@ -21,6 +21,7 @@ enum VendorName { all, amdgpu, nvptx, + intel, }; static cl::opt<VendorName> @@ -28,7 +29,8 @@ static cl::opt<VendorName> cl::init(all), cl::values(clEnumVal(all, "Print all GPUs (default)"), clEnumVal(amdgpu, "Only print AMD GPUs"), - clEnumVal(nvptx, "Only print NVIDIA GPUs"))); + clEnumVal(nvptx, "Only print NVIDIA GPUs"), + clEnumVal(intel, "Only print Intel GPUs"))); cl::opt<bool> Verbose("verbose", cl::desc("Enable verbose output"), cl::init(false), cl::cat(OffloadArchCategory)); @@ -40,6 +42,7 @@ static void PrintVersion(raw_ostream &OS) { int printGPUsByKFD(); int printGPUsByHIP(); int printGPUsByCUDA(); +int printGPUsByLevelZero(); static int printAMD() { #ifndef _WIN32 @@ -51,6 +54,7 @@ static int printAMD() { } static int printNVIDIA() { return printGPUsByCUDA(); } +static int printIntel() { return printGPUsByLevelZero(); } int main(int argc, char *argv[]) { cl::HideUnrelatedOptions(OffloadArchCategory); @@ -73,15 +77,22 @@ int main(int argc, char *argv[]) { sys::path::stem(argv[0]).starts_with("amdgpu-arch"); bool NVIDIAOnly = Only == VendorName::nvptx || sys::path::stem(argv[0]).starts_with("nvptx-arch"); + bool IntelOnly = Only == VendorName::intel || + sys::path::stem(argv[0]).starts_with("intelgpu-arch"); + bool All = !AMDGPUOnly && !NVIDIAOnly && !IntelOnly; int NVIDIAResult = 0; - if (!AMDGPUOnly) + if (NVIDIAOnly || All) NVIDIAResult = printNVIDIA(); int AMDResult = 0; - if (!NVIDIAOnly) + if (AMDGPUOnly || All) AMDResult = printAMD(); + int IntelResult = 0; + if (IntelOnly || All) + IntelResult = printIntel(); + // We only failed if all cases returned an error. - return AMDResult && NVIDIAResult; + return AMDResult && NVIDIAResult && IntelResult; } `````````` </details> https://github.com/llvm/llvm-project/pull/160570 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits