client: Mac OpenCL: fix arithmetic overflow in memory size calculation for AMD GPUs

This commit is contained in:
Charlie Fenton 2017-11-10 06:06:56 -08:00
parent c94188875e
commit 0a2115cedc
1 changed files with 48 additions and 4 deletions

View File

@ -138,6 +138,45 @@ static bool compare_pci_slots(int NVIDIA_GPU_Index1, int NVIDIA_GPU_Index2) {
nvidia_gpus[NVIDIA_GPU_Index2].pci_info.bus_id
);
}
// Test OS version number on all versions of OS X without using deprecated Gestalt
// compareOSVersionTo(x, y) returns:
// -1 if the OS version we are running on is less than x.y
// 0 if the OS version we are running on is equal to x.y
// +1 if the OS version we are running on is lgreater than x.y
static int compareOSVersionTo(int toMajor, int toMinor) {
static SInt32 major = -1;
static SInt32 minor = -1;
if (major < 0) {
char vers[100], *p1 = NULL;
FILE *f;
vers[0] = '\0';
f = popen("sw_vers -productVersion", "r");
if (f) {
fscanf(f, "%s", vers);
pclose(f);
}
if (vers[0] == '\0') {
fprintf(stderr, "popen(\"sw_vers -productVersion\" failed\n");
fflush(stderr);
return 0;
}
// Extract the major system version number
major = atoi(vers);
// Extract the minor system version number
p1 = strchr(vers, '.');
minor = atoi(p1+1);
}
if (major < toMajor) return -1;
if (major > toMajor) return 1;
// if (major == toMajor) compare minor version numbers
if (minor < toMinor) return -1;
if (minor > toMinor) return 1;
return 0;
}
#endif
@ -597,7 +636,10 @@ void COPROCS::get_opencl(
// This has already been fixed on latest Catalyst
// drivers, but Mac does not use Catalyst drivers.
if (ati_opencls.size() > 0) {
opencl_get_ati_mem_size_from_opengl(warnings);
// This problem seems to be fixed in OS 10.7
if (compareOSVersionTo(10, 7) < 0) {
opencl_get_ati_mem_size_from_opengl(warnings);
}
}
#endif
@ -1074,6 +1116,7 @@ void COPROCS::opencl_get_ati_mem_size_from_opengl(vector<string>& warnings) {
CGLRendererInfoObj info;
long i, j;
GLint numRenderers = 0, rv = 0, deviceVRAM, rendererID;
cl_ulong deviceMemSize;
CGLError theErr2 = kCGLNoError;
CGLContextObj curr_ctx = CGLGetCurrentContext (); // save current CGL context
int ati_gpu_index = 0;
@ -1129,7 +1172,7 @@ void COPROCS::opencl_get_ati_mem_size_from_opengl(vector<string>& warnings) {
// what is the VRAM?
CGLError notAvail = CGLDescribeRenderer (info, i, kCGLRPVideoMemoryMegabytes, &deviceVRAM);
if (notAvail == kCGLNoError) {
deviceVRAM = deviceVRAM * (1024*1024);
deviceMemSize = ((cl_ulong)deviceVRAM) * (1024L*1024L);
} else { // kCGLRPVideoMemoryMegabytes is not available before OS 10.7
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
@ -1137,6 +1180,7 @@ void COPROCS::opencl_get_ati_mem_size_from_opengl(vector<string>& warnings) {
// defined in later SDKs, so use a literal value here instead
// CGLDescribeRenderer (info, i, kCGLRPVideoMemory, &deviceVRAM);
CGLDescribeRenderer (info, i, (CGLRendererProperty)120, &deviceVRAM);
deviceMemSize = deviceVRAM;
#pragma clang diagnostic pop
}
@ -1160,8 +1204,8 @@ void COPROCS::opencl_get_ati_mem_size_from_opengl(vector<string>& warnings) {
// get vendor string from renderer
const GLubyte * strVend = glGetString (GL_VENDOR);
if (is_AMD((char *)strVend)) {
ati_opencls[ati_gpu_index].global_mem_size = deviceVRAM;
ati_opencls[ati_gpu_index].opencl_available_ram = deviceVRAM;
ati_opencls[ati_gpu_index].global_mem_size = deviceMemSize;
ati_opencls[ati_gpu_index].opencl_available_ram = deviceMemSize;
if (log_flags.coproc_debug) {
// For some GPUs, one API returns "ATI" but the other API returns