8 #if ((defined WIN32 || defined _WIN32 || defined WIN64 || defined _WIN64) && !defined __CYGWIN__ && !defined __CYGWIN32__)
44 #include "mpelogging.h"
50 #include "compute_io.h"
52 #include "checkpoint.h"
53 #include "mtop_util.h"
54 #include "sighandler.h"
62 /* include even when OpenMM not used to force compilation of do_md_openmm */
63 #include "openmm_wrapper.h"
66 enum { eglsNABNSB
, eglsCHKPT
, eglsTERM
, eglsRESETCOUNTERS
, eglsNR
};
70 int nstms
; /* The frequency for intersimulation communication */
71 int sig
[eglsNR
]; /* The signal set by one process in do_md */
72 int set
[eglsNR
]; /* The communicated signal, equal for all processes */
76 static int multisim_min(const gmx_multisim_t
*ms
,int nmin
,int n
)
84 gmx_sumi_sim(ms
->nsim
,buf
,ms
);
87 for (s
=0; s
<ms
->nsim
; s
++)
89 bPos
= bPos
&& (buf
[s
] > 0);
90 bEqual
= bEqual
&& (buf
[s
] == buf
[0]);
96 nmin
= min(nmin
,buf
[0]);
100 /* Find the least common multiple */
101 for (d
=2; d
<nmin
; d
++)
104 while (s
< ms
->nsim
&& d
% buf
[s
] == 0)
110 /* We found the LCM and it is less than nmin */
122 static int multisim_nstsimsync(const t_commrec
*cr
,
123 const t_inputrec
*ir
,int repl_ex_nst
)
130 nmin
= multisim_min(cr
->ms
,nmin
,ir
->nstlist
);
131 nmin
= multisim_min(cr
->ms
,nmin
,ir
->nstcalcenergy
);
132 nmin
= multisim_min(cr
->ms
,nmin
,repl_ex_nst
);
135 gmx_fatal(FARGS
,"Can not find an appropriate interval for inter-simulation communication, since nstlist, nstcalcenergy and -replex are all <= 0");
137 /* Avoid inter-simulation communication at every (second) step */
144 gmx_bcast(sizeof(int),&nmin
,cr
);
149 static void init_global_signals(globsig_t
*gs
,const t_commrec
*cr
,
150 const t_inputrec
*ir
,int repl_ex_nst
)
156 for (i
=0; i
<eglsNR
; i
++)
164 double do_md_openmm(FILE *fplog
,t_commrec
*cr
,int nfile
,const t_filenm fnm
[],
165 const output_env_t oenv
, bool bVerbose
,bool bCompact
,
167 gmx_vsite_t
*vsite
,gmx_constr_t constr
,
168 int stepout
,t_inputrec
*ir
,
169 gmx_mtop_t
*top_global
,
171 t_state
*state_global
,
173 t_nrnb
*nrnb
,gmx_wallcycle_t wcycle
,
174 gmx_edsam_t ed
,t_forcerec
*fr
,
175 int repl_ex_nst
,int repl_ex_seed
,
176 real cpt_period
,real max_hours
,
177 const char *deviceOptions
,
179 gmx_runtime_t
*runtime
)
182 gmx_large_int_t step
,step_rel
;
186 bFirstStep
,bStateFromTPX
,bLastStep
,bStartingFromCpt
;
188 bool bNEMD
,do_ene
,do_log
, do_verbose
,
190 tensor force_vir
,shake_vir
,total_vir
,pres
;
197 t_mdebin
*mdebin
=NULL
;
202 gmx_enerdata_t
*enerd
;
204 gmx_global_stat_t gstat
;
205 gmx_update_t upd
=NULL
;
209 gmx_groups_t
*groups
;
210 gmx_ekindata_t
*ekind
, *ekind_save
;
214 real reset_counters
=0,reset_counters_now
=0;
215 char sbuf
[STEPSTRSIZE
],sbuf2
[STEPSTRSIZE
];
216 int handledSignal
=-1; /* compare to last_signal_recvd */
217 bool bHandledSignal
=FALSE
;
219 const char *ommOptions
= NULL
;
222 bAppend
= (Flags
& MD_APPENDFILES
);
223 check_ir_old_tpx_versions(cr
,fplog
,ir
,top_global
);
225 groups
= &top_global
->groups
;
228 init_md(fplog
,cr
,ir
,oenv
,&t
,&t0
,&state_global
->lambda
,&lam0
,
229 nrnb
,top_global
,&upd
,
230 nfile
,fnm
,&outf
,&mdebin
,
231 force_vir
,shake_vir
,mu_tot
,&bNEMD
,&bSimAnn
,&vcm
,state_global
,Flags
);
233 clear_mat(total_vir
);
235 /* Energy terms and groups */
237 init_enerdata(top_global
->groups
.grps
[egcENER
].nr
,ir
->n_flambda
,enerd
);
238 snew(f
,top_global
->natoms
);
240 /* Kinetic energy data */
242 init_ekindata(fplog
,top_global
,&(ir
->opts
),ekind
);
243 /* needed for iteration of constraints */
245 init_ekindata(fplog
,top_global
,&(ir
->opts
),ekind_save
);
246 /* Copy the cos acceleration to the groups struct */
247 ekind
->cosacc
.cos_accel
= ir
->cos_accel
;
249 gstat
= global_stat_init(ir
);
253 double io
= compute_io(ir
,top_global
->natoms
,groups
,mdebin
->ebin
->nener
,1);
254 if ((io
> 2000) && MASTER(cr
))
256 "\nWARNING: This run will generate roughly %.0f Mb of data\n\n",
260 top
= gmx_mtop_generate_local_top(top_global
,ir
);
263 a1
= top_global
->natoms
;
265 state
= partdec_init_local_state(cr
,state_global
);
268 atoms2md(top_global
,ir
,0,NULL
,a0
,a1
-a0
,mdatoms
);
272 set_vsite_top(vsite
,top
,mdatoms
,cr
);
275 if (ir
->ePBC
!= epbcNONE
&& !ir
->bPeriodicMols
)
277 graph
= mk_graph(fplog
,&(top
->idef
),0,top_global
->natoms
,FALSE
,FALSE
);
280 update_mdatoms(mdatoms
,state
->lambda
);
282 if (deviceOptions
[0]=='\0')
284 /* empty options, which should default to OpenMM in this build */
285 ommOptions
=deviceOptions
;
289 if (gmx_strncasecmp(deviceOptions
,"OpenMM",6)!=0)
291 gmx_fatal(FARGS
, "This Gromacs version currently only works with OpenMM. Use -device \"OpenMM:<options>\"");
295 ommOptions
=strchr(deviceOptions
,':');
296 if (NULL
!=ommOptions
)
298 /* Increase the pointer to skip the colon */
304 openmmData
= openmm_init(fplog
, ommOptions
, cr
, ir
, top_global
, top
, mdatoms
, fr
, state
);
308 /* Update mdebin with energy history if appending to output files */
309 if ( Flags
& MD_APPENDFILES
)
311 restore_energyhistory_from_state(mdebin
,&state_global
->enerhist
);
313 /* Set the initial energy history in state to zero by updating once */
314 update_energyhistory(&state_global
->enerhist
,mdebin
);
319 set_constraints(constr
,top
,ir
,mdatoms
,cr
);
322 if (!ir
->bContinuation
)
324 if (mdatoms
->cFREEZE
&& (state
->flags
& (1<<estV
)))
326 /* Set the velocities of frozen particles to zero */
327 for (i
=mdatoms
->start
; i
<mdatoms
->start
+mdatoms
->homenr
; i
++)
329 for (m
=0; m
<DIM
; m
++)
331 if (ir
->opts
.nFreeze
[mdatoms
->cFREEZE
[i
]][m
])
341 /* Constrain the initial coordinates and velocities */
342 do_constrain_first(fplog
,constr
,ir
,mdatoms
,state
,f
,
343 graph
,cr
,nrnb
,fr
,top
,shake_vir
);
347 /* Construct the virtual sites for the initial configuration */
348 construct_vsites(fplog
,vsite
,state
->x
,nrnb
,ir
->delta_t
,NULL
,
349 top
->idef
.iparams
,top
->idef
.il
,
350 fr
->ePBC
,fr
->bMolPBC
,graph
,cr
,state
->box
);
359 fprintf(fplog
,"Initial temperature: %g K\n",enerd
->term
[F_TEMP
]);
360 fprintf(stderr
,"starting mdrun '%s'\n",
361 *(top_global
->name
));
364 sprintf(tbuf
,"%8.1f",(ir
->init_step
+ir
->nsteps
)*ir
->delta_t
);
368 sprintf(tbuf
,"%s","infinite");
370 if (ir
->init_step
> 0)
372 fprintf(stderr
,"%s steps, %s ps (continuing from step %s, %8.1f ps).\n",
373 gmx_step_str(ir
->init_step
+ir
->nsteps
,sbuf
),tbuf
,
374 gmx_step_str(ir
->init_step
,sbuf2
),
375 ir
->init_step
*ir
->delta_t
);
379 fprintf(stderr
,"%s steps, %s ps.\n",
380 gmx_step_str(ir
->nsteps
,sbuf
),tbuf
);
386 /* Set and write start time */
387 runtime_start(runtime
);
388 print_date_and_time(fplog
,cr
->nodeid
,"Started mdrun",runtime
);
389 wallcycle_start(wcycle
,ewcRUN
);
393 /* safest point to do file checkpointing is here. More general point would be immediately before integrator call */
396 /***********************************************************
400 ************************************************************/
402 /* loop over MD steps or if rerunMD to end of input trajectory */
404 /* Skip the first Nose-Hoover integration when we get the state from tpx */
405 bStateFromTPX
= !opt2bSet("-cpi",nfile
,fnm
);
406 bInitStep
= bFirstStep
&& bStateFromTPX
;
407 bStartingFromCpt
= (Flags
& MD_STARTFROMCPT
) && bInitStep
;
410 init_global_signals(&gs
,cr
,ir
,repl_ex_nst
);
412 step
= ir
->init_step
;
414 bLastStep
= ((ir
->nsteps
>= 0 && step_rel
> ir
->nsteps
));
418 wallcycle_start(wcycle
,ewcSTEP
);
420 GMX_MPE_LOG(ev_timestep1
);
422 bLastStep
= (step_rel
== ir
->nsteps
);
423 t
= t0
+ step
*ir
->delta_t
;
425 if (gs
.set
[eglsTERM
] != 0 )
430 do_log
= do_per_step(step
,ir
->nstlog
) || bFirstStep
|| bLastStep
;
431 do_verbose
= bVerbose
&&
432 (step
% stepout
== 0 || bFirstStep
|| bLastStep
);
434 if (MASTER(cr
) && do_log
)
436 print_ebin_header(fplog
,step
,t
,state
->lambda
);
439 clear_mat(force_vir
);
440 GMX_MPE_LOG(ev_timestep2
);
442 /* We write a checkpoint at this MD step when:
443 * either when we signalled through gs (in OpenMM NS works different),
444 * or at the last step (but not when we do not want confout),
445 * but never at the first step.
447 bCPT
= ((gs
.set
[eglsCHKPT
] ||
448 (bLastStep
&& (Flags
& MD_CONFOUT
))) &&
449 step
> ir
->init_step
);
452 gs
.set
[eglsCHKPT
] = 0;
455 /* Now we have the energies and forces corresponding to the
456 * coordinates at time t. We must output all of this before
458 * for RerunMD t is read from input trajectory
460 GMX_MPE_LOG(ev_output_start
);
463 if (do_per_step(step
,ir
->nstxout
))
465 mdof_flags
|= MDOF_X
;
467 if (do_per_step(step
,ir
->nstvout
))
469 mdof_flags
|= MDOF_V
;
471 if (do_per_step(step
,ir
->nstfout
))
473 mdof_flags
|= MDOF_F
;
475 if (do_per_step(step
,ir
->nstxtcout
))
477 mdof_flags
|= MDOF_XTC
;
481 mdof_flags
|= MDOF_CPT
;
483 do_ene
= do_per_step(step
,ir
->nstenergy
) || (bLastStep
&& ir
->nstenergy
);
487 bX
= (mdof_flags
& (MDOF_X
| MDOF_XTC
| MDOF_CPT
));
488 bV
= (mdof_flags
& (MDOF_V
| MDOF_CPT
));
490 wallcycle_start(wcycle
,ewcTRAJ
);
491 openmm_copy_state(openmmData
, state
, &t
, f
, enerd
, bX
, bV
, 0, 0);
492 wallcycle_stop(wcycle
,ewcTRAJ
);
495 openmm_take_one_step(openmmData
);
497 if (mdof_flags
!= 0 || do_ene
)
499 wallcycle_start(wcycle
,ewcTRAJ
);
500 bF
= (mdof_flags
& MDOF_F
);
503 openmm_copy_state(openmmData
, state
, &t
, f
, enerd
, 0, 0, bF
, do_ene
);
505 upd_mdebin(mdebin
, NULL
,TRUE
,
506 t
,mdatoms
->tmass
,enerd
,state
,lastbox
,
507 shake_vir
,force_vir
,total_vir
,pres
,
508 ekind
,mu_tot
,constr
);
509 print_ebin(outf
->fp_ene
,do_ene
,FALSE
,FALSE
,fplog
,step
,t
,
510 eprAVER
,FALSE
,mdebin
,fcd
,groups
,&(ir
->opts
));
512 write_traj(fplog
,cr
,outf
,mdof_flags
,top_global
,
513 step
,t
,state
,state_global
,f
,f_global
,&n_xtc
,&x_xtc
);
520 if (bLastStep
&& step_rel
== ir
->nsteps
&&
521 (Flags
& MD_CONFOUT
) && MASTER(cr
))
523 /* x and v have been collected in write_traj,
524 * because a checkpoint file will always be written
527 fprintf(stderr
,"\nWriting final coordinates.\n");
528 if (ir
->ePBC
!= epbcNONE
&& !ir
->bPeriodicMols
)
530 /* Make molecules whole only for confout writing */
531 do_pbc_mtop(fplog
,ir
->ePBC
,state
->box
,top_global
,state_global
->x
);
533 write_sto_conf_mtop(ftp2fn(efSTO
,nfile
,fnm
),
534 *top_global
->name
,top_global
,
535 state_global
->x
,state_global
->v
,
536 ir
->ePBC
,state
->box
);
539 wallcycle_stop(wcycle
,ewcTRAJ
);
541 GMX_MPE_LOG(ev_output_finish
);
544 /* Determine the wallclock run time up till now */
545 run_time
= gmx_gettime() - (double)runtime
->real
;
547 /* Check whether everything is still allright */
548 if ((bGotStopNextStepSignal
|| bGotStopNextNSStepSignal
) &&
549 (handledSignal
!=last_signal_number_recvd
) &&
552 if (bGotStopNextStepSignal
)
554 gs
.set
[eglsTERM
] = 1;
558 gs
.set
[eglsTERM
] = -1;
563 "\n\nReceived the %s signal, stopping at the next %sstep\n\n",
564 signal_name
[last_signal_number_recvd
],
565 gs
.set
[eglsTERM
]==-1 ? "NS " : "");
569 "\n\nReceived the %s signal, stopping at the next %sstep\n\n",
570 signal_name
[last_signal_number_recvd
],
571 gs
.set
[eglsTERM
]==-1 ? "NS " : "");
573 handledSignal
=last_signal_number_recvd
;
575 else if (MASTER(cr
) &&
576 (max_hours
> 0 && run_time
> max_hours
*60.0*60.0*0.99) &&
577 gs
.set
[eglsTERM
] == 0)
579 /* Signal to terminate the run */
580 gs
.set
[eglsTERM
] = 1;
583 fprintf(fplog
,"\nStep %s: Run time exceeded %.3f hours, will terminate the run\n",gmx_step_str(step
,sbuf
),max_hours
*0.99);
585 fprintf(stderr
, "\nStep %s: Run time exceeded %.3f hours, will terminate the run\n",gmx_step_str(step
,sbuf
),max_hours
*0.99);
589 if (MASTER(cr
) && (cpt_period
>= 0 &&
591 run_time
>= nchkpt
*cpt_period
*60.0)) &&
592 gs
.set
[eglsCHKPT
] == 0)
594 gs
.set
[eglsCHKPT
] = 1;
597 /* Time for performance */
598 if (((step
% stepout
) == 0) || bLastStep
)
600 runtime_upd_proc(runtime
);
603 if (do_per_step(step
,ir
->nstlog
))
605 if (fflush(fplog
) != 0)
607 gmx_fatal(FARGS
,"Cannot flush logfile - maybe you are out of quota?");
611 /* Remaining runtime */
612 if (MULTIMASTER(cr
) && do_verbose
)
614 print_time(stderr
,runtime
,step
,ir
,cr
);
619 bStartingFromCpt
= FALSE
;
623 /* End of main MD loop */
627 runtime_end(runtime
);
629 openmm_cleanup(fplog
, openmmData
);
635 runtime
->nsteps_done
= step_rel
;