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
42 #include <sys/syscall.h>
57 #include "pull_rotation.h"
70 #include "checkpoint.h"
71 #include "mtop_util.h"
72 #include "sighandler.h"
75 #include "pull_rotation.h"
93 #include "md_openmm.h"
98 gmx_integrator_t *func;
101 /* The array should match the eI array in include/types/enums.h */
102 #ifdef GMX_OPENMM /* FIXME do_md_openmm needs fixing */
103 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}};
105 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}};
108 gmx_large_int_t deform_init_init_step_tpx;
109 matrix deform_init_box_tpx;
110 #ifdef GMX_THREAD_MPI
111 tMPI_Thread_mutex_t deform_init_box_mutex=TMPI_THREAD_MUTEX_INITIALIZER;
115 #ifdef GMX_THREAD_MPI
116 struct mdrunner_arglist
130 const char *dddlb_opt;
144 const char *deviceOptions;
146 int ret; /* return value */
150 /* The function used for spawning threads. Extracts the mdrunner()
151 arguments from its one argument and calls mdrunner(), after making
153 static void mdrunner_start_fn(void *arg)
155 struct mdrunner_arglist *mda=(struct mdrunner_arglist*)arg;
156 struct mdrunner_arglist mc=*mda; /* copy the arg list to make sure
157 that it's thread-local. This doesn't
158 copy pointed-to items, of course,
159 but those are all const. */
160 t_commrec *cr; /* we need a local version of this */
164 fnm = dup_tfn(mc.nfile, mc.fnm);
166 cr = init_par_threads(mc.cr);
173 mda->ret=mdrunner(cr->nnodes, fplog, cr, mc.nfile, fnm, mc.oenv,
174 mc.bVerbose, mc.bCompact, mc.nstglobalcomm,
175 mc.ddxyz, mc.dd_node_order, mc.rdd,
176 mc.rconstr, mc.dddlb_opt, mc.dlb_scale,
177 mc.ddcsx, mc.ddcsy, mc.ddcsz, mc.nstepout, mc.resetstep,
178 mc.nmultisim, mc.repl_ex_nst, mc.repl_ex_nex, mc.repl_ex_seed, mc.pforce,
179 mc.cpt_period, mc.max_hours, mc.deviceOptions, mc.Flags);
182 /* called by mdrunner() to start a specific number of threads (including
183 the main thread) for thread-parallel runs. This in turn calls mdrunner()
185 All options besides nthreads are the same as for mdrunner(). */
186 static t_commrec *mdrunner_start_threads(int nthreads,
187 FILE *fplog,t_commrec *cr,int nfile,
188 const t_filenm fnm[], const output_env_t oenv, gmx_bool bVerbose,
189 gmx_bool bCompact, int nstglobalcomm,
190 ivec ddxyz,int dd_node_order,real rdd,real rconstr,
191 const char *dddlb_opt,real dlb_scale,
192 const char *ddcsx,const char *ddcsy,const char *ddcsz,
193 int nstepout,int resetstep,int nmultisim,int repl_ex_nst,
194 int repl_ex_nex, int repl_ex_seed, real pforce,real cpt_period, real max_hours,
195 const char *deviceOptions, unsigned long Flags)
198 struct mdrunner_arglist *mda;
199 t_commrec *crn; /* the new commrec */
202 /* first check whether we even need to start tMPI */
206 /* a few small, one-time, almost unavoidable memory leaks: */
208 fnmn=dup_tfn(nfile, fnm);
210 /* fill the data structure to pass as void pointer to thread start fn */
216 mda->bVerbose=bVerbose;
217 mda->bCompact=bCompact;
218 mda->nstglobalcomm=nstglobalcomm;
219 mda->ddxyz[XX]=ddxyz[XX];
220 mda->ddxyz[YY]=ddxyz[YY];
221 mda->ddxyz[ZZ]=ddxyz[ZZ];
222 mda->dd_node_order=dd_node_order;
224 mda->rconstr=rconstr;
225 mda->dddlb_opt=dddlb_opt;
226 mda->dlb_scale=dlb_scale;
230 mda->nstepout=nstepout;
231 mda->resetstep=resetstep;
232 mda->nmultisim=nmultisim;
233 mda->repl_ex_nst=repl_ex_nst;
234 mda->repl_ex_nex=repl_ex_nex;
235 mda->repl_ex_seed=repl_ex_seed;
237 mda->cpt_period=cpt_period;
238 mda->max_hours=max_hours;
239 mda->deviceOptions=deviceOptions;
242 fprintf(stderr, "Starting %d threads\n",nthreads);
244 /* now spawn new threads that start mdrunner_start_fn(), while
245 the main thread returns */
246 ret=tMPI_Init_fn(TRUE, nthreads, mdrunner_start_fn, (void*)(mda) );
247 if (ret!=TMPI_SUCCESS)
250 /* make a new comm_rec to reflect the new situation */
251 crn=init_par_threads(cr);
256 /* Get the number of threads to use for thread-MPI based on how many
257 * were requested, which algorithms we're using,
258 * and how many particles there are.
260 static int get_nthreads_mpi(int nthreads_requested, t_inputrec *inputrec,
263 int nthreads,nthreads_new;
264 int min_atoms_per_thread;
267 nthreads = nthreads_requested;
269 /* determine # of hardware threads. */
270 if (nthreads_requested < 1)
272 if ((env = getenv("GMX_MAX_THREADS")) != NULL)
275 sscanf(env,"%d",&nthreads);
278 gmx_fatal(FARGS,"GMX_MAX_THREADS (%d) should be larger than 0",
284 nthreads = tMPI_Thread_get_hw_number();
288 if (inputrec->eI == eiNM || EI_TPI(inputrec->eI))
290 /* Steps are divided over the nodes iso splitting the atoms */
291 min_atoms_per_thread = 0;
295 min_atoms_per_thread = MIN_ATOMS_PER_THREAD;
298 /* Check if an algorithm does not support parallel simulation. */
300 ( inputrec->eI == eiLBFGS ||
301 inputrec->coulombtype == eelEWALD ) )
303 fprintf(stderr,"\nThe integration or electrostatics algorithm doesn't support parallel runs. Not starting any threads.\n");
306 else if (nthreads_requested < 1 &&
307 mtop->natoms/nthreads < min_atoms_per_thread)
309 /* the thread number was chosen automatically, but there are too many
310 threads (too few atoms per thread) */
311 nthreads_new = max(1,mtop->natoms/min_atoms_per_thread);
313 if (nthreads_new > 8 || (nthreads == 8 && nthreads_new > 4))
315 /* Use only multiples of 4 above 8 threads
316 * or with an 8-core processor
317 * (to avoid 6 threads on 8 core processors with 4 real cores).
319 nthreads_new = (nthreads_new/4)*4;
321 else if (nthreads_new > 4)
323 /* Avoid 5 or 7 threads */
324 nthreads_new = (nthreads_new/2)*2;
327 nthreads = nthreads_new;
329 fprintf(stderr,"\n");
330 fprintf(stderr,"NOTE: Parallelization is limited by the small number of atoms,\n");
331 fprintf(stderr," only starting %d threads.\n",nthreads);
332 fprintf(stderr," You can use the -nt option to optimize the number of threads.\n\n");
339 int mdrunner(int nthreads_requested, FILE *fplog,t_commrec *cr,int nfile,
340 const t_filenm fnm[], const output_env_t oenv, gmx_bool bVerbose,
341 gmx_bool bCompact, int nstglobalcomm,
342 ivec ddxyz,int dd_node_order,real rdd,real rconstr,
343 const char *dddlb_opt,real dlb_scale,
344 const char *ddcsx,const char *ddcsy,const char *ddcsz,
345 int nstepout,int resetstep,int nmultisim, int repl_ex_nst, int repl_ex_nex,
346 int repl_ex_seed, real pforce,real cpt_period,real max_hours,
347 const char *deviceOptions, unsigned long Flags)
349 double nodetime=0,realtime;
350 t_inputrec *inputrec;
353 gmx_ddbox_t ddbox={0};
354 int npme_major,npme_minor;
357 gmx_mtop_t *mtop=NULL;
358 t_mdatoms *mdatoms=NULL;
362 gmx_pme_t *pmedata=NULL;
363 gmx_vsite_t *vsite=NULL;
365 int i,m,nChargePerturbed=-1,status,nalloc;
367 gmx_wallcycle_t wcycle;
368 gmx_bool bReadRNG,bReadEkin;
370 gmx_runtime_t runtime;
372 gmx_large_int_t reset_counters;
374 t_commrec *cr_old=cr;
377 gmx_membed_t membed=NULL;
379 /* CAUTION: threads may be started later on in this function, so
380 cr doesn't reflect the final parallel state right now */
384 if (bVerbose && SIMMASTER(cr))
386 fprintf(stderr,"Getting Loaded...\n");
389 if (Flags & MD_APPENDFILES)
397 /* Read (nearly) all data required for the simulation */
398 read_tpx_state(ftp2fn(efTPX,nfile,fnm),inputrec,state,NULL,mtop);
400 /* NOW the threads will be started: */
401 #ifdef GMX_THREAD_MPI
402 nthreads_mpi = get_nthreads_mpi(nthreads_requested, inputrec, mtop);
404 if (nthreads_mpi > 1)
406 /* now start the threads. */
407 cr=mdrunner_start_threads(nthreads_mpi, fplog, cr_old, nfile, fnm,
408 oenv, bVerbose, bCompact, nstglobalcomm,
409 ddxyz, dd_node_order, rdd, rconstr,
410 dddlb_opt, dlb_scale, ddcsx, ddcsy, ddcsz,
411 nstepout, resetstep, nmultisim,
412 repl_ex_nst, repl_ex_nex, repl_ex_seed, pforce,
413 cpt_period, max_hours, deviceOptions,
415 /* the main thread continues here with a new cr. We don't deallocate
416 the old cr because other threads may still be reading it. */
419 gmx_comm("Failed to spawn threads");
424 /* END OF CAUTION: cr is now reliable */
426 /* g_membed initialisation *
427 * Because we change the mtop, init_membed is called before the init_parallel *
428 * (in case we ever want to make it run in parallel) */
429 if (opt2bSet("-membed",nfile,fnm))
433 fprintf(stderr,"Initializing membed");
435 membed = init_membed(fplog,nfile,fnm,mtop,inputrec,state,cr,&cpt_period);
440 /* now broadcast everything to the non-master nodes/threads: */
441 init_parallel(fplog, cr, inputrec, mtop);
445 pr_inputrec(fplog,0,"Input Parameters",inputrec,FALSE);
448 /* now make sure the state is initialized and propagated */
449 set_state_entries(state,inputrec,cr->nnodes);
451 /* remove when vv and rerun works correctly! */
452 if (PAR(cr) && EI_VV(inputrec->eI) && ((Flags & MD_RERUN) || (Flags & MD_RERUN_VSITE)))
455 "Currently can't do velocity verlet with rerun in parallel.");
458 /* A parallel command line option consistency check that we can
459 only do after any threads have started. */
461 (ddxyz[XX] > 1 || ddxyz[YY] > 1 || ddxyz[ZZ] > 1 || cr->npmenodes > 0))
464 "The -dd or -npme option request a parallel simulation, "
466 "but mdrun was compiled without threads or MPI enabled"
468 #ifdef GMX_THREAD_MPI
469 "but the number of threads (option -nt) is 1"
471 "but mdrun was not started through mpirun/mpiexec or only one process was requested through mpirun/mpiexec"
477 if ((Flags & MD_RERUN) &&
478 (EI_ENERGY_MINIMIZATION(inputrec->eI) || eiNM == inputrec->eI))
480 gmx_fatal(FARGS, "The .mdp file specified an energy mininization or normal mode algorithm, and these are not compatible with mdrun -rerun");
483 if (can_use_allvsall(inputrec,mtop,TRUE,cr,fplog))
485 /* All-vs-all loops do not work with domain decomposition */
489 if (!EEL_PME(inputrec->coulombtype) || (Flags & MD_PARTDEC))
491 if (cr->npmenodes > 0)
493 if (!EEL_PME(inputrec->coulombtype))
495 gmx_fatal_collective(FARGS,cr,NULL,
496 "PME nodes are requested, but the system does not use PME electrostatics");
498 if (Flags & MD_PARTDEC)
500 gmx_fatal_collective(FARGS,cr,NULL,
501 "PME nodes are requested, but particle decomposition does not support separate PME nodes");
509 fcRegisterSteps(inputrec->nsteps,inputrec->init_step);
512 /* NMR restraints must be initialized before load_checkpoint,
513 * since with time averaging the history is added to t_state.
514 * For proper consistency check we therefore need to extend
516 * So the PME-only nodes (if present) will also initialize
517 * the distance restraints.
521 /* This needs to be called before read_checkpoint to extend the state */
522 init_disres(fplog,mtop,inputrec,cr,Flags & MD_PARTDEC,fcd,state);
524 if (gmx_mtop_ftype_count(mtop,F_ORIRES) > 0)
526 if (PAR(cr) && !(Flags & MD_PARTDEC))
528 gmx_fatal(FARGS,"Orientation restraints do not work (yet) with domain decomposition, use particle decomposition (mdrun option -pd)");
530 /* Orientation restraints */
533 init_orires(fplog,mtop,state->x,inputrec,cr->ms,&(fcd->orires),
538 if (DEFORM(*inputrec))
540 /* Store the deform reference box before reading the checkpoint */
543 copy_mat(state->box,box);
547 gmx_bcast(sizeof(box),box,cr);
549 /* Because we do not have the update struct available yet
550 * in which the reference values should be stored,
551 * we store them temporarily in static variables.
552 * This should be thread safe, since they are only written once
553 * and with identical values.
555 #ifdef GMX_THREAD_MPI
556 tMPI_Thread_mutex_lock(&deform_init_box_mutex);
558 deform_init_init_step_tpx = inputrec->init_step;
559 copy_mat(box,deform_init_box_tpx);
560 #ifdef GMX_THREAD_MPI
561 tMPI_Thread_mutex_unlock(&deform_init_box_mutex);
565 if (opt2bSet("-cpi",nfile,fnm))
567 /* Check if checkpoint file exists before doing continuation.
568 * This way we can use identical input options for the first and subsequent runs...
570 if( gmx_fexist_master(opt2fn_master("-cpi",nfile,fnm,cr),cr) )
572 load_checkpoint(opt2fn_master("-cpi",nfile,fnm,cr),&fplog,
573 cr,Flags & MD_PARTDEC,ddxyz,
574 inputrec,state,&bReadRNG,&bReadEkin,
575 (Flags & MD_APPENDFILES),
576 (Flags & MD_APPENDFILESSET));
580 Flags |= MD_READ_RNG;
584 Flags |= MD_READ_EKIN;
589 if (((MASTER(cr) || (Flags & MD_SEPPOT)) && (Flags & MD_APPENDFILES))
590 #ifdef GMX_THREAD_MPI
591 /* With thread MPI only the master node/thread exists in mdrun.c,
592 * therefore non-master nodes need to open the "seppot" log file here.
594 || (!MASTER(cr) && (Flags & MD_SEPPOT))
598 gmx_log_open(ftp2fn(efLOG,nfile,fnm),cr,!(Flags & MD_SEPPOT),
604 copy_mat(state->box,box);
609 gmx_bcast(sizeof(box),box,cr);
612 /* Essential dynamics */
613 if (opt2bSet("-ei",nfile,fnm))
615 /* Open input and output files, allocate space for ED data structure */
616 ed = ed_open(nfile,fnm,Flags,cr);
619 if (bVerbose && SIMMASTER(cr))
621 fprintf(stderr,"Loaded with Money\n\n");
624 if (PAR(cr) && !((Flags & MD_PARTDEC) ||
625 EI_TPI(inputrec->eI) ||
626 inputrec->eI == eiNM))
628 cr->dd = init_domain_decomposition(fplog,cr,Flags,ddxyz,rdd,rconstr,
633 &ddbox,&npme_major,&npme_minor);
635 make_dd_communicators(fplog,cr,dd_node_order);
637 /* Set overallocation to avoid frequent reallocation of arrays */
638 set_over_alloc_dd(TRUE);
642 /* PME, if used, is done on all nodes with 1D decomposition */
644 cr->duty = (DUTY_PP | DUTY_PME);
647 if (!EI_TPI(inputrec->eI))
649 npme_major = cr->nnodes;
652 if (inputrec->ePBC == epbcSCREW)
655 "pbc=%s is only implemented with domain decomposition",
656 epbc_names[inputrec->ePBC]);
662 /* After possible communicator splitting in make_dd_communicators.
663 * we can set up the intra/inter node communication.
665 gmx_setup_nodecomm(fplog,cr);
668 /* get number of OpenMP/PME threads
669 * env variable should be read only on one node to make sure it is identical everywhere */
671 if (EEL_PME(inputrec->coulombtype))
676 if ((ptr=getenv("GMX_PME_NTHREADS")) != NULL)
678 sscanf(ptr,"%d",&nthreads_pme);
680 if (fplog != NULL && nthreads_pme > 1)
682 fprintf(fplog,"Using %d threads for PME\n",nthreads_pme);
687 gmx_bcast_sim(sizeof(nthreads_pme),&nthreads_pme,cr);
692 wcycle = wallcycle_init(fplog,resetstep,cr,nthreads_pme);
695 /* Master synchronizes its value of reset_counters with all nodes
696 * including PME only nodes */
697 reset_counters = wcycle_get_reset_counters(wcycle);
698 gmx_bcast_sim(sizeof(reset_counters),&reset_counters,cr);
699 wcycle_set_reset_counters(wcycle, reset_counters);
704 if (cr->duty & DUTY_PP)
706 /* For domain decomposition we allocate dynamically
707 * in dd_partition_system.
709 if (DOMAINDECOMP(cr))
711 bcast_state_setup(cr,state);
717 bcast_state(cr,state,TRUE);
721 /* Initiate forcerecord */
723 init_forcerec(fplog,oenv,fr,fcd,inputrec,mtop,cr,box,FALSE,
724 opt2fn("-table",nfile,fnm),
725 opt2fn("-tabletf",nfile,fnm),
726 opt2fn("-tablep",nfile,fnm),
727 opt2fn("-tableb",nfile,fnm),FALSE,pforce);
729 /* version for PCA_NOT_READ_NODE (see md.c) */
730 /*init_forcerec(fplog,fr,fcd,inputrec,mtop,cr,box,FALSE,
731 "nofile","nofile","nofile","nofile",FALSE,pforce);
733 fr->bSepDVDL = ((Flags & MD_SEPPOT) == MD_SEPPOT);
735 /* Initialize QM-MM */
738 init_QMMMrec(cr,box,mtop,inputrec,fr);
741 /* Initialize the mdatoms structure.
742 * mdatoms is not filled with atom data,
743 * as this can not be done now with domain decomposition.
745 mdatoms = init_mdatoms(fplog,mtop,inputrec->efep!=efepNO);
747 /* Initialize the virtual site communication */
748 vsite = init_vsite(mtop,cr);
750 calc_shifts(box,fr->shift_vec);
752 /* With periodic molecules the charge groups should be whole at start up
753 * and the virtual sites should not be far from their proper positions.
755 if (!inputrec->bContinuation && MASTER(cr) &&
756 !(inputrec->ePBC != epbcNONE && inputrec->bPeriodicMols))
758 /* Make molecules whole at start of run */
759 if (fr->ePBC != epbcNONE)
761 do_pbc_first_mtop(fplog,inputrec->ePBC,box,mtop,state->x);
765 /* Correct initial vsite positions are required
766 * for the initial distribution in the domain decomposition
767 * and for the initial shell prediction.
769 construct_vsites_mtop(fplog,vsite,mtop,state->x);
773 if (EEL_PME(fr->eeltype))
775 ewaldcoeff = fr->ewaldcoeff;
776 pmedata = &fr->pmedata;
785 /* This is a PME only node */
787 /* We don't need the state */
790 ewaldcoeff = calc_ewaldcoeff(inputrec->rcoulomb, inputrec->ewald_rtol);
794 /* Initiate PME if necessary,
795 * either on all nodes or on dedicated PME nodes only. */
796 if (EEL_PME(inputrec->coulombtype))
800 nChargePerturbed = mdatoms->nChargePerturbed;
802 if (cr->npmenodes > 0)
804 /* The PME only nodes need to know nChargePerturbed */
805 gmx_bcast_sim(sizeof(nChargePerturbed),&nChargePerturbed,cr);
809 /* Set CPU affinity. Can be important for performance.
810 On some systems (e.g. Cray) CPU Affinity is set by default.
811 But default assigning doesn't work (well) with only some ranks
812 having threads. This causes very low performance.
813 External tools have cumbersome syntax for setting affinity
814 in the case that only some ranks have threads.
815 Thus it is important that GROMACS sets the affinity internally at
816 if only PME is using threads.
824 MPI_Comm comm_intra; /* intra communicator (but different to nc.comm_intra includes PME nodes) */
825 MPI_Comm_split(MPI_COMM_WORLD,gmx_hostname_num(),gmx_node_rank(),&comm_intra);
826 int local_omp_nthreads = (cr->duty & DUTY_PME) ? nthreads_pme : 1; /* threads on this node */
827 MPI_Scan(&local_omp_nthreads,&core, 1, MPI_INT, MPI_SUM, comm_intra);
828 core-=local_omp_nthreads; /* make exclusive scan */
829 #pragma omp parallel firstprivate(core) num_threads(local_omp_nthreads)
833 core+=gmx_omp_get_thread_num();
835 sched_setaffinity((pid_t) syscall (SYS_gettid),sizeof(cpu_set_t),&mask);
840 #endif /*GMX_OPENMP*/
842 if (cr->duty & DUTY_PME)
844 status = gmx_pme_init(pmedata,cr,npme_major,npme_minor,inputrec,
845 mtop ? mtop->natoms : 0,nChargePerturbed,
846 (Flags & MD_REPRODUCIBLE),nthreads_pme);
849 gmx_fatal(FARGS,"Error %d initializing PME",status);
855 if (integrator[inputrec->eI].func == do_md
858 integrator[inputrec->eI].func == do_md_openmm
862 /* Turn on signal handling on all nodes */
864 * (A user signal from the PME nodes (if any)
865 * is communicated to the PP nodes.
867 signal_handler_install();
870 if (cr->duty & DUTY_PP)
872 if (inputrec->ePull != epullNO)
874 /* Initialize pull code */
875 init_pull(fplog,inputrec,nfile,fnm,mtop,cr,oenv, inputrec->fepvals->init_lambda,
876 EI_DYNAMICS(inputrec->eI) && MASTER(cr),Flags);
881 /* Initialize enforced rotation code */
882 init_rot(fplog,inputrec,nfile,fnm,cr,state->x,box,mtop,oenv,
886 constr = init_constraints(fplog,mtop,inputrec,ed,state,cr);
888 if (DOMAINDECOMP(cr))
890 dd_init_bondeds(fplog,cr->dd,mtop,vsite,constr,inputrec,
891 Flags & MD_DDBONDCHECK,fr->cginfo_mb);
893 set_dd_parameters(fplog,cr->dd,dlb_scale,inputrec,fr,&ddbox);
895 setup_dd_grid(fplog,cr->dd);
898 /* Now do whatever the user wants us to do (how flexible...) */
899 integrator[inputrec->eI].func(fplog,cr,nfile,fnm,
900 oenv,bVerbose,bCompact,
903 nstepout,inputrec,mtop,
905 mdatoms,nrnb,wcycle,ed,fr,
906 repl_ex_nst,repl_ex_nex,repl_ex_seed,
908 cpt_period,max_hours,
913 if (inputrec->ePull != epullNO)
915 finish_pull(fplog,inputrec->pull);
920 finish_rot(fplog,inputrec->rot);
927 gmx_pmeonly(*pmedata,cr,nrnb,wcycle,ewaldcoeff,FALSE,inputrec);
930 if (EI_DYNAMICS(inputrec->eI) || EI_TPI(inputrec->eI))
932 /* Some timing stats */
935 if (runtime.proc == 0)
937 runtime.proc = runtime.real;
946 wallcycle_stop(wcycle,ewcRUN);
948 /* Finish up, write some stuff
949 * if rerunMD, don't write last frame again
951 finish_run(fplog,cr,ftp2fn(efSTO,nfile,fnm),
952 inputrec,nrnb,wcycle,&runtime,
953 EI_DYNAMICS(inputrec->eI) && !MULTISIM(cr));
955 if (opt2bSet("-membed",nfile,fnm))
960 /* Does what it says */
961 print_date_and_time(fplog,cr->nodeid,"Finished mdrun",&runtime);
963 /* Close logfile already here if we were appending to it */
964 if (MASTER(cr) && (Flags & MD_APPENDFILES))
966 gmx_log_close(fplog);
969 rc=(int)gmx_get_stop_condition();
971 #ifdef GMX_THREAD_MPI
972 /* we need to join all threads. The sub-threads join when they
973 exit this function, but the master thread needs to be told to
975 if (PAR(cr) && MASTER(cr))