Fixed nbnxn FE list allocation issue
authorBerk Hess <hess@kth.se>
Wed, 16 Apr 2014 08:11:50 +0000 (10:11 +0200)
committerGerrit Code Review <gerrit@gerrit.gromacs.org>
Wed, 23 Apr 2014 21:21:45 +0000 (23:21 +0200)
With free-energy calculations, the nbnxn search code could write
beyond the list bound, which could cause a segv.
Fixes #1474

Change-Id: I4c202fc14b04980f05ad1b3ea001732fdfaa9f00

src/gromacs/mdlib/nbnxn_search.c

index a2fe52a902444d28aed1f1bfde137d8bde2082a6..c06a5d10f1701d3d9981617c23622f525a44a1d2 100644 (file)
@@ -3310,8 +3310,11 @@ static void make_fep_list(const nbnxn_search_t    nbs,
     cj_ind_start = nbl_ci->cj_ind_start;
     cj_ind_end   = nbl_ci->cj_ind_end;
 
-    /* In worst case we have alternating energy groups and create npair lists */
-    nri_max = nbl->na_ci*(cj_ind_end - cj_ind_start);
+    /* In worst case we have alternating energy groups
+     * and create #atom-pair lists, which means we need the size
+     * of a cluster pair (na_ci*na_cj) times the number of cj's.
+     */
+    nri_max = nbl->na_ci*nbl->na_cj*(cj_ind_end - cj_ind_start);
     if (nlist->nri + nri_max > nlist->maxnri)
     {
         nlist->maxnri = over_alloc_large(nlist->nri + nri_max);
@@ -3447,6 +3450,7 @@ static void make_fep_list(const nbnxn_search_t    nbs,
 
             if (nlist->nrj > nlist->jindex[nri])
             {
+                /* Actually add this new, non-empty, list */
                 nlist->nri++;
                 nlist->jindex[nlist->nri] = nlist->nrj;
             }
@@ -3512,8 +3516,14 @@ static void make_fep_list_supersub(const nbnxn_search_t    nbs,
     cj4_ind_start = nbl_sci->cj4_ind_start;
     cj4_ind_end   = nbl_sci->cj4_ind_end;
 
-    /* No energy groups (yet), so we split lists in max_nrj_fep pairs */
-    nri_max = nbl->na_sc*(1 + ((cj4_ind_end - cj4_ind_start)*NBNXN_GPU_JGROUP_SIZE)/max_nrj_fep);
+    /* Here we process one super-cell, max #atoms na_sc, versus a list
+     * cj4 entries, each with max NBNXN_GPU_JGROUP_SIZE cj's, each
+     * of size na_cj atoms.
+     * On the GPU we don't support energy groups (yet).
+     * So for each of the na_sc i-atoms, we need max one FEP list
+     * for each max_nrj_fep j-atoms.
+     */
+    nri_max = nbl->na_sc*nbl->na_cj*(1 + ((cj4_ind_end - cj4_ind_start)*NBNXN_GPU_JGROUP_SIZE)/max_nrj_fep);
     if (nlist->nri + nri_max > nlist->maxnri)
     {
         nlist->maxnri = over_alloc_large(nlist->nri + nri_max);
@@ -3636,6 +3646,7 @@ static void make_fep_list_supersub(const nbnxn_search_t    nbs,
 
                 if (nlist->nrj > nlist->jindex[nri])
                 {
+                    /* Actually add this new, non-empty, list */
                     nlist->nri++;
                     nlist->jindex[nlist->nri] = nlist->nrj;
                 }