Implemented nbnxn LJ switch functions
[alexxy/gromacs.git] / src / gromacs / gmxlib / nrnb.c
index b65d1ed7eaa5850e92363e969fbc18a6d063da0f..2f818ff2525cdc7611fcd98d8e7f74187340f0f5 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
  * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014, by the GROMACS development team, led by
  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
  * and including many others, as listed in the AUTHORS file in the
  * top-level source directory and at http://www.gromacs.org.
@@ -99,20 +99,25 @@ static const t_nrnb_data nbdata[eNRNB] = {
      * - GPU always does exclusions, which requires 2-4 flops, but as invsqrt
      *   is always counted as 6 flops, this roughly compensates.
      */
-    { "NxN RF Elec. + VdW [F]",         38 }, /* nbnxn kernel LJ+RF, no ener */
-    { "NxN RF Elec. + VdW [V&F]",       54 },
-    { "NxN QSTab Elec. + VdW [F]",      41 }, /* nbnxn kernel LJ+tab, no en */
-    { "NxN QSTab Elec. + VdW [V&F]",    59 },
-    { "NxN Ewald Elec. + VdW [F]",      66 }, /* nbnxn kernel LJ+Ewald, no en */
-    { "NxN Ewald Elec. + VdW [V&F]",   107 },
-    { "NxN VdW [F]",                    33 }, /* nbnxn kernel LJ, no ener */
-    { "NxN VdW [V&F]",                  43 },
+    { "NxN RF Elec. + LJ [F]",          38 }, /* nbnxn kernel LJ+RF, no ener */
+    { "NxN RF Elec. + LJ [V&F]",        54 },
+    { "NxN QSTab Elec. + LJ [F]",       41 }, /* nbnxn kernel LJ+tab, no en */
+    { "NxN QSTab Elec. + LJ [V&F]",     59 },
+    { "NxN Ewald Elec. + LJ [F]",       66 }, /* nbnxn kernel LJ+Ewald, no en */
+    { "NxN Ewald Elec. + LJ [V&F]",    107 },
+    { "NxN LJ [F]",                     33 }, /* nbnxn kernel LJ, no ener */
+    { "NxN LJ [V&F]",                   43 },
     { "NxN RF Electrostatics [F]",      31 }, /* nbnxn kernel RF, no ener */
     { "NxN RF Electrostatics [V&F]",    36 },
     { "NxN QSTab Elec. [F]",            34 }, /* nbnxn kernel tab, no ener */
     { "NxN QSTab Elec. [V&F]",          41 },
     { "NxN Ewald Elec. [F]",            61 }, /* nbnxn kernel Ewald, no ener */
     { "NxN Ewald Elec. [V&F]",          84 },
+    /* The switch function flops should be added to the LJ kernels above */
+    { "NxN LJ add F-switch [F]",        12 }, /* extra cost for LJ F-switch */
+    { "NxN LJ add F-switch [V&F]",      22 },
+    { "NxN LJ add P-switch [F]",        27 }, /* extra cost for LJ P-switch */
+    { "NxN LJ add P-switch [V&F]",      20 },
     { "1,4 nonbonded interactions",     90 },
     { "Born radii (Still)",             47 },
     { "Born radii (HCT/OBC)",          183 },
@@ -305,9 +310,21 @@ void _inc_nrnb(t_nrnb *nrnb, int enr, int inc, char gmx_unused *file, int gmx_un
 #endif
 }
 
+/* Returns in enr is the index of a full nbnxn VdW kernel */
+static gmx_bool nrnb_is_nbnxn_vdw_kernel(int enr)
+{
+    return (enr >= eNR_NBNXN_LJ_RF && enr <= eNR_NBNXN_LJ_E);
+}
+
+/* Returns in enr is the index of an nbnxn kernel addition (switch function) */
+static gmx_bool nrnb_is_nbnxn_kernel_addition(int enr)
+{
+    return (enr >= eNR_NBNXN_LJ_FSW && enr <= eNR_NBNXN_LJ_PSW_E);
+}
+
 void print_flop(FILE *out, t_nrnb *nrnb, double *nbfs, double *mflop)
 {
-    int           i;
+    int           i, j;
     double        mni, frac, tfrac, tflop;
     const char   *myline = "-----------------------------------------------------------------------------";
 
@@ -367,13 +384,38 @@ void print_flop(FILE *out, t_nrnb *nrnb, double *nbfs, double *mflop)
     for (i = 0; (i < eNRNB); i++)
     {
         mni     = 1e-6*nrnb->n[i];
-        *mflop += mni*nbdata[i].flop;
-        frac    = 100.0*mni*nbdata[i].flop/tflop;
-        tfrac  += frac;
-        if (out && mni != 0)
+        /* Skip empty entries and nbnxn additional flops,
+         * which have been added to the kernel entry.
+         */
+        if (mni > 0 && !nrnb_is_nbnxn_kernel_addition(i))
         {
-            fprintf(out, " %-32s %16.6f %15.3f  %6.1f\n",
-                    nbdata[i].name, mni, mni*nbdata[i].flop, frac);
+            int flop;
+
+            flop    = nbdata[i].flop;
+            if (nrnb_is_nbnxn_vdw_kernel(i))
+            {
+                /* Possibly add the cost of a switch function */
+                for (j = eNR_NBNXN_LJ_FSW; j <= eNR_NBNXN_LJ_PSW; j += 2)
+                {
+                    int e_kernel_add;
+
+                    /* Select the force or energy flop count */
+                    e_kernel_add = j + ((i - eNR_NBNXN_LJ_RF) % 2);
+
+                    if (nrnb->n[e_kernel_add] > 0)
+                    {
+                        flop += nbdata[e_kernel_add].flop;
+                    }
+                }
+            }
+            *mflop += mni*flop;
+            frac    = 100.0*mni*flop/tflop;
+            tfrac  += frac;
+            if (out != NULL)
+            {
+                fprintf(out, " %-32s %16.6f %15.3f  %6.1f\n",
+                        nbdata[i].name, mni, mni*flop, frac);
+            }
         }
     }
     if (out)