Skip to content

Commit

Permalink
Merge pull request #903 from bjia56/intel
Browse files Browse the repository at this point in the history
Intel GPU support
  • Loading branch information
aristocratos authored Sep 21, 2024
2 parents 00c9088 + db5f895 commit 24fc97c
Show file tree
Hide file tree
Showing 19 changed files with 9,797 additions and 9 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/cmake-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
- uses: actions/checkout@v4

- name: Install build tools
run: apk add --no-cache --update clang cmake lld ninja lowdown
run: apk add --no-cache --update clang cmake lld ninja lowdown linux-headers

- name: Configure
run: CXX=clang++ LDFLAGS=-fuse-ld=lld cmake -B build -G Ninja -DBTOP_STATIC=ON
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/continuous-build-gpu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ jobs:
- uses: actions/checkout@v4

- name: Install build tools
run: apk add --no-cache --update gcc g++ make
run: apk add --no-cache --update gcc g++ make linux-headers

- name: Compile
run: make CXX=g++ GPU_SUPPORT=true
Expand Down
10 changes: 9 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ endif()
project("btop"
DESCRIPTION "A monitor of resources"
HOMEPAGE_URL "https://github.com/aristocratos/btop"
LANGUAGES CXX
LANGUAGES CXX C
)

include(CheckCXXCompilerFlag)
Expand Down Expand Up @@ -70,6 +70,14 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "NetBSD")
target_sources(btop PRIVATE src/netbsd/btop_collect.cpp)
elseif(LINUX)
target_sources(btop PRIVATE src/linux/btop_collect.cpp)
if(BTOP_GPU)
target_sources(btop PRIVATE
src/linux/intel_gpu_top/intel_gpu_top.c
src/linux/intel_gpu_top/igt_perf.c
src/linux/intel_gpu_top/intel_device_info.c
src/linux/intel_gpu_top/intel_name_lookup_shim.c
)
endif()
else()
message(FATAL_ERROR "${CMAKE_SYSTEM_NAME} is not supported")
endif()
Expand Down
32 changes: 27 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ override PLATFORM_LC := $(shell echo $(PLATFORM) | tr '[:upper:]' '[:lower:]')
ifeq ($(PLATFORM_LC)$(ARCH),linuxx86_64)
ifneq ($(STATIC),true)
GPU_SUPPORT := true
INTEL_GPU_SUPPORT := true
endif
endif
ifneq ($(GPU_SUPPORT),true)
Expand Down Expand Up @@ -208,13 +209,22 @@ endif

SOURCES := $(sort $(shell find $(SRCDIR) -maxdepth 1 -type f -name *.$(SRCEXT)))

SOURCES += $(sort $(shell find $(SRCDIR)/$(PLATFORM_DIR) -type f -name *.$(SRCEXT)))

#? Setup percentage progress
SOURCE_COUNT := $(words $(SOURCES))
SOURCES += $(sort $(shell find $(SRCDIR)/$(PLATFORM_DIR) -maxdepth 1 -type f -name *.$(SRCEXT)))

OBJECTS := $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%,$(SOURCES:.$(SRCEXT)=.$(OBJEXT)))

ifeq ($(GPU_SUPPORT)$(INTEL_GPU_SUPPORT),truetrue)
IGT_OBJECTS := $(BUILDDIR)/igt_perf.c.o $(BUILDDIR)/intel_device_info.c.o $(BUILDDIR)/intel_name_lookup_shim.c.o $(BUILDDIR)/intel_gpu_top.c.o
OBJECTS += $(IGT_OBJECTS)
SHOW_CC_INFO = false
CC_VERSION := $(shell $(CC) -dumpfullversion -dumpversion || echo 0)
else
SHOW_CC_INFO = true
endif

#? Setup percentage progress
SOURCE_COUNT := $(words $(OBJECTS))

ifeq ($(shell find $(BUILDDIR) -type f -newermt "$(DATESTAMP)" -name *.o >/dev/null 2>&1; echo $$?),0)
ifneq ($(wildcard $(BUILDDIR)/.*),)
SKIPPED_SOURCES := $(foreach fname,$(SOURCES),$(shell find $(BUILDDIR) -type f -newer $(fname) -name *.o | grep "$(basename $(notdir $(fname))).o" 2>/dev/null))
Expand Down Expand Up @@ -248,7 +258,8 @@ info:
@printf "\033[1;96mARCH \033[1;93m?| \033[0m$(ARCH)\n"
@printf "\033[1;95mGPU_SUPPORT \033[1;94m:| \033[0m$(GPU_SUPPORT)\n"
@printf "\033[1;93mCXX \033[1;93m?| \033[0m$(CXX) \033[1;93m(\033[97m$(CXX_VERSION)\033[93m)\n"
@printf "\033[1;94mTHREADS \033[1;94m:| \033[0m$(THREADS)\n"
@$(SHOW_CC_INFO) || printf "\033[1;93mCC \033[1;93m?| \033[0m$(CC) \033[1;93m(\033[97m$(CC_VERSION)\033[93m)\n"
@printf "\033[1;94mTHREADS \033[1;94m:| \033[0m$(THREADS)\n" gcc -dumpfullversion -dumpversion
@printf "\033[1;92mREQFLAGS \033[1;91m!| \033[0m$(REQFLAGS)\n"
@printf "\033[1;91mWARNFLAGS \033[1;94m:| \033[0m$(WARNFLAGS)\n"
@printf "\033[1;94mOPTFLAGS \033[1;94m:| \033[0m$(OPTFLAGS)\n"
Expand Down Expand Up @@ -409,5 +420,16 @@ $(BUILDDIR)/%.$(OBJEXT): $(SRCDIR)/%.$(SRCEXT) | rocm_smi directories config.h
@$(CXX) $(CXXFLAGS) $(INC) -MMD -c -o $@ $< || exit 1
@printf "\033[1;92m$$($(PROGRESS))$(P)\033[10D\033[5C-> \033[1;37m$@ \033[100D\033[38C\033[1;93m(\033[1;97m$$(du -ah $@ | cut -f1)iB\033[1;93m) \033[92m(\033[97m$$($(DATE_CMD) -d @$$(expr $$($(DATE_CMD) +%s 2>/dev/null || echo "0") - $${TSTAMP} 2>/dev/null) -u +%Mm:%Ss 2>/dev/null | sed 's/^00m://' || echo '')\033[92m)\033[0m\n"

#? Compile intel_gpu_top C sources for Intel GPU support
.ONESHELL:
$(BUILDDIR)/%.c.o: $(SRCDIR)/$(PLATFORM_DIR)/intel_gpu_top/%.c | directories
@sleep 0.3 2>/dev/null || true
@TSTAMP=$$(date +%s 2>/dev/null || echo "0")
@$(QUIET) || printf "\033[1;97mCompiling $<\033[0m\n"
@$(VERBOSE) || printf "$(CC) $(INC) -c -o $@ $<\n"
@$(CC) $(INC) -w -c -o $@ $< || exit 1
@printf "\033[1;92m$$($(PROGRESS))$(P)\033[10D\033[5C-> \033[1;37m$@ \033[100D\033[38C\033[1;93m(\033[1;97m$$(du -ah $@ | cut -f1)iB\033[1;93m) \033[92m(\033[97m$$($(DATE_CMD) -d @$$(expr $$($(DATE_CMD) +%s 2>/dev/null || echo "0") - $${TSTAMP} 2>/dev/null) -u +%Mm:%Ss 2>/dev/null | sed 's/^00m://' || echo '')\033[92m)\033[0m\n"


#? Non-File Targets
.PHONY: all config.h msg help pre
135 changes: 134 additions & 1 deletion src/linux/btop_collect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,14 @@ tab-size = 4
#include "../btop_config.hpp"
#include "../btop_tools.hpp"

#if defined(GPU_SUPPORT)
#define class class_
extern "C" {
#include "./intel_gpu_top/intel_gpu_top.h"
}
#undef class
#endif

using std::clamp;
using std::cmp_greater;
using std::cmp_less;
Expand Down Expand Up @@ -210,6 +218,19 @@ namespace Gpu {
template <bool is_init> bool collect(gpu_info* gpus_slice);
uint32_t device_count = 0;
}


//? Intel data collection
namespace Intel {
const char* device = "i915";
struct engines *engines = nullptr;

bool initialized = false;
bool init();
bool shutdown();
template <bool is_init> bool collect(gpu_info* gpus_slice);
uint32_t device_count = 0;
}
#endif
}

Expand Down Expand Up @@ -276,6 +297,7 @@ namespace Shared {
#ifdef GPU_SUPPORT
Gpu::Nvml::init();
Gpu::Rsmi::init();
Gpu::Intel::init();
if (not Gpu::gpu_names.empty()) {
for (auto const& [key, _] : Gpu::gpus[0].gpu_percent)
Cpu::available_fields.push_back(key);
Expand Down Expand Up @@ -1570,7 +1592,117 @@ namespace Gpu {
}
}

// TODO: Intel
namespace Intel {
bool init() {
if (initialized) return false;

char *gpu_path = find_intel_gpu_dir();
if (!gpu_path) {
Logger::debug("Failed to find Intel GPU sysfs path, Intel GPUs will not be detected");
return false;
}

char *gpu_device_id = get_intel_device_id(gpu_path);
if (!gpu_device_id) {
Logger::debug("Failed to find Intel GPU device ID, Intel GPUs will not be detected");
return false;
}

char *gpu_device_name = get_intel_device_name(gpu_device_id);
if (!gpu_device_name) {
Logger::warning("Failed to find Intel GPU device name in internal database");
}

free(gpu_device_id);

engines = discover_engines(device);
if (!engines) {
Logger::debug("Failed to find Intel GPU engines, Intel GPUs will not be detected");
return false;
}

int ret = pmu_init(engines);
if (ret) {
Logger::warning("Intel GPU: Failed to initialize PMU");
return false;
}

pmu_sample(engines);

device_count = 1;

gpus.resize(gpus.size() + device_count);
gpu_names.resize(gpus.size() + device_count);

if (gpu_device_name) {
gpu_names[Nvml::device_count + Rsmi::device_count] = string(gpu_device_name);
} else {
gpu_names[Nvml::device_count + Rsmi::device_count] = "Intel GPU";
}

free(gpu_device_name);

initialized = true;
Intel::collect<1>(gpus.data() + Nvml::device_count + Rsmi::device_count);

return true;
}

bool shutdown() {
if (!initialized) return false;
if (engines) {
free_engines(engines);
engines = nullptr;
}
initialized = false;
return true;
}

template <bool is_init> bool collect(gpu_info* gpus_slice) {
if (!initialized) return false;

if constexpr(is_init) {
gpus_slice->supported_functions = {
.gpu_utilization = true,
.mem_utilization = false,
.gpu_clock = true,
.mem_clock = false,
.pwr_usage = true,
.pwr_state = false,
.temp_info = false,
.mem_total = false,
.mem_used = false,
.pcie_txrx = false
};
}

pmu_sample(engines);
double t = (double)(engines->ts.cur - engines->ts.prev) / 1e9;

double max_util = 0;
for (unsigned int i = 0; i < engines->num_engines; i++) {
struct engine *engine = &(&engines->engine)[i];
double util = pmu_calc(&engine->busy.val, 1e9, t, 100);
if (util > max_util) {
max_util = util;
}
}
gpus_slice->gpu_percent.at("gpu-totals").push_back((long long)round(max_util));

double pwr = pmu_calc(&engines->r_gpu.val, 1, t, engines->r_gpu.scale); // in Watts
gpus_slice->pwr_usage = (long long)round(pwr * 1000);
if (gpus_slice->pwr_usage > 0) {
gpus_slice->gpu_percent.at("gpu-pwr-totals").push_back(100);
} else {
gpus_slice->gpu_percent.at("gpu-pwr-totals").push_back(0);
}

double freq = pmu_calc(&engines->freq_act.val, 1, t, 1); // in MHz
gpus_slice->gpu_clock_speed = (unsigned int)round(freq);

return true;
}
}

//? Collect data from GPU-specific libraries
auto collect(bool no_update) -> vector<gpu_info>& {
Expand All @@ -1581,6 +1713,7 @@ namespace Gpu {
//* Collect data
Nvml::collect<0>(gpus.data()); // raw pointer to vector data, size == Nvml::device_count
Rsmi::collect<0>(gpus.data() + Nvml::device_count); // size = Rsmi::device_count
Intel::collect<0>(gpus.data() + Nvml::device_count + Rsmi::device_count); // size = Intel::device_count

//* Calculate average usage
long long avg = 0;
Expand Down
Loading

0 comments on commit 24fc97c

Please sign in to comment.