#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/gmxassert.h"
#include "gromacs/utility/logger.h"
+#include "gromacs/utility/physicalnodecommunicator.h"
#include "gromacs/utility/stringutil.h"
{
public:
//! Constructor
- SingleRankChecker() : value_(false), reasons_() {}
+ SingleRankChecker() : value_(false) {}
/*! \brief Call this function for each possible condition
under which a single rank is required, along with a string
describing the constraint when it is applied. */
if (pmeOnGpu)
{
GMX_RELEASE_ASSERT((EEL_PME(inputrec->coulombtype) || EVDW_PME(inputrec->vdwtype)) &&
- pme_gpu_supports_input(inputrec, nullptr),
+ pme_gpu_supports_build(nullptr) && pme_gpu_supports_input(inputrec, nullptr),
"PME can't be on GPUs unless we are using PME");
// PME on GPUs supports a single PME rank with PP running on the same or few other ranks.
}
}
-void checkAndUpdateRequestedNumOpenmpThreads(gmx_hw_opt_t *hw_opt,
- const gmx_hw_info_t &hwinfo,
- const t_commrec *cr,
- PmeRunMode pmeRunMode,
- const gmx_mtop_t &mtop)
+void checkAndUpdateRequestedNumOpenmpThreads(gmx_hw_opt_t *hw_opt,
+ const gmx_hw_info_t &hwinfo,
+ const t_commrec *cr,
+ const gmx_multisim_t *ms,
+ int numRanksOnThisNode,
+ PmeRunMode pmeRunMode,
+ const gmx_mtop_t &mtop)
{
#if GMX_THREAD_MPI
GMX_RELEASE_ASSERT(hw_opt->nthreads_tmpi >= 1, "Must have at least one thread-MPI rank");
* all detected ncore_tot physical cores. We are currently not
* checking for that here.
*/
- int numRanksTot = cr->nnodes*(MULTISIM(cr) ? cr->ms->nsim : 1);
+ int numRanksTot = cr->nnodes*(isMultiSim(ms) ? ms->nsim : 1);
int numAtomsPerRank = mtop.natoms/cr->nnodes;
int numCoresPerRank = hwinfo.ncore_tot/numRanksTot;
if (numAtomsPerRank < c_numAtomsPerCoreSquaredSmtThreshold*gmx::square(numCoresPerRank))
{
- int numRanksInThisNode = (cr ? cr->nrank_intranode : 1);
/* Choose one OpenMP thread per physical core */
- hw_opt->nthreads_omp = std::max(1, hwinfo.hardwareTopology->numberOfCores()/numRanksInThisNode);
+ hw_opt->nthreads_omp = std::max(1, hwinfo.hardwareTopology->numberOfCores()/numRanksOnThisNode);
}
}
}
}
-void checkHardwareOversubscription(int numThreadsOnThisRank,
- const gmx::HardwareTopology &hwTop,
- const t_commrec *cr,
- const gmx::MDLogger &mdlog)
+namespace gmx
{
- if (hwTop.supportLevel() < gmx::HardwareTopology::SupportLevel::LogicalProcessorCount)
+
+void checkHardwareOversubscription(int numThreadsOnThisRank,
+ int rank,
+ const HardwareTopology &hwTop,
+ const PhysicalNodeCommunicator &comm,
+ const MDLogger &mdlog)
+{
+ if (hwTop.supportLevel() < HardwareTopology::SupportLevel::LogicalProcessorCount)
{
/* There is nothing we can check */
return;
}
- int numRanksOnThisNode = 1;
+ int numRanksOnThisNode = comm.size_;
int numThreadsOnThisNode = numThreadsOnThisRank;
-#if GMX_MPI
- if (PAR(cr) || MULTISIM(cr))
+ /* Avoid MPI calls with uninitialized thread-MPI communicators */
+ if (comm.size_ > 1)
{
+#if GMX_MPI
/* Count the threads within this physical node */
- MPI_Comm_size(cr->mpi_comm_physicalnode, &numRanksOnThisNode);
- MPI_Allreduce(&numThreadsOnThisRank, &numThreadsOnThisNode, 1, MPI_INT, MPI_SUM, cr->mpi_comm_physicalnode);
- }
+ MPI_Allreduce(&numThreadsOnThisRank, &numThreadsOnThisNode, 1, MPI_INT, MPI_SUM, comm.comm_);
#endif
+ }
if (numThreadsOnThisNode > hwTop.machine().logicalProcessorCount)
{
std::string mesg = "WARNING: ";
if (GMX_LIB_MPI)
{
- mesg += gmx::formatString("On rank %d: o", cr->sim_nodeid);
+ mesg += formatString("On rank %d: o", rank);
}
else
{
mesg += "O";
}
- mesg += gmx::formatString("versubscribing the available %d logical CPU cores", hwTop.machine().logicalProcessorCount);
+ mesg += formatString("versubscribing the available %d logical CPU cores", hwTop.machine().logicalProcessorCount);
if (GMX_LIB_MPI)
{
mesg += " per node";
}
- mesg += gmx::formatString(" with %d ", numThreadsOnThisNode);
+ mesg += formatString(" with %d ", numThreadsOnThisNode);
if (numRanksOnThisNode == numThreadsOnThisNode)
{
if (GMX_THREAD_MPI)
GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted(mesg.c_str());
}
}
+
+} // namespace