Merge release-4-6 into master
[alexxy/gromacs.git] / src / gromacs / mdlib / forcerec.c
index 8ed1a583a0c5ebc7c6febd83816b4d57c36691eb..9eb75af90711e5a2704f98e89b042b125be7d18e 100644 (file)
@@ -1524,61 +1524,18 @@ static void pick_nbnxn_kernel(FILE *fp,
                               const t_commrec *cr,
                               const gmx_hw_info_t *hwinfo,
                               gmx_bool use_cpu_acceleration,
-                              gmx_bool *bUseGPU,
+                              gmx_bool bUseGPU,
+                              gmx_bool bEmulateGPU,
                               const t_inputrec *ir,
                               int *kernel_type,
                               int *ewald_excl,
                               gmx_bool bDoNonbonded)
 {
-    gmx_bool bEmulateGPU, bGPU, bEmulateGPUEnvVarSet;
-    char gpu_err_str[STRLEN];
-
     assert(kernel_type);
 
     *kernel_type = nbnxnkNotSet;
     *ewald_excl  = ewaldexclTable;
 
-    bEmulateGPUEnvVarSet = (getenv("GMX_EMULATE_GPU") != NULL);
-
-    /* if bUseGPU == NULL we don't want a GPU (e.g. hybrid mode kernel selection) */
-    bGPU = ((bUseGPU != NULL) && hwinfo->bCanUseGPU);
-
-    /* Run GPU emulation mode if GMX_EMULATE_GPU is defined. We will
-     * automatically switch to emulation if non-bonded calculations are
-     * turned off via GMX_NO_NONBONDED - this is the simple and elegant
-     * way to turn off GPU initialization, data movement, and cleanup. */
-    bEmulateGPU = (bEmulateGPUEnvVarSet || (!bDoNonbonded && bGPU));
-
-    /* Enable GPU mode when GPUs are available or GPU emulation is requested.
-     * The latter is useful to assess the performance one can expect by adding
-     * GPU(s) to the machine. The conditional below allows this even if mdrun
-     * is compiled without GPU acceleration support.
-     * Note that such a GPU acceleration performance assessment should be
-     * carried out by setting the GMX_EMULATE_GPU and GMX_NO_NONBONDED env. vars
-     * (and freezing the system as otherwise it would explode). */
-    if (bGPU || bEmulateGPUEnvVarSet)
-    {
-        if (bEmulateGPU)
-        {
-            bGPU = FALSE;
-        }
-        else
-        {
-            /* Each PP node will use the intra-node id-th device from the
-             * list of detected/selected GPUs. */
-            if (!init_gpu(cr->rank_pp_intranode, gpu_err_str, &hwinfo->gpu_info))
-            {
-                /* At this point the init should never fail as we made sure that
-                 * we have all the GPUs we need. If it still does, we'll bail. */
-                gmx_fatal(FARGS, "On node %d failed to initialize GPU #%d: %s",
-                          cr->nodeid,
-                          get_gpu_device_id(&hwinfo->gpu_info, cr->rank_pp_intranode),
-                          gpu_err_str);
-            }
-        }
-        *bUseGPU = bGPU;
-    }
-
     if (bEmulateGPU)
     {
         *kernel_type = nbnxnk8x8x8_PlainC;
@@ -1588,7 +1545,7 @@ static void pick_nbnxn_kernel(FILE *fp,
             md_print_warn(cr, fp, "Emulating a GPU run on the CPU (slow)");
         }
     }
-    else if (bGPU)
+    else if (bUseGPU)
     {
         *kernel_type = nbnxnk8x8x8_CUDA;
     }
@@ -1615,6 +1572,55 @@ static void pick_nbnxn_kernel(FILE *fp,
     }
 }
 
+static void pick_nbnxn_resources(FILE *fp,
+                                 const t_commrec *cr,
+                                 const gmx_hw_info_t *hwinfo,
+                                 gmx_bool bDoNonbonded,
+                                 gmx_bool *bUseGPU,
+                                 gmx_bool *bEmulateGPU)
+{
+    gmx_bool bEmulateGPUEnvVarSet;
+    char gpu_err_str[STRLEN];
+
+    *bUseGPU = FALSE;
+
+    bEmulateGPUEnvVarSet = (getenv("GMX_EMULATE_GPU") != NULL);
+
+    /* Run GPU emulation mode if GMX_EMULATE_GPU is defined. Because
+     * GPUs (currently) only handle non-bonded calculations, we will
+     * automatically switch to emulation if non-bonded calculations are
+     * turned off via GMX_NO_NONBONDED - this is the simple and elegant
+     * way to turn off GPU initialization, data movement, and cleanup.
+     *
+     * GPU emulation can be useful to assess the performance one can expect by
+     * adding GPU(s) to the machine. The conditional below allows this even
+     * if mdrun is compiled without GPU acceleration support.
+     * Note that you should freezing the system as otherwise it will explode.
+     */
+    *bEmulateGPU = (bEmulateGPUEnvVarSet ||
+                    (!bDoNonbonded && hwinfo->bCanUseGPU));
+
+    /* Enable GPU mode when GPUs are available or no GPU emulation is requested.
+     */
+    if (hwinfo->bCanUseGPU && !(*bEmulateGPU))
+    {
+        /* Each PP node will use the intra-node id-th device from the
+         * list of detected/selected GPUs. */
+        if (!init_gpu(cr->rank_pp_intranode, gpu_err_str, &hwinfo->gpu_info))
+        {
+            /* At this point the init should never fail as we made sure that
+             * we have all the GPUs we need. If it still does, we'll bail. */
+            gmx_fatal(FARGS, "On node %d failed to initialize GPU #%d: %s",
+                      cr->nodeid,
+                      get_gpu_device_id(&hwinfo->gpu_info, cr->rank_pp_intranode),
+                      gpu_err_str);
+        }
+
+        /* Here we actually turn on hardware GPU acceleration */
+        *bUseGPU = TRUE;
+    }
+}
+
 gmx_bool uses_simple_tables(int cutoff_scheme,
                             nonbonded_verlet_t *nbv,
                             int group)
@@ -1797,13 +1803,18 @@ static void init_nb_verlet(FILE *fp,
     nonbonded_verlet_t *nbv;
     int  i;
     char *env;
-    gmx_bool bHybridGPURun = FALSE;
+    gmx_bool bEmulateGPU, bHybridGPURun = FALSE;
 
     nbnxn_alloc_t *nb_alloc;
     nbnxn_free_t  *nb_free;
 
     snew(nbv, 1);
 
+    pick_nbnxn_resources(fp, cr, fr->hwinfo,
+                         fr->bNonbonded,
+                         &nbv->bUseGPU,
+                         &bEmulateGPU);
+
     nbv->nbs = NULL;
 
     nbv->ngrp = (DOMAINDECOMP(cr) ? 2 : 1);
@@ -1816,7 +1827,7 @@ static void init_nb_verlet(FILE *fp,
         if (i == 0) /* local */
         {
             pick_nbnxn_kernel(fp, cr, fr->hwinfo, fr->use_cpu_acceleration,
-                              &nbv->bUseGPU,
+                              nbv->bUseGPU, bEmulateGPU,
                               ir,
                               &nbv->grp[i].kernel_type,
                               &nbv->grp[i].ewald_excl,
@@ -1828,7 +1839,7 @@ static void init_nb_verlet(FILE *fp,
             {
                 /* Use GPU for local, select a CPU kernel for non-local */
                 pick_nbnxn_kernel(fp, cr, fr->hwinfo, fr->use_cpu_acceleration,
-                                  NULL,
+                                  FALSE, FALSE,
                                   ir,
                                   &nbv->grp[i].kernel_type,
                                   &nbv->grp[i].ewald_excl,
@@ -2148,6 +2159,7 @@ void init_forcerec(FILE *fp,
             fr->bMolPBC = dd_bonded_molpbc(cr->dd,fr->ePBC);
         }
     }
+    fr->bGB = (ir->implicit_solvent == eisGBSA);
 
     fr->rc_scaling = ir->refcoord_scaling;
     copy_rvec(ir->posres_com,fr->posres_com);
@@ -2164,7 +2176,7 @@ void init_forcerec(FILE *fp,
     switch(fr->eeltype)
     {
         case eelCUT:
-            fr->nbkernel_elec_interaction = GMX_NBKERNEL_ELEC_COULOMB;
+            fr->nbkernel_elec_interaction = (fr->bGB) ? GMX_NBKERNEL_ELEC_GENERALIZEDBORN : GMX_NBKERNEL_ELEC_COULOMB;
             break;
 
         case eelRF:
@@ -2416,7 +2428,6 @@ void init_forcerec(FILE *fp,
         set_bham_b_max(fp,fr,mtop);
     }
 
-    fr->bGB = (ir->implicit_solvent == eisGBSA);
        fr->gb_epsilon_solvent = ir->gb_epsilon_solvent;
 
     /* Copy the GBSA data (radius, volume and surftens for each