/* Tell our PME-only node to finish */
GMX_LIBMD_EXPORT
-void gmx_pme_send_switch(t_commrec *cr, ivec grid_size, real ewaldcoeff);
+void gmx_pme_send_switchgrid(t_commrec *cr, ivec grid_size, real ewaldcoeff);
/* Tell our PME-only node to switch to a new grid size */
+GMX_LIBMD_EXPORT
+void gmx_pme_send_resetcounters(t_commrec *cr, gmx_large_int_t step);
+/* Tell our PME-only node to reset all cycle and flop counters */
+
void gmx_pme_receive_f(t_commrec *cr,
rvec f[], matrix vir,
real *energy, real *dvdlambda,
float *pme_cycles);
/* PP nodes receive the long range forces from the PME nodes */
+/* Return values for gmx_pme_recv_q_x */
+enum {
+ pmerecvqxX, /* calculate PME mesh interactions for new x */
+ pmerecvqxFINISH, /* the simulation should finish, we should quit */
+ pmerecvqxSWITCHGRID, /* change the PME grid size */
+ pmerecvqxRESETCOUNTERS /* reset the cycle and flop counters */
+};
+
int gmx_pme_recv_q_x(gmx_pme_pp_t pme_pp,
+ int *natoms,
real **chargeA, real **chargeB,
matrix box, rvec **x, rvec **f,
int *maxshift_x, int *maxshift_y,
gmx_large_int_t *step,
ivec grid_size, real *ewaldcoeff);
;
-/* Receive charges and/or coordinates from the PP-only nodes.
- * Returns the number of atoms, or -1 when the run is finished.
- * In the special case of a PME grid size switch request, -2 is returned
- * and grid_size and *ewaldcoeff are set, which are otherwise not set.
+/* With return value:
+ * pmerecvqxX: all parameters set, chargeA and chargeB can be NULL
+ * pmerecvqxFINISH: no parameters set
+ * pmerecvqxSWITCHGRID: only grid_size and *ewaldcoeff are set
+ * pmerecvqxRESETCOUNTERS: *step is set
*/
void gmx_pme_send_force_vir_ener(gmx_pme_pp_t pme_pp,
reset_all_counters(fplog, cr, step, &step_rel, ir, wcycle, nrnb, runtime,
fr->nbv != NULL && fr->nbv->bUseGPU ? fr->nbv->cu_nbv : NULL);
wcycle_set_reset_counters(wcycle, -1);
+ if (!(cr->duty & DUTY_PME))
+ {
+ /* Tell our PME node to reset its counters */
+ gmx_pme_send_resetcounters(cr, step);
+ }
/* Correct max_hours for the elapsed time */
max_hours -= run_time/(60.0*60.0);
bResetCountersHalfMaxH = FALSE;
else
{
/* Tell our PME-only node to switch grid */
- gmx_pme_send_switch(cr, set->grid, set->ewaldcoeff);
+ gmx_pme_send_switchgrid(cr, set->grid, set->ewaldcoeff);
}
if (debug)
static void reset_pmeonly_counters(t_commrec *cr, gmx_wallcycle_t wcycle,
- t_nrnb *nrnb, t_inputrec *ir, gmx_large_int_t step_rel)
+ t_nrnb *nrnb, t_inputrec *ir,
+ gmx_large_int_t step)
{
/* Reset all the counters related to performance over the run */
wallcycle_stop(wcycle, ewcRUN);
wallcycle_reset_all(wcycle);
init_nrnb(nrnb);
- ir->init_step += step_rel;
- ir->nsteps -= step_rel;
+ if (ir->nsteps >= 0)
+ {
+ /* ir->nsteps is not used here, but we update it for consistency */
+ ir->nsteps -= step - ir->init_step;
+ }
+ ir->init_step = step;
wallcycle_start(wcycle, ewcRUN);
}
int npmedata;
gmx_pme_t *pmedata;
gmx_pme_pp_t pme_pp;
+ int ret;
int natoms;
matrix box;
rvec *x_pp = NULL, *f_pp = NULL;
do
{
/* Domain decomposition */
- natoms = gmx_pme_recv_q_x(pme_pp,
- &chargeA, &chargeB, box, &x_pp, &f_pp,
- &maxshift_x, &maxshift_y,
- &pme->bFEP, &lambda,
- &bEnerVir,
- &step,
- grid_switch, &ewaldcoeff);
-
- if (natoms == -2)
+ ret = gmx_pme_recv_q_x(pme_pp,
+ &natoms,
+ &chargeA, &chargeB, box, &x_pp, &f_pp,
+ &maxshift_x, &maxshift_y,
+ &pme->bFEP, &lambda,
+ &bEnerVir,
+ &step,
+ grid_switch, &ewaldcoeff);
+
+ if (ret == pmerecvqxSWITCHGRID)
{
/* Switch the PME grid to grid_switch */
gmx_pmeonly_switch(&npmedata, &pmedata, grid_switch, cr, ir, &pme);
}
+
+ if (ret == pmerecvqxRESETCOUNTERS)
+ {
+ /* Reset the cycle and flop counters */
+ reset_pmeonly_counters(cr, wcycle, nrnb, ir, step);
+ }
}
- while (natoms == -2);
+ while (ret == pmerecvqxSWITCHGRID || ret == pmerecvqxRESETCOUNTERS);
- if (natoms == -1)
+ if (ret == pmerecvqxFINISH)
{
/* We should stop: break out of the loop */
break;
cycles);
count++;
-
- if (step_rel == wcycle_get_reset_counters(wcycle))
- {
- /* Reset all the counters related to performance over the run */
- reset_pmeonly_counters(cr, wcycle, nrnb, ir, step_rel);
- wcycle_set_reset_counters(wcycle, 0);
- }
-
} /***** end of quasi-loop, we stop with the break above */
while (TRUE);
#include "mpelogging.h"
-#define PP_PME_CHARGE (1<<0)
-#define PP_PME_CHARGEB (1<<1)
-#define PP_PME_COORD (1<<2)
-#define PP_PME_FEP (1<<3)
-#define PP_PME_ENER_VIR (1<<4)
-#define PP_PME_FINISH (1<<5)
-#define PP_PME_SWITCH (1<<6)
+#define PP_PME_CHARGE (1<<0)
+#define PP_PME_CHARGEB (1<<1)
+#define PP_PME_COORD (1<<2)
+#define PP_PME_FEP (1<<3)
+#define PP_PME_ENER_VIR (1<<4)
+#define PP_PME_FINISH (1<<5)
+#define PP_PME_SWITCHGRID (1<<6)
+#define PP_PME_RESETCOUNTERS (1<<7)
+
#define PME_PP_SIGSTOP (1<<0)
#define PME_PP_SIGSTOPNSS (1<<1)
gmx_pme_send_q_x(cr, flags, NULL, NULL, NULL, NULL, 0, 0, 0, -1);
}
-void gmx_pme_send_switch(t_commrec *cr, ivec grid_size, real ewaldcoeff)
+void gmx_pme_send_switchgrid(t_commrec *cr, ivec grid_size, real ewaldcoeff)
{
#ifdef GMX_MPI
gmx_pme_comm_n_box_t cnb;
+ /* Only let one PP node signal each PME node */
if (cr->dd->pme_receive_vir_ener)
{
- cnb.flags = PP_PME_SWITCH;
+ cnb.flags = PP_PME_SWITCHGRID;
copy_ivec(grid_size, cnb.grid_size);
cnb.ewaldcoeff = ewaldcoeff;
#endif
}
+void gmx_pme_send_resetcounters(t_commrec *cr, gmx_large_int_t step)
+{
+#ifdef GMX_MPI
+ gmx_pme_comm_n_box_t cnb;
+
+ /* Only let one PP node signal each PME node */
+ if (cr->dd->pme_receive_vir_ener)
+ {
+ cnb.flags = PP_PME_RESETCOUNTERS;
+ cnb.step = step;
+
+ /* We send this, uncommon, message blocking to simplify the code */
+ MPI_Send(&cnb, sizeof(cnb), MPI_BYTE,
+ cr->dd->pme_nodeid, 0, cr->mpi_comm_mysim);
+ }
+#endif
+}
+
int gmx_pme_recv_q_x(struct gmx_pme_pp *pme_pp,
+ int *natoms,
real **chargeA, real **chargeB,
matrix box, rvec **x, rvec **f,
int *maxshift_x, int *maxshift_y,
if (debug)
{
- fprintf(debug, "PME only node receiving:%s%s%s%s\n",
- (cnb.flags & PP_PME_CHARGE) ? " charges" : "",
- (cnb.flags & PP_PME_COORD ) ? " coordinates" : "",
- (cnb.flags & PP_PME_FINISH) ? " finish" : "",
- (cnb.flags & PP_PME_SWITCH) ? " switch" : "");
+ fprintf(debug, "PME only node receiving:%s%s%s%s%s\n",
+ (cnb.flags & PP_PME_CHARGE) ? " charges" : "",
+ (cnb.flags & PP_PME_COORD ) ? " coordinates" : "",
+ (cnb.flags & PP_PME_FINISH) ? " finish" : "",
+ (cnb.flags & PP_PME_SWITCHGRID) ? " switch grid" : "",
+ (cnb.flags & PP_PME_RESETCOUNTERS) ? " reset counters" : "");
}
- if (cnb.flags & PP_PME_SWITCH)
+ if (cnb.flags & PP_PME_SWITCHGRID)
{
/* Special case, receive the new parameters and return */
copy_ivec(cnb.grid_size, grid_size);
*ewaldcoeff = cnb.ewaldcoeff;
- return -2;
+ return pmerecvqxSWITCHGRID;
+ }
+
+ if (cnb.flags & PP_PME_RESETCOUNTERS)
+ {
+ /* Special case, receive the step and return */
+ *step = cnb.step;
+
+ return pmerecvqxRESETCOUNTERS;
}
if (cnb.flags & PP_PME_CHARGE)
*step = cnb.step;
#endif
+ *natoms = nat;
*chargeA = pme_pp->chargeA;
*chargeB = pme_pp->chargeB;
*x = pme_pp->x;
*f = pme_pp->f;
-
- return ((cnb.flags & PP_PME_FINISH) ? -1 : nat);
+ return ((cnb.flags & PP_PME_FINISH) ? pmerecvqxFINISH : pmerecvqxX);
}
static void receive_virial_energy(t_commrec *cr,