Skip to content

Commit 9c0fe06

Browse files
committed
Use Win32 API for GPU detection, replace driver with runtime version
1 parent 51f4688 commit 9c0fe06

File tree

3 files changed

+72
-31
lines changed

3 files changed

+72
-31
lines changed

src/ai/ort_install.c

Lines changed: 66 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@
3030
#include <curl/curl.h>
3131
#include <gio/gio.h>
3232
#include <string.h>
33+
#ifdef _WIN32
34+
#include <windows.h>
35+
#endif
3336

3437
// forward declarations
3538
static gchar *_get_rocm_version(void);
@@ -380,42 +383,59 @@ static gchar *_get_rocm_version(void)
380383
// GPU detection
381384
// ---------------------------------------------------------------------------
382385

386+
// Get CUDA toolkit version (major.minor) from nvcc, e.g. "13.2".
387+
// Returns NULL if nvcc is not available.
388+
static gchar *_get_cuda_version(void)
389+
{
390+
gchar *nvcc_out = NULL;
391+
if(!g_spawn_command_line_sync("nvcc --version", &nvcc_out, NULL, NULL, NULL)
392+
|| !nvcc_out)
393+
return NULL;
394+
gchar *v = g_strstr_len(nvcc_out, -1, ", V");
395+
gchar *result = NULL;
396+
if(v)
397+
result = _version_major_minor(v + 3); // skip ", V"
398+
g_free(nvcc_out);
399+
return result;
400+
}
401+
383402
static dt_ort_gpu_info_t *_detect_nvidia(void)
384403
{
385-
gchar *output = NULL;
404+
gchar *gpu_label = NULL;
405+
386406
#ifdef _WIN32
387-
const gchar *argv[] = { "nvidia-smi.exe",
388-
"--query-gpu=name,driver_version",
389-
"--format=csv,noheader", NULL };
390-
if(!_run_argv(argv, &output))
407+
// enumerate display adapters via Win32 API — no subprocess overhead
408+
DISPLAY_DEVICEA dev = { .cb = sizeof(dev) };
409+
for(DWORD i = 0; EnumDisplayDevicesA(NULL, i, &dev, 0); i++)
391410
{
392-
// fallback to known absolute path (System32 is always on PATH but
393-
// GUI processes occasionally lose env vars)
394-
const gchar *argv2[] = { "C:\\Windows\\System32\\nvidia-smi.exe",
395-
"--query-gpu=name,driver_version",
396-
"--format=csv,noheader", NULL };
397-
if(!_run_argv(argv2, &output))
398-
return NULL;
411+
if(strstr(dev.DeviceString, "NVIDIA"))
412+
{
413+
gpu_label = g_strdup(dev.DeviceString);
414+
break;
415+
}
399416
}
417+
if(!gpu_label) return NULL;
400418
#else
401-
const gchar *argv[] = { "nvidia-smi",
402-
"--query-gpu=name,driver_version",
419+
// Linux: use nvidia-smi to get GPU name
420+
const gchar *argv[] = { "nvidia-smi", "--query-gpu=name",
403421
"--format=csv,noheader", NULL };
404-
if(!_run_argv(argv, &output))
422+
if(!_run_argv(argv, &gpu_label) || !gpu_label || !gpu_label[0])
423+
{
424+
g_free(gpu_label);
405425
return NULL;
426+
}
406427
#endif
407428

408-
// parse "GeForce RTX 4090, 550.54.14"
409-
gchar **fields = g_strsplit(output, ",", 2);
410-
g_free(output);
411-
if(!fields[0]) { g_strfreev(fields); return NULL; }
412-
413429
dt_ort_gpu_info_t *info = g_new0(dt_ort_gpu_info_t, 1);
414430
info->vendor = DT_ORT_GPU_NVIDIA;
415-
info->label = g_strdup(g_strstrip(fields[0]));
416-
info->driver_version = fields[1] ? g_strdup(g_strstrip(fields[1])) : g_strdup("unknown");
431+
info->label = gpu_label;
417432
info->download_size_mb = 200;
418-
g_strfreev(fields);
433+
434+
gchar *cuda_ver = _get_cuda_version();
435+
info->runtime_version = cuda_ver
436+
? g_strdup_printf("CUDA %s", cuda_ver)
437+
: g_strdup("");
438+
g_free(cuda_ver);
419439

420440
// check cuDNN
421441
info->deps_met = TRUE;
@@ -496,7 +516,7 @@ static dt_ort_gpu_info_t *_detect_amd(void)
496516
dt_ort_gpu_info_t *info = g_new0(dt_ort_gpu_info_t, 1);
497517
info->vendor = DT_ORT_GPU_AMD;
498518
info->label = gpu_name ? gpu_name : g_strdup("AMD GPU");
499-
info->driver_version = g_strdup_printf("ROCm %s", rocm_ver);
519+
info->runtime_version = g_strdup_printf("ROCm %s", rocm_ver);
500520
info->download_size_mb = 300;
501521

502522
// check MIGraphX
@@ -527,7 +547,26 @@ static dt_ort_gpu_info_t *_detect_amd(void)
527547
static dt_ort_gpu_info_t *_detect_intel(void)
528548
{
529549
#ifdef _WIN32
530-
return NULL; // OpenVINO EP on Windows uses DirectML instead
550+
// enumerate display adapters via Win32 API — no subprocess overhead
551+
DISPLAY_DEVICEA dev = { .cb = sizeof(dev) };
552+
gchar *gpu_name = NULL;
553+
for(DWORD i = 0; EnumDisplayDevicesA(NULL, i, &dev, 0); i++)
554+
{
555+
if(strstr(dev.DeviceString, "Intel"))
556+
{
557+
gpu_name = g_strdup(dev.DeviceString);
558+
break;
559+
}
560+
}
561+
if(!gpu_name) return NULL;
562+
563+
dt_ort_gpu_info_t *info = g_new0(dt_ort_gpu_info_t, 1);
564+
info->vendor = DT_ORT_GPU_INTEL;
565+
info->label = gpu_name;
566+
info->runtime_version = g_strdup("");
567+
info->deps_met = TRUE; // OpenVINO runtime is downloaded with the ORT package
568+
info->download_size_mb = 100; // ORT 60MB + OpenVINO runtime 38MB
569+
return info;
531570
#elif defined(__APPLE__)
532571
return NULL;
533572
#else
@@ -543,7 +582,7 @@ static dt_ort_gpu_info_t *_detect_intel(void)
543582
dt_ort_gpu_info_t *info = g_new0(dt_ort_gpu_info_t, 1);
544583
info->vendor = DT_ORT_GPU_INTEL;
545584
info->label = gpu_name ? gpu_name : g_strdup("Intel GPU");
546-
info->driver_version = g_strdup("");
585+
info->runtime_version = g_strdup("");
547586
info->deps_met = TRUE; // OpenVINO wheel bundles everything
548587
info->download_size_mb = 150;
549588

@@ -571,7 +610,7 @@ void dt_ort_gpu_info_free(dt_ort_gpu_info_t *info)
571610
{
572611
if(!info) return;
573612
g_free(info->label);
574-
g_free(info->driver_version);
613+
g_free(info->runtime_version);
575614
g_free(info->deps_missing);
576615
g_free(info->deps_hint);
577616
g_free(info);

src/ai/ort_install.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ typedef struct
3333
{
3434
dt_ort_gpu_vendor_t vendor;
3535
char *label; // e.g. "NVIDIA GeForce RTX 4090"
36-
char *driver_version; // e.g. "550.54.14" or ROCm version
36+
char *runtime_version; // e.g. "CUDA 13.2" or "ROCm 7.2", may be ""
3737
gboolean deps_met; // all runtime prerequisites satisfied
3838
char *deps_missing; // human-readable list of what's missing
3939
char *deps_hint; // distro-specific install command

src/gui/preferences_ai.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1275,7 +1275,9 @@ static void _on_install_ort_clicked(GtkButton *button, gpointer user_data)
12751275
const char *ep = (g->vendor == DT_ORT_GPU_NVIDIA) ? "CUDA"
12761276
: (g->vendor == DT_ORT_GPU_AMD) ? "MIGraphX"
12771277
: "OpenVINO";
1278-
gchar *entry = g_strdup_printf("%s (%s) [%s]", g->label, g->driver_version, ep);
1278+
gchar *entry = (g->runtime_version && g->runtime_version[0])
1279+
? g_strdup_printf("%s (%s) [%s]", g->label, g->runtime_version, ep)
1280+
: g_strdup_printf("%s [%s]", g->label, ep);
12791281
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), entry);
12801282
g_free(entry);
12811283
}
@@ -1304,8 +1306,8 @@ static void _on_install_ort_clicked(GtkButton *button, gpointer user_data)
13041306
GString *msg = g_string_new(NULL);
13051307
g_string_append_printf(msg, _("install ONNX Runtime with %s support\n\n"), ep);
13061308
g_string_append_printf(msg, _("GPU: %s\n"), selected->label);
1307-
if(selected->driver_version && selected->driver_version[0])
1308-
g_string_append_printf(msg, _("driver: %s\n"), selected->driver_version);
1309+
if(selected->runtime_version && selected->runtime_version[0])
1310+
g_string_append_printf(msg, _("runtime: %s\n"), selected->runtime_version);
13091311
g_string_append_printf(msg, _("download size: ~%zu MB\n"), selected->download_size_mb);
13101312

13111313
if(selected->deps_missing && selected->deps_missing[0])

0 commit comments

Comments
 (0)