1 //===- AMDGPUArchByKFD.cpp - list AMDGPU installed ------*- C++ -*---------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file implements a tool for detecting name of AMD GPUs installed in
10 // system using the Linux sysfs interface for the AMD KFD driver. This file does
11 // not respect ROCR_VISIBLE_DEVICES like the ROCm environment would.
13 //===----------------------------------------------------------------------===//
15 #include "llvm/Support/FileSystem.h"
16 #include "llvm/Support/LineIterator.h"
17 #include "llvm/Support/MemoryBuffer.h"
18 #include "llvm/Support/Path.h"
23 constexpr static const char *KFD_SYSFS_NODE_PATH
=
24 "/sys/devices/virtual/kfd/kfd/topology/nodes";
26 // See the ROCm implementation for how this is handled.
27 // https://github.com/ROCm/ROCT-Thunk-Interface/blob/master/src/libhsakmt.h#L126
28 constexpr static long getMajor(long Ver
) { return (Ver
/ 10000) % 100; }
29 constexpr static long getMinor(long Ver
) { return (Ver
/ 100) % 100; }
30 constexpr static long getStep(long Ver
) { return Ver
% 100; }
32 int printGPUsByKFD() {
33 SmallVector
<std::pair
<long, long>> Devices
;
35 for (sys::fs::directory_iterator
Begin(KFD_SYSFS_NODE_PATH
, EC
), End
;
36 Begin
!= End
; Begin
.increment(EC
)) {
41 if (sys::path::stem(Begin
->path()).consumeInteger(10, Node
))
44 SmallString
<0> Path(Begin
->path());
45 sys::path::append(Path
, "properties");
47 ErrorOr
<std::unique_ptr
<MemoryBuffer
>> BufferOrErr
=
48 MemoryBuffer::getFileOrSTDIN(Path
);
49 if (std::error_code EC
= BufferOrErr
.getError())
53 for (line_iterator
Lines(**BufferOrErr
, false); !Lines
.is_at_end();
55 StringRef
Line(*Lines
);
56 if (Line
.consume_front("gfx_target_version")) {
57 if (Line
.drop_while([](char C
) { return std::isspace(C
); })
58 .consumeInteger(10, GFXVersion
))
64 // If this is zero the node is a CPU.
67 Devices
.emplace_back(Node
, GFXVersion
);
70 // Sort the devices by their node to make sure it prints in order.
71 llvm::sort(Devices
, [](auto &L
, auto &R
) { return L
.first
< R
.first
; });
72 for (const auto &[Node
, GFXVersion
] : Devices
)
73 std::fprintf(stdout
, "gfx%ld%ld%lx\n", getMajor(GFXVersion
),
74 getMinor(GFXVersion
), getStep(GFXVersion
));