diff --git a/CMakeLists.txt b/CMakeLists.txt index 0268455..0d9ac37 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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,33 @@ 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 extremely 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 +78,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 +123,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 "HSA_INCLUDE_DIR = ${ROCM_PATH}") + + 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 +160,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() diff --git a/build.sh b/build.sh index ee2d075..a37806c 100755 --- a/build.sh +++ b/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 .. diff --git a/src/common/master.cpp b/src/common/master.cpp index a5694f3..bc8bc45 100644 --- a/src/common/master.cpp +++ b/src/common/master.cpp @@ -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++; @@ -69,6 +82,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); diff --git a/src/hsa/hsa.cpp b/src/hsa/hsa.cpp new file mode 100644 index 0000000..42e5134 --- /dev/null +++ b/src/hsa/hsa.cpp @@ -0,0 +1,60 @@ +#include +#include +#include + +#include +#include +#include + +#include "hsa.hpp" +#include "../common/pci.hpp" +#include "../common/global.hpp" +#include "../common/uarch.hpp" + +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; + } + + hsa_status_t status; + + // Initialize the HSA runtime + status = hsa_init(); + if (status != HSA_STATUS_SUCCESS) { + printErr("Failed to initialize HSA runtime"); + return NULL; + } + + // Lambda for iterating over agents + auto agent_callback = [](hsa_agent_t agent, void* data) -> hsa_status_t { + hsa_device_type_t type; + if (hsa_agent_get_info(agent, HSA_AGENT_INFO_DEVICE, &type) != HSA_STATUS_SUCCESS) + return HSA_STATUS_SUCCESS; + + if (type == HSA_DEVICE_TYPE_GPU) { + char name[64] = {0}; + if (hsa_agent_get_info(agent, HSA_AGENT_INFO_NAME, name) == HSA_STATUS_SUCCESS) { + std::cout << name << std::endl; + } + } + + return HSA_STATUS_SUCCESS; + }; + + // Iterate over all agents in the system + status = hsa_iterate_agents(agent_callback, nullptr); + if (status != HSA_STATUS_SUCCESS) { + std::cerr << "Failed to iterate HSA agents.\n"; + hsa_shut_down(); + return NULL; + } + + // Shut down the HSA runtime + hsa_shut_down(); + return NULL; +} diff --git a/src/hsa/hsa.hpp b/src/hsa/hsa.hpp new file mode 100644 index 0000000..b8c688d --- /dev/null +++ b/src/hsa/hsa.hpp @@ -0,0 +1,9 @@ +#ifndef __HSA_GPU__ +#define __HSA_GPU__ + +#include "../common/gpu.hpp" +// #define CUDA_DRIVER_START_WARNING "Waiting for CUDA driver to start..." + +struct gpu_info* get_gpu_info_hsa(struct pci_dev *devices, int gpu_idx); + +#endif