[v0.11] Adding uarch backend for intel iGPUs
This commit is contained in:
@@ -54,7 +54,7 @@ set(CMAKE_CXX_FLAGS "${SANITY_FLAGS} -Wall -Wextra -pedantic -fstack-protector-a
|
||||
if(ENABLE_INTEL_BACKEND)
|
||||
target_compile_definitions(gpufetch PUBLIC BACKEND_INTEL)
|
||||
|
||||
add_library(intel_backend STATIC ${INTEL_DIR}/intel.cpp)
|
||||
add_library(intel_backend STATIC ${INTEL_DIR}/intel.cpp ${INTEL_DIR}/pci.cpp ${INTEL_DIR}/uarch.cpp)
|
||||
|
||||
if(NOT ${PCIUTILS_FOUND})
|
||||
add_dependencies(intel_backend pciutils)
|
||||
|
||||
@@ -20,6 +20,8 @@ struct gpu_list* get_gpu_list() {
|
||||
list->gpus = (struct gpu_info**) malloc(sizeof(struct info*) * MAX_GPUS);
|
||||
|
||||
#ifdef BACKEND_CUDA
|
||||
bool valid = true;
|
||||
|
||||
while(valid) {
|
||||
list->gpus[idx] = get_gpu_info_cuda(idx);
|
||||
if(list->gpus[idx] != NULL) idx++;
|
||||
|
||||
@@ -2,33 +2,39 @@
|
||||
#include "pci.hpp"
|
||||
#include <cstddef>
|
||||
|
||||
/*
|
||||
* doc: https://wiki.osdev.org/PCI#Class_Codes
|
||||
* https://pci-ids.ucw.cz/read/PC
|
||||
*/
|
||||
#define VENDOR_ID_NVIDIA 0x10de
|
||||
#define CLASS_VGA_CONTROLLER 0x0300
|
||||
|
||||
uint16_t pciutils_get_pci_vendor_id(struct pci_dev *devices) {
|
||||
uint16_t pciutils_get_pci_vendor_id(struct pci_dev *devices, int id) {
|
||||
for(struct pci_dev *dev=devices; dev != NULL; dev=dev->next) {
|
||||
if(dev->vendor_id == VENDOR_ID_NVIDIA && dev->device_class == CLASS_VGA_CONTROLLER) {
|
||||
if(dev->vendor_id == id && dev->device_class == CLASS_VGA_CONTROLLER) {
|
||||
return dev->vendor_id;
|
||||
}
|
||||
}
|
||||
printErr("Unable to find a CUDA device using pciutils");
|
||||
|
||||
printErr("Unable to find a valid device for id %d using pciutils", id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t pciutils_get_pci_device_id(struct pci_dev *devices) {
|
||||
uint16_t pciutils_get_pci_device_id(struct pci_dev *devices, int id) {
|
||||
for(struct pci_dev *dev=devices; dev != NULL; dev=dev->next) {
|
||||
if(dev->vendor_id == VENDOR_ID_NVIDIA && dev->device_class == CLASS_VGA_CONTROLLER) {
|
||||
if(dev->vendor_id == id && dev->device_class == CLASS_VGA_CONTROLLER) {
|
||||
return dev->device_id;
|
||||
}
|
||||
}
|
||||
printErr("Unable to find a CUDA device using pciutils");
|
||||
|
||||
printErr("Unable to find a valid device for id %d using pciutils", id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct pci* get_pci_from_pciutils(struct pci_dev *devices, int id) {
|
||||
struct pci* pci = (struct pci*) emalloc(sizeof(struct pci));
|
||||
|
||||
pci->vendor_id = pciutils_get_pci_vendor_id(devices, id);
|
||||
pci->device_id = pciutils_get_pci_device_id(devices, id);
|
||||
|
||||
return pci;
|
||||
}
|
||||
|
||||
struct pci_dev *get_pci_devices_from_pciutils() {
|
||||
struct pci_access *pacc;
|
||||
struct pci_dev *dev;
|
||||
|
||||
@@ -6,8 +6,12 @@ extern "C" {
|
||||
#include <pci/pci.h>
|
||||
}
|
||||
|
||||
uint16_t pciutils_get_pci_vendor_id(struct pci_dev *devices);
|
||||
uint16_t pciutils_get_pci_device_id(struct pci_dev *devices);
|
||||
struct pci {
|
||||
uint16_t vendor_id;
|
||||
uint16_t device_id;
|
||||
};
|
||||
|
||||
struct pci* get_pci_from_pciutils(struct pci_dev *devices, int id);
|
||||
struct pci_dev *get_pci_devices_from_pciutils();
|
||||
|
||||
#endif
|
||||
|
||||
20
src/common/uarch.hpp
Normal file
20
src/common/uarch.hpp
Normal file
@@ -0,0 +1,20 @@
|
||||
#ifndef __COMMON_UARCH__
|
||||
#define __COMMON_UARCH__
|
||||
|
||||
typedef uint32_t GPUCHIP;
|
||||
typedef uint32_t MICROARCH;
|
||||
|
||||
struct uarch {
|
||||
int32_t cc_major;
|
||||
int32_t cc_minor;
|
||||
int32_t compute_capability;
|
||||
|
||||
MICROARCH uarch;
|
||||
GPUCHIP chip;
|
||||
|
||||
int32_t process;
|
||||
char* uarch_str;
|
||||
char* chip_str;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef __GPUCHIPS__
|
||||
#define __GPUCHIPS__
|
||||
#ifndef __CUDA_GPUCHIPS__
|
||||
#define __CUDA_GPUCHIPS__
|
||||
|
||||
typedef uint32_t GPUCHIP;
|
||||
|
||||
|
||||
@@ -133,7 +133,7 @@ struct gpu_info* get_gpu_info_cuda(int gpu_idx) {
|
||||
strcpy(gpu->name, deviceProp.name);
|
||||
|
||||
struct pci_dev *devices = get_pci_devices_from_pciutils();
|
||||
gpu->pci = get_pci_from_pciutils(devices);
|
||||
gpu->pci = get_pci_from_pciutils(devices, PCI_VENDOR_ID_NVIDIA);
|
||||
gpu->arch = get_uarch_from_cuda(gpu);
|
||||
gpu->cach = get_cache_info(deviceProp);
|
||||
gpu->mem = get_memory_info(gpu, deviceProp);
|
||||
|
||||
@@ -10,20 +10,6 @@
|
||||
else if (pci->device_id == id) return chip;
|
||||
#define CHECK_PCI_END else { printBug("TODOO"); return CHIP_UNKNOWN; }
|
||||
|
||||
struct pci {
|
||||
uint16_t vendor_id;
|
||||
uint16_t device_id;
|
||||
};
|
||||
|
||||
struct pci* get_pci_from_pciutils(struct pci_dev *devices) {
|
||||
struct pci* pci = (struct pci*) emalloc(sizeof(struct pci));
|
||||
|
||||
pci->vendor_id = pciutils_get_pci_vendor_id(devices);
|
||||
pci->device_id = pciutils_get_pci_device_id(devices);
|
||||
|
||||
return pci;
|
||||
}
|
||||
|
||||
/*
|
||||
* pci ids were retrieved using https://github.com/pciutils/pciids
|
||||
* and parsed using a custom script to take only the relevant
|
||||
|
||||
@@ -6,6 +6,12 @@
|
||||
#include "../common/pci.hpp"
|
||||
#include "chips.hpp"
|
||||
|
||||
/*
|
||||
* doc: https://wiki.osdev.org/PCI#Class_Codes
|
||||
* https://pci-ids.ucw.cz/read/PC
|
||||
*/
|
||||
#define PCI_VENDOR_ID_NVIDIA 0x10de
|
||||
|
||||
struct pci;
|
||||
|
||||
struct pci* get_pci_from_pciutils(struct pci_dev *devices);
|
||||
|
||||
@@ -3,12 +3,11 @@
|
||||
#include <stdint.h>
|
||||
#include <cstddef>
|
||||
|
||||
#include "../common/uarch.hpp"
|
||||
#include "../common/global.hpp"
|
||||
#include "../common/gpu.hpp"
|
||||
#include "chips.hpp"
|
||||
|
||||
typedef uint32_t MICROARCH;
|
||||
|
||||
// Any clock multiplier
|
||||
#define CM_ANY -1
|
||||
|
||||
@@ -43,19 +42,6 @@ static const char *uarch_str[] = {
|
||||
/*[ARCH_AMPERE] = */ "Ampere",
|
||||
};
|
||||
|
||||
struct uarch {
|
||||
int32_t cc_major;
|
||||
int32_t cc_minor;
|
||||
int32_t compute_capability;
|
||||
|
||||
MICROARCH uarch;
|
||||
GPUCHIP chip;
|
||||
|
||||
int32_t process;
|
||||
char* uarch_str;
|
||||
char* chip_str;
|
||||
};
|
||||
|
||||
#define CHECK_UARCH_START if (false) {}
|
||||
#define CHECK_UARCH(arch, chip_, str, uarch, process) \
|
||||
else if (arch->chip == chip_) fill_uarch(arch, str, uarch, process);
|
||||
|
||||
13
src/intel/chips.hpp
Normal file
13
src/intel/chips.hpp
Normal file
@@ -0,0 +1,13 @@
|
||||
#ifndef __INTEL_GPUCHIPS__
|
||||
#define __INTEL_GPUCHIPS__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef uint32_t GPUCHIP;
|
||||
|
||||
enum {
|
||||
CHIP_UNKNOWN_INTEL,
|
||||
CHIP_UHDG_620,
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "intel.hpp"
|
||||
#include "uarch.hpp"
|
||||
#include "chips.hpp"
|
||||
#include "../common/pci.hpp"
|
||||
#include "../common/global.hpp"
|
||||
|
||||
@@ -11,8 +12,11 @@ struct gpu_info* get_gpu_info_intel() {
|
||||
const char* name = "UHD Graphics XXX";
|
||||
|
||||
gpu->vendor = GPU_VENDOR_INTEL;
|
||||
gpu->name = (char *) emalloc(sizeof(char) * (strlen(name) + 1));
|
||||
strcpy(gpu->name, name);
|
||||
|
||||
struct pci_dev *devices = get_pci_devices_from_pciutils();
|
||||
gpu->pci = get_pci_from_pciutils(devices, PCI_VENDOR_ID_INTEL);
|
||||
gpu->arch = get_uarch_from_pci(gpu->pci);
|
||||
gpu->name = get_name_from_uarch(gpu->arch);
|
||||
|
||||
return gpu;
|
||||
}
|
||||
|
||||
17
src/intel/pci.cpp
Normal file
17
src/intel/pci.cpp
Normal file
@@ -0,0 +1,17 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "pci.hpp"
|
||||
#include "chips.hpp"
|
||||
#include "../common/global.hpp"
|
||||
#include "../common/pci.hpp"
|
||||
|
||||
#define CHECK_PCI_START if (false) {}
|
||||
#define CHECK_PCI(pci, id, chip) \
|
||||
else if (pci->device_id == id) return chip;
|
||||
#define CHECK_PCI_END else { printBug("TODOO"); return CHIP_UNKNOWN_INTEL; }
|
||||
|
||||
GPUCHIP get_chip_from_pci(struct pci* pci) {
|
||||
CHECK_PCI_START
|
||||
CHECK_PCI(pci, 0x5917, CHIP_UHDG_620)
|
||||
CHECK_PCI_END
|
||||
}
|
||||
20
src/intel/pci.hpp
Normal file
20
src/intel/pci.hpp
Normal file
@@ -0,0 +1,20 @@
|
||||
#ifndef __PCI_INTEL__
|
||||
#define __PCI_INTEL__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "../common/pci.hpp"
|
||||
#include "chips.hpp"
|
||||
|
||||
/*
|
||||
* doc: https://wiki.osdev.org/PCI#Class_Codes
|
||||
* https://pci-ids.ucw.cz/read/PC
|
||||
*/
|
||||
#define PCI_VENDOR_ID_INTEL 0x8086
|
||||
|
||||
struct pci;
|
||||
|
||||
struct pci* get_pci_from_pciutils(struct pci_dev *devices);
|
||||
GPUCHIP get_chip_from_pci(struct pci* pci);
|
||||
|
||||
#endif
|
||||
59
src/intel/uarch.cpp
Normal file
59
src/intel/uarch.cpp
Normal file
@@ -0,0 +1,59 @@
|
||||
#include <stdint.h>
|
||||
#include <cstddef>
|
||||
#include <string.h>
|
||||
|
||||
#include "../common/uarch.hpp"
|
||||
#include "../common/global.hpp"
|
||||
#include "../common/gpu.hpp"
|
||||
#include "chips.hpp"
|
||||
|
||||
// Data not available
|
||||
#define NA -1
|
||||
|
||||
// Unknown manufacturing process
|
||||
#define UNK -1
|
||||
|
||||
// MICROARCH values
|
||||
enum {
|
||||
UARCH_UNKNOWN,
|
||||
UARCH_GEN9,
|
||||
UARCH_GEN9_5,
|
||||
};
|
||||
|
||||
static const char *uarch_str[] = {
|
||||
/*[ARCH_UNKNOWN = */ STRING_UNKNOWN,
|
||||
/*[ARCH_GEN9] = */ "Gen9",
|
||||
/*[ARCH_GEN9.5] = */ "Gen9.5",
|
||||
};
|
||||
|
||||
#define CHECK_UARCH_START if (false) {}
|
||||
#define CHECK_UARCH(arch, chip_, str, uarch, process) \
|
||||
else if (arch->chip == chip_) fill_uarch(arch, str, uarch, process);
|
||||
#define CHECK_UARCH_END else { printBug("map_chip_to_uarch: Unknown chip id: %d", arch->chip); fill_uarch(arch, STRING_UNKNOWN, UARCH_UNKNOWN, 0); }
|
||||
|
||||
void fill_uarch(struct uarch* arch, char const *str, MICROARCH u, uint32_t process) {
|
||||
arch->chip_str = (char *) emalloc(sizeof(char) * (strlen(str)+1));
|
||||
strcpy(arch->chip_str, str);
|
||||
arch->uarch = u;
|
||||
arch->process = process;
|
||||
}
|
||||
|
||||
void map_chip_to_uarch(struct uarch* arch) {
|
||||
CHECK_UARCH_START
|
||||
CHECK_UARCH(arch, CHIP_UHDG_620, "UHD Graphics 620", UARCH_GEN9_5, 14)
|
||||
CHECK_UARCH_END
|
||||
}
|
||||
|
||||
struct uarch* get_uarch_from_pci(struct pci* pci) {
|
||||
struct uarch* arch = (struct uarch*) emalloc(sizeof(struct uarch));
|
||||
|
||||
arch->chip_str = NULL;
|
||||
arch->chip = get_chip_from_pci(pci);
|
||||
map_chip_to_uarch(arch);
|
||||
|
||||
return arch;
|
||||
}
|
||||
|
||||
char* get_name_from_uarch(struct uarch* arch) {
|
||||
return arch->chip_str;
|
||||
}
|
||||
@@ -3,4 +3,9 @@
|
||||
|
||||
#include "../common/gpu.hpp"
|
||||
|
||||
struct uarch;
|
||||
|
||||
struct uarch* get_uarch_from_pci(struct pci* pci);
|
||||
char* get_name_from_uarch(struct uarch* arch);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user