#include "gromacs/utility/stringutil.h"
#include "biasgrid.h"
+#include "biassharing.h"
#include "pointstate.h"
namespace gmx
namespace
{
-/*! \brief
- * Sum an array over all simulations on the master rank of each simulation.
- *
- * \param[in,out] arrayRef The data to sum.
- * \param[in] multiSimComm Struct for multi-simulation communication.
- */
-void sumOverSimulations(gmx::ArrayRef<int> arrayRef, const gmx_multisim_t* multiSimComm)
-{
- gmx_sumi_sim(arrayRef.size(), arrayRef.data(), multiSimComm);
-}
-
-/*! \brief
- * Sum an array over all simulations on the master rank of each simulation.
- *
- * \param[in,out] arrayRef The data to sum.
- * \param[in] multiSimComm Struct for multi-simulation communication.
- */
-void sumOverSimulations(gmx::ArrayRef<double> arrayRef, const gmx_multisim_t* multiSimComm)
-{
- gmx_sumd_sim(arrayRef.size(), arrayRef.data(), multiSimComm);
-}
-
-/*! \brief
- * Sum an array over all simulations on all ranks of each simulation.
- *
- * This assumes the data is identical on all ranks within each simulation.
- *
- * \param[in,out] arrayRef The data to sum.
- * \param[in] commRecord Struct for intra-simulation communication.
- * \param[in] multiSimComm Struct for multi-simulation communication.
- */
-template<typename T>
-void sumOverSimulations(gmx::ArrayRef<T> arrayRef, const t_commrec* commRecord, const gmx_multisim_t* multiSimComm)
-{
- if (MASTER(commRecord))
- {
- sumOverSimulations(arrayRef, multiSimComm);
- }
- if (commRecord->nnodes > 1)
- {
- gmx_bcast(arrayRef.size() * sizeof(T), arrayRef.data(), commRecord->mpi_comm_mygroup);
- }
-}
-
/*! \brief
* Sum PMF over multiple simulations, when requested.
*
* \param[in,out] pointState The state of the points in the bias.
* \param[in] numSharedUpdate The number of biases sharing the histogram.
- * \param[in] commRecord Struct for intra-simulation communication.
- * \param[in] multiSimComm Struct for multi-simulation communication.
+ * \param[in] biasSharing Object for sharing bias data over multiple simulations
+ * \param[in] biasIndex Index of this bias in the total list of biases in this simulation
*/
-void sumPmf(gmx::ArrayRef<PointState> pointState,
- int numSharedUpdate,
- const t_commrec* commRecord,
- const gmx_multisim_t* multiSimComm)
+void sumPmf(gmx::ArrayRef<PointState> pointState, int numSharedUpdate, const BiasSharing* biasSharing, const int biasIndex)
{
if (numSharedUpdate == 1)
{
return;
}
- GMX_ASSERT(multiSimComm != nullptr && numSharedUpdate % multiSimComm->numSimulations_ == 0,
+ GMX_ASSERT(biasSharing != nullptr
+ && numSharedUpdate % biasSharing->numSharingSimulations(biasIndex) == 0,
"numSharedUpdate should be a multiple of multiSimComm->numSimulations_");
- GMX_ASSERT(numSharedUpdate == multiSimComm->numSimulations_,
+ GMX_ASSERT(numSharedUpdate == biasSharing->numSharingSimulations(biasIndex),
"Sharing within a simulation is not implemented (yet)");
std::vector<double> buffer(pointState.size());
buffer[i] = pointState[i].inTargetRegion() ? std::exp(pointState[i].logPmfSum()) : 0;
}
- sumOverSimulations(gmx::ArrayRef<double>(buffer), commRecord, multiSimComm);
+ biasSharing->sumOverSharingSimulations(gmx::ArrayRef<double>(buffer), biasIndex);
/* Take log again to get (non-normalized) PMF */
double normFac = 1.0 / numSharedUpdate;
{
double freeEnergyWeights = 0;
const GridPoint& point = grid.point(m);
- for (auto& neighbor : point.neighbor)
+ for (const auto& neighbor : point.neighbor)
{
/* Do not convolve the bias along a lambda axis - only use the pmf from the current point */
if (!pointsHaveDifferentLambda(grid, m, neighbor))
/* Sum up the histograms and get their normalization */
double sumVisits = 0;
double sumWeights = 0;
- for (auto& pointState : points_)
+ for (const auto& pointState : points_)
{
if (pointState.inTargetRegion())
{
/* For each neighbor point of the center point, refresh its state by adding the results of all past, skipped updates. */
const std::vector<int>& neighbors = grid.point(coordState_.gridpointIndex()).neighbor;
- for (auto& neighbor : neighbors)
+ for (const auto& neighbor : neighbors)
{
bool didUpdate = points_[neighbor].performPreviouslySkippedUpdates(
params, histogramSize_.numUpdates(), weightHistScaling, logPmfsumScaling);
*
* \param[in,out] updateList Update list for this simulation (assumed >= npoints long).
* \param[in] numPoints Total number of points.
- * \param[in] commRecord Struct for intra-simulation communication.
- * \param[in] multiSimComm Struct for multi-simulation communication.
+ * \param[in] biasSharing Object for sharing bias data over multiple simulations
+ * \param[in] biasIndex Index of this bias in the total list of biases in this simulation
*/
-void mergeSharedUpdateLists(std::vector<int>* updateList,
- int numPoints,
- const t_commrec* commRecord,
- const gmx_multisim_t* multiSimComm)
+void mergeSharedUpdateLists(std::vector<int>* updateList,
+ int numPoints,
+ const BiasSharing& biasSharing,
+ const int biasIndex)
{
std::vector<int> numUpdatesOfPoint;
}
/* Sum over the sims to get all the flagged points */
- sumOverSimulations(arrayRefFromArray(numUpdatesOfPoint.data(), numPoints), commRecord, multiSimComm);
+ biasSharing.sumOverSharingSimulations(arrayRefFromArray(numUpdatesOfPoint.data(), numPoints), biasIndex);
/* Collect the indices of the flagged points in place. The resulting array will be the merged update list.*/
updateList->clear();
* \param[in] grid The AWH bias.
* \param[in] points The point state.
* \param[in] originUpdatelist The origin of the rectangular region that has been sampled since
- * last update. \param[in] endUpdatelist The end of the rectangular that has been sampled since
- * last update. \param[in,out] updateList Local update list to set (assumed >= npoints long).
+ * last update.
+ * \param[in] endUpdatelist The end of the rectangular that has been sampled since
+ * last update.
+ * \param[in,out] updateList Local update list to set (assumed >= npoints long).
*/
void makeLocalUpdateList(const BiasGrid& grid,
ArrayRef<const PointState> points,
* \param[in,out] pointState The state of the points in the bias.
* \param[in,out] weightSumCovering The weights for checking covering.
* \param[in] numSharedUpdate The number of biases sharing the histrogram.
- * \param[in] commRecord Struct for intra-simulation communication.
- * \param[in] multiSimComm Struct for multi-simulation communication.
- * \param[in] localUpdateList List of points with data.
+ * \param[in] biasSharing Object for sharing bias data over multiple simulations
+ * \param[in] biasIndex Index of this bias in the total list of biases in this
+ * simulation \param[in] localUpdateList List of points with data.
*/
void sumHistograms(gmx::ArrayRef<PointState> pointState,
gmx::ArrayRef<double> weightSumCovering,
int numSharedUpdate,
- const t_commrec* commRecord,
- const gmx_multisim_t* multiSimComm,
+ const BiasSharing* biasSharing,
+ const int biasIndex,
const std::vector<int>& localUpdateList)
{
/* The covering checking histograms are added before summing over simulations, so that the
/* Sum histograms over multiple simulations if needed. */
if (numSharedUpdate > 1)
{
- GMX_ASSERT(numSharedUpdate == multiSimComm->numSimulations_,
+ GMX_ASSERT(numSharedUpdate == biasSharing->numSharingSimulations(biasIndex),
"Sharing within a simulation is not implemented (yet)");
/* Collect the weights and counts in linear arrays to be able to use gmx_sumd_sim. */
coordVisits[localIndex] = ps.numVisitsIteration();
}
- sumOverSimulations(gmx::ArrayRef<double>(weightSum), commRecord, multiSimComm);
- sumOverSimulations(gmx::ArrayRef<double>(coordVisits), commRecord, multiSimComm);
+ biasSharing->sumOverSharingSimulations(gmx::ArrayRef<double>(weightSum), biasIndex);
+ biasSharing->sumOverSharingSimulations(gmx::ArrayRef<double>(coordVisits), biasIndex);
/* Transfer back the result */
for (size_t localIndex = 0; localIndex < localUpdateList.size(); localIndex++)
bool BiasState::isSamplingRegionCovered(const BiasParams& params,
ArrayRef<const DimParams> dimParams,
- const BiasGrid& grid,
- const t_commrec* commRecord,
- const gmx_multisim_t* multiSimComm) const
+ const BiasGrid& grid) const
{
/* Allocate and initialize arrays: one for checking visits along each dimension,
one for keeping track of which points to check and one for the covered points.
/* For multiple dimensions this may not be the best way to do it. */
for (int d = 0; d < grid.numDimensions(); d++)
{
- sumOverSimulations(
+ biasSharing_->sumOverSharingSimulations(
gmx::arrayRefFromArray(checkDim[d].covered.data(), grid.axis(d).numPoints()),
- commRecord,
- multiSimComm);
+ params.biasIndex);
}
}
void BiasState::updateFreeEnergyAndAddSamplesToHistogram(ArrayRef<const DimParams> dimParams,
const BiasGrid& grid,
const BiasParams& params,
- const t_commrec* commRecord,
- const gmx_multisim_t* multiSimComm,
double t,
int64_t step,
FILE* fplog,
makeLocalUpdateList(grid, points_, originUpdatelist_, endUpdatelist_, updateList);
if (params.numSharedUpdate > 1)
{
- mergeSharedUpdateLists(updateList, points_.size(), commRecord, multiSimComm);
+ mergeSharedUpdateLists(updateList, points_.size(), *biasSharing_, params.biasIndex);
}
/* Reset the range for the next update */
resetLocalUpdateRange(grid);
/* Add samples to histograms for all local points and sync simulations if needed */
- sumHistograms(points_, weightSumCovering_, params.numSharedUpdate, commRecord, multiSimComm, *updateList);
+ sumHistograms(points_, weightSumCovering_, params.numSharedUpdate, biasSharing_, params.biasIndex, *updateList);
- sumPmf(points_, params.numSharedUpdate, commRecord, multiSimComm);
+ sumPmf(points_, params.numSharedUpdate, biasSharing_, params.biasIndex);
/* Renormalize the free energy if values are too large. */
bool needToNormalizeFreeEnergy = false;
if (inInitialStage())
{
detectedCovering =
- (params.isCheckCoveringStep(step)
- && isSamplingRegionCovered(params, dimParams, grid, commRecord, multiSimComm));
+ (params.isCheckCoveringStep(step) && isSamplingRegionCovered(params, dimParams, grid));
}
/* The weighthistogram size after this update. */
BiasState::BiasState(const AwhBiasParams& awhBiasParams,
double histogramSizeInitial,
ArrayRef<const DimParams> dimParams,
- const BiasGrid& grid) :
+ const BiasGrid& grid,
+ const BiasSharing* biasSharing) :
coordState_(awhBiasParams, dimParams, grid),
points_(grid.numPoints()),
weightSumCovering_(grid.numPoints()),
- histogramSize_(awhBiasParams, histogramSizeInitial)
+ histogramSize_(awhBiasParams, histogramSizeInitial),
+ biasSharing_(biasSharing)
{
/* The minimum and maximum multidimensional point indices that are affected by the next update */
for (size_t d = 0; d < dimParams.size(); d++)