Skip to content

Commit ba3bff8

Browse files
authored
Merge pull request #2 from makllama/mthreads
feat: Support Moore Threads GPU
2 parents da10faf + 8df0165 commit ba3bff8

File tree

7 files changed

+386
-1
lines changed

7 files changed

+386
-1
lines changed

CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -835,6 +835,9 @@ if(WIN32)
835835
list(APPEND LIBFASTFETCH_SRC src/detection/gpu/gpu_intel.c)
836836
list(APPEND LIBFASTFETCH_SRC src/detection/gpu/gpu_amd.c)
837837
endif()
838+
if(LINUX)
839+
list(APPEND LIBFASTFETCH_SRC src/detection/gpu/gpu_mthreads.c)
840+
endif()
838841

839842
include(CheckFunctionExists)
840843
check_function_exists(wcwidth HAVE_WCWIDTH)

src/detection/gpu/gpu.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const char* FF_GPU_VENDOR_NAME_APPLE = "Apple";
77
const char* FF_GPU_VENDOR_NAME_AMD = "AMD";
88
const char* FF_GPU_VENDOR_NAME_INTEL = "Intel";
99
const char* FF_GPU_VENDOR_NAME_NVIDIA = "NVIDIA";
10+
const char* FF_GPU_VENDOR_NAME_MTHREADS = "Moore Threads";
1011
const char* FF_GPU_VENDOR_NAME_QUALCOMM = "Qualcomm";
1112
const char* FF_GPU_VENDOR_NAME_MTK = "MTK";
1213
const char* FF_GPU_VENDOR_NAME_VMWARE = "VMware";
@@ -24,6 +25,7 @@ const char* ffGetGPUVendorString(unsigned vendorId)
2425
case 0x1002: case 0x1022: return FF_GPU_VENDOR_NAME_AMD;
2526
case 0x8086: case 0x8087: case 0x03e7: return FF_GPU_VENDOR_NAME_INTEL;
2627
case 0x0955: case 0x10de: case 0x12d2: return FF_GPU_VENDOR_NAME_NVIDIA;
28+
case 0x1ed5: return FF_GPU_VENDOR_NAME_MTHREADS;
2729
case 0x5143: return FF_GPU_VENDOR_NAME_QUALCOMM;
2830
case 0x14c3: return FF_GPU_VENDOR_NAME_MTK;
2931
case 0x15ad: return FF_GPU_VENDOR_NAME_VMWARE;
@@ -73,6 +75,8 @@ const char* detectByOpenGL(FFlist* gpus)
7375
ffStrbufSetStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_AMD);
7476
else if (ffStrbufContainS(&gpu->name, "NVIDIA"))
7577
ffStrbufSetStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_NVIDIA);
78+
else if (ffStrbufContainS(&gpu->name, "MTT"))
79+
ffStrbufSetStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_MTHREADS);
7680

7781
}
7882

src/detection/gpu/gpu.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ extern const char* FF_GPU_VENDOR_NAME_APPLE;
1515
extern const char* FF_GPU_VENDOR_NAME_AMD;
1616
extern const char* FF_GPU_VENDOR_NAME_INTEL;
1717
extern const char* FF_GPU_VENDOR_NAME_NVIDIA;
18+
extern const char* FF_GPU_VENDOR_NAME_MTHREADS;
1819
extern const char* FF_GPU_VENDOR_NAME_VMWARE;
1920
extern const char* FF_GPU_VENDOR_NAME_PARALLEL;
2021
extern const char* FF_GPU_VENDOR_NAME_MICROSOFT;

src/detection/gpu/gpu_driver_specific.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,12 @@ typedef struct FFGpuDriverResult
4848
uint32_t* coreCount;
4949
FFGPUType* type;
5050
double* frequency;
51-
double* coreUtilizationRate;
51+
double* coreUtilizationRate;
5252
} FFGpuDriverResult;
5353

5454
const char* ffDetectNvidiaGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverResult result, const char* soName);
5555
const char* ffDetectNvidiaGpuCount(uint32_t* result, const char* soName);
5656
const char* ffDetectIntelGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverResult result, const char* soName);
5757
const char* ffDetectAmdGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverResult result, const char* soName);
58+
const char* ffDetectMthreadsGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverResult result, const char* soName);
59+
const char* ffDetectMthreadsGpuCount(uint32_t* result, const char* soName);

src/detection/gpu/gpu_linux.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,41 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf
310310
gpu->type = FF_GPU_TYPE_DISCRETE;
311311
}
312312
}
313+
else if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_MTHREADS)
314+
{
315+
if (options->temp || options->driverSpecific)
316+
{
317+
ffDetectMthreadsGpuInfo(&(FFGpuDriverCondition){
318+
.type = FF_GPU_DRIVER_CONDITION_TYPE_BUS_ID,
319+
.pciBusId = {
320+
.domain = pciDomain,
321+
.bus = pciBus,
322+
.device = pciDevice,
323+
.func = pciFunc,
324+
},
325+
},
326+
(FFGpuDriverResult){
327+
.index = &gpu->index,
328+
.temp = options->temp ? &gpu->temperature : NULL,
329+
.memory = options->driverSpecific ? &gpu->dedicated : NULL,
330+
.coreCount = options->driverSpecific ? (uint32_t *)&gpu->coreCount : NULL,
331+
.type = &gpu->type,
332+
.frequency = options->driverSpecific ? &gpu->frequency : NULL,
333+
.coreUtilizationRate = &gpu->coreUtilizationRate,
334+
.uuid = &gpu->uuid,
335+
.name = &gpu->name,
336+
},
337+
"libmtml.so");
338+
}
339+
340+
if (gpu->type == FF_GPU_TYPE_UNKNOWN)
341+
{
342+
if (ffStrbufStartsWithIgnCaseS(&gpu->name, "GeForce") ||
343+
ffStrbufStartsWithIgnCaseS(&gpu->name, "Quadro") ||
344+
ffStrbufStartsWithIgnCaseS(&gpu->name, "Tesla"))
345+
gpu->type = FF_GPU_TYPE_DISCRETE;
346+
}
347+
}
313348

314349
return NULL;
315350
}

src/detection/gpu/gpu_mthreads.c

Lines changed: 269 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,269 @@
1+
#include "gpu_driver_specific.h"
2+
3+
#include "common/library.h"
4+
#include "mtml.h"
5+
6+
struct FFMtmlData
7+
{
8+
FF_LIBRARY_SYMBOL(mtmlDeviceGetBrand)
9+
FF_LIBRARY_SYMBOL(mtmlDeviceGetIndex)
10+
FF_LIBRARY_SYMBOL(mtmlDeviceGetName)
11+
FF_LIBRARY_SYMBOL(mtmlDeviceGetPciInfo)
12+
FF_LIBRARY_SYMBOL(mtmlDeviceGetUUID)
13+
FF_LIBRARY_SYMBOL(mtmlDeviceInitGpu)
14+
FF_LIBRARY_SYMBOL(mtmlDeviceInitMemory)
15+
FF_LIBRARY_SYMBOL(mtmlGpuGetMaxClock)
16+
FF_LIBRARY_SYMBOL(mtmlGpuGetTemperature)
17+
FF_LIBRARY_SYMBOL(mtmlGpuGetUtilization)
18+
FF_LIBRARY_SYMBOL(mtmlLibraryCountDevice)
19+
FF_LIBRARY_SYMBOL(mtmlLibraryInitDeviceByIndex)
20+
FF_LIBRARY_SYMBOL(mtmlLibraryInitDeviceByPciSbdf)
21+
FF_LIBRARY_SYMBOL(mtmlLibraryInitSystem)
22+
FF_LIBRARY_SYMBOL(mtmlMemoryGetTotal)
23+
FF_LIBRARY_SYMBOL(mtmlMemoryGetUsed)
24+
FF_LIBRARY_SYMBOL(mtmlMemoryGetUtilization)
25+
26+
bool inited;
27+
MtmlLibrary *lib;
28+
MtmlSystem *sys;
29+
} mtmlData;
30+
31+
const char *ffDetectMthreadsGpuCount(uint32_t *result, const char *soName)
32+
{
33+
#ifndef FF_DISABLE_DLOPEN
34+
35+
if (!mtmlData.inited)
36+
{
37+
mtmlData.inited = true;
38+
FF_LIBRARY_LOAD(libmtml, NULL, "dlopen mtml failed", soName, 1);
39+
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libmtml, mtmlLibraryInit)
40+
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libmtml, mtmlLibraryShutDown)
41+
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlDeviceGetBrand)
42+
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlDeviceGetIndex)
43+
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlDeviceGetName)
44+
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlDeviceGetPciInfo)
45+
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlDeviceGetUUID)
46+
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlDeviceInitGpu)
47+
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlDeviceInitMemory)
48+
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlGpuGetMaxClock)
49+
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlGpuGetTemperature)
50+
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlGpuGetUtilization)
51+
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlLibraryCountDevice)
52+
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlLibraryInitDeviceByIndex)
53+
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlLibraryInitDeviceByPciSbdf)
54+
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlLibraryInitSystem)
55+
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlMemoryGetTotal)
56+
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlMemoryGetUsed)
57+
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlMemoryGetUtilization)
58+
59+
if (ffmtmlLibraryInit(&mtmlData.lib) != MTML_SUCCESS)
60+
{
61+
mtmlData.ffmtmlLibraryInitSystem = NULL;
62+
return "mtmlLibraryInit failed";
63+
}
64+
if (mtmlData.ffmtmlLibraryInitSystem(mtmlData.lib, &mtmlData.sys) != MTML_SUCCESS)
65+
{
66+
mtmlData.ffmtmlLibraryInitSystem = NULL;
67+
return "mtmlLibraryInitSystem failed";
68+
}
69+
atexit((void *)ffmtmlLibraryShutDown);
70+
libmtml = NULL; // don't close mtml
71+
}
72+
73+
if (mtmlData.ffmtmlLibraryInitSystem == NULL)
74+
return "loading mtml library failed";
75+
76+
uint32_t count;
77+
if (mtmlData.ffmtmlLibraryCountDevice(mtmlData.lib, &count) != MTML_SUCCESS)
78+
return "mtmlLibraryCountDevice() failed";
79+
80+
*result = count;
81+
return NULL;
82+
#else
83+
84+
FF_UNUSED(cond, result, soName);
85+
return "dlopen is disabled";
86+
87+
#endif
88+
}
89+
90+
const char *ffDetectMthreadsGpuInfo(const FFGpuDriverCondition *cond, FFGpuDriverResult result, const char *soName)
91+
{
92+
#ifndef FF_DISABLE_DLOPEN
93+
94+
if (!mtmlData.inited)
95+
{
96+
mtmlData.inited = true;
97+
FF_LIBRARY_LOAD(libmtml, NULL, "dlopen mtml failed", soName, 1);
98+
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libmtml, mtmlLibraryInit)
99+
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libmtml, mtmlLibraryShutDown)
100+
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlDeviceGetBrand)
101+
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlDeviceGetIndex)
102+
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlDeviceGetName)
103+
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlDeviceGetPciInfo)
104+
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlDeviceGetUUID)
105+
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlDeviceInitGpu)
106+
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlDeviceInitMemory)
107+
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlGpuGetMaxClock)
108+
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlGpuGetTemperature)
109+
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlGpuGetUtilization)
110+
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlLibraryCountDevice)
111+
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlLibraryInitDeviceByIndex)
112+
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlLibraryInitDeviceByPciSbdf)
113+
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlLibraryInitSystem)
114+
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlMemoryGetTotal)
115+
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlMemoryGetUsed)
116+
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlMemoryGetUtilization)
117+
118+
if (ffmtmlLibraryInit(&mtmlData.lib) != MTML_SUCCESS)
119+
{
120+
mtmlData.ffmtmlLibraryInitSystem = NULL;
121+
return "mtmlLibraryInit failed";
122+
}
123+
if (mtmlData.ffmtmlLibraryInitSystem(mtmlData.lib, &mtmlData.sys) != MTML_SUCCESS)
124+
{
125+
mtmlData.ffmtmlLibraryInitSystem = NULL;
126+
return "mtmlLibraryInitSystem failed";
127+
}
128+
atexit((void *)ffmtmlLibraryShutDown);
129+
libmtml = NULL; // don't close mtml
130+
}
131+
132+
if (mtmlData.ffmtmlLibraryInitSystem == NULL)
133+
return "loading mtml library failed";
134+
135+
MtmlDevice *device = NULL;
136+
if (cond->type & FF_GPU_DRIVER_CONDITION_TYPE_BUS_ID)
137+
{
138+
char pciBusIdStr[32];
139+
snprintf(pciBusIdStr, sizeof(pciBusIdStr) - 1, "%04x:%02x:%02x.%d", cond->pciBusId.domain, cond->pciBusId.bus, cond->pciBusId.device, cond->pciBusId.func);
140+
141+
MtmlReturn ret = mtmlData.ffmtmlLibraryInitDeviceByPciSbdf(mtmlData.lib, pciBusIdStr, &device);
142+
if (ret != MTML_SUCCESS)
143+
return "mtmlLibraryInitDeviceByPciSbdf() failed";
144+
}
145+
else if (cond->type & FF_GPU_DRIVER_CONDITION_TYPE_DEVICE_ID)
146+
{
147+
uint32_t count;
148+
if (mtmlData.ffmtmlLibraryCountDevice(mtmlData.lib, &count) != MTML_SUCCESS)
149+
return "mtmlLibraryCountDevice() failed";
150+
151+
for (uint32_t i = 0; i < count; i++, device = NULL)
152+
{
153+
if (mtmlData.ffmtmlLibraryInitDeviceByIndex(mtmlData.lib, i, &device) != MTML_SUCCESS)
154+
continue;
155+
156+
MtmlPciInfo pciInfo;
157+
if (mtmlData.ffmtmlDeviceGetPciInfo(device, &pciInfo) != MTML_SUCCESS)
158+
continue;
159+
160+
if (pciInfo.pciDeviceId != ((cond->pciDeviceId.deviceId << 16u) | cond->pciDeviceId.vendorId) ||
161+
pciInfo.pciSubsystemId != cond->pciDeviceId.subSystemId || (cond->pciDeviceId.bus != FF_GPU_BUS_UNSET && (uint32_t)pciInfo.bus != cond->pciDeviceId.bus))
162+
continue;
163+
164+
break;
165+
}
166+
if (!device)
167+
return "Device not found";
168+
}
169+
else if (cond->type & FF_GPU_DRIVER_CONDITION_TYPE_INDEX)
170+
{
171+
if (mtmlData.ffmtmlLibraryInitDeviceByIndex(mtmlData.lib, (unsigned int)cond->index, &device) != MTML_SUCCESS)
172+
return "mtmlLibraryInitDeviceByIndex() failed";
173+
}
174+
else
175+
{
176+
return "Unknown condition type";
177+
}
178+
179+
MtmlBrandType brand;
180+
if (mtmlData.ffmtmlDeviceGetBrand(device, &brand) == MTML_SUCCESS)
181+
{
182+
switch (brand)
183+
{
184+
case MTML_BRAND_MTT:
185+
*result.type = FF_GPU_TYPE_DISCRETE;
186+
break;
187+
default:
188+
break;
189+
}
190+
}
191+
192+
if (result.index)
193+
{
194+
unsigned int value;
195+
if (mtmlData.ffmtmlDeviceGetIndex(device, &value) == MTML_SUCCESS)
196+
*result.index = (uint8_t)value;
197+
}
198+
199+
if (result.temp)
200+
{
201+
MtmlGpu *gpu = NULL;
202+
if (mtmlData.ffmtmlDeviceInitGpu(device, &gpu) == MTML_SUCCESS)
203+
{
204+
uint32_t value;
205+
if (mtmlData.ffmtmlGpuGetTemperature(gpu, &value) == MTML_SUCCESS)
206+
*result.temp = value;
207+
}
208+
}
209+
210+
if (result.memory)
211+
{
212+
MtmlMemory *mem = NULL;
213+
if (mtmlData.ffmtmlDeviceInitMemory(device, &mem) == MTML_SUCCESS)
214+
{
215+
unsigned long long total;
216+
if (mtmlData.ffmtmlMemoryGetTotal(mem, &total) == MTML_SUCCESS)
217+
result.memory->total = total;
218+
219+
unsigned long long used;
220+
if (mtmlData.ffmtmlMemoryGetUsed(mem, &used) == MTML_SUCCESS)
221+
result.memory->used = used;
222+
}
223+
}
224+
225+
if (result.frequency)
226+
{
227+
MtmlGpu *gpu = NULL;
228+
if (mtmlData.ffmtmlDeviceInitGpu(device, &gpu) == MTML_SUCCESS)
229+
{
230+
uint32_t clockMHz;
231+
if (mtmlData.ffmtmlGpuGetMaxClock(gpu, &clockMHz) == MTML_SUCCESS)
232+
*result.frequency = clockMHz / 1000.;
233+
}
234+
}
235+
236+
if (result.coreUtilizationRate)
237+
{
238+
MtmlGpu *gpu = NULL;
239+
if (mtmlData.ffmtmlDeviceInitGpu(device, &gpu) == MTML_SUCCESS)
240+
{
241+
unsigned int utilization;
242+
if (mtmlData.ffmtmlGpuGetUtilization(gpu, &utilization) == MTML_SUCCESS)
243+
*result.coreUtilizationRate = utilization;
244+
}
245+
}
246+
247+
if (result.uuid)
248+
{
249+
char uuid[MTML_DEVICE_UUID_BUFFER_SIZE];
250+
if (mtmlData.ffmtmlDeviceGetUUID(device, uuid, sizeof(uuid)) == MTML_SUCCESS)
251+
ffStrbufAppendS(result.uuid, uuid);
252+
}
253+
254+
if (result.name)
255+
{
256+
char name[MTML_DEVICE_NAME_BUFFER_SIZE];
257+
if (mtmlData.ffmtmlDeviceGetName(device, name, sizeof(name)) == MTML_SUCCESS)
258+
ffStrbufSetS(result.name, name);
259+
}
260+
261+
return NULL;
262+
263+
#else
264+
265+
FF_UNUSED(cond, result, soName);
266+
return "dlopen is disabled";
267+
268+
#endif
269+
}

0 commit comments

Comments
 (0)