The CUDA LINCS code has a limit on the number of coupled constraints.
This is now checked during in the GPU update decision function.
Change-Id: I5eee96b82f3f5196b64a5e815eae78d4ed367a80
#include "gromacs/pbcutil/pbc.h"
#include "gromacs/pbcutil/pbc_aiuc_cuda.cuh"
#include "gromacs/topology/ifunc.h"
+#include "gromacs/topology/topology.h"
namespace gmx
{
return numCoupledConstraints;
}
+bool LincsCuda::isNumCoupledConstraintsSupported(const gmx_mtop_t& mtop)
+{
+ for (const gmx_moltype_t& molType : mtop.moltype)
+ {
+ ArrayRef<const int> iatoms = molType.ilist[F_CONSTR].iatoms;
+ const auto atomsAdjacencyList = constructAtomsAdjacencyList(molType.atoms.nr, iatoms);
+ // Compute, how many constraints are coupled to each constraint
+ const auto numCoupledConstraints = countNumCoupledConstraints(iatoms, atomsAdjacencyList);
+ for (const int numCoupled : numCoupledConstraints)
+ {
+ if (numCoupled > c_threadsPerBlock)
+ {
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
void LincsCuda::set(const t_idef& idef, const t_mdatoms& md)
{
int numAtoms = md.nr;
*/
void setPbc(const t_pbc* pbc);
+ /*! \brief
+ * Returns whether the maximum number of coupled constraints is supported
+ * by the CUDA LINCS code.
+ *
+ * \param[in] mtop The molecular topology
+ */
+ static bool isNumCoupledConstraintsSupported(const gmx_mtop_t& mtop);
private:
//! CUDA stream
*/
GpuEventSynchronizer* getCoordinatesReadySync();
+ /*! \brief
+ * Returns whether the maximum number of coupled constraints is supported
+ * by the CUDA LINCS code.
+ *
+ * \param[in] mtop The molecular topology
+ */
+ static bool isNumCoupledConstraintsSupported(const gmx_mtop_t& mtop);
+
private:
class Impl;
gmx::PrivateImplPointer<Impl> impl_;
return nullptr;
}
+bool UpdateConstrainCuda::isNumCoupledConstraintsSupported(const gmx_mtop_t& /* mtop */)
+{
+ return false;
+}
+
} // namespace gmx
#endif /* GMX_GPU != GMX_GPU_CUDA */
return impl_->getCoordinatesReadySync();
}
+bool UpdateConstrainCuda::isNumCoupledConstraintsSupported(const gmx_mtop_t& mtop)
+{
+ return LincsCuda::isNumCoupledConstraintsSupported(mtop);
+}
+
} // namespace gmx
*/
GpuEventSynchronizer* getCoordinatesReadySync();
+ /*! \brief
+ * Returns whether the maximum number of coupled constraints is supported
+ * by the CUDA LINCS code.
+ *
+ * \param[in] mtop The molecular topology
+ */
+ static bool isNumCoupledConstraintsSupported(const gmx_mtop_t& mtop);
+
private:
//! CUDA stream
CommandStream commandStream_ = nullptr;
{
useGpuForUpdate = decideWhetherToUseGpuForUpdate(
devFlags.forceGpuUpdateDefaultOn, useDomainDecomposition, useGpuForPme,
- useGpuForNonbonded, updateTarget, gpusWereDetected, *inputrec,
- gmx_mtop_interaction_count(mtop, IF_VSITE) > 0, doEssentialDynamics,
+ useGpuForNonbonded, updateTarget, gpusWereDetected, *inputrec, mtop, doEssentialDynamics,
gmx_mtop_ftype_count(mtop, F_ORIRES) > 0, replExParams.exchangeInterval > 0);
}
GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR
#include "gromacs/hardware/hardwaretopology.h"
#include "gromacs/hardware/hw_info.h"
#include "gromacs/mdlib/gmx_omp_nthreads.h"
+#include "gromacs/mdlib/update_constrain_cuda.h"
#include "gromacs/mdtypes/commrec.h"
#include "gromacs/mdtypes/inputrec.h"
#include "gromacs/mdtypes/md_enums.h"
#include "gromacs/mdtypes/mdrunoptions.h"
#include "gromacs/taskassignment/taskassignment.h"
+#include "gromacs/topology/mtop_util.h"
#include "gromacs/topology/topology.h"
#include "gromacs/utility/baseversion.h"
#include "gromacs/utility/exceptions.h"
const TaskTarget updateTarget,
const bool gpusWereDetected,
const t_inputrec& inputrec,
- const bool haveVSites,
+ const gmx_mtop_t& mtop,
const bool useEssentialDynamics,
const bool doOrientationRestraints,
const bool useReplicaExchange)
// The graph is needed, but not supported
errorMessage += "Ewald surface correction is not supported.\n";
}
- if (haveVSites)
+ if (gmx_mtop_interaction_count(mtop, IF_VSITE) > 0)
{
errorMessage += "Virtual sites are not supported.\n";
}
errorMessage += "Swapping the coordinates is not supported.\n";
}
- // \todo Check for coupled constraint block size restriction needs to be added
- // when update auto chooses GPU in some cases. Currently exceeding the restriction
- // triggers a fatal error during LINCS setup.
+ // TODO: F_CONSTRNC is only unsupported, because isNumCoupledConstraintsSupported()
+ // does not support it, the actual CUDA LINCS code does support it
+ if (gmx_mtop_ftype_count(mtop, F_CONSTRNC) > 0)
+ {
+ errorMessage += "Non-connecting constraints are not supported";
+ }
+ if (!UpdateConstrainCuda::isNumCoupledConstraintsSupported(mtop))
+ {
+ errorMessage +=
+ "The number of coupled constraints is higher than supported in the CUDA LINCS "
+ "code.\n";
+ }
if (!errorMessage.empty())
{
* \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.
- * \param[in] haveVSites If there are virtual sites in the system.
+ * \param[in] mtop The global topology.
* \param[in] useEssentialDynamics If essential dynamics is active.
* \param[in] doOrientationRestraints If orientation restraints are enabled.
* \param[in] useReplicaExchange If this is a REMD simulation.
TaskTarget updateTarget,
bool gpusWereDetected,
const t_inputrec& inputrec,
- bool haveVSites,
+ const gmx_mtop_t& mtop,
bool useEssentialDynamics,
bool doOrientationRestraints,
bool useReplicaExchange);