/*! \brief Set up flags that have the lifetime of the domain indicating what type of work is there to compute.
*/
-static void
-setupDomainLifetimeWorkload(DomainLifetimeWorkload *domainWork,
- const t_inputrec &inputrec,
+static DomainLifetimeWorkload
+setupDomainLifetimeWorkload(const t_inputrec &inputrec,
const t_forcerec &fr,
const pull_t *pull_work,
const gmx_edsam *ed,
const t_mdatoms &mdatoms,
const StepWorkload &stepWork)
{
+ DomainLifetimeWorkload domainWork;
// Note that haveSpecialForces is constant over the whole run
- domainWork->haveSpecialForces = haveSpecialForces(inputrec, *fr.forceProviders, pull_work, stepWork.computeForces, ed);
- domainWork->haveCpuBondedWork = haveCpuBondeds(fr);
- domainWork->haveGpuBondedWork = ((fr.gpuBonded != nullptr) && fr.gpuBonded->haveInteractions());
- domainWork->haveRestraintsWork = havePositionRestraints(idef, fcd);
- domainWork->haveCpuListedForceWork = haveCpuListedForces(fr, idef, fcd);
+ domainWork.haveSpecialForces = haveSpecialForces(inputrec, *fr.forceProviders, pull_work, stepWork.computeForces, ed);
+ domainWork.haveCpuBondedWork = haveCpuBondeds(fr);
+ domainWork.haveGpuBondedWork = ((fr.gpuBonded != nullptr) && fr.gpuBonded->haveInteractions());
+ domainWork.haveRestraintsWork = havePositionRestraints(idef, fcd);
+ domainWork.haveCpuListedForceWork = haveCpuListedForces(fr, idef, fcd);
// Note that haveFreeEnergyWork is constant over the whole run
- domainWork->haveFreeEnergyWork = (fr.efep != efepNO && mdatoms.nPerturbed != 0);
+ domainWork.haveFreeEnergyWork = (fr.efep != efepNO && mdatoms.nPerturbed != 0);
+ return domainWork;
}
/*! \brief Set up force flag stuct from the force bitmask.
*
- * \param[out] flags Force schedule flags
* \param[in] legacyFlags Force bitmask flags used to construct the new flags
* \param[in] isNonbondedOn Global override, if false forces to turn off all nonbonded calculation.
+ * \returns New Stepworkload description.
*/
-static void
-setupStepWorkload(StepWorkload *flags,
- const int legacyFlags,
+static StepWorkload
+setupStepWorkload(const int legacyFlags,
const bool isNonbondedOn)
{
- flags->stateChanged = ((legacyFlags & GMX_FORCE_STATECHANGED) != 0);
- flags->haveDynamicBox = ((legacyFlags & GMX_FORCE_DYNAMICBOX) != 0);
- flags->doNeighborSearch = ((legacyFlags & GMX_FORCE_NS) != 0);
- flags->computeVirial = ((legacyFlags & GMX_FORCE_VIRIAL) != 0);
- flags->computeEnergy = ((legacyFlags & GMX_FORCE_ENERGY) != 0);
- flags->computeForces = ((legacyFlags & GMX_FORCE_FORCES) != 0);
- flags->computeListedForces = ((legacyFlags & GMX_FORCE_LISTED) != 0);
- flags->computeNonbondedForces = ((legacyFlags & GMX_FORCE_NONBONDED) != 0) && isNonbondedOn;
- flags->computeDhdl = ((legacyFlags & GMX_FORCE_DHDL) != 0);
+ StepWorkload flags;
+ flags.stateChanged = ((legacyFlags & GMX_FORCE_STATECHANGED) != 0);
+ flags.haveDynamicBox = ((legacyFlags & GMX_FORCE_DYNAMICBOX) != 0);
+ flags.doNeighborSearch = ((legacyFlags & GMX_FORCE_NS) != 0);
+ flags.computeVirial = ((legacyFlags & GMX_FORCE_VIRIAL) != 0);
+ flags.computeEnergy = ((legacyFlags & GMX_FORCE_ENERGY) != 0);
+ flags.computeForces = ((legacyFlags & GMX_FORCE_FORCES) != 0);
+ flags.computeListedForces = ((legacyFlags & GMX_FORCE_LISTED) != 0);
+ flags.computeNonbondedForces = ((legacyFlags & GMX_FORCE_NONBONDED) != 0) && isNonbondedOn;
+ flags.computeDhdl = ((legacyFlags & GMX_FORCE_DHDL) != 0);
+ return flags;
}
{
legacyFlags &= ~GMX_FORCE_NONBONDED;
}
- setupStepWorkload(&runScheduleWork->stepWork, legacyFlags, fr->bNonbonded);
+ runScheduleWork->stepWork = setupStepWorkload(legacyFlags, fr->bNonbonded);
const gmx::StepWorkload &stepWork = runScheduleWork->stepWork;
{
// Need to run after the GPU-offload bonded interaction lists
// are set up to be able to determine whether there is bonded work.
- setupDomainLifetimeWorkload(&runScheduleWork->domainWork,
- *inputrec,
- *fr,
- pull_work,
- ed,
- top->idef,
- *fcd,
- *mdatoms,
- stepWork);
+ runScheduleWork->domainWork =
+ setupDomainLifetimeWorkload(*inputrec,
+ *fr,
+ pull_work,
+ ed,
+ top->idef,
+ *fcd,
+ *mdatoms,
+ stepWork);
wallcycle_start_nocount(wcycle, ewcNS);
wallcycle_sub_start(wcycle, ewcsNBS_SEARCH_LOCAL);
gmx_membed_t *membed,
gmx_walltime_accounting *walltime_accounting,
std::unique_ptr<StopHandlerBuilder> stopHandlerBuilder,
- bool doRerun,
- bool useGpuForUpdate) :
+ bool doRerun) :
fplog(fplog),
cr(cr),
ms(ms),
membed(membed),
walltime_accounting(walltime_accounting),
stopHandlerBuilder(std::move(stopHandlerBuilder)),
- doRerun(doRerun),
- useGpuForUpdate(useGpuForUpdate)
+ doRerun(doRerun)
{}
protected:
std::unique_ptr<StopHandlerBuilder> stopHandlerBuilder;
//! Whether we're doing a rerun.
bool doRerun;
- //! Whether we will use the GPU for calculating the update.
- bool useGpuForUpdate;
-
};
} // namespace gmx
#include "gromacs/mdtypes/mdrunoptions.h"
#include "gromacs/mdtypes/observableshistory.h"
#include "gromacs/mdtypes/pullhistory.h"
+#include "gromacs/mdtypes/simulation_workload.h"
#include "gromacs/mdtypes/state.h"
#include "gromacs/mdtypes/state_propagator_data_gpu.h"
#include "gromacs/modularsimulator/energyelement.h"
// 1. We have the useGpuForBufferOps variable set and available here and in do_force(...)
// 2. The proper GPU syncronization is introduced, so that the H2D and D2H data copies can be performed in the separate
// stream owned by the StatePropagatorDataGpu
- bool useGpuForPme = (fr->pmedata != nullptr) && (pme_run_mode(fr->pmedata) != PmeRunMode::CPU);
- bool useGpuForNonbonded = fr->nbv->useGpu();
+ const auto &simulationWork = runScheduleWork->simulationWork;
+ const bool useGpuForPme = simulationWork.usePmeGpu;
+ const bool useGpuForNonbonded = simulationWork.useGpuNonbonded;
// Temporary solution to make sure that the buffer ops are offloaded when update is offloaded
- bool useGpuForBufferOps = (getenv("GMX_USE_GPU_BUFFER_OPS") != nullptr);
+ const bool useGpuForBufferOps = simulationWork.useGpuBufferOps;
+ const bool useGpuForUpdate = simulationWork.useGpuUpdate;
if (useGpuForUpdate)
{
#include "gromacs/restraint/restraintpotential.h"
#include "gromacs/swap/swapcoords.h"
#include "gromacs/taskassignment/decidegpuusage.h"
+#include "gromacs/taskassignment/decidesimulationworkload.h"
#include "gromacs/taskassignment/resourcedivision.h"
#include "gromacs/taskassignment/taskassignment.h"
#include "gromacs/taskassignment/usergpuids.h"
// this data structure, but currently it's the easiest way to
// make it work.
MdrunScheduleWorkload runScheduleWork;
+ // Also populates the simulation constant workload description.
+ runScheduleWork.simulationWork = createSimulationWorkload(useGpuForNonbonded,
+ useGpuForPme, (pmeRunMode == PmeRunMode::GPU), useGpuForBonded, useGpuForUpdate);
+
GMX_ASSERT(stopHandlerBuilder_, "Runner must provide StopHandlerBuilder to simulator.");
SimulatorBuilder simulatorBuilder;
membed,
walltime_accounting,
std::move(stopHandlerBuilder_),
- doRerun,
- useGpuForUpdate);
+ doRerun);
simulator->run();
if (inputrec->bPull)
*/
class SimulationWorkload
{
+ public:
+ //! If we have calculation of short range nonbondeds on GPU
+ bool useGpuNonbonded = false;
+ //! If we have calculation of long range PME in GPU
+ bool usePmeGpu = false;
+ //! If PME FFT solving is done on GPU.
+ bool usePmeFftGpu = false;
+ //! If bonded interactions are calculated on GPU.
+ bool useGpuBonded = false;
+ //! If update and constraint solving is performed on GPU.
+ bool useGpuUpdate = false;
+ //! If buffer operations are performed on GPU.
+ bool useGpuBufferOps = false;
+ //! If domain decomposition halo exchange is performed on GPU.
+ bool useGpuHaloExchange = false;
+ //! If direct PP-PME communication between GPU is used.
+ bool useGpuPmePPCommunication = false;
+ //! If direct GPU-GPU communication is enabled.
+ bool useGpuDirectCommunication = false;
};
class MdrunScheduleWorkload
{
public:
//! Workload descriptor for information constant for an entire run
- gmx::SimulationWorkload simulationWork;
+ SimulationWorkload simulationWork;
//! Workload descriptor for information constant for an nstlist range of steps
- gmx::DomainLifetimeWorkload domainWork;
+ DomainLifetimeWorkload domainWork;
//! Workload descriptor for information that may change per-step
- gmx::StepWorkload stepWork;
+ StepWorkload stepWork;
};
} // namespace gmx
#
# This file is part of the GROMACS molecular simulation package.
#
-# Copyright (c) 2017, by the GROMACS development team, led by
+# Copyright (c) 2017,2019, 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.
gmx_add_libgromacs_sources(
decidegpuusage.cpp
+ decidesimulationworkload.cpp
findallgputasks.cpp
reportgpuusage.cpp
resourcedivision.cpp
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2019, 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.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \internal \file
+ * \brief
+ * Defines routine for building simulation workload task description.
+ *
+ * \author Paul Bauer <paul.bauer.q@gmail.com>
+ * \ingroup module_taskassignment
+ */
+#include "gmxpre.h"
+
+#include "decidesimulationworkload.h"
+
+#include "gromacs/taskassignment/taskassignment.h"
+#include "gromacs/utility/arrayref.h"
+
+namespace gmx
+{
+
+SimulationWorkload createSimulationWorkload(bool useGpuForNonbonded,
+ bool useGpuForPme,
+ bool useGpuForPmeFft,
+ bool useGpuForBonded,
+ bool useGpuForUpdateConstraints)
+{
+ SimulationWorkload simulationWorkload {
+ useGpuForNonbonded,
+ useGpuForPme,
+ useGpuForPmeFft,
+ useGpuForBonded,
+ useGpuForUpdateConstraints,
+ (getenv("GMX_USE_GPU_BUFFER_OPS") != nullptr),
+ (getenv("GMX_GPU_DD_COMMS") != nullptr),
+ (getenv("GMX_GPU_PME_PP_COMMS") != nullptr),
+ (getenv("GMX_GPU_DD_COMMS") != nullptr) || (getenv("GMX_GPU_PME_PP_COMMS") != nullptr)
+ };
+
+ return simulationWorkload;
+}
+
+} // namespace gmx
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2019, 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.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \internal
+ * \file
+ * \brief Declares routine for deciding simulation workload based on GPU tasks.
+ *
+ * \author Paul Bauer <paul.bauer.q@gmail.com>
+ * \ingroup module_taskassignment
+ */
+#ifndef GMX_TASKASSIGNMENT_DECIDESIMULATIONWORKLOAD_H
+#define GMX_TASKASSIGNMENT_DECIDESIMULATIONWORKLOAD_H
+
+#include <vector>
+
+#include "gromacs/mdtypes/simulation_workload.h"
+
+namespace gmx
+{
+
+/*! \brief
+ * Build datastructure that contains decisions whether to run different workload
+ * task on GPUs.
+ *
+ * \param[in] useGpuForNonbonded If we have short-range nonbonded interactions
+ * calculations on GPU(s).
+ * \param[in] useGpuForPme If long range PME interactions are calculated on GPU(s).
+ * \param[in] useGpuForPmeFft If FFT solving for PME is done on the GPU.
+ * \param[in] useGpuForBonded If bonded interactions are calculated on GPU(s).
+ * \param[in] useGpuForUpdateConstraints If coordinate update and constraint solving is performed on
+ * GPU(s).
+ * \returns Simulation lifetime constant workload description.
+ */
+SimulationWorkload createSimulationWorkload(bool useGpuForNonbonded,
+ bool useGpuForPme,
+ bool useGpuForPmeFft,
+ bool useGpuForBonded,
+ bool useGpuForUpdateConstraints);
+
+
+} // namespace gmx
+
+#endif
//! Short-ranged interactions.
Nonbonded,
//! Long-ranged interactions.
- Pme
+ Pme,
+ //! Number of possible tasks.
+ Count
};
/*! \libinternal