1 /* -*- mode: c; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; c-file-style: "stroustrup"; -*-
4 * This source code is part of
8 * GROningen MAchine for Chemical Simulations
11 * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
12 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
13 * Copyright (c) 2001-2004, The GROMACS development team,
14 * check out http://www.gromacs.org for more information.
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
21 * If you want to redistribute modifications, please consider that
22 * scientific software is very special. Version control is crucial -
23 * bugs must be traceable. We will be happy to consider code for
24 * inclusion in the official distribution, but derived work must not
25 * be called official GROMACS. Details are found in the README & COPYING
26 * files - if they are missing, get the official version at www.gromacs.org.
28 * To help us fund GROMACS development, we humbly ask that you cite
29 * the papers on the package - you can find them in the top README file.
31 * For more info, check our website at http://www.gromacs.org
34 * Gallium Rubidium Oxygen Manganese Argon Carbon Silicon
43 #if ((defined WIN32 || defined _WIN32 || defined WIN64 || defined _WIN64) && !defined __CYGWIN__ && !defined __CYGWIN32__)
64 #include "mpelogging.h"
70 #include "checkpoint.h"
71 #include "mtop_util.h"
72 #include "sighandler.h"
74 #include "md_openmm.h"
88 #include "md_openmm.h"
91 /* The following two variables and the signal_handler function
92 * are used from md.c and pme.c as well
94 extern bool bGotTermSignal
, bGotUsr1Signal
;
96 static RETSIGTYPE
signal_handler(int n
)
100 bGotTermSignal
= TRUE
;
104 bGotUsr1Signal
= TRUE
;
111 gmx_integrator_t
*func
;
114 /* The array should match the eI array in include/types/enums.h */
115 #ifdef GMX_OPENMM /* FIXME do_md_openmm needs fixing */
116 const gmx_intp_t integrator
[eiNR
] = { {do_md_openmm
}, {do_md_openmm
}, {do_md_openmm
}, {do_md_openmm
}, {do_md_openmm
}, {do_md_openmm
}, {do_md_openmm
}, {do_md_openmm
}, {do_md_openmm
}, {do_md_openmm
}, {do_md_openmm
},{do_md_openmm
}};
118 const gmx_intp_t integrator
[eiNR
] = { {do_md
}, {do_steep
}, {do_cg
}, {do_md
}, {do_md
}, {do_nm
}, {do_lbfgs
}, {do_tpi
}, {do_tpi
}, {do_md
}, {do_md
},{do_md
}};
121 gmx_large_int_t deform_init_init_step_tpx
;
122 matrix deform_init_box_tpx
;
124 tMPI_Thread_mutex_t deform_init_box_mutex
=TMPI_THREAD_MUTEX_INITIALIZER
;
129 struct mdrunner_arglist
143 const char *dddlb_opt
;
156 const char *deviceOptions
;
158 int ret
; /* return value */
162 static void mdrunner_start_fn(void *arg
)
164 struct mdrunner_arglist
*mda
=(struct mdrunner_arglist
*)arg
;
165 struct mdrunner_arglist mc
=*mda
; /* copy the arg list to make sure
166 that it's thread-local. This doesn't
167 copy pointed-to items, of course,
168 but those are all const. */
169 t_commrec
*cr
; /* we need a local version of this */
171 t_filenm
*fnm
=dup_tfn(mc
.nfile
, mc
.fnm
);
173 cr
=init_par_threads(mc
.cr
);
180 mda
->ret
=mdrunner(fplog
, cr
, mc
.nfile
, mc
.fnm
, mc
.oenv
, mc
.bVerbose
,
181 mc
.bCompact
, mc
.nstglobalcomm
,
182 mc
.ddxyz
, mc
.dd_node_order
, mc
.rdd
,
183 mc
.rconstr
, mc
.dddlb_opt
, mc
.dlb_scale
,
184 mc
.ddcsx
, mc
.ddcsy
, mc
.ddcsz
, mc
.nstepout
, mc
.resetstep
, mc
.nmultisim
,
185 mc
.repl_ex_nst
, mc
.repl_ex_seed
, mc
.pforce
,
186 mc
.cpt_period
, mc
.max_hours
, mc
.deviceOptions
, mc
.Flags
);
191 int mdrunner_threads(int nthreads
,
192 FILE *fplog
,t_commrec
*cr
,int nfile
,const t_filenm fnm
[],
193 const output_env_t oenv
, bool bVerbose
,bool bCompact
,
195 ivec ddxyz
,int dd_node_order
,real rdd
,real rconstr
,
196 const char *dddlb_opt
,real dlb_scale
,
197 const char *ddcsx
,const char *ddcsy
,const char *ddcsz
,
198 int nstepout
,int resetstep
,int nmultisim
,int repl_ex_nst
,
199 int repl_ex_seed
, real pforce
,real cpt_period
,
200 real max_hours
, const char *deviceOptions
, unsigned long Flags
)
203 /* first check whether we even need to start tMPI */
206 ret
=mdrunner(fplog
, cr
, nfile
, fnm
, oenv
, bVerbose
, bCompact
,
208 ddxyz
, dd_node_order
, rdd
, rconstr
, dddlb_opt
, dlb_scale
,
209 ddcsx
, ddcsy
, ddcsz
, nstepout
, resetstep
, nmultisim
, repl_ex_nst
,
210 repl_ex_seed
, pforce
, cpt_period
, max_hours
, deviceOptions
, Flags
);
215 struct mdrunner_arglist mda
;
216 /* fill the data structure to pass as void pointer to thread start fn */
222 mda
.bVerbose
=bVerbose
;
223 mda
.bCompact
=bCompact
;
224 mda
.nstglobalcomm
=nstglobalcomm
;
225 mda
.ddxyz
[XX
]=ddxyz
[XX
];
226 mda
.ddxyz
[YY
]=ddxyz
[YY
];
227 mda
.ddxyz
[ZZ
]=ddxyz
[ZZ
];
228 mda
.dd_node_order
=dd_node_order
;
231 mda
.dddlb_opt
=dddlb_opt
;
232 mda
.dlb_scale
=dlb_scale
;
236 mda
.nstepout
=nstepout
;
237 mda
.resetstep
=resetstep
;
238 mda
.nmultisim
=nmultisim
;
239 mda
.repl_ex_nst
=repl_ex_nst
;
240 mda
.repl_ex_seed
=repl_ex_seed
;
242 mda
.cpt_period
=cpt_period
;
243 mda
.max_hours
=max_hours
;
244 mda
.deviceOptions
=deviceOptions
;
247 fprintf(stderr
, "Starting %d threads\n",nthreads
);
249 tMPI_Init_fn(nthreads
, mdrunner_start_fn
, (void*)(&mda
) );
253 gmx_comm("Multiple threads requested but not compiled with threads");
260 int mdrunner(FILE *fplog
,t_commrec
*cr
,int nfile
,const t_filenm fnm
[],
261 const output_env_t oenv
, bool bVerbose
,bool bCompact
,
263 ivec ddxyz
,int dd_node_order
,real rdd
,real rconstr
,
264 const char *dddlb_opt
,real dlb_scale
,
265 const char *ddcsx
,const char *ddcsy
,const char *ddcsz
,
266 int nstepout
,int resetstep
,int nmultisim
,int repl_ex_nst
,int repl_ex_seed
,
267 real pforce
,real cpt_period
,real max_hours
,
268 const char *deviceOptions
,
271 double nodetime
=0,realtime
;
272 t_inputrec
*inputrec
;
279 gmx_mtop_t
*mtop
=NULL
;
280 t_mdatoms
*mdatoms
=NULL
;
284 gmx_pme_t
*pmedata
=NULL
;
285 gmx_vsite_t
*vsite
=NULL
;
287 int i
,m
,nChargePerturbed
=-1,status
,nalloc
;
289 gmx_wallcycle_t wcycle
;
290 bool bReadRNG
,bReadEkin
;
292 gmx_runtime_t runtime
;
294 gmx_large_int_t reset_counters
;
297 /* A parallel command line option consistency check */
299 (ddxyz
[XX
] > 1 || ddxyz
[YY
] > 1 || ddxyz
[ZZ
] > 1 || cr
->npmenodes
> 0))
302 "The -dd or -npme option request a parallel simulation, "
304 "but mdrun was compiled without threads or MPI enabled"
307 "but the number of threads (option -nt) is 1"
309 "but mdrun was not started through mpirun/mpiexec or only one process was requested through mpirun/mpiexec"
315 /* Essential dynamics */
316 if (opt2bSet("-ei",nfile
,fnm
))
318 /* Open input and output files, allocate space for ED data structure */
319 ed
= ed_open(nfile
,fnm
,cr
);
327 if (bVerbose
&& SIMMASTER(cr
))
329 fprintf(stderr
,"Getting Loaded...\n");
332 if (Flags
& MD_APPENDFILES
)
339 /* The master thread on the master node reads from disk,
340 * then distributes everything to the other processors.
343 list
= (SIMMASTER(cr
) && !(Flags
& MD_APPENDFILES
)) ? (LIST_SCALARS
| LIST_INPUTREC
) : 0;
346 init_parallel(fplog
, opt2fn_master("-s",nfile
,fnm
,cr
),cr
,
347 inputrec
,mtop
,state
,list
);
352 /* Read a file for a single processor */
354 init_single(fplog
,inputrec
,ftp2fn(efTPX
,nfile
,fnm
),mtop
,state
);
356 if (!EEL_PME(inputrec
->coulombtype
) || (Flags
& MD_PARTDEC
))
362 fcRegisterSteps(inputrec
->nsteps
,inputrec
->init_step
);
365 /* NMR restraints must be initialized before load_checkpoint,
366 * since with time averaging the history is added to t_state.
367 * For proper consistency check we therefore need to extend
369 * So the PME-only nodes (if present) will also initialize
370 * the distance restraints.
374 /* This needs to be called before read_checkpoint to extend the state */
375 init_disres(fplog
,mtop
,inputrec
,cr
,Flags
& MD_PARTDEC
,fcd
,state
);
377 if (gmx_mtop_ftype_count(mtop
,F_ORIRES
) > 0)
379 if (PAR(cr
) && !(Flags
& MD_PARTDEC
))
381 gmx_fatal(FARGS
,"Orientation restraints do not work (yet) with domain decomposition, use particle decomposition (mdrun option -pd)");
383 /* Orientation restraints */
386 init_orires(fplog
,mtop
,state
->x
,inputrec
,cr
->ms
,&(fcd
->orires
),
391 if (DEFORM(*inputrec
))
393 /* Store the deform reference box before reading the checkpoint */
396 copy_mat(state
->box
,box
);
400 gmx_bcast(sizeof(box
),box
,cr
);
402 /* Because we do not have the update struct available yet
403 * in which the reference values should be stored,
404 * we store them temporarily in static variables.
405 * This should be thread safe, since they are only written once
406 * and with identical values.
409 tMPI_Thread_mutex_lock(&deform_init_box_mutex
);
411 deform_init_init_step_tpx
= inputrec
->init_step
;
412 copy_mat(box
,deform_init_box_tpx
);
414 tMPI_Thread_mutex_unlock(&deform_init_box_mutex
);
418 if (opt2bSet("-cpi",nfile
,fnm
))
420 /* Check if checkpoint file exists before doing continuation.
421 * This way we can use identical input options for the first and subsequent runs...
423 if( gmx_fexist_master(opt2fn_master("-cpi",nfile
,fnm
,cr
),cr
) )
425 load_checkpoint(opt2fn_master("-cpi",nfile
,fnm
,cr
),&fplog
,
426 cr
,Flags
& MD_PARTDEC
,ddxyz
,
427 inputrec
,state
,&bReadRNG
,&bReadEkin
,
428 (Flags
& MD_APPENDFILES
));
432 Flags
|= MD_READ_RNG
;
436 Flags
|= MD_READ_EKIN
;
441 if ((MASTER(cr
) || (Flags
& MD_SEPPOT
)) && (Flags
& MD_APPENDFILES
))
443 gmx_log_open(ftp2fn(efLOG
,nfile
,fnm
),cr
,!(Flags
& MD_SEPPOT
),
449 copy_mat(state
->box
,box
);
454 gmx_bcast(sizeof(box
),box
,cr
);
457 if (bVerbose
&& SIMMASTER(cr
))
459 fprintf(stderr
,"Loaded with Money\n\n");
462 if (PAR(cr
) && !((Flags
& MD_PARTDEC
) || EI_TPI(inputrec
->eI
)))
464 cr
->dd
= init_domain_decomposition(fplog
,cr
,Flags
,ddxyz
,rdd
,rconstr
,
471 make_dd_communicators(fplog
,cr
,dd_node_order
);
473 /* Set overallocation to avoid frequent reallocation of arrays */
474 set_over_alloc_dd(TRUE
);
478 cr
->duty
= (DUTY_PP
| DUTY_PME
);
479 npme_major
= cr
->nnodes
;
481 if (inputrec
->ePBC
== epbcSCREW
)
484 "pbc=%s is only implemented with domain decomposition",
485 epbc_names
[inputrec
->ePBC
]);
491 /* After possible communicator splitting in make_dd_communicators.
492 * we can set up the intra/inter node communication.
494 gmx_setup_nodecomm(fplog
,cr
);
497 wcycle
= wallcycle_init(fplog
,resetstep
,cr
);
500 /* Master synchronizes its value of reset_counters with all nodes
501 * including PME only nodes */
502 reset_counters
= wcycle_get_reset_counters(wcycle
);
503 gmx_bcast_sim(sizeof(reset_counters
),&reset_counters
,cr
);
504 wcycle_set_reset_counters(wcycle
, reset_counters
);
509 if (cr
->duty
& DUTY_PP
)
511 /* For domain decomposition we allocate dynamically
512 * in dd_partition_system.
514 if (DOMAINDECOMP(cr
))
516 bcast_state_setup(cr
,state
);
526 bcast_state(cr
,state
,TRUE
);
530 /* Dihedral Restraints */
531 if (gmx_mtop_ftype_count(mtop
,F_DIHRES
) > 0)
533 init_dihres(fplog
,mtop
,inputrec
,fcd
);
536 /* Initiate forcerecord */
538 init_forcerec(fplog
,oenv
,fr
,fcd
,inputrec
,mtop
,cr
,box
,FALSE
,
539 opt2fn("-table",nfile
,fnm
),
540 opt2fn("-tablep",nfile
,fnm
),
541 opt2fn("-tableb",nfile
,fnm
),FALSE
,pforce
);
543 /* version for PCA_NOT_READ_NODE (see md.c) */
544 /*init_forcerec(fplog,fr,fcd,inputrec,mtop,cr,box,FALSE,
545 "nofile","nofile","nofile",FALSE,pforce);
547 fr
->bSepDVDL
= ((Flags
& MD_SEPPOT
) == MD_SEPPOT
);
549 /* Initialize QM-MM */
552 init_QMMMrec(cr
,box
,mtop
,inputrec
,fr
);
555 /* Initialize the mdatoms structure.
556 * mdatoms is not filled with atom data,
557 * as this can not be done now with domain decomposition.
559 mdatoms
= init_mdatoms(fplog
,mtop
,inputrec
->efep
!=efepNO
);
561 /* Initialize the virtual site communication */
562 vsite
= init_vsite(mtop
,cr
);
564 calc_shifts(box
,fr
->shift_vec
);
566 /* With periodic molecules the charge groups should be whole at start up
567 * and the virtual sites should not be far from their proper positions.
569 if (!inputrec
->bContinuation
&& MASTER(cr
) &&
570 !(inputrec
->ePBC
!= epbcNONE
&& inputrec
->bPeriodicMols
))
572 /* Make molecules whole at start of run */
573 if (fr
->ePBC
!= epbcNONE
)
575 do_pbc_first_mtop(fplog
,inputrec
->ePBC
,box
,mtop
,state
->x
);
579 /* Correct initial vsite positions are required
580 * for the initial distribution in the domain decomposition
581 * and for the initial shell prediction.
583 construct_vsites_mtop(fplog
,vsite
,mtop
,state
->x
);
587 /* Initiate PPPM if necessary */
588 if (fr
->eeltype
== eelPPPM
)
590 if (mdatoms
->nChargePerturbed
)
592 gmx_fatal(FARGS
,"Free energy with %s is not implemented",
593 eel_names
[fr
->eeltype
]);
595 status
= gmx_pppm_init(fplog
,cr
,oenv
,FALSE
,TRUE
,box
,
596 getenv("GMXGHAT"),inputrec
, (Flags
& MD_REPRODUCIBLE
));
599 gmx_fatal(FARGS
,"Error %d initializing PPPM",status
);
603 if (EEL_PME(fr
->eeltype
))
605 ewaldcoeff
= fr
->ewaldcoeff
;
606 pmedata
= &fr
->pmedata
;
615 /* This is a PME only node */
617 /* We don't need the state */
620 ewaldcoeff
= calc_ewaldcoeff(inputrec
->rcoulomb
, inputrec
->ewald_rtol
);
624 /* Initiate PME if necessary,
625 * either on all nodes or on dedicated PME nodes only. */
626 if (EEL_PME(inputrec
->coulombtype
))
630 nChargePerturbed
= mdatoms
->nChargePerturbed
;
632 if (cr
->npmenodes
> 0)
634 /* The PME only nodes need to know nChargePerturbed */
635 gmx_bcast_sim(sizeof(nChargePerturbed
),&nChargePerturbed
,cr
);
637 if (cr
->duty
& DUTY_PME
)
639 status
= gmx_pme_init(pmedata
,cr
,npme_major
,inputrec
,
640 mtop
? mtop
->natoms
: 0,nChargePerturbed
,
641 (Flags
& MD_REPRODUCIBLE
));
644 gmx_fatal(FARGS
,"Error %d initializing PME",status
);
650 if (integrator
[inputrec
->eI
].func
== do_md
)
652 /* Turn on signal handling on all nodes */
654 * (A user signal from the PME nodes (if any)
655 * is communicated to the PP nodes.
657 signal_handler_install();
660 if (cr
->duty
& DUTY_PP
)
662 if (inputrec
->ePull
!= epullNO
)
664 /* Initialize pull code */
665 init_pull(fplog
,inputrec
,nfile
,fnm
,mtop
,cr
,oenv
,
666 EI_DYNAMICS(inputrec
->eI
) && MASTER(cr
),Flags
);
669 constr
= init_constraints(fplog
,mtop
,inputrec
,ed
,state
,cr
);
671 if (DOMAINDECOMP(cr
))
673 dd_init_bondeds(fplog
,cr
->dd
,mtop
,vsite
,constr
,inputrec
,
674 Flags
& MD_DDBONDCHECK
,fr
->cginfo_mb
);
676 set_dd_parameters(fplog
,cr
->dd
,dlb_scale
,inputrec
,fr
,&ddbox
);
678 setup_dd_grid(fplog
,cr
->dd
);
681 /* Now do whatever the user wants us to do (how flexible...) */
682 integrator
[inputrec
->eI
].func(fplog
,cr
,nfile
,fnm
,
683 oenv
,bVerbose
,bCompact
,
686 nstepout
,inputrec
,mtop
,
688 mdatoms
,nrnb
,wcycle
,ed
,fr
,
689 repl_ex_nst
,repl_ex_seed
,
690 cpt_period
,max_hours
,
695 if (inputrec
->ePull
!= epullNO
)
697 finish_pull(fplog
,inputrec
->pull
);
703 gmx_pmeonly(*pmedata
,cr
,nrnb
,wcycle
,ewaldcoeff
,FALSE
,inputrec
);
706 if (EI_DYNAMICS(inputrec
->eI
) || EI_TPI(inputrec
->eI
))
708 /* Some timing stats */
711 if (runtime
.proc
== 0)
713 runtime
.proc
= runtime
.real
;
722 wallcycle_stop(wcycle
,ewcRUN
);
724 /* Finish up, write some stuff
725 * if rerunMD, don't write last frame again
727 finish_run(fplog
,cr
,ftp2fn(efSTO
,nfile
,fnm
),
728 inputrec
,nrnb
,wcycle
,&runtime
,
729 EI_DYNAMICS(inputrec
->eI
) && !MULTISIM(cr
));
731 /* Does what it says */
732 print_date_and_time(fplog
,cr
->nodeid
,"Finished mdrun",&runtime
);
734 /* Close logfile already here if we were appending to it */
735 if (MASTER(cr
) && (Flags
& MD_APPENDFILES
))
737 gmx_log_close(fplog
);
740 if(bGotStopNextStepSignal
)
744 else if(bGotStopNextNSStepSignal
)
756 void md_print_warning(const t_commrec
*cr
,FILE *fplog
,const char *buf
)
760 fprintf(stderr
,"\n%s\n",buf
);
764 fprintf(fplog
,"\n%s\n",buf
);