Merge release-4-6 into master
[alexxy/gromacs.git] / src / gromacs / gmxlib / nonbonded / nb_kernel_avx_256_single / nb_kernel_ElecCSTab_VdwCSTab_GeomW3P1_avx_256_single.c
1 /*
2  * Note: this file was generated by the Gromacs avx_256_single kernel generator.
3  *
4  *                This source code is part of
5  *
6  *                 G   R   O   M   A   C   S
7  *
8  * Copyright (c) 2001-2012, The GROMACS Development Team
9  *
10  * Gromacs is a library for molecular simulation and trajectory analysis,
11  * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
12  * a full list of developers and information, check out http://www.gromacs.org
13  *
14  * This program is free software; you can redistribute it and/or modify it under
15  * the terms of the GNU Lesser General Public License as published by the Free
16  * Software Foundation; either version 2 of the License, or (at your option) any
17  * later version.
18  *
19  * To help fund GROMACS development, we humbly ask that you cite
20  * the papers people have written on it - you can find them on the website.
21  */
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <math.h>
27
28 #include "../nb_kernel.h"
29 #include "types/simple.h"
30 #include "vec.h"
31 #include "nrnb.h"
32
33 #include "gmx_math_x86_avx_256_single.h"
34 #include "kernelutil_x86_avx_256_single.h"
35
36 /*
37  * Gromacs nonbonded kernel:   nb_kernel_ElecCSTab_VdwCSTab_GeomW3P1_VF_avx_256_single
38  * Electrostatics interaction: CubicSplineTable
39  * VdW interaction:            CubicSplineTable
40  * Geometry:                   Water3-Particle
41  * Calculate force/pot:        PotentialAndForce
42  */
43 void
44 nb_kernel_ElecCSTab_VdwCSTab_GeomW3P1_VF_avx_256_single
45                     (t_nblist * gmx_restrict                nlist,
46                      rvec * gmx_restrict                    xx,
47                      rvec * gmx_restrict                    ff,
48                      t_forcerec * gmx_restrict              fr,
49                      t_mdatoms * gmx_restrict               mdatoms,
50                      nb_kernel_data_t * gmx_restrict        kernel_data,
51                      t_nrnb * gmx_restrict                  nrnb)
52 {
53     /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or 
54      * just 0 for non-waters.
55      * Suffixes A,B,C,D,E,F,G,H refer to j loop unrolling done with AVX, e.g. for the eight different
56      * jnr indices corresponding to data put in the four positions in the SIMD register.
57      */
58     int              i_shift_offset,i_coord_offset,outeriter,inneriter;
59     int              j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
60     int              jnrA,jnrB,jnrC,jnrD;
61     int              jnrE,jnrF,jnrG,jnrH;
62     int              jnrlistA,jnrlistB,jnrlistC,jnrlistD;
63     int              jnrlistE,jnrlistF,jnrlistG,jnrlistH;
64     int              j_coord_offsetA,j_coord_offsetB,j_coord_offsetC,j_coord_offsetD;
65     int              j_coord_offsetE,j_coord_offsetF,j_coord_offsetG,j_coord_offsetH;
66     int              *iinr,*jindex,*jjnr,*shiftidx,*gid;
67     real             rcutoff_scalar;
68     real             *shiftvec,*fshift,*x,*f;
69     real             *fjptrA,*fjptrB,*fjptrC,*fjptrD,*fjptrE,*fjptrF,*fjptrG,*fjptrH;
70     real             scratch[4*DIM];
71     __m256           tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
72     real *           vdwioffsetptr0;
73     __m256           ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
74     real *           vdwioffsetptr1;
75     __m256           ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
76     real *           vdwioffsetptr2;
77     __m256           ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
78     int              vdwjidx0A,vdwjidx0B,vdwjidx0C,vdwjidx0D,vdwjidx0E,vdwjidx0F,vdwjidx0G,vdwjidx0H;
79     __m256           jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
80     __m256           dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
81     __m256           dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
82     __m256           dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
83     __m256           velec,felec,velecsum,facel,crf,krf,krf2;
84     real             *charge;
85     int              nvdwtype;
86     __m256           rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
87     int              *vdwtype;
88     real             *vdwparam;
89     __m256           one_sixth   = _mm256_set1_ps(1.0/6.0);
90     __m256           one_twelfth = _mm256_set1_ps(1.0/12.0);
91     __m256i          vfitab;
92     __m128i          vfitab_lo,vfitab_hi;
93     __m128i          ifour       = _mm_set1_epi32(4);
94     __m256           rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
95     real             *vftab;
96     __m256           dummy_mask,cutoff_mask;
97     __m256           signbit = _mm256_castsi256_ps( _mm256_set1_epi32(0x80000000) );
98     __m256           one     = _mm256_set1_ps(1.0);
99     __m256           two     = _mm256_set1_ps(2.0);
100     x                = xx[0];
101     f                = ff[0];
102
103     nri              = nlist->nri;
104     iinr             = nlist->iinr;
105     jindex           = nlist->jindex;
106     jjnr             = nlist->jjnr;
107     shiftidx         = nlist->shift;
108     gid              = nlist->gid;
109     shiftvec         = fr->shift_vec[0];
110     fshift           = fr->fshift[0];
111     facel            = _mm256_set1_ps(fr->epsfac);
112     charge           = mdatoms->chargeA;
113     nvdwtype         = fr->ntype;
114     vdwparam         = fr->nbfp;
115     vdwtype          = mdatoms->typeA;
116
117     vftab            = kernel_data->table_elec_vdw->data;
118     vftabscale       = _mm256_set1_ps(kernel_data->table_elec_vdw->scale);
119
120     /* Setup water-specific parameters */
121     inr              = nlist->iinr[0];
122     iq0              = _mm256_mul_ps(facel,_mm256_set1_ps(charge[inr+0]));
123     iq1              = _mm256_mul_ps(facel,_mm256_set1_ps(charge[inr+1]));
124     iq2              = _mm256_mul_ps(facel,_mm256_set1_ps(charge[inr+2]));
125     vdwioffsetptr0   = vdwparam+2*nvdwtype*vdwtype[inr+0];
126
127     /* Avoid stupid compiler warnings */
128     jnrA = jnrB = jnrC = jnrD = jnrE = jnrF = jnrG = jnrH = 0;
129     j_coord_offsetA = 0;
130     j_coord_offsetB = 0;
131     j_coord_offsetC = 0;
132     j_coord_offsetD = 0;
133     j_coord_offsetE = 0;
134     j_coord_offsetF = 0;
135     j_coord_offsetG = 0;
136     j_coord_offsetH = 0;
137
138     outeriter        = 0;
139     inneriter        = 0;
140
141     for(iidx=0;iidx<4*DIM;iidx++)
142     {
143         scratch[iidx] = 0.0;
144     }
145
146     /* Start outer loop over neighborlists */
147     for(iidx=0; iidx<nri; iidx++)
148     {
149         /* Load shift vector for this list */
150         i_shift_offset   = DIM*shiftidx[iidx];
151
152         /* Load limits for loop over neighbors */
153         j_index_start    = jindex[iidx];
154         j_index_end      = jindex[iidx+1];
155
156         /* Get outer coordinate index */
157         inr              = iinr[iidx];
158         i_coord_offset   = DIM*inr;
159
160         /* Load i particle coords and add shift vector */
161         gmx_mm256_load_shift_and_3rvec_broadcast_ps(shiftvec+i_shift_offset,x+i_coord_offset,
162                                                     &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
163
164         fix0             = _mm256_setzero_ps();
165         fiy0             = _mm256_setzero_ps();
166         fiz0             = _mm256_setzero_ps();
167         fix1             = _mm256_setzero_ps();
168         fiy1             = _mm256_setzero_ps();
169         fiz1             = _mm256_setzero_ps();
170         fix2             = _mm256_setzero_ps();
171         fiy2             = _mm256_setzero_ps();
172         fiz2             = _mm256_setzero_ps();
173
174         /* Reset potential sums */
175         velecsum         = _mm256_setzero_ps();
176         vvdwsum          = _mm256_setzero_ps();
177
178         /* Start inner kernel loop */
179         for(jidx=j_index_start; jidx<j_index_end && jjnr[jidx+7]>=0; jidx+=8)
180         {
181
182             /* Get j neighbor index, and coordinate index */
183             jnrA             = jjnr[jidx];
184             jnrB             = jjnr[jidx+1];
185             jnrC             = jjnr[jidx+2];
186             jnrD             = jjnr[jidx+3];
187             jnrE             = jjnr[jidx+4];
188             jnrF             = jjnr[jidx+5];
189             jnrG             = jjnr[jidx+6];
190             jnrH             = jjnr[jidx+7];
191             j_coord_offsetA  = DIM*jnrA;
192             j_coord_offsetB  = DIM*jnrB;
193             j_coord_offsetC  = DIM*jnrC;
194             j_coord_offsetD  = DIM*jnrD;
195             j_coord_offsetE  = DIM*jnrE;
196             j_coord_offsetF  = DIM*jnrF;
197             j_coord_offsetG  = DIM*jnrG;
198             j_coord_offsetH  = DIM*jnrH;
199
200             /* load j atom coordinates */
201             gmx_mm256_load_1rvec_8ptr_swizzle_ps(x+j_coord_offsetA,x+j_coord_offsetB,
202                                                  x+j_coord_offsetC,x+j_coord_offsetD,
203                                                  x+j_coord_offsetE,x+j_coord_offsetF,
204                                                  x+j_coord_offsetG,x+j_coord_offsetH,
205                                                  &jx0,&jy0,&jz0);
206
207             /* Calculate displacement vector */
208             dx00             = _mm256_sub_ps(ix0,jx0);
209             dy00             = _mm256_sub_ps(iy0,jy0);
210             dz00             = _mm256_sub_ps(iz0,jz0);
211             dx10             = _mm256_sub_ps(ix1,jx0);
212             dy10             = _mm256_sub_ps(iy1,jy0);
213             dz10             = _mm256_sub_ps(iz1,jz0);
214             dx20             = _mm256_sub_ps(ix2,jx0);
215             dy20             = _mm256_sub_ps(iy2,jy0);
216             dz20             = _mm256_sub_ps(iz2,jz0);
217
218             /* Calculate squared distance and things based on it */
219             rsq00            = gmx_mm256_calc_rsq_ps(dx00,dy00,dz00);
220             rsq10            = gmx_mm256_calc_rsq_ps(dx10,dy10,dz10);
221             rsq20            = gmx_mm256_calc_rsq_ps(dx20,dy20,dz20);
222
223             rinv00           = gmx_mm256_invsqrt_ps(rsq00);
224             rinv10           = gmx_mm256_invsqrt_ps(rsq10);
225             rinv20           = gmx_mm256_invsqrt_ps(rsq20);
226
227             /* Load parameters for j particles */
228             jq0              = gmx_mm256_load_8real_swizzle_ps(charge+jnrA+0,charge+jnrB+0,
229                                                                  charge+jnrC+0,charge+jnrD+0,
230                                                                  charge+jnrE+0,charge+jnrF+0,
231                                                                  charge+jnrG+0,charge+jnrH+0);
232             vdwjidx0A        = 2*vdwtype[jnrA+0];
233             vdwjidx0B        = 2*vdwtype[jnrB+0];
234             vdwjidx0C        = 2*vdwtype[jnrC+0];
235             vdwjidx0D        = 2*vdwtype[jnrD+0];
236             vdwjidx0E        = 2*vdwtype[jnrE+0];
237             vdwjidx0F        = 2*vdwtype[jnrF+0];
238             vdwjidx0G        = 2*vdwtype[jnrG+0];
239             vdwjidx0H        = 2*vdwtype[jnrH+0];
240
241             fjx0             = _mm256_setzero_ps();
242             fjy0             = _mm256_setzero_ps();
243             fjz0             = _mm256_setzero_ps();
244
245             /**************************
246              * CALCULATE INTERACTIONS *
247              **************************/
248
249             r00              = _mm256_mul_ps(rsq00,rinv00);
250
251             /* Compute parameters for interactions between i and j atoms */
252             qq00             = _mm256_mul_ps(iq0,jq0);
253             gmx_mm256_load_8pair_swizzle_ps(vdwioffsetptr0+vdwjidx0A,
254                                             vdwioffsetptr0+vdwjidx0B,
255                                             vdwioffsetptr0+vdwjidx0C,
256                                             vdwioffsetptr0+vdwjidx0D,
257                                             vdwioffsetptr0+vdwjidx0E,
258                                             vdwioffsetptr0+vdwjidx0F,
259                                             vdwioffsetptr0+vdwjidx0G,
260                                             vdwioffsetptr0+vdwjidx0H,
261                                             &c6_00,&c12_00);
262
263             /* Calculate table index by multiplying r with table scale and truncate to integer */
264             rt               = _mm256_mul_ps(r00,vftabscale);
265             vfitab           = _mm256_cvttps_epi32(rt);
266             vfeps            = _mm256_sub_ps(rt,_mm256_round_ps(rt, _MM_FROUND_FLOOR));
267             /*         AVX1 does not support 256-bit integer operations, so now we go to 128-bit mode... */
268             vfitab_lo        = _mm256_extractf128_si256(vfitab,0x0);
269             vfitab_hi        = _mm256_extractf128_si256(vfitab,0x1);
270             vfitab_lo        = _mm_slli_epi32(_mm_add_epi32(vfitab_lo,_mm_slli_epi32(vfitab_lo,1)),2);
271             vfitab_hi        = _mm_slli_epi32(_mm_add_epi32(vfitab_hi,_mm_slli_epi32(vfitab_hi,1)),2);
272
273             /* CUBIC SPLINE TABLE ELECTROSTATICS */
274             Y                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,0)),
275                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,0)));
276             F                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,1)),
277                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,1)));
278             G                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,2)),
279                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,2)));
280             H                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,3)),
281                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,3)));
282             GMX_MM256_HALFTRANSPOSE4_PS(Y,F,G,H);
283             Heps             = _mm256_mul_ps(vfeps,H);
284             Fp               = _mm256_add_ps(F,_mm256_mul_ps(vfeps,_mm256_add_ps(G,Heps)));
285             VV               = _mm256_add_ps(Y,_mm256_mul_ps(vfeps,Fp));
286             velec            = _mm256_mul_ps(qq00,VV);
287             FF               = _mm256_add_ps(Fp,_mm256_mul_ps(vfeps,_mm256_add_ps(G,_mm256_add_ps(Heps,Heps))));
288             felec            = _mm256_xor_ps(signbit,_mm256_mul_ps(_mm256_mul_ps(qq00,FF),_mm256_mul_ps(vftabscale,rinv00)));
289
290             /* CUBIC SPLINE TABLE DISPERSION */
291             vfitab_lo        = _mm_add_epi32(vfitab_lo,ifour);
292             vfitab_hi        = _mm_add_epi32(vfitab_hi,ifour);
293             Y                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,0)),
294                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,0)));
295             F                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,1)),
296                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,1)));
297             G                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,2)),
298                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,2)));
299             H                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,3)),
300                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,3)));
301             GMX_MM256_HALFTRANSPOSE4_PS(Y,F,G,H);
302             Heps             = _mm256_mul_ps(vfeps,H);
303             Fp               = _mm256_add_ps(F,_mm256_mul_ps(vfeps,_mm256_add_ps(G,Heps)));
304             VV               = _mm256_add_ps(Y,_mm256_mul_ps(vfeps,Fp));
305             vvdw6            = _mm256_mul_ps(c6_00,VV);
306             FF               = _mm256_add_ps(Fp,_mm256_mul_ps(vfeps,_mm256_add_ps(G,_mm256_add_ps(Heps,Heps))));
307             fvdw6            = _mm256_mul_ps(c6_00,FF);
308
309             /* CUBIC SPLINE TABLE REPULSION */
310             vfitab_lo        = _mm_add_epi32(vfitab_lo,ifour);
311             vfitab_hi        = _mm_add_epi32(vfitab_hi,ifour);
312             Y                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,0)),
313                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,0)));
314             F                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,1)),
315                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,1)));
316             G                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,2)),
317                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,2)));
318             H                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,3)),
319                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,3)));
320             GMX_MM256_HALFTRANSPOSE4_PS(Y,F,G,H);
321             Heps             = _mm256_mul_ps(vfeps,H);
322             Fp               = _mm256_add_ps(F,_mm256_mul_ps(vfeps,_mm256_add_ps(G,Heps)));
323             VV               = _mm256_add_ps(Y,_mm256_mul_ps(vfeps,Fp));
324             vvdw12           = _mm256_mul_ps(c12_00,VV);
325             FF               = _mm256_add_ps(Fp,_mm256_mul_ps(vfeps,_mm256_add_ps(G,_mm256_add_ps(Heps,Heps))));
326             fvdw12           = _mm256_mul_ps(c12_00,FF);
327             vvdw             = _mm256_add_ps(vvdw12,vvdw6);
328             fvdw             = _mm256_xor_ps(signbit,_mm256_mul_ps(_mm256_add_ps(fvdw6,fvdw12),_mm256_mul_ps(vftabscale,rinv00)));
329
330             /* Update potential sum for this i atom from the interaction with this j atom. */
331             velecsum         = _mm256_add_ps(velecsum,velec);
332             vvdwsum          = _mm256_add_ps(vvdwsum,vvdw);
333
334             fscal            = _mm256_add_ps(felec,fvdw);
335
336             /* Calculate temporary vectorial force */
337             tx               = _mm256_mul_ps(fscal,dx00);
338             ty               = _mm256_mul_ps(fscal,dy00);
339             tz               = _mm256_mul_ps(fscal,dz00);
340
341             /* Update vectorial force */
342             fix0             = _mm256_add_ps(fix0,tx);
343             fiy0             = _mm256_add_ps(fiy0,ty);
344             fiz0             = _mm256_add_ps(fiz0,tz);
345
346             fjx0             = _mm256_add_ps(fjx0,tx);
347             fjy0             = _mm256_add_ps(fjy0,ty);
348             fjz0             = _mm256_add_ps(fjz0,tz);
349
350             /**************************
351              * CALCULATE INTERACTIONS *
352              **************************/
353
354             r10              = _mm256_mul_ps(rsq10,rinv10);
355
356             /* Compute parameters for interactions between i and j atoms */
357             qq10             = _mm256_mul_ps(iq1,jq0);
358
359             /* Calculate table index by multiplying r with table scale and truncate to integer */
360             rt               = _mm256_mul_ps(r10,vftabscale);
361             vfitab           = _mm256_cvttps_epi32(rt);
362             vfeps            = _mm256_sub_ps(rt,_mm256_round_ps(rt, _MM_FROUND_FLOOR));
363             /*         AVX1 does not support 256-bit integer operations, so now we go to 128-bit mode... */
364             vfitab_lo        = _mm256_extractf128_si256(vfitab,0x0);
365             vfitab_hi        = _mm256_extractf128_si256(vfitab,0x1);
366             vfitab_lo        = _mm_slli_epi32(_mm_add_epi32(vfitab_lo,_mm_slli_epi32(vfitab_lo,1)),2);
367             vfitab_hi        = _mm_slli_epi32(_mm_add_epi32(vfitab_hi,_mm_slli_epi32(vfitab_hi,1)),2);
368
369             /* CUBIC SPLINE TABLE ELECTROSTATICS */
370             Y                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,0)),
371                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,0)));
372             F                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,1)),
373                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,1)));
374             G                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,2)),
375                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,2)));
376             H                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,3)),
377                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,3)));
378             GMX_MM256_HALFTRANSPOSE4_PS(Y,F,G,H);
379             Heps             = _mm256_mul_ps(vfeps,H);
380             Fp               = _mm256_add_ps(F,_mm256_mul_ps(vfeps,_mm256_add_ps(G,Heps)));
381             VV               = _mm256_add_ps(Y,_mm256_mul_ps(vfeps,Fp));
382             velec            = _mm256_mul_ps(qq10,VV);
383             FF               = _mm256_add_ps(Fp,_mm256_mul_ps(vfeps,_mm256_add_ps(G,_mm256_add_ps(Heps,Heps))));
384             felec            = _mm256_xor_ps(signbit,_mm256_mul_ps(_mm256_mul_ps(qq10,FF),_mm256_mul_ps(vftabscale,rinv10)));
385
386             /* Update potential sum for this i atom from the interaction with this j atom. */
387             velecsum         = _mm256_add_ps(velecsum,velec);
388
389             fscal            = felec;
390
391             /* Calculate temporary vectorial force */
392             tx               = _mm256_mul_ps(fscal,dx10);
393             ty               = _mm256_mul_ps(fscal,dy10);
394             tz               = _mm256_mul_ps(fscal,dz10);
395
396             /* Update vectorial force */
397             fix1             = _mm256_add_ps(fix1,tx);
398             fiy1             = _mm256_add_ps(fiy1,ty);
399             fiz1             = _mm256_add_ps(fiz1,tz);
400
401             fjx0             = _mm256_add_ps(fjx0,tx);
402             fjy0             = _mm256_add_ps(fjy0,ty);
403             fjz0             = _mm256_add_ps(fjz0,tz);
404
405             /**************************
406              * CALCULATE INTERACTIONS *
407              **************************/
408
409             r20              = _mm256_mul_ps(rsq20,rinv20);
410
411             /* Compute parameters for interactions between i and j atoms */
412             qq20             = _mm256_mul_ps(iq2,jq0);
413
414             /* Calculate table index by multiplying r with table scale and truncate to integer */
415             rt               = _mm256_mul_ps(r20,vftabscale);
416             vfitab           = _mm256_cvttps_epi32(rt);
417             vfeps            = _mm256_sub_ps(rt,_mm256_round_ps(rt, _MM_FROUND_FLOOR));
418             /*         AVX1 does not support 256-bit integer operations, so now we go to 128-bit mode... */
419             vfitab_lo        = _mm256_extractf128_si256(vfitab,0x0);
420             vfitab_hi        = _mm256_extractf128_si256(vfitab,0x1);
421             vfitab_lo        = _mm_slli_epi32(_mm_add_epi32(vfitab_lo,_mm_slli_epi32(vfitab_lo,1)),2);
422             vfitab_hi        = _mm_slli_epi32(_mm_add_epi32(vfitab_hi,_mm_slli_epi32(vfitab_hi,1)),2);
423
424             /* CUBIC SPLINE TABLE ELECTROSTATICS */
425             Y                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,0)),
426                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,0)));
427             F                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,1)),
428                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,1)));
429             G                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,2)),
430                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,2)));
431             H                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,3)),
432                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,3)));
433             GMX_MM256_HALFTRANSPOSE4_PS(Y,F,G,H);
434             Heps             = _mm256_mul_ps(vfeps,H);
435             Fp               = _mm256_add_ps(F,_mm256_mul_ps(vfeps,_mm256_add_ps(G,Heps)));
436             VV               = _mm256_add_ps(Y,_mm256_mul_ps(vfeps,Fp));
437             velec            = _mm256_mul_ps(qq20,VV);
438             FF               = _mm256_add_ps(Fp,_mm256_mul_ps(vfeps,_mm256_add_ps(G,_mm256_add_ps(Heps,Heps))));
439             felec            = _mm256_xor_ps(signbit,_mm256_mul_ps(_mm256_mul_ps(qq20,FF),_mm256_mul_ps(vftabscale,rinv20)));
440
441             /* Update potential sum for this i atom from the interaction with this j atom. */
442             velecsum         = _mm256_add_ps(velecsum,velec);
443
444             fscal            = felec;
445
446             /* Calculate temporary vectorial force */
447             tx               = _mm256_mul_ps(fscal,dx20);
448             ty               = _mm256_mul_ps(fscal,dy20);
449             tz               = _mm256_mul_ps(fscal,dz20);
450
451             /* Update vectorial force */
452             fix2             = _mm256_add_ps(fix2,tx);
453             fiy2             = _mm256_add_ps(fiy2,ty);
454             fiz2             = _mm256_add_ps(fiz2,tz);
455
456             fjx0             = _mm256_add_ps(fjx0,tx);
457             fjy0             = _mm256_add_ps(fjy0,ty);
458             fjz0             = _mm256_add_ps(fjz0,tz);
459
460             fjptrA             = f+j_coord_offsetA;
461             fjptrB             = f+j_coord_offsetB;
462             fjptrC             = f+j_coord_offsetC;
463             fjptrD             = f+j_coord_offsetD;
464             fjptrE             = f+j_coord_offsetE;
465             fjptrF             = f+j_coord_offsetF;
466             fjptrG             = f+j_coord_offsetG;
467             fjptrH             = f+j_coord_offsetH;
468
469             gmx_mm256_decrement_1rvec_8ptr_swizzle_ps(fjptrA,fjptrB,fjptrC,fjptrD,fjptrE,fjptrF,fjptrG,fjptrH,fjx0,fjy0,fjz0);
470
471             /* Inner loop uses 162 flops */
472         }
473
474         if(jidx<j_index_end)
475         {
476
477             /* Get j neighbor index, and coordinate index */
478             jnrlistA         = jjnr[jidx];
479             jnrlistB         = jjnr[jidx+1];
480             jnrlistC         = jjnr[jidx+2];
481             jnrlistD         = jjnr[jidx+3];
482             jnrlistE         = jjnr[jidx+4];
483             jnrlistF         = jjnr[jidx+5];
484             jnrlistG         = jjnr[jidx+6];
485             jnrlistH         = jjnr[jidx+7];
486             /* Sign of each element will be negative for non-real atoms.
487              * This mask will be 0xFFFFFFFF for dummy entries and 0x0 for real ones,
488              * so use it as val = _mm_andnot_ps(mask,val) to clear dummy entries.
489              */
490             dummy_mask = gmx_mm256_set_m128(gmx_mm_castsi128_ps(_mm_cmplt_epi32(_mm_loadu_si128((const __m128i *)(jjnr+jidx+4)),_mm_setzero_si128())),
491                                             gmx_mm_castsi128_ps(_mm_cmplt_epi32(_mm_loadu_si128((const __m128i *)(jjnr+jidx)),_mm_setzero_si128())));
492                                             
493             jnrA       = (jnrlistA>=0) ? jnrlistA : 0;
494             jnrB       = (jnrlistB>=0) ? jnrlistB : 0;
495             jnrC       = (jnrlistC>=0) ? jnrlistC : 0;
496             jnrD       = (jnrlistD>=0) ? jnrlistD : 0;
497             jnrE       = (jnrlistE>=0) ? jnrlistE : 0;
498             jnrF       = (jnrlistF>=0) ? jnrlistF : 0;
499             jnrG       = (jnrlistG>=0) ? jnrlistG : 0;
500             jnrH       = (jnrlistH>=0) ? jnrlistH : 0;
501             j_coord_offsetA  = DIM*jnrA;
502             j_coord_offsetB  = DIM*jnrB;
503             j_coord_offsetC  = DIM*jnrC;
504             j_coord_offsetD  = DIM*jnrD;
505             j_coord_offsetE  = DIM*jnrE;
506             j_coord_offsetF  = DIM*jnrF;
507             j_coord_offsetG  = DIM*jnrG;
508             j_coord_offsetH  = DIM*jnrH;
509
510             /* load j atom coordinates */
511             gmx_mm256_load_1rvec_8ptr_swizzle_ps(x+j_coord_offsetA,x+j_coord_offsetB,
512                                                  x+j_coord_offsetC,x+j_coord_offsetD,
513                                                  x+j_coord_offsetE,x+j_coord_offsetF,
514                                                  x+j_coord_offsetG,x+j_coord_offsetH,
515                                                  &jx0,&jy0,&jz0);
516
517             /* Calculate displacement vector */
518             dx00             = _mm256_sub_ps(ix0,jx0);
519             dy00             = _mm256_sub_ps(iy0,jy0);
520             dz00             = _mm256_sub_ps(iz0,jz0);
521             dx10             = _mm256_sub_ps(ix1,jx0);
522             dy10             = _mm256_sub_ps(iy1,jy0);
523             dz10             = _mm256_sub_ps(iz1,jz0);
524             dx20             = _mm256_sub_ps(ix2,jx0);
525             dy20             = _mm256_sub_ps(iy2,jy0);
526             dz20             = _mm256_sub_ps(iz2,jz0);
527
528             /* Calculate squared distance and things based on it */
529             rsq00            = gmx_mm256_calc_rsq_ps(dx00,dy00,dz00);
530             rsq10            = gmx_mm256_calc_rsq_ps(dx10,dy10,dz10);
531             rsq20            = gmx_mm256_calc_rsq_ps(dx20,dy20,dz20);
532
533             rinv00           = gmx_mm256_invsqrt_ps(rsq00);
534             rinv10           = gmx_mm256_invsqrt_ps(rsq10);
535             rinv20           = gmx_mm256_invsqrt_ps(rsq20);
536
537             /* Load parameters for j particles */
538             jq0              = gmx_mm256_load_8real_swizzle_ps(charge+jnrA+0,charge+jnrB+0,
539                                                                  charge+jnrC+0,charge+jnrD+0,
540                                                                  charge+jnrE+0,charge+jnrF+0,
541                                                                  charge+jnrG+0,charge+jnrH+0);
542             vdwjidx0A        = 2*vdwtype[jnrA+0];
543             vdwjidx0B        = 2*vdwtype[jnrB+0];
544             vdwjidx0C        = 2*vdwtype[jnrC+0];
545             vdwjidx0D        = 2*vdwtype[jnrD+0];
546             vdwjidx0E        = 2*vdwtype[jnrE+0];
547             vdwjidx0F        = 2*vdwtype[jnrF+0];
548             vdwjidx0G        = 2*vdwtype[jnrG+0];
549             vdwjidx0H        = 2*vdwtype[jnrH+0];
550
551             fjx0             = _mm256_setzero_ps();
552             fjy0             = _mm256_setzero_ps();
553             fjz0             = _mm256_setzero_ps();
554
555             /**************************
556              * CALCULATE INTERACTIONS *
557              **************************/
558
559             r00              = _mm256_mul_ps(rsq00,rinv00);
560             r00              = _mm256_andnot_ps(dummy_mask,r00);
561
562             /* Compute parameters for interactions between i and j atoms */
563             qq00             = _mm256_mul_ps(iq0,jq0);
564             gmx_mm256_load_8pair_swizzle_ps(vdwioffsetptr0+vdwjidx0A,
565                                             vdwioffsetptr0+vdwjidx0B,
566                                             vdwioffsetptr0+vdwjidx0C,
567                                             vdwioffsetptr0+vdwjidx0D,
568                                             vdwioffsetptr0+vdwjidx0E,
569                                             vdwioffsetptr0+vdwjidx0F,
570                                             vdwioffsetptr0+vdwjidx0G,
571                                             vdwioffsetptr0+vdwjidx0H,
572                                             &c6_00,&c12_00);
573
574             /* Calculate table index by multiplying r with table scale and truncate to integer */
575             rt               = _mm256_mul_ps(r00,vftabscale);
576             vfitab           = _mm256_cvttps_epi32(rt);
577             vfeps            = _mm256_sub_ps(rt,_mm256_round_ps(rt, _MM_FROUND_FLOOR));
578             /*         AVX1 does not support 256-bit integer operations, so now we go to 128-bit mode... */
579             vfitab_lo        = _mm256_extractf128_si256(vfitab,0x0);
580             vfitab_hi        = _mm256_extractf128_si256(vfitab,0x1);
581             vfitab_lo        = _mm_slli_epi32(_mm_add_epi32(vfitab_lo,_mm_slli_epi32(vfitab_lo,1)),2);
582             vfitab_hi        = _mm_slli_epi32(_mm_add_epi32(vfitab_hi,_mm_slli_epi32(vfitab_hi,1)),2);
583
584             /* CUBIC SPLINE TABLE ELECTROSTATICS */
585             Y                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,0)),
586                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,0)));
587             F                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,1)),
588                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,1)));
589             G                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,2)),
590                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,2)));
591             H                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,3)),
592                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,3)));
593             GMX_MM256_HALFTRANSPOSE4_PS(Y,F,G,H);
594             Heps             = _mm256_mul_ps(vfeps,H);
595             Fp               = _mm256_add_ps(F,_mm256_mul_ps(vfeps,_mm256_add_ps(G,Heps)));
596             VV               = _mm256_add_ps(Y,_mm256_mul_ps(vfeps,Fp));
597             velec            = _mm256_mul_ps(qq00,VV);
598             FF               = _mm256_add_ps(Fp,_mm256_mul_ps(vfeps,_mm256_add_ps(G,_mm256_add_ps(Heps,Heps))));
599             felec            = _mm256_xor_ps(signbit,_mm256_mul_ps(_mm256_mul_ps(qq00,FF),_mm256_mul_ps(vftabscale,rinv00)));
600
601             /* CUBIC SPLINE TABLE DISPERSION */
602             vfitab_lo        = _mm_add_epi32(vfitab_lo,ifour);
603             vfitab_hi        = _mm_add_epi32(vfitab_hi,ifour);
604             Y                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,0)),
605                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,0)));
606             F                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,1)),
607                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,1)));
608             G                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,2)),
609                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,2)));
610             H                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,3)),
611                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,3)));
612             GMX_MM256_HALFTRANSPOSE4_PS(Y,F,G,H);
613             Heps             = _mm256_mul_ps(vfeps,H);
614             Fp               = _mm256_add_ps(F,_mm256_mul_ps(vfeps,_mm256_add_ps(G,Heps)));
615             VV               = _mm256_add_ps(Y,_mm256_mul_ps(vfeps,Fp));
616             vvdw6            = _mm256_mul_ps(c6_00,VV);
617             FF               = _mm256_add_ps(Fp,_mm256_mul_ps(vfeps,_mm256_add_ps(G,_mm256_add_ps(Heps,Heps))));
618             fvdw6            = _mm256_mul_ps(c6_00,FF);
619
620             /* CUBIC SPLINE TABLE REPULSION */
621             vfitab_lo        = _mm_add_epi32(vfitab_lo,ifour);
622             vfitab_hi        = _mm_add_epi32(vfitab_hi,ifour);
623             Y                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,0)),
624                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,0)));
625             F                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,1)),
626                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,1)));
627             G                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,2)),
628                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,2)));
629             H                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,3)),
630                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,3)));
631             GMX_MM256_HALFTRANSPOSE4_PS(Y,F,G,H);
632             Heps             = _mm256_mul_ps(vfeps,H);
633             Fp               = _mm256_add_ps(F,_mm256_mul_ps(vfeps,_mm256_add_ps(G,Heps)));
634             VV               = _mm256_add_ps(Y,_mm256_mul_ps(vfeps,Fp));
635             vvdw12           = _mm256_mul_ps(c12_00,VV);
636             FF               = _mm256_add_ps(Fp,_mm256_mul_ps(vfeps,_mm256_add_ps(G,_mm256_add_ps(Heps,Heps))));
637             fvdw12           = _mm256_mul_ps(c12_00,FF);
638             vvdw             = _mm256_add_ps(vvdw12,vvdw6);
639             fvdw             = _mm256_xor_ps(signbit,_mm256_mul_ps(_mm256_add_ps(fvdw6,fvdw12),_mm256_mul_ps(vftabscale,rinv00)));
640
641             /* Update potential sum for this i atom from the interaction with this j atom. */
642             velec            = _mm256_andnot_ps(dummy_mask,velec);
643             velecsum         = _mm256_add_ps(velecsum,velec);
644             vvdw             = _mm256_andnot_ps(dummy_mask,vvdw);
645             vvdwsum          = _mm256_add_ps(vvdwsum,vvdw);
646
647             fscal            = _mm256_add_ps(felec,fvdw);
648
649             fscal            = _mm256_andnot_ps(dummy_mask,fscal);
650
651             /* Calculate temporary vectorial force */
652             tx               = _mm256_mul_ps(fscal,dx00);
653             ty               = _mm256_mul_ps(fscal,dy00);
654             tz               = _mm256_mul_ps(fscal,dz00);
655
656             /* Update vectorial force */
657             fix0             = _mm256_add_ps(fix0,tx);
658             fiy0             = _mm256_add_ps(fiy0,ty);
659             fiz0             = _mm256_add_ps(fiz0,tz);
660
661             fjx0             = _mm256_add_ps(fjx0,tx);
662             fjy0             = _mm256_add_ps(fjy0,ty);
663             fjz0             = _mm256_add_ps(fjz0,tz);
664
665             /**************************
666              * CALCULATE INTERACTIONS *
667              **************************/
668
669             r10              = _mm256_mul_ps(rsq10,rinv10);
670             r10              = _mm256_andnot_ps(dummy_mask,r10);
671
672             /* Compute parameters for interactions between i and j atoms */
673             qq10             = _mm256_mul_ps(iq1,jq0);
674
675             /* Calculate table index by multiplying r with table scale and truncate to integer */
676             rt               = _mm256_mul_ps(r10,vftabscale);
677             vfitab           = _mm256_cvttps_epi32(rt);
678             vfeps            = _mm256_sub_ps(rt,_mm256_round_ps(rt, _MM_FROUND_FLOOR));
679             /*         AVX1 does not support 256-bit integer operations, so now we go to 128-bit mode... */
680             vfitab_lo        = _mm256_extractf128_si256(vfitab,0x0);
681             vfitab_hi        = _mm256_extractf128_si256(vfitab,0x1);
682             vfitab_lo        = _mm_slli_epi32(_mm_add_epi32(vfitab_lo,_mm_slli_epi32(vfitab_lo,1)),2);
683             vfitab_hi        = _mm_slli_epi32(_mm_add_epi32(vfitab_hi,_mm_slli_epi32(vfitab_hi,1)),2);
684
685             /* CUBIC SPLINE TABLE ELECTROSTATICS */
686             Y                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,0)),
687                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,0)));
688             F                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,1)),
689                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,1)));
690             G                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,2)),
691                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,2)));
692             H                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,3)),
693                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,3)));
694             GMX_MM256_HALFTRANSPOSE4_PS(Y,F,G,H);
695             Heps             = _mm256_mul_ps(vfeps,H);
696             Fp               = _mm256_add_ps(F,_mm256_mul_ps(vfeps,_mm256_add_ps(G,Heps)));
697             VV               = _mm256_add_ps(Y,_mm256_mul_ps(vfeps,Fp));
698             velec            = _mm256_mul_ps(qq10,VV);
699             FF               = _mm256_add_ps(Fp,_mm256_mul_ps(vfeps,_mm256_add_ps(G,_mm256_add_ps(Heps,Heps))));
700             felec            = _mm256_xor_ps(signbit,_mm256_mul_ps(_mm256_mul_ps(qq10,FF),_mm256_mul_ps(vftabscale,rinv10)));
701
702             /* Update potential sum for this i atom from the interaction with this j atom. */
703             velec            = _mm256_andnot_ps(dummy_mask,velec);
704             velecsum         = _mm256_add_ps(velecsum,velec);
705
706             fscal            = felec;
707
708             fscal            = _mm256_andnot_ps(dummy_mask,fscal);
709
710             /* Calculate temporary vectorial force */
711             tx               = _mm256_mul_ps(fscal,dx10);
712             ty               = _mm256_mul_ps(fscal,dy10);
713             tz               = _mm256_mul_ps(fscal,dz10);
714
715             /* Update vectorial force */
716             fix1             = _mm256_add_ps(fix1,tx);
717             fiy1             = _mm256_add_ps(fiy1,ty);
718             fiz1             = _mm256_add_ps(fiz1,tz);
719
720             fjx0             = _mm256_add_ps(fjx0,tx);
721             fjy0             = _mm256_add_ps(fjy0,ty);
722             fjz0             = _mm256_add_ps(fjz0,tz);
723
724             /**************************
725              * CALCULATE INTERACTIONS *
726              **************************/
727
728             r20              = _mm256_mul_ps(rsq20,rinv20);
729             r20              = _mm256_andnot_ps(dummy_mask,r20);
730
731             /* Compute parameters for interactions between i and j atoms */
732             qq20             = _mm256_mul_ps(iq2,jq0);
733
734             /* Calculate table index by multiplying r with table scale and truncate to integer */
735             rt               = _mm256_mul_ps(r20,vftabscale);
736             vfitab           = _mm256_cvttps_epi32(rt);
737             vfeps            = _mm256_sub_ps(rt,_mm256_round_ps(rt, _MM_FROUND_FLOOR));
738             /*         AVX1 does not support 256-bit integer operations, so now we go to 128-bit mode... */
739             vfitab_lo        = _mm256_extractf128_si256(vfitab,0x0);
740             vfitab_hi        = _mm256_extractf128_si256(vfitab,0x1);
741             vfitab_lo        = _mm_slli_epi32(_mm_add_epi32(vfitab_lo,_mm_slli_epi32(vfitab_lo,1)),2);
742             vfitab_hi        = _mm_slli_epi32(_mm_add_epi32(vfitab_hi,_mm_slli_epi32(vfitab_hi,1)),2);
743
744             /* CUBIC SPLINE TABLE ELECTROSTATICS */
745             Y                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,0)),
746                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,0)));
747             F                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,1)),
748                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,1)));
749             G                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,2)),
750                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,2)));
751             H                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,3)),
752                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,3)));
753             GMX_MM256_HALFTRANSPOSE4_PS(Y,F,G,H);
754             Heps             = _mm256_mul_ps(vfeps,H);
755             Fp               = _mm256_add_ps(F,_mm256_mul_ps(vfeps,_mm256_add_ps(G,Heps)));
756             VV               = _mm256_add_ps(Y,_mm256_mul_ps(vfeps,Fp));
757             velec            = _mm256_mul_ps(qq20,VV);
758             FF               = _mm256_add_ps(Fp,_mm256_mul_ps(vfeps,_mm256_add_ps(G,_mm256_add_ps(Heps,Heps))));
759             felec            = _mm256_xor_ps(signbit,_mm256_mul_ps(_mm256_mul_ps(qq20,FF),_mm256_mul_ps(vftabscale,rinv20)));
760
761             /* Update potential sum for this i atom from the interaction with this j atom. */
762             velec            = _mm256_andnot_ps(dummy_mask,velec);
763             velecsum         = _mm256_add_ps(velecsum,velec);
764
765             fscal            = felec;
766
767             fscal            = _mm256_andnot_ps(dummy_mask,fscal);
768
769             /* Calculate temporary vectorial force */
770             tx               = _mm256_mul_ps(fscal,dx20);
771             ty               = _mm256_mul_ps(fscal,dy20);
772             tz               = _mm256_mul_ps(fscal,dz20);
773
774             /* Update vectorial force */
775             fix2             = _mm256_add_ps(fix2,tx);
776             fiy2             = _mm256_add_ps(fiy2,ty);
777             fiz2             = _mm256_add_ps(fiz2,tz);
778
779             fjx0             = _mm256_add_ps(fjx0,tx);
780             fjy0             = _mm256_add_ps(fjy0,ty);
781             fjz0             = _mm256_add_ps(fjz0,tz);
782
783             fjptrA             = (jnrlistA>=0) ? f+j_coord_offsetA : scratch;
784             fjptrB             = (jnrlistB>=0) ? f+j_coord_offsetB : scratch;
785             fjptrC             = (jnrlistC>=0) ? f+j_coord_offsetC : scratch;
786             fjptrD             = (jnrlistD>=0) ? f+j_coord_offsetD : scratch;
787             fjptrE             = (jnrlistE>=0) ? f+j_coord_offsetE : scratch;
788             fjptrF             = (jnrlistF>=0) ? f+j_coord_offsetF : scratch;
789             fjptrG             = (jnrlistG>=0) ? f+j_coord_offsetG : scratch;
790             fjptrH             = (jnrlistH>=0) ? f+j_coord_offsetH : scratch;
791
792             gmx_mm256_decrement_1rvec_8ptr_swizzle_ps(fjptrA,fjptrB,fjptrC,fjptrD,fjptrE,fjptrF,fjptrG,fjptrH,fjx0,fjy0,fjz0);
793
794             /* Inner loop uses 165 flops */
795         }
796
797         /* End of innermost loop */
798
799         gmx_mm256_update_iforce_3atom_swizzle_ps(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
800                                                  f+i_coord_offset,fshift+i_shift_offset);
801
802         ggid                        = gid[iidx];
803         /* Update potential energies */
804         gmx_mm256_update_1pot_ps(velecsum,kernel_data->energygrp_elec+ggid);
805         gmx_mm256_update_1pot_ps(vvdwsum,kernel_data->energygrp_vdw+ggid);
806
807         /* Increment number of inner iterations */
808         inneriter                  += j_index_end - j_index_start;
809
810         /* Outer loop uses 20 flops */
811     }
812
813     /* Increment number of outer iterations */
814     outeriter        += nri;
815
816     /* Update outer/inner flops */
817
818     inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3_VF,outeriter*20 + inneriter*165);
819 }
820 /*
821  * Gromacs nonbonded kernel:   nb_kernel_ElecCSTab_VdwCSTab_GeomW3P1_F_avx_256_single
822  * Electrostatics interaction: CubicSplineTable
823  * VdW interaction:            CubicSplineTable
824  * Geometry:                   Water3-Particle
825  * Calculate force/pot:        Force
826  */
827 void
828 nb_kernel_ElecCSTab_VdwCSTab_GeomW3P1_F_avx_256_single
829                     (t_nblist * gmx_restrict                nlist,
830                      rvec * gmx_restrict                    xx,
831                      rvec * gmx_restrict                    ff,
832                      t_forcerec * gmx_restrict              fr,
833                      t_mdatoms * gmx_restrict               mdatoms,
834                      nb_kernel_data_t * gmx_restrict        kernel_data,
835                      t_nrnb * gmx_restrict                  nrnb)
836 {
837     /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or 
838      * just 0 for non-waters.
839      * Suffixes A,B,C,D,E,F,G,H refer to j loop unrolling done with AVX, e.g. for the eight different
840      * jnr indices corresponding to data put in the four positions in the SIMD register.
841      */
842     int              i_shift_offset,i_coord_offset,outeriter,inneriter;
843     int              j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
844     int              jnrA,jnrB,jnrC,jnrD;
845     int              jnrE,jnrF,jnrG,jnrH;
846     int              jnrlistA,jnrlistB,jnrlistC,jnrlistD;
847     int              jnrlistE,jnrlistF,jnrlistG,jnrlistH;
848     int              j_coord_offsetA,j_coord_offsetB,j_coord_offsetC,j_coord_offsetD;
849     int              j_coord_offsetE,j_coord_offsetF,j_coord_offsetG,j_coord_offsetH;
850     int              *iinr,*jindex,*jjnr,*shiftidx,*gid;
851     real             rcutoff_scalar;
852     real             *shiftvec,*fshift,*x,*f;
853     real             *fjptrA,*fjptrB,*fjptrC,*fjptrD,*fjptrE,*fjptrF,*fjptrG,*fjptrH;
854     real             scratch[4*DIM];
855     __m256           tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
856     real *           vdwioffsetptr0;
857     __m256           ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
858     real *           vdwioffsetptr1;
859     __m256           ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
860     real *           vdwioffsetptr2;
861     __m256           ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
862     int              vdwjidx0A,vdwjidx0B,vdwjidx0C,vdwjidx0D,vdwjidx0E,vdwjidx0F,vdwjidx0G,vdwjidx0H;
863     __m256           jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
864     __m256           dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
865     __m256           dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
866     __m256           dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
867     __m256           velec,felec,velecsum,facel,crf,krf,krf2;
868     real             *charge;
869     int              nvdwtype;
870     __m256           rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
871     int              *vdwtype;
872     real             *vdwparam;
873     __m256           one_sixth   = _mm256_set1_ps(1.0/6.0);
874     __m256           one_twelfth = _mm256_set1_ps(1.0/12.0);
875     __m256i          vfitab;
876     __m128i          vfitab_lo,vfitab_hi;
877     __m128i          ifour       = _mm_set1_epi32(4);
878     __m256           rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
879     real             *vftab;
880     __m256           dummy_mask,cutoff_mask;
881     __m256           signbit = _mm256_castsi256_ps( _mm256_set1_epi32(0x80000000) );
882     __m256           one     = _mm256_set1_ps(1.0);
883     __m256           two     = _mm256_set1_ps(2.0);
884     x                = xx[0];
885     f                = ff[0];
886
887     nri              = nlist->nri;
888     iinr             = nlist->iinr;
889     jindex           = nlist->jindex;
890     jjnr             = nlist->jjnr;
891     shiftidx         = nlist->shift;
892     gid              = nlist->gid;
893     shiftvec         = fr->shift_vec[0];
894     fshift           = fr->fshift[0];
895     facel            = _mm256_set1_ps(fr->epsfac);
896     charge           = mdatoms->chargeA;
897     nvdwtype         = fr->ntype;
898     vdwparam         = fr->nbfp;
899     vdwtype          = mdatoms->typeA;
900
901     vftab            = kernel_data->table_elec_vdw->data;
902     vftabscale       = _mm256_set1_ps(kernel_data->table_elec_vdw->scale);
903
904     /* Setup water-specific parameters */
905     inr              = nlist->iinr[0];
906     iq0              = _mm256_mul_ps(facel,_mm256_set1_ps(charge[inr+0]));
907     iq1              = _mm256_mul_ps(facel,_mm256_set1_ps(charge[inr+1]));
908     iq2              = _mm256_mul_ps(facel,_mm256_set1_ps(charge[inr+2]));
909     vdwioffsetptr0   = vdwparam+2*nvdwtype*vdwtype[inr+0];
910
911     /* Avoid stupid compiler warnings */
912     jnrA = jnrB = jnrC = jnrD = jnrE = jnrF = jnrG = jnrH = 0;
913     j_coord_offsetA = 0;
914     j_coord_offsetB = 0;
915     j_coord_offsetC = 0;
916     j_coord_offsetD = 0;
917     j_coord_offsetE = 0;
918     j_coord_offsetF = 0;
919     j_coord_offsetG = 0;
920     j_coord_offsetH = 0;
921
922     outeriter        = 0;
923     inneriter        = 0;
924
925     for(iidx=0;iidx<4*DIM;iidx++)
926     {
927         scratch[iidx] = 0.0;
928     }
929
930     /* Start outer loop over neighborlists */
931     for(iidx=0; iidx<nri; iidx++)
932     {
933         /* Load shift vector for this list */
934         i_shift_offset   = DIM*shiftidx[iidx];
935
936         /* Load limits for loop over neighbors */
937         j_index_start    = jindex[iidx];
938         j_index_end      = jindex[iidx+1];
939
940         /* Get outer coordinate index */
941         inr              = iinr[iidx];
942         i_coord_offset   = DIM*inr;
943
944         /* Load i particle coords and add shift vector */
945         gmx_mm256_load_shift_and_3rvec_broadcast_ps(shiftvec+i_shift_offset,x+i_coord_offset,
946                                                     &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
947
948         fix0             = _mm256_setzero_ps();
949         fiy0             = _mm256_setzero_ps();
950         fiz0             = _mm256_setzero_ps();
951         fix1             = _mm256_setzero_ps();
952         fiy1             = _mm256_setzero_ps();
953         fiz1             = _mm256_setzero_ps();
954         fix2             = _mm256_setzero_ps();
955         fiy2             = _mm256_setzero_ps();
956         fiz2             = _mm256_setzero_ps();
957
958         /* Start inner kernel loop */
959         for(jidx=j_index_start; jidx<j_index_end && jjnr[jidx+7]>=0; jidx+=8)
960         {
961
962             /* Get j neighbor index, and coordinate index */
963             jnrA             = jjnr[jidx];
964             jnrB             = jjnr[jidx+1];
965             jnrC             = jjnr[jidx+2];
966             jnrD             = jjnr[jidx+3];
967             jnrE             = jjnr[jidx+4];
968             jnrF             = jjnr[jidx+5];
969             jnrG             = jjnr[jidx+6];
970             jnrH             = jjnr[jidx+7];
971             j_coord_offsetA  = DIM*jnrA;
972             j_coord_offsetB  = DIM*jnrB;
973             j_coord_offsetC  = DIM*jnrC;
974             j_coord_offsetD  = DIM*jnrD;
975             j_coord_offsetE  = DIM*jnrE;
976             j_coord_offsetF  = DIM*jnrF;
977             j_coord_offsetG  = DIM*jnrG;
978             j_coord_offsetH  = DIM*jnrH;
979
980             /* load j atom coordinates */
981             gmx_mm256_load_1rvec_8ptr_swizzle_ps(x+j_coord_offsetA,x+j_coord_offsetB,
982                                                  x+j_coord_offsetC,x+j_coord_offsetD,
983                                                  x+j_coord_offsetE,x+j_coord_offsetF,
984                                                  x+j_coord_offsetG,x+j_coord_offsetH,
985                                                  &jx0,&jy0,&jz0);
986
987             /* Calculate displacement vector */
988             dx00             = _mm256_sub_ps(ix0,jx0);
989             dy00             = _mm256_sub_ps(iy0,jy0);
990             dz00             = _mm256_sub_ps(iz0,jz0);
991             dx10             = _mm256_sub_ps(ix1,jx0);
992             dy10             = _mm256_sub_ps(iy1,jy0);
993             dz10             = _mm256_sub_ps(iz1,jz0);
994             dx20             = _mm256_sub_ps(ix2,jx0);
995             dy20             = _mm256_sub_ps(iy2,jy0);
996             dz20             = _mm256_sub_ps(iz2,jz0);
997
998             /* Calculate squared distance and things based on it */
999             rsq00            = gmx_mm256_calc_rsq_ps(dx00,dy00,dz00);
1000             rsq10            = gmx_mm256_calc_rsq_ps(dx10,dy10,dz10);
1001             rsq20            = gmx_mm256_calc_rsq_ps(dx20,dy20,dz20);
1002
1003             rinv00           = gmx_mm256_invsqrt_ps(rsq00);
1004             rinv10           = gmx_mm256_invsqrt_ps(rsq10);
1005             rinv20           = gmx_mm256_invsqrt_ps(rsq20);
1006
1007             /* Load parameters for j particles */
1008             jq0              = gmx_mm256_load_8real_swizzle_ps(charge+jnrA+0,charge+jnrB+0,
1009                                                                  charge+jnrC+0,charge+jnrD+0,
1010                                                                  charge+jnrE+0,charge+jnrF+0,
1011                                                                  charge+jnrG+0,charge+jnrH+0);
1012             vdwjidx0A        = 2*vdwtype[jnrA+0];
1013             vdwjidx0B        = 2*vdwtype[jnrB+0];
1014             vdwjidx0C        = 2*vdwtype[jnrC+0];
1015             vdwjidx0D        = 2*vdwtype[jnrD+0];
1016             vdwjidx0E        = 2*vdwtype[jnrE+0];
1017             vdwjidx0F        = 2*vdwtype[jnrF+0];
1018             vdwjidx0G        = 2*vdwtype[jnrG+0];
1019             vdwjidx0H        = 2*vdwtype[jnrH+0];
1020
1021             fjx0             = _mm256_setzero_ps();
1022             fjy0             = _mm256_setzero_ps();
1023             fjz0             = _mm256_setzero_ps();
1024
1025             /**************************
1026              * CALCULATE INTERACTIONS *
1027              **************************/
1028
1029             r00              = _mm256_mul_ps(rsq00,rinv00);
1030
1031             /* Compute parameters for interactions between i and j atoms */
1032             qq00             = _mm256_mul_ps(iq0,jq0);
1033             gmx_mm256_load_8pair_swizzle_ps(vdwioffsetptr0+vdwjidx0A,
1034                                             vdwioffsetptr0+vdwjidx0B,
1035                                             vdwioffsetptr0+vdwjidx0C,
1036                                             vdwioffsetptr0+vdwjidx0D,
1037                                             vdwioffsetptr0+vdwjidx0E,
1038                                             vdwioffsetptr0+vdwjidx0F,
1039                                             vdwioffsetptr0+vdwjidx0G,
1040                                             vdwioffsetptr0+vdwjidx0H,
1041                                             &c6_00,&c12_00);
1042
1043             /* Calculate table index by multiplying r with table scale and truncate to integer */
1044             rt               = _mm256_mul_ps(r00,vftabscale);
1045             vfitab           = _mm256_cvttps_epi32(rt);
1046             vfeps            = _mm256_sub_ps(rt,_mm256_round_ps(rt, _MM_FROUND_FLOOR));
1047             /*         AVX1 does not support 256-bit integer operations, so now we go to 128-bit mode... */
1048             vfitab_lo        = _mm256_extractf128_si256(vfitab,0x0);
1049             vfitab_hi        = _mm256_extractf128_si256(vfitab,0x1);
1050             vfitab_lo        = _mm_slli_epi32(_mm_add_epi32(vfitab_lo,_mm_slli_epi32(vfitab_lo,1)),2);
1051             vfitab_hi        = _mm_slli_epi32(_mm_add_epi32(vfitab_hi,_mm_slli_epi32(vfitab_hi,1)),2);
1052
1053             /* CUBIC SPLINE TABLE ELECTROSTATICS */
1054             Y                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,0)),
1055                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,0)));
1056             F                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,1)),
1057                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,1)));
1058             G                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,2)),
1059                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,2)));
1060             H                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,3)),
1061                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,3)));
1062             GMX_MM256_HALFTRANSPOSE4_PS(Y,F,G,H);
1063             Heps             = _mm256_mul_ps(vfeps,H);
1064             Fp               = _mm256_add_ps(F,_mm256_mul_ps(vfeps,_mm256_add_ps(G,Heps)));
1065             FF               = _mm256_add_ps(Fp,_mm256_mul_ps(vfeps,_mm256_add_ps(G,_mm256_add_ps(Heps,Heps))));
1066             felec            = _mm256_xor_ps(signbit,_mm256_mul_ps(_mm256_mul_ps(qq00,FF),_mm256_mul_ps(vftabscale,rinv00)));
1067
1068             /* CUBIC SPLINE TABLE DISPERSION */
1069             vfitab_lo        = _mm_add_epi32(vfitab_lo,ifour);
1070             vfitab_hi        = _mm_add_epi32(vfitab_hi,ifour);
1071             Y                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,0)),
1072                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,0)));
1073             F                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,1)),
1074                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,1)));
1075             G                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,2)),
1076                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,2)));
1077             H                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,3)),
1078                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,3)));
1079             GMX_MM256_HALFTRANSPOSE4_PS(Y,F,G,H);
1080             Heps             = _mm256_mul_ps(vfeps,H);
1081             Fp               = _mm256_add_ps(F,_mm256_mul_ps(vfeps,_mm256_add_ps(G,Heps)));
1082             FF               = _mm256_add_ps(Fp,_mm256_mul_ps(vfeps,_mm256_add_ps(G,_mm256_add_ps(Heps,Heps))));
1083             fvdw6            = _mm256_mul_ps(c6_00,FF);
1084
1085             /* CUBIC SPLINE TABLE REPULSION */
1086             vfitab_lo        = _mm_add_epi32(vfitab_lo,ifour);
1087             vfitab_hi        = _mm_add_epi32(vfitab_hi,ifour);
1088             Y                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,0)),
1089                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,0)));
1090             F                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,1)),
1091                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,1)));
1092             G                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,2)),
1093                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,2)));
1094             H                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,3)),
1095                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,3)));
1096             GMX_MM256_HALFTRANSPOSE4_PS(Y,F,G,H);
1097             Heps             = _mm256_mul_ps(vfeps,H);
1098             Fp               = _mm256_add_ps(F,_mm256_mul_ps(vfeps,_mm256_add_ps(G,Heps)));
1099             FF               = _mm256_add_ps(Fp,_mm256_mul_ps(vfeps,_mm256_add_ps(G,_mm256_add_ps(Heps,Heps))));
1100             fvdw12           = _mm256_mul_ps(c12_00,FF);
1101             fvdw             = _mm256_xor_ps(signbit,_mm256_mul_ps(_mm256_add_ps(fvdw6,fvdw12),_mm256_mul_ps(vftabscale,rinv00)));
1102
1103             fscal            = _mm256_add_ps(felec,fvdw);
1104
1105             /* Calculate temporary vectorial force */
1106             tx               = _mm256_mul_ps(fscal,dx00);
1107             ty               = _mm256_mul_ps(fscal,dy00);
1108             tz               = _mm256_mul_ps(fscal,dz00);
1109
1110             /* Update vectorial force */
1111             fix0             = _mm256_add_ps(fix0,tx);
1112             fiy0             = _mm256_add_ps(fiy0,ty);
1113             fiz0             = _mm256_add_ps(fiz0,tz);
1114
1115             fjx0             = _mm256_add_ps(fjx0,tx);
1116             fjy0             = _mm256_add_ps(fjy0,ty);
1117             fjz0             = _mm256_add_ps(fjz0,tz);
1118
1119             /**************************
1120              * CALCULATE INTERACTIONS *
1121              **************************/
1122
1123             r10              = _mm256_mul_ps(rsq10,rinv10);
1124
1125             /* Compute parameters for interactions between i and j atoms */
1126             qq10             = _mm256_mul_ps(iq1,jq0);
1127
1128             /* Calculate table index by multiplying r with table scale and truncate to integer */
1129             rt               = _mm256_mul_ps(r10,vftabscale);
1130             vfitab           = _mm256_cvttps_epi32(rt);
1131             vfeps            = _mm256_sub_ps(rt,_mm256_round_ps(rt, _MM_FROUND_FLOOR));
1132             /*         AVX1 does not support 256-bit integer operations, so now we go to 128-bit mode... */
1133             vfitab_lo        = _mm256_extractf128_si256(vfitab,0x0);
1134             vfitab_hi        = _mm256_extractf128_si256(vfitab,0x1);
1135             vfitab_lo        = _mm_slli_epi32(_mm_add_epi32(vfitab_lo,_mm_slli_epi32(vfitab_lo,1)),2);
1136             vfitab_hi        = _mm_slli_epi32(_mm_add_epi32(vfitab_hi,_mm_slli_epi32(vfitab_hi,1)),2);
1137
1138             /* CUBIC SPLINE TABLE ELECTROSTATICS */
1139             Y                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,0)),
1140                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,0)));
1141             F                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,1)),
1142                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,1)));
1143             G                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,2)),
1144                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,2)));
1145             H                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,3)),
1146                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,3)));
1147             GMX_MM256_HALFTRANSPOSE4_PS(Y,F,G,H);
1148             Heps             = _mm256_mul_ps(vfeps,H);
1149             Fp               = _mm256_add_ps(F,_mm256_mul_ps(vfeps,_mm256_add_ps(G,Heps)));
1150             FF               = _mm256_add_ps(Fp,_mm256_mul_ps(vfeps,_mm256_add_ps(G,_mm256_add_ps(Heps,Heps))));
1151             felec            = _mm256_xor_ps(signbit,_mm256_mul_ps(_mm256_mul_ps(qq10,FF),_mm256_mul_ps(vftabscale,rinv10)));
1152
1153             fscal            = felec;
1154
1155             /* Calculate temporary vectorial force */
1156             tx               = _mm256_mul_ps(fscal,dx10);
1157             ty               = _mm256_mul_ps(fscal,dy10);
1158             tz               = _mm256_mul_ps(fscal,dz10);
1159
1160             /* Update vectorial force */
1161             fix1             = _mm256_add_ps(fix1,tx);
1162             fiy1             = _mm256_add_ps(fiy1,ty);
1163             fiz1             = _mm256_add_ps(fiz1,tz);
1164
1165             fjx0             = _mm256_add_ps(fjx0,tx);
1166             fjy0             = _mm256_add_ps(fjy0,ty);
1167             fjz0             = _mm256_add_ps(fjz0,tz);
1168
1169             /**************************
1170              * CALCULATE INTERACTIONS *
1171              **************************/
1172
1173             r20              = _mm256_mul_ps(rsq20,rinv20);
1174
1175             /* Compute parameters for interactions between i and j atoms */
1176             qq20             = _mm256_mul_ps(iq2,jq0);
1177
1178             /* Calculate table index by multiplying r with table scale and truncate to integer */
1179             rt               = _mm256_mul_ps(r20,vftabscale);
1180             vfitab           = _mm256_cvttps_epi32(rt);
1181             vfeps            = _mm256_sub_ps(rt,_mm256_round_ps(rt, _MM_FROUND_FLOOR));
1182             /*         AVX1 does not support 256-bit integer operations, so now we go to 128-bit mode... */
1183             vfitab_lo        = _mm256_extractf128_si256(vfitab,0x0);
1184             vfitab_hi        = _mm256_extractf128_si256(vfitab,0x1);
1185             vfitab_lo        = _mm_slli_epi32(_mm_add_epi32(vfitab_lo,_mm_slli_epi32(vfitab_lo,1)),2);
1186             vfitab_hi        = _mm_slli_epi32(_mm_add_epi32(vfitab_hi,_mm_slli_epi32(vfitab_hi,1)),2);
1187
1188             /* CUBIC SPLINE TABLE ELECTROSTATICS */
1189             Y                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,0)),
1190                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,0)));
1191             F                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,1)),
1192                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,1)));
1193             G                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,2)),
1194                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,2)));
1195             H                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,3)),
1196                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,3)));
1197             GMX_MM256_HALFTRANSPOSE4_PS(Y,F,G,H);
1198             Heps             = _mm256_mul_ps(vfeps,H);
1199             Fp               = _mm256_add_ps(F,_mm256_mul_ps(vfeps,_mm256_add_ps(G,Heps)));
1200             FF               = _mm256_add_ps(Fp,_mm256_mul_ps(vfeps,_mm256_add_ps(G,_mm256_add_ps(Heps,Heps))));
1201             felec            = _mm256_xor_ps(signbit,_mm256_mul_ps(_mm256_mul_ps(qq20,FF),_mm256_mul_ps(vftabscale,rinv20)));
1202
1203             fscal            = felec;
1204
1205             /* Calculate temporary vectorial force */
1206             tx               = _mm256_mul_ps(fscal,dx20);
1207             ty               = _mm256_mul_ps(fscal,dy20);
1208             tz               = _mm256_mul_ps(fscal,dz20);
1209
1210             /* Update vectorial force */
1211             fix2             = _mm256_add_ps(fix2,tx);
1212             fiy2             = _mm256_add_ps(fiy2,ty);
1213             fiz2             = _mm256_add_ps(fiz2,tz);
1214
1215             fjx0             = _mm256_add_ps(fjx0,tx);
1216             fjy0             = _mm256_add_ps(fjy0,ty);
1217             fjz0             = _mm256_add_ps(fjz0,tz);
1218
1219             fjptrA             = f+j_coord_offsetA;
1220             fjptrB             = f+j_coord_offsetB;
1221             fjptrC             = f+j_coord_offsetC;
1222             fjptrD             = f+j_coord_offsetD;
1223             fjptrE             = f+j_coord_offsetE;
1224             fjptrF             = f+j_coord_offsetF;
1225             fjptrG             = f+j_coord_offsetG;
1226             fjptrH             = f+j_coord_offsetH;
1227
1228             gmx_mm256_decrement_1rvec_8ptr_swizzle_ps(fjptrA,fjptrB,fjptrC,fjptrD,fjptrE,fjptrF,fjptrG,fjptrH,fjx0,fjy0,fjz0);
1229
1230             /* Inner loop uses 142 flops */
1231         }
1232
1233         if(jidx<j_index_end)
1234         {
1235
1236             /* Get j neighbor index, and coordinate index */
1237             jnrlistA         = jjnr[jidx];
1238             jnrlistB         = jjnr[jidx+1];
1239             jnrlistC         = jjnr[jidx+2];
1240             jnrlistD         = jjnr[jidx+3];
1241             jnrlistE         = jjnr[jidx+4];
1242             jnrlistF         = jjnr[jidx+5];
1243             jnrlistG         = jjnr[jidx+6];
1244             jnrlistH         = jjnr[jidx+7];
1245             /* Sign of each element will be negative for non-real atoms.
1246              * This mask will be 0xFFFFFFFF for dummy entries and 0x0 for real ones,
1247              * so use it as val = _mm_andnot_ps(mask,val) to clear dummy entries.
1248              */
1249             dummy_mask = gmx_mm256_set_m128(gmx_mm_castsi128_ps(_mm_cmplt_epi32(_mm_loadu_si128((const __m128i *)(jjnr+jidx+4)),_mm_setzero_si128())),
1250                                             gmx_mm_castsi128_ps(_mm_cmplt_epi32(_mm_loadu_si128((const __m128i *)(jjnr+jidx)),_mm_setzero_si128())));
1251                                             
1252             jnrA       = (jnrlistA>=0) ? jnrlistA : 0;
1253             jnrB       = (jnrlistB>=0) ? jnrlistB : 0;
1254             jnrC       = (jnrlistC>=0) ? jnrlistC : 0;
1255             jnrD       = (jnrlistD>=0) ? jnrlistD : 0;
1256             jnrE       = (jnrlistE>=0) ? jnrlistE : 0;
1257             jnrF       = (jnrlistF>=0) ? jnrlistF : 0;
1258             jnrG       = (jnrlistG>=0) ? jnrlistG : 0;
1259             jnrH       = (jnrlistH>=0) ? jnrlistH : 0;
1260             j_coord_offsetA  = DIM*jnrA;
1261             j_coord_offsetB  = DIM*jnrB;
1262             j_coord_offsetC  = DIM*jnrC;
1263             j_coord_offsetD  = DIM*jnrD;
1264             j_coord_offsetE  = DIM*jnrE;
1265             j_coord_offsetF  = DIM*jnrF;
1266             j_coord_offsetG  = DIM*jnrG;
1267             j_coord_offsetH  = DIM*jnrH;
1268
1269             /* load j atom coordinates */
1270             gmx_mm256_load_1rvec_8ptr_swizzle_ps(x+j_coord_offsetA,x+j_coord_offsetB,
1271                                                  x+j_coord_offsetC,x+j_coord_offsetD,
1272                                                  x+j_coord_offsetE,x+j_coord_offsetF,
1273                                                  x+j_coord_offsetG,x+j_coord_offsetH,
1274                                                  &jx0,&jy0,&jz0);
1275
1276             /* Calculate displacement vector */
1277             dx00             = _mm256_sub_ps(ix0,jx0);
1278             dy00             = _mm256_sub_ps(iy0,jy0);
1279             dz00             = _mm256_sub_ps(iz0,jz0);
1280             dx10             = _mm256_sub_ps(ix1,jx0);
1281             dy10             = _mm256_sub_ps(iy1,jy0);
1282             dz10             = _mm256_sub_ps(iz1,jz0);
1283             dx20             = _mm256_sub_ps(ix2,jx0);
1284             dy20             = _mm256_sub_ps(iy2,jy0);
1285             dz20             = _mm256_sub_ps(iz2,jz0);
1286
1287             /* Calculate squared distance and things based on it */
1288             rsq00            = gmx_mm256_calc_rsq_ps(dx00,dy00,dz00);
1289             rsq10            = gmx_mm256_calc_rsq_ps(dx10,dy10,dz10);
1290             rsq20            = gmx_mm256_calc_rsq_ps(dx20,dy20,dz20);
1291
1292             rinv00           = gmx_mm256_invsqrt_ps(rsq00);
1293             rinv10           = gmx_mm256_invsqrt_ps(rsq10);
1294             rinv20           = gmx_mm256_invsqrt_ps(rsq20);
1295
1296             /* Load parameters for j particles */
1297             jq0              = gmx_mm256_load_8real_swizzle_ps(charge+jnrA+0,charge+jnrB+0,
1298                                                                  charge+jnrC+0,charge+jnrD+0,
1299                                                                  charge+jnrE+0,charge+jnrF+0,
1300                                                                  charge+jnrG+0,charge+jnrH+0);
1301             vdwjidx0A        = 2*vdwtype[jnrA+0];
1302             vdwjidx0B        = 2*vdwtype[jnrB+0];
1303             vdwjidx0C        = 2*vdwtype[jnrC+0];
1304             vdwjidx0D        = 2*vdwtype[jnrD+0];
1305             vdwjidx0E        = 2*vdwtype[jnrE+0];
1306             vdwjidx0F        = 2*vdwtype[jnrF+0];
1307             vdwjidx0G        = 2*vdwtype[jnrG+0];
1308             vdwjidx0H        = 2*vdwtype[jnrH+0];
1309
1310             fjx0             = _mm256_setzero_ps();
1311             fjy0             = _mm256_setzero_ps();
1312             fjz0             = _mm256_setzero_ps();
1313
1314             /**************************
1315              * CALCULATE INTERACTIONS *
1316              **************************/
1317
1318             r00              = _mm256_mul_ps(rsq00,rinv00);
1319             r00              = _mm256_andnot_ps(dummy_mask,r00);
1320
1321             /* Compute parameters for interactions between i and j atoms */
1322             qq00             = _mm256_mul_ps(iq0,jq0);
1323             gmx_mm256_load_8pair_swizzle_ps(vdwioffsetptr0+vdwjidx0A,
1324                                             vdwioffsetptr0+vdwjidx0B,
1325                                             vdwioffsetptr0+vdwjidx0C,
1326                                             vdwioffsetptr0+vdwjidx0D,
1327                                             vdwioffsetptr0+vdwjidx0E,
1328                                             vdwioffsetptr0+vdwjidx0F,
1329                                             vdwioffsetptr0+vdwjidx0G,
1330                                             vdwioffsetptr0+vdwjidx0H,
1331                                             &c6_00,&c12_00);
1332
1333             /* Calculate table index by multiplying r with table scale and truncate to integer */
1334             rt               = _mm256_mul_ps(r00,vftabscale);
1335             vfitab           = _mm256_cvttps_epi32(rt);
1336             vfeps            = _mm256_sub_ps(rt,_mm256_round_ps(rt, _MM_FROUND_FLOOR));
1337             /*         AVX1 does not support 256-bit integer operations, so now we go to 128-bit mode... */
1338             vfitab_lo        = _mm256_extractf128_si256(vfitab,0x0);
1339             vfitab_hi        = _mm256_extractf128_si256(vfitab,0x1);
1340             vfitab_lo        = _mm_slli_epi32(_mm_add_epi32(vfitab_lo,_mm_slli_epi32(vfitab_lo,1)),2);
1341             vfitab_hi        = _mm_slli_epi32(_mm_add_epi32(vfitab_hi,_mm_slli_epi32(vfitab_hi,1)),2);
1342
1343             /* CUBIC SPLINE TABLE ELECTROSTATICS */
1344             Y                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,0)),
1345                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,0)));
1346             F                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,1)),
1347                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,1)));
1348             G                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,2)),
1349                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,2)));
1350             H                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,3)),
1351                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,3)));
1352             GMX_MM256_HALFTRANSPOSE4_PS(Y,F,G,H);
1353             Heps             = _mm256_mul_ps(vfeps,H);
1354             Fp               = _mm256_add_ps(F,_mm256_mul_ps(vfeps,_mm256_add_ps(G,Heps)));
1355             FF               = _mm256_add_ps(Fp,_mm256_mul_ps(vfeps,_mm256_add_ps(G,_mm256_add_ps(Heps,Heps))));
1356             felec            = _mm256_xor_ps(signbit,_mm256_mul_ps(_mm256_mul_ps(qq00,FF),_mm256_mul_ps(vftabscale,rinv00)));
1357
1358             /* CUBIC SPLINE TABLE DISPERSION */
1359             vfitab_lo        = _mm_add_epi32(vfitab_lo,ifour);
1360             vfitab_hi        = _mm_add_epi32(vfitab_hi,ifour);
1361             Y                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,0)),
1362                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,0)));
1363             F                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,1)),
1364                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,1)));
1365             G                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,2)),
1366                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,2)));
1367             H                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,3)),
1368                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,3)));
1369             GMX_MM256_HALFTRANSPOSE4_PS(Y,F,G,H);
1370             Heps             = _mm256_mul_ps(vfeps,H);
1371             Fp               = _mm256_add_ps(F,_mm256_mul_ps(vfeps,_mm256_add_ps(G,Heps)));
1372             FF               = _mm256_add_ps(Fp,_mm256_mul_ps(vfeps,_mm256_add_ps(G,_mm256_add_ps(Heps,Heps))));
1373             fvdw6            = _mm256_mul_ps(c6_00,FF);
1374
1375             /* CUBIC SPLINE TABLE REPULSION */
1376             vfitab_lo        = _mm_add_epi32(vfitab_lo,ifour);
1377             vfitab_hi        = _mm_add_epi32(vfitab_hi,ifour);
1378             Y                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,0)),
1379                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,0)));
1380             F                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,1)),
1381                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,1)));
1382             G                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,2)),
1383                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,2)));
1384             H                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,3)),
1385                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,3)));
1386             GMX_MM256_HALFTRANSPOSE4_PS(Y,F,G,H);
1387             Heps             = _mm256_mul_ps(vfeps,H);
1388             Fp               = _mm256_add_ps(F,_mm256_mul_ps(vfeps,_mm256_add_ps(G,Heps)));
1389             FF               = _mm256_add_ps(Fp,_mm256_mul_ps(vfeps,_mm256_add_ps(G,_mm256_add_ps(Heps,Heps))));
1390             fvdw12           = _mm256_mul_ps(c12_00,FF);
1391             fvdw             = _mm256_xor_ps(signbit,_mm256_mul_ps(_mm256_add_ps(fvdw6,fvdw12),_mm256_mul_ps(vftabscale,rinv00)));
1392
1393             fscal            = _mm256_add_ps(felec,fvdw);
1394
1395             fscal            = _mm256_andnot_ps(dummy_mask,fscal);
1396
1397             /* Calculate temporary vectorial force */
1398             tx               = _mm256_mul_ps(fscal,dx00);
1399             ty               = _mm256_mul_ps(fscal,dy00);
1400             tz               = _mm256_mul_ps(fscal,dz00);
1401
1402             /* Update vectorial force */
1403             fix0             = _mm256_add_ps(fix0,tx);
1404             fiy0             = _mm256_add_ps(fiy0,ty);
1405             fiz0             = _mm256_add_ps(fiz0,tz);
1406
1407             fjx0             = _mm256_add_ps(fjx0,tx);
1408             fjy0             = _mm256_add_ps(fjy0,ty);
1409             fjz0             = _mm256_add_ps(fjz0,tz);
1410
1411             /**************************
1412              * CALCULATE INTERACTIONS *
1413              **************************/
1414
1415             r10              = _mm256_mul_ps(rsq10,rinv10);
1416             r10              = _mm256_andnot_ps(dummy_mask,r10);
1417
1418             /* Compute parameters for interactions between i and j atoms */
1419             qq10             = _mm256_mul_ps(iq1,jq0);
1420
1421             /* Calculate table index by multiplying r with table scale and truncate to integer */
1422             rt               = _mm256_mul_ps(r10,vftabscale);
1423             vfitab           = _mm256_cvttps_epi32(rt);
1424             vfeps            = _mm256_sub_ps(rt,_mm256_round_ps(rt, _MM_FROUND_FLOOR));
1425             /*         AVX1 does not support 256-bit integer operations, so now we go to 128-bit mode... */
1426             vfitab_lo        = _mm256_extractf128_si256(vfitab,0x0);
1427             vfitab_hi        = _mm256_extractf128_si256(vfitab,0x1);
1428             vfitab_lo        = _mm_slli_epi32(_mm_add_epi32(vfitab_lo,_mm_slli_epi32(vfitab_lo,1)),2);
1429             vfitab_hi        = _mm_slli_epi32(_mm_add_epi32(vfitab_hi,_mm_slli_epi32(vfitab_hi,1)),2);
1430
1431             /* CUBIC SPLINE TABLE ELECTROSTATICS */
1432             Y                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,0)),
1433                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,0)));
1434             F                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,1)),
1435                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,1)));
1436             G                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,2)),
1437                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,2)));
1438             H                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,3)),
1439                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,3)));
1440             GMX_MM256_HALFTRANSPOSE4_PS(Y,F,G,H);
1441             Heps             = _mm256_mul_ps(vfeps,H);
1442             Fp               = _mm256_add_ps(F,_mm256_mul_ps(vfeps,_mm256_add_ps(G,Heps)));
1443             FF               = _mm256_add_ps(Fp,_mm256_mul_ps(vfeps,_mm256_add_ps(G,_mm256_add_ps(Heps,Heps))));
1444             felec            = _mm256_xor_ps(signbit,_mm256_mul_ps(_mm256_mul_ps(qq10,FF),_mm256_mul_ps(vftabscale,rinv10)));
1445
1446             fscal            = felec;
1447
1448             fscal            = _mm256_andnot_ps(dummy_mask,fscal);
1449
1450             /* Calculate temporary vectorial force */
1451             tx               = _mm256_mul_ps(fscal,dx10);
1452             ty               = _mm256_mul_ps(fscal,dy10);
1453             tz               = _mm256_mul_ps(fscal,dz10);
1454
1455             /* Update vectorial force */
1456             fix1             = _mm256_add_ps(fix1,tx);
1457             fiy1             = _mm256_add_ps(fiy1,ty);
1458             fiz1             = _mm256_add_ps(fiz1,tz);
1459
1460             fjx0             = _mm256_add_ps(fjx0,tx);
1461             fjy0             = _mm256_add_ps(fjy0,ty);
1462             fjz0             = _mm256_add_ps(fjz0,tz);
1463
1464             /**************************
1465              * CALCULATE INTERACTIONS *
1466              **************************/
1467
1468             r20              = _mm256_mul_ps(rsq20,rinv20);
1469             r20              = _mm256_andnot_ps(dummy_mask,r20);
1470
1471             /* Compute parameters for interactions between i and j atoms */
1472             qq20             = _mm256_mul_ps(iq2,jq0);
1473
1474             /* Calculate table index by multiplying r with table scale and truncate to integer */
1475             rt               = _mm256_mul_ps(r20,vftabscale);
1476             vfitab           = _mm256_cvttps_epi32(rt);
1477             vfeps            = _mm256_sub_ps(rt,_mm256_round_ps(rt, _MM_FROUND_FLOOR));
1478             /*         AVX1 does not support 256-bit integer operations, so now we go to 128-bit mode... */
1479             vfitab_lo        = _mm256_extractf128_si256(vfitab,0x0);
1480             vfitab_hi        = _mm256_extractf128_si256(vfitab,0x1);
1481             vfitab_lo        = _mm_slli_epi32(_mm_add_epi32(vfitab_lo,_mm_slli_epi32(vfitab_lo,1)),2);
1482             vfitab_hi        = _mm_slli_epi32(_mm_add_epi32(vfitab_hi,_mm_slli_epi32(vfitab_hi,1)),2);
1483
1484             /* CUBIC SPLINE TABLE ELECTROSTATICS */
1485             Y                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,0)),
1486                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,0)));
1487             F                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,1)),
1488                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,1)));
1489             G                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,2)),
1490                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,2)));
1491             H                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,3)),
1492                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,3)));
1493             GMX_MM256_HALFTRANSPOSE4_PS(Y,F,G,H);
1494             Heps             = _mm256_mul_ps(vfeps,H);
1495             Fp               = _mm256_add_ps(F,_mm256_mul_ps(vfeps,_mm256_add_ps(G,Heps)));
1496             FF               = _mm256_add_ps(Fp,_mm256_mul_ps(vfeps,_mm256_add_ps(G,_mm256_add_ps(Heps,Heps))));
1497             felec            = _mm256_xor_ps(signbit,_mm256_mul_ps(_mm256_mul_ps(qq20,FF),_mm256_mul_ps(vftabscale,rinv20)));
1498
1499             fscal            = felec;
1500
1501             fscal            = _mm256_andnot_ps(dummy_mask,fscal);
1502
1503             /* Calculate temporary vectorial force */
1504             tx               = _mm256_mul_ps(fscal,dx20);
1505             ty               = _mm256_mul_ps(fscal,dy20);
1506             tz               = _mm256_mul_ps(fscal,dz20);
1507
1508             /* Update vectorial force */
1509             fix2             = _mm256_add_ps(fix2,tx);
1510             fiy2             = _mm256_add_ps(fiy2,ty);
1511             fiz2             = _mm256_add_ps(fiz2,tz);
1512
1513             fjx0             = _mm256_add_ps(fjx0,tx);
1514             fjy0             = _mm256_add_ps(fjy0,ty);
1515             fjz0             = _mm256_add_ps(fjz0,tz);
1516
1517             fjptrA             = (jnrlistA>=0) ? f+j_coord_offsetA : scratch;
1518             fjptrB             = (jnrlistB>=0) ? f+j_coord_offsetB : scratch;
1519             fjptrC             = (jnrlistC>=0) ? f+j_coord_offsetC : scratch;
1520             fjptrD             = (jnrlistD>=0) ? f+j_coord_offsetD : scratch;
1521             fjptrE             = (jnrlistE>=0) ? f+j_coord_offsetE : scratch;
1522             fjptrF             = (jnrlistF>=0) ? f+j_coord_offsetF : scratch;
1523             fjptrG             = (jnrlistG>=0) ? f+j_coord_offsetG : scratch;
1524             fjptrH             = (jnrlistH>=0) ? f+j_coord_offsetH : scratch;
1525
1526             gmx_mm256_decrement_1rvec_8ptr_swizzle_ps(fjptrA,fjptrB,fjptrC,fjptrD,fjptrE,fjptrF,fjptrG,fjptrH,fjx0,fjy0,fjz0);
1527
1528             /* Inner loop uses 145 flops */
1529         }
1530
1531         /* End of innermost loop */
1532
1533         gmx_mm256_update_iforce_3atom_swizzle_ps(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
1534                                                  f+i_coord_offset,fshift+i_shift_offset);
1535
1536         /* Increment number of inner iterations */
1537         inneriter                  += j_index_end - j_index_start;
1538
1539         /* Outer loop uses 18 flops */
1540     }
1541
1542     /* Increment number of outer iterations */
1543     outeriter        += nri;
1544
1545     /* Update outer/inner flops */
1546
1547     inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3_F,outeriter*18 + inneriter*145);
1548 }