void gmx_bcast_sim(int nbytes, void *b, const t_commrec *cr) { #ifndef GMX_MPI gmx_call("gmx_bast"); #else MPI_Bcast(b, nbytes, MPI_BYTE, MASTERRANK(cr), cr->mpi_comm_mysim); #endif }
static bool invalidWithinSimulation(const t_commrec *cr, bool invalidLocally) { #ifdef GMX_MPI int value = invalidLocally ? 1 : 0; int globalValue; MPI_Reduce(&value, &globalValue, 1, MPI_INT, MPI_LAND, MASTERRANK(cr), cr->mpi_comm_mysim); return SIMMASTER(cr) ? (globalValue != 0) : invalidLocally; #else return invalidLocally; #endif }
gmx_bool replica_exchange(FILE *fplog, const t_commrec *cr, struct gmx_repl_ex *re, t_state *state, gmx_enerdata_t *enerd, t_state *state_local, gmx_int64_t step, real time) { int i, j; int replica_id = 0; int exchange_partner; int maxswap = 0; /* Number of rounds of exchanges needed to deal with any multiple * exchanges. */ /* Where each replica ends up after the exchange attempt(s). */ /* The order in which multiple exchanges will occur. */ gmx_bool bThisReplicaExchanged = FALSE; if (MASTER(cr)) { replica_id = re->repl; test_for_replica_exchange(fplog, cr->ms, re, enerd, det(state_local->box), step, time); prepare_to_do_exchange(fplog, re->destinations, replica_id, re->nrepl, &maxswap, re->order, re->cyclic, re->incycle, &bThisReplicaExchanged); } /* Do intra-simulation broadcast so all processors belonging to * 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 (DOMAINDECOMP(cr)) { #ifdef GMX_MPI MPI_Bcast(&bThisReplicaExchanged, sizeof(gmx_bool), MPI_BYTE, MASTERRANK(cr), cr->mpi_comm_mygroup); #endif } if (bThisReplicaExchanged) { /* Exchange the states */ /* Collect the global state on the master node */ if (DOMAINDECOMP(cr)) { dd_collect_state(cr->dd, state_local, state); } else { copy_state_nonatomdata(state_local, state); } if (MASTER(cr)) { /* There will be only one swap cycle with standard replica * exchange, but there may be multiple swap cycles if we * allow multiple swaps. */ for (j = 0; j < maxswap; j++) { exchange_partner = re->order[replica_id][j]; if (exchange_partner != replica_id) { /* Exchange the global states between the master nodes */ if (debug) { fprintf(debug, "Exchanging %d with %d\n", replica_id, exchange_partner); } exchange_state(cr->ms, exchange_partner, state); } } /* For temperature-type replica exchange, we need to scale * the velocities. */ if (re->type == ereTEMP || re->type == ereTL) { scale_velocities(state, sqrt(re->q[ereTEMP][replica_id]/re->q[ereTEMP][re->destinations[replica_id]])); } } /* With domain decomposition the global state is distributed later */ if (!DOMAINDECOMP(cr)) { /* Copy the global state to the local state data structure */ copy_state_nonatomdata(state, state_local); } } return bThisReplicaExchanged; }
gmx_bool replica_exchange(FILE *fplog,const t_commrec *cr,struct gmx_repl_ex *re, t_state *state,real *ener, t_state *state_local, int step,real time) { gmx_multisim_t *ms; int exchange=-1,shift; gmx_bool bExchanged=FALSE; ms = cr->ms; if (MASTER(cr)) { exchange = get_replica_exchange(fplog,ms,re,ener,det(state->box), step,time); bExchanged = (exchange >= 0); } if (PAR(cr)) { #ifdef GMX_MPI MPI_Bcast(&bExchanged,sizeof(gmx_bool),MPI_BYTE,MASTERRANK(cr), cr->mpi_comm_mygroup); #endif } if (bExchanged) { /* Exchange the states */ if (PAR(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); } } if (MASTER(cr)) { /* Exchange the global states between the master nodes */ if (debug) { fprintf(debug,"Exchanging %d with %d\n",ms->sim,exchange); } exchange_state(ms,exchange,state); if (re->type == ereTEMP) { scale_velocities(state,sqrt(re->q[ms->sim]/re->q[exchange])); } } /* With domain decomposition the global state is distributed later */ if (!DOMAINDECOMP(cr)) { /* Copy the global state to the local state data structure */ copy_state_nonatomdata(state,state_local); if (PAR(cr)) { bcast_state(cr,state,FALSE); } } } return bExchanged; }