1d15fd00da4cfe63aa361464950a798134127e28
[alexxy/gromacs.git] / src / contrib / runner_openmm.c
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
5  * Copyright (c) 2001-2004, The GROMACS development team,
6  * check out http://www.gromacs.org for more information.
7  * Copyright (c) 2012, by the GROMACS development team, led by
8  * David van der Spoel, Berk Hess, Erik Lindahl, and including many
9  * others, as listed in the AUTHORS file in the top-level source
10  * directory and at http://www.gromacs.org.
11  *
12  * GROMACS is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU Lesser General Public License
14  * as published by the Free Software Foundation; either version 2.1
15  * of the License, or (at your option) any later version.
16  *
17  * GROMACS is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20  * Lesser General Public License for more details.
21  *
22  * You should have received a copy of the GNU Lesser General Public
23  * License along with GROMACS; if not, see
24  * http://www.gnu.org/licenses, or write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
26  *
27  * If you want to redistribute modifications to GROMACS, please
28  * consider that scientific software is very special. Version
29  * control is crucial - bugs must be traceable. We will be happy to
30  * consider code for inclusion in the official distribution, but
31  * derived work must not be called official GROMACS. Details are found
32  * in the README & COPYING files - if they are missing, get the
33  * official version at http://www.gromacs.org.
34  *
35  * To help us fund GROMACS development, we humbly ask that you cite
36  * the research papers on the package. Check out http://www.gromacs.org.
37  */
38 #ifdef HAVE_CONFIG_H
39 #include <config.h>
40 #endif
41 #if defined(HAVE_SCHED_H) && defined(HAVE_SCHED_GETAFFINITY)
42 #define _GNU_SOURCE
43 #include <sched.h>
44 #include <sys/syscall.h>
45 #endif
46 #include <signal.h>
47 #include <stdlib.h>
48 #include <string.h>
49 #include <assert.h>
50
51 #include "typedefs.h"
52 #include "smalloc.h"
53 #include "sysstuff.h"
54 #include "statutil.h"
55 #include "mdrun.h"
56 #include "md_logging.h"
57 #include "md_support.h"
58 #include "network.h"
59 #include "pull.h"
60 #include "names.h"
61 #include "disre.h"
62 #include "orires.h"
63 #include "pme.h"
64 #include "mdatoms.h"
65 #include "repl_ex.h"
66 #include "qmmm.h"
67 #include "mpelogging.h"
68 #include "domdec.h"
69 #include "partdec.h"
70 #include "coulomb.h"
71 #include "constr.h"
72 #include "mvdata.h"
73 #include "checkpoint.h"
74 #include "mtop_util.h"
75 #include "sighandler.h"
76 #include "tpxio.h"
77 #include "txtdump.h"
78 #include "gmx_detect_hardware.h"
79 #include "gmx_omp_nthreads.h"
80 #include "pull_rotation.h"
81 #include "calc_verletbuf.h"
82 #include "../mdlib/nbnxn_search.h"
83 #include "../mdlib/nbnxn_consts.h"
84 #include "gmx_fatal_collective.h"
85 #include "membed.h"
86 #include "md_openmm.h"
87 #include "gmx_omp.h"
88
89 #include "thread_mpi/threads.h"
90
91 #include "gromacs/utility/gmxmpi.h"
92
93 #ifdef GMX_FAHCORE
94 #include "corewrap.h"
95 #endif
96
97 #include "gpu_utils.h"
98 #include "nbnxn_cuda_data_mgmt.h"
99
100 typedef struct { 
101     gmx_integrator_t *func;
102 } gmx_intp_t;
103
104 /* The array should match the eI array in include/types/enums.h */
105 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}};
106
107 gmx_large_int_t     deform_init_init_step_tpx;
108 matrix              deform_init_box_tpx;
109 #ifdef GMX_THREAD_MPI
110 tMPI_Thread_mutex_t deform_init_box_mutex=TMPI_THREAD_MUTEX_INITIALIZER;
111 #endif
112
113
114 #ifdef GMX_THREAD_MPI
115 struct mdrunner_arglist
116 {
117     gmx_hw_opt_t *hw_opt;
118     FILE *fplog;
119     t_commrec *cr;
120     int nfile;
121     const t_filenm *fnm;
122     output_env_t oenv;
123     gmx_bool bVerbose;
124     gmx_bool bCompact;
125     int nstglobalcomm;
126     ivec ddxyz;
127     int dd_node_order;
128     real rdd;
129     real rconstr;
130     const char *dddlb_opt;
131     real dlb_scale;
132     const char *ddcsx;
133     const char *ddcsy;
134     const char *ddcsz;
135     const char *nbpu_opt;
136     int nsteps_cmdline;
137     int nstepout;
138     int resetstep;
139     int nmultisim;
140     int repl_ex_nst;
141     int repl_ex_nex;
142     int repl_ex_seed;
143     real pforce;
144     real cpt_period;
145     real max_hours;
146     const char *deviceOptions;
147     unsigned long Flags;
148     int ret; /* return value */
149 };
150
151
152 /* The function used for spawning threads. Extracts the mdrunner() 
153    arguments from its one argument and calls mdrunner(), after making
154    a commrec. */
155 static void mdrunner_start_fn(void *arg)
156 {
157     struct mdrunner_arglist *mda=(struct mdrunner_arglist*)arg;
158     struct mdrunner_arglist mc=*mda; /* copy the arg list to make sure 
159                                         that it's thread-local. This doesn't
160                                         copy pointed-to items, of course,
161                                         but those are all const. */
162     t_commrec *cr;  /* we need a local version of this */
163     FILE *fplog=NULL;
164     t_filenm *fnm;
165
166     fnm = dup_tfn(mc.nfile, mc.fnm);
167
168     cr = init_par_threads(mc.cr);
169
170     if (MASTER(cr))
171     {
172         fplog=mc.fplog;
173     }
174
175     mda->ret=mdrunner(mc.hw_opt, fplog, cr, mc.nfile, fnm, mc.oenv, 
176                       mc.bVerbose, mc.bCompact, mc.nstglobalcomm, 
177                       mc.ddxyz, mc.dd_node_order, mc.rdd,
178                       mc.rconstr, mc.dddlb_opt, mc.dlb_scale, 
179                       mc.ddcsx, mc.ddcsy, mc.ddcsz,
180                       mc.nbpu_opt,
181                       mc.nsteps_cmdline, mc.nstepout, mc.resetstep,
182                       mc.nmultisim, mc.repl_ex_nst, mc.repl_ex_nex, mc.repl_ex_seed, mc.pforce, 
183                       mc.cpt_period, mc.max_hours, mc.deviceOptions, mc.Flags);
184 }
185
186 /* called by mdrunner() to start a specific number of threads (including 
187    the main thread) for thread-parallel runs. This in turn calls mdrunner()
188    for each thread. 
189    All options besides nthreads are the same as for mdrunner(). */
190 static t_commrec *mdrunner_start_threads(gmx_hw_opt_t *hw_opt, 
191               FILE *fplog,t_commrec *cr,int nfile, 
192               const t_filenm fnm[], const output_env_t oenv, gmx_bool bVerbose,
193               gmx_bool bCompact, int nstglobalcomm,
194               ivec ddxyz,int dd_node_order,real rdd,real rconstr,
195               const char *dddlb_opt,real dlb_scale,
196               const char *ddcsx,const char *ddcsy,const char *ddcsz,
197               const char *nbpu_opt,
198               int nsteps_cmdline, int nstepout,int resetstep,
199               int nmultisim,int repl_ex_nst,int repl_ex_nex, int repl_ex_seed,
200               real pforce,real cpt_period, real max_hours, 
201               const char *deviceOptions, unsigned long Flags)
202 {
203     int ret;
204     struct mdrunner_arglist *mda;
205     t_commrec *crn; /* the new commrec */
206     t_filenm *fnmn;
207
208     /* first check whether we even need to start tMPI */
209     if (hw_opt->nthreads_tmpi < 2)
210     {
211         return cr;
212     }
213
214     /* a few small, one-time, almost unavoidable memory leaks: */
215     snew(mda,1);
216     fnmn=dup_tfn(nfile, fnm);
217
218     /* fill the data structure to pass as void pointer to thread start fn */
219     mda->hw_opt=hw_opt;
220     mda->fplog=fplog;
221     mda->cr=cr;
222     mda->nfile=nfile;
223     mda->fnm=fnmn;
224     mda->oenv=oenv;
225     mda->bVerbose=bVerbose;
226     mda->bCompact=bCompact;
227     mda->nstglobalcomm=nstglobalcomm;
228     mda->ddxyz[XX]=ddxyz[XX];
229     mda->ddxyz[YY]=ddxyz[YY];
230     mda->ddxyz[ZZ]=ddxyz[ZZ];
231     mda->dd_node_order=dd_node_order;
232     mda->rdd=rdd;
233     mda->rconstr=rconstr;
234     mda->dddlb_opt=dddlb_opt;
235     mda->dlb_scale=dlb_scale;
236     mda->ddcsx=ddcsx;
237     mda->ddcsy=ddcsy;
238     mda->ddcsz=ddcsz;
239     mda->nbpu_opt=nbpu_opt;
240     mda->nsteps_cmdline=nsteps_cmdline;
241     mda->nstepout=nstepout;
242     mda->resetstep=resetstep;
243     mda->nmultisim=nmultisim;
244     mda->repl_ex_nst=repl_ex_nst;
245     mda->repl_ex_nex=repl_ex_nex;
246     mda->repl_ex_seed=repl_ex_seed;
247     mda->pforce=pforce;
248     mda->cpt_period=cpt_period;
249     mda->max_hours=max_hours;
250     mda->deviceOptions=deviceOptions;
251     mda->Flags=Flags;
252
253     /* now spawn new threads that start mdrunner_start_fn(), while 
254        the main thread returns */
255     ret=tMPI_Init_fn(TRUE, hw_opt->nthreads_tmpi,
256                      (hw_opt->bThreadPinning ? TMPI_AFFINITY_ALL_CORES : TMPI_AFFINITY_NONE),
257                      mdrunner_start_fn, (void*)(mda) );
258     if (ret!=TMPI_SUCCESS)
259         return NULL;
260
261     /* make a new comm_rec to reflect the new situation */
262     crn=init_par_threads(cr);
263     return crn;
264 }
265
266
267 static int get_tmpi_omp_thread_division(const gmx_hw_info_t *hwinfo,
268                                         const gmx_hw_opt_t *hw_opt,
269                                         int nthreads_tot,
270                                         int ngpu)
271 {
272     int nthreads_tmpi;
273
274     /* There are no separate PME nodes here, as we ensured in
275      * check_and_update_hw_opt that nthreads_tmpi>0 with PME nodes
276      * and a conditional ensures we would not have ended up here.
277      * Note that separate PME nodes might be switched on later.
278      */
279     if (ngpu > 0)
280     {
281         nthreads_tmpi = ngpu;
282         if (nthreads_tot > 0 && nthreads_tot < nthreads_tmpi)
283         {
284             nthreads_tmpi = nthreads_tot;
285         }
286     }
287     else if (hw_opt->nthreads_omp > 0)
288     {
289         /* Here we could oversubscribe, when we do, we issue a warning later */
290         nthreads_tmpi = max(1,nthreads_tot/hw_opt->nthreads_omp);
291     }
292     else
293     {
294         /* TODO choose nthreads_omp based on hardware topology
295            when we have a hardware topology detection library */
296         /* In general, when running up to 4 threads, OpenMP should be faster.
297          * Note: on AMD Bulldozer we should avoid running OpenMP over two dies.
298          * On Intel>=Nehalem running OpenMP on a single CPU is always faster,
299          * even on two CPUs it's usually faster (but with many OpenMP threads
300          * it could be faster not to use HT, currently we always use HT).
301          * On Nehalem/Westmere we want to avoid running 16 threads over
302          * two CPUs with HT, so we need a limit<16; thus we use 12.
303          * A reasonable limit for Intel Sandy and Ivy bridge,
304          * not knowing the topology, is 16 threads.
305          */
306         const int nthreads_omp_always_faster             =  4;
307         const int nthreads_omp_always_faster_Nehalem     = 12;
308         const int nthreads_omp_always_faster_SandyBridge = 16;
309         const int first_model_Nehalem     = 0x1A;
310         const int first_model_SandyBridge = 0x2A;
311         gmx_bool bIntel_Family6;
312
313         bIntel_Family6 =
314             (gmx_cpuid_vendor(hwinfo->cpuid_info) == GMX_CPUID_VENDOR_INTEL &&
315              gmx_cpuid_family(hwinfo->cpuid_info) == 6);
316
317         if (nthreads_tot <= nthreads_omp_always_faster ||
318             (bIntel_Family6 &&
319              ((gmx_cpuid_model(hwinfo->cpuid_info) >= nthreads_omp_always_faster_Nehalem && nthreads_tot <= nthreads_omp_always_faster_Nehalem) ||
320               (gmx_cpuid_model(hwinfo->cpuid_info) >= nthreads_omp_always_faster_SandyBridge && nthreads_tot <= nthreads_omp_always_faster_SandyBridge))))
321         {
322             /* Use pure OpenMP parallelization */
323             nthreads_tmpi = 1;
324         }
325         else
326         {
327             /* Don't use OpenMP parallelization */
328             nthreads_tmpi = nthreads_tot;
329         }
330     }
331
332     return nthreads_tmpi;
333 }
334
335
336 /* Get the number of threads to use for thread-MPI based on how many
337  * were requested, which algorithms we're using,
338  * and how many particles there are.
339  * At the point we have already called check_and_update_hw_opt.
340  * Thus all options should be internally consistent and consistent
341  * with the hardware, except that ntmpi could be larger than #GPU.
342  */
343 static int get_nthreads_mpi(gmx_hw_info_t *hwinfo,
344                             gmx_hw_opt_t *hw_opt,
345                             t_inputrec *inputrec, gmx_mtop_t *mtop,
346                             const t_commrec *cr,
347                             FILE *fplog)
348 {
349     int nthreads_hw,nthreads_tot_max,nthreads_tmpi,nthreads_new,ngpu;
350     int min_atoms_per_mpi_thread;
351     char *env;
352     char sbuf[STRLEN];
353     gmx_bool bCanUseGPU;
354
355     if (hw_opt->nthreads_tmpi > 0)
356     {
357         /* Trivial, return right away */
358         return hw_opt->nthreads_tmpi;
359     }
360
361     nthreads_hw = hwinfo->nthreads_hw_avail;
362
363     /* How many total (#tMPI*#OpenMP) threads can we start? */ 
364     if (hw_opt->nthreads_tot > 0)
365     {
366         nthreads_tot_max = hw_opt->nthreads_tot;
367     }
368     else
369     {
370         nthreads_tot_max = nthreads_hw;
371     }
372
373     bCanUseGPU = (inputrec->cutoff_scheme == ecutsVERLET && hwinfo->bCanUseGPU);
374     if (bCanUseGPU)
375     {
376         ngpu = hwinfo->gpu_info.ncuda_dev_use;
377     }
378     else
379     {
380         ngpu = 0;
381     }
382
383     nthreads_tmpi =
384         get_tmpi_omp_thread_division(hwinfo,hw_opt,nthreads_tot_max,ngpu);
385
386     if (inputrec->eI == eiNM || EI_TPI(inputrec->eI))
387     {
388         /* Steps are divided over the nodes iso splitting the atoms */
389         min_atoms_per_mpi_thread = 0;
390     }
391     else
392     {
393         if (bCanUseGPU)
394         {
395             min_atoms_per_mpi_thread = MIN_ATOMS_PER_GPU;
396         }
397         else
398         {
399             min_atoms_per_mpi_thread = MIN_ATOMS_PER_MPI_THREAD;
400         }
401     }
402
403     /* Check if an algorithm does not support parallel simulation.  */
404     if (nthreads_tmpi != 1 &&
405         ( inputrec->eI == eiLBFGS ||
406           inputrec->coulombtype == eelEWALD ) )
407     {
408         nthreads_tmpi = 1;
409
410         md_print_warn(cr,fplog,"The integration or electrostatics algorithm doesn't support parallel runs. Using a single thread-MPI thread.\n");
411         if (hw_opt->nthreads_tmpi > nthreads_tmpi)
412         {
413             gmx_fatal(FARGS,"You asked for more than 1 thread-MPI thread, but an algorithm doesn't support that");
414         }
415     }
416     else if (mtop->natoms/nthreads_tmpi < min_atoms_per_mpi_thread)
417     {
418         /* the thread number was chosen automatically, but there are too many
419            threads (too few atoms per thread) */
420         nthreads_new = max(1,mtop->natoms/min_atoms_per_mpi_thread);
421
422         /* Avoid partial use of Hyper-Threading */
423         if (gmx_cpuid_x86_smt(hwinfo->cpuid_info) == GMX_CPUID_X86_SMT_ENABLED &&
424             nthreads_new > nthreads_hw/2 && nthreads_new < nthreads_hw)
425         {
426             nthreads_new = nthreads_hw/2;
427         }
428
429         /* Avoid large prime numbers in the thread count */
430         if (nthreads_new >= 6)
431         {
432             /* Use only 6,8,10 with additional factors of 2 */
433             int fac;
434
435             fac = 2;
436             while (3*fac*2 <= nthreads_new)
437             {
438                 fac *= 2;
439             }
440
441             nthreads_new = (nthreads_new/fac)*fac;
442         }
443         else
444         {
445             /* Avoid 5 */
446             if (nthreads_new == 5)
447             {
448                 nthreads_new = 4;
449             }
450         }
451
452         nthreads_tmpi = nthreads_new;
453
454         fprintf(stderr,"\n");
455         fprintf(stderr,"NOTE: Parallelization is limited by the small number of atoms,\n");
456         fprintf(stderr,"      only starting %d thread-MPI threads.\n",nthreads_tmpi);
457         fprintf(stderr,"      You can use the -nt and/or -ntmpi option to optimize the number of threads.\n\n");
458     }
459
460     return nthreads_tmpi;
461 }
462 #endif /* GMX_THREAD_MPI */
463
464
465 /* Environment variable for setting nstlist */
466 static const char*  NSTLIST_ENVVAR          =  "GMX_NSTLIST";
467 /* Try to increase nstlist when using a GPU with nstlist less than this */
468 static const int    NSTLIST_GPU_ENOUGH      = 20;
469 /* Increase nstlist until the non-bonded cost increases more than this factor */
470 static const float  NBNXN_GPU_LIST_OK_FAC   = 1.25;
471 /* Don't increase nstlist beyond a non-bonded cost increases of this factor */
472 static const float  NBNXN_GPU_LIST_MAX_FAC  = 1.40;
473
474 /* Try to increase nstlist when running on a GPU */
475 static void increase_nstlist(FILE *fp,t_commrec *cr,
476                              t_inputrec *ir,const gmx_mtop_t *mtop,matrix box)
477 {
478     char *env;
479     int  nstlist_orig,nstlist_prev;
480     verletbuf_list_setup_t ls;
481     real rlist_inc,rlist_ok,rlist_max,rlist_new,rlist_prev;
482     int  i;
483     t_state state_tmp;
484     gmx_bool bBox,bDD,bCont;
485     const char *nstl_fmt="\nFor optimal performance with a GPU nstlist (now %d) should be larger.\nThe optimum depends on your CPU and GPU resources.\nYou might want to try several nstlist values.\n";
486     const char *vbd_err="Can not increase nstlist for GPU run because verlet-buffer-drift is not set or used";
487     const char *box_err="Can not increase nstlist for GPU run because the box is too small";
488     const char *dd_err ="Can not increase nstlist for GPU run because of domain decomposition limitations";
489     char buf[STRLEN];
490
491     /* Number of + nstlist alternative values to try when switching  */
492     const int nstl[]={ 20, 25, 40, 50 };
493 #define NNSTL  sizeof(nstl)/sizeof(nstl[0])
494
495     env = getenv(NSTLIST_ENVVAR);
496     if (env == NULL)
497     {
498         if (fp != NULL)
499         {
500             fprintf(fp,nstl_fmt,ir->nstlist);
501         }
502     }
503
504     if (ir->verletbuf_drift == 0)
505     {
506         gmx_fatal(FARGS,"You are using an old tpr file with a GPU, please generate a new tpr file with an up to date version of grompp");
507     }
508
509     if (ir->verletbuf_drift < 0)
510     {
511         if (MASTER(cr))
512         {
513             fprintf(stderr,"%s\n",vbd_err);
514         }
515         if (fp != NULL)
516         {
517             fprintf(fp,"%s\n",vbd_err);
518         }
519
520         return;
521     }
522
523     nstlist_orig = ir->nstlist;
524     if (env != NULL)
525     {
526         sprintf(buf,"Getting nstlist from environment variable GMX_NSTLIST=%s",env);
527         if (MASTER(cr))
528         {
529             fprintf(stderr,"%s\n",buf);
530         }
531         if (fp != NULL)
532         {
533             fprintf(fp,"%s\n",buf);
534         }
535         sscanf(env,"%d",&ir->nstlist);
536     }
537
538     verletbuf_get_list_setup(TRUE,&ls);
539
540     /* Allow rlist to make the list double the size of the cut-off sphere */
541     rlist_inc = nbnxn_get_rlist_effective_inc(NBNXN_GPU_CLUSTER_SIZE,mtop->natoms/det(box));
542     rlist_ok  = (max(ir->rvdw,ir->rcoulomb) + rlist_inc)*pow(NBNXN_GPU_LIST_OK_FAC,1.0/3.0) - rlist_inc;
543     rlist_max = (max(ir->rvdw,ir->rcoulomb) + rlist_inc)*pow(NBNXN_GPU_LIST_MAX_FAC,1.0/3.0) - rlist_inc;
544     if (debug)
545     {
546         fprintf(debug,"GPU nstlist tuning: rlist_inc %.3f rlist_max %.3f\n",
547                 rlist_inc,rlist_max);
548     }
549
550     i = 0;
551     nstlist_prev = nstlist_orig;
552     rlist_prev   = ir->rlist;
553     do
554     {
555         if (env == NULL)
556         {
557             ir->nstlist = nstl[i];
558         }
559
560         /* Set the pair-list buffer size in ir */
561         calc_verlet_buffer_size(mtop,det(box),ir,ir->verletbuf_drift,&ls,
562                                 NULL,&rlist_new);
563
564         /* Does rlist fit in the box? */
565         bBox = (sqr(rlist_new) < max_cutoff2(ir->ePBC,box));
566         bDD  = TRUE;
567         if (bBox && DOMAINDECOMP(cr))
568         {
569             /* Check if rlist fits in the domain decomposition */
570             if (inputrec2nboundeddim(ir) < DIM)
571             {
572                 gmx_incons("Changing nstlist with domain decomposition and unbounded dimensions is not implemented yet");
573             }
574             copy_mat(box,state_tmp.box);
575             bDD = change_dd_cutoff(cr,&state_tmp,ir,rlist_new);
576         }
577
578         bCont = FALSE;
579
580         if (env == NULL)
581         {
582             if (bBox && bDD && rlist_new <= rlist_max)
583             {
584                 /* Increase nstlist */
585                 nstlist_prev = ir->nstlist;
586                 rlist_prev   = rlist_new;
587                 bCont = (i+1 < NNSTL && rlist_new < rlist_ok);
588             }
589             else
590             {
591                 /* Stick with the previous nstlist */
592                 ir->nstlist = nstlist_prev;
593                 rlist_new   = rlist_prev;
594                 bBox = TRUE;
595                 bDD  = TRUE;
596             }
597         }
598
599         i++;
600     }
601     while (bCont);
602
603     if (!bBox || !bDD)
604     {
605         gmx_warning(!bBox ? box_err : dd_err);
606         if (fp != NULL)
607         {
608             fprintf(fp,"\n%s\n",bBox ? box_err : dd_err);
609         }
610         ir->nstlist = nstlist_orig;
611     }
612     else if (ir->nstlist != nstlist_orig || rlist_new != ir->rlist)
613     {
614         sprintf(buf,"Changing nstlist from %d to %d, rlist from %g to %g",
615                 nstlist_orig,ir->nstlist,
616                 ir->rlist,rlist_new);
617         if (MASTER(cr))
618         {
619             fprintf(stderr,"%s\n\n",buf);
620         }
621         if (fp != NULL)
622         {
623             fprintf(fp,"%s\n\n",buf);
624         }
625         ir->rlist     = rlist_new;
626         ir->rlistlong = rlist_new;
627     }
628 }
629
630 static void prepare_verlet_scheme(FILE *fplog,
631                                   gmx_hw_info_t *hwinfo,
632                                   t_commrec *cr,
633                                   gmx_hw_opt_t *hw_opt,
634                                   const char *nbpu_opt,
635                                   t_inputrec *ir,
636                                   const gmx_mtop_t *mtop,
637                                   matrix box,
638                                   gmx_bool *bUseGPU)
639 {
640     /* Here we only check for GPU usage on the MPI master process,
641      * as here we don't know how many GPUs we will use yet.
642      * We check for a GPU on all processes later.
643      */
644     *bUseGPU = hwinfo->bCanUseGPU || (getenv("GMX_EMULATE_GPU") != NULL);
645
646     if (ir->verletbuf_drift > 0)
647     {
648         /* Update the Verlet buffer size for the current run setup */
649         verletbuf_list_setup_t ls;
650         real rlist_new;
651
652         /* Here we assume CPU acceleration is on. But as currently
653          * calc_verlet_buffer_size gives the same results for 4x8 and 4x4
654          * and 4x2 gives a larger buffer than 4x4, this is ok.
655          */
656         verletbuf_get_list_setup(*bUseGPU,&ls);
657
658         calc_verlet_buffer_size(mtop,det(box),ir,
659                                 ir->verletbuf_drift,&ls,
660                                 NULL,&rlist_new);
661         if (rlist_new != ir->rlist)
662         {
663             if (fplog != NULL)
664             {
665                 fprintf(fplog,"\nChanging rlist from %g to %g for non-bonded %dx%d atom kernels\n\n",
666                         ir->rlist,rlist_new,
667                         ls.cluster_size_i,ls.cluster_size_j);
668             }
669             ir->rlist     = rlist_new;
670             ir->rlistlong = rlist_new;
671         }
672     }
673
674     /* With GPU or emulation we should check nstlist for performance */
675     if ((EI_DYNAMICS(ir->eI) &&
676          *bUseGPU &&
677          ir->nstlist < NSTLIST_GPU_ENOUGH) ||
678         getenv(NSTLIST_ENVVAR) != NULL)
679     {
680         /* Choose a better nstlist */
681         increase_nstlist(fplog,cr,ir,mtop,box);
682     }
683 }
684
685 static void convert_to_verlet_scheme(FILE *fplog,
686                                      t_inputrec *ir,
687                                      gmx_mtop_t *mtop,real box_vol)
688 {
689     char *conv_mesg="Converting input file with group cut-off scheme to the Verlet cut-off scheme";
690
691     md_print_warn(NULL,fplog,"%s\n",conv_mesg);
692
693     ir->cutoff_scheme   = ecutsVERLET;
694     ir->verletbuf_drift = 0.005;
695
696     if (ir->rcoulomb != ir->rvdw)
697     {
698         gmx_fatal(FARGS,"The VdW and Coulomb cut-offs are different, whereas the Verlet scheme only supports equal cut-offs");
699     }
700
701     if (ir->vdwtype == evdwUSER || EEL_USER(ir->coulombtype))
702     {
703         gmx_fatal(FARGS,"User non-bonded potentials are not (yet) supported with the Verlet scheme");
704     }
705     else if (EVDW_SWITCHED(ir->vdwtype) || EEL_SWITCHED(ir->coulombtype))
706     {
707         md_print_warn(NULL,fplog,"Converting switched or shifted interactions to a shifted potential (without force shift), this will lead to slightly different interaction potentials");
708
709         if (EVDW_SWITCHED(ir->vdwtype))
710         {
711             ir->vdwtype = evdwCUT;
712         }
713         if (EEL_SWITCHED(ir->coulombtype))
714         {
715             if (EEL_FULL(ir->coulombtype))
716             {
717                 /* With full electrostatic only PME can be switched */
718                 ir->coulombtype = eelPME;
719             }
720             else
721             {
722                 md_print_warn(NULL,fplog,"NOTE: Replacing %s electrostatics with reaction-field with epsilon-rf=inf\n",eel_names[ir->coulombtype]);
723                 ir->coulombtype = eelRF;
724                 ir->epsilon_rf  = 0.0;
725             }
726         }
727
728         /* We set the target energy drift to a small number.
729          * Note that this is only for testing. For production the user
730          * should think about this and set the mdp options.
731          */
732         ir->verletbuf_drift = 1e-4;
733     }
734
735     if (inputrec2nboundeddim(ir) != 3)
736     {
737         gmx_fatal(FARGS,"Can only convert old tpr files to the Verlet cut-off scheme with 3D pbc");
738     }
739
740     if (ir->efep != efepNO || ir->implicit_solvent != eisNO)
741     {
742         gmx_fatal(FARGS,"Will not convert old tpr files to the Verlet cut-off scheme with free-energy calculations or implicit solvent");
743     }
744
745     if (EI_DYNAMICS(ir->eI) && !(EI_MD(ir->eI) && ir->etc == etcNO))
746     {
747         verletbuf_list_setup_t ls;
748
749         verletbuf_get_list_setup(FALSE,&ls);
750         calc_verlet_buffer_size(mtop,box_vol,ir,ir->verletbuf_drift,&ls,
751                                 NULL,&ir->rlist);
752     }
753     else
754     {
755         ir->verletbuf_drift = -1;
756         ir->rlist           = 1.05*max(ir->rvdw,ir->rcoulomb);
757     }
758
759     gmx_mtop_remove_chargegroups(mtop);
760 }
761
762 /* Check the process affinity mask. If it is non-zero, something
763  * else has set the affinity, and mdrun should honor that and
764  * not attempt to do its own thread pinning.
765  *
766  * This function should be called twice. Once before the OpenMP
767  * library gets initialized with bAfterOpenMPInit=FALSE (which will
768  * detect affinity set by external tools like taskset), and again
769  * later, after the OpenMP initialization, with bAfterOpenMPInit=TRUE
770  * (which will detect affinity changes made by the OpenMP library).
771  *
772  * Note that this will only work on Linux, because we use a GNU
773  * feature. */
774 static void check_cpu_affinity_set(FILE *fplog, const t_commrec *cr,
775                                    gmx_hw_opt_t *hw_opt, int ncpus,
776                                    gmx_bool bAfterOpenmpInit)
777 {
778 #ifdef HAVE_SCHED_GETAFFINITY
779     cpu_set_t mask_current;
780     int       i, ret, cpu_count, cpu_set;
781     gmx_bool  bAllSet;
782
783     assert(hw_opt);
784     if (!hw_opt->bThreadPinning)
785     {
786         /* internal affinity setting is off, don't bother checking process affinity */
787         return;
788     }
789
790     CPU_ZERO(&mask_current);
791     if ((ret = sched_getaffinity(0, sizeof(cpu_set_t), &mask_current)) != 0)
792     {
793         /* failed to query affinity mask, will just return */
794         if (debug)
795         {
796             fprintf(debug, "Failed to query affinity mask (error %d)", ret);
797         }
798         return;
799     }
800
801     /* Before proceeding with the actual check, make sure that the number of
802      * detected CPUs is >= the CPUs in the current set.
803      * We need to check for CPU_COUNT as it was added only in glibc 2.6. */
804 #ifdef CPU_COUNT
805     if (ncpus < CPU_COUNT(&mask_current))
806     {
807         if (debug)
808         {
809             fprintf(debug, "%d CPUs detected, but %d was returned by CPU_COUNT",
810                     ncpus, CPU_COUNT(&mask_current));
811         }
812         return;
813     }
814 #endif /* CPU_COUNT */
815
816     bAllSet = TRUE;
817     for (i = 0; (i < ncpus && i < CPU_SETSIZE); i++)
818     {
819         bAllSet = bAllSet && (CPU_ISSET(i, &mask_current) != 0);
820     }
821
822     if (!bAllSet)
823     {
824         if (!bAfterOpenmpInit)
825         {
826             md_print_warn(cr, fplog,
827                           "%s detected a non-default process affinity, "
828                           "so it will not attempt to pin its threads", ShortProgram());
829         }
830         else
831         {
832             md_print_warn(cr, fplog,
833                           "%s detected a non-default process affinity, "
834                           "probably set by the OpenMP library, "
835                           "so it will not attempt to pin its threads", ShortProgram());
836         }
837         hw_opt->bThreadPinning = FALSE;
838
839         if (debug)
840         {
841             fprintf(debug, "Non-default affinity mask found, mdrun will not pin threads\n");
842         }
843     }
844     else
845     {
846         if (debug)
847         {
848             fprintf(debug, "Default affinity mask found\n");
849         }
850     }
851 #endif /* HAVE_SCHED_GETAFFINITY */
852 }
853
854 /* Set CPU affinity. Can be important for performance.
855    On some systems (e.g. Cray) CPU Affinity is set by default.
856    But default assigning doesn't work (well) with only some ranks
857    having threads. This causes very low performance.
858    External tools have cumbersome syntax for setting affinity
859    in the case that only some ranks have threads.
860    Thus it is important that GROMACS sets the affinity internally
861    if only PME is using threads.
862 */
863 static void set_cpu_affinity(FILE *fplog,
864                              const t_commrec *cr,
865                              gmx_hw_opt_t *hw_opt,
866                              int nthreads_pme,
867                              const gmx_hw_info_t *hwinfo,
868                              const t_inputrec *inputrec)
869 {
870 #if defined GMX_THREAD_MPI
871     /* With the number of TMPI threads equal to the number of cores
872      * we already pinned in thread-MPI, so don't pin again here.
873      */
874     if (hw_opt->nthreads_tmpi == tMPI_Thread_get_hw_number())
875     {
876         return;
877     }
878 #endif
879
880 #ifndef __APPLE__
881     /* If the tMPI thread affinity setting is not supported encourage the user
882      * to report it as it's either a bug or an exotic platform which we might
883      * want to support. */
884     if (tMPI_Thread_setaffinity_support() != TMPI_SETAFFINITY_SUPPORT_YES)
885     {
886         md_print_warn(NULL, fplog,
887                       "Can not set thread affinities on the current plarform. On NUMA systems this\n"
888                       "can cause performance degradation. If you think your platform should support\n"
889                       "setting affinities, contact the GROMACS developers.");
890         return;
891     }
892 #endif /* __APPLE__ */
893
894     if (hw_opt->bThreadPinning)
895     {
896         int nth_affinity_set, thread_id_node, thread_id,
897             nthread_local, nthread_node, nthread_hw_max, nphyscore;
898         int offset;
899         char *env;
900
901         /* threads on this MPI process or TMPI thread */
902         if (cr->duty & DUTY_PP)
903         {
904             nthread_local = gmx_omp_nthreads_get(emntNonbonded);
905         }
906         else
907         {
908             nthread_local = gmx_omp_nthreads_get(emntPME);
909         }
910
911         /* map the current process to cores */
912         thread_id_node = 0;
913         nthread_node = nthread_local;
914 #ifdef GMX_MPI
915         if (PAR(cr) || MULTISIM(cr))
916         {
917             /* We need to determine a scan of the thread counts in this
918              * compute node.
919              */
920             MPI_Comm comm_intra;
921
922             MPI_Comm_split(MPI_COMM_WORLD,gmx_hostname_num(),cr->rank_intranode,
923                            &comm_intra);
924             MPI_Scan(&nthread_local,&thread_id_node,1,MPI_INT,MPI_SUM,comm_intra);
925             /* MPI_Scan is inclusive, but here we need exclusive */
926             thread_id_node -= nthread_local;
927             /* Get the total number of threads on this physical node */
928             MPI_Allreduce(&nthread_local,&nthread_node,1,MPI_INT,MPI_SUM,comm_intra);
929             MPI_Comm_free(&comm_intra);
930         }
931 #endif
932
933         offset = 0;
934         if (hw_opt->core_pinning_offset > 0)
935         {
936             offset = hw_opt->core_pinning_offset;
937             if (SIMMASTER(cr))
938             {
939                 fprintf(stderr, "Applying core pinning offset %d\n", offset);
940             }
941             if (fplog)
942             {
943                 fprintf(fplog, "Applying core pinning offset %d\n", offset);
944             }
945         }
946
947         /* With Intel Hyper-Threading enabled, we want to pin consecutive
948          * threads to physical cores when using more threads than physical
949          * cores or when the user requests so.
950          */
951         nthread_hw_max = hwinfo->nthreads_hw_avail;
952         nphyscore = -1;
953         if (hw_opt->bPinHyperthreading ||
954             (gmx_cpuid_x86_smt(hwinfo->cpuid_info) == GMX_CPUID_X86_SMT_ENABLED &&
955              nthread_node > nthread_hw_max/2 && getenv("GMX_DISABLE_PINHT") == NULL))
956         {
957             if (gmx_cpuid_x86_smt(hwinfo->cpuid_info) != GMX_CPUID_X86_SMT_ENABLED)
958             {
959                 /* We print to stderr on all processes, as we might have
960                  * different settings on different physical nodes.
961                  */
962                 if (gmx_cpuid_vendor(hwinfo->cpuid_info) != GMX_CPUID_VENDOR_INTEL)
963                 {
964                     md_print_warn(NULL, fplog, "Pinning for Hyper-Threading layout requested, "
965                                   "but non-Intel CPU detected (vendor: %s)\n",
966                                   gmx_cpuid_vendor_string[gmx_cpuid_vendor(hwinfo->cpuid_info)]);
967                 }
968                 else
969                 {
970                     md_print_warn(NULL, fplog, "Pinning for Hyper-Threading layout requested, "
971                                   "but the CPU detected does not have Intel Hyper-Threading support "
972                                   "(or it is turned off)\n");
973                 }
974             }
975             nphyscore = nthread_hw_max/2;
976
977             if (SIMMASTER(cr))
978             {
979                 fprintf(stderr, "Pinning to Hyper-Threading cores with %d physical cores in a compute node\n",
980                         nphyscore);
981             }
982             if (fplog)
983             {
984                 fprintf(fplog, "Pinning to Hyper-Threading cores with %d physical cores in a compute node\n",
985                         nphyscore);
986             }
987         }
988
989         /* Set the per-thread affinity. In order to be able to check the success
990          * of affinity settings, we will set nth_affinity_set to 1 on threads
991          * where the affinity setting succeded and to 0 where it failed.
992          * Reducing these 0/1 values over the threads will give the total number
993          * of threads on which we succeeded.
994          */
995          nth_affinity_set = 0;
996 #pragma omp parallel firstprivate(thread_id_node) num_threads(nthread_local) \
997                      reduction(+:nth_affinity_set)
998         {
999             int      core;
1000             gmx_bool setaffinity_ret;
1001
1002             thread_id       = gmx_omp_get_thread_num();
1003             thread_id_node += thread_id;
1004             if (nphyscore <= 0)
1005             {
1006                 core = offset + thread_id_node;
1007             }
1008             else
1009             {
1010                 /* Lock pairs of threads to the same hyperthreaded core */
1011                 core = offset + thread_id_node/2 + (thread_id_node % 2)*nphyscore;
1012             }
1013
1014             setaffinity_ret = tMPI_Thread_setaffinity_single(tMPI_Thread_self(), core);
1015
1016             /* store the per-thread success-values of the setaffinity */
1017             nth_affinity_set = (setaffinity_ret == 0);
1018
1019             if (debug)
1020             {
1021                 fprintf(debug, "On rank %2d, thread %2d, core %2d the affinity setting returned %d\n",
1022                         cr->nodeid, gmx_omp_get_thread_num(), core, setaffinity_ret);
1023             }
1024         }
1025
1026         if (nth_affinity_set > nthread_local)
1027         {
1028             char msg[STRLEN];
1029
1030             sprintf(msg, "Looks like we have set affinity for more threads than "
1031                     "we have (%d > %d)!\n", nth_affinity_set, nthread_local);
1032             gmx_incons(msg);
1033         }
1034         else
1035         {
1036             /* check & warn if some threads failed to set their affinities */
1037             if (nth_affinity_set != nthread_local)
1038             {
1039                 char sbuf1[STRLEN], sbuf2[STRLEN];
1040
1041                 /* sbuf1 contains rank info, while sbuf2 OpenMP thread info */
1042                 sbuf1[0] = sbuf2[0] = '\0';
1043 #ifdef GMX_MPI
1044 #ifdef GMX_THREAD_MPI
1045                 sprintf(sbuf1, "In thread-MPI thread #%d: ", cr->nodeid);
1046 #else /* GMX_LIB_MPI */
1047                 sprintf(sbuf1, "In MPI process #%d: ", cr->nodeid);
1048 #endif
1049 #endif /* GMX_MPI */
1050
1051                 if (nthread_local > 1)
1052                 {
1053                     sprintf(sbuf2, "of %d/%d thread%s ",
1054                             nthread_local - nth_affinity_set, nthread_local,
1055                             (nthread_local - nth_affinity_set) > 1 ? "s" : "");
1056                 }
1057
1058                 md_print_warn(NULL, fplog,
1059                               "NOTE: %sAffinity setting %sfailed.\n"
1060                               "      This can cause performance degradation!",
1061                               sbuf1, sbuf2);
1062             }
1063         }
1064     }
1065 }
1066
1067
1068 static void check_and_update_hw_opt(gmx_hw_opt_t *hw_opt,
1069                                     int cutoff_scheme)
1070 {
1071     gmx_omp_nthreads_read_env(&hw_opt->nthreads_omp);
1072
1073 #ifndef GMX_THREAD_MPI
1074     if (hw_opt->nthreads_tot > 0)
1075     {
1076         gmx_fatal(FARGS,"Setting the total number of threads is only supported with thread-MPI and Gromacs was compiled without thread-MPI");
1077     }
1078     if (hw_opt->nthreads_tmpi > 0)
1079     {
1080         gmx_fatal(FARGS,"Setting the number of thread-MPI threads is only supported with thread-MPI and Gromacs was compiled without thread-MPI");
1081     }
1082 #endif
1083
1084     if (hw_opt->nthreads_tot > 0 && hw_opt->nthreads_omp_pme <= 0)
1085     {
1086         /* We have the same number of OpenMP threads for PP and PME processes,
1087          * thus we can perform several consistency checks.
1088          */
1089         if (hw_opt->nthreads_tmpi > 0 &&
1090             hw_opt->nthreads_omp > 0 &&
1091             hw_opt->nthreads_tot != hw_opt->nthreads_tmpi*hw_opt->nthreads_omp)
1092         {
1093             gmx_fatal(FARGS,"The total number of threads requested (%d) does not match the thread-MPI threads (%d) times the OpenMP threads (%d) requested",
1094                       hw_opt->nthreads_tot,hw_opt->nthreads_tmpi,hw_opt->nthreads_omp);
1095         }
1096
1097         if (hw_opt->nthreads_tmpi > 0 &&
1098             hw_opt->nthreads_tot % hw_opt->nthreads_tmpi != 0)
1099         {
1100             gmx_fatal(FARGS,"The total number of threads requested (%d) is not divisible by the number of thread-MPI threads requested (%d)",
1101                       hw_opt->nthreads_tot,hw_opt->nthreads_tmpi);
1102         }
1103
1104         if (hw_opt->nthreads_omp > 0 &&
1105             hw_opt->nthreads_tot % hw_opt->nthreads_omp != 0)
1106         {
1107             gmx_fatal(FARGS,"The total number of threads requested (%d) is not divisible by the number of OpenMP threads requested (%d)",
1108                       hw_opt->nthreads_tot,hw_opt->nthreads_omp);
1109         }
1110
1111         if (hw_opt->nthreads_tmpi > 0 &&
1112             hw_opt->nthreads_omp <= 0)
1113         {
1114             hw_opt->nthreads_omp = hw_opt->nthreads_tot/hw_opt->nthreads_tmpi;
1115         }
1116     }
1117
1118 #ifndef GMX_OPENMP
1119     if (hw_opt->nthreads_omp > 1)
1120     {
1121         gmx_fatal(FARGS,"OpenMP threads are requested, but Gromacs was compiled without OpenMP support");
1122     }
1123 #endif
1124
1125     if (cutoff_scheme == ecutsGROUP)
1126     {
1127         /* We only have OpenMP support for PME only nodes */
1128         if (hw_opt->nthreads_omp > 1)
1129         {
1130             gmx_fatal(FARGS,"OpenMP threads have been requested with cut-off scheme %s, but these are only supported with cut-off scheme %s",
1131                       ecutscheme_names[cutoff_scheme],
1132                       ecutscheme_names[ecutsVERLET]);
1133         }
1134         hw_opt->nthreads_omp = 1;
1135     }
1136
1137     if (hw_opt->nthreads_omp_pme > 0 && hw_opt->nthreads_omp <= 0)
1138     {
1139         gmx_fatal(FARGS,"You need to specify -ntomp in addition to -ntomp_pme");
1140     }
1141
1142     if (hw_opt->nthreads_tot == 1)
1143     {
1144         hw_opt->nthreads_tmpi = 1;
1145
1146         if (hw_opt->nthreads_omp > 1)
1147         {
1148             gmx_fatal(FARGS,"You requested %d OpenMP threads with %d total threads",
1149                       hw_opt->nthreads_tmpi,hw_opt->nthreads_tot);
1150         }
1151         hw_opt->nthreads_omp = 1;
1152     }
1153
1154     if (hw_opt->nthreads_omp_pme <= 0 && hw_opt->nthreads_omp > 0)
1155     {
1156         hw_opt->nthreads_omp_pme = hw_opt->nthreads_omp;
1157     }
1158
1159     if (debug)
1160     {
1161         fprintf(debug,"hw_opt: nt %d ntmpi %d ntomp %d ntomp_pme %d gpu_id '%s'\n",
1162                 hw_opt->nthreads_tot,
1163                 hw_opt->nthreads_tmpi,
1164                 hw_opt->nthreads_omp,
1165                 hw_opt->nthreads_omp_pme,
1166                 hw_opt->gpu_id!=NULL ? hw_opt->gpu_id : "");
1167                 
1168     }
1169 }
1170
1171
1172 /* Override the value in inputrec with value passed on the command line (if any) */
1173 static void override_nsteps_cmdline(FILE *fplog,
1174                                     int nsteps_cmdline,
1175                                     t_inputrec *ir,
1176                                     const t_commrec *cr)
1177 {
1178     assert(ir);
1179     assert(cr);
1180
1181     /* override with anything else than the default -2 */
1182     if (nsteps_cmdline > -2)
1183     {
1184         char stmp[STRLEN];
1185
1186         ir->nsteps = nsteps_cmdline;
1187         if (EI_DYNAMICS(ir->eI))
1188         {
1189             sprintf(stmp, "Overriding nsteps with value passed on the command line: %d steps, %.3f ps",
1190                     nsteps_cmdline, nsteps_cmdline*ir->delta_t);
1191         }
1192         else
1193         {
1194             sprintf(stmp, "Overriding nsteps with value passed on the command line: %d steps",
1195                     nsteps_cmdline);
1196         }
1197
1198         md_print_warn(cr, fplog, "%s\n", stmp);
1199     }
1200 }
1201
1202 /* Data structure set by SIMMASTER which needs to be passed to all nodes
1203  * before the other nodes have read the tpx file and called gmx_detect_hardware.
1204  */
1205 typedef struct {
1206     int cutoff_scheme; /* The cutoff scheme from inputrec_t */
1207     gmx_bool bUseGPU;       /* Use GPU or GPU emulation          */
1208 } master_inf_t;
1209
1210 int mdrunner(gmx_hw_opt_t *hw_opt,
1211              FILE *fplog,t_commrec *cr,int nfile,
1212              const t_filenm fnm[], const output_env_t oenv, gmx_bool bVerbose,
1213              gmx_bool bCompact, int nstglobalcomm,
1214              ivec ddxyz,int dd_node_order,real rdd,real rconstr,
1215              const char *dddlb_opt,real dlb_scale,
1216              const char *ddcsx,const char *ddcsy,const char *ddcsz,
1217              const char *nbpu_opt,
1218              int nsteps_cmdline, int nstepout,int resetstep,
1219              int nmultisim,int repl_ex_nst,int repl_ex_nex,
1220              int repl_ex_seed, real pforce,real cpt_period,real max_hours,
1221              const char *deviceOptions, unsigned long Flags)
1222 {
1223     gmx_bool   bForceUseGPU,bTryUseGPU;
1224     double     nodetime=0,realtime;
1225     t_inputrec *inputrec;
1226     t_state    *state=NULL;
1227     matrix     box;
1228     gmx_ddbox_t ddbox={0};
1229     int        npme_major,npme_minor;
1230     real       tmpr1,tmpr2;
1231     t_nrnb     *nrnb;
1232     gmx_mtop_t *mtop=NULL;
1233     t_mdatoms  *mdatoms=NULL;
1234     t_forcerec *fr=NULL;
1235     t_fcdata   *fcd=NULL;
1236     real       ewaldcoeff=0;
1237     gmx_pme_t  *pmedata=NULL;
1238     gmx_vsite_t *vsite=NULL;
1239     gmx_constr_t constr;
1240     int        i,m,nChargePerturbed=-1,status,nalloc;
1241     char       *gro;
1242     gmx_wallcycle_t wcycle;
1243     gmx_bool       bReadRNG,bReadEkin;
1244     int        list;
1245     gmx_runtime_t runtime;
1246     int        rc;
1247     gmx_large_int_t reset_counters;
1248     gmx_edsam_t ed=NULL;
1249     t_commrec   *cr_old=cr; 
1250     int         nthreads_pme=1;
1251     int         nthreads_pp=1;
1252     gmx_membed_t membed=NULL;
1253     gmx_hw_info_t *hwinfo=NULL;
1254     master_inf_t minf={-1,FALSE};
1255
1256     /* CAUTION: threads may be started later on in this function, so
1257        cr doesn't reflect the final parallel state right now */
1258     snew(inputrec,1);
1259     snew(mtop,1);
1260     
1261     if (Flags & MD_APPENDFILES) 
1262     {
1263         fplog = NULL;
1264     }
1265
1266     bForceUseGPU = (strncmp(nbpu_opt, "gpu", 3) == 0);
1267     bTryUseGPU   = (strncmp(nbpu_opt, "auto", 4) == 0) || bForceUseGPU;
1268
1269     snew(state,1);
1270     if (SIMMASTER(cr)) 
1271     {
1272         /* Read (nearly) all data required for the simulation */
1273         read_tpx_state(ftp2fn(efTPX,nfile,fnm),inputrec,state,NULL,mtop);
1274
1275         if (inputrec->cutoff_scheme != ecutsVERLET &&
1276             ((Flags & MD_TESTVERLET) || getenv("GMX_VERLET_SCHEME") != NULL))
1277         {
1278             convert_to_verlet_scheme(fplog,inputrec,mtop,det(state->box));
1279         }
1280
1281         /* Detect hardware, gather information. With tMPI only thread 0 does it
1282          * and after threads are started broadcasts hwinfo around. */
1283         snew(hwinfo, 1);
1284         gmx_detect_hardware(fplog, hwinfo, cr,
1285                             bForceUseGPU, bTryUseGPU, hw_opt->gpu_id);
1286
1287         minf.cutoff_scheme = inputrec->cutoff_scheme;
1288         minf.bUseGPU       = FALSE;
1289
1290         if (inputrec->cutoff_scheme == ecutsVERLET)
1291         {
1292             prepare_verlet_scheme(fplog,hwinfo,cr,hw_opt,nbpu_opt,
1293                                   inputrec,mtop,state->box,
1294                                   &minf.bUseGPU);
1295         }
1296         else if (hwinfo->bCanUseGPU)
1297         {
1298             md_print_warn(cr,fplog,
1299                           "NOTE: GPU(s) found, but the current simulation can not use GPUs\n"
1300                           "      To use a GPU, set the mdp option: cutoff-scheme = Verlet\n"
1301                           "      (for quick performance testing you can use the -testverlet option)\n");
1302
1303             if (bForceUseGPU)
1304             {
1305                 gmx_fatal(FARGS,"GPU requested, but can't be used without cutoff-scheme=Verlet");
1306             }
1307         }
1308     }
1309 #ifndef GMX_THREAD_MPI
1310     if (PAR(cr))
1311     {
1312         gmx_bcast_sim(sizeof(minf),&minf,cr);
1313     }
1314 #endif
1315     if (minf.bUseGPU && cr->npmenodes == -1)
1316     {
1317         /* Don't automatically use PME-only nodes with GPUs */
1318         cr->npmenodes = 0;
1319     }
1320
1321     /* Check for externally set OpenMP affinity and turn off internal
1322      * pinning if any is found. We need to do this check early to tell
1323      * thread-MPI whether it should do pinning when spawning threads.
1324      */
1325     gmx_omp_check_thread_affinity(fplog, cr, hw_opt);
1326
1327 #ifdef GMX_THREAD_MPI
1328     /* With thread-MPI inputrec is only set here on the master thread */
1329     if (SIMMASTER(cr))
1330 #endif
1331     {
1332         check_and_update_hw_opt(hw_opt,minf.cutoff_scheme);
1333
1334 #ifdef GMX_THREAD_MPI
1335         /* Early check for externally set process affinity. Can't do over all
1336          * MPI processes because hwinfo is not available everywhere, but with
1337          * thread-MPI it's needed as pinning might get turned off which needs
1338          * to be known before starting thread-MPI. */
1339         check_cpu_affinity_set(fplog,
1340                                NULL,
1341                                hw_opt, hwinfo->nthreads_hw_avail, FALSE);
1342 #endif
1343
1344 #ifdef GMX_THREAD_MPI
1345         if (cr->npmenodes > 0 && hw_opt->nthreads_tmpi <= 0)
1346         {
1347             gmx_fatal(FARGS,"You need to explicitly specify the number of MPI threads (-ntmpi) when using separate PME nodes");
1348         }
1349 #endif
1350
1351         if (hw_opt->nthreads_omp_pme != hw_opt->nthreads_omp &&
1352             cr->npmenodes <= 0)
1353         {
1354             gmx_fatal(FARGS,"You need to explicitly specify the number of PME nodes (-npme) when using different number of OpenMP threads for PP and PME nodes");
1355         }
1356     }
1357
1358 #ifdef GMX_THREAD_MPI
1359     if (SIMMASTER(cr))
1360     {
1361         /* NOW the threads will be started: */
1362         hw_opt->nthreads_tmpi = get_nthreads_mpi(hwinfo,
1363                                                  hw_opt,
1364                                                  inputrec, mtop,
1365                                                  cr, fplog);
1366         if (hw_opt->nthreads_tot > 0 && hw_opt->nthreads_omp <= 0)
1367         {
1368             hw_opt->nthreads_omp = hw_opt->nthreads_tot/hw_opt->nthreads_tmpi;
1369         }
1370
1371         if (hw_opt->nthreads_tmpi > 1)
1372         {
1373             /* now start the threads. */
1374             cr=mdrunner_start_threads(hw_opt, fplog, cr_old, nfile, fnm, 
1375                                       oenv, bVerbose, bCompact, nstglobalcomm, 
1376                                       ddxyz, dd_node_order, rdd, rconstr, 
1377                                       dddlb_opt, dlb_scale, ddcsx, ddcsy, ddcsz,
1378                                       nbpu_opt,
1379                                       nsteps_cmdline, nstepout, resetstep, nmultisim, 
1380                                       repl_ex_nst, repl_ex_nex, repl_ex_seed, pforce,
1381                                       cpt_period, max_hours, deviceOptions, 
1382                                       Flags);
1383             /* the main thread continues here with a new cr. We don't deallocate
1384                the old cr because other threads may still be reading it. */
1385             if (cr == NULL)
1386             {
1387                 gmx_comm("Failed to spawn threads");
1388             }
1389         }
1390     }
1391 #endif
1392     /* END OF CAUTION: cr is now reliable */
1393
1394     /* g_membed initialisation *
1395      * Because we change the mtop, init_membed is called before the init_parallel *
1396      * (in case we ever want to make it run in parallel) */
1397     if (opt2bSet("-membed",nfile,fnm))
1398     {
1399         if (MASTER(cr))
1400         {
1401             fprintf(stderr,"Initializing membed");
1402         }
1403         membed = init_membed(fplog,nfile,fnm,mtop,inputrec,state,cr,&cpt_period);
1404     }
1405
1406     if (PAR(cr))
1407     {
1408         /* now broadcast everything to the non-master nodes/threads: */
1409         init_parallel(fplog, cr, inputrec, mtop);
1410
1411         /* This check needs to happen after get_nthreads_mpi() */
1412         if (inputrec->cutoff_scheme == ecutsVERLET && (Flags & MD_PARTDEC))
1413         {
1414             gmx_fatal_collective(FARGS,cr,NULL,
1415                                  "The Verlet cut-off scheme is not supported with particle decomposition.\n"
1416                                  "You can achieve the same effect as particle decomposition by running in parallel using only OpenMP threads.");
1417         }
1418     }
1419     if (fplog != NULL)
1420     {
1421         pr_inputrec(fplog,0,"Input Parameters",inputrec,FALSE);
1422     }
1423
1424 #if defined GMX_THREAD_MPI
1425     /* With tMPI we detected on thread 0 and we'll just pass the hwinfo pointer
1426      * to the other threads  -- slightly uncool, but works fine, just need to
1427      * make sure that the data doesn't get freed twice. */
1428     if (cr->nnodes > 1)
1429     {
1430         if (!SIMMASTER(cr))
1431         {
1432             snew(hwinfo, 1);
1433         }
1434         gmx_bcast(sizeof(&hwinfo), &hwinfo, cr);
1435     }
1436 #else
1437     if (PAR(cr) && !SIMMASTER(cr))
1438     {
1439         /* now we have inputrec on all nodes, can run the detection */
1440         /* TODO: perhaps it's better to propagate within a node instead? */
1441         snew(hwinfo, 1);
1442         gmx_detect_hardware(fplog, hwinfo, cr,
1443                                  bForceUseGPU, bTryUseGPU, hw_opt->gpu_id);
1444     }
1445
1446     /* Now do the affinity check with MPI/no-MPI (done earlier with thread-MPI). */
1447     check_cpu_affinity_set(fplog, cr,
1448                            hw_opt, hwinfo->nthreads_hw_avail, FALSE);
1449 #endif
1450
1451     /* now make sure the state is initialized and propagated */
1452     set_state_entries(state,inputrec,cr->nnodes);
1453
1454     /* remove when vv and rerun works correctly! */
1455     if (PAR(cr) && EI_VV(inputrec->eI) && ((Flags & MD_RERUN) || (Flags & MD_RERUN_VSITE)))
1456     {
1457         gmx_fatal(FARGS,
1458                   "Currently can't do velocity verlet with rerun in parallel.");
1459     }
1460
1461     /* A parallel command line option consistency check that we can
1462        only do after any threads have started. */
1463     if (!PAR(cr) &&
1464         (ddxyz[XX] > 1 || ddxyz[YY] > 1 || ddxyz[ZZ] > 1 || cr->npmenodes > 0))
1465     {
1466         gmx_fatal(FARGS,
1467                   "The -dd or -npme option request a parallel simulation, "
1468 #ifndef GMX_MPI
1469                   "but %s was compiled without threads or MPI enabled"
1470 #else
1471 #ifdef GMX_THREAD_MPI
1472                   "but the number of threads (option -nt) is 1"
1473 #else
1474                   "but %s was not started through mpirun/mpiexec or only one process was requested through mpirun/mpiexec"
1475 #endif
1476 #endif
1477                   , ShortProgram()
1478             );
1479     }
1480
1481     if ((Flags & MD_RERUN) &&
1482         (EI_ENERGY_MINIMIZATION(inputrec->eI) || eiNM == inputrec->eI))
1483     {
1484         gmx_fatal(FARGS, "The .mdp file specified an energy mininization or normal mode algorithm, and these are not compatible with mdrun -rerun");
1485     }
1486
1487     if (can_use_allvsall(inputrec,mtop,TRUE,cr,fplog) && PAR(cr))
1488     {
1489         /* All-vs-all loops do not work with domain decomposition */
1490         Flags |= MD_PARTDEC;
1491     }
1492
1493     if (!EEL_PME(inputrec->coulombtype) || (Flags & MD_PARTDEC))
1494     {
1495         if (cr->npmenodes > 0)
1496         {
1497             if (!EEL_PME(inputrec->coulombtype))
1498             {
1499                 gmx_fatal_collective(FARGS,cr,NULL,
1500                                      "PME nodes are requested, but the system does not use PME electrostatics");
1501             }
1502             if (Flags & MD_PARTDEC)
1503             {
1504                 gmx_fatal_collective(FARGS,cr,NULL,
1505                                      "PME nodes are requested, but particle decomposition does not support separate PME nodes");
1506             }
1507         }
1508
1509         cr->npmenodes = 0;
1510     }
1511
1512 #ifdef GMX_FAHCORE
1513     fcRegisterSteps(inputrec->nsteps,inputrec->init_step);
1514 #endif
1515
1516     /* NMR restraints must be initialized before load_checkpoint,
1517      * since with time averaging the history is added to t_state.
1518      * For proper consistency check we therefore need to extend
1519      * t_state here.
1520      * So the PME-only nodes (if present) will also initialize
1521      * the distance restraints.
1522      */
1523     snew(fcd,1);
1524
1525     /* This needs to be called before read_checkpoint to extend the state */
1526     init_disres(fplog,mtop,inputrec,cr,Flags & MD_PARTDEC,fcd,state);
1527
1528     if (gmx_mtop_ftype_count(mtop,F_ORIRES) > 0)
1529     {
1530         if (PAR(cr) && !(Flags & MD_PARTDEC))
1531         {
1532             gmx_fatal(FARGS,"Orientation restraints do not work (yet) with domain decomposition, use particle decomposition (mdrun option -pd)");
1533         }
1534         /* Orientation restraints */
1535         if (MASTER(cr))
1536         {
1537             init_orires(fplog,mtop,state->x,inputrec,cr->ms,&(fcd->orires),
1538                         state);
1539         }
1540     }
1541
1542     if (DEFORM(*inputrec))
1543     {
1544         /* Store the deform reference box before reading the checkpoint */
1545         if (SIMMASTER(cr))
1546         {
1547             copy_mat(state->box,box);
1548         }
1549         if (PAR(cr))
1550         {
1551             gmx_bcast(sizeof(box),box,cr);
1552         }
1553         /* Because we do not have the update struct available yet
1554          * in which the reference values should be stored,
1555          * we store them temporarily in static variables.
1556          * This should be thread safe, since they are only written once
1557          * and with identical values.
1558          */
1559 #ifdef GMX_THREAD_MPI
1560         tMPI_Thread_mutex_lock(&deform_init_box_mutex);
1561 #endif
1562         deform_init_init_step_tpx = inputrec->init_step;
1563         copy_mat(box,deform_init_box_tpx);
1564 #ifdef GMX_THREAD_MPI
1565         tMPI_Thread_mutex_unlock(&deform_init_box_mutex);
1566 #endif
1567     }
1568
1569     if (opt2bSet("-cpi",nfile,fnm)) 
1570     {
1571         /* Check if checkpoint file exists before doing continuation.
1572          * This way we can use identical input options for the first and subsequent runs...
1573          */
1574         if( gmx_fexist_master(opt2fn_master("-cpi",nfile,fnm,cr),cr) )
1575         {
1576             load_checkpoint(opt2fn_master("-cpi",nfile,fnm,cr),&fplog,
1577                             cr,Flags & MD_PARTDEC,ddxyz,
1578                             inputrec,state,&bReadRNG,&bReadEkin,
1579                             (Flags & MD_APPENDFILES),
1580                             (Flags & MD_APPENDFILESSET));
1581             
1582             if (bReadRNG)
1583             {
1584                 Flags |= MD_READ_RNG;
1585             }
1586             if (bReadEkin)
1587             {
1588                 Flags |= MD_READ_EKIN;
1589             }
1590         }
1591     }
1592
1593     if (((MASTER(cr) || (Flags & MD_SEPPOT)) && (Flags & MD_APPENDFILES))
1594 #ifdef GMX_THREAD_MPI
1595         /* With thread MPI only the master node/thread exists in mdrun.c,
1596          * therefore non-master nodes need to open the "seppot" log file here.
1597          */
1598         || (!MASTER(cr) && (Flags & MD_SEPPOT))
1599 #endif
1600         )
1601     {
1602         gmx_log_open(ftp2fn(efLOG,nfile,fnm),cr,!(Flags & MD_SEPPOT),
1603                              Flags,&fplog);
1604     }
1605
1606     /* override nsteps with value from cmdline */
1607     override_nsteps_cmdline(fplog, nsteps_cmdline, inputrec, cr);
1608
1609     if (SIMMASTER(cr)) 
1610     {
1611         copy_mat(state->box,box);
1612     }
1613
1614     if (PAR(cr)) 
1615     {
1616         gmx_bcast(sizeof(box),box,cr);
1617     }
1618
1619     /* Essential dynamics */
1620     if (opt2bSet("-ei",nfile,fnm))
1621     {
1622         /* Open input and output files, allocate space for ED data structure */
1623         ed = ed_open(nfile,fnm,Flags,cr);
1624     }
1625
1626     if (PAR(cr) && !((Flags & MD_PARTDEC) ||
1627                      EI_TPI(inputrec->eI) ||
1628                      inputrec->eI == eiNM))
1629     {
1630         cr->dd = init_domain_decomposition(fplog,cr,Flags,ddxyz,rdd,rconstr,
1631                                            dddlb_opt,dlb_scale,
1632                                            ddcsx,ddcsy,ddcsz,
1633                                            mtop,inputrec,
1634                                            box,state->x,
1635                                            &ddbox,&npme_major,&npme_minor);
1636
1637         make_dd_communicators(fplog,cr,dd_node_order);
1638
1639         /* Set overallocation to avoid frequent reallocation of arrays */
1640         set_over_alloc_dd(TRUE);
1641     }
1642     else
1643     {
1644         /* PME, if used, is done on all nodes with 1D decomposition */
1645         cr->npmenodes = 0;
1646         cr->duty = (DUTY_PP | DUTY_PME);
1647         npme_major = 1;
1648         npme_minor = 1;
1649         if (!EI_TPI(inputrec->eI))
1650         {
1651             npme_major = cr->nnodes;
1652         }
1653         
1654         if (inputrec->ePBC == epbcSCREW)
1655         {
1656             gmx_fatal(FARGS,
1657                       "pbc=%s is only implemented with domain decomposition",
1658                       epbc_names[inputrec->ePBC]);
1659         }
1660     }
1661
1662     if (PAR(cr))
1663     {
1664         /* After possible communicator splitting in make_dd_communicators.
1665          * we can set up the intra/inter node communication.
1666          */
1667         gmx_setup_nodecomm(fplog,cr);
1668     }
1669
1670     /* Initialize per-physical-node MPI process/thread ID and counters. */
1671     gmx_init_intranode_counters(cr);
1672
1673 #ifdef GMX_MPI
1674     md_print_info(cr,fplog,"Using %d MPI %s\n",
1675                   cr->nnodes,
1676 #ifdef GMX_THREAD_MPI
1677                   cr->nnodes==1 ? "thread" : "threads"
1678 #else
1679                   cr->nnodes==1 ? "process" : "processes"
1680 #endif
1681                   );
1682     fflush(stderr);
1683 #endif
1684
1685     gmx_omp_nthreads_init(fplog, cr,
1686                           hwinfo->nthreads_hw_avail,
1687                           hw_opt->nthreads_omp,
1688                           hw_opt->nthreads_omp_pme,
1689                           (cr->duty & DUTY_PP) == 0,
1690                           inputrec->cutoff_scheme == ecutsVERLET);
1691
1692     gmx_check_hw_runconf_consistency(fplog, hwinfo, cr, hw_opt->nthreads_tmpi, minf.bUseGPU);
1693
1694     /* getting number of PP/PME threads
1695        PME: env variable should be read only on one node to make sure it is 
1696        identical everywhere;
1697      */
1698     /* TODO nthreads_pp is only used for pinning threads.
1699      * This is a temporary solution until we have a hw topology library.
1700      */
1701     nthreads_pp  = gmx_omp_nthreads_get(emntNonbonded);
1702     nthreads_pme = gmx_omp_nthreads_get(emntPME);
1703
1704     wcycle = wallcycle_init(fplog,resetstep,cr,nthreads_pp,nthreads_pme);
1705
1706     if (PAR(cr))
1707     {
1708         /* Master synchronizes its value of reset_counters with all nodes 
1709          * including PME only nodes */
1710         reset_counters = wcycle_get_reset_counters(wcycle);
1711         gmx_bcast_sim(sizeof(reset_counters),&reset_counters,cr);
1712         wcycle_set_reset_counters(wcycle, reset_counters);
1713     }
1714
1715     snew(nrnb,1);
1716     if (cr->duty & DUTY_PP)
1717     {
1718         /* For domain decomposition we allocate dynamically
1719          * in dd_partition_system.
1720          */
1721         if (DOMAINDECOMP(cr))
1722         {
1723             bcast_state_setup(cr,state);
1724         }
1725         else
1726         {
1727             if (PAR(cr))
1728             {
1729                 bcast_state(cr,state,TRUE);
1730             }
1731         }
1732
1733         /* Initiate forcerecord */
1734         fr = mk_forcerec();
1735         fr->hwinfo = hwinfo;
1736         init_forcerec(fplog,oenv,fr,fcd,inputrec,mtop,cr,box,FALSE,
1737                       opt2fn("-table",nfile,fnm),
1738                       opt2fn("-tabletf",nfile,fnm),
1739                       opt2fn("-tablep",nfile,fnm),
1740                       opt2fn("-tableb",nfile,fnm),
1741                       nbpu_opt,
1742                       FALSE,pforce);
1743
1744         /* version for PCA_NOT_READ_NODE (see md.c) */
1745         /*init_forcerec(fplog,fr,fcd,inputrec,mtop,cr,box,FALSE,
1746           "nofile","nofile","nofile","nofile",FALSE,pforce);
1747           */        
1748         fr->bSepDVDL = ((Flags & MD_SEPPOT) == MD_SEPPOT);
1749
1750         /* Initialize QM-MM */
1751         if(fr->bQMMM)
1752         {
1753             init_QMMMrec(cr,box,mtop,inputrec,fr);
1754         }
1755
1756         /* Initialize the mdatoms structure.
1757          * mdatoms is not filled with atom data,
1758          * as this can not be done now with domain decomposition.
1759          */
1760         mdatoms = init_mdatoms(fplog,mtop,inputrec->efep!=efepNO);
1761
1762         /* Initialize the virtual site communication */
1763         vsite = init_vsite(mtop,cr,FALSE);
1764
1765         calc_shifts(box,fr->shift_vec);
1766
1767         /* With periodic molecules the charge groups should be whole at start up
1768          * and the virtual sites should not be far from their proper positions.
1769          */
1770         if (!inputrec->bContinuation && MASTER(cr) &&
1771             !(inputrec->ePBC != epbcNONE && inputrec->bPeriodicMols))
1772         {
1773             /* Make molecules whole at start of run */
1774             if (fr->ePBC != epbcNONE)
1775             {
1776                 do_pbc_first_mtop(fplog,inputrec->ePBC,box,mtop,state->x);
1777             }
1778             if (vsite)
1779             {
1780                 /* Correct initial vsite positions are required
1781                  * for the initial distribution in the domain decomposition
1782                  * and for the initial shell prediction.
1783                  */
1784                 construct_vsites_mtop(fplog,vsite,mtop,state->x);
1785             }
1786         }
1787
1788         if (EEL_PME(fr->eeltype))
1789         {
1790             ewaldcoeff = fr->ewaldcoeff;
1791             pmedata = &fr->pmedata;
1792         }
1793         else
1794         {
1795             pmedata = NULL;
1796         }
1797     }
1798     else
1799     {
1800         /* This is a PME only node */
1801
1802         /* We don't need the state */
1803         done_state(state);
1804
1805         ewaldcoeff = calc_ewaldcoeff(inputrec->rcoulomb, inputrec->ewald_rtol);
1806         snew(pmedata,1);
1807     }
1808
1809     /* Before setting affinity, check whether the affinity has changed
1810      * - which indicates that probably the OpenMP library has changed it since
1811      * we first checked). */
1812     check_cpu_affinity_set(fplog, cr, hw_opt, hwinfo->nthreads_hw_avail, TRUE);
1813
1814     /* Set the CPU affinity */
1815     set_cpu_affinity(fplog,cr,hw_opt,nthreads_pme,hwinfo,inputrec);
1816
1817     /* Initiate PME if necessary,
1818      * either on all nodes or on dedicated PME nodes only. */
1819     if (EEL_PME(inputrec->coulombtype))
1820     {
1821         if (mdatoms)
1822         {
1823             nChargePerturbed = mdatoms->nChargePerturbed;
1824         }
1825         if (cr->npmenodes > 0)
1826         {
1827             /* The PME only nodes need to know nChargePerturbed */
1828             gmx_bcast_sim(sizeof(nChargePerturbed),&nChargePerturbed,cr);
1829         }
1830
1831         if (cr->duty & DUTY_PME)
1832         {
1833             status = gmx_pme_init(pmedata,cr,npme_major,npme_minor,inputrec,
1834                                   mtop ? mtop->natoms : 0,nChargePerturbed,
1835                                   (Flags & MD_REPRODUCIBLE),nthreads_pme);
1836             if (status != 0) 
1837             {
1838                 gmx_fatal(FARGS,"Error %d initializing PME",status);
1839             }
1840         }
1841     }
1842
1843
1844     if (integrator[inputrec->eI].func == do_md
1845         ||
1846         integrator[inputrec->eI].func == do_md_openmm
1847         )
1848     {
1849         /* Turn on signal handling on all nodes */
1850         /*
1851          * (A user signal from the PME nodes (if any)
1852          * is communicated to the PP nodes.
1853          */
1854         signal_handler_install();
1855     }
1856
1857     if (cr->duty & DUTY_PP)
1858     {
1859         if (inputrec->ePull != epullNO)
1860         {
1861             /* Initialize pull code */
1862             init_pull(fplog,inputrec,nfile,fnm,mtop,cr,oenv, inputrec->fepvals->init_lambda,
1863                       EI_DYNAMICS(inputrec->eI) && MASTER(cr),Flags);
1864         }
1865         
1866         if (inputrec->bRot)
1867         {
1868            /* Initialize enforced rotation code */
1869            init_rot(fplog,inputrec,nfile,fnm,cr,state->x,box,mtop,oenv,
1870                     bVerbose,Flags);
1871         }
1872
1873         constr = init_constraints(fplog,mtop,inputrec,ed,state,cr);
1874
1875         if (DOMAINDECOMP(cr))
1876         {
1877             dd_init_bondeds(fplog,cr->dd,mtop,vsite,constr,inputrec,
1878                             Flags & MD_DDBONDCHECK,fr->cginfo_mb);
1879
1880             set_dd_parameters(fplog,cr->dd,dlb_scale,inputrec,fr,&ddbox);
1881
1882             setup_dd_grid(fplog,cr->dd);
1883         }
1884
1885         /* Now do whatever the user wants us to do (how flexible...) */
1886         integrator[inputrec->eI].func(fplog,cr,nfile,fnm,
1887                                       oenv,bVerbose,bCompact,
1888                                       nstglobalcomm,
1889                                       vsite,constr,
1890                                       nstepout,inputrec,mtop,
1891                                       fcd,state,
1892                                       mdatoms,nrnb,wcycle,ed,fr,
1893                                       repl_ex_nst,repl_ex_nex,repl_ex_seed,
1894                                       membed,
1895                                       cpt_period,max_hours,
1896                                       deviceOptions,
1897                                       Flags,
1898                                       &runtime);
1899
1900         if (inputrec->ePull != epullNO)
1901         {
1902             finish_pull(fplog,inputrec->pull);
1903         }
1904         
1905         if (inputrec->bRot)
1906         {
1907             finish_rot(inputrec->rot);
1908         }
1909
1910     } 
1911     else 
1912     {
1913         /* do PME only */
1914         gmx_pmeonly(*pmedata,cr,nrnb,wcycle,ewaldcoeff,FALSE,inputrec);
1915     }
1916
1917     if (EI_DYNAMICS(inputrec->eI) || EI_TPI(inputrec->eI))
1918     {
1919         /* Some timing stats */  
1920         if (SIMMASTER(cr))
1921         {
1922             if (runtime.proc == 0)
1923             {
1924                 runtime.proc = runtime.real;
1925             }
1926         }
1927         else
1928         {
1929             runtime.real = 0;
1930         }
1931     }
1932
1933     wallcycle_stop(wcycle,ewcRUN);
1934
1935     /* Finish up, write some stuff
1936      * if rerunMD, don't write last frame again 
1937      */
1938     finish_run(fplog,cr,ftp2fn(efSTO,nfile,fnm),
1939                inputrec,nrnb,wcycle,&runtime,
1940                fr != NULL && fr->nbv != NULL && fr->nbv->bUseGPU ?
1941                  nbnxn_cuda_get_timings(fr->nbv->cu_nbv) : NULL,
1942                nthreads_pp, 
1943                EI_DYNAMICS(inputrec->eI) && !MULTISIM(cr));
1944
1945     if ((cr->duty & DUTY_PP) && fr->nbv != NULL && fr->nbv->bUseGPU)
1946     {
1947         char gpu_err_str[STRLEN];
1948
1949         /* free GPU memory and uninitialize GPU (by destroying the context) */
1950         nbnxn_cuda_free(fplog, fr->nbv->cu_nbv);
1951
1952         if (!free_gpu(gpu_err_str))
1953         {
1954             gmx_warning("On node %d failed to free GPU #%d: %s",
1955                         cr->nodeid, get_current_gpu_device_id(), gpu_err_str);
1956         }
1957     }
1958
1959     if (opt2bSet("-membed",nfile,fnm))
1960     {
1961         sfree(membed);
1962     }
1963
1964 #ifdef GMX_THREAD_MPI
1965     if (PAR(cr) && SIMMASTER(cr))
1966 #endif
1967     {
1968         gmx_hardware_info_free(hwinfo);
1969     }
1970
1971     /* Does what it says */  
1972     print_date_and_time(fplog,cr->nodeid,"Finished mdrun",&runtime);
1973
1974     /* Close logfile already here if we were appending to it */
1975     if (MASTER(cr) && (Flags & MD_APPENDFILES))
1976     {
1977         gmx_log_close(fplog);
1978     }   
1979
1980     rc=(int)gmx_get_stop_condition();
1981
1982 #ifdef GMX_THREAD_MPI
1983     /* we need to join all threads. The sub-threads join when they
1984        exit this function, but the master thread needs to be told to 
1985        wait for that. */
1986     if (PAR(cr) && MASTER(cr))
1987     {
1988         tMPI_Finalize();
1989     }
1990 #endif
1991
1992     return rc;
1993 }