diff --git a/src/common/gpu.hpp b/src/common/gpu.hpp index 5e5620c..c63fd3e 100644 --- a/src/common/gpu.hpp +++ b/src/common/gpu.hpp @@ -45,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; @@ -73,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; }; diff --git a/src/common/printer.cpp b/src/common/printer.cpp index 62ada3e..e255e57 100644 --- a/src/common/printer.cpp +++ b/src/common/printer.cpp @@ -10,6 +10,7 @@ #include "../intel/uarch.hpp" #include "../intel/intel.hpp" +#include "../hsa/hsa.hpp" #include "../cuda/cuda.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 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; } #endif diff --git a/src/hsa/hsa.cpp b/src/hsa/hsa.cpp index 643db0f..6e13506 100644 --- a/src/hsa/hsa.cpp +++ b/src/hsa/hsa.cpp @@ -6,6 +6,11 @@ #include #include +#include +#include +#include +#include + #include "hsa.hpp" #include "../common/pci.hpp" #include "../common/global.hpp" @@ -13,7 +18,11 @@ struct agent_info { 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) { \ @@ -42,11 +51,32 @@ hsa_status_t agent_callback(hsa_agent_t agent, void *data) { 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; @@ -82,11 +112,19 @@ struct gpu_info* get_gpu_info_hsa(struct pci_dev *devices, int gpu_idx) { return NULL; } + gpu->freq = info.max_clock_freq; gpu->vendor = GPU_VENDOR_AMD; - gpu->name = (char *) emalloc(sizeof(char) * (strlen(info.gpu_name) + 1)); - strcpy(gpu->name, info.gpu_name); + 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); +} diff --git a/src/hsa/hsa.hpp b/src/hsa/hsa.hpp index 151b291..06d1c38 100644 --- a/src/hsa/hsa.hpp +++ b/src/hsa/hsa.hpp @@ -4,5 +4,6 @@ #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