// Before we start the actual simulator, try if we can run the update task on the GPU.
useGpuForUpdate = decideWhetherToUseGpuForUpdate(DOMAINDECOMP(cr),
+ useGpuForPme,
useGpuForNonbonded,
+ c_enableGpuBufOps,
updateTarget,
gpusWereDetected,
*inputrec,
}
bool decideWhetherToUseGpuForUpdate(bool isDomainDecomposition,
+ bool useGpuForPme,
bool useGpuForNonbonded,
+ bool useGpuForBufferOps,
TaskTarget updateTarget,
bool gpusWereDetected,
const t_inputrec &inputrec,
{
errorMessage += "Domain decomposition is not supported.\n";
}
- if (!useGpuForNonbonded)
+ // Using the GPU-version of update makes sense if forces are already on the GPU, i.e. if at least:
+ // 1. PME is on the GPU (there should be a copy of coordinates on a GPU in rvec format for PME spread).
+ // 2. Non-bonded interactions and buffer ops are on the GPU.
+ if (!(useGpuForPme || (useGpuForNonbonded && useGpuForBufferOps)))
{
- errorMessage += "Short-ranged non-bonded interaction tasks must run on the GPU.\n";
+ errorMessage += "Either PME or short-ranged non-bonded interaction tasks must run on the GPU.\n";
}
if (!gpusWereDetected)
{
/*! \brief Decide whether to use GPU for update.
*
* \param[in] isDomainDecomposition Whether there more than one domain.
+ * \param[in] useGpuForPme Whether GPUs will be used for PME interactions.
* \param[in] useGpuForNonbonded Whether GPUs will be used for nonbonded interactions.
+ * \param[in] useGpuForBufferOps Whether GPUs will be used for buffer operations.
* \param[in] updateTarget User choice for running simulation on GPU.
* \param[in] gpusWereDetected Whether compatible GPUs were detected on any node.
* \param[in] inputrec The user input.
* InconsistentInputError If the user requirements are inconsistent.
*/
bool decideWhetherToUseGpuForUpdate(bool isDomainDecomposition,
+ bool useGpuForPme,
bool useGpuForNonbonded,
+ bool useGpuForBufferOps,
TaskTarget updateTarget,
bool gpusWereDetected,
const t_inputrec &inputrec,