fix: should not select vulkan by default when there are Nvidia GPUs detected (#4720)

This commit is contained in:
Louis 2025-02-24 18:51:22 +07:00 committed by GitHub
parent 2d7dd8e8ce
commit 60257635ad
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 203 additions and 5 deletions

View File

@ -58,3 +58,126 @@ describe('migrate engine settings', () => {
expect(mockUpdateEngines).not.toBeCalled()
})
})
describe('getEngines', () => {
let extension: JanEngineManagementExtension
beforeEach(() => {
// @ts-ignore
extension = new JanEngineManagementExtension()
})
it('should return a list of engines', async () => {
const mockKyGet = vi.spyOn(extension, 'getEngines')
mockKyGet.mockResolvedValue(mockEngines)
const engines = await extension.getEngines()
expect(engines).toEqual(mockEngines)
})
})
describe('updateDefaultEngine', () => {
let extension: JanEngineManagementExtension
beforeEach(() => {
// @ts-ignore
extension = new JanEngineManagementExtension()
})
it('should set default engine variant if not installed', async () => {
vi.stubGlobal('PLATFORM', 'win32')
vi.stubGlobal('CORTEX_ENGINE_VERSION', '1.0.0')
const mockGetDefaultEngineVariant = vi.spyOn(
extension,
'getDefaultEngineVariant'
)
mockGetDefaultEngineVariant.mockResolvedValue({
variant: 'variant1',
version: '1.0.0',
})
const mockGetInstalledEngines = vi.spyOn(extension, 'getInstalledEngines')
mockGetInstalledEngines.mockResolvedValue([])
const mockSetDefaultEngineVariant = vi.spyOn(
extension,
'setDefaultEngineVariant'
)
mockSetDefaultEngineVariant.mockResolvedValue({ messages: 'OK' })
vi.mock('@janhq/core', async (importOriginal) => {
const actual = (await importOriginal()) as any
return {
...actual,
systemInformation: vi.fn().mockResolvedValue({ gpuSetting: 'high' }),
}
})
vi.mock('./utils', async (importOriginal) => {
const actual = (await importOriginal()) as any
return {
...actual,
engineVariant: vi.fn().mockResolvedValue('windows-amd64-noavx'),
}
})
await extension.updateDefaultEngine()
expect(mockSetDefaultEngineVariant).toHaveBeenCalledWith('llama-cpp', {
variant: 'windows-amd64-noavx',
version: '1.0.0',
})
})
it('should not reset default engine variant if not installed', async () => {
vi.stubGlobal('PLATFORM', 'win32')
vi.stubGlobal('CORTEX_ENGINE_VERSION', '1.0.0')
const mockGetDefaultEngineVariant = vi.spyOn(
extension,
'getDefaultEngineVariant'
)
mockGetDefaultEngineVariant.mockResolvedValue({
variant: 'windows-amd64-noavx',
version: '1.0.0',
})
const mockGetInstalledEngines = vi.spyOn(extension, 'getInstalledEngines')
mockGetInstalledEngines.mockResolvedValue([
{
name: 'windows-amd64-noavx',
version: '1.0.0',
type: 'local',
engine: InferenceEngine.cortex_llamacpp,
},
])
const mockSetDefaultEngineVariant = vi.spyOn(
extension,
'setDefaultEngineVariant'
)
mockSetDefaultEngineVariant.mockResolvedValue({ messages: 'OK' })
vi.mock('@janhq/core', async (importOriginal) => {
const actual = (await importOriginal()) as any
return {
...actual,
systemInformation: vi.fn().mockResolvedValue({ gpuSetting: 'high' }),
}
})
vi.mock('./utils', async (importOriginal) => {
const actual = (await importOriginal()) as any
return {
...actual,
engineVariant: vi.fn().mockResolvedValue('windows-amd64-noavx'),
}
})
await extension.updateDefaultEngine()
expect(mockSetDefaultEngineVariant).not.toBeCalled()
})
})

View File

@ -0,0 +1,72 @@
import { describe, it, expect, vi } from 'vitest'
import { engineVariant } from './utils'
vi.mock('@janhq/core', () => {
return {
log: () => {},
}
})
describe('engineVariant', () => {
it('should return mac-arm64 when platform is darwin and arch is arm64', async () => {
vi.stubGlobal('PLATFORM', 'darwin')
const result = await engineVariant({
cpu: { arch: 'arm64', instructions: '' },
gpus: [],
vulkan: false,
})
expect(result).toBe('mac-arm64')
})
it('should return mac-amd64 when platform is darwin and arch is not arm64', async () => {
vi.stubGlobal('PLATFORM', 'darwin')
const result = await engineVariant({
cpu: { arch: 'x64', instructions: '' },
gpus: [],
vulkan: false,
})
expect(result).toBe('mac-amd64')
})
it('should return windows-amd64-noavx-cuda-12-0 when platform is win32, cuda is enabled, and cuda version is 12', async () => {
vi.stubGlobal('PLATFORM', 'win32')
const result = await engineVariant({
cpu: { arch: 'x64', instructions: 'avx2' },
gpus: [
{
activated: true,
version: '12',
additional_information: { driver_version: '1.0' },
},
],
vulkan: false,
})
expect(result).toBe('windows-amd64-avx2-cuda-12-0')
})
it('should return linux-amd64-noavx-cuda-11-7 when platform is linux, cuda is enabled, and cuda version is 11', async () => {
vi.stubGlobal('PLATFORM', 'linux')
const result = await engineVariant({
cpu: { arch: 'x64', instructions: 'avx2' },
gpus: [
{
activated: true,
version: '11',
additional_information: { driver_version: '1.0' },
},
],
vulkan: false,
})
expect(result).toBe('linux-amd64-avx2-cuda-11-7')
})
it('should return windows-amd64-vulkan when platform is win32 and vulkan is enabled', async () => {
vi.stubGlobal('PLATFORM', 'win32')
const result = await engineVariant({
cpu: { arch: 'x64', instructions: '' },
gpus: [{ activated: true, version: '12' }],
vulkan: true,
})
expect(result).toBe('windows-amd64-vulkan')
})
})

View File

@ -65,10 +65,12 @@ export const engineVariant = async (
// There is no need to append the variant extension for mac
if (platform.startsWith('mac')) return platform
// Only Nvidia GPUs have addition_information set and activated by default
let engineVariant =
gpuSetting?.vulkan || gpuSetting.gpus.some((e) => !e.additional_information)
? [platform, 'vulkan']
: [
!gpuSetting?.vulkan ||
!gpuSetting.gpus?.length ||
gpuSetting.gpus.some((e) => e.additional_information && e.activated)
? [
platform,
gpuRunMode(gpuSetting) === 'cuda' &&
(gpuSetting.cpu.instructions.includes('avx2') ||
@ -78,6 +80,7 @@ export const engineVariant = async (
gpuRunMode(gpuSetting),
cudaVersion(gpuSetting),
].filter(Boolean) // Remove any falsy values
: [platform, 'vulkan']
let engineVariantString = engineVariant.join('-')

View File

@ -112,7 +112,7 @@ export const scanModelsFolder = async (): Promise<
}
return undefined
})
.filter((e) => !!e)
.filter(Boolean)
return modelData
} catch (err) {

View File

@ -226,7 +226,7 @@ export const MarkdownTextMessage = memo(
renderKatex ? [rehypeKatex, { throwOnError: false }] : undefined,
[rehypeHighlightCodeLines, { showLineNumbers: true }],
wrapCodeBlocksWithoutVisit,
].filter((e) => !!e) as PluggableList
].filter(Boolean) as PluggableList
}
components={markdownComponents}
>