PME spline+spread CUDA kernel and unit tests
[alexxy/gromacs.git] / src / gromacs / ewald / pme-gpu.cpp
index e830c53d8d9fe0b13dec41e8faadadc418e222d4..e24565adbf26b8028cc09d99789d252b5e3803c0 100644 (file)
 
 #include "gmxpre.h"
 
+#include "config.h"
+
+#include <list>
+
 #include "gromacs/ewald/pme.h"
+#include "gromacs/mdtypes/inputrec.h"
 #include "gromacs/utility/exceptions.h"
 #include "gromacs/utility/fatalerror.h"
 #include "gromacs/utility/gmxassert.h"
+#include "gromacs/utility/stringutil.h"
 
 #include "pme-gpu-internal.h"
 #include "pme-grid.h"
@@ -57,6 +63,54 @@ bool pme_gpu_task_enabled(const gmx_pme_t *pme)
     return (pme != nullptr) && (pme->runMode != PmeRunMode::CPU);
 }
 
+bool pme_gpu_supports_input(const t_inputrec *ir, std::string *error)
+{
+    std::list<std::string> errorReasons;
+    if (!EEL_PME(ir->coulombtype))
+    {
+        errorReasons.push_back("systems that do not use PME for electrostatics");
+    }
+    if (ir->pme_order != 4)
+    {
+        errorReasons.push_back("interpolation orders other than 4");
+    }
+    if (ir->efep != efepNO)
+    {
+        errorReasons.push_back("free energy calculations (multiple grids)");
+    }
+    if (EVDW_PME(ir->vdwtype))
+    {
+        errorReasons.push_back("Lennard-Jones PME");
+    }
+#if GMX_DOUBLE
+    {
+        errorReasons.push_back("double precision");
+    }
+#endif
+#if GMX_GPU != GMX_GPU_CUDA
+    {
+        errorReasons.push_back("non-CUDA build of GROMACS");
+    }
+#endif
+    if (ir->cutoff_scheme == ecutsGROUP)
+    {
+        errorReasons.push_back("group cutoff scheme");
+    }
+    if (EI_TPI(ir->eI))
+    {
+        errorReasons.push_back("test particle insertion");
+    }
+
+    bool inputSupported = errorReasons.empty();
+    if (!inputSupported && error)
+    {
+        std::string regressionTestMarker = "PME GPU does not support";
+        // this prefix is tested for in the regression tests script gmxtest.pl
+        *error = regressionTestMarker + ": " + gmx::joinStrings(errorReasons, "; ") + ".";
+    }
+    return inputSupported;
+}
+
 void pme_gpu_reset_timings(const gmx_pme_t *pme)
 {
     if (pme_gpu_active(pme))