Compare commits
6 Commits
master
...
amd-suppor
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8021aecb8c | ||
|
|
b788bb7476 | ||
|
|
b5f8139038 | ||
|
|
60a1ef70d8 | ||
|
|
14c745f7cb | ||
|
|
2f5a41a135 |
@@ -7,17 +7,18 @@ project(gpufetch CXX)
|
||||
set(SRC_DIR "src")
|
||||
set(COMMON_DIR "${SRC_DIR}/common")
|
||||
set(CUDA_DIR "${SRC_DIR}/cuda")
|
||||
set(HSA_DIR "${SRC_DIR}/hsa")
|
||||
set(INTEL_DIR "${SRC_DIR}/intel")
|
||||
|
||||
# Enable Intel backend by default
|
||||
if(NOT DEFINED ENABLE_INTEL_BACKEND)
|
||||
set(ENABLE_INTEL_BACKEND true)
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED ENABLE_CUDA_BACKEND OR ENABLE_CUDA_BACKEND)
|
||||
if(ENABLE_CUDA_BACKEND)
|
||||
check_language(CUDA)
|
||||
if(CMAKE_CUDA_COMPILER)
|
||||
enable_language(CUDA)
|
||||
set(ENABLE_CUDA_BACKEND true)
|
||||
# Must link_directories early so add_executable(gpufetch ...) gets the right directories
|
||||
link_directories(cuda_backend ${CMAKE_CUDA_COMPILER_TOOLKIT_ROOT}/targets/x86_64-linux/lib)
|
||||
else()
|
||||
@@ -25,6 +26,34 @@ if(NOT DEFINED ENABLE_CUDA_BACKEND OR ENABLE_CUDA_BACKEND)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(ENABLE_HSA_BACKEND)
|
||||
# TODO: Needs rocm-cmake, what if its not insalled?
|
||||
find_package(ROCmCMakeBuildTools)
|
||||
if (ROCmCMakeBuildTools_FOUND)
|
||||
find_package(hsa-runtime64 1.0 REQUIRED)
|
||||
link_directories(hsa_backend hsa-runtime64::hsa-runtime64)
|
||||
|
||||
# Find HSA headers
|
||||
# ROCm does not seem to provide this, which is quite frustrating.
|
||||
find_path(HSA_INCLUDE_DIR
|
||||
NAMES hsa/hsa.h
|
||||
HINTS
|
||||
$ENV{ROCM_PATH}/include # allow users override via env variable
|
||||
/opt/rocm/include # common default path
|
||||
/usr/include
|
||||
/usr/local/include
|
||||
)
|
||||
|
||||
if(NOT HSA_INCLUDE_DIR)
|
||||
message(STATUS "${BoldYellow}HSA not found, disabling HSA backend${ColorReset}")
|
||||
set(ENABLE_HSA_BACKEND false)
|
||||
endif()
|
||||
else()
|
||||
set(ENABLE_HSA_BACKEND false)
|
||||
message(STATUS "${BoldYellow}ROCm not found${ColorReset}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
|
||||
find_package(PCIUTILS)
|
||||
if(NOT ${PCIUTILS_FOUND})
|
||||
@@ -50,8 +79,9 @@ else()
|
||||
endif()
|
||||
|
||||
add_executable(gpufetch ${COMMON_DIR}/main.cpp ${COMMON_DIR}/args.cpp ${COMMON_DIR}/gpu.cpp ${COMMON_DIR}/pci.cpp ${COMMON_DIR}/sort.cpp ${COMMON_DIR}/global.cpp ${COMMON_DIR}/printer.cpp ${COMMON_DIR}/master.cpp ${COMMON_DIR}/uarch.cpp)
|
||||
set(SANITY_FLAGS "-Wfloat-equal -Wshadow -Wpointer-arith")
|
||||
set(CMAKE_CXX_FLAGS "${SANITY_FLAGS} -Wall -Wextra -pedantic -fstack-protector-all -pedantic -std=c++11")
|
||||
set(SANITY_FLAGS -Wfloat-equal -Wshadow -Wpointer-arith -Wall -Wextra -pedantic -fstack-protector-all -pedantic)
|
||||
target_compile_features(gpufetch PRIVATE cxx_std_11)
|
||||
target_compile_options(gpufetch PRIVATE ${SANITY_FLAGS})
|
||||
|
||||
if(ENABLE_INTEL_BACKEND)
|
||||
target_compile_definitions(gpufetch PUBLIC BACKEND_INTEL)
|
||||
@@ -94,6 +124,22 @@ if(ENABLE_CUDA_BACKEND)
|
||||
target_link_libraries(gpufetch cuda_backend)
|
||||
endif()
|
||||
|
||||
if(ENABLE_HSA_BACKEND)
|
||||
target_compile_definitions(gpufetch PUBLIC BACKEND_HSA)
|
||||
|
||||
add_library(hsa_backend STATIC ${HSA_DIR}/hsa.cpp)
|
||||
|
||||
if(NOT ${PCIUTILS_FOUND})
|
||||
add_dependencies(hsa_backend pciutils)
|
||||
endif()
|
||||
|
||||
target_include_directories(hsa_backend PRIVATE "${HSA_INCLUDE_DIR}")
|
||||
message(STATUS "Found HSA: ${HSA_INCLUDE_DIR}")
|
||||
|
||||
target_link_libraries(hsa_backend PRIVATE hsa-runtime64::hsa-runtime64)
|
||||
target_link_libraries(gpufetch hsa_backend)
|
||||
endif()
|
||||
|
||||
target_link_libraries(gpufetch pci z)
|
||||
install(TARGETS gpufetch DESTINATION bin)
|
||||
|
||||
@@ -115,6 +161,11 @@ if(ENABLE_CUDA_BACKEND)
|
||||
else()
|
||||
message(STATUS "CUDA backend: ${BoldRed}OFF${ColorReset}")
|
||||
endif()
|
||||
if(ENABLE_HSA_BACKEND)
|
||||
message(STATUS "HSA backend: ${BoldGreen}ON${ColorReset}")
|
||||
else()
|
||||
message(STATUS "HSA backend: ${BoldRed}OFF${ColorReset}")
|
||||
endif()
|
||||
if(ENABLE_INTEL_BACKEND)
|
||||
message(STATUS "Intel backend: ${BoldGreen}ON${ColorReset}")
|
||||
else()
|
||||
|
||||
24
README.md
24
README.md
@@ -33,15 +33,16 @@ gpufetch is a command-line tool written in C++ that displays the GPU information
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
|
||||
|
||||
- [1. Support](#1-support)
|
||||
- [2. Backends](#2-backends)
|
||||
- [2.1 CUDA backend is not enabled. Why?](#21-cuda-backend-is-not-enabled-why)
|
||||
- [2.2 The backend is enabled, but gpufetch is unable to detect my GPU](#22-the-backend-is-enabled-but-gpufetch-is-unable-to-detect-my-gpu)
|
||||
- [3. Installation (building from source)](#3-installation-building-from-source)
|
||||
- [4. Colors](#4-colors)
|
||||
- [4.1 Specifying a name](#41-specifying-a-name)
|
||||
- [4.2 Specifying the colors in RGB format](#42-specifying-the-colors-in-rgb-format)
|
||||
- [5. Bugs or improvements](#5-bugs-or-improvements)
|
||||
- [Table of contents](#table-of-contents)
|
||||
- [1. Support](#1-support)
|
||||
- [2. Backends](#2-backends)
|
||||
- [2.1 CUDA backend is not enabled. Why?](#21-cuda-backend-is-not-enabled-why)
|
||||
- [2.2 The backend is enabled, but gpufetch is unable to detect my GPU](#22-the-backend-is-enabled-but-gpufetch-is-unable-to-detect-my-gpu)
|
||||
- [3. Installation (building from source)](#3-installation-building-from-source)
|
||||
- [4. Colors](#4-colors)
|
||||
- [4.1 Specifying a name](#41-specifying-a-name)
|
||||
- [4.2 Specifying the colors in RGB format](#42-specifying-the-colors-in-rgb-format)
|
||||
- [5. Bugs or improvements](#5-bugs-or-improvements)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
|
||||
@@ -49,14 +50,16 @@ gpufetch is a command-line tool written in C++ that displays the GPU information
|
||||
gpufetch supports the following GPUs:
|
||||
|
||||
- **NVIDIA** GPUs (Compute Capability >= 2.0)
|
||||
- **AMD** GPUs (Experimental) (RDNA 3.0, CDNA 3.0)
|
||||
- **Intel** iGPUs (Generation >= Gen6)
|
||||
|
||||
Only compilation under **Linux** is supported.
|
||||
|
||||
## 2. Backends
|
||||
gpufetch is made up of two backends:
|
||||
gpufetch is made up of three backends:
|
||||
|
||||
- CUDA backend
|
||||
- HSA backend
|
||||
- Intel backend
|
||||
|
||||
Backends are enabled and disabled at **compile time**. When compiling gpufetch, check the CMake output to see which backends are enabled.
|
||||
@@ -111,6 +114,7 @@ By default, `gpufetch` will print the GPU logo with the system color scheme. How
|
||||
By specifying a name, gpufetch will use the specific colors of each manufacture. Valid values are:
|
||||
|
||||
- intel
|
||||
- amd
|
||||
- nvidia
|
||||
|
||||
```
|
||||
|
||||
2
build.sh
2
build.sh
@@ -23,6 +23,8 @@ fi
|
||||
# In case you want to explicitely disable a backend, you can:
|
||||
# Disable CUDA backend:
|
||||
# cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DENABLE_CUDA_BACKEND=OFF ..
|
||||
# Disable HSA backend:
|
||||
# cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DENABLE_HSA_BACKEND=OFF ..
|
||||
# Disable Intel backend:
|
||||
# cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DENABLE_INTEL_BACKEND=OFF ..
|
||||
|
||||
|
||||
@@ -13,12 +13,14 @@
|
||||
#define NUM_COLORS 4
|
||||
|
||||
#define COLOR_STR_NVIDIA "nvidia"
|
||||
#define COLOR_STR_AMD "amd"
|
||||
#define COLOR_STR_INTEL "intel"
|
||||
|
||||
// +-----------------------+-----------------------+
|
||||
// | Color logo | Color text |
|
||||
// | Color 1 | Color 2 | Color 1 | Color 2 |
|
||||
#define COLOR_DEFAULT_NVIDIA "118,185,000:255,255,255:255,255,255:118,185,000"
|
||||
#define COLOR_DEFAULT_AMD "250,250,250:250,250,250:200,200,200:255,255,255"
|
||||
#define COLOR_DEFAULT_INTEL "015,125,194:230,230,230:040,150,220:230,230,230"
|
||||
|
||||
struct args_struct {
|
||||
@@ -168,6 +170,7 @@ bool parse_color(char* optarg_str, struct color*** cs) {
|
||||
bool free_ptr = true;
|
||||
|
||||
if(strcmp(optarg_str, COLOR_STR_NVIDIA) == 0) color_to_copy = COLOR_DEFAULT_NVIDIA;
|
||||
else if(strcmp(optarg_str, COLOR_STR_AMD) == 0) color_to_copy = COLOR_DEFAULT_AMD;
|
||||
else if(strcmp(optarg_str, COLOR_STR_INTEL) == 0) color_to_copy = COLOR_DEFAULT_INTEL;
|
||||
else {
|
||||
str_to_parse = optarg_str;
|
||||
|
||||
@@ -34,6 +34,23 @@ $C2## ## ## ## ## ## ## ## #: :# \
|
||||
$C2## ## ## ## ## ## ## ## ####### \
|
||||
$C2## ## ### ## ###### ## ## ## "
|
||||
|
||||
#define ASCII_AMD \
|
||||
"$C2 '############### \
|
||||
$C2 ,############# \
|
||||
$C2 .#### \
|
||||
$C2 #. .#### \
|
||||
$C2 :##. .#### \
|
||||
$C2 :###. .#### \
|
||||
$C2 #########. :## \
|
||||
$C2 #######. ; \
|
||||
$C1 \
|
||||
$C1 ### ### ### ####### \
|
||||
$C1 ## ## ##### ##### ## ## \
|
||||
$C1 ## ## ### #### ### ## ## \
|
||||
$C1 ######### ### ## ### ## ## \
|
||||
$C1## ## ### ### ## ## \
|
||||
$C1## ## ### ### ####### "
|
||||
|
||||
#define ASCII_INTEL \
|
||||
"$C1 .#################. \
|
||||
$C1 .#### ####. \
|
||||
@@ -68,6 +85,27 @@ $C1 olcc::; ,:ccloMMMMMMMMM \
|
||||
$C1 :......oMMMMMMMMMMMMMMMMMMMMMM \
|
||||
$C1 :lllMMMMMMMMMMMMMMMMMMMMMMMMMM "
|
||||
|
||||
#define ASCII_AMD_L \
|
||||
"$C1 \
|
||||
$C1 \
|
||||
$C1 \
|
||||
$C1 \
|
||||
$C1 \
|
||||
$C1 \
|
||||
$C1 @@@@ @@@ @@@ @@@@@@@@ $C2 ############ \
|
||||
$C1 @@@@@@ @@@@@ @@@@@ @@@ @@@ $C2 ########## \
|
||||
$C1 @@@ @@@ @@@@@@@@@@@@@ @@@ @@ $C2 # ##### \
|
||||
$C1 @@@ @@@ @@@ @@@ @@@ @@@ @@ $C2 ### ##### \
|
||||
$C1 @@@@@@@@@@@@ @@@ @@@ @@@ @@@ $C2######### ### \
|
||||
$C1 @@@ @@@ @@@ @@@ @@@@@@@@@ $C2######## ## \
|
||||
$C1 \
|
||||
$C1 \
|
||||
$C1 \
|
||||
$C1 \
|
||||
$C1 \
|
||||
$C1 \
|
||||
$C1 "
|
||||
|
||||
#define ASCII_INTEL_L \
|
||||
"$C1 ###############@ \
|
||||
$C1 ######@ ######@ \
|
||||
@@ -94,11 +132,13 @@ typedef struct ascii_logo asciiL;
|
||||
// ------------------------------------------------------------------------------------------
|
||||
// | LOGO | W | H | REPLACE | COLORS LOGO | COLORS TEXT |
|
||||
// ------------------------------------------------------------------------------------------
|
||||
asciiL logo_nvidia = { ASCII_NVIDIA, 45, 19, false, {C_FG_GREEN, C_FG_WHITE}, {C_FG_WHITE, C_FG_GREEN} };
|
||||
asciiL logo_intel = { ASCII_INTEL, 48, 14, false, {C_FG_CYAN}, {C_FG_CYAN, C_FG_WHITE} };
|
||||
asciiL logo_nvidia = { ASCII_NVIDIA, 45, 19, false, {C_FG_GREEN, C_FG_WHITE}, {C_FG_WHITE, C_FG_GREEN} };
|
||||
asciiL logo_amd = { ASCII_AMD, 39, 15, false, {C_FG_WHITE, C_FG_GREEN}, {C_FG_WHITE, C_FG_GREEN} };
|
||||
asciiL logo_intel = { ASCII_INTEL, 48, 14, false, {C_FG_CYAN}, {C_FG_CYAN, C_FG_WHITE} };
|
||||
// Long variants | ---------------------------------------------------------------------------------------|
|
||||
asciiL logo_nvidia_l = { ASCII_NVIDIA_L, 50, 15, false, {C_FG_GREEN, C_FG_WHITE}, {C_FG_WHITE, C_FG_GREEN} };
|
||||
asciiL logo_intel_l = { ASCII_INTEL_L, 62, 19, true, {C_BG_CYAN, C_BG_WHITE}, {C_FG_CYAN, C_FG_WHITE} };
|
||||
asciiL logo_unknown = { NULL, 0, 0, false, {C_NONE}, {C_NONE, C_NONE} };
|
||||
asciiL logo_nvidia_l = { ASCII_NVIDIA_L, 50, 15, false, {C_FG_GREEN, C_FG_WHITE}, {C_FG_WHITE, C_FG_GREEN} };
|
||||
asciiL logo_amd_l = { ASCII_AMD_L, 62, 19, true, {C_BG_WHITE, C_BG_WHITE}, {C_FG_CYAN, C_FG_B_WHITE} };
|
||||
asciiL logo_intel_l = { ASCII_INTEL_L, 62, 19, true, {C_BG_CYAN, C_BG_WHITE}, {C_FG_CYAN, C_FG_WHITE} };
|
||||
asciiL logo_unknown = { NULL, 0, 0, false, {C_NONE}, {C_NONE, C_NONE} };
|
||||
|
||||
#endif
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
enum {
|
||||
GPU_VENDOR_NVIDIA,
|
||||
GPU_VENDOR_AMD,
|
||||
GPU_VENDOR_INTEL
|
||||
};
|
||||
|
||||
@@ -44,6 +45,11 @@ struct topology_c {
|
||||
int32_t tensor_cores;
|
||||
};
|
||||
|
||||
// HSA topology
|
||||
struct topology_h {
|
||||
int32_t compute_units;
|
||||
};
|
||||
|
||||
// Intel topology
|
||||
struct topology_i {
|
||||
int32_t slices;
|
||||
@@ -72,6 +78,8 @@ struct gpu_info {
|
||||
struct memory* mem;
|
||||
struct cache* cach;
|
||||
struct topology_c* topo_c;
|
||||
// HSA specific
|
||||
struct topology_h* topo_h;
|
||||
// Intel specific
|
||||
struct topology_i* topo_i;
|
||||
};
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "master.hpp"
|
||||
#include "args.hpp"
|
||||
#include "../cuda/cuda.hpp"
|
||||
#include "../hsa/hsa.hpp"
|
||||
#include "../intel/intel.hpp"
|
||||
|
||||
#define MAX_GPUS 1000
|
||||
@@ -35,6 +36,18 @@ struct gpu_list* get_gpu_list() {
|
||||
list->num_gpus += idx;
|
||||
#endif
|
||||
|
||||
#ifdef BACKEND_HSA
|
||||
bool valid = true;
|
||||
|
||||
while(valid) {
|
||||
list->gpus[idx] = get_gpu_info_hsa(devices, idx);
|
||||
if(list->gpus[idx] != NULL) idx++;
|
||||
else valid = false;
|
||||
}
|
||||
|
||||
list->num_gpus += idx;
|
||||
#endif
|
||||
|
||||
#ifdef BACKEND_INTEL
|
||||
list->gpus[idx] = get_gpu_info_intel(devices);
|
||||
if(list->gpus[idx] != NULL) list->num_gpus++;
|
||||
@@ -51,6 +64,11 @@ bool print_gpus_list(struct gpu_list* list) {
|
||||
print_gpu_cuda(list->gpus[i]);
|
||||
#endif
|
||||
}
|
||||
else if(list->gpus[i]->vendor == GPU_VENDOR_AMD) {
|
||||
#ifdef BACKEND_AMD
|
||||
print_gpu_hsa(list->gpus[i]);
|
||||
#endif
|
||||
}
|
||||
else if(list->gpus[i]->vendor == GPU_VENDOR_INTEL) {
|
||||
#ifdef BACKEND_INTEL
|
||||
print_gpu_intel(list->gpus[i]);
|
||||
@@ -69,6 +87,13 @@ void print_enabled_backends() {
|
||||
printf("%sOFF%s\n", C_FG_RED, C_RESET);
|
||||
#endif
|
||||
|
||||
printf("- HSA backend: ");
|
||||
#ifdef BACKEND_HSA
|
||||
printf("%sON%s\n", C_FG_GREEN, C_RESET);
|
||||
#else
|
||||
printf("%sOFF%s\n", C_FG_RED, C_RESET);
|
||||
#endif
|
||||
|
||||
printf("- Intel backend: ");
|
||||
#ifdef BACKEND_INTEL
|
||||
printf("%sON%s\n", C_FG_GREEN, C_RESET);
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include "../intel/uarch.hpp"
|
||||
#include "../intel/intel.hpp"
|
||||
#include "../hsa/hsa.hpp"
|
||||
#include "../cuda/cuda.hpp"
|
||||
#include "../cuda/uarch.hpp"
|
||||
|
||||
@@ -233,6 +234,9 @@ void choose_ascii_art(struct ascii* art, struct color** cs, struct terminal* ter
|
||||
if(art->vendor == GPU_VENDOR_NVIDIA) {
|
||||
art->art = choose_ascii_art_aux(&logo_nvidia_l, &logo_nvidia, term, lf);
|
||||
}
|
||||
else if(art->vendor == GPU_VENDOR_AMD) {
|
||||
art->art = choose_ascii_art_aux(&logo_amd_l, &logo_amd, term, lf);
|
||||
}
|
||||
else if(art->vendor == GPU_VENDOR_INTEL) {
|
||||
art->art = choose_ascii_art_aux(&logo_intel_l, &logo_intel, term, lf);
|
||||
}
|
||||
@@ -478,6 +482,42 @@ bool print_gpufetch_cuda(struct gpu_info* gpu, STYLE s, struct color** cs, struc
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BACKEND_HSA
|
||||
bool print_gpufetch_amd(struct gpu_info* gpu, STYLE s, struct color** cs, struct terminal* term) {
|
||||
struct ascii* art = set_ascii(get_gpu_vendor(gpu), s);
|
||||
|
||||
if(art == NULL)
|
||||
return false;
|
||||
|
||||
char* gpu_name = get_str_gpu_name(gpu);
|
||||
char* sms = get_str_cu(gpu);
|
||||
char* max_frequency = get_str_freq(gpu);
|
||||
|
||||
setAttribute(art, ATTRIBUTE_NAME, gpu_name);
|
||||
setAttribute(art, ATTRIBUTE_FREQUENCY, max_frequency);
|
||||
setAttribute(art, ATTRIBUTE_STREAMINGMP, sms);
|
||||
|
||||
const char** attribute_fields = ATTRIBUTE_FIELDS;
|
||||
uint32_t longest_attribute = longest_attribute_length(art, attribute_fields);
|
||||
uint32_t longest_field = longest_field_length(art, longest_attribute);
|
||||
choose_ascii_art(art, cs, term, longest_field);
|
||||
|
||||
if(!ascii_fits_screen(term->w, *art->art, longest_field)) {
|
||||
// Despite of choosing the smallest logo, the output does not fit
|
||||
// Choose the shorter field names and recalculate the longest attr
|
||||
attribute_fields = ATTRIBUTE_FIELDS_SHORT;
|
||||
longest_attribute = longest_attribute_length(art, attribute_fields);
|
||||
}
|
||||
|
||||
print_ascii_generic(art, longest_attribute, term->w - art->art->width, attribute_fields);
|
||||
|
||||
free(art->attributes);
|
||||
free(art);
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
struct terminal* get_terminal_size() {
|
||||
struct terminal* term = (struct terminal*) emalloc(sizeof(struct terminal));
|
||||
|
||||
@@ -517,11 +557,22 @@ bool print_gpufetch(struct gpu_info* gpu, STYLE s, struct color** cs) {
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
else if(gpu->vendor == GPU_VENDOR_AMD) {
|
||||
#ifdef BACKEND_HSA
|
||||
return print_gpufetch_amd(gpu, s, cs, term);
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
else if(gpu->vendor == GPU_VENDOR_INTEL) {
|
||||
#ifdef BACKEND_INTEL
|
||||
return print_gpufetch_intel(gpu, s, cs, term);
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
printErr("Invalid GPU vendor: %d", gpu->vendor);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
130
src/hsa/hsa.cpp
Normal file
130
src/hsa/hsa.cpp
Normal file
@@ -0,0 +1,130 @@
|
||||
#include <iostream>
|
||||
#include <hsa/hsa.h>
|
||||
#include <hsa/hsa_ext_amd.h>
|
||||
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <hsa/hsa.h>
|
||||
#include <hsa/hsa_ext_amd.h>
|
||||
|
||||
#include "hsa.hpp"
|
||||
#include "../common/pci.hpp"
|
||||
#include "../common/global.hpp"
|
||||
#include "../common/uarch.hpp"
|
||||
|
||||
struct agent_info {
|
||||
unsigned deviceId; // ID of the target GPU device
|
||||
char gpu_name[64];
|
||||
char vendor_name[64];
|
||||
char device_mkt_name[64];
|
||||
uint32_t max_clock_freq;
|
||||
uint32_t compute_unit;
|
||||
};
|
||||
|
||||
#define RET_IF_HSA_ERR(err) { \
|
||||
if ((err) != HSA_STATUS_SUCCESS) { \
|
||||
char err_val[12]; \
|
||||
char* err_str = NULL; \
|
||||
if (hsa_status_string(err, \
|
||||
(const char**)&err_str) != HSA_STATUS_SUCCESS) { \
|
||||
snprintf(&(err_val[0]), sizeof(err_val), "%#x", (uint32_t)err); \
|
||||
err_str = &(err_val[0]); \
|
||||
} \
|
||||
printErr("HSA failure at: %s:%d\n", \
|
||||
__FILE__, __LINE__); \
|
||||
printErr("Call returned %s\n", err_str); \
|
||||
return (err); \
|
||||
} \
|
||||
}
|
||||
|
||||
hsa_status_t agent_callback(hsa_agent_t agent, void *data) {
|
||||
struct agent_info* info = reinterpret_cast<struct agent_info *>(data);
|
||||
|
||||
hsa_device_type_t type;
|
||||
hsa_status_t err = hsa_agent_get_info(agent, HSA_AGENT_INFO_DEVICE, &type);
|
||||
RET_IF_HSA_ERR(err);
|
||||
|
||||
if (type == HSA_DEVICE_TYPE_GPU) {
|
||||
err = hsa_agent_get_info(agent, HSA_AGENT_INFO_NAME, info->gpu_name);
|
||||
RET_IF_HSA_ERR(err);
|
||||
|
||||
// TODO: What if vendor_name is not AMD?
|
||||
err = hsa_agent_get_info(agent, HSA_AGENT_INFO_VENDOR_NAME, info->vendor_name);
|
||||
RET_IF_HSA_ERR(err);
|
||||
|
||||
err = hsa_agent_get_info(agent, (hsa_agent_info_t) HSA_AMD_AGENT_INFO_PRODUCT_NAME, &info->device_mkt_name);
|
||||
RET_IF_HSA_ERR(err);
|
||||
|
||||
err = hsa_agent_get_info(agent, (hsa_agent_info_t) HSA_AMD_AGENT_INFO_MAX_CLOCK_FREQUENCY, &info->max_clock_freq);
|
||||
RET_IF_HSA_ERR(err);
|
||||
|
||||
err = hsa_agent_get_info(agent, (hsa_agent_info_t) HSA_AMD_AGENT_INFO_COMPUTE_UNIT_COUNT, &info->compute_unit);
|
||||
RET_IF_HSA_ERR(err);
|
||||
}
|
||||
|
||||
return HSA_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
struct topology_h* get_topology_info(struct agent_info info) {
|
||||
struct topology_h* topo = (struct topology_h*) emalloc(sizeof(struct topology_h));
|
||||
|
||||
topo->compute_units = info.compute_unit;
|
||||
|
||||
return topo;
|
||||
}
|
||||
|
||||
struct gpu_info* get_gpu_info_hsa(struct pci_dev *devices, int gpu_idx) {
|
||||
struct gpu_info* gpu = (struct gpu_info*) emalloc(sizeof(struct gpu_info));
|
||||
gpu->pci = NULL;
|
||||
gpu->idx = gpu_idx;
|
||||
|
||||
if(gpu->idx < 0) {
|
||||
printErr("GPU index must be equal or greater than zero");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(gpu->idx > 0) {
|
||||
// Currently we only support fetching GPU 0.
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hsa_status_t status;
|
||||
|
||||
// Initialize the HSA runtime
|
||||
status = hsa_init();
|
||||
if (status != HSA_STATUS_SUCCESS) {
|
||||
printErr("Failed to initialize HSA runtime");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct agent_info info;
|
||||
info.deviceId = gpu_idx;
|
||||
|
||||
// Iterate over all agents in the system
|
||||
status = hsa_iterate_agents(agent_callback, &info);
|
||||
if (status != HSA_STATUS_SUCCESS) {
|
||||
printErr("Failed to iterate HSA agents");
|
||||
hsa_shut_down();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gpu->freq = info.max_clock_freq;
|
||||
gpu->vendor = GPU_VENDOR_AMD;
|
||||
gpu->name = (char *) emalloc(sizeof(char) * (strlen(info.device_mkt_name) + 1));
|
||||
strcpy(gpu->name, info.device_mkt_name);
|
||||
gpu->topo_h = get_topology_info(info);
|
||||
|
||||
// TODO: Use gpu_name for uarch detection
|
||||
|
||||
// Shut down the HSA runtime
|
||||
hsa_shut_down();
|
||||
return gpu;
|
||||
}
|
||||
|
||||
char* get_str_cu(struct gpu_info* gpu) {
|
||||
return get_str_generic(gpu->topo_h->compute_units);
|
||||
}
|
||||
9
src/hsa/hsa.hpp
Normal file
9
src/hsa/hsa.hpp
Normal file
@@ -0,0 +1,9 @@
|
||||
#ifndef __HSA_GPU__
|
||||
#define __HSA_GPU__
|
||||
|
||||
#include "../common/gpu.hpp"
|
||||
|
||||
struct gpu_info* get_gpu_info_hsa(struct pci_dev *devices, int gpu_idx);
|
||||
char* get_str_cu(struct gpu_info* gpu);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user