/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019, by the GROMACS development team, led by
+ * Copyright (c) 2019,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#define GMX_MDTYPES_LOCALITY_H
#include "gromacs/utility/enumerationhelpers.h"
+#include "gromacs/utility/exceptions.h"
namespace gmx
{
{ "local", "non-local" }
};
+/*! \brief Convert atom locality to interaction locality.
+ *
+ * In the current implementation the this is straightforward conversion:
+ * local to local, non-local to non-local.
+ *
+ * \param[in] atomLocality Atom locality specifier
+ * \returns Interaction locality corresponding to the atom locality passed.
+ */
+static inline InteractionLocality atomToInteractionLocality(const AtomLocality atomLocality)
+{
+
+ /* determine interaction locality from atom locality */
+ if (atomLocality == AtomLocality::Local)
+ {
+ return InteractionLocality::Local;
+ }
+ else if (atomLocality == AtomLocality::NonLocal)
+ {
+ return InteractionLocality::NonLocal;
+ }
+ else
+ {
+ GMX_THROW(gmx::InconsistentInputError(
+ "Only Local and NonLocal atom locities can be converted to interaction locality."));
+ }
+}
+
} // namespace gmx
#endif // GMX_MDTYPES_LOCALITY_H
const int numColumns = grid.numColumns();
const int cellOffset = grid.cellOffset();
const int numAtomsPerCell = grid.numAtomsPerCell();
- Nbnxm::InteractionLocality interactionLoc = gpuAtomToInteractionLocality(locality);
+ Nbnxm::InteractionLocality interactionLoc = atomToInteractionLocality(locality);
const DeviceStream& deviceStream = *nb->deviceStreams[interactionLoc];
}
/* determine interaction locality from atom locality */
- const InteractionLocality iLocality = gpuAtomToInteractionLocality(atomLocality);
+ const InteractionLocality iLocality = atomToInteractionLocality(atomLocality);
const bool didEnergyKernels = stepWork.computeEnergy;
/* only increase counter once (at local F wait) */
GMX_ASSERT(nb, "Need a valid nbnxn_gpu object");
/* determine interaction locality from atom locality */
- const InteractionLocality iLocality = gpuAtomToInteractionLocality(aloc);
+ const InteractionLocality iLocality = atomToInteractionLocality(aloc);
// Transfers are launched and therefore need to be waited on if:
// We skip when during the non-local phase there was actually no work to do.
// This is consistent with nbnxn_gpu_launch_kernel but it also considers possible
// bonded GPU work.
- if ((iLocality == InteractionLocality::Local) || haveGpuShortRangeWork(*nb, iLocality))
+ if ((iLocality == InteractionLocality::Local) || haveGpuShortRangeWork(nb, iLocality))
{
// Query the state of the GPU stream and return early if we're not done
if (completionKind == GpuTaskCompletion::Check)
gmx::ArrayRef<gmx::RVec> shiftForces,
gmx_wallcycle* wcycle)
{
- auto cycleCounter = (gpuAtomToInteractionLocality(aloc) == InteractionLocality::Local)
+ auto cycleCounter = (atomToInteractionLocality(aloc) == InteractionLocality::Local)
? ewcWAIT_GPU_NB_L
: ewcWAIT_GPU_NB_NL;
return (iloc == InteractionLocality::NonLocal && nb.plist[iloc]->nsci == 0);
}
-/*! \brief Convert atom locality to interaction locality.
- *
- * In the current implementation the this is straightforward conversion:
- * local to local, non-local to non-local.
- *
- * \param[in] atomLocality Atom locality specifier
- * \returns Interaction locality corresponding to the atom locality passed.
- */
-static inline InteractionLocality gpuAtomToInteractionLocality(const AtomLocality atomLocality)
-{
-
- /* determine interaction locality from atom locality */
- if (atomLocality == AtomLocality::Local)
- {
- return InteractionLocality::Local;
- }
- else if (atomLocality == AtomLocality::NonLocal)
- {
- return InteractionLocality::NonLocal;
- }
- else
- {
- GMX_THROW(gmx::InconsistentInputError(
- "Only Local and NonLocal atom locities can be converted to interaction locality."));
- }
-}
-
-/*! \brief Returns true if there is GPU short-range work for the given interaction locality.
- *
- * Note that as, unlike nonbonded tasks, bonded tasks are not split into local/nonlocal,
- * and therefore if there are GPU offloaded bonded interactions, this function will return
- * true for all interaction localities.
- *
- * \param[inout] nb Pointer to the nonbonded GPU data structure
- * \param[in] iLocality Interaction locality identifier
- */
-static inline bool haveGpuShortRangeWork(const NbnxmGpu& nb, const gmx::InteractionLocality iLocality)
-{
- return nb.haveWork[iLocality];
-}
-
/*! \brief Calculate atom range and return start index and length.
*
* \param[in] atomData Atom descriptor data structure
/* Skip the reduction if there was no short-range GPU work to do
* (either NB or both NB and bonded work). */
- if (!pairlistIsSimple() && !Nbnxm::haveGpuShortRangeWork(gpu_nbv, locality))
+ if (!pairlistIsSimple() && !Nbnxm::haveGpuShortRangeWork(gpu_nbv, atomToInteractionLocality(locality)))
{
return;
}
const gmx::GpuBonded gmx_unused* gpuBonded,
gmx::InteractionLocality gmx_unused iLocality) GPU_FUNC_TERM;
-/*! \brief Returns true if there is GPU short-range work for the given atom locality.
+/*! \brief Returns true if there is GPU short-range work for the given interaction locality.
*
* Note that as, unlike nonbonded tasks, bonded tasks are not split into local/nonlocal,
* and therefore if there are GPU offloaded bonded interactions, this function will return
* true for both local and nonlocal atom range.
*
- * \param[inout] nb Pointer to the nonbonded GPU data structure
- * \param[in] aLocality Atom locality identifier
+ * \param[inout] nb Pointer to the nonbonded GPU data structure
+ * \param[in] interactionLocality Interaction locality identifier
+ *
+ * \return Whether there is short range work for a given locality.
*/
GPU_FUNC_QUALIFIER
-bool haveGpuShortRangeWork(const NbnxmGpu gmx_unused* nb, gmx::AtomLocality gmx_unused aLocality)
+bool haveGpuShortRangeWork(const NbnxmGpu gmx_unused* nb, gmx::InteractionLocality gmx_unused interactionLocality)
GPU_FUNC_TERM_WITH_RETURN(false);
/*! \brief sync CPU thread on coordinate copy to device
|| (gpuBonded != nullptr && gpuBonded->haveInteractions()));
}
-bool haveGpuShortRangeWork(const NbnxmGpu* nb, const gmx::AtomLocality aLocality)
+bool haveGpuShortRangeWork(const NbnxmGpu* nb, const gmx::InteractionLocality interactionLocality)
{
GMX_ASSERT(nb, "Need a valid nbnxn_gpu object");
- return haveGpuShortRangeWork(*nb, gpuAtomToInteractionLocality(aLocality));
+ return nb->haveWork[interactionLocality];
}
/*! \brief
GMX_ASSERT(nb, "Need a valid nbnxn_gpu object");
/* determine interaction locality from atom locality */
- const InteractionLocality iloc = gpuAtomToInteractionLocality(atomLocality);
+ const InteractionLocality iloc = atomToInteractionLocality(atomLocality);
GMX_ASSERT(iloc == InteractionLocality::Local
|| (iloc == InteractionLocality::NonLocal && nb->bNonLocalStreamDoneMarked == false),
"Non-local stream is indicating that the copy back event is enqueued at the "
const DeviceStream& deviceStream = *nb->deviceStreams[iloc];
/* don't launch non-local copy-back if there was no non-local work to do */
- if ((iloc == InteractionLocality::NonLocal) && !haveGpuShortRangeWork(*nb, iloc))
+ if ((iloc == InteractionLocality::NonLocal) && !haveGpuShortRangeWork(nb, iloc))
{
/* TODO An alternative way to signal that non-local work is
complete is to use a clEnqueueMarker+clEnqueueBarrier
{
GMX_ASSERT(nb, "Need a valid nbnxn_gpu object");
- const InteractionLocality iloc = gpuAtomToInteractionLocality(atomLocality);
+ const InteractionLocality iloc = atomToInteractionLocality(atomLocality);
NBAtomData* adat = nb->atdat;
gpu_plist* plist = nb->plist[iloc];
we always call the local local x+q copy (and the rest of the local
work in nbnxn_gpu_launch_kernel().
*/
- if ((iloc == InteractionLocality::NonLocal) && !haveGpuShortRangeWork(*nb, iloc))
+ if ((iloc == InteractionLocality::NonLocal) && !haveGpuShortRangeWork(nb, iloc))
{
plist->haveFreshList = false;