1//===- OffloadArch.cpp - list available GPUs ------------------------------===//
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#include "clang/Basic/Version.h"
10#include "llvm/Support/CommandLine.h"
11#include "llvm/Support/Path.h"
12
13using namespace llvm;
14
15static cl::opt<bool> Help("h", cl::desc("Alias for -help"), cl::Hidden);
16
17// Mark all our options with this category.
18static cl::OptionCategory OffloadArchCategory("offload-arch options");
19
20extern cl::OptionCategory AMDGPUArchByHIPCategory;
21
22enum VendorName {
23 all,
24 amdgpu,
25 nvptx,
26 intel,
27};
28
29static cl::opt<VendorName>
30 Only("only", cl::desc("Restrict to vendor:"), cl::cat(OffloadArchCategory),
31 cl::init(Val: all),
32 cl::values(clEnumVal(all, "Print all GPUs (default)"),
33 clEnumVal(amdgpu, "Only print AMD GPUs"),
34 clEnumVal(nvptx, "Only print NVIDIA GPUs"),
35 clEnumVal(intel, "Only print Intel GPUs")));
36
37cl::opt<bool> Verbose("verbose", cl::desc("Enable verbose output"),
38 cl::init(Val: false), cl::cat(OffloadArchCategory));
39
40static void PrintVersion(raw_ostream &OS) {
41 OS << clang::getClangToolFullVersion(ToolName: "offload-arch") << '\n';
42}
43
44int printGPUsByKFD();
45int printGPUsByHIP();
46int printGPUsByCUDA();
47int printGPUsByLevelZero();
48
49static int printAMD() {
50#ifndef _WIN32
51 if (!printGPUsByKFD())
52 return 0;
53#endif
54
55 return printGPUsByHIP();
56}
57
58static int printNVIDIA() { return printGPUsByCUDA(); }
59static int printIntel() { return printGPUsByLevelZero(); }
60
61const std::array<std::pair<VendorName, function_ref<int()>>, 3> VendorTable{
62 ._M_elems: {{VendorName::amdgpu, printAMD},
63 {VendorName::nvptx, printNVIDIA},
64 {VendorName::intel, printIntel}}};
65
66int main(int argc, char *argv[]) {
67 cl::HideUnrelatedOptions(Categories: {&OffloadArchCategory, &AMDGPUArchByHIPCategory});
68
69 cl::SetVersionPrinter(PrintVersion);
70 cl::ParseCommandLineOptions(
71 argc, argv,
72 Overview: "A tool to detect the presence of offloading devices on the system. \n\n"
73 "The tool will output each detected GPU architecture separated by a\n"
74 "newline character. If multiple GPUs of the same architecture are found\n"
75 "a string will be printed for each\n");
76
77 if (Help) {
78 cl::PrintHelpMessage();
79 return 0;
80 }
81
82 // Support legacy binaries.
83 if (sys::path::stem(path: argv[0]).starts_with(Prefix: "amdgpu-arch"))
84 Only = VendorName::amdgpu;
85 if (sys::path::stem(path: argv[0]).starts_with(Prefix: "nvptx-arch"))
86 Only = VendorName::nvptx;
87
88 int Result = 1;
89 for (auto [Name, Func] : VendorTable) {
90 if (Only == VendorName::all || Only == Name)
91 Result &= Func();
92 }
93
94 return Result;
95}
96