From 4422cf1b17fe4c346ac014c5315d038455a63a82 Mon Sep 17 00:00:00 2001 From: Xiaodong Ye Date: Fri, 2 Aug 2024 12:38:07 +0800 Subject: [PATCH] feat: Support Moore Threads GPU Signed-off-by: Xiaodong Ye --- CMakeLists.txt | 3 + src/detection/gpu/gpu.c | 4 + src/detection/gpu/gpu.h | 1 + src/detection/gpu/gpu_driver_specific.h | 2 + src/detection/gpu/gpu_linux.c | 23 +++ src/detection/gpu/gpu_mthreads.c | 232 ++++++++++++++++++++++++ src/detection/gpu/mtml.h | 116 ++++++++++++ 7 files changed, 381 insertions(+) create mode 100644 src/detection/gpu/gpu_mthreads.c create mode 100644 src/detection/gpu/mtml.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 319bc18e77..9af2b04414 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -843,6 +843,9 @@ if(WIN32) list(APPEND LIBFASTFETCH_SRC src/detection/gpu/gpu_intel.c) list(APPEND LIBFASTFETCH_SRC src/detection/gpu/gpu_amd.c) endif() +if(LINUX) + list(APPEND LIBFASTFETCH_SRC src/detection/gpu/gpu_mthreads.c) +endif() include(CheckFunctionExists) check_function_exists(wcwidth HAVE_WCWIDTH) diff --git a/src/detection/gpu/gpu.c b/src/detection/gpu/gpu.c index fee845022c..d1831f92a9 100644 --- a/src/detection/gpu/gpu.c +++ b/src/detection/gpu/gpu.c @@ -7,6 +7,7 @@ const char* FF_GPU_VENDOR_NAME_APPLE = "Apple"; const char* FF_GPU_VENDOR_NAME_AMD = "AMD"; const char* FF_GPU_VENDOR_NAME_INTEL = "Intel"; const char* FF_GPU_VENDOR_NAME_NVIDIA = "NVIDIA"; +const char* FF_GPU_VENDOR_NAME_MTHREADS = "Moore Threads"; const char* FF_GPU_VENDOR_NAME_QUALCOMM = "Qualcomm"; const char* FF_GPU_VENDOR_NAME_MTK = "MTK"; const char* FF_GPU_VENDOR_NAME_VMWARE = "VMware"; @@ -24,6 +25,7 @@ const char* ffGetGPUVendorString(unsigned vendorId) case 0x1002: case 0x1022: return FF_GPU_VENDOR_NAME_AMD; case 0x8086: case 0x8087: case 0x03e7: return FF_GPU_VENDOR_NAME_INTEL; case 0x0955: case 0x10de: case 0x12d2: return FF_GPU_VENDOR_NAME_NVIDIA; + case 0x1ed5: return FF_GPU_VENDOR_NAME_MTHREADS; case 0x5143: return FF_GPU_VENDOR_NAME_QUALCOMM; case 0x14c3: return FF_GPU_VENDOR_NAME_MTK; case 0x15ad: return FF_GPU_VENDOR_NAME_VMWARE; @@ -71,6 +73,8 @@ const char* detectByOpenGL(FFlist* gpus) ffStrbufSetStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_AMD); else if (ffStrbufContainS(&gpu->name, "NVIDIA")) ffStrbufSetStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_NVIDIA); + else if (ffStrbufContainS(&gpu->name, "MTT")) + ffStrbufSetStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_MTHREADS); } diff --git a/src/detection/gpu/gpu.h b/src/detection/gpu/gpu.h index ffa82d0cac..6e999d6ee2 100644 --- a/src/detection/gpu/gpu.h +++ b/src/detection/gpu/gpu.h @@ -12,6 +12,7 @@ extern const char* FF_GPU_VENDOR_NAME_APPLE; extern const char* FF_GPU_VENDOR_NAME_AMD; extern const char* FF_GPU_VENDOR_NAME_INTEL; extern const char* FF_GPU_VENDOR_NAME_NVIDIA; +extern const char* FF_GPU_VENDOR_NAME_MTHREADS; extern const char* FF_GPU_VENDOR_NAME_VMWARE; extern const char* FF_GPU_VENDOR_NAME_PARALLEL; extern const char* FF_GPU_VENDOR_NAME_MICROSOFT; diff --git a/src/detection/gpu/gpu_driver_specific.h b/src/detection/gpu/gpu_driver_specific.h index 5bcf4d2db2..eecd6d8a23 100644 --- a/src/detection/gpu/gpu_driver_specific.h +++ b/src/detection/gpu/gpu_driver_specific.h @@ -48,3 +48,5 @@ typedef struct FFGpuDriverResult const char* ffDetectNvidiaGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverResult result, const char* soName); const char* ffDetectIntelGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverResult result, const char* soName); const char* ffDetectAmdGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverResult result, const char* soName); +const char* ffDetectMthreadsGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverResult result, const char* soName); +const char* ffDetectMthreadsGpuCount(uint32_t* result, const char* soName); diff --git a/src/detection/gpu/gpu_linux.c b/src/detection/gpu/gpu_linux.c index b132d282ad..03301929de 100644 --- a/src/detection/gpu/gpu_linux.c +++ b/src/detection/gpu/gpu_linux.c @@ -380,6 +380,29 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf gpu->type = FF_GPU_TYPE_DISCRETE; } } + else if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_MTHREADS) + { + if (options->temp || options->driverSpecific) + { + ffDetectMthreadsGpuInfo(&(FFGpuDriverCondition){ + .type = FF_GPU_DRIVER_CONDITION_TYPE_BUS_ID, + .pciBusId = { + .domain = pciDomain, + .bus = pciBus, + .device = pciDevice, + .func = pciFunc, + }, + }, + (FFGpuDriverResult){ + .temp = options->temp ? &gpu->temperature : NULL, + .memory = options->driverSpecific ? &gpu->dedicated : NULL, + .coreCount = options->driverSpecific ? (uint32_t*) &gpu->coreCount : NULL, + .type = &gpu->type, + .frequency = options->driverSpecific ? &gpu->frequency : NULL, + }, + "libmtml.so"); + } + } return NULL; } diff --git a/src/detection/gpu/gpu_mthreads.c b/src/detection/gpu/gpu_mthreads.c new file mode 100644 index 0000000000..97a74bbaf0 --- /dev/null +++ b/src/detection/gpu/gpu_mthreads.c @@ -0,0 +1,232 @@ +#include "gpu_driver_specific.h" + +#include "common/library.h" +#include "mtml.h" + +struct FFMtmlData +{ + FF_LIBRARY_SYMBOL(mtmlDeviceGetBrand) + FF_LIBRARY_SYMBOL(mtmlDeviceGetIndex) + FF_LIBRARY_SYMBOL(mtmlDeviceGetName) + FF_LIBRARY_SYMBOL(mtmlDeviceGetPciInfo) + FF_LIBRARY_SYMBOL(mtmlDeviceGetUUID) + FF_LIBRARY_SYMBOL(mtmlDeviceInitGpu) + FF_LIBRARY_SYMBOL(mtmlDeviceInitMemory) + FF_LIBRARY_SYMBOL(mtmlGpuGetMaxClock) + FF_LIBRARY_SYMBOL(mtmlGpuGetTemperature) + FF_LIBRARY_SYMBOL(mtmlGpuGetUtilization) + FF_LIBRARY_SYMBOL(mtmlLibraryCountDevice) + FF_LIBRARY_SYMBOL(mtmlLibraryInitDeviceByIndex) + FF_LIBRARY_SYMBOL(mtmlLibraryInitDeviceByPciSbdf) + FF_LIBRARY_SYMBOL(mtmlLibraryInitSystem) + FF_LIBRARY_SYMBOL(mtmlMemoryGetTotal) + FF_LIBRARY_SYMBOL(mtmlMemoryGetUsed) + FF_LIBRARY_SYMBOL(mtmlMemoryGetUtilization) + + bool inited; + MtmlLibrary *lib; + MtmlSystem *sys; +} mtmlData; + +const char *ffDetectMthreadsGpuCount(uint32_t *result, const char *soName) +{ +#ifndef FF_DISABLE_DLOPEN + + if (!mtmlData.inited) + { + mtmlData.inited = true; + FF_LIBRARY_LOAD(libmtml, NULL, "dlopen mtml failed", soName, 1); + FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libmtml, mtmlLibraryInit) + FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libmtml, mtmlLibraryShutDown) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlDeviceGetBrand) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlDeviceGetIndex) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlDeviceGetName) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlDeviceGetPciInfo) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlDeviceGetUUID) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlDeviceInitGpu) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlDeviceInitMemory) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlGpuGetMaxClock) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlGpuGetTemperature) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlGpuGetUtilization) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlLibraryCountDevice) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlLibraryInitDeviceByIndex) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlLibraryInitDeviceByPciSbdf) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlLibraryInitSystem) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlMemoryGetTotal) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlMemoryGetUsed) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlMemoryGetUtilization) + + if (ffmtmlLibraryInit(&mtmlData.lib) != MTML_SUCCESS) + { + mtmlData.ffmtmlLibraryInitSystem = NULL; + return "mtmlLibraryInit failed"; + } + if (mtmlData.ffmtmlLibraryInitSystem(mtmlData.lib, &mtmlData.sys) != MTML_SUCCESS) + { + mtmlData.ffmtmlLibraryInitSystem = NULL; + return "mtmlLibraryInitSystem failed"; + } + atexit((void *)ffmtmlLibraryShutDown); + libmtml = NULL; // don't close mtml + } + + if (mtmlData.ffmtmlLibraryInitSystem == NULL) + return "loading mtml library failed"; + + uint32_t count; + if (mtmlData.ffmtmlLibraryCountDevice(mtmlData.lib, &count) != MTML_SUCCESS) + return "mtmlLibraryCountDevice() failed"; + + *result = count; + return NULL; +#else + + FF_UNUSED(cond, result, soName); + return "dlopen is disabled"; + +#endif +} + +const char *ffDetectMthreadsGpuInfo(const FFGpuDriverCondition *cond, FFGpuDriverResult result, const char *soName) +{ +#ifndef FF_DISABLE_DLOPEN + + if (!mtmlData.inited) + { + mtmlData.inited = true; + FF_LIBRARY_LOAD(libmtml, NULL, "dlopen mtml failed", soName, 1); + FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libmtml, mtmlLibraryInit) + FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libmtml, mtmlLibraryShutDown) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlDeviceGetBrand) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlDeviceGetIndex) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlDeviceGetName) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlDeviceGetPciInfo) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlDeviceGetUUID) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlDeviceInitGpu) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlDeviceInitMemory) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlGpuGetMaxClock) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlGpuGetTemperature) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlGpuGetUtilization) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlLibraryCountDevice) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlLibraryInitDeviceByIndex) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlLibraryInitDeviceByPciSbdf) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlLibraryInitSystem) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlMemoryGetTotal) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlMemoryGetUsed) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlMemoryGetUtilization) + + if (ffmtmlLibraryInit(&mtmlData.lib) != MTML_SUCCESS) + { + mtmlData.ffmtmlLibraryInitSystem = NULL; + return "mtmlLibraryInit failed"; + } + if (mtmlData.ffmtmlLibraryInitSystem(mtmlData.lib, &mtmlData.sys) != MTML_SUCCESS) + { + mtmlData.ffmtmlLibraryInitSystem = NULL; + return "mtmlLibraryInitSystem failed"; + } + atexit((void *)ffmtmlLibraryShutDown); + libmtml = NULL; // don't close mtml + } + + if (mtmlData.ffmtmlLibraryInitSystem == NULL) + return "loading mtml library failed"; + + MtmlDevice *device = NULL; + if (cond->type & FF_GPU_DRIVER_CONDITION_TYPE_BUS_ID) + { + char pciBusIdStr[32]; + snprintf(pciBusIdStr, sizeof(pciBusIdStr) - 1, "%04x:%02x:%02x.%d", cond->pciBusId.domain, cond->pciBusId.bus, cond->pciBusId.device, cond->pciBusId.func); + + MtmlReturn ret = mtmlData.ffmtmlLibraryInitDeviceByPciSbdf(mtmlData.lib, pciBusIdStr, &device); + if (ret != MTML_SUCCESS) + return "mtmlLibraryInitDeviceByPciSbdf() failed"; + } + else if (cond->type & FF_GPU_DRIVER_CONDITION_TYPE_DEVICE_ID) + { + uint32_t count; + if (mtmlData.ffmtmlLibraryCountDevice(mtmlData.lib, &count) != MTML_SUCCESS) + return "mtmlLibraryCountDevice() failed"; + + for (uint32_t i = 0; i < count; i++, device = NULL) + { + if (mtmlData.ffmtmlLibraryInitDeviceByIndex(mtmlData.lib, i, &device) != MTML_SUCCESS) + continue; + + MtmlPciInfo pciInfo; + if (mtmlData.ffmtmlDeviceGetPciInfo(device, &pciInfo) != MTML_SUCCESS) + continue; + + if (pciInfo.pciDeviceId != ((cond->pciDeviceId.deviceId << 16u) | cond->pciDeviceId.vendorId) || + pciInfo.pciSubsystemId != cond->pciDeviceId.subSystemId) + continue; + + break; + } + if (!device) + return "Device not found"; + } + else + { + return "Unknown condition type"; + } + + MtmlBrandType brand; + if (mtmlData.ffmtmlDeviceGetBrand(device, &brand) == MTML_SUCCESS) + { + switch (brand) + { + case MTML_BRAND_MTT: + *result.type = FF_GPU_TYPE_DISCRETE; + break; + default: + break; + } + } + + if (result.temp) + { + MtmlGpu *gpu = NULL; + if (mtmlData.ffmtmlDeviceInitGpu(device, &gpu) == MTML_SUCCESS) + { + uint32_t value; + if (mtmlData.ffmtmlGpuGetTemperature(gpu, &value) == MTML_SUCCESS) + *result.temp = value; + } + } + + if (result.memory) + { + MtmlMemory *mem = NULL; + if (mtmlData.ffmtmlDeviceInitMemory(device, &mem) == MTML_SUCCESS) + { + unsigned long long total; + if (mtmlData.ffmtmlMemoryGetTotal(mem, &total) == MTML_SUCCESS) + result.memory->total = total; + + unsigned long long used; + if (mtmlData.ffmtmlMemoryGetUsed(mem, &used) == MTML_SUCCESS) + result.memory->used = used; + } + } + + if (result.frequency) + { + MtmlGpu *gpu = NULL; + if (mtmlData.ffmtmlDeviceInitGpu(device, &gpu) == MTML_SUCCESS) + { + uint32_t clockMHz; + if (mtmlData.ffmtmlGpuGetMaxClock(gpu, &clockMHz) == MTML_SUCCESS) + *result.frequency = clockMHz / 1000.; + } + } + + return NULL; + +#else + + FF_UNUSED(cond, result, soName); + return "dlopen is disabled"; + +#endif +} diff --git a/src/detection/gpu/mtml.h b/src/detection/gpu/mtml.h new file mode 100644 index 0000000000..421cb0b241 --- /dev/null +++ b/src/detection/gpu/mtml.h @@ -0,0 +1,116 @@ +#pragma once + +// DISCLAIMER: +// THIS FILE IS CREATED FROM SCRATCH, BY READING THE OFFICIAL MTML API +// DOCUMENTATION REFERENCED BELOW, IN ORDER TO MAKE FASTFETCH MIT COMPLIANT. + +#define MTML_API __attribute__((visibility("default"))) +#define MTML_DEVICE_PCI_SBDF_BUFFER_SIZE 32 +#define MTML_DEVICE_NAME_BUFFER_SIZE 32 +#define MTML_DEVICE_UUID_BUFFER_SIZE 48 + +/** + * Return values for MTML API calls. + */ +typedef enum +{ + MTML_SUCCESS = 0, +} MtmlReturn; + +/** + * The brand of the device. + */ +typedef enum +{ + MTML_BRAND_MTT = 0, //!< MTT series. + MTML_BRAND_UNKNOWN, //!< An unknown brand. + + // Keep this on the last line. + MTML_BRAND_COUNT //!< The number of brands. +} MtmlBrandType; + +typedef struct MtmlLibrary MtmlLibrary; +typedef struct MtmlSystem MtmlSystem; +typedef struct MtmlDevice MtmlDevice; +typedef struct MtmlGpu MtmlGpu; +typedef struct MtmlMemory MtmlMemory; + +/** + * PCI information about a device. + */ +typedef struct +{ + char sbdf[MTML_DEVICE_PCI_SBDF_BUFFER_SIZE]; //!< The tuple segment:bus:device.function PCI identifier (& NULL terminator). + unsigned int segment; //!< The PCI segment group(domain) on which the device's bus resides, 0 to 0xffffffff. + unsigned int bus; //!< The bus on which the device resides, 0 to 0xff. + unsigned int device; //!< The device ID on the bus, 0 to 31. + unsigned int pciDeviceId; //!< The combined 16-bit device ID and 16-bit vendor ID. + unsigned int pciSubsystemId; //!< The 32-bit sub system device ID. + unsigned int busWidth; //!< @deprecated This value set to zero. + float pciMaxSpeed; //!< The maximum link speed (transfer rate per lane) of the device. The unit is GT/s. + float pciCurSpeed; //!< The current link speed (transfer rate per lane) of the device. The unit is GT/s. + unsigned int pciMaxWidth; //!< The maximum link width of the device. + unsigned int pciCurWidth; //!< The current link width of the device. + unsigned int pciMaxGen; //!< The maximum supported generation of the device. + unsigned int pciCurGen; //!< The current generation of the device. + int rsvd[6]; //!< Reserved for future extension. +} MtmlPciInfo; + +// Retrieves the brand of a device. +MtmlReturn MTML_API mtmlDeviceGetBrand(const MtmlDevice *dev, MtmlBrandType *type); +// Retrieves the index associated with the specified device. +MtmlReturn MTML_API mtmlDeviceGetIndex(const MtmlDevice *dev, unsigned int *index); +// Retrieves the name of a device. +MtmlReturn MTML_API mtmlDeviceGetName(const MtmlDevice *dev, char *name, unsigned int length); +// Retrieves the PCI attributes of a device. +MtmlReturn MTML_API mtmlDeviceGetPciInfo(const MtmlDevice *dev, MtmlPciInfo *pci); +/** + * Retrieves the UUID of a specified device. The UUID is a hexadecimal string in the + * form of xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, where each 'x' is an ASCII character that represents a hexidecimal + * digit. The UUID is globally unique for every single device thus can be used to identify different devices + * physically. + */ +MtmlReturn MTML_API mtmlDeviceGetUUID(const MtmlDevice *dev, char *uuid, unsigned int length); +// Initializes a GPU opaque object to represent a specific graphic core on the target device that is designated by its index. +MtmlReturn MTML_API mtmlDeviceInitGpu(const MtmlDevice *dev, MtmlGpu **gpu); +// Initializes a memory opaque object to represent the memory on the target device. +MtmlReturn MTML_API mtmlDeviceInitMemory(const MtmlDevice *dev, MtmlMemory **mem); + +// Retrieves the maximum supported clock speed for the device's graphic core. +MtmlReturn MTML_API mtmlGpuGetMaxClock(const MtmlGpu *gpu, unsigned int *clockMhz); +// Retrieves the current temperature readings for the device's graphic core, in degrees Celsius. +MtmlReturn MTML_API mtmlGpuGetTemperature(const MtmlGpu *gpu, unsigned int *temp); +// Retrieves the current utilization rate for the device's graphic core. +MtmlReturn MTML_API mtmlGpuGetUtilization(const MtmlGpu *gpu, unsigned int *utilization); + +// Retrieves the number of devices that can be accessed by the library opaque object. +MtmlReturn MTML_API mtmlLibraryCountDevice(const MtmlLibrary *lib, unsigned int *count); +/** + * Initializes a device opaque object to represent a device that is designated by its index. + * The index ranges from (0) to (deviceCount - 1), where deviceCount is retrieved from \ref mtmlLibraryCountDevice(). + */ +MtmlReturn MTML_API mtmlLibraryInit(MtmlLibrary **lib); +/** + * Initializes a device opaque object to represent a device that is designated by its index. + * The index ranges from (0) to (deviceCount - 1), where deviceCount is retrieved from \ref mtmlLibraryCountDevice(). + */ +MtmlReturn MTML_API mtmlLibraryInitDeviceByIndex(const MtmlLibrary *lib, unsigned int index, MtmlDevice **dev); +/** + * Initializes a device opaque object to represent a device that is designated by its PCI Sbdf. + * The PCI Sbdf format like 00000000:3a:00.0 refer to \ref MtmlPciInfo::sbdf. + */ +MtmlReturn MTML_API mtmlLibraryInitDeviceByPciSbdf(const MtmlLibrary *lib, const char *pciSbdf, MtmlDevice **dev); +// Initializes a MtmlSystem opaque pointer that is bound to a library opaque object. +MtmlReturn MTML_API mtmlLibraryInitSystem(const MtmlLibrary *lib, MtmlSystem **sys); +/** + * Shuts down the library opaque object that is previously initialized by \ref mtmlLibraryInit() and releases its resources. + * The \a lib pointer cannot be used anymore after this function returns. + */ +MtmlReturn MTML_API mtmlLibraryShutDown(MtmlLibrary *lib); + +// Retrieves the amount of total memory available on the device, in bytes. +MtmlReturn MTML_API mtmlMemoryGetTotal(const MtmlMemory *mem, unsigned long long *total); +// Retrieves the amount of used memory on the device, in bytes. +MtmlReturn MTML_API mtmlMemoryGetUsed(const MtmlMemory *mem, unsigned long long *used); +// Retrieves the current memory utilization rate for the device. +MtmlReturn MTML_API mtmlMemoryGetUtilization(const MtmlMemory *mem, unsigned int *utilization);