Supporting HSA detection of basic features and printing

This commit is contained in:
Dr-Noob
2025-10-12 12:11:16 +02:00
parent 14c745f7cb
commit 60a1ef70d8
4 changed files with 80 additions and 4 deletions

View File

@@ -45,6 +45,11 @@ struct topology_c {
int32_t tensor_cores; int32_t tensor_cores;
}; };
// HSA topology
struct topology_h {
int32_t compute_units;
};
// Intel topology // Intel topology
struct topology_i { struct topology_i {
int32_t slices; int32_t slices;
@@ -73,6 +78,8 @@ struct gpu_info {
struct memory* mem; struct memory* mem;
struct cache* cach; struct cache* cach;
struct topology_c* topo_c; struct topology_c* topo_c;
// HSA specific
struct topology_h* topo_h;
// Intel specific // Intel specific
struct topology_i* topo_i; struct topology_i* topo_i;
}; };

View File

@@ -10,6 +10,7 @@
#include "../intel/uarch.hpp" #include "../intel/uarch.hpp"
#include "../intel/intel.hpp" #include "../intel/intel.hpp"
#include "../hsa/hsa.hpp"
#include "../cuda/cuda.hpp" #include "../cuda/cuda.hpp"
#include "../cuda/uarch.hpp" #include "../cuda/uarch.hpp"
@@ -483,7 +484,36 @@ bool print_gpufetch_cuda(struct gpu_info* gpu, STYLE s, struct color** cs, struc
#ifdef BACKEND_HSA #ifdef BACKEND_HSA
bool print_gpufetch_amd(struct gpu_info* gpu, STYLE s, struct color** cs, struct terminal* term) { bool print_gpufetch_amd(struct gpu_info* gpu, STYLE s, struct color** cs, struct terminal* term) {
printErr("AMD TODO"); 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; return true;
} }
#endif #endif

View File

@@ -6,6 +6,11 @@
#include <cstdlib> #include <cstdlib>
#include <cstdio> #include <cstdio>
#include <iostream>
#include <iomanip>
#include <hsa/hsa.h>
#include <hsa/hsa_ext_amd.h>
#include "hsa.hpp" #include "hsa.hpp"
#include "../common/pci.hpp" #include "../common/pci.hpp"
#include "../common/global.hpp" #include "../common/global.hpp"
@@ -14,6 +19,10 @@
struct agent_info { struct agent_info {
unsigned deviceId; // ID of the target GPU device unsigned deviceId; // ID of the target GPU device
char gpu_name[64]; 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) { \ #define RET_IF_HSA_ERR(err) { \
@@ -42,11 +51,32 @@ hsa_status_t agent_callback(hsa_agent_t agent, void *data) {
if (type == HSA_DEVICE_TYPE_GPU) { if (type == HSA_DEVICE_TYPE_GPU) {
err = hsa_agent_get_info(agent, HSA_AGENT_INFO_NAME, info->gpu_name); err = hsa_agent_get_info(agent, HSA_AGENT_INFO_NAME, info->gpu_name);
RET_IF_HSA_ERR(err); 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; 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* get_gpu_info_hsa(struct pci_dev *devices, int gpu_idx) {
struct gpu_info* gpu = (struct gpu_info*) emalloc(sizeof(struct gpu_info)); struct gpu_info* gpu = (struct gpu_info*) emalloc(sizeof(struct gpu_info));
gpu->pci = NULL; gpu->pci = NULL;
@@ -82,11 +112,19 @@ struct gpu_info* get_gpu_info_hsa(struct pci_dev *devices, int gpu_idx) {
return NULL; return NULL;
} }
gpu->freq = info.max_clock_freq;
gpu->vendor = GPU_VENDOR_AMD; gpu->vendor = GPU_VENDOR_AMD;
gpu->name = (char *) emalloc(sizeof(char) * (strlen(info.gpu_name) + 1)); gpu->name = (char *) emalloc(sizeof(char) * (strlen(info.device_mkt_name) + 1));
strcpy(gpu->name, info.gpu_name); 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 // Shut down the HSA runtime
hsa_shut_down(); hsa_shut_down();
return gpu; return gpu;
} }
char* get_str_cu(struct gpu_info* gpu) {
return get_str_generic(gpu->topo_h->compute_units);
}

View File

@@ -4,5 +4,6 @@
#include "../common/gpu.hpp" #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(struct pci_dev *devices, int gpu_idx);
char* get_str_cu(struct gpu_info* gpu);
#endif #endif