#include "gromacs/utility/logger.h"
#include "gromacs/utility/real.h"
#include "gromacs/utility/smalloc.h"
-#include "gromacs/utility/stringutil.h"
+#include "gromacs/utility/message_string_collector.h"
#include "gromacs/utility/unique_cptr.h"
#include "calculate_spline_moduli.h"
#include "pme_spline_work.h"
#include "pme_spread.h"
-/*! \brief Help build a descriptive message in \c error if there are
- * \c errorReasons why PME on GPU is not supported.
- *
- * \returns Whether the lack of errorReasons indicate there is support. */
-static bool addMessageIfNotSupported(const std::list<std::string>& errorReasons, std::string* error)
-{
- bool isSupported = errorReasons.empty();
- if (!isSupported && error)
- {
- std::string regressionTestMarker = "PME GPU does not support";
- // this prefix is tested for in the regression tests script gmxtest.pl
- *error = regressionTestMarker;
- if (errorReasons.size() == 1)
- {
- *error += " " + errorReasons.back();
- }
- else
- {
- *error += ": " + gmx::joinStrings(errorReasons, "; ");
- }
- *error += ".";
- }
- return isSupported;
-}
-
bool pme_gpu_supports_build(std::string* error)
{
- std::list<std::string> errorReasons;
- if (GMX_DOUBLE)
- {
- errorReasons.emplace_back("a double-precision build");
- }
- if (!GMX_GPU)
- {
- errorReasons.emplace_back("a non-GPU build");
- }
- if (GMX_GPU_SYCL)
- {
- errorReasons.emplace_back("SYCL build"); // SYCL-TODO
- }
- return addMessageIfNotSupported(errorReasons, error);
+ gmx::MessageStringCollector errorReasons;
+ // Before changing the prefix string, make sure that it is not searched for in regression tests.
+ errorReasons.startContext("PME GPU does not support:");
+ errorReasons.appendIf(GMX_DOUBLE, "Double-precision build of GROMACS.");
+ errorReasons.appendIf(!GMX_GPU, "Non-GPU build of GROMACS.");
+ errorReasons.appendIf(GMX_GPU_SYCL, "SYCL build."); // SYCL-TODO
+ errorReasons.finishContext();
+ if (error != nullptr)
+ {
+ *error = errorReasons.toString();
+ }
+ return errorReasons.isEmpty();
}
bool pme_gpu_supports_hardware(const gmx_hw_info_t gmx_unused& hwinfo, std::string* error)
{
- std::list<std::string> errorReasons;
-
- if (GMX_GPU_OPENCL)
- {
+ gmx::MessageStringCollector errorReasons;
+ // Before changing the prefix string, make sure that it is not searched for in regression tests.
+ errorReasons.startContext("PME GPU does not support:");
#ifdef __APPLE__
- errorReasons.emplace_back("Apple OS X operating system");
+ errorReasons.appendIf(GMX_GPU_OPENCL, "Apple OS X operating system");
#endif
+ errorReasons.finishContext();
+ if (error != nullptr)
+ {
+ *error = errorReasons.toString();
}
- return addMessageIfNotSupported(errorReasons, error);
+ return errorReasons.isEmpty();
}
bool pme_gpu_supports_input(const t_inputrec& ir, std::string* error)
{
- std::list<std::string> errorReasons;
- if (!EEL_PME(ir.coulombtype))
- {
- errorReasons.emplace_back("systems that do not use PME for electrostatics");
- }
- if (ir.pme_order != 4)
- {
- errorReasons.emplace_back("interpolation orders other than 4");
- }
- if (EVDW_PME(ir.vdwtype))
- {
- errorReasons.emplace_back("Lennard-Jones PME");
- }
- if (!EI_DYNAMICS(ir.eI))
- {
- errorReasons.emplace_back(
- "Cannot compute PME interactions on a GPU, because PME GPU requires a dynamical "
- "integrator (md, sd, etc).");
- }
- return addMessageIfNotSupported(errorReasons, error);
+ gmx::MessageStringCollector errorReasons;
+ // Before changing the prefix string, make sure that it is not searched for in regression tests.
+ errorReasons.startContext("PME GPU does not support:");
+ errorReasons.appendIf(!EEL_PME(ir.coulombtype),
+ "Systems that do not use PME for electrostatics.");
+ errorReasons.appendIf((ir.pme_order != 4), "Interpolation orders other than 4.");
+ errorReasons.appendIf(EVDW_PME(ir.vdwtype), "Lennard-Jones PME.");
+ errorReasons.appendIf(!EI_DYNAMICS(ir.eI), "Non-dynamical integrator (use md, sd, etc).");
+ errorReasons.finishContext();
+ if (error != nullptr)
+ {
+ *error = errorReasons.toString();
+ }
+ return errorReasons.isEmpty();
}
/*! \brief \libinternal
*/
static bool pme_gpu_check_restrictions(const gmx_pme_t* pme, std::string* error)
{
- std::list<std::string> errorReasons;
- if (pme->nnodes != 1)
- {
- errorReasons.emplace_back("PME decomposition");
- }
- if (pme->pme_order != 4)
- {
- errorReasons.emplace_back("interpolation orders other than 4");
- }
- if (pme->doLJ)
- {
- errorReasons.emplace_back("Lennard-Jones PME");
- }
- if (GMX_DOUBLE)
- {
- errorReasons.emplace_back("double precision");
- }
- if (!GMX_GPU)
- {
- errorReasons.emplace_back("non-GPU build of GROMACS");
- }
- if (GMX_GPU_SYCL)
- {
- errorReasons.emplace_back("SYCL build of GROMACS"); // SYCL-TODO
- }
- return addMessageIfNotSupported(errorReasons, error);
+ gmx::MessageStringCollector errorReasons;
+ // Before changing the prefix string, make sure that it is not searched for in regression tests.
+ errorReasons.startContext("PME GPU does not support:");
+ errorReasons.appendIf((pme->nnodes != 1), "PME decomposition.");
+ errorReasons.appendIf((pme->pme_order != 4), "interpolation orders other than 4.");
+ errorReasons.appendIf(pme->doLJ, "Lennard-Jones PME.");
+ errorReasons.appendIf(GMX_DOUBLE, "Double precision build of GROMACS.");
+ errorReasons.appendIf(!GMX_GPU, "Non-GPU build of GROMACS.");
+ errorReasons.appendIf(GMX_GPU_SYCL, "SYCL build of GROMACS."); // SYCL-TODO
+ errorReasons.finishContext();
+ if (error != nullptr)
+ {
+ *error = errorReasons.toString();
+ }
+ return errorReasons.isEmpty();
}
PmeRunMode pme_run_mode(const gmx_pme_t* pme)
};
return s_gpuApiCallBehaviorNames[enumValue];
}
-
-/*! \brief Help build a descriptive message in \c error if there are
- * \c errorReasons why nonbondeds on a GPU are not supported.
- *
- * \returns Whether the lack of errorReasons indicate there is support. */
-static bool addMessageIfNotSupported(gmx::ArrayRef<const std::string> errorReasons, std::string* error)
-{
- bool isSupported = errorReasons.empty();
- if (!isSupported && error)
- {
- *error = "Nonbonded interactions cannot run on GPUs: ";
- *error += joinStrings(errorReasons, "; ") + ".";
- }
- return isSupported;
-}
-
-bool buildSupportsNonbondedOnGpu(std::string* error)
-{
- std::vector<std::string> errorReasons;
- if (GMX_DOUBLE)
- {
- errorReasons.emplace_back("double precision");
- }
- if (!GMX_GPU)
- {
- errorReasons.emplace_back("non-GPU build of GROMACS");
- }
- return addMessageIfNotSupported(errorReasons, error);
-}
Check /*<< Only check whether the task has completed */
};
-/*! \brief Check if GROMACS has been built with GPU support.
- *
- * \param[in] error Pointer to error string or nullptr.
- * \todo Move this to NB module once it exists.
- */
-bool buildSupportsNonbondedOnGpu(std::string* error);
-
/*! \brief Starts the GPU profiler if mdrun is being profiled.
*
* When a profiler run is in progress (based on the presence of the NVPROF_ID
#include "gromacs/listed_forces/gpubonded.h"
#include "gromacs/mdtypes/inputrec.h"
#include "gromacs/topology/topology.h"
-#include "gromacs/utility/stringutil.h"
+#include "gromacs/utility/message_string_collector.h"
namespace gmx
{
return false;
}
-/*! \brief Help build a descriptive message in \c error if there are
- * \c errorReasons why bondeds on a GPU are not supported.
- *
- * \returns Whether the lack of errorReasons indicate there is support. */
-static bool addMessageIfNotSupported(ArrayRef<const std::string> errorReasons, std::string* error)
-{
- bool isSupported = errorReasons.empty();
- if (!isSupported && error)
- {
- *error = "Bonded interactions cannot run on GPUs: ";
- *error += joinStrings(errorReasons, "; ") + ".";
- }
- return isSupported;
-}
-
bool buildSupportsGpuBondeds(std::string* error)
{
- std::vector<std::string> errorReasons;
-
- if (GMX_DOUBLE)
- {
- errorReasons.emplace_back("not supported with double precision");
- }
- if (GMX_GPU_OPENCL)
- {
- errorReasons.emplace_back("not supported with OpenCL build of GROMACS");
- }
- if (GMX_GPU_SYCL)
+ MessageStringCollector errorReasons;
+ // Before changing the prefix string, make sure that it is not searched for in regression tests.
+ errorReasons.startContext("Bonded interactions on GPU are not supported in:");
+ errorReasons.appendIf(GMX_DOUBLE, "Double precision build of GROMACS");
+ errorReasons.appendIf(GMX_GPU_OPENCL, "OpenCL build of GROMACS");
+ errorReasons.appendIf(GMX_GPU_SYCL, "SYCL build of GROMACS");
+ errorReasons.appendIf(!GMX_GPU, "CPU-only build of GROMACS");
+ errorReasons.finishContext();
+ if (error != nullptr)
{
- errorReasons.emplace_back("not supported with SYCL build of GROMACS");
+ *error = errorReasons.toString();
}
- else if (!GMX_GPU)
- {
- errorReasons.emplace_back("not supported with CPU-only build of GROMACS");
- }
- return addMessageIfNotSupported(errorReasons, error);
+ return errorReasons.isEmpty();
}
bool inputSupportsGpuBondeds(const t_inputrec& ir, const gmx_mtop_t& mtop, std::string* error)
{
- std::vector<std::string> errorReasons;
-
- if (!bondedInteractionsCanRunOnGpu(mtop))
- {
- errorReasons.emplace_back("No supported bonded interactions are present");
- }
- if (!EI_DYNAMICS(ir.eI))
- {
- errorReasons.emplace_back(
- "Cannot compute bonded interactions on a GPU, because GPU implementation requires "
- "a dynamical integrator (md, sd, etc).");
- }
- if (EI_MIMIC(ir.eI))
- {
- errorReasons.emplace_back("MiMiC");
- }
- if (ir.useMts)
- {
- errorReasons.emplace_back("Cannot run with multiple time stepping");
- }
- if (ir.opts.ngener > 1)
+ MessageStringCollector errorReasons;
+ // Before changing the prefix string, make sure that it is not searched for in regression tests.
+ errorReasons.startContext("Bonded interactions can not be computed on a GPU:");
+
+ errorReasons.appendIf(!bondedInteractionsCanRunOnGpu(mtop),
+ "None of the bonded types are implemented on the GPU.");
+ errorReasons.appendIf(
+ !EI_DYNAMICS(ir.eI),
+ "Cannot compute bonded interactions on a GPU, because GPU implementation requires "
+ "a dynamical integrator (md, sd, etc).");
+ errorReasons.appendIf(EI_MIMIC(ir.eI), "MiMiC");
+ errorReasons.appendIf(ir.useMts, "Cannot run with multiple time stepping");
+ errorReasons.appendIf((ir.opts.ngener > 1), "Cannot run with multiple energy groups");
+ errorReasons.finishContext();
+ if (error != nullptr)
{
- errorReasons.emplace_back("Cannot run with multiple energy groups");
+ *error = errorReasons.toString();
}
- return addMessageIfNotSupported(errorReasons, error);
+ return errorReasons.isEmpty();
}
#if !GMX_GPU_CUDA
#include "gromacs/domdec/domdec_struct.h"
#include "gromacs/nbnxm/atomdata.h"
#include "gromacs/timing/wallcycle.h"
+#include "gromacs/utility/message_string_collector.h"
#include "nbnxm_gpu.h"
#include "pairlistsets.h"
Nbnxm::nbnxn_gpu_init_x_to_nbat_x(pairSearch_->gridSet(), gpu_nbv);
}
+bool buildSupportsNonbondedOnGpu(std::string* error)
+{
+ gmx::MessageStringCollector errorReasons;
+ // Before changing the prefix string, make sure that it is not searched for in regression tests.
+ errorReasons.startContext("Nonbonded interactions on GPUs are not supported in:");
+ errorReasons.appendIf(GMX_DOUBLE, "Double precision build of GROMACS");
+ errorReasons.appendIf(!GMX_GPU, "Non-GPU build of GROMACS.");
+ errorReasons.finishContext();
+ if (error != nullptr)
+ {
+ *error = errorReasons.toString();
+ }
+ return errorReasons.isEmpty();
+}
+
+
/*! \endcond */
gmx::ArrayRef<const int> atomInfo,
gmx::ArrayRef<const gmx::RVec> x);
+/*! \brief Check if GROMACS has been built with GPU support.
+ *
+ * \param[in] error Pointer to error string or nullptr.
+ * \todo Move this to NB module once it exists.
+ */
+bool buildSupportsNonbondedOnGpu(std::string* error);
+
#endif // GMX_NBNXN_NBNXM_H