146 lines
3.8 KiB
C++
146 lines
3.8 KiB
C++
#include <cstddef>
|
|
#include <cstring>
|
|
#include <cstdio>
|
|
#include <cassert>
|
|
#include <cerrno>
|
|
#include <cmath>
|
|
|
|
#include "../common/global.hpp"
|
|
#include "gpu.hpp"
|
|
|
|
#define STRING_YES "Yes"
|
|
#define STRING_NO "No"
|
|
#define STRING_NONE "None"
|
|
#define STRING_MEGAHERZ "MHz"
|
|
#define STRING_GIGAHERZ "GHz"
|
|
#define STRING_KILOBYTES "KB"
|
|
#define STRING_MEGABYTES "MB"
|
|
#define STRING_GIGABYTES "GB"
|
|
|
|
static const char *memtype_str[] = {
|
|
/*[MEMTYPE_UNKNOWN] = */ STRING_UNKNOWN,
|
|
/*[MEMTYPE_DDR3] = */ "DDR3",
|
|
/*[MEMTYPE_DDR4] = */ "DDR4",
|
|
/*[MEMTYPE_GDDR5] = */ "GDDR5",
|
|
/*[MEMTYPE_GDDR5X] = */ "GDDR5X",
|
|
/*[MEMTYPE_GDDR6] = */ "GDDR6",
|
|
/*[MEMTYPE_GDDR6X] = */ "GDDR6X",
|
|
/*[MEMTYPE_HBM2] = */ "HBM2"
|
|
};
|
|
|
|
VENDOR get_gpu_vendor(struct gpu_info* gpu) {
|
|
return gpu->vendor;
|
|
}
|
|
|
|
double trunc(double val) {
|
|
int digits = floor (log10 (abs (val))) + 1;
|
|
int decimals = 4 - digits;
|
|
return val - (5 * pow(10, -(decimals + 1)));
|
|
}
|
|
|
|
int32_t get_value_as_smallest_unit(char ** str, uint64_t value) {
|
|
int32_t ret;
|
|
int max_len = 10; // Max is 8 for digits, 2 for units
|
|
*str = (char *) emalloc(sizeof(char)* (max_len + 1));
|
|
|
|
if(value/1024 >= (1 << 20))
|
|
ret = snprintf(*str, max_len, "%.4g " STRING_GIGABYTES, trunc((double)value/(1<<30)));
|
|
else if(value/1024 >= (1 << 10))
|
|
ret = snprintf(*str, max_len, "%.4g " STRING_MEGABYTES, trunc((double)value/(1<<20)));
|
|
else
|
|
ret = snprintf(*str, max_len, "%.4g " STRING_KILOBYTES, trunc((double)value/(1<<10)));
|
|
|
|
return ret;
|
|
}
|
|
|
|
char* get_str_gpu_name(struct gpu_info* gpu) {
|
|
return gpu->name;
|
|
}
|
|
|
|
char* get_freq_as_str_mhz(int64_t freq) {
|
|
// Max 20 digits and 3 for 'MHz'
|
|
uint32_t size = (20+1+3+1);
|
|
assert(strlen(STRING_UNKNOWN) + 1 <= size);
|
|
char* string = (char *) ecalloc(size, sizeof(char));
|
|
|
|
if(freq == UNKNOWN_FREQ || freq < 0)
|
|
snprintf(string, strlen(STRING_UNKNOWN)+1, STRING_UNKNOWN);
|
|
else
|
|
snprintf(string, size, "%ld " STRING_MEGAHERZ, freq);
|
|
|
|
return string;
|
|
}
|
|
|
|
char* get_str_freq(struct gpu_info* gpu) {
|
|
return get_freq_as_str_mhz(gpu->freq);
|
|
}
|
|
|
|
// TODO: Refactor
|
|
char* get_str_memory_size(struct gpu_info* gpu) {
|
|
char* string;
|
|
int32_t str_len = get_value_as_smallest_unit(&string, gpu->mem->size_bytes);
|
|
|
|
if(str_len < 0) {
|
|
printBug("get_value_as_smallest_unit: %s", strerror(errno));
|
|
return NULL;
|
|
}
|
|
|
|
return string;
|
|
}
|
|
|
|
char* get_str_memory_type(struct gpu_info* gpu) {
|
|
char* str = (char *) emalloc(sizeof(char) * (strlen(memtype_str[gpu->mem->type]) +1));
|
|
strcpy(str, memtype_str[gpu->mem->type]);
|
|
return str;
|
|
}
|
|
|
|
char* get_str_bus_width(struct gpu_info* gpu) {
|
|
uint32_t size = 3+1+3+1;
|
|
assert(strlen(STRING_UNKNOWN)+1 <= size);
|
|
char* string = (char *) ecalloc(size, sizeof(char));
|
|
|
|
sprintf(string, "%d bit", gpu->mem->bus_width);
|
|
|
|
return string;
|
|
}
|
|
|
|
char* get_str_memory_clock(struct gpu_info* gpu) {
|
|
return get_freq_as_str_mhz(gpu->mem->freq);
|
|
}
|
|
|
|
char* get_str_l2(struct gpu_info* gpu) {
|
|
char* string;
|
|
int32_t str_len = get_value_as_smallest_unit(&string, gpu->cach->L2->size);
|
|
|
|
if(str_len < 0) {
|
|
printBug("get_value_as_smallest_unit: %s", strerror(errno));
|
|
return NULL;
|
|
}
|
|
|
|
return string;
|
|
}
|
|
|
|
char* get_str_peak_performance(struct gpu_info* gpu) {
|
|
char* str;
|
|
|
|
if(gpu->peak_performance == -1) {
|
|
str = (char *) emalloc(sizeof(char) * (strlen(STRING_UNKNOWN) + 1));
|
|
strncpy(str, STRING_UNKNOWN, strlen(STRING_UNKNOWN) + 1);
|
|
return str;
|
|
}
|
|
|
|
// 7 for digits (e.g, XXXX.XX), 7 for XFLOP/s
|
|
double flopsd = (double) gpu->peak_performance;
|
|
uint32_t max_size = 7+1+7+1;
|
|
str = (char *) ecalloc(max_size, sizeof(char));
|
|
|
|
if(flopsd >= (double)1000000000000.0)
|
|
snprintf(str, max_size, "%.2f TFLOP/s", flopsd/1000000000000);
|
|
else if(flopsd >= 1000000000.0)
|
|
snprintf(str, max_size, "%.2f GFLOP/s", flopsd/1000000000);
|
|
else
|
|
snprintf(str, max_size, "%.2f MFLOP/s", flopsd/1000000);
|
|
|
|
return str;
|
|
}
|