+static bool canUseGpusForPme(const bool useGpuForNonbonded,
+ const TaskTarget pmeTarget,
+ const TaskTarget pmeFftTarget,
+ const gmx_hw_info_t& hardwareInfo,
+ const t_inputrec& inputrec,
+ std::string* errorMessage)
+{
+ if (pmeTarget == TaskTarget::Cpu)
+ {
+ return false;
+ }
+
+ std::string tempString;
+ gmx::MessageStringCollector errorReasons;
+ // Before changing the prefix string, make sure that it is not searched for in regression tests.
+ errorReasons.startContext("Cannot compute PME interactions on a GPU, because:");
+ errorReasons.appendIf(!useGpuForNonbonded, "Nonbonded interactions must also run on GPUs.");
+ errorReasons.appendIf(!pme_gpu_supports_build(&tempString), tempString);
+ errorReasons.appendIf(!pme_gpu_supports_hardware(hardwareInfo, &tempString), tempString);
+ errorReasons.appendIf(!pme_gpu_supports_input(inputrec, &tempString), tempString);
+ if (pmeFftTarget == TaskTarget::Cpu)
+ {
+ // User requested PME FFT on CPU, so we check whether we are able to use PME Mixed mode.
+ errorReasons.appendIf(!pme_gpu_mixed_mode_supports_input(inputrec, &tempString), tempString);
+ }
+ errorReasons.finishContext();
+
+ if (errorReasons.isEmpty())
+ {
+ return true;
+ }
+ else
+ {
+ if (pmeTarget == TaskTarget::Gpu && errorMessage != nullptr)
+ {
+ *errorMessage = errorReasons.toString();
+ }
+ return false;
+ }
+}
+