Skip to content

Commit

Permalink
Prevent AMD OpenCL on OS X prior to 10.10.4
Browse files Browse the repository at this point in the history
OS X release 10.9.x has been confirmed to produce invalid OpenCL
kernels for AMD (but correct for NVIDIA), and we have tested that
it is fixed in 10.10.4. The fix might actually have appeared
already in 10.10.3, but it's not worth tracking down the exact
point since 10.10.5 is already out.
This change will issue a CMake warning when compiling GROMACS
on earlier OS X releases, and at runtime we check the version
again and mark AMD GPUs as incompatible.

Also fixed docs about the length of time JIT compilation takes
on AMD.

Refs #1783

Change-Id: I0202faea60c39daae6621d2bb9ba828aab5532a0
  • Loading branch information
Erik Lindahl authored and Gerrit Code Review committed Aug 12, 2015
1 parent 2a5b0b6 commit c66e8fa
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 11 deletions.
5 changes: 5 additions & 0 deletions cmake/gmxManageOpenCL.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ if (UNIX)
set(OPENCL_DEFINITIONS ${OPENCL_DEFINITIONS} " -Wno-comment")
endif()

# Yes Virginia, Darwin kernel version 14.4 corresponds to OS X 10.4.
if(APPLE AND ${CMAKE_SYSTEM_VERSION} VERSION_LESS "14.4")
message(WARNING "OS X prior to version 10.10.4 produces incorrect AMD OpenCL code at runtime. You will not be able to use AMD GPUs on this host unless you upgrade your operating system.");
endif()

add_definitions(${OPENCL_DEFINITIONS})

include_directories(${OPENCL_INCLUDE_DIRS})
Expand Down
2 changes: 2 additions & 0 deletions docs/install-guide/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -630,6 +630,8 @@ do so anyway, because NVIDIA OpenCL support is part of the CUDA
package, a C++ compiler supported by your CUDA installation is
required.

On Mac OS, an AMD GPU can be used only with OS version 10.10.4 and
higher; earlier OS versions are known to run incorrectly.

Static linking
^^^^^^^^^^^^^^
Expand Down
9 changes: 3 additions & 6 deletions docs/user-guide/mdrun-performance.rst
Original file line number Diff line number Diff line change
Expand Up @@ -537,12 +537,9 @@ The following devices are known to work correctly:
- NVIDIA: GeForce GTX 660M, GeForce GTX 660Ti, GeForce GTX 750Ti,
GeForce GTX 780, GTX Titan

Building an OpenCL program can take a significant amount of
time. NVIDIA implements a mechanism to cache the result of the
build. As a consequence, only the first run will take longer (because
of the kernel builds), and the following runs will be very fast. AMD
drivers, on the other hand, implement no caching and the initial phase
of running an OpenCL program can be very slow. This is not normally a
Building the OpenCL program can take a few seconds when :ref:`gmx
mdrun` starts up, because the kernels that run on the
GPU can only be compiled at run time. This is not normally a
problem for long production MD, but you might prefer to do some kinds
of work on just the CPU (e.g. see ``-nb`` above).

Expand Down
46 changes: 41 additions & 5 deletions src/gromacs/gmxlib/gpu_utils/gpu_utils_ocl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if __APPLE__
# include <sys/sysctl.h>
#endif

#include <memory.h>

Expand Down Expand Up @@ -81,6 +84,36 @@ static bool is_compatible_gpu(int stat)
return (stat == egpuCompatible);
}

/*! \brief Return true if executing on OS X earlier than 10.10.4
*
* Uses the BSD sysctl() interfaces to extract the kernel version.
*
* \return true if version is 14.4 or later (= OS X version 10.10.4),
* otherwise false.
*/
static bool
runningOnWorkingOSXVersionForAmd()
{
#ifdef __APPLE__
int mib[2];
char kernelVersion[256];
size_t len = sizeof(kernelVersion);

mib[0] = CTL_KERN;
mib[1] = KERN_OSRELEASE;

sysctl(mib, sizeof(mib)/sizeof(mib[0]), kernelVersion, &len, NULL, 0);

int major = strtod(kernelVersion, NULL);
int minor = strtod(strchr(kernelVersion, '.')+1, NULL);

// Kernel 14.4 corresponds to OS X 10.10.4
return (major > 14 || (major == 14 && minor >= 4));
#else
return false;
#endif
}

/*! \brief Returns true if the gpu characterized by the device properties is
* supported by the native gpu acceleration.
* \returns true if the GPU properties passed indicate a compatible
Expand All @@ -89,15 +122,18 @@ static bool is_compatible_gpu(int stat)
static int is_gmx_supported_gpu_id(struct gmx_device_info_t *ocl_gpu_device)
{
/* Only AMD and NVIDIA GPUs are supported for now */
if ((OCL_VENDOR_NVIDIA == ocl_gpu_device->vendor_e) ||
(OCL_VENDOR_AMD == ocl_gpu_device->vendor_e))
switch (ocl_gpu_device->vendor_e)
{
return egpuCompatible;
case OCL_VENDOR_NVIDIA:
return egpuCompatible;
case OCL_VENDOR_AMD:
return runningOnWorkingOSXVersionForAmd() ? egpuCompatible : egpuIncompatible;
default:
return egpuIncompatible;
}

return egpuIncompatible;
}


/*! \brief Returns an ocl_vendor_id_t value corresponding to the input OpenCL vendor name.
*
* \param[in] vendor_name String with OpenCL vendor name.
Expand Down

0 comments on commit c66e8fa

Please sign in to comment.