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