10 #include "gmx_simd_macros.h"
11 #include "gmx_simd_vec.h"
13 #define GMX_SIMD_J_UNROLL_SIZE {3}
15 #include "../nbnxn_kernel_common.h"
16 #include "gmx_omp_nthreads.h"
17 #include "types/force_flags.h"
19 /*! \brief Kinds of electrostatic treatments in SIMD Verlet kernels
22 coultRF, coultTAB, coultTAB_TWIN, coultEWALD, coultEWALD_TWIN, coultNR
25 /* Declare and define the kernel function pointer lookup tables. */
26 static p_nbk_func_ener p_nbk_ener[coultNR][ljcrNR] =
28 static p_nbk_func_ener p_nbk_energrp[coultNR][ljcrNR] =
30 static p_nbk_func_noener p_nbk_noener[coultNR][ljcrNR] =
34 reduce_group_energies(int ng, int ng_2log,
35 const real *VSvdw, const real *VSc,
38 const int unrollj = GMX_SIMD_WIDTH_HERE/GMX_SIMD_J_UNROLL_SIZE;
39 const int unrollj_half = unrollj/2;
40 int ng_p2, i, j, j0, j1, c, s;
44 /* The size of the x86 SIMD energy group buffer array is:
45 * ng*ng*ng_p2*unrollj_half*simd_width
47 for (i = 0; i < ng; i++)
49 for (j = 0; j < ng; j++)
55 for (j1 = 0; j1 < ng; j1++)
57 for (j0 = 0; j0 < ng; j0++)
59 c = ((i*ng + j1)*ng_p2 + j0)*unrollj_half*unrollj;
60 for (s = 0; s < unrollj_half; s++)
62 Vvdw[i*ng+j0] += VSvdw[c+0];
63 Vvdw[i*ng+j1] += VSvdw[c+1];
64 Vc [i*ng+j0] += VSc [c+0];
65 Vc [i*ng+j1] += VSc [c+1];
75 #include "gmx_fatal.h"
80 {5}(nbnxn_pairlist_set_t *nbl_list,
81 {6}const nbnxn_atomdata_t *nbat,
82 {6}const interaction_const_t *ic,
93 nbnxn_pairlist_t **nbl;
97 nnbl = nbl_list->nnbl;
100 if (EEL_RF(ic->eeltype) || ic->eeltype == eelCUT)
106 if (ewald_excl == ewaldexclTable)
108 if (ic->rcoulomb == ic->rvdw)
114 coult = coultTAB_TWIN;
119 if (ic->rcoulomb == ic->rvdw)
125 coult = coultEWALD_TWIN;
130 #pragma omp parallel for schedule(static) num_threads(gmx_omp_nthreads_get(emntNonbonded))
131 for (nb = 0; nb < nnbl; nb++)
133 nbnxn_atomdata_output_t *out;
136 out = &nbat->out[nb];
138 if (clearF == enbvClearFYes)
140 clear_f(nbat, nb, out->f);
143 if ((force_flags & GMX_FORCE_VIRIAL) && nnbl == 1)
149 fshift_p = out->fshift;
151 if (clearF == enbvClearFYes)
153 clear_fshift(fshift_p);
157 /* With Ewald type electrostatics we the forces for excluded atom pairs
158 * should not contribute to the virial sum. The exclusion forces
159 * are not calculate in the energy kernels, but are in _noener.
161 if (!((force_flags & GMX_FORCE_ENERGY) ||
162 (EEL_FULL(ic->eeltype) && (force_flags & GMX_FORCE_VIRIAL))))
164 /* Don't calculate energies */
165 p_nbk_noener[coult][nbat->comb_rule](nbl[nb], nbat,
171 else if (out->nV == 1 || !(force_flags & GMX_FORCE_ENERGY))
173 /* No energy groups */
177 p_nbk_ener[coult][nbat->comb_rule](nbl[nb], nbat,
187 /* Calculate energy group contributions */
190 for (i = 0; i < out->nVS; i++)
194 for (i = 0; i < out->nVS; i++)
199 p_nbk_energrp[coult][nbat->comb_rule](nbl[nb], nbat,
207 reduce_group_energies(nbat->nenergrp, nbat->neg_2log,
208 out->VSvdw, out->VSc,
213 if (force_flags & GMX_FORCE_ENERGY)
215 reduce_energies_over_lists(nbat, nnbl, Vvdw, Vc);
220 gmx_incons("{5} called when such kernels "
221 " are not enabled.");
224 #undef GMX_SIMD_J_UNROLL_SIZE