Merge release-2018 into master
[alexxy/gromacs.git] / src / gromacs / gpu_utils / ocl_compiler.cpp
index 957c6bc45387d0832fc20d850e6a6addb47cefab..fce784e1de1a5807d95f3a2c0f5a3711ee9ae455 100644 (file)
@@ -195,7 +195,7 @@ selectCompilerOptions(ocl_vendor_id_t deviceVendorId)
         }
     }
 
-    if ( ( deviceVendorId == OCL_VENDOR_AMD ) && getenv("GMX_OCL_DEBUG"))
+    if (getenv("GMX_OCL_DEBUG"))
     {
         compilerOptions += " -g";
     }
@@ -203,22 +203,24 @@ selectCompilerOptions(ocl_vendor_id_t deviceVendorId)
     return compilerOptions;
 }
 
-/*! \brief Get the path to the main folder storing OpenCL kernels.
+/*! \brief Get the path to the folder storing an OpenCL source file.
  *
  * By default, this function constructs the full path to the OpenCL from
  * the known location of the binary that is running, so that we handle
  * both in-source and installed builds. The user can override this
  * behavior by defining GMX_OCL_FILE_PATH environment variable.
  *
- * \return OS-normalized path string to the main folder storing OpenCL kernels
+ * \param[in] sourceRelativePath    Relative path to the kernel or other file in the source tree,
+ *                                  e.g. "src/gromacs/mdlib/nbnxn_ocl" for NB kernels.
+ * \return OS-normalized path string to the folder storing OpenCL source file
  *
  * \throws std::bad_alloc    if out of memory.
  *         FileIOError  if GMX_OCL_FILE_PATH does not specify a readable path
  */
 static std::string
-getKernelRootPath()
+getSourceRootPath(const std::string &sourceRelativePath)
 {
-    std::string kernelRootPath;
+    std::string sourceRootPath;
     /* Use GMX_OCL_FILE_PATH if the user has defined it */
     const char *gmxOclFilePath = getenv("GMX_OCL_FILE_PATH");
 
@@ -228,9 +230,9 @@ getKernelRootPath()
            root path from the path to the binary that is running. */
         InstallationPrefixInfo      info           = getProgramContext().installationPrefix();
         std::string                 dataPathSuffix = (info.bSourceLayout ?
-                                                      "src/gromacs/mdlib/nbnxn_ocl" :
+                                                      sourceRelativePath :
                                                       GMX_INSTALL_OCLDIR);
-        kernelRootPath = Path::join(info.path, dataPathSuffix);
+        sourceRootPath = Path::join(info.path, dataPathSuffix);
     }
     else
     {
@@ -239,11 +241,11 @@ getKernelRootPath()
             GMX_THROW(FileIOError(formatString("GMX_OCL_FILE_PATH must point to the directory where OpenCL"
                                                "kernels are found, but '%s' does not exist", gmxOclFilePath)));
         }
-        kernelRootPath = gmxOclFilePath;
+        sourceRootPath = gmxOclFilePath;
     }
 
     // Make sure we return an OS-correct path format
-    return Path::normalize(kernelRootPath);
+    return Path::normalize(sourceRootPath);
 }
 
 /*!  \brief Get the warp size reported by device
@@ -324,8 +326,11 @@ makeVendorFlavorChoice(ocl_vendor_id_t vendorId)
         case OCL_VENDOR_NVIDIA:
             choice = "-D_NVIDIA_SOURCE_";
             break;
+        case OCL_VENDOR_INTEL:
+            choice = "-D_INTEL_SOURCE_";
+            break;
         default:
-            choice = "-D_WARPLESS_SOURCE_";
+            choice = "";
             break;
     }
     return choice;
@@ -385,6 +390,7 @@ removeExtraSpaces(std::string *str)
  * \throws std::bad_alloc  if out of memory. */
 static std::string
 makePreprocessorOptions(const std::string   &kernelRootPath,
+                        const std::string   &includeRootPath,
                         size_t               warpSize,
                         ocl_vendor_id_t      deviceVendorId,
                         const std::string   &extraDefines)
@@ -401,6 +407,8 @@ makePreprocessorOptions(const std::string   &kernelRootPath,
     preprocessorOptions += selectCompilerOptions(deviceVendorId);
     preprocessorOptions += ' ';
     preprocessorOptions += makeKernelIncludePathOption(kernelRootPath);
+    preprocessorOptions += ' ';
+    preprocessorOptions += makeKernelIncludePathOption(includeRootPath);
 
     // Mac OS (and maybe some other implementations) does not accept double spaces in options
     removeExtraSpaces(&preprocessorOptions);
@@ -410,6 +418,7 @@ makePreprocessorOptions(const std::string   &kernelRootPath,
 
 cl_program
 compileProgram(FILE              *fplog,
+               const std::string &kernelRelativePath,
                const std::string &kernelBaseFilename,
                const std::string &extraDefines,
                cl_context         context,
@@ -417,7 +426,8 @@ compileProgram(FILE              *fplog,
                ocl_vendor_id_t    deviceVendorId)
 {
     cl_int      cl_error;
-    std::string kernelRootPath = getKernelRootPath();
+    std::string kernelRootPath  = getSourceRootPath(kernelRelativePath);
+    std::string includeRootPath = getSourceRootPath("src/gromacs/gpu_utils");
 
     GMX_RELEASE_ASSERT(fplog != nullptr, "Need a valid log file for building OpenCL programs");
 
@@ -427,6 +437,7 @@ compileProgram(FILE              *fplog,
 
     /* Make the build options */
     std::string preprocessorOptions = makePreprocessorOptions(kernelRootPath,
+                                                              includeRootPath,
                                                               getWarpSize(context, deviceId),
                                                               deviceVendorId,
                                                               extraDefines);