Disable fastmath with OpenCL on Intel devices
[alexxy/gromacs.git] / src / gromacs / gpu_utils / ocl_compiler.cpp
index 5ce28b8fd2bff832410e3dcaa3485a726f230cd5..64e925b885036f74e01a9dd2049f2d790cbb5a9a 100644 (file)
@@ -2,7 +2,7 @@
  * This file is part of the GROMACS molecular simulation package.
  *
  * Copyright (c) 2012,2013,2014,2015,2016 by the GROMACS development team.
- * Copyright (c) 2017,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2017,2018,2019,2020,2021, by the GROMACS development team, led by
  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
  * and including many others, as listed in the AUTHORS file in the
  * top-level source directory and at http://www.gromacs.org.
@@ -80,7 +80,7 @@ static bool useBuildCache = getenv("GMX_OCL_GENCACHE") != nullptr;
 
 /*! \brief Handles writing the OpenCL JIT compilation log to \c fplog.
  *
- * If \c fplog is non-null and either the GMX_OCL_DUMP_LOG environment
+ * If \c fplog is non-null and either the \c GMX_OCL_DUMP_LOG environment
  * variable is set or the compilation failed, then the OpenCL
  * compilation log is written.
  *
@@ -89,7 +89,8 @@ static bool useBuildCache = getenv("GMX_OCL_GENCACHE") != nullptr;
  * \param deviceId            Id of the device for which compilation took place
  * \param kernelFilename      File name containing the kernel
  * \param preprocessorOptions String containing the preprocessor command-line options used for the
- * build \param buildFailed         Whether the OpenCL build succeeded
+ *                            build
+ * \param buildFailed         Whether the OpenCL build succeeded
  *
  * \throws std::bad_alloc if out of memory */
 static void writeOclBuildLog(FILE*              fplog,
@@ -126,8 +127,8 @@ static void writeOclBuildLog(FILE*              fplog,
         buildLogGuard.reset(buildLog);
 
         /* Get the actual compilation log */
-        cl_error = clGetProgramBuildInfo(program, deviceId, CL_PROGRAM_BUILD_LOG, buildLogSize,
-                                         buildLog, nullptr);
+        cl_error = clGetProgramBuildInfo(
+                program, deviceId, CL_PROGRAM_BUILD_LOG, buildLogSize, buildLog, nullptr);
         if (cl_error != CL_SUCCESS)
         {
             GMX_THROW(InternalError("Could not get OpenCL program build log, error was "
@@ -168,8 +169,9 @@ static std::string selectCompilerOptions(DeviceVendor deviceVendor)
         compilerOptions += " -cl-opt-disable";
     }
 
-    /* Fastmath imprves performance on all supported arch */
-    if (getenv("GMX_OCL_DISABLE_FASTMATH") == nullptr)
+    /* Fastmath improves performance on all supported arch,
+     * but is tends to cause problems on Intel (Issue #3898) */
+    if ((deviceVendor != DeviceVendor::Intel) && (getenv("GMX_OCL_DISABLE_FASTMATH") == nullptr))
     {
         compilerOptions += " -cl-fast-relaxed-math";
 
@@ -248,9 +250,8 @@ static std::string getSourceRootPath(const std::string& sourceRelativePath)
 size_t getKernelWarpSize(cl_kernel kernel, cl_device_id deviceId)
 {
     size_t warpSize = 0;
-    cl_int cl_error =
-            clGetKernelWorkGroupInfo(kernel, deviceId, CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE,
-                                     sizeof(warpSize), &warpSize, nullptr);
+    cl_int cl_error = clGetKernelWorkGroupInfo(
+            kernel, deviceId, CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE, sizeof(warpSize), &warpSize, nullptr);
     if (cl_error != CL_SUCCESS)
     {
         GMX_THROW(InternalError("Could not query OpenCL preferred workgroup size, error was "
@@ -313,7 +314,7 @@ size_t getDeviceWarpSize(cl_context context, cl_device_id deviceId)
  *
  * \return The appropriate compilation-line define
  */
-static const std::string makeVendorFlavorChoice(DeviceVendor deviceVendor)
+static std::string makeVendorFlavorChoice(DeviceVendor deviceVendor)
 {
     switch (deviceVendor)
     {
@@ -450,11 +451,16 @@ cl_program compileProgram(FILE*              fplog,
                 // Failing to read from the cache is not a critical error
                 formatExceptionMessageToFile(fplog, e);
             }
+            fprintf(fplog,
+                    "OpenCL binary cache file %s is present, will load kernels.\n",
+                    cacheFilename.c_str());
         }
         else
         {
             fprintf(fplog,
-                    "No OpenCL binary cache file was present, so will compile kernels normally.\n");
+                    "No OpenCL binary cache file was present for %s, so will compile kernels "
+                    "normally.\n",
+                    kernelBaseFilename.c_str());
         }
     }
     if (program == nullptr)
@@ -483,8 +489,7 @@ cl_program compileProgram(FILE*              fplog,
 
     /* Write log first, and then throw exception that the user know what is
        the issue even if the build fails. */
-    writeOclBuildLog(fplog, program, deviceId, kernelFilename, preprocessorOptions,
-                     buildStatus != CL_SUCCESS);
+    writeOclBuildLog(fplog, program, deviceId, kernelFilename, preprocessorOptions, buildStatus != CL_SUCCESS);
 
     if (buildStatus != CL_SUCCESS)
     {