Skip to content

Commit 4da85f6

Browse files
authored
Merge pull request #352 from abergeron/check_version
Blacklist bad versions of the cuda drivers
2 parents 97faa58 + 309e87b commit 4da85f6

5 files changed

Lines changed: 115 additions & 12 deletions

File tree

Makefile

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,8 @@ debug: install-debugc py
1111

1212
.PHONY: install-debugc py debug install-relc rel config
1313

14-
Debug:
15-
mkdir Debug
16-
17-
Debug/Makefile: Debug config
14+
Debug/Makefile: Debug Makefile.conf
15+
mkdir -p Debug
1816
ifndef INSTALL_PREFIX
1917
(cd Debug && NUM_DEVS=${NUM_DEVS} DEV_NAMES=${DEV_NAMES} cmake .. -DCMAKE_BUILD_TYPE=Debug)
2018
else
@@ -34,10 +32,8 @@ endif
3432
install-debugc: debugc
3533
(cd Debug && ${SUDO} make install)
3634

37-
Release:
38-
mkdir Release
39-
40-
Release/Makefile: Release config
35+
Release/Makefile: Makefile.conf
36+
mkdir -p Release
4137
ifndef INSTALL_PREFIX
4238
(cd Release && NUM_DEVS=${NUM_DEVS} DEV_NAMES=${DEV_NAMES} cmake .. -DCMAKE_BUILD_TYPE=Release)
4339
else
@@ -57,5 +53,5 @@ endif
5753
install-relc: relc
5854
(cd Release && ${SUDO} make install)
5955

60-
py: config
56+
py: Makefile.conf
6157
python setup.py build_ext --inplace

src/loaders/dyn_load.c

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
#if defined(__unix__) || defined(__APPLE__)
44

55
#include <dlfcn.h>
6-
#include <stddef.h>
76
#include <err.h>
7+
#include <stddef.h>
8+
#include <stdlib.h>
9+
#include <string.h>
810

911
void *ga_load_library(const char *name) {
1012
void *res = dlopen(name, RTLD_LAZY|RTLD_LOCAL);
@@ -24,10 +26,50 @@ void *ga_func_ptr(void *h, const char *name) {
2426
return res;
2527
}
2628

29+
float ga_lib_version(void *h, void *sym) {
30+
Dl_info dli;
31+
char *real_path;
32+
char *dot1;
33+
char *dot2;
34+
char *end;
35+
float res;
36+
37+
if (!dladdr(sym, &dli))
38+
return -1;
39+
40+
real_path = realpath(dli.dli_fname, NULL);
41+
if (real_path == NULL)
42+
return -1;
43+
44+
dot1 = strrchr(real_path, '.');
45+
if (dot1 == NULL) {
46+
free(real_path);
47+
return -1;
48+
}
49+
dot1[0] = '\0';
50+
51+
dot2 = strrchr(real_path, '.');
52+
if (dot2 == NULL) {
53+
free(real_path);
54+
return -1;
55+
}
56+
dot1[0] = '.';
57+
58+
res = strtof(dot2+1, &end);
59+
if (*end != '\0') {
60+
free(real_path);
61+
return -1;
62+
}
63+
64+
free(real_path);
65+
return res;
66+
}
67+
2768
#else
2869

2970
/* Should be windows */
3071
#include <windows.h>
72+
#pragma comment(lib,"Version.lib")
3173

3274
void *ga_load_library(const char *name) {
3375
return LoadLibrary(name);
@@ -37,4 +79,39 @@ void *ga_func_ptr(void *h, const char *name) {
3779
return (void *)GetProcAddress(h, name);
3880
}
3981

82+
float ga_lib_version(void *h, void *sym) {
83+
char fname[1024];
84+
char *vinfo;
85+
size_t vsize;
86+
VS_FIXEDFILEINFO *vp;
87+
unsigned int ui;
88+
float res;
89+
90+
if (GetModuleFileName(h, fname, sizeof(fname)) == sizeof(fname))
91+
return -1;
92+
93+
vsize = GetFileVersionInfoSize(fname, NULL);
94+
if (vsize == 0)
95+
return -1;
96+
97+
vinfo = malloc(vsize);
98+
if (vinfo == NULL)
99+
return -1;
100+
101+
if (!GetFileVersionInfo(fname, 0, vsize, vinfo)) {
102+
free(vinfo);
103+
return -1;
104+
}
105+
106+
if (!VerQueryValue(vinfo, "\\", &vp, &ui)) {
107+
free(vinfo);
108+
return -1;
109+
}
110+
111+
res = ( ((HIWORD(vp->dwFileVersionLS) - 10) * 10000) + LOWORD(vp->dwFileVersionLS) ) / 100.0;
112+
113+
free(vinfo);
114+
return res;
115+
}
116+
40117
#endif

src/loaders/dyn_load.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@
33

44
void *ga_load_library(const char *name);
55
void *ga_func_ptr(void *h, const char *name);
6+
float ga_lib_version(void *h, void *sym);
67

78
#endif

src/loaders/libcuda.c

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#include <stdio.h>
12
#include <stdlib.h>
23

34
#include "libcuda.h"
@@ -9,7 +10,7 @@
910
static char libname[] = "nvcuda.dll";
1011
#else /* Unix */
1112
#ifdef __APPLE__
12-
static char libname[] = "CUDA.framework/CUDA";
13+
static char libname[] = "/Library/Frameworks/CUDA.framework/CUDA";
1314
#else
1415
static char libname[] = "libcuda.so";
1516
#endif
@@ -41,6 +42,9 @@ static int loaded = 0;
4142

4243
int load_libcuda(void) {
4344
void *lib;
45+
#ifndef __APPLE__
46+
float v;
47+
#endif
4448

4549
if (loaded)
4650
return GA_NO_ERROR;
@@ -51,6 +55,31 @@ int load_libcuda(void) {
5155

5256
#include "libcuda.fn"
5357

58+
/*
59+
* The blacklisted versions of cuda are not available on mac as far as I know.
60+
*/
61+
#ifndef __APPLE__
62+
v = ga_lib_version(lib, cuInit);
63+
if (v == -1)
64+
fprintf(stderr, "WARNING: could not determine cuda driver version. Some versions return bad results, make sure your version is fine\n");
65+
#ifdef DEBUG
66+
fprintf(stderr, "CUDA driver version detected: %.2f\n", v);
67+
#endif
68+
69+
if (v > 373.06) {
70+
if (getenv("GPUARRAY_FORCE_CUDA_DRIVER_LOAD") != NULL) {
71+
fprintf(stderr, "WARNING: loading blacklisted driver because the load was forced.\n");
72+
} else {
73+
fprintf(stderr, "ERROR: refusing to load cuda driver library "
74+
"because the version is blacklisted. "
75+
"Versions 373.06 and below are known to be ok.\n"
76+
"If you want to bypass this check and force the driver load "
77+
"define GPUARRAY_FORCE_CUDA_DRIVER_LOAD in your environement.\n");
78+
return GA_LOAD_ERROR;
79+
}
80+
}
81+
#endif
82+
5483
loaded = 1;
5584
return GA_NO_ERROR;
5685
}

src/loaders/libopencl.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
static char libname[] = "OpenCL.dll";
99
#else /* Unix */
1010
#ifdef __APPLE__
11-
static char libname[] = "OpenCL.framework/OpenCL";
11+
static char libname[] = "/System/Library/Frameworks/OpenCL.framework/OpenCL";
1212
#else
1313
static char libname[] = "libOpenCL.so";
1414
#endif

0 commit comments

Comments
 (0)