Skip to content

Commit

Permalink
fix: gpu settings and enable Vulkan support
Browse files Browse the repository at this point in the history
  • Loading branch information
louis-jan committed Feb 21, 2024
1 parent 4c4abad commit 452e127
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 54 deletions.
Binary file not shown.
114 changes: 76 additions & 38 deletions extensions/inference-nitro-extension/src/node/accelerator.ts
Original file line number Diff line number Diff line change
@@ -1,7 1,7 @@
import { writeFileSync, existsSync, readFileSync } from 'fs'
import { exec } from 'child_process'
import { exec, spawn } from 'child_process'
import path from 'path'
import { getJanDataFolderPath } from '@janhq/core/node'
import { getJanDataFolderPath, log } from '@janhq/core/node'

/**
* Default GPU settings
Expand Down Expand Up @@ -164,42 164,80 @@ export function updateCudaExistence(
* Get GPU information
*/
export async function updateGpuInfo(): Promise<void> {
exec(
'nvidia-smi --query-gpu=index,memory.total,name --format=csv,noheader,nounits',
(error, stdout) => {
let data = JSON.parse(readFileSync(GPU_INFO_FILE, 'utf-8'))

if (!error) {
// Get GPU info and gpu has higher memory first
let highestVram = 0
let highestVramId = '0'
let gpus = stdout
.trim()
.split('\n')
.map((line) => {
let [id, vram, name] = line.split(', ')
vram = vram.replace(/\r/g, '')
if (parseFloat(vram) > highestVram) {
highestVram = parseFloat(vram)
highestVramId = id
}
return { id, vram, name }
})

data.gpus = gpus
data.gpu_highest_vram = highestVramId
} else {
data.gpus = []
data.gpu_highest_vram = ''
let data = JSON.parse(readFileSync(GPU_INFO_FILE, 'utf-8'))

// Cuda
if (data['vulkan'] === true) {
// Vulkan
exec(
process.platform === 'win32'
? `${__dirname}\\..\\bin\\vulkaninfoSDK.exe --summary`
: '',
(error, stdout) => {
if (!error) {
const output = stdout.toString()
log(output)

const gpuRegex = /GPU(\d ):(?:[\s\S]*?)deviceName\s*=\s*(.*)/g

let gpus = []
let match
while ((match = gpuRegex.exec(output)) !== null) {
const id = match[1]
const name = match[2]
console.log(`GPU${id}: ${name}`)
gpus.push({ id, vram: 0, name })
}
console.log('done', gpus)

data.gpus = gpus

if (!data['gpus_in_use'] || data['gpus_in_use'].length === 0) {
data.gpus_in_use = [data.gpus.length > 1 ? '1' : '0']
}

data = updateCudaExistence(data)
writeFileSync(GPU_INFO_FILE, JSON.stringify(data, null, 2))
}
Promise.resolve()
}

if (!data['gpus_in_use'] || data['gpus_in_use'].length === 0) {
data.gpus_in_use = [data['gpu_highest_vram']]
)
} else {
exec(
'nvidia-smi --query-gpu=index,memory.total,name --format=csv,noheader,nounits',
(error, stdout) => {
if (!error) {
// Get GPU info and gpu has higher memory first
let highestVram = 0
let highestVramId = '0'
let gpus = stdout
.trim()
.split('\n')
.map((line) => {
let [id, vram, name] = line.split(', ')
vram = vram.replace(/\r/g, '')
if (parseFloat(vram) > highestVram) {
highestVram = parseFloat(vram)
highestVramId = id
}
return { id, vram, name }
})

data.gpus = gpus
data.gpu_highest_vram = highestVramId
} else {
data.gpus = []
data.gpu_highest_vram = ''
}

if (!data['gpus_in_use'] || data['gpus_in_use'].length === 0) {
data.gpus_in_use = [data['gpu_highest_vram']]
}

data = updateCudaExistence(data)
writeFileSync(GPU_INFO_FILE, JSON.stringify(data, null, 2))
Promise.resolve()
}

data = updateCudaExistence(data)
writeFileSync(GPU_INFO_FILE, JSON.stringify(data, null, 2))
Promise.resolve()
}
)
)
}
}
2 changes: 1 addition & 1 deletion extensions/monitoring-extension/src/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 40,7 @@ const getCurrentLoad = () =>
if (gpuIds !== '' && data['vulkan'] !== true) {
exec(
`nvidia-smi --query-gpu=index,name,temperature.gpu,utilization.gpu,memory.total,memory.free,utilization.memory --format=csv,noheader,nounits --id=${gpuIds}`,
(error, stdout, stderr) => {
(error, stdout, _) => {
if (error) {
console.error(`exec error: ${error}`)
reject(error)
Expand Down
11 changes: 10 additions & 1 deletion web/hooks/useSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 60,17 @@ export const useSettings = () => {
if (runMode != null) settings.run_mode = runMode
if (notify != null) settings.notify = notify
if (gpusInUse != null) settings.gpus_in_use = gpusInUse
if (vulkan != null) settings.vulkan = vulkan
if (vulkan != null) {
settings.vulkan = vulkan
// GPU enabled, set run_mode to 'gpu'
settings.run_mode = vulkan ? 'gpu' : 'cpu'
}
await fs.writeFileSync(settingsFile, JSON.stringify(settings))

// Relaunch to apply settings
if (vulkan != null) {
window.location.reload()
}
}

return {
Expand Down
5 changes: 1 addition & 4 deletions web/screens/Settings/Advanced/DataFolder/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 83,7 @@ const DataFolder = () => {
await window.core?.api?.getAppConfigurations()
const currentJanDataFolder = appConfiguration.data_folder
appConfiguration.data_folder = destinationPath
const { _, err } = await fs.syncFile(
currentJanDataFolder,
destinationPath
)
const { err } = await fs.syncFile(currentJanDataFolder, destinationPath)
if (err) throw err
await window.core?.api?.updateAppConfiguration(appConfiguration)
console.debug(
Expand Down
28 changes: 18 additions & 10 deletions web/screens/Settings/Advanced/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 99,7 @@ const Advanced = () => {
}
}
setUseGpuIfPossible()
}, [readSettings])
}, [readSettings, setGpuList, setGpuEnabled, setGpusInUse, setVulkanEnabled])

const clearLogs = async () => {
if (await fs.existsSync(`file://logs`)) {
Expand Down Expand Up @@ -172,11 172,11 @@ const Advanced = () => {
<div className="space-y-1.5">
<div className="flex gap-x-2">
<h6 className="text-sm font-semibold capitalize">
NVIDIA GPU Acceleration
GPU Acceleration
</h6>
</div>
<p className="pr-8 leading-relaxed">
Enable to enhance model performance by utilizing your NVIDIA GPU
Enable to enhance model performance by utilizing your GPU
devices for acceleration. Read{' '}
<span>
{' '}
Expand Down Expand Up @@ -217,7 217,7 @@ const Advanced = () => {
<Tooltip>
<TooltipTrigger>
<Switch
disabled={gpuList.length === 0}
disabled={gpuList.length === 0 || vulkanEnabled}
checked={gpuEnabled}
onCheckedChange={(e) => {
if (e === true) {
Expand Down Expand Up @@ -279,12 279,16 @@ const Advanced = () => {
<SelectPortal>
<SelectContent className="w-[400px] px-1 pb-2">
<SelectGroup>
<SelectLabel>Nvidia</SelectLabel>
<SelectLabel>
{vulkanEnabled ? 'Vulkan Supported GPUs' : 'Nvidia'}
</SelectLabel>
<div className="px-4 pb-2">
<div className="rounded-lg bg-secondary p-3">
{gpuList
.filter((gpu) =>
gpu.name?.toLowerCase().includes('nvidia')
vulkanEnabled
? gpu.name
: gpu.name?.toLowerCase().includes('nvidia')
)
.map((gpu) => (
<div
Expand All @@ -304,7 308,9 @@ const Advanced = () => {
htmlFor={`gpu-${gpu.id}`}
>
<span>{gpu.name}</span>
<span>{gpu.vram}MB VRAM</span>
{!vulkanEnabled && (
<span>{gpu.vram}MB VRAM</span>
)}
</label>
</div>
))}
Expand Down Expand Up @@ -335,15 341,17 @@ const Advanced = () => {

{/* Vulkan for AMD GPU/ APU and Intel Arc GPU */}
{/* TODO: This needs to be set based on user toggle in settings for enabled BOOLEAN and index as INT */}
{!isMac && (
{!isMac && experimentalFeature && (
<div className="flex w-full items-start justify-between border-b border-border py-4 first:pt-0 last:border-none">
<div className="flex-shrink-0 space-y-1.5">
<div className="flex gap-x-2">
<h6 className="text-sm font-semibold capitalize">Vulkan GPU</h6>
<h6 className="text-sm font-semibold capitalize">
Vulkan Support
</h6>
</div>
<p className="text-xs leading-relaxed">
Enable Vulkan with AMD GPU/APU and Intel Arc GPU for better model
performance.
performance (relaunch needed).
</p>
</div>

Expand Down

0 comments on commit 452e127

Please sign in to comment.