achieved for a small number of processors. The scaling will depend
a lot on the algorithms used. Also, different algorithms can have different
restrictions on the interaction ranges between atoms.
-In {\gromacs} we have two types of parallelization: particle decomposition
-and domain decomposition. Particle decomposition is only useful for
-a few special cases. Domain decomposition, which is the default algorithm,
-will always be faster and scale better.
-
-\section{Particle decomposition\index{particle decomposition}}
-Particle decomposition, also called \index{force decomposition},
-is the simplest type of decomposition. At the start of the simulation,
-particles are assigned to processors. Then forces between particles
-need to be assigned to processors such that the force load is evenly balanced.
-This decomposition requires that each processor know the coordinates
-of at least half of the particles in the system.
-Thus for a high number of processors $N$, about $N \times N/2$ coordinates
-need to be communicated. Because of this quadratic relation
-particle decomposition does not scale well.
-
-Particle decomposition was the only method available before version 4
-of {\gromacs}. Now it is only useful in cases where domain decomposition
-does not work, such as systems with long-range bonded interactions,
-especially NMR distance or orientation restraints.
-With particle decomposition only whole molecules can be assigned to a processor.
\section{Domain decomposition\index{domain decomposition}}
Since most interactions in molecular simulations are local,
\item {\tt GMX_ALLOW_CPT_MISMATCH}: when set, runs will not exit if the
ensemble set in the {\tt .tpr} file does not match that of the
{\tt .cpt} file.
-\item {\tt GMX_CAPACITY}: the maximum capacity of charge groups per
- processor when using particle decomposition.
\item {\tt GMX_CUDA_NB_EWALD_TWINCUT}: force the use of twin-range cutoff kernel even if {\tt rvdw} =
{\tt rcoulomb} after PP-PME load balancing. The switch to twin-range kernels is automated,
so this variable should be used only for benchmarking.
<dt><b>no</b></dt>
<dd>Use no periodic boundary conditions, ignore the box.
To simulate without cut-offs, set all cut-offs to 0 and <b>nstlist</b><tt>=0</tt>.
-For best performance without cut-offs, use <b>nstlist</b><tt>=0</tt>,
-<b>ns-type</b><tt>=simple</tt>
-and particle decomposition instead of domain decomposition.</dd>
+For best performance without cut-offs on a single MPI rank,
+use <b>nstlist</b><tt>=0</tt>, <b>ns-type</b><tt>=simple</tt></dd>
<dt><b>xy</b></dt>
<dd>Use periodic boundary conditions in x and y directions only.
This works only with <b>ns-type</b><tt>=grid</tt> and can be used
#include "smalloc.h"
#include "names.h"
#include "gromacs/fileio/confio.h"
-#include "mvdata.h"
#include "txtdump.h"
#include "vec.h"
#include <time.h>
matrix fit_rotmat; /* ... and rotation from fit to reference structure */
rvec *ref_x_old = NULL; /* helper pointer */
-
- if (!DOMAINDECOMP(cr) && PAR(cr) && MASTER(cr))
- {
- gmx_fatal(FARGS, "Please switch on domain decomposition to use essential dynamics in parallel.");
- }
-
if (MASTER(cr))
{
fprintf(stderr, "ED: Initializing essential dynamics constraints.\n");
return of->fp_dhdl;
}
-static void moveit(t_commrec *cr, rvec xx[])
-{
- if (!xx)
- {
- return;
- }
-
- move_rvecs(cr, FALSE, FALSE, xx, NULL, (cr->nnodes-cr->npmenodes)-1, NULL);
-}
-
void mdoutf_write_to_trajectory_files(FILE *fplog, t_commrec *cr,
gmx_mdoutf_t of,
int mdof_flags,
rvec *local_v;
rvec *global_v;
-#define MX(xvf) moveit(cr, xvf)
-
/* MRS -- defining these variables is to manage the difference
* between half step and full step velocities, but there must be a better way . . . */
copy_mat(state_local->fvir_prev, state_global->fvir_prev);
copy_mat(state_local->pres_prev, state_global->pres_prev);
}
- if (cr->nnodes > 1)
- {
- /* Particle decomposition, collect the data on the master node */
- if (mdof_flags & MDOF_CPT)
- {
- if (state_local->flags & (1<<estX))
- {
- MX(state_global->x);
- }
- if (state_local->flags & (1<<estV))
- {
- MX(state_global->v);
- }
- if (state_local->flags & (1<<estSDX))
- {
- MX(state_global->sd_X);
- }
- if (state_global->nrngi > 1)
- {
- if (state_local->flags & (1<<estLD_RNG))
- {
-#ifdef GMX_MPI
- MPI_Gather(state_local->ld_rng,
- state_local->nrng*sizeof(state_local->ld_rng[0]), MPI_BYTE,
- state_global->ld_rng,
- state_local->nrng*sizeof(state_local->ld_rng[0]), MPI_BYTE,
- MASTERRANK(cr), cr->mpi_comm_mygroup);
-#endif
- }
- if (state_local->flags & (1<<estLD_RNGI))
- {
-#ifdef GMX_MPI
- MPI_Gather(state_local->ld_rngi,
- sizeof(state_local->ld_rngi[0]), MPI_BYTE,
- state_global->ld_rngi,
- sizeof(state_local->ld_rngi[0]), MPI_BYTE,
- MASTERRANK(cr), cr->mpi_comm_mygroup);
-#endif
- }
- }
- }
- else
- {
- if (mdof_flags & (MDOF_X | MDOF_X_COMPRESSED))
- {
- MX(state_global->x);
- }
- if (mdof_flags & MDOF_V)
- {
- MX(global_v);
- }
- }
- if (mdof_flags & MDOF_F)
- {
- MX(f_global);
- }
- }
}
if (MASTER(cr))
}
ir.dr_tau = 0.0;
- init_disres(fplog, &mtop, &ir, NULL, FALSE, &fcd, NULL, FALSE);
+ init_disres(fplog, &mtop, &ir, NULL, &fcd, NULL, FALSE);
natoms = read_first_x(oenv, &status, ftp2fn(efTRX, NFILE, fnm), &t, &x, box);
snew(f, 5*natoms);
}
mdatoms = init_mdatoms(fplog, &mtop, ir.efep != efepNO);
- atoms2md(&mtop, &ir, 0, NULL, 0, mtop.natoms, mdatoms);
+ atoms2md(&mtop, &ir, 0, NULL, mtop.natoms, mdatoms);
update_mdatoms(mdatoms, ir.fepvals->init_lambda);
init_nrnb(&nrnb);
if (ir.ePBC != epbcNONE)
int flags_eks, flags_enh, flags_dfh, i;
t_fileio *ret;
- if (PAR(cr))
+ if (DOMAINDECOMP(cr))
{
- if (DOMAINDECOMP(cr))
- {
- nppnodes = cr->dd->nnodes;
- npmenodes = cr->npmenodes;
- }
- else
- {
- nppnodes = cr->nnodes;
- npmenodes = 0;
- }
+ nppnodes = cr->dd->nnodes;
+ npmenodes = cr->npmenodes;
}
else
{
char *version,
char *btime, char *buser, char *bhost, int double_prec,
char *fprog,
- t_commrec *cr, gmx_bool bPartDecomp, int npp_f, int npme_f,
+ t_commrec *cr, int npp_f, int npme_f,
ivec dd_nc, ivec dd_nc_f)
{
int npp;
check_string(fplog, "Program name", Program(), fprog, &mm);
check_int (fplog, "#nodes", cr->nnodes, npp_f+npme_f, &mm);
- if (bPartDecomp)
- {
- dd_nc[XX] = 1;
- dd_nc[YY] = 1;
- dd_nc[ZZ] = 1;
- }
if (cr->nnodes > 1)
{
check_int (fplog, "#PME-nodes", cr->npmenodes, npme_f, &mm);
}
static void read_checkpoint(const char *fn, FILE **pfplog,
- t_commrec *cr, gmx_bool bPartDecomp, ivec dd_nc,
+ t_commrec *cr, ivec dd_nc,
int eIntegrator, int *init_fep_state, gmx_int64_t *step, double *t,
t_state *state, gmx_bool *bReadRNG, gmx_bool *bReadEkin,
int *simulation_part,
fl.l_pid = 0;
#endif
- if (PARTDECOMP(cr))
- {
- gmx_fatal(FARGS,
- "read_checkpoint not (yet) supported with particle decomposition");
- }
-
fp = gmx_fio_open(fn, "r");
do_cpt_header(gmx_fio_getxdr(fp), TRUE, &file_version,
&version, &btime, &buser, &bhost, &double_prec, &fprog, &ftime,
nppnodes = 1;
cr->npmenodes = 0;
}
- else if (bPartDecomp)
- {
- nppnodes = cr->nnodes;
- cr->npmenodes = 0;
- }
else if (cr->nnodes == nppnodes_f + npmenodes_f)
{
if (cr->npmenodes < 0)
if (MASTER(cr))
{
check_match(fplog, version, btime, buser, bhost, double_prec, fprog,
- cr, bPartDecomp, nppnodes_f, npmenodes_f, dd_nc, dd_nc_f);
+ cr, nppnodes_f, npmenodes_f, dd_nc, dd_nc_f);
}
}
ret = do_cpt_state(gmx_fio_getxdr(fp), TRUE, fflags, state, *bReadRNG, NULL);
void load_checkpoint(const char *fn, FILE **fplog,
- t_commrec *cr, gmx_bool bPartDecomp, ivec dd_nc,
+ t_commrec *cr, ivec dd_nc,
t_inputrec *ir, t_state *state,
gmx_bool *bReadRNG, gmx_bool *bReadEkin,
gmx_bool bAppend, gmx_bool bForceAppend)
{
/* Read the state from the checkpoint file */
read_checkpoint(fn, fplog,
- cr, bPartDecomp, dd_nc,
+ cr, dd_nc,
ir->eI, &(ir->fepvals->init_fep_state), &step, &t, state, bReadRNG, bReadEkin,
&ir->simulation_part, bAppend, bForceAppend);
}
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014, 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.
#include "mtop_util.h"
void init_disres(FILE *fplog, const gmx_mtop_t *mtop,
- t_inputrec *ir, const t_commrec *cr, gmx_bool bPartDecomp,
+ t_inputrec *ir, const t_commrec *cr,
t_fcdata *fcd, t_state *state, gmx_bool bIsREMD)
{
int fa, nmol, i, npair, np;
}
}
- if (cr && PAR(cr) && !bPartDecomp)
+ if (cr && PAR(cr))
{
/* Temporary check, will be removed when disre is implemented with DD */
- const char *notestr = "NOTE: atoms involved in distance restraints should be within the longest cut-off distance, if this is not the case mdrun generates a fatal error, in that case use particle decomposition (mdrun option -pd)";
+ const char *notestr = "NOTE: atoms involved in distance restraints should be within the same domain. If this is not the case mdrun generates a fatal error. If you encounter this, use a single MPI rank (Verlet+OpenMP+GPUs work fine).";
if (MASTER(cr))
{
if (dd->dr_tau != 0 || ir->eDisre == edrEnsemble || cr->ms != NULL ||
dd->nres != dd->npair)
{
- gmx_fatal(FARGS, "Time or ensemble averaged or multiple pair distance restraints do not work (yet) with domain decomposition, use particle decomposition (mdrun option -pd)");
+ gmx_fatal(FARGS, "Time or ensemble averaged or multiple pair distance restraints do not work (yet) with domain decomposition, use a single MPI rank%s", cr->ms ? " per simulation" : "");
}
if (ir->nstdisreout != 0)
{
}
}
-void bcast_state_setup(const t_commrec *cr, t_state *state)
+void bcast_state(const t_commrec *cr, t_state *state)
{
+ int i, nnht, nnhtp;
+ gmx_bool bAlloc;
+
+ if (!PAR(cr))
+ {
+ return;
+ }
+
+ /* Broadcasts the state sizes and flags from the master to all nodes
+ * in cr->mpi_comm_mygroup. The arrays are not broadcasted. */
block_bc(cr, state->natoms);
block_bc(cr, state->ngtc);
block_bc(cr, state->nnhpres);
{
snew_bc(cr, state->lambda, efptNR)
}
-}
-
-void bcast_state(const t_commrec *cr, t_state *state, gmx_bool bAlloc)
-{
- int i, nnht, nnhtp;
- bcast_state_setup(cr, state);
+ if (cr->dd)
+ {
+ /* We allocate dynamically in dd_partition_system. */
+ return;
+ }
+ /* The code below is reachable only by TPI and NM, so it is not
+ tested by anything. */
nnht = (state->ngtc)*(state->nhchainlength);
nnhtp = (state->nnhpres)*(state->nhchainlength);
- if (MASTER(cr))
- {
- bAlloc = FALSE;
- }
+ /* We still need to allocate the arrays in state for non-master
+ * ranks, which is done (implicitly via bAlloc) in the dirty,
+ * dirty nblock_abc macro. */
+ bAlloc = !MASTER(cr);
if (bAlloc)
{
state->nalloc = state->natoms;
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2009, The GROMACS Development Team.
- * Copyright (c) 2013, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014, 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.
type = mdatoms->typeA;
facel = fr->epsfac;
natoms = mdatoms->nr;
- ni0 = mdatoms->start;
- ni1 = mdatoms->start+mdatoms->homenr;
+ ni0 = 0;
+ ni1 = mdatoms->homenr;
aadata = fr->AllvsAll_work;
excl = kernel_data->exclusions;
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2009, The GROMACS Development Team.
- * Copyright (c) 2013, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014, 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.
vpol = kernel_data->energygrp_polarization;
natoms = mdatoms->nr;
- ni0 = mdatoms->start;
- ni1 = mdatoms->start+mdatoms->homenr;
+ ni0 = 0;
+ ni1 = mdatoms->homenr;
aadata = fr->AllvsAll_work;
excl = kernel_data->exclusions;
rvec xref[],
const t_inputrec *ir,
const t_commrec *cr, t_oriresdata *od,
- t_state *state, gmx_bool bIsParticleDecomposition)
+ t_state *state)
{
int i, j, d, ex, nmol, *nr_ex;
double mtot;
return;
}
- if (PAR(cr) && !bIsParticleDecomposition)
+ if (DOMAINDECOMP(cr))
{
- gmx_fatal(FARGS, "Orientation restraints do not work (yet) with domain decomposition, use particle decomposition (mdrun option -pd)");
+ gmx_fatal(FARGS, "Orientation restraints do not work with more than one domain (ie. MPI rank).");
}
/* Orientation restraints */
if (!MASTER(cr))
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014, 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.
* To help us fund GROMACS development, we humbly ask that you cite
* the research papers on the package. Check out http://www.gromacs.org.
*/
+#include "splitter.h"
+
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <assert.h>
-#include <stdio.h>
#include <string.h>
-
-#include "sysstuff.h"
#include "macros.h"
#include "smalloc.h"
-#include "typedefs.h"
#include "mshift.h"
-#include "invblock.h"
-#include "txtdump.h"
-#include <math.h>
#include "gmx_fatal.h"
-#include "splitter.h"
-
-typedef struct {
- int nr;
- t_iatom *ia;
-} t_sf;
-
-static t_sf *init_sf(int nr)
-{
- t_sf *sf;
- int i;
-
- snew(sf, nr);
- for (i = 0; (i < nr); i++)
- {
- sf[i].nr = 0;
- sf[i].ia = NULL;
- }
-
- return sf;
-}
-
-static void done_sf(int nr, t_sf *sf)
-{
- int i;
-
- for (i = 0; (i < nr); i++)
- {
- sf[i].nr = 0;
- sfree(sf[i].ia);
- sf[i].ia = NULL;
- }
- sfree(sf);
-}
-
-static void push_sf(t_sf *sf, int nr, t_iatom ia[])
-{
- int i;
-
- srenew(sf->ia, sf->nr+nr);
- for (i = 0; (i < nr); i++)
- {
- sf->ia[sf->nr+i] = ia[i];
- }
- sf->nr += nr;
-}
-
-static int min_nodeid(int nr, atom_id list[], int hid[])
-{
- int i, nodeid, minnodeid;
-
- if (nr <= 0)
- {
- gmx_incons("Invalid node number");
- }
- minnodeid = hid[list[0]];
- for (i = 1; (i < nr); i++)
- {
- if ((nodeid = hid[list[i]]) < minnodeid)
- {
- minnodeid = nodeid;
- }
- }
-
- return minnodeid;
-}
-
-
-static void split_force2(t_inputrec *ir, int nnodes, int hid[], int ftype, t_ilist *ilist,
- int *multinr,
- int *constr_min_nodeid, int * constr_max_nodeid,
- int *left_range, int *right_range)
-{
- int i, j, k, type, nodeid, nratoms, tnr;
- int nvsite_constr;
- t_iatom ai, aj;
- int node_low_ai, node_low_aj, node_high_ai, node_high_aj;
- int node_low, node_high;
- int nodei, nodej;
- t_sf *sf;
- int nextra;
-
- sf = init_sf(nnodes);
-
- node_high = node_low = 0;
- nextra = 0;
-
- /* Walk along all the bonded forces, find the appropriate node
- * to calc it on, and add it to that nodes list.
- */
- for (i = 0; i < ilist->nr; i += (1+nratoms))
- {
- type = ilist->iatoms[i];
- nratoms = interaction_function[ftype].nratoms;
-
- if (ftype == F_CONSTR)
- {
- ai = ilist->iatoms[i+1];
- aj = ilist->iatoms[i+2];
-
- nodei = hid[ai];
- nodej = hid[aj];
- nodeid = nodei;
-
- if (ir->eConstrAlg == econtLINCS)
- {
- node_low_ai = constr_min_nodeid[ai];
- node_low_aj = constr_min_nodeid[aj];
- node_high_ai = constr_max_nodeid[ai];
- node_high_aj = constr_max_nodeid[aj];
-
- node_low = min(node_low_ai, node_low_aj);
- node_high = max(node_high_ai, node_high_aj);
-
- if (node_high-nodei > 1 || nodei-node_low > 1 ||
- node_high-nodej > 1 || nodej-node_low > 1)
- {
- gmx_fatal(FARGS, "Constraint dependencies further away than next-neighbor\n"
- "in particle decomposition. Constraint between atoms %d--%d evaluated\n"
- "on node %d and %d, but atom %d has connections within %d bonds (lincs_order)\n"
- "of node %d, and atom %d has connections within %d bonds of node %d.\n"
- "Reduce the # nodes, lincs_order, or\n"
- "try domain decomposition.", ai, aj, nodei, nodej, ai, ir->nProjOrder, node_low, aj, ir->nProjOrder, node_high);
- }
-
- if (node_low < nodei || node_low < nodej)
- {
- right_range[node_low] = max(right_range[node_low], aj);
- }
- if (node_high > nodei || node_high > nodej)
- {
- left_range[node_high] = min(left_range[node_high], ai);
- }
- }
- else
- {
- /* Shake */
- if (hid[ilist->iatoms[i+2]] != nodei)
- {
- gmx_fatal(FARGS, "Shake block crossing node boundaries\n"
- "constraint between atoms (%d,%d) (try LINCS instead!)",
- ilist->iatoms[i+1]+1, ilist->iatoms[i+2]+1);
- }
- }
- }
- else if (ftype == F_SETTLE)
- {
- /* Only the first particle is stored for settles ... */
- ai = ilist->iatoms[i+1];
- nodeid = hid[ai];
- if (nodeid != hid[ilist->iatoms[i+2]] ||
- nodeid != hid[ilist->iatoms[i+3]])
- {
- gmx_fatal(FARGS, "Settle block crossing node boundaries\n"
- "constraint between atoms %d, %d, %d)",
- ai, ilist->iatoms[i+2], ilist->iatoms[i+3]);
- }
- }
- else if (interaction_function[ftype].flags & IF_VSITE)
- {
- /* Virtual sites are special, since we need to pre-communicate
- * their coordinates to construct vsites before then main
- * coordinate communication.
- * Vsites can have constructing atoms both larger and smaller than themselves.
- * To minimize communication and book-keeping, each vsite is constructed on
- * the home node of the atomnr of the vsite.
- * Since the vsite coordinates too have to be communicated to the next node,
- * we need to
- *
- * 1. Pre-communicate coordinates of constructing atoms
- * 2. Construct the vsite
- * 3. Perform main coordinate communication
- *
- * Note that this has change from gromacs 4.0 and earlier, where the vsite
- * was constructed on the home node of the lowest index of any of the constructing
- * atoms and the vsite itself.
- */
-
- if (ftype == F_VSITE2)
- {
- nvsite_constr = 2;
- }
- else if (ftype == F_VSITE4FD || ftype == F_VSITE4FDN)
- {
- nvsite_constr = 4;
- }
- else
- {
- nvsite_constr = 3;
- }
-
- /* Vsites are constructed on the home node of the actual site to save communication
- * and simplify the book-keeping.
- */
- nodeid = hid[ilist->iatoms[i+1]];
-
- for (k = 2; k < nvsite_constr+2; k++)
- {
- if (hid[ilist->iatoms[i+k]] < (nodeid-1) ||
- hid[ilist->iatoms[i+k]] > (nodeid+1))
- {
- gmx_fatal(FARGS, "Virtual site %d and its constructing"
- " atoms are not on the same or adjacent\n"
- " nodes. This is necessary to avoid a lot\n"
- " of extra communication. The easiest way"
- " to ensure this is to place virtual sites\n"
- " close to the constructing atoms.\n"
- " Sorry, but you will have to rework your topology!\n",
- ilist->iatoms[i+1]);
- }
- }
- }
- else
- {
- nodeid = min_nodeid(nratoms, &ilist->iatoms[i+1], hid);
- }
-
- if (ftype == F_CONSTR && ir->eConstrAlg == econtLINCS)
- {
- push_sf(&(sf[nodeid]), nratoms+1, &(ilist->iatoms[i]));
-
- if (node_low < nodeid)
- {
- push_sf(&(sf[node_low]), nratoms+1, &(ilist->iatoms[i]));
- nextra += nratoms+1;
- }
- if (node_high > nodeid)
- {
- push_sf(&(sf[node_high]), nratoms+1, &(ilist->iatoms[i]));
- nextra += nratoms+1;
- }
- }
- else
- {
- push_sf(&(sf[nodeid]), nratoms+1, &(ilist->iatoms[i]));
- }
- }
-
- if (nextra > 0)
- {
- ilist->nr += nextra;
- srenew(ilist->iatoms, ilist->nr);
- }
-
- tnr = 0;
- for (nodeid = 0; (nodeid < nnodes); nodeid++)
- {
- for (i = 0; (i < sf[nodeid].nr); i++)
- {
- ilist->iatoms[tnr++] = sf[nodeid].ia[i];
- }
-
- multinr[nodeid] = (nodeid == 0) ? 0 : multinr[nodeid-1];
- multinr[nodeid] += sf[nodeid].nr;
- }
-
- if (tnr != ilist->nr)
- {
- gmx_incons("Splitting forces over processors");
- }
-
- done_sf(nnodes, sf);
-}
-
-static int *home_index(int nnodes, t_block *cgs, int *multinr)
-{
- /* This routine determines the node id for each particle */
- int *hid;
- int nodeid, j0, j1, j, k;
-
- snew(hid, cgs->index[cgs->nr]);
- /* Initiate to -1 to make it possible to check afterwards,
- * all hid's should be set in the loop below
- */
- for (k = 0; (k < cgs->index[cgs->nr]); k++)
- {
- hid[k] = -1;
- }
-
- /* loop over nodes */
- for (nodeid = 0; (nodeid < nnodes); nodeid++)
- {
- j0 = (nodeid == 0) ? 0 : multinr[nodeid-1];
- j1 = multinr[nodeid];
-
- /* j0 and j1 are the boundariesin the index array */
- for (j = j0; (j < j1); j++)
- {
- for (k = cgs->index[j]; (k < cgs->index[j+1]); k++)
- {
- hid[k] = nodeid;
- }
- }
- }
- /* Now verify that all hid's are not -1 */
- for (k = 0; (k < cgs->index[cgs->nr]); k++)
- {
- if (hid[k] == -1)
- {
- gmx_fatal(FARGS, "hid[%d] = -1, cgs->nr = %d, natoms = %d",
- k, cgs->nr, cgs->index[cgs->nr]);
- }
- }
-
- return hid;
-}
-
-typedef struct {
- int atom, ic, is;
-} t_border;
-
-void set_bor(t_border *b, int atom, int ic, int is)
-{
- if (debug)
- {
- fprintf(debug, "border @ atom %5d [ ic = %5d, is = %5d ]\n", atom, ic, is);
- }
- b->atom = atom;
- b->ic = ic;
- b->is = is;
-}
-
-static gmx_bool is_bor(atom_id ai[], int i)
-{
- return ((ai[i] != ai[i-1]) || ((ai[i] == NO_ATID) && (ai[i-1] == NO_ATID)));
-}
-
-static t_border *mk_border(FILE *fp, int natom, atom_id *invcgs,
- atom_id *invshk, int *nb)
-{
- t_border *bor;
- atom_id *sbor, *cbor;
- int i, j, is, ic, ns, nc, nbor;
-
- if (debug)
- {
- for (i = 0; (i < natom); i++)
- {
- fprintf(debug, "atom: %6d cgindex: %6d shkindex: %6d\n",
- i, invcgs[i], invshk[i]);
- }
- }
-
- snew(sbor, natom+1);
- snew(cbor, natom+1);
- ns = nc = 1;
- for (i = 1; (i < natom); i++)
- {
- if (is_bor(invcgs, i))
- {
- cbor[nc++] = i;
- }
- if (is_bor(invshk, i))
- {
- sbor[ns++] = i;
- }
- }
- sbor[ns] = 0;
- cbor[nc] = 0;
- if (fp)
- {
- fprintf(fp, "There are %d charge group borders", nc);
- if (invshk != NULL)
- {
- fprintf(fp, " and %d shake borders", ns);
- }
- fprintf(fp, ".\n");
- }
- snew(bor, max(nc, ns));
- ic = is = nbor = 0;
- while ((ic < nc) || (is < ns))
- {
- if (sbor[is] == cbor[ic])
- {
- set_bor(&(bor[nbor]), cbor[ic], ic, is);
- nbor++;
- if (ic < nc)
- {
- ic++;
- }
- if (is < ns)
- {
- is++;
- }
- }
- else if (cbor[ic] > sbor[is])
- {
- if (is == ns)
- {
- set_bor(&(bor[nbor]), cbor[ic], ic, is);
- nbor++;
- if (ic < nc)
- {
- ic++;
- }
- }
- else if (is < ns)
- {
- is++;
- }
- }
- else if (ic < nc)
- {
- ic++;
- }
- else
- {
- is++; /*gmx_fatal(FARGS,"Can't happen is=%d, ic=%d (%s, %d)",
- is,ic,__FILE__,__LINE__);*/
- }
- }
- if (fp)
- {
- fprintf(fp, "There are %d total borders\n", nbor);
- }
-
- if (debug)
- {
- fprintf(debug, "There are %d actual bor entries\n", nbor);
- for (i = 0; (i < nbor); i++)
- {
- fprintf(debug, "bor[%5d] = atom: %d ic: %d is: %d\n", i,
- bor[i].atom, bor[i].ic, bor[i].is);
- }
- }
-
- *nb = nbor;
-
- return bor;
-}
-
-static void split_blocks(FILE *fp, int nnodes,
- t_block *cgs, t_blocka *sblock, real capacity[],
- int *multinr_cgs)
-{
- int natoms, *maxatom;
- int i, ii, ai, b0, b1;
- int nodeid, last_shk, nbor;
- t_border *border;
- double tload, tcap;
-
- gmx_bool bSHK;
- atom_id *shknum, *cgsnum;
-
- natoms = cgs->index[cgs->nr];
-
- if (NULL != debug)
- {
- pr_block(debug, 0, "cgs", cgs, TRUE);
- pr_blocka(debug, 0, "sblock", sblock, TRUE);
- fflush(debug);
- }
-
- cgsnum = make_invblock(cgs, natoms+1);
- shknum = make_invblocka(sblock, natoms+1);
- border = mk_border(fp, natoms, cgsnum, shknum, &nbor);
-
- snew(maxatom, nnodes);
- tload = capacity[0]*natoms;
- tcap = 1.0;
- nodeid = 0;
- /* Start at bor is 1, to force the first block on the first processor */
- for (i = 0; (i < nbor) && (tload < natoms); i++)
- {
- if (i < (nbor-1))
- {
- b1 = border[i+1].atom;
- }
- else
- {
- b1 = natoms;
- }
-
- b0 = border[i].atom;
-
- if ((fabs(b0-tload) < fabs(b1-tload)))
- {
- /* New nodeid time */
- multinr_cgs[nodeid] = border[i].ic;
- maxatom[nodeid] = b0;
- tcap -= capacity[nodeid];
- nodeid++;
-
- /* Recompute target load */
- tload = b0 + (natoms-b0)*capacity[nodeid]/tcap;
-
- if (debug)
- {
- printf("tload: %g tcap: %g nodeid: %d\n", tload, tcap, nodeid);
- }
- }
- }
- /* Now the last one... */
- while (nodeid < nnodes)
- {
- multinr_cgs[nodeid] = cgs->nr;
- /* Store atom number, see above */
- maxatom[nodeid] = natoms;
- nodeid++;
- }
- if (nodeid != nnodes)
- {
- gmx_fatal(FARGS, "nodeid = %d, nnodes = %d, file %s, line %d",
- nodeid, nnodes, __FILE__, __LINE__);
- }
-
- for (i = nnodes-1; (i > 0); i--)
- {
- maxatom[i] -= maxatom[i-1];
- }
-
- if (fp)
- {
- fprintf(fp, "Division over nodes in atoms:\n");
- for (i = 0; (i < nnodes); i++)
- {
- fprintf(fp, " %7d", maxatom[i]);
- }
- fprintf(fp, "\n");
- }
-
- sfree(maxatom);
- sfree(shknum);
- sfree(cgsnum);
- sfree(border);
-}
typedef struct {
int atom, sid;
fprintf(debug, "Done gen_sblocks\n");
}
}
-
-static t_blocka block2blocka(t_block *block)
-{
- t_blocka blocka;
- int i;
-
- blocka.nr = block->nr;
- blocka.nalloc_index = blocka.nr + 1;
- snew(blocka.index, blocka.nalloc_index);
- for (i = 0; i <= block->nr; i++)
- {
- blocka.index[i] = block->index[i];
- }
- blocka.nra = block->index[block->nr];
- blocka.nalloc_a = blocka.nra;
- snew(blocka.a, blocka.nalloc_a);
- for (i = 0; i < blocka.nra; i++)
- {
- blocka.a[i] = i;
- }
-
- return blocka;
-}
-
-typedef struct
-{
- int nconstr;
- int index[10];
-} pd_constraintlist_t;
-
-
-static void
-find_constraint_range_recursive(pd_constraintlist_t * constraintlist,
- int thisatom,
- int depth,
- int * min_atomid,
- int * max_atomid)
-{
- int i, j;
- int nconstr;
-
- for (i = 0; i < constraintlist[thisatom].nconstr; i++)
- {
- j = constraintlist[thisatom].index[i];
-
- *min_atomid = (j < *min_atomid) ? j : *min_atomid;
- *max_atomid = (j > *max_atomid) ? j : *max_atomid;
-
- if (depth > 0)
- {
- find_constraint_range_recursive(constraintlist, j, depth-1, min_atomid, max_atomid);
- }
- }
-}
-
-static void
-pd_determine_constraints_range(t_inputrec * ir,
- int natoms,
- t_ilist * ilist,
- int hid[],
- int * min_nodeid,
- int * max_nodeid)
-{
- int i, j, k;
- int nratoms;
- int depth;
- int ai, aj;
- int min_atomid, max_atomid;
- pd_constraintlist_t *constraintlist;
-
- nratoms = interaction_function[F_CONSTR].nratoms;
- depth = ir->nProjOrder;
-
- snew(constraintlist, natoms);
-
- /* Make a list of all the connections */
- for (i = 0; i < ilist->nr; i += nratoms+1)
- {
- ai = ilist->iatoms[i+1];
- aj = ilist->iatoms[i+2];
- constraintlist[ai].index[constraintlist[ai].nconstr++] = aj;
- constraintlist[aj].index[constraintlist[aj].nconstr++] = ai;
- }
-
- for (i = 0; i < natoms; i++)
- {
- min_atomid = i;
- max_atomid = i;
-
- find_constraint_range_recursive(constraintlist, i, depth, &min_atomid, &max_atomid);
-
- min_nodeid[i] = hid[min_atomid];
- max_nodeid[i] = hid[max_atomid];
- }
- sfree(constraintlist);
-}
-
-
-void split_top(FILE *fp, int nnodes, gmx_localtop_t *top, t_inputrec *ir, t_block *mols,
- real *capacity, int *multinr_cgs, int **multinr_nre, int *left_range, int * right_range)
-{
- int natoms, i, j, k, mj, atom, maxatom, sstart, send, bstart, nodeid;
- t_blocka sblock;
- int *homeind;
- int ftype, nvsite_constr, nra, nrd;
- t_iatom *ia;
- int minhome, ihome, minidx;
- int *constr_min_nodeid;
- int *constr_max_nodeid;
-
- if (nnodes <= 1)
- {
- return;
- }
-
- natoms = mols->index[mols->nr];
-
- if (fp)
- {
- fprintf(fp, "splitting topology...\n");
- }
-
-/*#define MOL_BORDER*/
-/*Removed the above to allow splitting molecules with h-bond constraints
- over processors. The results in DP are the same. */
- init_blocka(&sblock);
- if (ir->eConstrAlg != econtLINCS)
- {
-#ifndef MOL_BORDER
- /* Make a special shake block that includes settles */
- gen_sblocks(fp, 0, natoms, &top->idef, &sblock, TRUE);
-#else
- sblock = block2blocka(mols);
-#endif
- }
-
- split_blocks(fp, nnodes, &top->cgs, &sblock, capacity, multinr_cgs);
-
- homeind = home_index(nnodes, &top->cgs, multinr_cgs);
-
- snew(constr_min_nodeid, natoms);
- snew(constr_max_nodeid, natoms);
-
- if (top->idef.il[F_CONSTR].nr > 0)
- {
- pd_determine_constraints_range(ir, natoms, &top->idef.il[F_CONSTR], homeind, constr_min_nodeid, constr_max_nodeid);
- }
- else
- {
- /* Not 100% necessary, but it is a bad habit to have uninitialized arrays around... */
- for (i = 0; i < natoms; i++)
- {
- constr_min_nodeid[i] = constr_max_nodeid[i] = homeind[i];
- }
- }
-
- /* Default limits (no communication) for PD constraints */
- left_range[0] = 0;
- for (i = 1; i < nnodes; i++)
- {
- left_range[i] = top->cgs.index[multinr_cgs[i-1]];
- right_range[i-1] = left_range[i]-1;
- }
- right_range[nnodes-1] = top->cgs.index[multinr_cgs[nnodes-1]]-1;
-
- for (j = 0; (j < F_NRE); j++)
- {
- split_force2(ir, nnodes, homeind, j, &top->idef.il[j], multinr_nre[j], constr_min_nodeid, constr_max_nodeid,
- left_range, right_range);
- }
-
- sfree(constr_min_nodeid);
- sfree(constr_max_nodeid);
-
- sfree(homeind);
- done_blocka(&sblock);
-}
#include "pbc.h"
#include "macros.h"
#include <string.h>
+#include "gromacs/random/random.h"
#include "gromacs/legacyheaders/thread_mpi/threads.h"
}
}
+t_state *serial_init_local_state(t_state *state_global)
+{
+ int i;
+ t_state *state_local;
+
+ snew(state_local, 1);
+
+ /* Copy all the contents */
+ *state_local = *state_global;
+ snew(state_local->lambda, efptNR);
+ /* local storage for lambda */
+ for (i = 0; i < efptNR; i++)
+ {
+ state_local->lambda[i] = state_global->lambda[i];
+ }
+ if (state_global->nrngi > 1)
+ {
+ /* With stochastic dynamics we need local storage for the random state */
+ if (state_local->flags & (1<<estLD_RNG))
+ {
+ state_local->nrng = gmx_rng_n();
+ snew(state_local->ld_rng, state_local->nrng);
+ }
+ if (state_local->flags & (1<<estLD_RNGI))
+ {
+ snew(state_local->ld_rngi, 1);
+ }
+ }
+
+ return state_local;
+}
+
static void do_box_rel(t_inputrec *ir, matrix box_rel, matrix b, gmx_bool bInit)
{
int d, d2;
snew(nFreeze, 2);
snew(md, 1);
md = init_mdatoms(fp, mtop, FALSE);
- atoms2md(mtop, ir, 0, NULL, 0, mtop->natoms, md);
+ atoms2md(mtop, ir, 0, NULL, mtop->natoms, md);
sfree(nFreeze);
/* forcerec structure */
}
if (ir->nstlist > 0)
{
- warning_note(wi, "Simulating without cut-offs is usually (slightly) faster with nstlist=0, nstype=simple and particle decomposition");
+ warning_note(wi, "Simulating without cut-offs can be (slightly) faster with nstlist=0, nstype=simple and only one MPI rank");
}
}
init_pull(NULL, ir, 0, NULL, mtop, NULL, oenv, lambda, FALSE, 0);
md = init_mdatoms(NULL, mtop, ir->efep);
- atoms2md(mtop, ir, 0, NULL, 0, mtop->natoms, md);
+ atoms2md(mtop, ir, 0, NULL, mtop->natoms, md);
if (ir->efep)
{
update_mdatoms(md, lambda);
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014, 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.
* support file locking.
*/
void load_checkpoint(const char *fn, FILE **fplog,
- t_commrec *cr, gmx_bool bPartDecomp, ivec dd_nc,
+ t_commrec *cr, ivec dd_nc,
t_inputrec *ir, t_state *state, gmx_bool *bReadRNG,
gmx_bool *bReadEkin, gmx_bool bAppend, gmx_bool bForceAppend);
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014, 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.
#endif
void init_disres(FILE *fplog, const gmx_mtop_t *mtop,
- t_inputrec *ir, const t_commrec *cr, gmx_bool bPartDecomp,
+ t_inputrec *ir, const t_commrec *cr,
t_fcdata *fcd, t_state *state, gmx_bool bIsREMD);
/* Initiate *fcd data, must be called once, nbonds is the number
* of iatoms in the ilist of the idef struct.
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014, 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.
* print_force >= 0: print forces for atoms with force >= print_force
*/
-void forcerec_set_excl_load(t_forcerec *fr,
- const gmx_localtop_t *top, const t_commrec *cr);
+void forcerec_set_excl_load(t_forcerec *fr,
+ const gmx_localtop_t *top);
/* Set the exclusion load for the local exclusions and possibly threads */
void init_enerdata(int ngener, int n_lambda, gmx_enerdata_t *enerd);
/* Initialise GB stuff */
int init_gb(gmx_genborn_t **p_born,
- const t_commrec *cr, t_forcerec *fr, const t_inputrec *ir,
+ t_forcerec *fr, const t_inputrec *ir,
const gmx_mtop_t *mtop, int gb_algorithm);
-void gb_pd_send(t_commrec *cr, real *send_data, int nr);
-
-
-
/* Functions for calculating adjustments due to ie chain rule terms */
void
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2010, by the GROMACS development team, led by
+ * Copyright (c) 2010,2014, 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.
void atoms2md(gmx_mtop_t *mtop, t_inputrec *ir,
int nindex, int *index,
- int start, int homenr,
+ int homenr,
t_mdatoms *md);
/* This routine copies the atoms->atom struct into md.
* If index!=NULL only the indexed atoms are copied.
#define MD_RERUN (1<<4)
#define MD_RERUN_VSITE (1<<5)
#define MD_SEPPOT (1<<7)
-#define MD_PARTDEC (1<<9)
#define MD_DDBONDCHECK (1<<10)
#define MD_DDBONDCOMM (1<<11)
#define MD_CONFOUT (1<<12)
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014, 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.
/* Broadcasts ir and mtop from the master to all nodes in cr->mpi_comm_mygroup.
*/
-void bcast_state_setup(const t_commrec *cr, t_state *state);
-/* Broadcasts the state sizes and flags
- * from the master to all nodes in cr->mpi_comm_mygroup.
- * The arrays are not broadcasted.
- */
-
-void bcast_state(const t_commrec *cr, t_state *state, gmx_bool bAlloc);
+void bcast_state(const t_commrec *cr, t_state *state);
/* Broadcasts state from the master to all nodes in cr->mpi_comm_mygroup.
- * The arrays in state are allocated when bAlloc is TRUE.
*/
-
-/* Routines for particle decomposition only in mvxvf.c */
-
-void move_cgcm(FILE *log, const t_commrec *cr, rvec cg_cm[]);
-
-void move_rvecs(const t_commrec *cr, gmx_bool bForward, gmx_bool bSum, rvec vecs[], rvec buf[],
- int shift, t_nrnb *nrnb);
-
-void move_x(const t_commrec *cr, rvec x[], t_nrnb *nrnb);
-
-void move_f(const t_commrec *cr, rvec f[], rvec fadd[],
- t_nrnb *nrnb);
-
#ifdef __cplusplus
}
#endif
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014, 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.
void print_grid(FILE *log, t_grid *grid);
-void mv_grid(t_commrec *cr, t_grid *grid);
-/* Move the grid over processors */
-
#ifdef __cplusplus
}
#endif
rvec x[],
const t_inputrec *ir,
const t_commrec *cr, t_oriresdata *od,
- t_state *state,
- gmx_bool bIsParticleDecomposition);
+ t_state *state);
/* Decides whether orientation restraints can work, and initializes
all the orientation restraint stuff in *od (and assumes *od is
already allocated. */
+++ /dev/null
-/*
- * This file is part of the GROMACS molecular simulation package.
- *
- * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
- * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013, 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.
- */
-
-#ifndef _partdec_h
-#define _partdec_h
-
-#include "vsite.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-#define GMX_LEFT 0 /* channel to the left processor */
-#define GMX_RIGHT 1 /* channel to the right processor */
-
-/* These are the good old ring communication routines */
-
-void gmx_tx(const t_commrec *cr, int dir, void *buf, int bufsize);
-/*
- * Asynchronously sends bufsize bytes from the buffer pointed to by buf
- * over the communication channel, identified by chan. The buffer becomes
- * available after a successful call of gmx_tx_wait(dir).
- */
-
-void gmx_tx_wait(const t_commrec *cr);
-/*
- * Waits until the asynchronous send operation associated with chan has
- * succeeded. This makes the buffer of the send operation available to
- * the sending process.
- */
-
-void gmx_rx(const t_commrec *cr, int dir, void *buf, int bufsize);
-/*
- * Asynchronously receives bufsize bytes in the buffer pointed to by buf
- * from communication channel identified by chan. The buffer becomes
- * available after a successful call of gmx_rx_wait(chan).
- */
-
-void gmx_rx_wait(const t_commrec *cr);
-/*
- * Waits until the asynchronous receive operation, associated with chan,
- * has succeeded. This makes the buffer of the receive operation
- * available to the receiving process.
- */
-
-void gmx_left_right(int nnodes, int nodeid,
- int *left, int *right);
-/* Get left and right proc id. */
-
-void gmx_tx_rx(const t_commrec *cr,
- int send_dir, void *send_buf, int send_bufsize,
- int recv_dir, void *recv_buf, int recv_bufsize);
-/* Communicate simultaneously left and right */
-
-void gmx_tx_rx_real(const t_commrec *cr,
- int send_dir, real *send_buf, int send_bufsize,
- int recv_dir, real *recv_buf, int recv_bufsize);
-/* Communicate simultaneously left and right, reals only */
-
-void gmx_wait(const t_commrec *cr);
-/* Wait for communication to finish */
-
-void pd_move_f(const t_commrec *cr, rvec f[], t_nrnb *nrnb);
-/* Sum the forces over the nodes */
-
-int *pd_cgindex(const t_commrec *cr);
-
-int *pd_index(const t_commrec *cr);
-
-int pd_shift(const t_commrec *cr);
-
-int pd_bshift(const t_commrec *cr);
-
-void pd_cg_range(const t_commrec *cr, int *cg0, int *cg1);
-/* Get the range for the home charge groups */
-
-void pd_at_range(const t_commrec *cr, int *at0, int *at1);
-/* Get the range for the home particles */
-
-gmx_localtop_t *split_system(FILE *log,
- gmx_mtop_t *mtop, t_inputrec *inputrec,
- t_commrec *cr);
-/* Split the system over N processors. */
-
-gmx_bool setup_parallel_vsites(t_idef *idef, t_commrec *cr,
- t_comm_vsites *vsitecomm);
-
-t_state *partdec_init_local_state(t_commrec *cr, t_state *state_global);
-/* Generate a local state struct from the global one */
-
-void
-pd_get_constraint_range(gmx_partdec_p_t pd, int *start, int *natoms);
-
-
-int *
-pd_constraints_nlocalatoms(gmx_partdec_p_t pd);
-
-/* Move x0 and also x1 if x1!=NULL */
-void
-pd_move_x_constraints(t_commrec * cr,
- rvec * x0,
- rvec * x1);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2010, by the GROMACS development team, led by
+ * Copyright (c) 2010,2014, 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.
extern "C" {
#endif
-void split_top(FILE *fp, int nnodes, gmx_localtop_t *top,
- t_inputrec *ir, t_block *mols,
- real *capacity, int *mulitnr_cgs, int **multinr_nre,
- int *left_range, int *right_range);
-/* Split the topology (blocks and forces, based on charge groups
- * and shake blocks.
- * The capacity is releated to the capacity of each node. If all numbers are
- * equal, load will be distributed equally. If not some (the higher ones)
- * will get more than others. The sum of capacities should be 1.
- * Info is written to the file pointer fp.
- */
-
void gen_sblocks(FILE *fp, int at_start, int at_end,
t_idef *idef, t_blocka *sblock,
gmx_bool bSettle);
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014, 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.
void done_energyhistory(energyhistory_t * enerhist);
void init_gtc_state(t_state *state, int ngtc, int nnhpres, int nhchainlength);
void init_state(t_state *state, int natoms, int ngtc, int nnhpres, int nhchainlength, int nlambda);
+t_state *serial_init_local_state(t_state *state_global);
void init_df_history(df_history_t *dfhist, int nlambda);
void done_df_history(df_history_t *dfhist);
void copy_df_history(df_history_t * df_dest, df_history_t *df_source);
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014, 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_domdec_t;
-typedef struct gmx_partdec *gmx_partdec_p_t;
-
typedef struct {
int nsim;
int sim;
/* For domain decomposition */
gmx_domdec_t *dd;
- /* For particle decomposition */
- gmx_partdec_p_t pd;
-
/* The duties of this node, see the defines above */
int duty;
#define RANK(cr, nodeid) (nodeid)
#define MASTERRANK(cr) (0)
+/* Note that even with particle decomposition removed, the use of
+ * non-DD parallelization in TPI, NM and multi-simulations means that
+ * PAR(cr) and DOMAINDECOMP(cr) are not universally synonymous. In
+ * particular, DOMAINDECOMP(cr) == true indicates that there is more
+ * than one domain, not just that the dd algorithm is active. */
#define DOMAINDECOMP(cr) (((cr)->dd != NULL) && PAR(cr))
#define DDMASTER(dd) ((dd)->rank == (dd)->masterrank)
-#define PARTDECOMP(cr) ((cr)->pd != NULL)
-
#define MULTISIM(cr) ((cr)->ms)
#define MSRANK(ms, nodeid) (nodeid)
#define MASTERSIM(ms) ((ms)->sim == 0)
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2012,2013, by the GROMACS development team, led by
+ * Copyright (c) 2012,2013,2014, 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.
/* for QMMM, atomnumber contains atomic number of the atoms */
gmx_bool *bQM;
/* The range of home atoms */
- int start;
int homenr;
/* The lambda value used to create the contents of the struct */
real lambda;
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014, 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.
extern "C" {
#endif
-typedef struct {
- int * left_import_construct;
- int left_import_nconstruct;
- int * left_export_construct;
- int left_export_nconstruct;
- int * right_import_construct;
- int right_import_nconstruct;
- int * right_export_construct;
- int right_export_nconstruct;
- rvec * send_buf;
- rvec * recv_buf;
-} t_comm_vsites;
-
typedef struct {
t_ilist ilist[F_NRE]; /* vsite ilists for this thread */
rvec fshift[SHIFTS]; /* fshift accumulation buffer */
int ***vsite_pbc_molt; /* The pbc atoms for intercg vsites */
int **vsite_pbc_loc; /* The local pbc atoms */
int *vsite_pbc_loc_nalloc; /* Sizes of vsite_pbc_loc */
- gmx_bool bPDvsitecomm; /* Do we need vsite communication with PD? */
- t_comm_vsites *vsitecomm; /* The PD vsite communication struct */
int nthreads; /* Number of threads used for vsites */
gmx_vsite_thread_t *tdata; /* Thread local vsites and work structs */
int *th_ind; /* Work array */
rvec x[],
real dt, rvec v[],
t_iparams ip[], t_ilist ilist[],
- int ePBC, gmx_bool bMolPBC, t_graph *graph,
+ int ePBC, gmx_bool bMolPBC,
t_commrec *cr, matrix box);
/* Create positions of vsite atoms based on surrounding atoms
* for the local system.
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014, 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.
#include "mdrun.h"
#include "nrnb.h"
#include "domdec.h"
-#include "partdec.h"
#include "mtop_util.h"
#include "gmx_omp_nthreads.h"
{
nlocat = dd_constraints_nlocalatoms(cr->dd);
}
- else if (PARTDECOMP(cr))
- {
- nlocat = pd_constraints_nlocalatoms(cr->pd);
- }
else
{
nlocat = NULL;
for (iter = 0; iter < lincsd->nIter; iter++)
{
- if ((lincsd->bCommIter && DOMAINDECOMP(cr) && cr->dd->constraints) ||
- PARTDECOMP(cr))
+ if ((lincsd->bCommIter && DOMAINDECOMP(cr) && cr->dd->constraints))
{
#pragma omp barrier
#pragma omp master
{
dd_move_x_constraints(cr->dd, box, xp, NULL);
}
- else
- {
- pd_move_x_constraints(cr, xp, NULL);
- }
}
}
}
start = 0;
}
- else if (PARTDECOMP(cr))
- {
- pd_get_constraint_range(cr->pd, &start, &natoms);
- }
else
{
- start = md->start;
+ start = 0;
natoms = md->homenr;
}
at2con = make_at2con(start, natoms, idef->il, idef->iparams, bDynamics,
#include "txtdump.h"
#include "domdec.h"
#include "gromacs/fileio/pdbio.h"
-#include "partdec.h"
#include "splitter.h"
#include "mtop_util.h"
#include "gromacs/fileio/gmxfio.h"
char *anm, *resnm;
dd = NULL;
+ if (DOMAINDECOMP(cr))
+ {
+ dd = cr->dd;
+ dd_get_constraint_range(dd, &dd_ac0, &dd_ac1);
+ start = 0;
+ homenr = dd_ac1;
+ }
+
if (PAR(cr))
{
sprintf(fname, "%s_n%d.pdb", fn, cr->sim_nodeid);
- if (DOMAINDECOMP(cr))
- {
- dd = cr->dd;
- dd_get_constraint_range(dd, &dd_ac0, &dd_ac1);
- start = 0;
- homenr = dd_ac1;
- }
}
else
{
bOK = TRUE;
bDump = FALSE;
- start = md->start;
+ start = 0;
homenr = md->homenr;
nrend = start+homenr;
{
dd_move_x_constraints(cr->dd, box, x, xprime);
}
- else if (PARTDECOMP(cr))
- {
- pd_move_x_constraints(cr, x, xprime);
- }
if (constr->lincsd != NULL)
{
}
else
{
- calcvir_atom_end = md->start + md->homenr;
+ calcvir_atom_end = md->homenr;
}
switch (econq)
}
}
-static void make_shake_sblock_pd(struct gmx_constr *constr,
- t_idef *idef, t_mdatoms *md)
+static void make_shake_sblock_serial(struct gmx_constr *constr,
+ t_idef *idef, t_mdatoms *md)
{
int i, j, m, ncons;
int bstart, bnr;
ncons = idef->il[F_CONSTR].nr/3;
init_blocka(&sblocks);
- gen_sblocks(NULL, md->start, md->start+md->homenr, idef, &sblocks, FALSE);
+ gen_sblocks(NULL, 0, md->homenr, idef, &sblocks, FALSE);
/*
bstart=(idef->nodeid > 0) ? blocks->multinr[idef->nodeid-1] : 0;
}
else
{
- make_shake_sblock_pd(constr, idef, md);
+ make_shake_sblock_serial(constr, idef, md);
}
if (ncons > constr->lagr_nalloc)
{
/* but do we actually need the total? */
/* modify the velocities as well */
- for (n = md->start; n < md->start+md->homenr; n++)
+ for (n = 0; n < md->homenr; n++)
{
if (md->cTC) /* does this conditional need to be here? is this always true?*/
{
if (ir->ns_type == ensSIMPLE)
{
- gmx_fatal(FARGS, "Domain decomposition does not support simple neighbor searching, use grid searching or use particle decomposition");
+ gmx_fatal(FARGS, "Domain decomposition does not support simple neighbor searching, use grid searching or run with one MPI rank");
}
if (ir->nstlist == 0)
*/
/* This call also sets the new number of home particles to dd->nat_home */
atoms2md(top_global, ir,
- comm->nat[ddnatCON], dd->gatindex, 0, dd->nat_home, mdatoms);
+ comm->nat[ddnatCON], dd->gatindex, dd->nat_home, mdatoms);
/* Now we have the charges we can sort the FE interactions */
dd_sort_local_top(dd, mdatoms, top_local);
{
dd->nbonded_local += nexcl;
- forcerec_set_excl_load(fr, ltop, NULL);
+ forcerec_set_excl_load(fr, ltop);
}
ltop->atomtypes = mtop->atomtypes;
{
construct_vsites(vsite, xs, 0.0, NULL,
ffparams->iparams, molt->ilist,
- epbcNONE, TRUE, NULL, NULL, NULL);
+ epbcNONE, TRUE, NULL, NULL);
}
calc_cgcm(NULL, 0, molt->cgs.nr, &molt->cgs, xs, cg_cm);
#include "string2.h"
#include "smalloc.h"
#include "names.h"
-#include "mvdata.h"
+#include "gromacs/fileio/confio.h"
#include "txtdump.h"
#include "pbc.h"
#include "chargegroup.h"
#include "xvgr.h"
#include "gromacs/random/random.h"
#include "domdec.h"
-#include "partdec.h"
#include "macros.h"
#include "gromacs/fileio/confio.h"
/* we don't need to manipulate the ekind information, as it isn't due to be reset until the next step anyway */
- nstart = mdatoms->start;
- nend = nstart + mdatoms->homenr;
+ nstart = 0;
+ nend = mdatoms->homenr;
for (n = nstart; n < nend; n++)
{
gt = 0;
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014, 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.
#include "pme.h"
#include "mdrun.h"
#include "domdec.h"
-#include "partdec.h"
#include "qmmm.h"
#include "gmx_omp_nthreads.h"
}
wallcycle_start(wcycle, ewcPMEMESH);
status = gmx_pme_do(fr->pmedata,
- md->start, md->homenr - fr->n_tpi,
+ 0, md->homenr - fr->n_tpi,
x, fr->f_novirsum,
md->chargeA, md->chargeB,
md->c6A, md->c6B,
#include "md_support.h"
#include "md_logging.h"
#include "domdec.h"
-#include "partdec.h"
#include "qmmm.h"
#include "copyrite.h"
#include "mtop_util.h"
fr->gbtabr = 100;
fr->gbtab = make_gb_table(oenv, fr);
- init_gb(&fr->born, cr, fr, ir, mtop, ir->gb_algorithm);
+ init_gb(&fr->born, fr, ir, mtop, ir->gb_algorithm);
/* Copy local gb data (for dd, this is done in dd_partition_system) */
if (!DOMAINDECOMP(cr))
if (!DOMAINDECOMP(cr))
{
- /* When using particle decomposition, the effect of the second argument,
- * which sets fr->hcg, is corrected later in do_md and init_em.
- */
forcerec_set_ranges(fr, ncg_mtop(mtop), ncg_mtop(mtop),
mtop->natoms, mtop->natoms, mtop->natoms);
}
fflush(fp);
}
-void forcerec_set_excl_load(t_forcerec *fr,
- const gmx_localtop_t *top, const t_commrec *cr)
+void forcerec_set_excl_load(t_forcerec *fr,
+ const gmx_localtop_t *top)
{
const int *ind, *a;
int t, i, j, ntot, n, ntarget;
- if (cr != NULL && PARTDECOMP(cr))
- {
- /* No OpenMP with particle decomposition */
- pd_at_range(cr,
- &fr->excl_load[0],
- &fr->excl_load[1]);
-
- return;
- }
-
ind = top->excls.index;
a = top->excls.a;
#include "gromacs/fileio/pdbio.h"
#include "names.h"
#include "physics.h"
-#include "partdec.h"
#include "domdec.h"
#include "network.h"
#include "gmx_fatal.h"
}
}
-int init_gb_nblist(int natoms, t_nblist *nl)
+static int init_gb_nblist(int natoms, t_nblist *nl)
{
nl->maxnri = natoms*4;
nl->maxnrj = 0;
return 0;
}
-void gb_pd_send(t_commrec gmx_unused *cr, real gmx_unused *send_data, int gmx_unused nr)
-{
-#ifdef GMX_MPI
- int i, cur;
- int *index, *sendc, *disp;
-
- snew(sendc, cr->nnodes);
- snew(disp, cr->nnodes);
-
- index = pd_index(cr);
- cur = cr->nodeid;
-
- /* Setup count/index arrays */
- for (i = 0; i < cr->nnodes; i++)
- {
- sendc[i] = index[i+1]-index[i];
- disp[i] = index[i];
- }
-
- /* Do communication */
- MPI_Gatherv(send_data+index[cur], sendc[cur], GMX_MPI_REAL, send_data, sendc,
- disp, GMX_MPI_REAL, 0, cr->mpi_comm_mygroup);
- MPI_Bcast(send_data, nr, GMX_MPI_REAL, 0, cr->mpi_comm_mygroup);
-
-#endif
-}
-
-int init_gb_still(const t_commrec *cr,
- const t_atomtypes *atype, t_idef *idef, t_atoms *atoms,
- gmx_genborn_t *born, int natoms)
+static int init_gb_still(const t_atomtypes *atype, t_idef *idef, t_atoms *atoms,
+ gmx_genborn_t *born, int natoms)
{
int i, j, i1, i2, k, m, nbond, nang, ia, ib, ic, id, nb, idx, idx2, at;
snew(gp, natoms);
snew(born->gpol_still_work, natoms+3);
- if (PAR(cr))
- {
- if (PARTDECOMP(cr))
- {
- pd_at_range(cr, &at0, &at1);
-
- for (i = 0; i < natoms; i++)
- {
- vsol[i] = gp[i] = 0;
- }
- }
- else
- {
- at0 = 0;
- at1 = natoms;
- }
- }
- else
- {
- at0 = 0;
- at1 = natoms;
- }
+ at0 = 0;
+ at1 = natoms;
doffset = born->gb_doffset;
h = ri*(1+ratio);
term = (M_PI/3.0)*h*h*(3.0*ri-h);
- if (PARTDECOMP(cr))
- {
- vsol[ia] += term;
- }
- else
- {
- born->vsolv_globalindex[ia] -= term;
- }
+ born->vsolv_globalindex[ia] -= term;
ratio = (ri2-rj2-r*r)/(2*rj*r);
h = rj*(1+ratio);
term = (M_PI/3.0)*h*h*(3.0*rj-h);
- if (PARTDECOMP(cr))
- {
- vsol[ib] += term;
- }
- else
- {
- born->vsolv_globalindex[ib] -= term;
- }
- }
-
- if (PARTDECOMP(cr))
- {
- gmx_sum(natoms, vsol, cr);
-
- for (i = 0; i < natoms; i++)
- {
- born->vsolv_globalindex[i] = born->vsolv_globalindex[i]-vsol[i];
- }
+ born->vsolv_globalindex[ib] -= term;
}
/* Get the self-, 1-2 and 1-3 polarization energies for analytical Still
r4 = r*r*r*r;
- if (PARTDECOMP(cr))
- {
- gp[ia] += STILL_P2*born->vsolv_globalindex[ib]/r4;
- gp[ib] += STILL_P2*born->vsolv_globalindex[ia]/r4;
- }
- else
- {
- born->gpol_globalindex[ia] = born->gpol_globalindex[ia]+
- STILL_P2*born->vsolv_globalindex[ib]/r4;
- born->gpol_globalindex[ib] = born->gpol_globalindex[ib]+
- STILL_P2*born->vsolv_globalindex[ia]/r4;
- }
+ born->gpol_globalindex[ia] = born->gpol_globalindex[ia]+
+ STILL_P2*born->vsolv_globalindex[ib]/r4;
+ born->gpol_globalindex[ib] = born->gpol_globalindex[ib]+
+ STILL_P2*born->vsolv_globalindex[ia]/r4;
}
/* 1-3 */
r = idef->iparams[m].gb.st;
r4 = r*r*r*r;
- if (PARTDECOMP(cr))
- {
- gp[ia] += STILL_P3*born->vsolv[ib]/r4;
- gp[ib] += STILL_P3*born->vsolv[ia]/r4;
- }
- else
- {
- born->gpol_globalindex[ia] = born->gpol_globalindex[ia]+
- STILL_P3*born->vsolv_globalindex[ib]/r4;
- born->gpol_globalindex[ib] = born->gpol_globalindex[ib]+
- STILL_P3*born->vsolv_globalindex[ia]/r4;
- }
- }
-
- if (PARTDECOMP(cr))
- {
- gmx_sum(natoms, gp, cr);
-
- for (i = 0; i < natoms; i++)
- {
- born->gpol_globalindex[i] = born->gpol_globalindex[i]+gp[i];
- }
+ born->gpol_globalindex[ia] = born->gpol_globalindex[ia]+
+ STILL_P3*born->vsolv_globalindex[ib]/r4;
+ born->gpol_globalindex[ib] = born->gpol_globalindex[ib]+
+ STILL_P3*born->vsolv_globalindex[ia]/r4;
}
sfree(vsol);
/* Initialize all GB datastructs and compute polarization energies */
int init_gb(gmx_genborn_t **p_born,
- const t_commrec *cr, t_forcerec *fr, const t_inputrec *ir,
+ t_forcerec *fr, const t_inputrec *ir,
const gmx_mtop_t *mtop, int gb_algorithm)
{
int i, j, m, ai, aj, jj, natoms, nalloc;
/* If Still model, initialise the polarisation energies */
if (gb_algorithm == egbSTILL)
{
- init_gb_still(cr, &(mtop->atomtypes), &(localtop->idef), &atoms,
+ init_gb_still(&(mtop->atomtypes), &(localtop->idef), &atoms,
born, natoms);
}
static int
-calc_gb_rad_still(t_commrec *cr, t_forcerec *fr, int natoms, gmx_localtop_t *top,
+calc_gb_rad_still(t_commrec *cr, t_forcerec *fr, gmx_localtop_t *top,
rvec x[], t_nblist *nl,
gmx_genborn_t *born, t_mdatoms *md)
{
}
/* Parallel summations */
- if (PARTDECOMP(cr))
- {
- gmx_sum(natoms, born->gpol_still_work, cr);
- }
- else if (DOMAINDECOMP(cr))
+ if (DOMAINDECOMP(cr))
{
dd_atom_sum_real(cr->dd, born->gpol_still_work);
}
static int
-calc_gb_rad_hct(t_commrec *cr, t_forcerec *fr, int natoms, gmx_localtop_t *top,
+calc_gb_rad_hct(t_commrec *cr, t_forcerec *fr, gmx_localtop_t *top,
rvec x[], t_nblist *nl,
gmx_genborn_t *born, t_mdatoms *md)
{
}
/* Parallel summations */
- if (PARTDECOMP(cr))
- {
- gmx_sum(natoms, born->gpol_hct_work, cr);
- }
- else if (DOMAINDECOMP(cr))
+ if (DOMAINDECOMP(cr))
{
dd_atom_sum_real(cr->dd, born->gpol_hct_work);
}
}
static int
-calc_gb_rad_obc(t_commrec *cr, t_forcerec *fr, int natoms, gmx_localtop_t *top,
+calc_gb_rad_obc(t_commrec *cr, t_forcerec *fr, gmx_localtop_t *top,
rvec x[], t_nblist *nl, gmx_genborn_t *born, t_mdatoms *md)
{
int i, k, ai, aj, nj0, nj1, n, at0, at1;
}
/* Parallel summations */
- if (PARTDECOMP(cr))
- {
- gmx_sum(natoms, born->gpol_hct_work, cr);
- }
- else if (DOMAINDECOMP(cr))
+ if (DOMAINDECOMP(cr))
{
dd_atom_sum_real(cr->dd, born->gpol_hct_work);
}
genborn_allvsall_calc_still_radii(fr, md, born, top, x[0], cr, &fr->AllvsAll_workgb);
}
#else
- genborn_allvsall_calc_still_radii(fr, md, born, top, x[0], cr, &fr->AllvsAll_workgb);
+ genborn_allvsall_calc_still_radii(fr, md, born, top, x[0], &fr->AllvsAll_workgb);
#endif
/* 13 flops in outer loop, 47 flops in inner loop */
inc_nrnb(nrnb, eNR_BORN_AVA_RADII_STILL, md->homenr*13+cnt*47);
genborn_allvsall_calc_hct_obc_radii(fr, md, born, ir->gb_algorithm, top, x[0], cr, &fr->AllvsAll_workgb);
}
#else
- genborn_allvsall_calc_hct_obc_radii(fr, md, born, ir->gb_algorithm, top, x[0], cr, &fr->AllvsAll_workgb);
+ genborn_allvsall_calc_hct_obc_radii(fr, md, born, ir->gb_algorithm, top, x[0], &fr->AllvsAll_workgb);
#endif
/* 24 flops in outer loop, 183 in inner */
inc_nrnb(nrnb, eNR_BORN_AVA_RADII_HCT_OBC, md->homenr*24+cnt*183);
}
else
{
- calc_gb_rad_still(cr, fr, born->nr, top, atype, x, nl, born, md);
+ calc_gb_rad_still(cr, fr, top, x, nl, born, md);
}
break;
case egbHCT:
}
else
{
- calc_gb_rad_hct(cr, fr, born->nr, top, atype, x, nl, born, md);
+ calc_gb_rad_hct(cr, fr, top, x, nl, born, md);
}
break;
case egbOBC:
}
else
{
- calc_gb_rad_obc(cr, fr, born->nr, top, atype, x, nl, born, md);
+ calc_gb_rad_obc(cr, fr, born->nr, top, x, nl, born, md);
}
break;
switch (ir->gb_algorithm)
{
case egbSTILL:
- calc_gb_rad_still(cr, fr, born->nr, top, x, nl, born, md);
+ calc_gb_rad_still(cr, fr, top, x, nl, born, md);
break;
case egbHCT:
- calc_gb_rad_hct(cr, fr, born->nr, top, x, nl, born, md);
+ calc_gb_rad_hct(cr, fr, top, x, nl, born, md);
break;
case egbOBC:
- calc_gb_rad_obc(cr, fr, born->nr, top, x, nl, born, md);
+ calc_gb_rad_obc(cr, fr, top, x, nl, born, md);
break;
default:
}
else
{
- calc_gb_rad_still(cr, fr, born->nr, top, x, nl, born, md);
+ calc_gb_rad_still(cr, fr, top, x, nl, born, md);
}
break;
case egbHCT:
}
else
{
- calc_gb_rad_hct(cr, fr, born->nr, top, x, nl, born, md);
+ calc_gb_rad_hct(cr, fr, top, x, nl, born, md);
}
break;
switch (ir->gb_algorithm)
{
case egbSTILL:
- calc_gb_rad_still(cr, fr, born->nr, top, x, nl, born, md);
+ calc_gb_rad_still(cr, fr, top, x, nl, born, md);
break;
case egbHCT:
- calc_gb_rad_hct(cr, fr, born->nr, top, x, nl, born, md);
+ calc_gb_rad_hct(cr, fr, top, x, nl, born, md);
break;
case egbOBC:
- calc_gb_rad_obc(cr, fr, born->nr, top, x, nl, born, md);
+ calc_gb_rad_obc(cr, fr, top, x, nl, born, md);
break;
default:
int i, ai, at0, at1;
real rai, e, derb, q, q2, fi, rai_inv, vtot;
- if (PARTDECOMP(cr))
- {
- pd_at_range(cr, &at0, &at1);
- }
- else if (DOMAINDECOMP(cr))
+ if (DOMAINDECOMP(cr))
{
at0 = 0;
at1 = cr->dd->nat_home;
/* To keep the compiler happy */
factor = 0;
- if (PARTDECOMP(cr))
- {
- pd_at_range(cr, &at0, &at1);
- }
- else if (DOMAINDECOMP(cr))
+ if (DOMAINDECOMP(cr))
{
at0 = 0;
at1 = cr->dd->nat_home;
enerd->term[F_GBPOL] += calc_gb_selfcorrections(cr, born->nr, md->chargeA, born, fr->dvda, fr->epsfac);
/* If parallel, sum the derivative of the potential w.r.t the born radii */
- if (PARTDECOMP(cr))
- {
- gmx_sum(md->nr, fr->dvda, cr);
- }
- else if (DOMAINDECOMP(cr))
+ if (DOMAINDECOMP(cr))
{
dd_atom_sum_real(cr->dd, fr->dvda);
dd_atom_spread_real(cr->dd, fr->dvda);
}
else
{
- /* Single node or particle decomp (global==local), just copy pointers and return */
+ /* Single node, just copy pointers and return */
if (gb_algorithm == egbSTILL)
{
born->gpol = born->gpol_globalindex;
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2009, The GROMACS Development Team.
- * Copyright (c) 2010, by the GROMACS development team, led by
+ * Copyright (c) 2010,2014, 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.
#include "vec.h"
#include "smalloc.h"
-#include "partdec.h"
#include "network.h"
#include "physics.h"
#include "genborn.h"
gmx_genborn_t * born,
gmx_localtop_t * top,
real * x,
- t_commrec * cr,
void * work)
{
gmx_allvsallgb2_data_t *aadata;
real term, prod, icf4, icf6, gpi2, factor, sinq;
natoms = mdatoms->nr;
- ni0 = mdatoms->start;
- ni1 = mdatoms->start+mdatoms->homenr;
+ ni0 = 0;
+ ni1 = mdatoms->homenr;
factor = 0.5*ONE_4PI_EPS0;
n = 0;
born->gpol_still_work[i] += gpi;
}
- /* Parallel summations */
- if (PARTDECOMP(cr))
- {
- gmx_sum(natoms, born->gpol_still_work, cr);
- }
+ /* Parallel summations would go here if ever implemented with DD */
/* Calculate the radii */
for (i = 0; i < natoms; i++)
int gb_algorithm,
gmx_localtop_t * top,
real * x,
- t_commrec * cr,
void * work)
{
gmx_allvsallgb2_data_t *aadata;
real rad, min_rad;
natoms = mdatoms->nr;
- ni0 = mdatoms->start;
- ni1 = mdatoms->start+mdatoms->homenr;
+ ni0 = 0;
+ ni1 = mdatoms->homenr;
n = 0;
prod = 0;
born->gpol_hct_work[i] += sum_ai;
}
- /* Parallel summations */
- if (PARTDECOMP(cr))
- {
- gmx_sum(natoms, born->gpol_hct_work, cr);
- }
+ /* Parallel summations would go here if ever implemented with DD */
if (gb_algorithm == egbHCT)
{
real * dadx;
natoms = mdatoms->nr;
- ni0 = mdatoms->start;
- ni1 = mdatoms->start+mdatoms->homenr;
+ ni0 = 0;
+ ni1 = mdatoms->homenr;
dadx = fr->dadx;
aadata = (gmx_allvsallgb2_data_t *)work;
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2009, The GROMACS Development Team.
- * Copyright (c) 2010, by the GROMACS development team, led by
+ * Copyright (c) 2010,2014, 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_genborn_t * born,
gmx_localtop_t * top,
real * x,
- t_commrec * cr,
void * work);
int
int gb_algorithm,
gmx_localtop_t * top,
real * x,
- t_commrec * cr,
void * work);
int
#include "vec.h"
#include "smalloc.h"
-#include "partdec.h"
#include "network.h"
#include "physics.h"
#include "genborn.h"
aadata->fz_align[i] = 0.0;
}
- setup_gb_exclusions_and_indices(aadata, top->idef.il, mdatoms->start, mdatoms->start+mdatoms->homenr, mdatoms->nr,
+ setup_gb_exclusions_and_indices(aadata, top->idef.il, 0, mdatoms->homenr, mdatoms->nr,
bInclude12, bInclude13, bInclude14);
}
__m128d still_p4_SSE, still_p5inv_SSE, still_pip5_SSE;
natoms = mdatoms->nr;
- ni0 = (mdatoms->start/SIMD_WIDTH)*SIMD_WIDTH;
- ni1 = mdatoms->start+mdatoms->homenr;
+ ni0 = 0;
+ ni1 = mdatoms->homenr;
n = 0;
work[i-natoms] += work[i];
}
- /* Parallel summations */
- if (PARTDECOMP(cr))
- {
- gmx_sum(natoms, work, cr);
- }
+ /* Parallel summations would go here if ever implemented with DD */
factor = 0.5 * ONE_4PI_EPS0;
/* Calculate the radii - should we do all atoms, or just our local ones? */
__m128d doffset_SSE, tmpSSE;
natoms = mdatoms->nr;
- ni0 = (mdatoms->start/SIMD_WIDTH)*SIMD_WIDTH;
- ni1 = mdatoms->start+mdatoms->homenr;
+ ni0 = 0;
+ ni1 = mdatoms->homenr;
n = 0;
work[i] += work[natoms+i];
}
- /* Parallel summations */
-
- if (PARTDECOMP(cr))
- {
- gmx_sum(natoms, work, cr);
- }
+ /* Parallel summations would go here if ever implemented in DD */
if (gb_algorithm == egbHCT)
{
__m128d t1, t2, tmpSSE;
natoms = mdatoms->nr;
- ni0 = (mdatoms->start/SIMD_WIDTH)*SIMD_WIDTH;
- ni1 = mdatoms->start+mdatoms->homenr;
+ ni0 = 0;
+ ni1 = mdatoms->homenr;
aadata = (gmx_allvsallgb2_data_t *)paadata;
#include "vec.h"
#include "smalloc.h"
-#include "partdec.h"
#include "network.h"
#include "physics.h"
#include "genborn.h"
aadata->fz_align[i] = 0.0;
}
- setup_gb_exclusions_and_indices(aadata, top->idef.il, mdatoms->start, mdatoms->start+mdatoms->homenr, mdatoms->nr,
+ setup_gb_exclusions_and_indices(aadata, top->idef.il, 0, mdatoms->homenr, mdatoms->nr,
bInclude12, bInclude13, bInclude14);
}
__m128 still_p4_SSE, still_p5inv_SSE, still_pip5_SSE;
natoms = mdatoms->nr;
- ni0 = (mdatoms->start/SIMD_WIDTH)*SIMD_WIDTH;
- ni1 = mdatoms->start+mdatoms->homenr;
+ ni0 = 0;
+ ni1 = mdatoms->homenr;
n = 0;
work[i-natoms] += work[i];
}
- /* Parallel summations */
- if (PARTDECOMP(cr))
- {
- gmx_sum(natoms, work, cr);
- }
+ /* Parallel summations would go here if ever implemented with DD */
factor = 0.5 * ONE_4PI_EPS0;
/* Calculate the radii - should we do all atoms, or just our local ones? */
__m128 doffset_SSE;
natoms = mdatoms->nr;
- ni0 = (mdatoms->start/SIMD_WIDTH)*SIMD_WIDTH;
- ni1 = mdatoms->start+mdatoms->homenr;
+ ni0 = 0;
+ ni1 = mdatoms->homenr;
n = 0;
work[i] += work[natoms+i];
}
- /* Parallel summations */
-
- if (PARTDECOMP(cr))
- {
- gmx_sum(natoms, work, cr);
- }
+ /* Parallel summations would go here if ever implemented with DD */
if (gb_algorithm == egbHCT)
{
__m128 t1, t2;
natoms = mdatoms->nr;
- ni0 = (mdatoms->start/SIMD_WIDTH)*SIMD_WIDTH;
- ni1 = mdatoms->start+mdatoms->homenr;
+ ni0 = 0;
+ ni1 = mdatoms->homenr;
dadx = fr->dadx;
aadata = (gmx_allvsallgb2_data_t *)paadata;
#include "names.h"
#include "physics.h"
#include "domdec.h"
-#include "partdec.h"
#include "network.h"
#include "gmx_fatal.h"
#include "mtop_util.h"
}
/* Sum up the polarization energy from other nodes */
- if (PARTDECOMP(cr))
- {
- gmx_sum(natoms, work, cr);
- }
- else if (DOMAINDECOMP(cr))
+ if (DOMAINDECOMP(cr))
{
dd_atom_sum_real(cr->dd, work);
}
}
/* Parallel summations */
- if (PARTDECOMP(cr))
- {
- gmx_sum(natoms, work, cr);
- }
- else if (DOMAINDECOMP(cr))
+ if (DOMAINDECOMP(cr))
{
dd_atom_sum_real(cr->dd, work);
}
#include "gromacs/fileio/pdbio.h"
#include "names.h"
#include "physics.h"
-#include "partdec.h"
#include "domdec.h"
#include "network.h"
#include "gmx_fatal.h"
}
/* Sum up the polarization energy from other nodes */
- if (PARTDECOMP(cr))
- {
- gmx_sum(natoms, work, cr);
- }
- else if (DOMAINDECOMP(cr))
+ if (DOMAINDECOMP(cr))
{
dd_atom_sum_real(cr->dd, work);
}
}
/* Parallel summations */
- if (PARTDECOMP(cr))
- {
- gmx_sum(natoms, work, cr);
- }
- else if (DOMAINDECOMP(cr))
+ if (DOMAINDECOMP(cr))
{
dd_atom_sum_real(cr->dd, work);
}
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014, 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.
/* Calculate center of mass velocity if necessary, also parallellized */
if (bStopCM)
{
- calc_vcm_grp(mdatoms->start, mdatoms->homenr, mdatoms,
+ calc_vcm_grp(0, mdatoms->homenr, mdatoms,
state->x, state->v, vcm);
}
if (!ekind->bNEMD && debug && bTemp && (vcm->nr > 0))
{
correct_ekin(debug,
- mdatoms->start, mdatoms->start+mdatoms->homenr,
+ 0, mdatoms->homenr,
state->v, vcm->group_p[0],
mdatoms->massT, mdatoms->tmass, ekind->ekin);
}
if (bStopCM)
{
check_cm_grp(fplog, vcm, ir, 1);
- do_stopcm_grp(mdatoms->start, mdatoms->homenr, mdatoms->cVCM,
+ do_stopcm_grp(0, mdatoms->homenr, mdatoms->cVCM,
state->x, state->v, vcm);
inc_nrnb(nrnb, eNR_STOPCM, mdatoms->homenr);
}
*bNotLastFrame = (fr->natoms >= 0);
- if (*bNotLastFrame && PARTDECOMP(cr))
- {
- /* x and v are the only variable size quantities stored in trr
- * that are required for rerun (f is not needed).
- */
- if (bAlloc)
- {
- snew(fr->x, fr->natoms);
- snew(fr->v, fr->natoms);
- }
- if (fr->bX)
- {
- gmx_bcast(fr->natoms*sizeof(fr->x[0]), fr->x[0], cr);
- }
- if (fr->bV)
- {
- gmx_bcast(fr->natoms*sizeof(fr->v[0]), fr->v[0], cr);
- }
- }
}
void atoms2md(gmx_mtop_t *mtop, t_inputrec *ir,
int nindex, int *index,
- int start, int homenr,
+ int homenr,
t_mdatoms *md)
{
gmx_mtop_atomlookup_t alook;
molblock = mtop->molblock;
- /* Index==NULL indicates particle decomposition,
- * unless we have an empty DD node, so also check for homenr and start.
- * This should be signaled properly with an extra parameter or nindex==-1.
+ /* Index==NULL indicates no DD (unless we have a DD node with no
+ * atoms), so also check for homenr. This should be
+ * signaled properly with an extra parameter or nindex==-1.
*/
- if (index == NULL && (homenr > 0 || start > 0))
+ if (index == NULL && (homenr > 0))
{
md->nr = mtop->natoms;
}
gmx_mtop_atomlookup_destroy(alook);
- md->start = start;
md->homenr = homenr;
md->lambda = 0;
}
#include "md_support.h"
#include "sim_util.h"
#include "domdec.h"
-#include "partdec.h"
#include "mdatoms.h"
#include "ns.h"
#include "mtop_util.h"
fmax2 = 0;
la_max = -1;
gf = 0;
- start = mdatoms->start;
- end = mdatoms->homenr + start;
+ start = 0;
+ end = mdatoms->homenr;
if (mdatoms->cFREEZE)
{
for (i = start; i < end; i++)
int nfile, const t_filenm fnm[],
gmx_mdoutf_t *outf, t_mdebin **mdebin)
{
- int start, homenr, i;
+ int i;
real dvdl_constr;
if (fplog)
}
copy_mat(state_global->box, ems->s.box);
- if (PAR(cr) && ir->eI != eiNM)
- {
- /* Initialize the particle decomposition and split the topology */
- *top = split_system(fplog, top_global, ir, cr);
-
- pd_cg_range(cr, &fr->cg0, &fr->hcg);
- }
- else
- {
- *top = gmx_mtop_generate_local_top(top_global, ir);
- }
+ *top = gmx_mtop_generate_local_top(top_global, ir);
*f_global = *f;
- forcerec_set_excl_load(fr, *top, cr);
+ forcerec_set_excl_load(fr, *top);
setup_bonded_threading(fr, &(*top)->idef);
*graph = NULL;
}
- if (PARTDECOMP(cr))
- {
- pd_at_range(cr, &start, &homenr);
- homenr -= start;
- }
- else
- {
- start = 0;
- homenr = top_global->natoms;
- }
- atoms2md(top_global, ir, 0, NULL, start, homenr, mdatoms);
+ atoms2md(top_global, ir, 0, NULL, top_global->natoms, mdatoms);
update_mdatoms(mdatoms, state_global->lambda[efptFEP]);
if (vsite)
}
copy_mat(s1->box, s2->box);
- start = md->start;
- end = md->start + md->homenr;
+ start = 0;
+ end = md->homenr;
x1 = s1->x;
x2 = s2->x;
if (bFirst ||
(DOMAINDECOMP(cr) && ems->s.ddp_count < cr->dd->ddp_count))
{
- /* This the first state or an old state used before the last ns */
+ /* This is the first state or an old state used before the last ns */
bNS = TRUE;
}
else
{
construct_vsites(vsite, ems->s.x, 1, NULL,
top->idef.iparams, top->idef.il,
- fr->ePBC, fr->bMolPBC, graph, cr, ems->s.box);
+ fr->ePBC, fr->bMolPBC, cr, ems->s.box);
}
- if (DOMAINDECOMP(cr))
+ if (DOMAINDECOMP(cr) && bNS)
{
- if (bNS)
- {
- /* Repartition the domain decomposition */
- em_dd_partition_system(fplog, count, cr, top_global, inputrec,
- ems, top, mdatoms, fr, vsite, constr,
- nrnb, wcycle);
- }
+ /* Repartition the domain decomposition */
+ em_dd_partition_system(fplog, count, cr, top_global, inputrec,
+ ems, top, mdatoms, fr, vsite, constr,
+ nrnb, wcycle);
}
/* Calc force & energy on new trial position */
/* This part of code can be incorrect with DD,
* since the atom ordering in s_b and s_min might differ.
*/
- for (i = mdatoms->start; i < mdatoms->start+mdatoms->homenr; i++)
+ for (i = 0; i < mdatoms->homenr; i++)
{
if (mdatoms->cFREEZE)
{
sf = s_min->f;
gpa = 0;
gf = 0;
- for (i = mdatoms->start; i < mdatoms->start+mdatoms->homenr; i++)
+ for (i = 0; i < mdatoms->homenr; i++)
{
if (mdatoms->cFREEZE)
{
* relative change in coordinate is smaller than precision
*/
minstep = 0;
- for (i = mdatoms->start; i < mdatoms->start+mdatoms->homenr; i++)
+ for (i = 0; i < mdatoms->homenr; i++)
{
for (m = 0; m < DIM; m++)
{
p = s_c->s.cg_p;
sf = s_c->f;
gpc = 0;
- for (i = mdatoms->start; i < mdatoms->start+mdatoms->homenr; i++)
+ for (i = 0; i < mdatoms->homenr; i++)
{
for (m = 0; m < DIM; m++)
{
p = s_b->s.cg_p;
sf = s_b->f;
gpb = 0;
- for (i = mdatoms->start; i < mdatoms->start+mdatoms->homenr; i++)
+ for (i = 0; i < mdatoms->homenr; i++)
{
for (m = 0; m < DIM; m++)
{
xx = (real *)state->x;
ff = (real *)f;
- start = mdatoms->start;
- end = mdatoms->homenr + start;
+ start = 0;
+ end = mdatoms->homenr;
/* Print to log file */
print_em_start(fplog, cr, walltime_accounting, wcycle, LBFGS);
{
construct_vsites(vsite, state->x, 1, NULL,
top->idef.iparams, top->idef.il,
- fr->ePBC, fr->bMolPBC, graph, cr, state->box);
+ fr->ePBC, fr->bMolPBC, cr, state->box);
}
/* Call the force routine and some auxiliary (neighboursearching etc.) */
+++ /dev/null
-/*
- * This file is part of the GROMACS molecular simulation package.
- *
- * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
- * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, 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.
- */
-/* This file is completely threadsafe - keep it that way! */
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <string.h>
-
-#include "typedefs.h"
-#include "main.h"
-#include "mvdata.h"
-#include "network.h"
-#include "smalloc.h"
-#include "gmx_fatal.h"
-#include "symtab.h"
-#include "main.h"
-#include "typedefs.h"
-#include "vec.h"
-#include "tgroup.h"
-#include "nrnb.h"
-#include "partdec.h"
-
-void move_rvecs(const t_commrec *cr, gmx_bool bForward, gmx_bool bSum,
- rvec vecs[], rvec buf[],
- int shift, t_nrnb *nrnb)
-{
- int i, j, j0 = 137, j1 = 391;
- int cur, nsum;
- int *index;
-#define next ((cur + 1) % cr->nnodes)
-#define prev ((cur - 1 + cr->nnodes) % cr->nnodes)
-
-#define HOMENRI(ind, i) ((ind)[(i)+1] - (ind)[(i)])
-
- index = pd_index(cr);
-
- if (bSum)
- {
- cur = (cr->nodeid + pd_shift(cr)) % cr->nnodes;
- }
- else
- {
- cur = cr->nodeid;
- }
-
- nsum = 0;
- for (i = 0; (i < shift); i++)
- {
- if (bSum)
- {
- if (bForward)
- {
- j0 = index[prev];
- j1 = index[prev+1];
- }
- else
- {
- j0 = index[next];
- j1 = index[next+1];
- }
- for (j = j0; (j < j1); j++)
- {
- clear_rvec(buf[j]);
- }
- }
- /* Forward pulse around the ring, to increasing NODE number */
- if (bForward)
- {
- if (bSum)
- {
- gmx_tx_rx_real(cr,
- GMX_RIGHT, vecs[index[cur ]], HOMENRI(index, cur )*DIM,
- GMX_LEFT, buf [index[prev]], HOMENRI(index, prev)*DIM);
- }
- else
- {
- gmx_tx_rx_real(cr,
- GMX_RIGHT, vecs[index[cur ]], HOMENRI(index, cur )*DIM,
- GMX_LEFT, vecs[index[prev]], HOMENRI(index, prev)*DIM);
- }
- /* Wait for communication to end */
- gmx_wait(cr);
- }
-
- /* Backward pulse around the ring, to decreasing NODE number */
- else
- {
- if (bSum)
- {
- gmx_tx_rx_real(cr,
- GMX_LEFT, vecs[index[cur ]], HOMENRI(index, cur )*DIM,
- GMX_RIGHT, buf [index[next]], HOMENRI(index, next)*DIM);
- }
- else
- {
- gmx_tx_rx_real(cr,
- GMX_LEFT, vecs[index[cur ]], HOMENRI(index, cur )*DIM,
- GMX_RIGHT, vecs[index[next]], HOMENRI(index, next)*DIM);
- }
- /* Wait for communication to end */
- gmx_wait(cr);
- }
-
- /* Actual summation */
- if (bSum)
- {
- for (j = j0; (j < j1); j++)
- {
- rvec_inc(vecs[j], buf[j]);
- }
- nsum += (j1-j0);
- }
- if (bForward)
- {
- cur = prev;
- }
- else
- {
- cur = next;
- }
- }
- if (nsum > 0)
- {
- inc_nrnb(nrnb, eNR_FSUM, nsum);
- }
-#undef next
-#undef prev
-}
-
-
-void move_x(const t_commrec *cr,
- rvec x[], t_nrnb *nrnb)
-{
- move_rvecs(cr, FALSE, FALSE, x, NULL, pd_shift(cr), nrnb);
- move_rvecs(cr, TRUE, FALSE, x, NULL, pd_bshift(cr), nrnb);
-
- where();
-}
-
-
-void move_f(const t_commrec *cr,
- rvec f[], rvec fadd[],
- t_nrnb *nrnb)
-{
- move_rvecs(cr, TRUE, TRUE, f, fadd, pd_shift(cr), nrnb);
- move_rvecs(cr, FALSE, TRUE, f, fadd, pd_bshift(cr), nrnb);
-
- where();
-}
-
-void move_cgcm(FILE gmx_unused *log, const t_commrec *cr, rvec cg_cm[])
-{
- int i, start, nr;
- int cur = cr->nodeid;
- int *cgindex;
-
-#define next ((cur+1) % cr->nnodes)
-
- cgindex = pd_cgindex(cr);
-
- for (i = 0; (i < cr->nnodes-1); i++)
- {
- start = cgindex[cur];
- nr = cgindex[cur+1] - start;
-
- gmx_tx(cr, GMX_LEFT, cg_cm[start], nr*sizeof(cg_cm[0]));
-#ifdef DEBUG
- fprintf(log, "move_cgcm: TX start=%d, nr=%d\n", start, nr);
-#endif
- start = cgindex[next];
- nr = cgindex[next+1] - start;
-
- gmx_rx(cr, GMX_RIGHT, cg_cm[start], nr*sizeof(cg_cm[0]));
-#ifdef DEBUG
- fprintf(log, "move_cgcm: RX start=%d, nr=%d\n", start, nr);
-#endif
- gmx_tx_wait(cr);
- gmx_rx_wait(cr);
-
- if (debug)
- {
- fprintf(debug, "cgcm[0][XX] %f\n", cg_cm[0][XX]);
- }
-
- cur = next;
- }
-#undef next
-}
ns->bexcl = NULL;
if (!DOMAINDECOMP(cr))
{
- /* This could be reduced with particle decomposition */
ns_realloc_natoms(ns, mtop->natoms);
}
}
debug_gmx();
- /* Don't know why this all is... (DvdS 3/99) */
-#ifndef SEGV
start = 0;
end = cgs->nr;
-#else
- start = fr->cg0;
- end = (cgs->nr+1)/2;
-#endif
if (DOMAINDECOMP(cr))
{
grid->icg0 = fr->cg0;
grid->icg1 = fr->hcg;
debug_gmx();
-
- if (PARTDECOMP(cr))
- {
- mv_grid(cr, grid);
- }
- debug_gmx();
}
calc_elemnr(grid, start, end, cgs->nr);
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014, 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.
#include "vec.h"
#include "network.h"
#include "domdec.h"
-#include "partdec.h"
#include "pbc.h"
#include <stdio.h>
#include "gromacs/fileio/futil.h"
}
fflush(log);
}
-
-void mv_grid(t_commrec *cr, t_grid *grid)
-{
- int i, start, nr;
- int cur = cr->nodeid;
- int *ci, *cgindex;
-#define next ((cur+1) % (cr->nnodes-cr->npmenodes))
-
- ci = grid->cell_index;
- cgindex = pd_cgindex(cr);
- for (i = 0; (i < cr->nnodes-1); i++)
- {
- start = cgindex[cur];
- nr = cgindex[cur+1] - start;
- gmx_tx(cr, GMX_LEFT, &(ci[start]), nr*sizeof(*ci));
-
- start = cgindex[next];
- nr = cgindex[next+1] - start;
- gmx_rx(cr, GMX_RIGHT, &(ci[start]), nr*sizeof(*ci));
-
- gmx_tx_wait(cr);
- gmx_rx_wait(cr);
-
- cur = next;
- }
-}
+++ /dev/null
-/*
- * This file is part of the GROMACS molecular simulation package.
- *
- * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
- * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, 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.
- */
-/* This file is completely threadsafe - keep it that way! */
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <math.h>
-
-#include "sysstuff.h"
-#include "typedefs.h"
-#include "smalloc.h"
-#include "invblock.h"
-#include "macros.h"
-#include "main.h"
-#include "ns.h"
-#include "partdec.h"
-#include "splitter.h"
-#include "gromacs/random/random.h"
-#include "mtop_util.h"
-#include "mvdata.h"
-#include "vec.h"
-
-typedef struct gmx_partdec_constraint
-{
- int left_range_receive;
- int right_range_receive;
- int left_range_send;
- int right_range_send;
- int nconstraints;
- int * nlocalatoms;
- rvec * sendbuf;
- rvec * recvbuf;
-}
-gmx_partdec_constraint_t;
-
-
-typedef struct gmx_partdec {
- int neighbor[2]; /* The nodeids of left and right neighb */
- int *cgindex; /* The charge group boundaries, */
- /* size nnodes+1, */
- /* only allocated with particle decomp. */
- int *index; /* The home particle boundaries, */
- /* size nnodes+1, */
- /* only allocated with particle decomp. */
- int shift, bshift; /* Coordinates are shifted left for */
- /* 'shift' systolic pulses, and right */
- /* for 'bshift' pulses. Forces are */
- /* shifted right for 'shift' pulses */
- /* and left for 'bshift' pulses */
- /* This way is not necessary to shift */
- /* the coordinates over the entire ring */
- rvec *vbuf; /* Buffer for summing the forces */
-#ifdef GMX_MPI
- MPI_Request mpi_req_rx; /* MPI reqs for async transfers */
- MPI_Request mpi_req_tx;
-#endif
- gmx_partdec_constraint_t * constraints;
-} gmx_partdec_t;
-
-
-void gmx_tx(const t_commrec gmx_unused *cr, int gmx_unused dir, void gmx_unused *buf, int gmx_unused bufsize)
-{
-#ifndef GMX_MPI
- gmx_call("gmx_tx");
-#else
- int nodeid;
- int tag, flag;
- MPI_Status status;
-
- nodeid = cr->pd->neighbor[dir];
-
-#ifdef DEBUG
- fprintf(stderr, "gmx_tx: nodeid=%d, buf=%x, bufsize=%d\n",
- nodeid, buf, bufsize);
-#endif
-#ifdef MPI_TEST
- /* workaround for crashes encountered with MPI on IRIX 6.5 */
- if (cr->pd->mpi_req_tx != MPI_REQUEST_NULL)
- {
- MPI_Test(&cr->pd->mpi_req_tx, &flag, &status);
- if (flag == FALSE)
- {
- fprintf(stdlog, "gmx_tx called before previous send was complete: nodeid=%d, buf=%x, bufsize=%d\n",
- nodeid, buf, bufsize);
- gmx_tx_wait(nodeid);
- }
- }
-#endif
- tag = 0;
- if (MPI_Isend(buf, bufsize, MPI_BYTE, RANK(cr, nodeid), tag, cr->mpi_comm_mygroup, &cr->pd->mpi_req_tx) != 0)
- {
- gmx_comm("MPI_Isend Failed");
- }
-#endif
-}
-
-void gmx_tx_wait(const t_commrec gmx_unused *cr)
-{
-#ifndef GMX_MPI
- gmx_call("gmx_tx_wait");
-#else
- MPI_Status status;
- int mpi_result;
-
- if ((mpi_result = MPI_Wait(&cr->pd->mpi_req_tx, &status)) != 0)
- {
- gmx_fatal(FARGS, "MPI_Wait: result=%d", mpi_result);
- }
-#endif
-}
-
-void gmx_rx(const t_commrec gmx_unused *cr, int gmx_unused dir, void gmx_unused *buf, int gmx_unused bufsize)
-{
-#ifndef GMX_MPI
- gmx_call("gmx_rx");
-#else
- int nodeid;
- int tag;
-
- nodeid = cr->pd->neighbor[dir];
-#ifdef DEBUG
- fprintf(stderr, "gmx_rx: nodeid=%d, buf=%x, bufsize=%d\n",
- nodeid, buf, bufsize);
-#endif
- tag = 0;
- if (MPI_Irecv( buf, bufsize, MPI_BYTE, RANK(cr, nodeid), tag, cr->mpi_comm_mygroup, &cr->pd->mpi_req_rx) != 0)
- {
- gmx_comm("MPI_Recv Failed");
- }
-#endif
-}
-
-void gmx_rx_wait(const t_commrec gmx_unused *cr)
-{
-#ifndef GMX_MPI
- gmx_call("gmx_rx_wait");
-#else
- MPI_Status status;
- int mpi_result;
-
- if ((mpi_result = MPI_Wait(&cr->pd->mpi_req_rx, &status)) != 0)
- {
- gmx_fatal(FARGS, "MPI_Wait: result=%d", mpi_result);
- }
-#endif
-}
-
-void gmx_tx_rx_real(const t_commrec gmx_unused *cr,
- int gmx_unused send_dir, real gmx_unused *send_buf, int gmx_unused send_bufsize,
- int gmx_unused recv_dir, real gmx_unused *recv_buf, int gmx_unused recv_bufsize)
-{
-#ifndef GMX_MPI
- gmx_call("gmx_tx_rx_real");
-#else
- int send_nodeid, recv_nodeid;
- int tx_tag = 0, rx_tag = 0;
- MPI_Status stat;
-
- send_nodeid = cr->pd->neighbor[send_dir];
- recv_nodeid = cr->pd->neighbor[recv_dir];
-
-#ifdef GMX_DOUBLE
-#define mpi_type MPI_DOUBLE
-#else
-#define mpi_type MPI_FLOAT
-#endif
-
- if (send_bufsize > 0 && recv_bufsize > 0)
- {
- MPI_Sendrecv(send_buf, send_bufsize, mpi_type, RANK(cr, send_nodeid), tx_tag,
- recv_buf, recv_bufsize, mpi_type, RANK(cr, recv_nodeid), rx_tag,
- cr->mpi_comm_mygroup, &stat);
- }
- else if (send_bufsize > 0)
- {
- MPI_Send(send_buf, send_bufsize, mpi_type, RANK(cr, send_nodeid), tx_tag,
- cr->mpi_comm_mygroup);
- }
- else if (recv_bufsize > 0)
- {
- MPI_Recv(recv_buf, recv_bufsize, mpi_type, RANK(cr, recv_nodeid), rx_tag,
- cr->mpi_comm_mygroup, &stat);
- }
-#undef mpi_type
-#endif
-}
-
-
-void gmx_tx_rx_void(const t_commrec gmx_unused *cr,
- int gmx_unused send_dir, void gmx_unused *send_buf, int gmx_unused send_bufsize,
- int gmx_unused recv_dir, void gmx_unused *recv_buf, int gmx_unused recv_bufsize)
-{
-#ifndef GMX_MPI
- gmx_call("gmx_tx_rx_void");
-#else
- int send_nodeid, recv_nodeid;
- int tx_tag = 0, rx_tag = 0;
- MPI_Status stat;
-
- send_nodeid = cr->pd->neighbor[send_dir];
- recv_nodeid = cr->pd->neighbor[recv_dir];
-
-
- MPI_Sendrecv(send_buf, send_bufsize, MPI_BYTE, RANK(cr, send_nodeid), tx_tag,
- recv_buf, recv_bufsize, MPI_BYTE, RANK(cr, recv_nodeid), rx_tag,
- cr->mpi_comm_mygroup, &stat);
-
-#endif
-}
-
-
-/*void gmx_wait(int dir_send,int dir_recv)*/
-
-void gmx_wait(const t_commrec gmx_unused *cr)
-{
-#ifndef GMX_MPI
- gmx_call("gmx_wait");
-#else
- gmx_tx_wait(cr);
- gmx_rx_wait(cr);
-#endif
-}
-
-static void set_left_right(t_commrec *cr)
-{
- cr->pd->neighbor[GMX_LEFT] = (cr->nnodes + cr->nodeid - 1) % cr->nnodes;
- cr->pd->neighbor[GMX_RIGHT] = (cr->nodeid + 1) % cr->nnodes;
-}
-
-void pd_move_f(const t_commrec *cr, rvec f[], t_nrnb *nrnb)
-{
- move_f(cr, f, cr->pd->vbuf, nrnb);
-}
-
-int *pd_cgindex(const t_commrec *cr)
-{
- return cr->pd->cgindex;
-}
-
-int *pd_index(const t_commrec *cr)
-{
- return cr->pd->index;
-}
-
-int pd_shift(const t_commrec *cr)
-{
- return cr->pd->shift;
-}
-
-int pd_bshift(const t_commrec *cr)
-{
- return cr->pd->bshift;
-}
-
-void pd_cg_range(const t_commrec *cr, int *cg0, int *cg1)
-{
- *cg0 = cr->pd->cgindex[cr->nodeid];
- *cg1 = cr->pd->cgindex[cr->nodeid+1];
-}
-
-void pd_at_range(const t_commrec *cr, int *at0, int *at1)
-{
- *at0 = cr->pd->index[cr->nodeid];
- *at1 = cr->pd->index[cr->nodeid+1];
-}
-
-void
-pd_get_constraint_range(gmx_partdec_p_t pd, int *start, int *natoms)
-{
- *start = pd->constraints->left_range_receive;
- *natoms = pd->constraints->right_range_receive-pd->constraints->left_range_receive;
-}
-
-int *
-pd_constraints_nlocalatoms(gmx_partdec_p_t pd)
-{
- int *rc;
-
- if (NULL != pd && NULL != pd->constraints)
- {
- rc = pd->constraints->nlocalatoms;
- }
- else
- {
- rc = NULL;
- }
- return rc;
-}
-
-
-
-
-/* This routine is used to communicate the non-home-atoms needed for constrains.
- * We have already calculated this range of atoms during setup, and stored in the
- * partdec constraints structure.
- *
- * When called, we send/receive left_range_send/receive atoms to our left (lower)
- * node neighbor, and similar to the right (higher) node.
- *
- * This has not been tested for periodic molecules...
- */
-void
-pd_move_x_constraints(t_commrec gmx_unused *cr,
- rvec gmx_unused *x0,
- rvec gmx_unused *x1)
-{
-#ifdef GMX_MPI
- gmx_partdec_t *pd;
- gmx_partdec_constraint_t *pdc;
-
- rvec * sendptr;
- rvec * recvptr;
- int thisnode;
- int i;
- int cnt;
- int sendcnt, recvcnt;
-
- pd = cr->pd;
- pdc = pd->constraints;
-
- if (pdc == NULL)
- {
- return;
- }
-
- thisnode = cr->nodeid;
-
- /* First pulse to right */
-
- recvcnt = 3*(pd->index[thisnode]-pdc->left_range_receive);
- sendcnt = 3*(cr->pd->index[thisnode+1]-cr->pd->constraints->right_range_send);
-
- if (x1 != NULL)
- {
- /* Assemble temporary array with both x0 & x1 */
- recvptr = pdc->recvbuf;
- sendptr = pdc->sendbuf;
-
- cnt = 0;
- for (i = pdc->right_range_send; i < pd->index[thisnode+1]; i++)
- {
- copy_rvec(x0[i], sendptr[cnt++]);
- }
- for (i = pdc->right_range_send; i < pd->index[thisnode+1]; i++)
- {
- copy_rvec(x1[i], sendptr[cnt++]);
- }
- recvcnt *= 2;
- sendcnt *= 2;
- }
- else
- {
- recvptr = x0 + pdc->left_range_receive;
- sendptr = x0 + pdc->right_range_send;
- }
-
- gmx_tx_rx_real(cr,
- GMX_RIGHT, (real *)sendptr, sendcnt,
- GMX_LEFT, (real *)recvptr, recvcnt);
-
- if (x1 != NULL)
- {
- /* copy back to x0/x1 */
- cnt = 0;
- for (i = pdc->left_range_receive; i < pd->index[thisnode]; i++)
- {
- copy_rvec(recvptr[cnt++], x0[i]);
- }
- for (i = pdc->left_range_receive; i < pd->index[thisnode]; i++)
- {
- copy_rvec(recvptr[cnt++], x1[i]);
- }
- }
-
- /* And pulse to left */
- sendcnt = 3*(pdc->left_range_send-pd->index[thisnode]);
- recvcnt = 3*(pdc->right_range_receive-pd->index[thisnode+1]);
-
- if (x1 != NULL)
- {
- cnt = 0;
- for (i = cr->pd->index[thisnode]; i < pdc->left_range_send; i++)
- {
- copy_rvec(x0[i], sendptr[cnt++]);
- }
- for (i = cr->pd->index[thisnode]; i < pdc->left_range_send; i++)
- {
- copy_rvec(x1[i], sendptr[cnt++]);
- }
- recvcnt *= 2;
- sendcnt *= 2;
- }
- else
- {
- sendptr = x0 + pd->index[thisnode];
- recvptr = x0 + pd->index[thisnode+1];
- }
-
- gmx_tx_rx_real(cr,
- GMX_LEFT, (real *)sendptr, sendcnt,
- GMX_RIGHT, (real *)recvptr, recvcnt);
-
- /* Final copy back from buffers */
- if (x1 != NULL)
- {
- /* First copy received data back into x0 & x1 */
- cnt = 0;
- for (i = pd->index[thisnode+1]; i < pdc->right_range_receive; i++)
- {
- copy_rvec(recvptr[cnt++], x0[i]);
- }
- for (i = pd->index[thisnode+1]; i < pdc->right_range_receive; i++)
- {
- copy_rvec(recvptr[cnt++], x1[i]);
- }
- }
-#endif
-}
-
-static int home_cpu(int nnodes, gmx_partdec_t *pd, int atomid)
-{
- int k;
-
- for (k = 0; (k < nnodes); k++)
- {
- if (atomid < pd->index[k+1])
- {
- return k;
- }
- }
- gmx_fatal(FARGS, "Atomid %d is larger than number of atoms (%d)",
- atomid+1, pd->index[nnodes]+1);
-
- return -1;
-}
-
-static void calc_nsbshift(FILE *fp, int nnodes, gmx_partdec_t *pd, t_idef *idef)
-{
- int i, j, k;
- int lastcg, targetcg, nshift, naaj;
- int homeid[32];
-
- pd->bshift = 0;
- for (i = 1; (i < nnodes); i++)
- {
- targetcg = pd->cgindex[i];
- for (nshift = i; (nshift > 0) && (pd->cgindex[nshift] > targetcg); nshift--)
- {
- ;
- }
- pd->bshift = max(pd->bshift, i-nshift);
- }
-
- pd->shift = (nnodes + 1)/2;
- for (i = 0; (i < nnodes); i++)
- {
- lastcg = pd->cgindex[i+1]-1;
- naaj = calc_naaj(lastcg, pd->cgindex[nnodes]);
- targetcg = (lastcg+naaj) % pd->cgindex[nnodes];
-
- /* Search until we find the target charge group */
- for (nshift = 0;
- (nshift < nnodes) && (targetcg > pd->cgindex[nshift+1]);
- nshift++)
- {
- ;
- }
- /* Now compute the shift, that is the difference in node index */
- nshift = ((nshift - i + nnodes) % nnodes);
-
- if (fp)
- {
- fprintf(fp, "CPU=%3d, lastcg=%5d, targetcg=%5d, myshift=%5d\n",
- i, lastcg, targetcg, nshift);
- }
-
- /* It's the largest shift that matters */
- pd->shift = max(nshift, pd->shift);
- }
- /* Now for the bonded forces */
- for (i = 0; (i < F_NRE); i++)
- {
- if (interaction_function[i].flags & IF_BOND)
- {
- int nratoms = interaction_function[i].nratoms;
- for (j = 0; (j < idef->il[i].nr); j += nratoms+1)
- {
- for (k = 1; (k <= nratoms); k++)
- {
- homeid[k-1] = home_cpu(nnodes, pd, idef->il[i].iatoms[j+k]);
- }
- for (k = 1; (k < nratoms); k++)
- {
- pd->shift = max(pd->shift, abs(homeid[k]-homeid[0]));
- }
- }
- }
- }
- if (fp)
- {
- fprintf(fp, "pd->shift = %3d, pd->bshift=%3d\n",
- pd->shift, pd->bshift);
- }
-}
-
-
-static void
-init_partdec_constraint(t_commrec *cr,
- t_idef * idef,
- int *left_range,
- int *right_range)
-{
- gmx_partdec_t * pd = cr->pd;
- gmx_partdec_constraint_t *pdc;
- int i, cnt, k;
- int ai, aj, nodei, nodej;
- int nratoms;
- int nodeid;
-
- snew(pdc, 1);
- cr->pd->constraints = pdc;
-
-
- /* Who am I? */
- nodeid = cr->nodeid;
-
- /* Setup LINCS communication ranges */
- pdc->left_range_receive = left_range[nodeid];
- pdc->right_range_receive = right_range[nodeid]+1;
- pdc->left_range_send = (nodeid > 0) ? right_range[nodeid-1]+1 : 0;
- pdc->right_range_send = (nodeid < cr->nnodes-1) ? left_range[nodeid+1] : pd->index[cr->nnodes];
-
- snew(pdc->nlocalatoms, idef->il[F_CONSTR].nr);
- nratoms = interaction_function[F_CONSTR].nratoms;
-
- for (i = 0, cnt = 0; i < idef->il[F_CONSTR].nr; i += nratoms+1, cnt++)
- {
- ai = idef->il[F_CONSTR].iatoms[i+1];
- aj = idef->il[F_CONSTR].iatoms[i+2];
- nodei = 0;
- while (ai >= pd->index[nodei+1])
- {
- nodei++;
- }
- nodej = 0;
- while (aj >= pd->index[nodej+1])
- {
- nodej++;
- }
- pdc->nlocalatoms[cnt] = 0;
- if (nodei == nodeid)
- {
- pdc->nlocalatoms[cnt]++;
- }
- if (nodej == nodeid)
- {
- pdc->nlocalatoms[cnt]++;
- }
- }
- pdc->nconstraints = cnt;
-
- snew(pdc->sendbuf, max(6*(pd->index[cr->nodeid+1]-pd->constraints->right_range_send), 6*(pdc->left_range_send-pd->index[cr->nodeid])));
- snew(pdc->recvbuf, max(6*(pd->index[cr->nodeid]-pdc->left_range_receive), 6*(pdc->right_range_receive-pd->index[cr->nodeid+1])));
-
-}
-
-static void init_partdec(FILE *fp, t_commrec *cr, t_block *cgs, int *multinr,
- t_idef *idef)
-{
- int i, nodeid;
- gmx_partdec_t *pd;
-
- snew(pd, 1);
- cr->pd = pd;
-
- set_left_right(cr);
-
- if (cr->nnodes > 1)
- {
- if (multinr == NULL)
- {
- gmx_fatal(FARGS, "Internal error in init_partdec: multinr = NULL");
- }
- snew(pd->index, cr->nnodes+1);
- snew(pd->cgindex, cr->nnodes+1);
- pd->cgindex[0] = 0;
- pd->index[0] = 0;
- for (i = 0; (i < cr->nnodes); i++)
- {
- pd->cgindex[i+1] = multinr[i];
- pd->index[i+1] = cgs->index[multinr[i]];
- }
- calc_nsbshift(fp, cr->nnodes, pd, idef);
- /* This is a hack to do with bugzilla 148 */
- /*pd->shift = cr->nnodes-1;
- pd->bshift = 0;*/
-
- /* Allocate a buffer of size natoms of the whole system
- * for summing the forces over the nodes.
- */
- snew(pd->vbuf, cgs->index[cgs->nr]);
- pd->constraints = NULL;
- }
-#ifdef GMX_MPI
- pd->mpi_req_tx = MPI_REQUEST_NULL;
- pd->mpi_req_rx = MPI_REQUEST_NULL;
-#endif
-}
-
-static void print_partdec(FILE *fp, const char *title,
- int nnodes, gmx_partdec_t *pd)
-{
- int i;
-
- fprintf(fp, "%s\n", title);
- fprintf(fp, "nnodes: %5d\n", nnodes);
- fprintf(fp, "pd->shift: %5d\n", pd->shift);
- fprintf(fp, "pd->bshift: %5d\n", pd->bshift);
-
- fprintf(fp, "Nodeid atom0 #atom cg0 #cg\n");
- for (i = 0; (i < nnodes); i++)
- {
- fprintf(fp, "%6d%8d%8d%8d%10d\n",
- i,
- pd->index[i], pd->index[i+1]-pd->index[i],
- pd->cgindex[i], pd->cgindex[i+1]-pd->cgindex[i]);
- }
- fprintf(fp, "\n");
-}
-
-static void pr_idef_division(FILE *fp, t_idef *idef, int nnodes, int **multinr)
-{
- int i, ftype, nr, nra, m0, m1;
-
- fprintf(fp, "Division of bonded forces over processors\n");
- fprintf(fp, "%-12s", "CPU");
- for (i = 0; (i < nnodes); i++)
- {
- fprintf(fp, " %5d", i);
- }
- fprintf(fp, "\n");
-
- for (ftype = 0; (ftype < F_NRE); ftype++)
- {
- if (idef->il[ftype].nr > 0)
- {
- nr = idef->il[ftype].nr;
- nra = 1+interaction_function[ftype].nratoms;
- fprintf(fp, "%-12s", interaction_function[ftype].name);
- /* Loop over processors */
- for (i = 0; (i < nnodes); i++)
- {
- m0 = (i == 0) ? 0 : multinr[ftype][i-1]/nra;
- m1 = multinr[ftype][i]/nra;
- fprintf(fp, " %5d", m1-m0);
- }
- fprintf(fp, "\n");
- }
- }
-}
-
-static void select_my_ilist(t_ilist *il, int *multinr, t_commrec *cr)
-{
- t_iatom *ia;
- int i, start, end, nr;
-
- if (cr->nodeid == 0)
- {
- start = 0;
- }
- else
- {
- start = multinr[cr->nodeid-1];
- }
- end = multinr[cr->nodeid];
-
- nr = end-start;
- if (nr < 0)
- {
- gmx_fatal(FARGS, "Negative number of atoms (%d) on node %d\n"
- "You have probably not used the same value for -np with grompp"
- " and mdrun",
- nr, cr->nodeid);
- }
- snew(ia, nr);
-
- for (i = 0; (i < nr); i++)
- {
- ia[i] = il->iatoms[start+i];
- }
-
- sfree(il->iatoms);
- il->iatoms = ia;
-
- il->nr = nr;
-}
-
-static void select_my_idef(t_idef *idef, int **multinr, t_commrec *cr)
-{
- int i;
-
- for (i = 0; (i < F_NRE); i++)
- {
- select_my_ilist(&idef->il[i], multinr[i], cr);
- }
-}
-
-gmx_localtop_t *split_system(FILE *log,
- gmx_mtop_t *mtop, t_inputrec *inputrec,
- t_commrec *cr)
-{
- int i, npp, n, nn;
- real *capacity;
- double tcap = 0, cap;
- int *multinr_cgs, **multinr_nre;
- char *cap_env;
- gmx_localtop_t *top;
- int *left_range;
- int *right_range;
-
- /* Time to setup the division of charge groups over processors */
- npp = cr->nnodes-cr->npmenodes;
- snew(capacity, npp);
- cap_env = getenv("GMX_CAPACITY");
- if (cap_env == NULL)
- {
- for (i = 0; (i < npp-1); i++)
- {
- capacity[i] = 1.0/(double)npp;
- tcap += capacity[i];
- }
- /* Take care that the sum of capacities is 1.0 */
- capacity[npp-1] = 1.0 - tcap;
- }
- else
- {
- tcap = 0;
- nn = 0;
- for (i = 0; i < npp; i++)
- {
- cap = 0;
- sscanf(cap_env+nn, "%lf%n", &cap, &n);
- if (cap == 0)
- {
- gmx_fatal(FARGS, "Incorrect entry or number of entries in GMX_CAPACITY='%s'", cap_env);
- }
- capacity[i] = cap;
- tcap += cap;
- nn += n;
- }
- for (i = 0; i < npp; i++)
- {
- capacity[i] /= tcap;
- }
- }
-
- /* Convert the molecular topology to a fully listed topology */
- top = gmx_mtop_generate_local_top(mtop, inputrec);
-
- snew(multinr_cgs, npp);
- snew(multinr_nre, F_NRE);
- for (i = 0; i < F_NRE; i++)
- {
- snew(multinr_nre[i], npp);
- }
-
-
- snew(left_range, cr->nnodes);
- snew(right_range, cr->nnodes);
-
- /* This computes which entities can be placed on processors */
- split_top(log, npp, top, inputrec, &mtop->mols, capacity, multinr_cgs, multinr_nre, left_range, right_range);
-
- sfree(capacity);
- init_partdec(log, cr, &(top->cgs), multinr_cgs, &(top->idef));
-
- /* This should be fine */
- /*split_idef(&(top->idef),cr->nnodes-cr->npmenodes);*/
-
- select_my_idef(&(top->idef), multinr_nre, cr);
-
- if (top->idef.il[F_CONSTR].nr > 0)
- {
- init_partdec_constraint(cr, &(top->idef), left_range, right_range);
- }
-
- if (log)
- {
- pr_idef_division(log, &(top->idef), npp, multinr_nre);
- }
-
- for (i = 0; i < F_NRE; i++)
- {
- sfree(multinr_nre[i]);
- }
- sfree(multinr_nre);
- sfree(multinr_cgs);
-
- sfree(left_range);
- sfree(right_range);
-
- if (log)
- {
- print_partdec(log, "Workload division", cr->nnodes, cr->pd);
- }
-
- return top;
-}
-
-static void
-add_to_vsitelist(int **list, int *nitem, int *nalloc, int newitem)
-{
- int i, idx;
- gmx_bool found;
-
- found = FALSE;
- idx = *nitem;
- for (i = 0; i < idx && !found; i++)
- {
- found = (newitem == (*list)[i]);
- }
- if (!found)
- {
- *nalloc += 100;
- srenew(*list, *nalloc);
- (*list)[idx++] = newitem;
- *nitem = idx;
- }
-}
-
-gmx_bool setup_parallel_vsites(t_idef *idef, t_commrec *cr,
- t_comm_vsites *vsitecomm)
-{
- int i, j, ftype;
- int nra;
- gmx_bool do_comm;
- t_iatom *ia;
- gmx_partdec_t *pd;
- int iconstruct;
- int i0, i1;
- int nalloc_left_construct, nalloc_right_construct;
- int sendbuf[2], recvbuf[2];
- int bufsize, leftbuf, rightbuf;
-
- pd = cr->pd;
-
- i0 = pd->index[cr->nodeid];
- i1 = pd->index[cr->nodeid+1];
-
- vsitecomm->left_import_construct = NULL;
- vsitecomm->left_import_nconstruct = 0;
- nalloc_left_construct = 0;
-
- vsitecomm->right_import_construct = NULL;
- vsitecomm->right_import_nconstruct = 0;
- nalloc_right_construct = 0;
-
- for (ftype = 0; (ftype < F_NRE); ftype++)
- {
- if (!(interaction_function[ftype].flags & IF_VSITE) )
- {
- continue;
- }
-
- nra = interaction_function[ftype].nratoms;
- ia = idef->il[ftype].iatoms;
-
- for (i = 0; i < idef->il[ftype].nr; i += nra+1)
- {
- for (j = 2; j < 1+nra; j++)
- {
- iconstruct = ia[i+j];
- if (iconstruct < i0)
- {
- add_to_vsitelist(&vsitecomm->left_import_construct,
- &vsitecomm->left_import_nconstruct,
- &nalloc_left_construct, iconstruct);
- }
- else if (iconstruct >= i1)
- {
- add_to_vsitelist(&vsitecomm->right_import_construct,
- &vsitecomm->right_import_nconstruct,
- &nalloc_right_construct, iconstruct);
- }
- }
- }
- }
-
- /* Pre-communicate the array lengths */
- gmx_tx_rx_void(cr,
- GMX_RIGHT, (void *)&vsitecomm->right_import_nconstruct, sizeof(int),
- GMX_LEFT, (void *)&vsitecomm->left_export_nconstruct, sizeof(int));
- gmx_tx_rx_void(cr,
- GMX_LEFT, (void *)&vsitecomm->left_import_nconstruct, sizeof(int),
- GMX_RIGHT, (void *)&vsitecomm->right_export_nconstruct, sizeof(int));
-
- snew(vsitecomm->left_export_construct, vsitecomm->left_export_nconstruct);
- snew(vsitecomm->right_export_construct, vsitecomm->right_export_nconstruct);
-
- /* Communicate the construcing atom index arrays */
- gmx_tx_rx_void(cr,
- GMX_RIGHT, (void *)vsitecomm->right_import_construct, vsitecomm->right_import_nconstruct*sizeof(int),
- GMX_LEFT, (void *)vsitecomm->left_export_construct, vsitecomm->left_export_nconstruct*sizeof(int));
-
- /* Communicate the construcing atom index arrays */
- gmx_tx_rx_void(cr,
- GMX_LEFT, (void *)vsitecomm->left_import_construct, vsitecomm->left_import_nconstruct*sizeof(int),
- GMX_RIGHT, (void *)vsitecomm->right_export_construct, vsitecomm->right_export_nconstruct*sizeof(int));
-
- leftbuf = max(vsitecomm->left_export_nconstruct, vsitecomm->left_import_nconstruct);
- rightbuf = max(vsitecomm->right_export_nconstruct, vsitecomm->right_import_nconstruct);
-
- bufsize = max(leftbuf, rightbuf);
-
- do_comm = (bufsize > 0);
-
- snew(vsitecomm->send_buf, 2*bufsize);
- snew(vsitecomm->recv_buf, 2*bufsize);
-
- return do_comm;
-}
-
-t_state *partdec_init_local_state(t_commrec gmx_unused *cr, t_state *state_global)
-{
- int i;
- t_state *state_local;
-
- snew(state_local, 1);
-
- /* Copy all the contents */
- *state_local = *state_global;
- snew(state_local->lambda, efptNR);
- /* local storage for lambda */
- for (i = 0; i < efptNR; i++)
- {
- state_local->lambda[i] = state_global->lambda[i];
- }
- if (state_global->nrngi > 1)
- {
- /* With stochastic dynamics we need local storage for the random state */
- if (state_local->flags & (1<<estLD_RNG))
- {
- state_local->nrng = gmx_rng_n();
- snew(state_local->ld_rng, state_local->nrng);
-#ifdef GMX_MPI
- if (PAR(cr))
- {
- MPI_Scatter(state_global->ld_rng,
- state_local->nrng*sizeof(state_local->ld_rng[0]), MPI_BYTE,
- state_local->ld_rng,
- state_local->nrng*sizeof(state_local->ld_rng[0]), MPI_BYTE,
- MASTERRANK(cr), cr->mpi_comm_mygroup);
- }
-#endif
- }
- if (state_local->flags & (1<<estLD_RNGI))
- {
- snew(state_local->ld_rngi, 1);
-#ifdef GMX_MPI
- if (PAR(cr))
- {
- MPI_Scatter(state_global->ld_rngi,
- sizeof(state_local->ld_rngi[0]), MPI_BYTE,
- state_local->ld_rngi,
- sizeof(state_local->ld_rngi[0]), MPI_BYTE,
- MASTERRANK(cr), cr->mpi_comm_mygroup);
- }
-#endif
- }
- }
-
- return state_local;
-}
/* thread local work data for solve_pme */
pme_work_t *work;
- /* Work data for PME_redist */
- gmx_bool redist_init;
- int * scounts;
- int * rcounts;
- int * sdispls;
- int * rdispls;
- int * sidx;
- int * idxa;
- real * redist_buf;
- int redist_buf_nalloc;
-
/* Work data for sum_qgrid */
real * sum_qgrid_tmp;
real * sum_qgrid_dd_tmp;
}
}
-static void pmeredist_pd(gmx_pme_t pme, gmx_bool gmx_unused forw,
- int n, gmx_bool gmx_unused bXF, rvec gmx_unused *x_f,
- real gmx_unused *charge, pme_atomcomm_t *atc)
-/* Redistribute particle data for PME calculation */
-/* domain decomposition by x coordinate */
-{
- int *idxa;
- int i, ii;
-
- if (FALSE == pme->redist_init)
- {
- snew(pme->scounts, atc->nslab);
- snew(pme->rcounts, atc->nslab);
- snew(pme->sdispls, atc->nslab);
- snew(pme->rdispls, atc->nslab);
- snew(pme->sidx, atc->nslab);
- pme->redist_init = TRUE;
- }
- if (n > pme->redist_buf_nalloc)
- {
- pme->redist_buf_nalloc = over_alloc_dd(n);
- srenew(pme->redist_buf, pme->redist_buf_nalloc*DIM);
- }
-
- pme->idxa = atc->pd;
-
-#ifdef GMX_MPI
- if (forw && bXF)
- {
- /* forward, redistribution from pp to pme */
-
- /* Calculate send counts and exchange them with other nodes */
- for (i = 0; (i < atc->nslab); i++)
- {
- pme->scounts[i] = 0;
- }
- for (i = 0; (i < n); i++)
- {
- pme->scounts[pme->idxa[i]]++;
- }
- MPI_Alltoall( pme->scounts, 1, MPI_INT, pme->rcounts, 1, MPI_INT, atc->mpi_comm);
-
- /* Calculate send and receive displacements and index into send
- buffer */
- pme->sdispls[0] = 0;
- pme->rdispls[0] = 0;
- pme->sidx[0] = 0;
- for (i = 1; i < atc->nslab; i++)
- {
- pme->sdispls[i] = pme->sdispls[i-1]+pme->scounts[i-1];
- pme->rdispls[i] = pme->rdispls[i-1]+pme->rcounts[i-1];
- pme->sidx[i] = pme->sdispls[i];
- }
- /* Total # of particles to be received */
- atc->n = pme->rdispls[atc->nslab-1] + pme->rcounts[atc->nslab-1];
-
- pme_realloc_atomcomm_things(atc);
-
- /* Copy particle coordinates into send buffer and exchange*/
- for (i = 0; (i < n); i++)
- {
- ii = DIM*pme->sidx[pme->idxa[i]];
- pme->sidx[pme->idxa[i]]++;
- pme->redist_buf[ii+XX] = x_f[i][XX];
- pme->redist_buf[ii+YY] = x_f[i][YY];
- pme->redist_buf[ii+ZZ] = x_f[i][ZZ];
- }
- MPI_Alltoallv(pme->redist_buf, pme->scounts, pme->sdispls,
- pme->rvec_mpi, atc->x, pme->rcounts, pme->rdispls,
- pme->rvec_mpi, atc->mpi_comm);
- }
- if (forw)
- {
- /* Copy charge into send buffer and exchange*/
- for (i = 0; i < atc->nslab; i++)
- {
- pme->sidx[i] = pme->sdispls[i];
- }
- for (i = 0; (i < n); i++)
- {
- ii = pme->sidx[pme->idxa[i]];
- pme->sidx[pme->idxa[i]]++;
- pme->redist_buf[ii] = charge[i];
- }
- MPI_Alltoallv(pme->redist_buf, pme->scounts, pme->sdispls, mpi_type,
- atc->q, pme->rcounts, pme->rdispls, mpi_type,
- atc->mpi_comm);
- }
- else /* backward, redistribution from pme to pp */
- {
- MPI_Alltoallv(atc->f, pme->rcounts, pme->rdispls, pme->rvec_mpi,
- pme->redist_buf, pme->scounts, pme->sdispls,
- pme->rvec_mpi, atc->mpi_comm);
-
- /* Copy data from receive buffer */
- for (i = 0; i < atc->nslab; i++)
- {
- pme->sidx[i] = pme->sdispls[i];
- }
- for (i = 0; (i < n); i++)
- {
- ii = DIM*pme->sidx[pme->idxa[i]];
- x_f[i][XX] += pme->redist_buf[ii+XX];
- x_f[i][YY] += pme->redist_buf[ii+YY];
- x_f[i][ZZ] += pme->redist_buf[ii+ZZ];
- pme->sidx[pme->idxa[i]]++;
- }
- }
-#endif
-}
-
static void pme_dd_sendrecv(pme_atomcomm_t gmx_unused *atc,
gmx_bool gmx_unused bBackward, int gmx_unused shift,
void gmx_unused *buf_s, int gmx_unused nbyte_s,
if (atc->nslab > 1)
{
- /* These three allocations are not required for particle decomp. */
snew(atc->node_dest, atc->nslab);
snew(atc->node_src, atc->nslab);
setup_coordinate_communication(atc);
}
snew(pme, 1);
- pme->redist_init = FALSE;
pme->sum_qgrid_tmp = NULL;
pme->sum_qgrid_dd_tmp = NULL;
pme->buf_nalloc = 0;
- pme->redist_buf_nalloc = 0;
pme->nnodes = 1;
pme->bPPnode = TRUE;
{
dd_pmeredist_x_q(pme, n_d, bFirst, x_d, q_d, atc);
}
- else
- {
- pmeredist_pd(pme, TRUE, n_d, bFirst, x_d, q_d, atc);
- }
}
}
dd_pmeredist_f(pme, atc, n_d, f_d,
d == pme->ndecompdim-1 && pme->bPPnode);
}
- else
- {
- pmeredist_pd(pme, FALSE, n_d, TRUE, f_d, NULL, atc);
- }
}
wallcycle_stop(wcycle, ewcPME_REDISTXF);
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014, 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.
rvec dx, df;
atom_id *AA;
ivec dt;
- int start = mdatoms->start;
- int end = mdatoms->homenr+start;
+ int start = 0;
+ int end = mdatoms->homenr;
int niat;
gmx_bool bMolPBC = fr->bMolPBC;
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2008, The GROMACS development team.
- * Copyright (c) 2013, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014, 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.
#include "txtdump.h"
#include "force.h"
#include "mdrun.h"
-#include "partdec.h"
#include "mdatoms.h"
#include "vsite.h"
#include "network.h"
#include "names.h"
#include "constr.h"
#include "domdec.h"
-#include "partdec.h"
#include "physics.h"
#include "shellfc.h"
#include "mtop_util.h"
int a0, a1, *ind, nshell, i;
gmx_domdec_t *dd = NULL;
- if (PAR(cr))
+ if (DOMAINDECOMP(cr))
{
- if (DOMAINDECOMP(cr))
- {
- dd = cr->dd;
- a0 = 0;
- a1 = dd->nat_home;
- }
- else
- {
- pd_at_range(cr, &a0, &a1);
- }
+ dd = cr->dd;
+ a0 = 0;
+ a1 = dd->nat_home;
}
else
{
{
shell[nshell] = shfc->shell_gl[ind[i]];
}
+
/* With inter-cg shells we can no do shell prediction,
* so we do not need the nuclei numbers.
*/
char sbuf[22];
gmx_bool bCont, bInit;
int nat, dd_ac0, dd_ac1 = 0, i;
- int start = md->start, homenr = md->homenr, end = start+homenr, cg0, cg1;
+ int start = 0, homenr = md->homenr, end = start+homenr, cg0, cg1;
int nflexcon, g, number_steps, d, Min = 0, count = 0;
#define Try (1-Min) /* At start Try = 1 */
force[i] = shfc->f[i];
}
- /* With particle decomposition this code only works
- * when all particles involved with each shell are in the same cg.
- */
-
+ /* When we had particle decomposition, this code only worked with
+ * PD when all particles involved with each shell were in the same
+ * charge group. Not sure if this is still relevant. */
if (bDoNS && inputrec->ePBC != epbcNONE && !DOMAINDECOMP(cr))
{
/* This is the only time where the coordinates are used
* before do_force is called, which normally puts all
* charge groups in the box.
*/
- if (PARTDECOMP(cr))
- {
- pd_cg_range(cr, &cg0, &cg1);
- }
- else
- {
- cg0 = 0;
- cg1 = top->cgs.nr;
- }
+ cg0 = 0;
+ cg1 = top->cgs.nr;
put_charge_groups_in_box(fplog, cg0, cg1, fr->ePBC, state->box,
&(top->cgs), state->x, fr->cg_cm);
if (graph)
{
construct_vsites(vsite, pos[Min], inputrec->delta_t, state->v,
idef->iparams, idef->il,
- fr->ePBC, fr->bMolPBC, graph, cr, state->box);
+ fr->ePBC, fr->bMolPBC, cr, state->box);
}
if (nflexcon)
#include "string2.h"
#include "smalloc.h"
#include "names.h"
-#include "mvdata.h"
#include "txtdump.h"
#include "pbc.h"
#include "chargegroup.h"
#include "copyrite.h"
#include "gromacs/random/random.h"
#include "domdec.h"
-#include "partdec.h"
#include "genborn.h"
#include "nbnxn_atomdata.h"
#include "nbnxn_search.h"
char buf[STEPSTRSIZE];
pf2 = sqr(pforce);
- for (i = md->start; i < md->start+md->homenr; i++)
+ for (i = 0; i < md->homenr; i++)
{
fn2 = norm2(f[i]);
/* We also catch NAN, if the compiler does not optimize this away. */
}
else
{
- sum_forces(mdatoms->start, mdatoms->start+mdatoms->homenr,
+ sum_forces(0, mdatoms->homenr,
f, fr->f_novirsum);
}
if (EEL_FULL(fr->eeltype))
nbv = fr->nbv;
nb_kernel_type = fr->nbv->grp[0].kernel_type;
- start = mdatoms->start;
+ start = 0;
homenr = mdatoms->homenr;
bSepDVDL = (fr->bSepDVDL && do_per_step(step, inputrec->nstlog));
reset_enerdata(fr, bNS, enerd, MASTER(cr));
clear_rvecs(SHIFTS, fr->fshift);
- if (DOMAINDECOMP(cr))
+ if (DOMAINDECOMP(cr) && !(cr->duty & DUTY_PME))
{
- if (!(cr->duty & DUTY_PME))
- {
- wallcycle_start(wcycle, ewcPPDURINGPME);
- dd_force_flop_start(cr->dd, nrnb);
- }
+ wallcycle_start(wcycle, ewcPPDURINGPME);
+ dd_force_flop_start(cr->dd, nrnb);
}
if (inputrec->bRot)
}
}
- if (bDoForces)
+ if (bDoForces && DOMAINDECOMP(cr))
{
/* Communicate the forces */
- if (PAR(cr))
+ wallcycle_start(wcycle, ewcMOVEF);
+ dd_move_f(cr->dd, f, fr->fshift);
+ /* Do we need to communicate the separate force array
+ * for terms that do not contribute to the single sum virial?
+ * Position restraints and electric fields do not introduce
+ * inter-cg forces, only full electrostatics methods do.
+ * When we do not calculate the virial, fr->f_novirsum = f,
+ * so we have already communicated these forces.
+ */
+ if (EEL_FULL(fr->eeltype) && cr->dd->n_intercg_excl &&
+ (flags & GMX_FORCE_VIRIAL))
{
- wallcycle_start(wcycle, ewcMOVEF);
- if (DOMAINDECOMP(cr))
- {
- dd_move_f(cr->dd, f, fr->fshift);
- /* Do we need to communicate the separate force array
- * for terms that do not contribute to the single sum virial?
- * Position restraints and electric fields do not introduce
- * inter-cg forces, only full electrostatics methods do.
- * When we do not calculate the virial, fr->f_novirsum = f,
- * so we have already communicated these forces.
- */
- if (EEL_FULL(fr->eeltype) && cr->dd->n_intercg_excl &&
- (flags & GMX_FORCE_VIRIAL))
- {
- dd_move_f(cr->dd, fr->f_novirsum, NULL);
- }
- if (bSepLRF)
- {
- /* We should not update the shift forces here,
- * since f_twin is already included in f.
- */
- dd_move_f(cr->dd, fr->f_twin, NULL);
- }
- }
- wallcycle_stop(wcycle, ewcMOVEF);
+ dd_move_f(cr->dd, fr->f_novirsum, NULL);
}
+ if (bSepLRF)
+ {
+ /* We should not update the shift forces here,
+ * since f_twin is already included in f.
+ */
+ dd_move_f(cr->dd, fr->f_twin, NULL);
+ }
+ wallcycle_stop(wcycle, ewcMOVEF);
}
if (bUseOrEmulGPU)
if (flags & GMX_FORCE_VIRIAL)
{
/* Calculation of the virial must be done after vsites! */
- calc_virial(mdatoms->start, mdatoms->homenr, x, f,
+ calc_virial(0, mdatoms->homenr, x, f,
vir_force, graph, box, nrnb, fr, inputrec->ePBC);
}
}
t_pbc pbc;
float cycles_pme, cycles_force;
- start = mdatoms->start;
+ start = 0;
homenr = mdatoms->homenr;
bSepDVDL = (fr->bSepDVDL && do_per_step(step, inputrec->nstlog));
clear_mat(vir_force);
- if (PARTDECOMP(cr))
+ cg0 = 0;
+ if (DOMAINDECOMP(cr))
{
- pd_cg_range(cr, &cg0, &cg1);
+ cg1 = cr->dd->ncg_tot;
}
else
{
- cg0 = 0;
- if (DOMAINDECOMP(cr))
- {
- cg1 = cr->dd->ncg_tot;
- }
- else
- {
- cg1 = top->cgs.nr;
- }
- if (fr->n_tpi > 0)
- {
- cg1--;
- }
+ cg1 = top->cgs.nr;
+ }
+ if (fr->n_tpi > 0)
+ {
+ cg1--;
}
bStateChanged = (flags & GMX_FORCE_STATECHANGED);
inc_nrnb(nrnb, eNR_CGCM, homenr);
}
- if (bCalcCGCM)
+ if (bCalcCGCM && gmx_debug_at)
{
- if (PAR(cr))
- {
- move_cgcm(fplog, cr, fr->cg_cm);
- }
- if (gmx_debug_at)
- {
- pr_rvecs(debug, 0, "cgcm", fr->cg_cm, top->cgs.nr);
- }
+ pr_rvecs(debug, 0, "cgcm", fr->cg_cm, top->cgs.nr);
}
#ifdef GMX_MPI
#endif /* GMX_MPI */
/* Communicate coordinates and sum dipole if necessary */
- if (PAR(cr))
+ if (DOMAINDECOMP(cr))
{
wallcycle_start(wcycle, ewcMOVEX);
- if (DOMAINDECOMP(cr))
- {
- dd_move_x(cr->dd, box, x);
- }
- else
- {
- move_x(cr, x, nrnb);
- }
+ dd_move_x(cr->dd, box, x);
wallcycle_stop(wcycle, ewcMOVEX);
}
x, box, fr, &top->idef, graph, fr->born);
}
- if (DOMAINDECOMP(cr))
+ if (DOMAINDECOMP(cr) && !(cr->duty & DUTY_PME))
{
- if (!(cr->duty & DUTY_PME))
- {
- wallcycle_start(wcycle, ewcPPDURINGPME);
- dd_force_flop_start(cr->dd, nrnb);
- }
+ wallcycle_start(wcycle, ewcPPDURINGPME);
+ dd_force_flop_start(cr->dd, nrnb);
}
if (inputrec->bRot)
}
/* Communicate the forces */
- if (PAR(cr))
+ if (DOMAINDECOMP(cr))
{
wallcycle_start(wcycle, ewcMOVEF);
- if (DOMAINDECOMP(cr))
+ dd_move_f(cr->dd, f, fr->fshift);
+ /* Do we need to communicate the separate force array
+ * for terms that do not contribute to the single sum virial?
+ * Position restraints and electric fields do not introduce
+ * inter-cg forces, only full electrostatics methods do.
+ * When we do not calculate the virial, fr->f_novirsum = f,
+ * so we have already communicated these forces.
+ */
+ if (EEL_FULL(fr->eeltype) && cr->dd->n_intercg_excl &&
+ (flags & GMX_FORCE_VIRIAL))
{
- dd_move_f(cr->dd, f, fr->fshift);
- /* Do we need to communicate the separate force array
- * for terms that do not contribute to the single sum virial?
- * Position restraints and electric fields do not introduce
- * inter-cg forces, only full electrostatics methods do.
- * When we do not calculate the virial, fr->f_novirsum = f,
- * so we have already communicated these forces.
- */
- if (EEL_FULL(fr->eeltype) && cr->dd->n_intercg_excl &&
- (flags & GMX_FORCE_VIRIAL))
- {
- dd_move_f(cr->dd, fr->f_novirsum, NULL);
- }
- if (bSepLRF)
- {
- /* We should not update the shift forces here,
- * since f_twin is already included in f.
- */
- dd_move_f(cr->dd, fr->f_twin, NULL);
- }
+ dd_move_f(cr->dd, fr->f_novirsum, NULL);
}
- else
+ if (bSepLRF)
{
- pd_move_f(cr, f, nrnb);
- if (bSepLRF)
- {
- pd_move_f(cr, fr->f_twin, nrnb);
- }
+ /* We should not update the shift forces here,
+ * since f_twin is already included in f.
+ */
+ dd_move_f(cr->dd, fr->f_twin, NULL);
}
wallcycle_stop(wcycle, ewcMOVEF);
}
if (flags & GMX_FORCE_VIRIAL)
{
/* Calculation of the virial must be done after vsites! */
- calc_virial(mdatoms->start, mdatoms->homenr, x, f,
+ calc_virial(0, mdatoms->homenr, x, f,
vir_force, graph, box, nrnb, fr, inputrec->ePBC);
}
}
snew(savex, state->natoms);
- start = md->start;
- end = md->homenr + start;
+ start = 0;
+ end = md->homenr;
if (debug)
{
print_dd_statistics(cr, inputrec, fplog);
}
-#ifdef GMX_MPI
- if (PARTDECOMP(cr))
- {
- if (MASTER(cr))
- {
- t_nrnb *nrnb_all;
- int s;
- MPI_Status stat;
-
- snew(nrnb_all, cr->nnodes);
- nrnb_all[0] = *nrnb;
- for (s = 1; s < cr->nnodes; s++)
- {
- MPI_Recv(nrnb_all[s].n, eNRNB, MPI_DOUBLE, s, 0,
- cr->mpi_comm_mysim, &stat);
- }
- pr_load(fplog, cr, nrnb_all);
- sfree(nrnb_all);
- }
- else
- {
- MPI_Send(nrnb->n, eNRNB, MPI_DOUBLE, MASTERRANK(cr), 0,
- cr->mpi_comm_mysim);
- }
- }
-#endif
-
if (SIMMASTER(cr))
{
wallcycle_print(fplog, cr->nnodes, cr->npmenodes,
#include "physics.h"
#include "vec.h"
#include "gromacs/math/utilities.h"
-#include "mvdata.h"
#include "main.h"
#include "force.h"
#include "vcm.h"
#include "gromacs/fileio/gmxfio.h"
#include "gromacs/fileio/trnio.h"
#include "domdec.h"
-#include "partdec.h"
#include "constr.h"
#include "checkpoint.h"
#include "xvgr.h"
#include "force.h"
#include "mdrun.h"
#include "domdec.h"
-#include "partdec.h"
#include "gromacs/random/random.h"
#include "physics.h"
#include "xvgr.h"
sscanf(dump_pdb, "%lf", &dump_ener);
}
- atoms2md(top_global, inputrec, 0, NULL, 0, top_global->natoms, mdatoms);
+ atoms2md(top_global, inputrec, 0, NULL, top_global->natoms, mdatoms);
update_mdatoms(mdatoms, inputrec->fepvals->init_lambda);
snew(enerd, 1);
matrix *ekin_sum;
real *dekindl_sum;
- start_t = md->start + ((thread+0)*md->homenr)/nthread;
- end_t = md->start + ((thread+1)*md->homenr)/nthread;
+ start_t = ((thread+0)*md->homenr)/nthread;
+ end_t = ((thread+1)*md->homenr)/nthread;
ekin_sum = ekind->ekin_work[thread];
dekindl_sum = ekind->dekindl_work[thread];
gmx_ekindata_t *ekind,
t_nrnb *nrnb, gmx_bool bEkinAveVel)
{
- int start = md->start, homenr = md->homenr;
+ int start = 0, homenr = md->homenr;
int g, d, n, m, gt = 0;
rvec v_corrt;
real hm;
/* rescale in place here */
if (EI_VV(inputrec->eI))
{
- rescale_velocities(ekind, md, md->start, md->start+md->homenr, state->v);
+ rescale_velocities(ekind, md, 0, md->homenr, state->v);
}
}
else
/* for now, SD update is here -- though it really seems like it
should be reformulated as a velocity verlet method, since it has two parts */
- start = md->start;
+ start = 0;
homenr = md->homenr;
nrend = start+homenr;
int start, homenr, nrend, i, n, m, g;
tensor vir_con;
- start = md->start;
+ start = 0;
homenr = md->homenr;
nrend = start+homenr;
gmx_incons("update_coords called for velocity without VV integrator");
}
- start = md->start;
+ start = 0;
homenr = md->homenr;
nrend = start+homenr;
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014, 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.
#include "smalloc.h"
#include "nrnb.h"
#include "vec.h"
-#include "mvdata.h"
#include "network.h"
#include "mshift.h"
#include "pbc.h"
#include "domdec.h"
-#include "partdec.h"
#include "mtop_util.h"
#include "gmx_omp_nthreads.h"
* of constructing atoms.
*/
-static void move_construct_x(t_comm_vsites *vsitecomm, rvec x[], t_commrec *cr)
-{
- rvec *sendbuf;
- rvec *recvbuf;
- int i, ia;
-
- sendbuf = vsitecomm->send_buf;
- recvbuf = vsitecomm->recv_buf;
-
-
- /* Prepare pulse left by copying to send buffer */
- for (i = 0; i < vsitecomm->left_export_nconstruct; i++)
- {
- ia = vsitecomm->left_export_construct[i];
- copy_rvec(x[ia], sendbuf[i]);
- }
-
- /* Pulse coordinates left */
- gmx_tx_rx_real(cr, GMX_LEFT, (real *)sendbuf, 3*vsitecomm->left_export_nconstruct, GMX_RIGHT, (real *)recvbuf, 3*vsitecomm->right_import_nconstruct);
-
- /* Copy from receive buffer to coordinate array */
- for (i = 0; i < vsitecomm->right_import_nconstruct; i++)
- {
- ia = vsitecomm->right_import_construct[i];
- copy_rvec(recvbuf[i], x[ia]);
- }
-
- /* Prepare pulse right by copying to send buffer */
- for (i = 0; i < vsitecomm->right_export_nconstruct; i++)
- {
- ia = vsitecomm->right_export_construct[i];
- copy_rvec(x[ia], sendbuf[i]);
- }
-
- /* Pulse coordinates right */
- gmx_tx_rx_real(cr, GMX_RIGHT, (real *)sendbuf, 3*vsitecomm->right_export_nconstruct, GMX_LEFT, (real *)recvbuf, 3*vsitecomm->left_import_nconstruct);
-
- /* Copy from receive buffer to coordinate array */
- for (i = 0; i < vsitecomm->left_import_nconstruct; i++)
- {
- ia = vsitecomm->left_import_construct[i];
- copy_rvec(recvbuf[i], x[ia]);
- }
-}
-
-
-static void move_construct_f(t_comm_vsites *vsitecomm, rvec f[], t_commrec *cr)
-{
- rvec *sendbuf;
- rvec *recvbuf;
- int i, ia;
-
- sendbuf = vsitecomm->send_buf;
- recvbuf = vsitecomm->recv_buf;
-
- /* Prepare pulse right by copying to send buffer */
- for (i = 0; i < vsitecomm->right_import_nconstruct; i++)
- {
- ia = vsitecomm->right_import_construct[i];
- copy_rvec(f[ia], sendbuf[i]);
- clear_rvec(f[ia]); /* Zero it here after moving, just to simplify debug book-keeping... */
- }
-
- /* Pulse forces right */
- gmx_tx_rx_real(cr, GMX_RIGHT, (real *)sendbuf, 3*vsitecomm->right_import_nconstruct, GMX_LEFT, (real *)recvbuf, 3*vsitecomm->left_export_nconstruct);
-
- /* Copy from receive buffer to coordinate array */
- for (i = 0; i < vsitecomm->left_export_nconstruct; i++)
- {
- ia = vsitecomm->left_export_construct[i];
- rvec_inc(f[ia], recvbuf[i]);
- }
-
- /* Prepare pulse left by copying to send buffer */
- for (i = 0; i < vsitecomm->left_import_nconstruct; i++)
- {
- ia = vsitecomm->left_import_construct[i];
- copy_rvec(f[ia], sendbuf[i]);
- clear_rvec(f[ia]); /* Zero it here after moving, just to simplify debug book-keeping... */
- }
-
- /* Pulse coordinates left */
- gmx_tx_rx_real(cr, GMX_LEFT, (real *)sendbuf, 3*vsitecomm->left_import_nconstruct, GMX_RIGHT, (real *)recvbuf, 3*vsitecomm->right_export_nconstruct);
-
- /* Copy from receive buffer to coordinate array */
- for (i = 0; i < vsitecomm->right_export_nconstruct; i++)
- {
- ia = vsitecomm->right_export_construct[i];
- rvec_inc(f[ia], recvbuf[i]);
- }
-
- /* All forces are now on the home processors */
-}
-
-
-static void
-pd_clear_nonlocal_constructs(t_comm_vsites *vsitecomm, rvec f[])
-{
- int i, ia;
-
- for (i = 0; i < vsitecomm->left_import_nconstruct; i++)
- {
- ia = vsitecomm->left_import_construct[i];
- clear_rvec(f[ia]);
- }
- for (i = 0; i < vsitecomm->right_import_nconstruct; i++)
- {
- ia = vsitecomm->right_import_construct[i];
- clear_rvec(f[ia]);
- }
-}
-
-
-
static int pbc_rvec_sub(const t_pbc *pbc, const rvec xi, const rvec xj, rvec dx)
{
if (pbc)
rvec x[],
real dt, rvec *v,
t_iparams ip[], t_ilist ilist[],
- int ePBC, gmx_bool bMolPBC, t_graph *graph,
+ int ePBC, gmx_bool bMolPBC,
t_commrec *cr, matrix box)
{
t_pbc pbc, *pbc_null;
pbc_null = NULL;
}
- if (cr)
+ if (bDomDec)
{
- if (bDomDec)
- {
- dd_move_x_vsites(cr->dd, box, x);
- }
- else if (vsite->bPDvsitecomm)
- {
- /* I'm not sure whether the periodicity and shift are guaranteed
- * to be consistent between different nodes when running e.g. polymers
- * in parallel. In this special case we thus unshift/shift,
- * but only when necessary. This is to make sure the coordinates
- * we move don't end up a box away...
- */
- if (graph != NULL)
- {
- unshift_self(graph, box, x);
- }
-
- move_construct_x(vsite->vsitecomm, x, cr);
-
- if (graph != NULL)
- {
- shift_self(graph, box, x);
- }
- }
+ dd_move_x_vsites(cr->dd, box, x);
}
if (vsite->nthreads == 1)
{
construct_vsites(vsite, x+as, 0.0, NULL,
mtop->ffparams.iparams, molt->ilist,
- epbcNONE, TRUE, NULL, NULL, NULL);
+ epbcNONE, TRUE, NULL, NULL);
as += molt->atoms.nr;
}
}
{
dd_clear_f_vsites(cr->dd, f);
}
- else if (PARTDECOMP(cr) && vsite->vsitecomm != NULL)
- {
- pd_clear_nonlocal_constructs(vsite->vsitecomm, f);
- }
if (vsite->nthreads == 1)
{
{
dd_move_f_vsites(cr->dd, f, fshift);
}
- else if (vsite->bPDvsitecomm)
- {
- /* We only move forces here, and they are independent of shifts */
- move_construct_f(vsite->vsitecomm, f, cr);
- }
inc_nrnb(nrnb, eNR_VSITE2, vsite_count(idef->il, F_VSITE2));
inc_nrnb(nrnb, eNR_VSITE3, vsite_count(idef->il, F_VSITE3));
sfree(a2cg);
}
- if (PARTDECOMP(cr))
- {
- snew(vsite->vsitecomm, 1);
- vsite->bPDvsitecomm =
- setup_parallel_vsites(&(top->idef), cr, vsite->vsitecomm);
- }
}
if (vsite->nthreads > 1)
{
- if (vsite->bHaveChargeGroups || PARTDECOMP(cr))
+ if (vsite->bHaveChargeGroups)
{
- gmx_incons("Can not use threads virtual sites combined with charge groups or particle decomposition");
+ gmx_fatal(FARGS, "The combination of threading, virtual sites and charge groups is not implemented");
}
split_vsites_over_threads(top->idef.il, md, !DOMAINDECOMP(cr), vsite);
lamfac = 1;
type = md->typeA;
}
- for (i = md->start; i < md->start+md->homenr; i++)
+ for (i = 0; i < md->homenr; i++)
{
for (w = 0; w < nwall; w++)
{
#include "pull.h"
#include "xvgr.h"
#include "names.h"
-#include "partdec.h"
#include "pbc.h"
#include "mtop_util.h"
#include "mdrun.h"
static void apply_forces_grp(const t_pull_group *pgrp, const t_mdatoms *md,
const dvec f_pull, int sign, rvec *f)
{
- int i, ii, m, start, end;
+ int i, ii, m;
double wmass, inv_wm;
- start = md->start;
- end = md->homenr + start;
-
inv_wm = pgrp->wscale*pgrp->invtm;
for (i = 0; i < pgrp->nat_loc; i++)
for (g = 0; g < pull->ngroup; g++)
{
make_local_pull_group(ga2la, &pull->group[g],
- md->start, md->start+md->homenr);
+ 0, md->homenr);
}
}
static void init_pull_group_index(FILE *fplog, t_commrec *cr,
- int start, int end,
int g, t_pull_group *pg, ivec pulldims,
gmx_mtop_t *mtop, t_inputrec *ir, real lambda)
{
int i, ii, d, nfrozen, ndim;
real m, w, mbd;
double tmass, wmass, wwmass;
- gmx_bool bDomDec;
- gmx_ga2la_t ga2la = NULL;
gmx_groups_t *groups;
gmx_mtop_atomlookup_t alook;
t_atom *atom;
- bDomDec = (cr && DOMAINDECOMP(cr));
- if (bDomDec)
- {
- ga2la = cr->dd->ga2la;
- }
-
if (EI_ENERGY_MINIMIZATION(ir->eI) || ir->eI == eiBD)
{
/* There are no masses in the integrator.
{
ii = pg->ind[i];
gmx_mtop_atomnr_to_atom(alook, ii, &atom);
- if (cr && PAR(cr) && !bDomDec && ii >= start && ii < end)
- {
- pg->ind_loc[pg->nat_loc++] = ii;
- }
if (ir->opts.nFreeze)
{
for (d = 0; d < DIM; d++)
pull->bVirial = FALSE;
}
- if (cr && PARTDECOMP(cr))
- {
- pd_at_range(cr, &start, &end);
- }
pull->rbuf = NULL;
pull->dbuf = NULL;
pull->dbuf_cyl = NULL;
}
}
/* Set the indices */
- init_pull_group_index(fplog, cr, start, end, g, pgrp, pull->dim, mtop, ir, lambda);
+ init_pull_group_index(fplog, cr, g, pgrp, pull->dim, mtop, ir, lambda);
if (PULL_CYL(pull) && pgrp->invtm == 0)
{
gmx_fatal(FARGS, "Can not have frozen atoms in a cylinder pull group");
rvec *x_pbc = NULL; /* Space for the pbc-correct atom positions */
- if ( (PAR(cr)) && !DOMAINDECOMP(cr) )
- {
- gmx_fatal(FARGS, "Enforced rotation is only implemented for domain decomposition!");
- }
-
if (MASTER(cr) && bVerbose)
{
fprintf(stdout, "%s Initializing ...\n", RotStr);
a = pgrp->pbcatom;
}
- if (a >= md->start && a < md->start+md->homenr)
+ if (a >= 0 && a < md->homenr)
{
copy_rvec(x[a], x_pbc);
}
ga2la = cr->dd->ga2la;
}
- start = md->start;
- end = md->homenr + start;
+ start = 0;
+ end = md->homenr;
r0_2 = dsqr(pull->cyl_r0);
#include "qmmm.h"
#include "domdec.h"
#include "domdec_network.h"
-#include "partdec.h"
+#include "gromacs/gmxlib/topsort.h"
#include "coulomb.h"
#include "constr.h"
#include "shellfc.h"
#include "compute_io.h"
-#include "mvdata.h"
#include "checkpoint.h"
#include "mtop_util.h"
#include "sighandler.h"
gmx_bool bVV, bIterativeCase, bFirstIterate, bTemp, bPres, bTrotter;
gmx_bool bUpdateDoLR;
real dvdl_constr;
- int a0, a1;
rvec *cbuf = NULL;
matrix lastbox;
real veta_save, scalevir, tracevir;
}
else
{
- if (PAR(cr))
- {
- /* Initialize the particle decomposition and split the topology */
- top = split_system(fplog, top_global, ir, cr);
+ top = gmx_mtop_generate_local_top(top_global, ir);
- pd_cg_range(cr, &fr->cg0, &fr->hcg);
- pd_at_range(cr, &a0, &a1);
- }
- else
- {
- top = gmx_mtop_generate_local_top(top_global, ir);
-
- a0 = 0;
- a1 = top_global->natoms;
- }
+ forcerec_set_excl_load(fr, top);
- forcerec_set_excl_load(fr, top, cr);
-
- state = partdec_init_local_state(cr, state_global);
+ state = serial_init_local_state(state_global);
f_global = f;
- atoms2md(top_global, ir, 0, NULL, a0, a1-a0, mdatoms);
+ atoms2md(top_global, ir, 0, NULL, top_global->natoms, mdatoms);
if (vsite)
{
}
setup_bonded_threading(fr, &top->idef);
-
- if (ir->pull && PAR(cr))
- {
- dd_make_local_pull_groups(NULL, ir->pull, mdatoms);
- }
}
if (DOMAINDECOMP(cr))
}
/* Initialize constraints */
- if (constr)
+ if (constr && !DOMAINDECOMP(cr))
{
- if (!DOMAINDECOMP(cr))
- {
- set_constraints(constr, top, ir, mdatoms, cr);
- }
+ set_constraints(constr, top, ir, mdatoms, cr);
}
if (repl_ex_nst > 0)
if (mdatoms->cFREEZE && (state->flags & (1<<estV)))
{
/* Set the velocities of frozen particles to zero */
- for (i = mdatoms->start; i < mdatoms->start+mdatoms->homenr; i++)
+ for (i = 0; i < mdatoms->homenr; i++)
{
for (m = 0; m < DIM; m++)
{
/* Construct the virtual sites for the initial configuration */
construct_vsites(vsite, state->x, ir->delta_t, NULL,
top->idef.iparams, top->idef.il,
- fr->ePBC, fr->bMolPBC, graph, cr, state->box);
+ fr->ePBC, fr->bMolPBC, cr, state->box);
}
}
if (bRerunMD)
{
- if (!(DOMAINDECOMP(cr) && !MASTER(cr)))
+ if (!DOMAINDECOMP(cr) || MASTER(cr))
{
for (i = 0; i < state_global->natoms; i++)
{
{
if (DOMAINDECOMP(cr))
{
- gmx_fatal(FARGS, "Vsite recalculation with -rerun is not implemented for domain decomposition, use particle decomposition");
+ gmx_fatal(FARGS, "Vsite recalculation with -rerun is not implemented with domain decomposition, use a single rank");
}
if (graph)
{
}
construct_vsites(vsite, state->x, ir->delta_t, state->v,
top->idef.iparams, top->idef.il,
- fr->ePBC, fr->bMolPBC, graph, cr, state->box);
+ fr->ePBC, fr->bMolPBC, cr, state->box);
if (graph)
{
unshift_self(graph, state->box, state->x);
}
construct_vsites(vsite, state->x, ir->delta_t, state->v,
top->idef.iparams, top->idef.il,
- fr->ePBC, fr->bMolPBC, graph, cr, state->box);
+ fr->ePBC, fr->bMolPBC, cr, state->box);
if (graph != NULL)
{
"[PAR]",
"When [TT]mdrun[tt] is started using MPI with more than 1 process",
"or with thread-MPI with more than 1 thread, MPI parallelization is used.",
- "By default domain decomposition is used, unless the [TT]-pd[tt]",
- "option is set, which selects particle decomposition.",
+ "Domain decomposition is always used with MPI parallelism.",
"[PAR]",
"With domain decomposition, the spatial decomposition can be set",
"with option [TT]-dd[tt]. By default [TT]mdrun[tt] selects a good decomposition.",
#define NFILE asize(fnm)
/* Command line options ! */
- gmx_bool bPartDec = FALSE;
gmx_bool bDDBondCheck = TRUE;
gmx_bool bDDBondComm = TRUE;
gmx_bool bTunePME = TRUE;
t_pargs pa[] = {
- { "-pd", FALSE, etBOOL, {&bPartDec},
- "Use particle decompostion" },
{ "-dd", FALSE, etRVEC, {&realddxyz},
"Domain decomposition grid, 0 is optimize" },
{ "-ddorder", FALSE, etENUM, {ddno_opt},
Flags = opt2bSet("-rerun", NFILE, fnm) ? MD_RERUN : 0;
Flags = Flags | (bSepPot ? MD_SEPPOT : 0);
- Flags = Flags | (bPartDec ? MD_PARTDEC : 0);
Flags = Flags | (bDDBondCheck ? MD_DDBONDCHECK : 0);
Flags = Flags | (bDDBondComm ? MD_DDBONDCOMM : 0);
Flags = Flags | (bTunePME ? MD_TUNEPME : 0);
#include "macros.h"
#include "vec.h"
#include "names.h"
-#include "mvdata.h"
#include "domdec.h"
-#include "partdec.h"
#define PROBABILITYCUTOFF 100
/* we don't bother evaluating if events are more rare than exp(-100) = 3.7x10^-44 */
{
gmx_fatal(FARGS, "Nothing to exchange with only one replica, maybe you forgot to set the -multi option of mdrun?");
}
+ if (!EI_DYNAMICS(ir->eI))
+ {
+ gmx_fatal(FARGS, "Replica exchange is only supported by dynamical simulations");
+ /* Note that PAR(cr) is defined by cr->nnodes > 1, which is
+ * distinct from MULTISIM(cr). A multi-simulation only runs
+ * with real MPI parallelism, but this does not imply PAR(cr)
+ * is true!
+ *
+ * Since we are using a dynamical integrator, the only
+ * decomposition is DD, so PAR(cr) and DOMAINDECOMP(cr) are
+ * synonymous. The only way for cr->nnodes > 1 to be true is
+ * if we are using DD. */
+ }
snew(re, 1);
}
}
-static void pd_collect_state(const t_commrec *cr, t_state *state)
-{
- int shift;
-
- if (debug)
- {
- fprintf(debug, "Collecting state before exchange\n");
- }
- shift = cr->nnodes - cr->npmenodes - 1;
- move_rvecs(cr, FALSE, FALSE, state->x, NULL, shift, NULL);
- if (state->v)
- {
- move_rvecs(cr, FALSE, FALSE, state->v, NULL, shift, NULL);
- }
- if (state->sd_X)
- {
- move_rvecs(cr, FALSE, FALSE, state->sd_X, NULL, shift, NULL);
- }
-}
-
static void print_transition_matrix(FILE *fplog, int n, int **nmoves, int *nattempt)
{
int i, j, ntot;
* each simulation know whether they need to participate in
* collecting the state. Otherwise, they might as well get on with
* the next thing to do. */
- if (PAR(cr))
+ if (DOMAINDECOMP(cr))
{
#ifdef GMX_MPI
MPI_Bcast(&bThisReplicaExchanged, sizeof(gmx_bool), MPI_BYTE, MASTERRANK(cr),
if (bThisReplicaExchanged)
{
/* Exchange the states */
-
- if (PAR(cr))
+ /* Collect the global state on the master node */
+ if (DOMAINDECOMP(cr))
{
- /* Collect the global state on the master node */
- if (DOMAINDECOMP(cr))
- {
- dd_collect_state(cr->dd, state_local, state);
- }
- else
- {
- pd_collect_state(cr, state);
- }
+ dd_collect_state(cr->dd, state_local, state);
}
else
{
{
/* Copy the global state to the local state data structure */
copy_state_nonatomdata(state, state_local);
-
- if (PAR(cr))
- {
- bcast_state(cr, state, FALSE);
- }
}
}
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2011,2012,2013, by the GROMACS development team, led by
+ * Copyright (c) 2011,2012,2013,2014, 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.
* Returns TRUE if this state has been exchanged.
* When running each replica in parallel,
* this routine collects the state on the master node before exchange.
- * With particle the state is redistributed over the nodes after exchange.
- * With domain decomposition the global state after exchanged in stored
+ * With domain decomposition, the global state after exchange is stored
* in state and still needs to be redistributed over the nodes.
*/
extern void print_replica_exchange_statistics(FILE *fplog, gmx_repl_ex_t re);
/* Should only be called on the master nodes */
-extern void pd_distribute_state(const t_commrec *cr, t_state *state);
-/* Distributes the state after exchange for particle decomposition */
-
#endif /* _repl_ex_h */
#include "repl_ex.h"
#include "qmmm.h"
#include "domdec.h"
-#include "partdec.h"
#include "coulomb.h"
#include "constr.h"
#include "mvdata.h"
{
/* now broadcast everything to the non-master nodes/threads: */
init_parallel(cr, inputrec, mtop);
-
- /* This check needs to happen after get_nthreads_mpi() */
- if (inputrec->cutoff_scheme == ecutsVERLET && (Flags & MD_PARTDEC))
- {
- gmx_fatal_collective(FARGS, cr, NULL,
- "The Verlet cut-off scheme is not supported with particle decomposition.\n"
- "You can achieve the same effect as particle decomposition by running in parallel using only OpenMP threads.");
- }
}
if (fplog != NULL)
{
gmx_fatal(FARGS, "The .mdp file specified an energy mininization or normal mode algorithm, and these are not compatible with mdrun -rerun");
}
- if (can_use_allvsall(inputrec, TRUE, cr, fplog) && PAR(cr))
+ if (can_use_allvsall(inputrec, TRUE, cr, fplog) && DOMAINDECOMP(cr))
{
- /* Simple neighbour searching and (also?) all-vs-all loops
- * do not work with domain decomposition. */
- Flags |= MD_PARTDEC;
+ gmx_fatal(FARGS, "All-vs-all loops do not work with domain decomposition, use a single MPI rank");
}
- if (!(EEL_PME(inputrec->coulombtype) || EVDW_PME(inputrec->vdwtype)) || (Flags & MD_PARTDEC))
+ if (!(EEL_PME(inputrec->coulombtype) || EVDW_PME(inputrec->vdwtype)))
{
if (cr->npmenodes > 0)
{
- if (!EEL_PME(inputrec->coulombtype) && !EVDW_PME(inputrec->vdwtype))
- {
- gmx_fatal_collective(FARGS, cr, NULL,
- "PME nodes are requested, but the system does not use PME electrostatics or LJ-PME");
- }
- if (Flags & MD_PARTDEC)
- {
- gmx_fatal_collective(FARGS, cr, NULL,
- "PME nodes are requested, but particle decomposition does not support separate PME nodes");
- }
+ gmx_fatal_collective(FARGS, cr, NULL,
+ "PME nodes are requested, but the system does not use PME electrostatics or LJ-PME");
}
cr->npmenodes = 0;
snew(fcd, 1);
/* This needs to be called before read_checkpoint to extend the state */
- init_disres(fplog, mtop, inputrec, cr, Flags & MD_PARTDEC, fcd, state, repl_ex_nst > 0);
+ init_disres(fplog, mtop, inputrec, cr, fcd, state, repl_ex_nst > 0);
init_orires(fplog, mtop, state->x, inputrec, cr, &(fcd->orires),
- state, Flags & MD_PARTDEC);
+ state);
if (DEFORM(*inputrec))
{
if (gmx_fexist_master(opt2fn_master("-cpi", nfile, fnm, cr), cr) )
{
load_checkpoint(opt2fn_master("-cpi", nfile, fnm, cr), &fplog,
- cr, Flags & MD_PARTDEC, ddxyz,
+ cr, ddxyz,
inputrec, state, &bReadRNG, &bReadEkin,
(Flags & MD_APPENDFILES),
(Flags & MD_APPENDFILESSET));
ed = ed_open(mtop->natoms, &state->edsamstate, nfile, fnm, Flags, oenv, cr);
}
- if (PAR(cr) && !((Flags & MD_PARTDEC) ||
- EI_TPI(inputrec->eI) ||
+ if (PAR(cr) && !(EI_TPI(inputrec->eI) ||
inputrec->eI == eiNM))
{
cr->dd = init_domain_decomposition(fplog, cr, Flags, ddxyz, rdd, rconstr,
cr->duty = (DUTY_PP | DUTY_PME);
npme_major = 1;
npme_minor = 1;
- /* NM and TPI perform single node energy calculations in parallel */
- if (!(inputrec->eI == eiNM || EI_TPI(inputrec->eI)))
- {
- npme_major = cr->nnodes;
- }
if (inputrec->ePBC == epbcSCREW)
{
snew(nrnb, 1);
if (cr->duty & DUTY_PP)
{
- /* For domain decomposition we allocate dynamically
- * in dd_partition_system.
- */
- if (DOMAINDECOMP(cr))
- {
- bcast_state_setup(cr, state);
- }
- else
- {
- if (PAR(cr))
- {
- bcast_state(cr, state, TRUE);
- }
- }
+ bcast_state(cr, state);
/* Initiate forcerecord */
fr = mk_forcerec();