aiservermanager 0.4.2 → 0.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/backend/dist/di/container.js +4 -4
- package/backend/dist/di/container.js.map +1 -1
- package/backend/dist/services/probes/amdLinuxUsageProbe.js +36 -17
- package/backend/dist/services/probes/amdLinuxUsageProbe.js.map +1 -1
- package/backend/dist/services/resolvers/sysfsRenderIndexResolver.js +113 -0
- package/backend/dist/services/resolvers/sysfsRenderIndexResolver.js.map +1 -0
- package/package.json +1 -1
- package/backend/dist/services/resolvers/pciBusOrderIndexResolver.js +0 -77
- package/backend/dist/services/resolvers/pciBusOrderIndexResolver.js.map +0 -1
|
@@ -13,7 +13,7 @@ const nvidiaSmiDetector_1 = require("../services/detectors/nvidiaSmiDetector");
|
|
|
13
13
|
const amdLinuxDetector_1 = require("../services/detectors/amdLinuxDetector");
|
|
14
14
|
const wmiDetector_1 = require("../services/detectors/wmiDetector");
|
|
15
15
|
const lspciEnricher_1 = require("../services/enrichers/lspciEnricher");
|
|
16
|
-
const
|
|
16
|
+
const sysfsRenderIndexResolver_1 = require("../services/resolvers/sysfsRenderIndexResolver");
|
|
17
17
|
const listOrderIndexResolver_1 = require("../services/resolvers/listOrderIndexResolver");
|
|
18
18
|
const nvidiaSmiUsageProbe_1 = require("../services/probes/nvidiaSmiUsageProbe");
|
|
19
19
|
const amdLinuxUsageProbe_1 = require("../services/probes/amdLinuxUsageProbe");
|
|
@@ -53,9 +53,9 @@ function createContainer() {
|
|
|
53
53
|
if (!isWindows) {
|
|
54
54
|
container.bind(types_1.GPU_ENRICHER).to(lspciEnricher_1.LspciEnricher);
|
|
55
55
|
}
|
|
56
|
-
// Index resolvers — assign the device number (gpuIndex);
|
|
57
|
-
// first resolver that matches wins (
|
|
58
|
-
container.bind(types_1.GPU_INDEX_RESOLVER).to(
|
|
56
|
+
// Index resolvers — assign the runtime device number (gpuIndex);
|
|
57
|
+
// first resolver that matches wins (sysfs on Linux, list order elsewhere)
|
|
58
|
+
container.bind(types_1.GPU_INDEX_RESOLVER).to(sysfsRenderIndexResolver_1.SysfsRenderIndexResolver);
|
|
59
59
|
container.bind(types_1.GPU_INDEX_RESOLVER).to(listOrderIndexResolver_1.ListOrderIndexResolver);
|
|
60
60
|
// Usage probes — dynamic metrics (usage, temperature, vramUsed)
|
|
61
61
|
container.bind(types_1.GPU_USAGE_PROBE).to(nvidiaSmiUsageProbe_1.NvidiaSmiUsageProbe);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"container.js","sourceRoot":"","sources":["../../src/di/container.ts"],"names":[],"mappings":";;AAiDA,0CAmEC;AApHD,4BAA0B;AAC1B,yCAAsC;AACtC,mCAeiB;AACjB,yDAAsD;AAEtD,kFAA+E;AAC/E,sFAAmF;AACnF,uDAAoD;AACpD,6DAA0D;AAE1D,+EAA4E;AAC5E,6EAA0E;AAC1E,mEAAgE;AAEhE,uEAAoE;AAEpE,6FAA0F;AAC1F,yFAAsF;AAEtF,gFAA6E;AAC7E,8EAA2E;AAC3E,+DAA4D;AAE5D,qFAAkF;AAClF,+FAA4F;AAC5F,iFAA8E;AAC9E,qFAAkF;AAClF,mFAAgF;AAEhF,2FAAwF;AACxF,+FAA4F;AAE5F,MAAM,SAAS,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC;AAE/C,SAAgB,eAAe;IAC7B,MAAM,SAAS,GAAG,IAAI,qBAAS,EAAE,CAAC;IAElC,iDAAiD;IACjD,IAAI,SAAS,EAAE,CAAC;QACd,SAAS,CAAC,IAAI,CAAmB,yBAAiB,CAAC,CAAC,EAAE,CAAC,iDAAuB,CAAC,CAAC,gBAAgB,EAAE,CAAC;IACrG,CAAC;SAAM,CAAC;QACN,SAAS,CAAC,IAAI,CAAmB,yBAAiB,CAAC,CAAC,EAAE,CAAC,6CAAqB,CAAC,CAAC,gBAAgB,EAAE,CAAC;IACnG,CAAC;IAED,yDAAyD;IACzD,SAAS,CAAC,IAAI,CAAc,oBAAY,CAAC,CAAC,EAAE,CAAC,yBAAW,CAAC,CAAC,gBAAgB,EAAE,CAAC;IAE7E,qDAAqD;IACrD,SAAS,CAAC,IAAI,CAAa,mBAAW,CAAC,CAAC,EAAE,CAAC,uBAAU,CAAC,CAAC,gBAAgB,EAAE,CAAC;IAE1E,oCAAoC;IACpC,SAAS,CAAC,IAAI,CAAgB,sBAAc,CAAC,CAAC,EAAE,CAAC,6BAAa,CAAC,CAAC,gBAAgB,EAAE,CAAC;IAEnF,sDAAsD;IACtD,SAAS,CAAC,IAAI,CAAc,oBAAY,CAAC,CAAC,EAAE,CAAC,qCAAiB,CAAC,CAAC;IAChE,IAAI,SAAS,EAAE,CAAC;QACd,SAAS,CAAC,IAAI,CAAc,oBAAY,CAAC,CAAC,EAAE,CAAC,yBAAW,CAAC,CAAC;IAC5D,CAAC;SAAM,CAAC;QACN,SAAS,CAAC,IAAI,CAAc,oBAAY,CAAC,CAAC,EAAE,CAAC,mCAAgB,CAAC,CAAC;IACjE,CAAC;IAED,6CAA6C;IAC7C,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,SAAS,CAAC,IAAI,CAAc,oBAAY,CAAC,CAAC,EAAE,CAAC,6BAAa,CAAC,CAAC;IAC9D,CAAC;IAED,
|
|
1
|
+
{"version":3,"file":"container.js","sourceRoot":"","sources":["../../src/di/container.ts"],"names":[],"mappings":"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"}
|
|
@@ -14,10 +14,17 @@ const inversify_1 = require("inversify");
|
|
|
14
14
|
const ExecTools_1 = require("../../helpers/ExecTools");
|
|
15
15
|
/**
|
|
16
16
|
* Lightweight usage probe for AMD GPUs on Linux via `rocm-smi`.
|
|
17
|
-
* Queries only temperature, usage%, and VRAM — skips product name
|
|
17
|
+
* Queries only temperature, usage%, and VRAM — skips product name.
|
|
18
|
+
*
|
|
19
|
+
* rocm-smi JSON keys are its own card numbers ("card0", "card1", ...) which
|
|
20
|
+
* follow BDF order and are NOT related to the static GPU list order (kernel
|
|
21
|
+
* probe / HIP order can differ, e.g. buses 83/86/C3/C6 probe as C3/C6/83/86).
|
|
22
|
+
* So each card is resolved to its PCI bus via `--showbus` (cached once —
|
|
23
|
+
* static info) and matched to GPUs by pciBusId — never positionally.
|
|
18
24
|
*/
|
|
19
25
|
let AmdLinuxUsageProbe = class AmdLinuxUsageProbe {
|
|
20
26
|
availableCache = null;
|
|
27
|
+
cardBusesCache = null;
|
|
21
28
|
constructor() {
|
|
22
29
|
if (process.platform !== "linux") {
|
|
23
30
|
this.availableCache = false;
|
|
@@ -34,6 +41,8 @@ let AmdLinuxUsageProbe = class AmdLinuxUsageProbe {
|
|
|
34
41
|
return available;
|
|
35
42
|
}
|
|
36
43
|
async probe(gpus) {
|
|
44
|
+
if (gpus.length === 0)
|
|
45
|
+
return [];
|
|
37
46
|
const results = await Promise.all([
|
|
38
47
|
ExecTools_1.ExecTools.safeExec("rocm-smi -t --json", { timeout: 10000 }),
|
|
39
48
|
ExecTools_1.ExecTools.safeExec("rocm-smi -u --json", { timeout: 10000 }),
|
|
@@ -42,11 +51,15 @@ let AmdLinuxUsageProbe = class AmdLinuxUsageProbe {
|
|
|
42
51
|
const tempData = this.parseJson(results[0].stdout);
|
|
43
52
|
const usageData = this.parseJson(results[1].stdout);
|
|
44
53
|
const memData = this.parseJson(results[2].stdout);
|
|
45
|
-
//
|
|
46
|
-
|
|
54
|
+
// Match cards to GPUs by PCI bus — rocm-smi card numbering is unrelated
|
|
55
|
+
// to the static list order
|
|
56
|
+
const cardBuses = await this.getCardBuses();
|
|
57
|
+
const knownBuses = new Set(gpus.map((g) => g.pciBusId));
|
|
47
58
|
const usages = [];
|
|
48
|
-
for (const [cardKey,
|
|
49
|
-
|
|
59
|
+
for (const [cardKey, pciBusId] of cardBuses) {
|
|
60
|
+
if (!knownBuses.has(pciBusId))
|
|
61
|
+
continue; // card outside the dashboard (iGPU, ...)
|
|
62
|
+
usages.push(this.extractUsage(cardKey, pciBusId, tempData, usageData, memData));
|
|
50
63
|
}
|
|
51
64
|
return usages;
|
|
52
65
|
}
|
|
@@ -58,19 +71,25 @@ let AmdLinuxUsageProbe = class AmdLinuxUsageProbe {
|
|
|
58
71
|
return null;
|
|
59
72
|
}
|
|
60
73
|
}
|
|
61
|
-
/**
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
buildKeyMap(gpus) {
|
|
74
|
+
/** "cardN" → "BB:DD.F" (detector format), from `--showbus`. Cached — static info. */
|
|
75
|
+
async getCardBuses() {
|
|
76
|
+
if (this.cardBusesCache !== null && this.cardBusesCache.size > 0)
|
|
77
|
+
return this.cardBusesCache;
|
|
66
78
|
const map = new Map();
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
79
|
+
const result = await ExecTools_1.ExecTools.safeExec("rocm-smi --showbus --json", { timeout: 10000 });
|
|
80
|
+
const data = this.parseJson(result.stdout);
|
|
81
|
+
if (data) {
|
|
82
|
+
for (const [cardKey, card] of Object.entries(data)) {
|
|
83
|
+
const pci = card?.["PCI Bus"];
|
|
84
|
+
if (typeof pci !== "string" || !pci.trim())
|
|
85
|
+
continue;
|
|
86
|
+
// "0000:83:00.0" → "83:00.0" to match detector / lspci format
|
|
87
|
+
map.set(cardKey, pci.trim().toUpperCase().replace(/^0+:/, ""));
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
// Don't cache a failed/empty lookup — retry on the next poll
|
|
91
|
+
if (map.size > 0) {
|
|
92
|
+
this.cardBusesCache = map;
|
|
74
93
|
}
|
|
75
94
|
return map;
|
|
76
95
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"amdLinuxUsageProbe.js","sourceRoot":"","sources":["../../../src/services/probes/amdLinuxUsageProbe.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,yCAAuC;AAEvC,uDAAoD;AAGpD
|
|
1
|
+
{"version":3,"file":"amdLinuxUsageProbe.js","sourceRoot":"","sources":["../../../src/services/probes/amdLinuxUsageProbe.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
19
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
20
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
21
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
22
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
23
|
+
};
|
|
24
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
25
|
+
var ownKeys = function(o) {
|
|
26
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
27
|
+
var ar = [];
|
|
28
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
29
|
+
return ar;
|
|
30
|
+
};
|
|
31
|
+
return ownKeys(o);
|
|
32
|
+
};
|
|
33
|
+
return function (mod) {
|
|
34
|
+
if (mod && mod.__esModule) return mod;
|
|
35
|
+
var result = {};
|
|
36
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
37
|
+
__setModuleDefault(result, mod);
|
|
38
|
+
return result;
|
|
39
|
+
};
|
|
40
|
+
})();
|
|
41
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
+
exports.SysfsRenderIndexResolver = void 0;
|
|
43
|
+
const fs = __importStar(require("fs"));
|
|
44
|
+
const inversify_1 = require("inversify");
|
|
45
|
+
const ExecTools_1 = require("../../helpers/ExecTools");
|
|
46
|
+
/**
|
|
47
|
+
* Lists DRM cards that own a render node, with their PCI address:
|
|
48
|
+
*
|
|
49
|
+
* card1 0000:c3:00.0
|
|
50
|
+
* card2 0000:c6:00.0
|
|
51
|
+
*
|
|
52
|
+
* Vendor-agnostic: works for any GPU with a DRM render node (AMD, NVIDIA, ...).
|
|
53
|
+
* - Connector entries (card1-DP-1) resolve to the drm card dir, not a PCI
|
|
54
|
+
* device, so they fail the render-node check below.
|
|
55
|
+
* - BMC/iGPU cards without a render node (e.g. ASPEED VGA) are skipped.
|
|
56
|
+
* - Card numbers are assigned by the kernel in device probe order — the same
|
|
57
|
+
* order KFD registers its agents — so card order == HIP order.
|
|
58
|
+
*
|
|
59
|
+
* Linux only.
|
|
60
|
+
*/
|
|
61
|
+
const LIST_RENDER_CARDS = `
|
|
62
|
+
for c in /sys/class/drm/card[0-9]*; do
|
|
63
|
+
d=$(readlink -f "$c/device" 2>/dev/null) || continue
|
|
64
|
+
ls "$d"/drm/renderD* >/dev/null 2>&1 || continue
|
|
65
|
+
printf '%s %s\\n' "$(basename "$c")" "$(basename "$d")"
|
|
66
|
+
done
|
|
67
|
+
`;
|
|
68
|
+
let SysfsRenderIndexResolver = class SysfsRenderIndexResolver {
|
|
69
|
+
async isAvailable() {
|
|
70
|
+
return process.platform === "linux" && fs.existsSync("/sys/class/drm");
|
|
71
|
+
}
|
|
72
|
+
async resolve(gpus) {
|
|
73
|
+
if (gpus.length === 0)
|
|
74
|
+
return 0;
|
|
75
|
+
const result = await ExecTools_1.ExecTools.safeExec(LIST_RENDER_CARDS, { timeout: 5000 });
|
|
76
|
+
if (!result.stdout.trim())
|
|
77
|
+
return 0;
|
|
78
|
+
const byPci = new Map();
|
|
79
|
+
for (const gpu of gpus) {
|
|
80
|
+
if (gpu.pciBusId)
|
|
81
|
+
byPci.set(normalizePci(gpu.pciBusId), gpu);
|
|
82
|
+
}
|
|
83
|
+
let index = 0;
|
|
84
|
+
for (const { pci } of this.parseLines(result.stdout)) {
|
|
85
|
+
const gpu = byPci.get(normalizePci(pci));
|
|
86
|
+
if (!gpu)
|
|
87
|
+
continue; // render card not in the detected list (iGPU, etc.)
|
|
88
|
+
gpu.gpuIndex = index++;
|
|
89
|
+
}
|
|
90
|
+
return index;
|
|
91
|
+
}
|
|
92
|
+
/** "cardN <pci>" lines, sorted by numeric card number (probe order). */
|
|
93
|
+
parseLines(raw) {
|
|
94
|
+
const cards = [];
|
|
95
|
+
for (const line of raw.trim().split("\n")) {
|
|
96
|
+
const [name, pci] = line.split(/\s+/);
|
|
97
|
+
const card = parseInt((name ?? "").replace("card", ""), 10);
|
|
98
|
+
if (name === undefined || pci === undefined || Number.isNaN(card))
|
|
99
|
+
continue;
|
|
100
|
+
cards.push({ card, pci });
|
|
101
|
+
}
|
|
102
|
+
return cards.sort((a, b) => a.card - b.card);
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
exports.SysfsRenderIndexResolver = SysfsRenderIndexResolver;
|
|
106
|
+
exports.SysfsRenderIndexResolver = SysfsRenderIndexResolver = __decorate([
|
|
107
|
+
(0, inversify_1.injectable)()
|
|
108
|
+
], SysfsRenderIndexResolver);
|
|
109
|
+
/** "0000:c3:00.0" → "C3:00.0" — strip domain prefix, uppercase (detector format). */
|
|
110
|
+
function normalizePci(raw) {
|
|
111
|
+
return raw.trim().toUpperCase().replace(/^0+:/, "");
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=sysfsRenderIndexResolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sysfsRenderIndexResolver.js","sourceRoot":"","sources":["../../../src/services/resolvers/sysfsRenderIndexResolver.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,uCAAyB;AACzB,yCAAuC;AAEvC,uDAAoD;AAGpD;;;;;;;;;;;;;;GAcG;AACH,MAAM,iBAAiB,GAAG;;;;;;CAMzB,CAAC;AAGK,IAAM,wBAAwB,GAA9B,MAAM,wBAAwB;IACnC,KAAK,CAAC,WAAW;QACf,OAAO,OAAO,CAAC,QAAQ,KAAK,OAAO,IAAI,EAAE,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC;IACzE,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,IAAe;QAC3B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,CAAC,CAAC;QAEhC,MAAM,MAAM,GAAG,MAAM,qBAAS,CAAC,QAAQ,CAAC,iBAAiB,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9E,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE;YAAE,OAAO,CAAC,CAAC;QAEpC,MAAM,KAAK,GAAG,IAAI,GAAG,EAAmB,CAAC;QACzC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,IAAI,GAAG,CAAC,QAAQ;gBAAE,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,GAAG,CAAC,CAAC;QAC/D,CAAC;QAED,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,KAAK,MAAM,EAAE,GAAG,EAAE,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;YACrD,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC;YACzC,IAAI,CAAC,GAAG;gBAAE,SAAS,CAAC,oDAAoD;YACxE,GAAG,CAAC,QAAQ,GAAG,KAAK,EAAE,CAAC;QACzB,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAED,wEAAwE;IAChE,UAAU,CAAC,GAAW;QAC5B,MAAM,KAAK,GAAoC,EAAE,CAAC;QAElD,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1C,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACtC,MAAM,IAAI,GAAG,QAAQ,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;YAC5D,IAAI,IAAI,KAAK,SAAS,IAAI,GAAG,KAAK,SAAS,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC;gBAAE,SAAS;YAC5E,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;QAC5B,CAAC;QAED,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;IAC/C,CAAC;CACF,CAAA;AAvCY,4DAAwB;mCAAxB,wBAAwB;IADpC,IAAA,sBAAU,GAAE;GACA,wBAAwB,CAuCpC;AAED,qFAAqF;AACrF,SAAS,YAAY,CAAC,GAAW;IAC/B,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AACtD,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
-
};
|
|
8
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.PciBusOrderIndexResolver = void 0;
|
|
10
|
-
const inversify_1 = require("inversify");
|
|
11
|
-
/**
|
|
12
|
-
* Assigns gpuIndex by PCIe address (BDF) order: GPUs are sorted by the
|
|
13
|
-
* numeric value of their PCI address (bus, then device, then function) and
|
|
14
|
-
* each gets its position in that order — 0, 1, 2, ...
|
|
15
|
-
*
|
|
16
|
-
* This is the sequential number visible in `lspci` / `rocm-smi --showbus` —
|
|
17
|
-
* deliberately NOT the kernel probe order (HIP/KFD agent order), which can
|
|
18
|
-
* differ from BDF order (e.g. buses 83/86/C3/C6 probe as C3/C6/83/86).
|
|
19
|
-
*
|
|
20
|
-
* Platform-agnostic: every detector reports pciBusId as "BB:DD.F" (an
|
|
21
|
-
* optional "DDDD:" domain prefix is accepted too). GPUs without a
|
|
22
|
-
* parseable address are appended after the sorted ones, preserving detector
|
|
23
|
-
* list order, so every GPU still gets a unique index.
|
|
24
|
-
*/
|
|
25
|
-
let PciBusOrderIndexResolver = class PciBusOrderIndexResolver {
|
|
26
|
-
async isAvailable() {
|
|
27
|
-
return true;
|
|
28
|
-
}
|
|
29
|
-
async resolve(gpus) {
|
|
30
|
-
if (gpus.length === 0)
|
|
31
|
-
return 0;
|
|
32
|
-
const withBus = [];
|
|
33
|
-
const withoutBus = [];
|
|
34
|
-
for (const gpu of gpus) {
|
|
35
|
-
const value = parsePciBusId(gpu.pciBusId);
|
|
36
|
-
if (value === null) {
|
|
37
|
-
withoutBus.push(gpu);
|
|
38
|
-
}
|
|
39
|
-
else {
|
|
40
|
-
withBus.push({ gpu, value });
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
withBus.sort((a, b) => a.value - b.value);
|
|
44
|
-
let index = 0;
|
|
45
|
-
for (const { gpu } of withBus) {
|
|
46
|
-
gpu.gpuIndex = index++;
|
|
47
|
-
}
|
|
48
|
-
for (const gpu of withoutBus) {
|
|
49
|
-
gpu.gpuIndex = index++;
|
|
50
|
-
}
|
|
51
|
-
return gpus.length;
|
|
52
|
-
}
|
|
53
|
-
};
|
|
54
|
-
exports.PciBusOrderIndexResolver = PciBusOrderIndexResolver;
|
|
55
|
-
exports.PciBusOrderIndexResolver = PciBusOrderIndexResolver = __decorate([
|
|
56
|
-
(0, inversify_1.injectable)()
|
|
57
|
-
], PciBusOrderIndexResolver);
|
|
58
|
-
/**
|
|
59
|
-
* "BB:DD.F" (optionally "DDDD:BB:DD.F") → numeric BDF value, or null when
|
|
60
|
-
* the string is not a PCI address. Case-insensitive.
|
|
61
|
-
*/
|
|
62
|
-
function parsePciBusId(raw) {
|
|
63
|
-
if (!raw)
|
|
64
|
-
return null;
|
|
65
|
-
const match = raw
|
|
66
|
-
.trim()
|
|
67
|
-
.toUpperCase()
|
|
68
|
-
.match(/^(?:([0-9A-F]{1,4}):)?([0-9A-F]{1,2}):([0-9A-F]{1,2})\.([0-7])$/);
|
|
69
|
-
if (!match)
|
|
70
|
-
return null;
|
|
71
|
-
const domain = match[1] ? parseInt(match[1], 16) : 0;
|
|
72
|
-
const bus = parseInt(match[2], 16);
|
|
73
|
-
const device = parseInt(match[3], 16);
|
|
74
|
-
const func = parseInt(match[4], 16);
|
|
75
|
-
return (domain << 16) | (bus << 8) | (device << 3) | func;
|
|
76
|
-
}
|
|
77
|
-
//# sourceMappingURL=pciBusOrderIndexResolver.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"pciBusOrderIndexResolver.js","sourceRoot":"","sources":["../../../src/services/resolvers/pciBusOrderIndexResolver.ts"],"names":[],"mappings":";;;;;;;;;AAAA,yCAAuC;AAIvC;;;;;;;;;;;;;GAaG;AAEI,IAAM,wBAAwB,GAA9B,MAAM,wBAAwB;IACnC,KAAK,CAAC,WAAW;QACf,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,IAAe;QAC3B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,CAAC,CAAC;QAEhC,MAAM,OAAO,GAAsC,EAAE,CAAC;QACtD,MAAM,UAAU,GAAc,EAAE,CAAC;QAEjC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,MAAM,KAAK,GAAG,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YAC1C,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;gBACnB,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACvB,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC;YAC/B,CAAC;QACH,CAAC;QAED,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;QAE1C,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,KAAK,MAAM,EAAE,GAAG,EAAE,IAAI,OAAO,EAAE,CAAC;YAC9B,GAAG,CAAC,QAAQ,GAAG,KAAK,EAAE,CAAC;QACzB,CAAC;QACD,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;YAC7B,GAAG,CAAC,QAAQ,GAAG,KAAK,EAAE,CAAC;QACzB,CAAC;QAED,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;CACF,CAAA;AAhCY,4DAAwB;mCAAxB,wBAAwB;IADpC,IAAA,sBAAU,GAAE;GACA,wBAAwB,CAgCpC;AAED;;;GAGG;AACH,SAAS,aAAa,CAAC,GAAW;IAChC,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IAEtB,MAAM,KAAK,GAAG,GAAG;SACd,IAAI,EAAE;SACN,WAAW,EAAE;SACb,KAAK,CAAC,iEAAiE,CAAC,CAAC;IAC5E,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IAExB,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACrD,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACnC,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACtC,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAEpC,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC;AAC5D,CAAC"}
|