ohmu
·
2026-10-15
1#include "gpu_driver_specific.h"
2
3#include "common/library.h"
4#include "mtml.h"
5
6struct FFMtmlData {
7 FF_LIBRARY_SYMBOL(mtmlDeviceCountGpuCores)
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 FF_LIBRARY_SYMBOL(mtmlLibraryShutDown)
26
27 bool inited;
28 MtmlLibrary* lib;
29 MtmlSystem* sys;
30} mtmlData;
31
32[[maybe_unused]] static void shutdownMtml(void) {
33 mtmlData.ffmtmlLibraryShutDown(mtmlData.lib);
34}
35
36const char* ffDetectMthreadsGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverResult result, const char* soName) {
37#ifndef FF_DISABLE_DLOPEN
38
39 if (!mtmlData.inited) {
40 mtmlData.inited = true;
41 FF_LIBRARY_LOAD(libmtml, "dlopen mtml failed", soName, 1);
42 FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libmtml, mtmlLibraryInit)
43 FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlDeviceCountGpuCores)
44 FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlDeviceGetBrand)
45 FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlDeviceGetIndex)
46 FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlDeviceGetName)
47 FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlDeviceGetPciInfo)
48 FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlDeviceGetUUID)
49 FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlDeviceInitGpu)
50 FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlDeviceInitMemory)
51 FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlGpuGetMaxClock)
52 FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlGpuGetTemperature)
53 FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlGpuGetUtilization)
54 FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlLibraryCountDevice)
55 FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlLibraryInitDeviceByIndex)
56 FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlLibraryInitDeviceByPciSbdf)
57 FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlLibraryInitSystem)
58 FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlMemoryGetTotal)
59 FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlMemoryGetUsed)
60 FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlMemoryGetUtilization)
61 FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlLibraryShutDown)
62
63 if (ffmtmlLibraryInit(&mtmlData.lib) != MTML_SUCCESS) {
64 mtmlData.ffmtmlLibraryInitSystem = nullptr;
65 return "mtmlLibraryInit failed";
66 }
67 if (mtmlData.ffmtmlLibraryInitSystem(mtmlData.lib, &mtmlData.sys) != MTML_SUCCESS) {
68 mtmlData.ffmtmlLibraryShutDown(mtmlData.lib);
69 mtmlData.ffmtmlLibraryInitSystem = nullptr;
70 return "mtmlLibraryInitSystem failed";
71 }
72 atexit(shutdownMtml);
73 libmtml = nullptr; // don't close mtml
74 }
75
76 if (mtmlData.ffmtmlLibraryInitSystem == nullptr) {
77 return "loading mtml library failed";
78 }
79
80 MtmlDevice* device = nullptr;
81 if (cond->type & FF_GPU_DRIVER_CONDITION_TYPE_BUS_ID) {
82 char pciBusIdStr[32];
83 snprintf(pciBusIdStr, ARRAY_SIZE(pciBusIdStr) - 1, "%04x:%02x:%02x.%d", cond->pciBusId.domain, cond->pciBusId.bus, cond->pciBusId.device, cond->pciBusId.func);
84
85 MtmlReturn ret = mtmlData.ffmtmlLibraryInitDeviceByPciSbdf(mtmlData.lib, pciBusIdStr, &device);
86 if (ret != MTML_SUCCESS) {
87 return "mtmlLibraryInitDeviceByPciSbdf() failed";
88 }
89 } else if (cond->type & FF_GPU_DRIVER_CONDITION_TYPE_DEVICE_ID) {
90 uint32_t count;
91 if (mtmlData.ffmtmlLibraryCountDevice(mtmlData.lib, &count) != MTML_SUCCESS) {
92 return "mtmlLibraryCountDevice() failed";
93 }
94
95 for (uint32_t i = 0; i < count; i++, device = nullptr) {
96 if (mtmlData.ffmtmlLibraryInitDeviceByIndex(mtmlData.lib, i, &device) != MTML_SUCCESS) {
97 continue;
98 }
99
100 MtmlPciInfo pciInfo;
101 if (mtmlData.ffmtmlDeviceGetPciInfo(device, &pciInfo) != MTML_SUCCESS) {
102 continue;
103 }
104
105 if (pciInfo.pciDeviceId != ((cond->pciDeviceId.deviceId << 16u) | cond->pciDeviceId.vendorId) ||
106 pciInfo.pciSubsystemId != cond->pciDeviceId.subSystemId) {
107 continue;
108 }
109
110 break;
111 }
112 if (!device) {
113 return "Device not found";
114 }
115 } else {
116 return "Unknown condition type";
117 }
118
119 MtmlBrandType brand;
120 if (mtmlData.ffmtmlDeviceGetBrand(device, &brand) == MTML_SUCCESS) {
121 switch (brand) {
122 case MTML_BRAND_MTT:
123 *result.type = FF_GPU_TYPE_DISCRETE;
124 break;
125 default:
126 break;
127 }
128 }
129
130 if (result.index) {
131 unsigned int value;
132 if (mtmlData.ffmtmlDeviceGetIndex(device, &value) == MTML_SUCCESS) {
133 *result.index = value;
134 }
135 }
136
137 if (result.temp) {
138 MtmlGpu* gpu = nullptr;
139 if (mtmlData.ffmtmlDeviceInitGpu(device, &gpu) == MTML_SUCCESS) {
140 uint32_t value;
141 if (mtmlData.ffmtmlGpuGetTemperature(gpu, &value) == MTML_SUCCESS) {
142 *result.temp = value;
143 }
144 }
145 }
146
147 if (result.memory) {
148 MtmlMemory* mem = nullptr;
149 if (mtmlData.ffmtmlDeviceInitMemory(device, &mem) == MTML_SUCCESS) {
150 unsigned long long total;
151 if (mtmlData.ffmtmlMemoryGetTotal(mem, &total) == MTML_SUCCESS) {
152 result.memory->total = total;
153 }
154
155 unsigned long long used;
156 if (mtmlData.ffmtmlMemoryGetUsed(mem, &used) == MTML_SUCCESS) {
157 result.memory->used = used;
158 }
159 }
160 }
161
162 if (result.coreCount) {
163 mtmlData.ffmtmlDeviceCountGpuCores(device, result.coreCount);
164 }
165
166 if (result.frequency) {
167 MtmlGpu* gpu = nullptr;
168 if (mtmlData.ffmtmlDeviceInitGpu(device, &gpu) == MTML_SUCCESS) {
169 uint32_t clockMHz;
170 if (mtmlData.ffmtmlGpuGetMaxClock(gpu, &clockMHz) == MTML_SUCCESS) {
171 *result.frequency = clockMHz;
172 }
173 }
174 }
175
176 if (result.coreUsage) {
177 MtmlGpu* gpu = nullptr;
178 if (mtmlData.ffmtmlDeviceInitGpu(device, &gpu) == MTML_SUCCESS) {
179 unsigned int utilization;
180 if (mtmlData.ffmtmlGpuGetUtilization(gpu, &utilization) == MTML_SUCCESS) {
181 *result.coreUsage = utilization;
182 }
183 }
184 }
185
186 if (result.name) {
187 char name[MTML_DEVICE_NAME_BUFFER_SIZE];
188 if (mtmlData.ffmtmlDeviceGetName(device, name, ARRAY_SIZE(name)) == MTML_SUCCESS) {
189 ffStrbufSetS(result.name, name);
190 }
191 }
192
193 if (result.psCurr || result.psMax) {
194 MtmlPciInfo pciInfo;
195 if (mtmlData.ffmtmlDeviceGetPciInfo(device, &pciInfo) == MTML_SUCCESS) {
196 if (result.psCurr) {
197 result.psCurr->lanes = (uint16_t) pciInfo.pciCurWidth;
198 result.psCurr->gen = (uint16_t) pciInfo.pciCurGen;
199 }
200 if (result.psMax) {
201 result.psMax->lanes = (uint16_t) pciInfo.pciMaxWidth;
202 result.psMax->gen = (uint16_t) pciInfo.pciMaxGen;
203 }
204 }
205 }
206
207 return nullptr;
208
209#else
210
211 FF_UNUSED(cond, result, soName);
212 return "dlopen is disabled";
213
214#endif
215}