From 141f548d91b86fb8732b4352adedd39f344b0a1d Mon Sep 17 00:00:00 2001 From: lone-cloud Date: Fri, 5 Sep 2025 12:01:05 -0700 Subject: [PATCH] fix ROCm on Windows --- package.json | 2 +- src/hooks/useWarnings.ts | 13 +++- src/main/managers/HardwareManager.ts | 92 +++++++++++++++++++--------- 3 files changed, 75 insertions(+), 32 deletions(-) diff --git a/package.json b/package.json index 338fcf0..0fec7f5 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "gerbil", "productName": "Gerbil", - "version": "1.0.0", + "version": "1.0.1", "description": "Run Large Language Models locally", "main": "out/main/index.js", "homepage": "./", diff --git a/src/hooks/useWarnings.ts b/src/hooks/useWarnings.ts index 444c5c5..c0a0155 100644 --- a/src/hooks/useWarnings.ts +++ b/src/hooks/useWarnings.ts @@ -86,10 +86,19 @@ const checkGpuWarnings = async ( !gpuCapabilities.rocm.supported && gpuInfo.hasAMD ) { + const platform = await window.electronAPI.kobold.getPlatform(); + const baseMessage = + 'Your binary supports ROCm and you have an AMD GPU, but ROCm runtime is not detected on your system.'; + + let message = baseMessage; + if (platform === 'win32') { + message += + ' On Windows, make sure ROCm is installed and its bin directory is added to your PATH so that hipInfo.exe can be found.'; + } + warnings.push({ type: 'warning', - message: - 'Your binary supports ROCm and you have an AMD GPU, but ROCm runtime is not detected on your system.', + message, }); } diff --git a/src/main/managers/HardwareManager.ts b/src/main/managers/HardwareManager.ts index e9d695f..0314671 100644 --- a/src/main/managers/HardwareManager.ts +++ b/src/main/managers/HardwareManager.ts @@ -195,12 +195,28 @@ export class HardwareManager { } } + private async findRocminfoCommand(): Promise { + const platform = await import('process').then((p) => p.platform); + + if (platform === 'win32') { + return 'hipInfo'; + } else { + return 'rocminfo'; + } + } + async detectROCm(): Promise<{ supported: boolean; devices: string[]; }> { try { - const rocminfo = spawn('rocminfo', [], { timeout: 5000 }); + const rocminfoCommand = await this.findRocminfoCommand(); + if (!rocminfoCommand) { + return { supported: false, devices: [] }; + } + + const isWindows = rocminfoCommand.includes('hipInfo'); + const rocminfo = spawn(rocminfoCommand, [], { timeout: 5000 }); let output = ''; rocminfo.stdout.on('data', (data) => { @@ -212,41 +228,59 @@ export class HardwareManager { rocminfo.on('close', (code) => { if (code === 0 && output.trim()) { const devices: string[] = []; - const lines = output.split('\n'); - for (let i = 0; i < lines.length; i++) { - const line = lines[i]; + if (isWindows) { + const lines = output.split('\n'); - if (line.includes('Marketing Name:')) { - const name = line.split('Marketing Name:')[1]?.trim(); - if (name) { - let deviceType = ''; - - const searchRangeLines = 20; - const searchStartIndex = Math.max(0, i - searchRangeLines); - const searchEndIndex = Math.min( - lines.length, - i + searchRangeLines - ); - - for ( - let searchIndex = searchStartIndex; - searchIndex < searchEndIndex; - searchIndex++ + for (const line of lines) { + const trimmedLine = line.trim(); + if (trimmedLine.startsWith('Name:')) { + const name = trimmedLine.split('Name:')[1]?.trim(); + if ( + name && + !name.toLowerCase().includes('cpu') && + !devices.includes(shortenDeviceName(name)) ) { - if (lines[searchIndex].includes('Device Type:')) { - deviceType = - lines[searchIndex].split('Device Type:')[1]?.trim() || - ''; - break; - } - } - - if (deviceType !== 'CPU') { devices.push(shortenDeviceName(name)); } } } + } else { + const lines = output.split('\n'); + for (let i = 0; i < lines.length; i++) { + const line = lines[i]; + + if (line.includes('Marketing Name:')) { + const name = line.split('Marketing Name:')[1]?.trim(); + if (name) { + let deviceType = ''; + + const searchRangeLines = 20; + const searchStartIndex = Math.max(0, i - searchRangeLines); + const searchEndIndex = Math.min( + lines.length, + i + searchRangeLines + ); + + for ( + let searchIndex = searchStartIndex; + searchIndex < searchEndIndex; + searchIndex++ + ) { + if (lines[searchIndex].includes('Device Type:')) { + deviceType = + lines[searchIndex].split('Device Type:')[1]?.trim() || + ''; + break; + } + } + + if (deviceType !== 'CPU') { + devices.push(shortenDeviceName(name)); + } + } + } + } } resolve({