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 gmx_unused *nbl_list,
81 {6}const nbnxn_atomdata_t gmx_unused *nbat,
82 {6}const interaction_const_t gmx_unused *ic,
83 {6}int gmx_unused ewald_excl,
84 {6}rvec gmx_unused *shift_vec,
85 {6}int gmx_unused force_flags,
86 {6}int gmx_unused clearF,
87 {6}real gmx_unused *fshift,
88 {6}real gmx_unused *Vc,
89 {6}real gmx_unused *Vvdw)
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 if (!(force_flags & GMX_FORCE_ENERGY))
159 /* Don't calculate energies */
160 p_nbk_noener[coult][nbat->comb_rule](nbl[nb], nbat,
166 else if (out->nV == 1)
168 /* No energy groups */
172 p_nbk_ener[coult][nbat->comb_rule](nbl[nb], nbat,
182 /* Calculate energy group contributions */
185 for (i = 0; i < out->nVS; i++)
189 for (i = 0; i < out->nVS; i++)
194 p_nbk_energrp[coult][nbat->comb_rule](nbl[nb], nbat,
202 reduce_group_energies(nbat->nenergrp, nbat->neg_2log,
203 out->VSvdw, out->VSc,
208 if (force_flags & GMX_FORCE_ENERGY)
210 reduce_energies_over_lists(nbat, nnbl, Vvdw, Vc);
215 gmx_incons("{5} called when such kernels "
216 " are not enabled.");
219 #undef GMX_SIMD_J_UNROLL_SIZE