From 0950b97393d1452f1368ff72aece281720010a65 Mon Sep 17 00:00:00 2001 From: Dr-Noob Date: Thu, 16 Oct 2025 08:26:42 +0200 Subject: [PATCH] [v0.30] Build pciutils only if neccesary If only HSA is enabled we dont need pciutils since AMD detection does not rely on it. Therefore we change CMakeLists.txt to build pciutils only if required. This commit has some side-effects: 1. We now don't build Intel backend by default. In other words, no backend is built by default, the user must specify which backend to use. 2. There were some issues with includes and wrongly used defines and variables. This commit fixes all that. --- CMakeLists.txt | 79 +++++++++++++++++++++++++++++-------------- src/common/gpu.hpp | 2 -- src/common/main.cpp | 8 +++++ src/common/master.cpp | 9 +++-- src/cuda/cuda.cpp | 6 ++-- src/cuda/uarch.cpp | 6 ++++ src/cuda/uarch.hpp | 1 + src/hsa/hsa.cpp | 3 +- src/hsa/hsa.hpp | 2 +- src/hsa/uarch.cpp | 2 +- 10 files changed, 81 insertions(+), 37 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a4f256e..fd7927a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,9 +10,10 @@ 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) +# Make sure that at least one backend is enabled. +# It does not make sense that the user has not specified any backend. +if(NOT ENABLE_INTEL_BACKEND AND NOT ENABLE_CUDA_BACKEND AND NOT ENABLE_HSA_BACKEND) + message(FATAL_ERROR "No backend was enabled! Please enable at least one backend with -DENABLE_XXX_BACKEND") endif() if(ENABLE_CUDA_BACKEND) @@ -66,35 +67,63 @@ if(ENABLE_HSA_BACKEND) endif() endif() -list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake") -find_package(PCIUTILS) -if(NOT ${PCIUTILS_FOUND}) - message(STATUS "${BoldYellow}pciutils not found, downloading and building a local copy...${ColorReset}") +set(GPUFECH_COMMON + ${COMMON_DIR}/main.cpp + ${COMMON_DIR}/args.cpp + ${COMMON_DIR}/gpu.cpp + ${COMMON_DIR}/global.cpp + ${COMMON_DIR}/printer.cpp + ${COMMON_DIR}/master.cpp + ${COMMON_DIR}/uarch.cpp +) - # Download and build pciutils - set(PCIUTILS_INSTALL_LOCATION ${CMAKE_BINARY_DIR}/pciutils-install) - ExternalProject_Add(pciutils - GIT_REPOSITORY https://github.com/pciutils/pciutils - CONFIGURE_COMMAND "" - BUILD_COMMAND make SHARED=no HWDB=no - BUILD_IN_SOURCE true - INSTALL_COMMAND make PREFIX=${PCIUTILS_INSTALL_LOCATION} install-lib - ) +set(GPUFETCH_LINK_TARGETS z) - include_directories(${PCIUTILS_INSTALL_LOCATION}/include) - link_directories(${PCIUTILS_INSTALL_LOCATION}/lib) -else() - include_directories(${PCIUTILS_INCLUDE_DIR}) - link_libraries(${PCIUTILS_LIBRARIES}) - # Needed for linking libpci in FreeBSD - link_directories(/usr/local/lib/) +if(NOT(ENABLE_HSA_BACKEND AND NOT ENABLE_CUDA_BACKEND AND NOT ENABLE_INTEL_BACKEND)) + # Look for pciutils only if not building HSA only. + # + # This has the (intented) secondary effect that if only HSA backend is enabled + # by the user, but ROCm cannot be found, pciutils will still be compiled in + # order to show the list of GPUs available on the system, so that the user will + # get at least some feedback even if HSA is not found. + list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake") + list(APPEND GPUFECH_COMMON ${COMMON_DIR}/pci.cpp ${COMMON_DIR}/sort.cpp) + list(APPEND GPUFETCH_LINK_TARGETS pci) + set(CMAKE_ENABLE_PCIUTILS ON) + + find_package(PCIUTILS) + if(NOT ${PCIUTILS_FOUND}) + message(STATUS "${BoldYellow}pciutils not found, downloading and building a local copy...${ColorReset}") + + # Download and build pciutils + set(PCIUTILS_INSTALL_LOCATION ${CMAKE_BINARY_DIR}/pciutils-install) + ExternalProject_Add(pciutils + GIT_REPOSITORY https://github.com/pciutils/pciutils + CONFIGURE_COMMAND "" + BUILD_COMMAND make SHARED=no HWDB=no + BUILD_IN_SOURCE true + INSTALL_COMMAND make PREFIX=${PCIUTILS_INSTALL_LOCATION} install-lib + ) + + include_directories(${PCIUTILS_INSTALL_LOCATION}/include) + link_directories(${PCIUTILS_INSTALL_LOCATION}/lib) + else() + include_directories(${PCIUTILS_INCLUDE_DIR}) + link_libraries(${PCIUTILS_LIBRARIES}) + # Needed for linking libpci in FreeBSD + link_directories(/usr/local/lib/) + endif() 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) +add_executable(gpufetch ${GPUFECH_COMMON}) 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 (CMAKE_ENABLE_PCIUTILS) + target_compile_definitions(gpufetch PUBLIC BACKEND_USE_PCI) +endif() + if(ENABLE_INTEL_BACKEND) target_compile_definitions(gpufetch PUBLIC BACKEND_INTEL) @@ -156,7 +185,7 @@ if(ENABLE_HSA_BACKEND) target_link_libraries(gpufetch hsa_backend) endif() -target_link_libraries(gpufetch pci z) +target_link_libraries(gpufetch ${GPUFETCH_LINK_TARGETS}) install(TARGETS gpufetch DESTINATION bin) if(NOT WIN32) diff --git a/src/common/gpu.hpp b/src/common/gpu.hpp index c63fd3e..3d35faf 100644 --- a/src/common/gpu.hpp +++ b/src/common/gpu.hpp @@ -3,8 +3,6 @@ #include -#include "../cuda/pci.hpp" - #define UNKNOWN_FREQ -1 enum { diff --git a/src/common/main.cpp b/src/common/main.cpp index 5d12b27..7f95486 100644 --- a/src/common/main.cpp +++ b/src/common/main.cpp @@ -8,6 +8,10 @@ #include "../cuda/cuda.hpp" #include "../cuda/uarch.hpp" +#ifdef BACKEND_USE_PCI +#include "pci.hpp" +#endif + static const char* VERSION = "0.30"; void print_help(char *argv[]) { @@ -79,8 +83,12 @@ int main(int argc, char* argv[]) { } if(get_num_gpus_available(list) == 0) { +#ifdef BACKEND_USE_PCI printErr("No GPU was detected! Available GPUs are:"); print_gpus_list_pci(); +#else + printErr("No GPU was detected!"); +#endif printf("Please, make sure that the appropiate backend is enabled:\n"); print_enabled_backends(); printf("Visit https://github.com/Dr-Noob/gpufetch#2-backends for more information\n"); diff --git a/src/common/master.cpp b/src/common/master.cpp index 9353630..9c5062e 100644 --- a/src/common/master.cpp +++ b/src/common/master.cpp @@ -1,7 +1,10 @@ #include #include -#include "pci.hpp" +#ifdef BACKEND_USE_PCI + #include "pci.hpp" +#endif + #include "global.hpp" #include "colors.hpp" #include "master.hpp" @@ -19,7 +22,9 @@ struct gpu_list { struct gpu_list* get_gpu_list() { int idx = 0; +#ifdef BACKEND_USE_PCI struct pci_dev *devices = get_pci_devices_from_pciutils(); +#endif struct gpu_list* list = (struct gpu_list*) malloc(sizeof(struct gpu_list)); list->num_gpus = 0; list->gpus = (struct gpu_info**) malloc(sizeof(struct info*) * MAX_GPUS); @@ -40,7 +45,7 @@ struct gpu_list* get_gpu_list() { bool valid = true; while(valid) { - list->gpus[idx] = get_gpu_info_hsa(devices, idx); + list->gpus[idx] = get_gpu_info_hsa(idx); if(list->gpus[idx] != NULL) idx++; else valid = false; } diff --git a/src/cuda/cuda.cpp b/src/cuda/cuda.cpp index e6aff86..20f1d93 100644 --- a/src/cuda/cuda.cpp +++ b/src/cuda/cuda.cpp @@ -5,8 +5,8 @@ #include "cuda.hpp" #include "uarch.hpp" +#include "pci.hpp" #include "gpufetch_helper_cuda.hpp" -#include "../common/pci.hpp" #include "../common/global.hpp" #include "../common/uarch.hpp" @@ -33,10 +33,8 @@ int get_tensor_cores(struct uarch* arch, int sm, int major) { if(major == 7) { // TU116 does not have tensor cores! // https://www.anandtech.com/show/13973/nvidia-gtx-1660-ti-review-feat-evga-xc-gaming/2 - if(arch->chip == CHIP_TU116 || arch->chip == CHIP_TU116BM || - arch->chip == CHIP_TU116GL || arch->chip == CHIP_TU116M) { + if (is_chip_TU116(arch)) return 0; - } return sm * 8; } else if(major == 8) return sm * 4; diff --git a/src/cuda/uarch.cpp b/src/cuda/uarch.cpp index 425f74b..096f36c 100644 --- a/src/cuda/uarch.cpp +++ b/src/cuda/uarch.cpp @@ -8,6 +8,7 @@ #include "../common/uarch.hpp" #include "../common/global.hpp" #include "../common/gpu.hpp" +#include "pci.hpp" #include "chips.hpp" // Any clock multiplier @@ -361,3 +362,8 @@ void free_uarch_struct(struct uarch* arch) { free(arch->chip_str); free(arch); } + +bool is_chip_TU116(struct uarch* arch) { + return arch->chip == CHIP_TU116 || arch->chip == CHIP_TU116BM || + arch->chip == CHIP_TU116GL || arch->chip == CHIP_TU116M; +} diff --git a/src/cuda/uarch.hpp b/src/cuda/uarch.hpp index 375b001..71622dd 100644 --- a/src/cuda/uarch.hpp +++ b/src/cuda/uarch.hpp @@ -13,5 +13,6 @@ char* get_str_cc(struct uarch* arch); char* get_str_chip(struct uarch* arch); char* get_str_process(struct uarch* arch); void free_uarch_struct(struct uarch* arch); +bool is_chip_TU116(struct uarch* arch); #endif diff --git a/src/hsa/hsa.cpp b/src/hsa/hsa.cpp index 8edd28d..da58673 100644 --- a/src/hsa/hsa.cpp +++ b/src/hsa/hsa.cpp @@ -13,7 +13,6 @@ #include "hsa.hpp" #include "uarch.hpp" -#include "../common/pci.hpp" #include "../common/global.hpp" #include "../common/uarch.hpp" @@ -76,7 +75,7 @@ struct topology_h* get_topology_info(struct agent_info info) { return topo; } -struct gpu_info* get_gpu_info_hsa(struct pci_dev *devices, int gpu_idx) { +struct gpu_info* get_gpu_info_hsa(int gpu_idx) { struct gpu_info* gpu = (struct gpu_info*) emalloc(sizeof(struct gpu_info)); gpu->pci = NULL; gpu->idx = gpu_idx; diff --git a/src/hsa/hsa.hpp b/src/hsa/hsa.hpp index 06d1c38..0942d2f 100644 --- a/src/hsa/hsa.hpp +++ b/src/hsa/hsa.hpp @@ -3,7 +3,7 @@ #include "../common/gpu.hpp" -struct gpu_info* get_gpu_info_hsa(struct pci_dev *devices, int gpu_idx); +struct gpu_info* get_gpu_info_hsa(int gpu_idx); char* get_str_cu(struct gpu_info* gpu); #endif diff --git a/src/hsa/uarch.cpp b/src/hsa/uarch.cpp index ae66bb9..3243350 100644 --- a/src/hsa/uarch.cpp +++ b/src/hsa/uarch.cpp @@ -127,7 +127,7 @@ enum { #define CHECK_UARCH_START if (false) {} #define CHECK_UARCH(arch, chip_, str, uarch, process) \ else if (arch->chip == chip_) fill_uarch(arch, str, uarch, process); -#define CHECK_UARCH_END else { if(arch->chip != CHIP_UNKNOWN_CUDA) printBug("map_chip_to_uarch_hsa: Unknown chip id: %d", arch->chip); fill_uarch(arch, STRING_UNKNOWN, UARCH_UNKNOWN, UNK); } +#define CHECK_UARCH_END else { if(arch->chip != CHIP_UNKNOWN_HSA) printBug("map_chip_to_uarch_hsa: Unknown chip id: %d", arch->chip); fill_uarch(arch, STRING_UNKNOWN, UARCH_UNKNOWN, UNK); } void fill_uarch(struct uarch* arch, char const *str, MICROARCH u, uint32_t process) { arch->chip_str = (char *) emalloc(sizeof(char) * (strlen(str)+1));