made errors during GPU detection non-fatal
[alexxy/gromacs.git] / src / gmxlib / nonbonded / nb_kernel_avx_256_single / nb_kernel_ElecCoul_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_ElecCoul_VdwCSTab_GeomW3P1_VF_avx_256_single
38  * Electrostatics interaction: Coulomb
39  * VdW interaction:            CubicSplineTable
40  * Geometry:                   Water3-Particle
41  * Calculate force/pot:        PotentialAndForce
42  */
43 void
44 nb_kernel_ElecCoul_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_vdw->data;
118     vftabscale       = _mm256_set1_ps(kernel_data->table_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             rinvsq00         = _mm256_mul_ps(rinv00,rinv00);
228             rinvsq10         = _mm256_mul_ps(rinv10,rinv10);
229             rinvsq20         = _mm256_mul_ps(rinv20,rinv20);
230
231             /* Load parameters for j particles */
232             jq0              = gmx_mm256_load_8real_swizzle_ps(charge+jnrA+0,charge+jnrB+0,
233                                                                  charge+jnrC+0,charge+jnrD+0,
234                                                                  charge+jnrE+0,charge+jnrF+0,
235                                                                  charge+jnrG+0,charge+jnrH+0);
236             vdwjidx0A        = 2*vdwtype[jnrA+0];
237             vdwjidx0B        = 2*vdwtype[jnrB+0];
238             vdwjidx0C        = 2*vdwtype[jnrC+0];
239             vdwjidx0D        = 2*vdwtype[jnrD+0];
240             vdwjidx0E        = 2*vdwtype[jnrE+0];
241             vdwjidx0F        = 2*vdwtype[jnrF+0];
242             vdwjidx0G        = 2*vdwtype[jnrG+0];
243             vdwjidx0H        = 2*vdwtype[jnrH+0];
244
245             fjx0             = _mm256_setzero_ps();
246             fjy0             = _mm256_setzero_ps();
247             fjz0             = _mm256_setzero_ps();
248
249             /**************************
250              * CALCULATE INTERACTIONS *
251              **************************/
252
253             r00              = _mm256_mul_ps(rsq00,rinv00);
254
255             /* Compute parameters for interactions between i and j atoms */
256             qq00             = _mm256_mul_ps(iq0,jq0);
257             gmx_mm256_load_8pair_swizzle_ps(vdwioffsetptr0+vdwjidx0A,
258                                             vdwioffsetptr0+vdwjidx0B,
259                                             vdwioffsetptr0+vdwjidx0C,
260                                             vdwioffsetptr0+vdwjidx0D,
261                                             vdwioffsetptr0+vdwjidx0E,
262                                             vdwioffsetptr0+vdwjidx0F,
263                                             vdwioffsetptr0+vdwjidx0G,
264                                             vdwioffsetptr0+vdwjidx0H,
265                                             &c6_00,&c12_00);
266
267             /* Calculate table index by multiplying r with table scale and truncate to integer */
268             rt               = _mm256_mul_ps(r00,vftabscale);
269             vfitab           = _mm256_cvttps_epi32(rt);
270             vfeps            = _mm256_sub_ps(rt,_mm256_round_ps(rt, _MM_FROUND_FLOOR));
271             /*         AVX1 does not support 256-bit integer operations, so now we go to 128-bit mode... */
272             vfitab_lo        = _mm256_extractf128_si256(vfitab,0x0);
273             vfitab_hi        = _mm256_extractf128_si256(vfitab,0x1);
274             vfitab_lo        = _mm_slli_epi32(vfitab_lo,3);
275             vfitab_hi        = _mm_slli_epi32(vfitab_hi,3);
276
277             /* COULOMB ELECTROSTATICS */
278             velec            = _mm256_mul_ps(qq00,rinv00);
279             felec            = _mm256_mul_ps(velec,rinvsq00);
280
281             /* CUBIC SPLINE TABLE DISPERSION */
282             Y                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,0)),
283                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,0)));
284             F                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,1)),
285                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,1)));
286             G                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,2)),
287                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,2)));
288             H                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,3)),
289                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,3)));
290             GMX_MM256_HALFTRANSPOSE4_PS(Y,F,G,H);
291             Heps             = _mm256_mul_ps(vfeps,H);
292             Fp               = _mm256_add_ps(F,_mm256_mul_ps(vfeps,_mm256_add_ps(G,Heps)));
293             VV               = _mm256_add_ps(Y,_mm256_mul_ps(vfeps,Fp));
294             vvdw6            = _mm256_mul_ps(c6_00,VV);
295             FF               = _mm256_add_ps(Fp,_mm256_mul_ps(vfeps,_mm256_add_ps(G,_mm256_add_ps(Heps,Heps))));
296             fvdw6            = _mm256_mul_ps(c6_00,FF);
297
298             /* CUBIC SPLINE TABLE REPULSION */
299             vfitab_lo        = _mm_add_epi32(vfitab_lo,ifour);
300             vfitab_hi        = _mm_add_epi32(vfitab_hi,ifour);
301             Y                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,0)),
302                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,0)));
303             F                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,1)),
304                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,1)));
305             G                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,2)),
306                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,2)));
307             H                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,3)),
308                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,3)));
309             GMX_MM256_HALFTRANSPOSE4_PS(Y,F,G,H);
310             Heps             = _mm256_mul_ps(vfeps,H);
311             Fp               = _mm256_add_ps(F,_mm256_mul_ps(vfeps,_mm256_add_ps(G,Heps)));
312             VV               = _mm256_add_ps(Y,_mm256_mul_ps(vfeps,Fp));
313             vvdw12           = _mm256_mul_ps(c12_00,VV);
314             FF               = _mm256_add_ps(Fp,_mm256_mul_ps(vfeps,_mm256_add_ps(G,_mm256_add_ps(Heps,Heps))));
315             fvdw12           = _mm256_mul_ps(c12_00,FF);
316             vvdw             = _mm256_add_ps(vvdw12,vvdw6);
317             fvdw             = _mm256_xor_ps(signbit,_mm256_mul_ps(_mm256_add_ps(fvdw6,fvdw12),_mm256_mul_ps(vftabscale,rinv00)));
318
319             /* Update potential sum for this i atom from the interaction with this j atom. */
320             velecsum         = _mm256_add_ps(velecsum,velec);
321             vvdwsum          = _mm256_add_ps(vvdwsum,vvdw);
322
323             fscal            = _mm256_add_ps(felec,fvdw);
324
325             /* Calculate temporary vectorial force */
326             tx               = _mm256_mul_ps(fscal,dx00);
327             ty               = _mm256_mul_ps(fscal,dy00);
328             tz               = _mm256_mul_ps(fscal,dz00);
329
330             /* Update vectorial force */
331             fix0             = _mm256_add_ps(fix0,tx);
332             fiy0             = _mm256_add_ps(fiy0,ty);
333             fiz0             = _mm256_add_ps(fiz0,tz);
334
335             fjx0             = _mm256_add_ps(fjx0,tx);
336             fjy0             = _mm256_add_ps(fjy0,ty);
337             fjz0             = _mm256_add_ps(fjz0,tz);
338
339             /**************************
340              * CALCULATE INTERACTIONS *
341              **************************/
342
343             /* Compute parameters for interactions between i and j atoms */
344             qq10             = _mm256_mul_ps(iq1,jq0);
345
346             /* COULOMB ELECTROSTATICS */
347             velec            = _mm256_mul_ps(qq10,rinv10);
348             felec            = _mm256_mul_ps(velec,rinvsq10);
349
350             /* Update potential sum for this i atom from the interaction with this j atom. */
351             velecsum         = _mm256_add_ps(velecsum,velec);
352
353             fscal            = felec;
354
355             /* Calculate temporary vectorial force */
356             tx               = _mm256_mul_ps(fscal,dx10);
357             ty               = _mm256_mul_ps(fscal,dy10);
358             tz               = _mm256_mul_ps(fscal,dz10);
359
360             /* Update vectorial force */
361             fix1             = _mm256_add_ps(fix1,tx);
362             fiy1             = _mm256_add_ps(fiy1,ty);
363             fiz1             = _mm256_add_ps(fiz1,tz);
364
365             fjx0             = _mm256_add_ps(fjx0,tx);
366             fjy0             = _mm256_add_ps(fjy0,ty);
367             fjz0             = _mm256_add_ps(fjz0,tz);
368
369             /**************************
370              * CALCULATE INTERACTIONS *
371              **************************/
372
373             /* Compute parameters for interactions between i and j atoms */
374             qq20             = _mm256_mul_ps(iq2,jq0);
375
376             /* COULOMB ELECTROSTATICS */
377             velec            = _mm256_mul_ps(qq20,rinv20);
378             felec            = _mm256_mul_ps(velec,rinvsq20);
379
380             /* Update potential sum for this i atom from the interaction with this j atom. */
381             velecsum         = _mm256_add_ps(velecsum,velec);
382
383             fscal            = felec;
384
385             /* Calculate temporary vectorial force */
386             tx               = _mm256_mul_ps(fscal,dx20);
387             ty               = _mm256_mul_ps(fscal,dy20);
388             tz               = _mm256_mul_ps(fscal,dz20);
389
390             /* Update vectorial force */
391             fix2             = _mm256_add_ps(fix2,tx);
392             fiy2             = _mm256_add_ps(fiy2,ty);
393             fiz2             = _mm256_add_ps(fiz2,tz);
394
395             fjx0             = _mm256_add_ps(fjx0,tx);
396             fjy0             = _mm256_add_ps(fjy0,ty);
397             fjz0             = _mm256_add_ps(fjz0,tz);
398
399             fjptrA             = f+j_coord_offsetA;
400             fjptrB             = f+j_coord_offsetB;
401             fjptrC             = f+j_coord_offsetC;
402             fjptrD             = f+j_coord_offsetD;
403             fjptrE             = f+j_coord_offsetE;
404             fjptrF             = f+j_coord_offsetF;
405             fjptrG             = f+j_coord_offsetG;
406             fjptrH             = f+j_coord_offsetH;
407
408             gmx_mm256_decrement_1rvec_8ptr_swizzle_ps(fjptrA,fjptrB,fjptrC,fjptrD,fjptrE,fjptrF,fjptrG,fjptrH,fjx0,fjy0,fjz0);
409
410             /* Inner loop uses 119 flops */
411         }
412
413         if(jidx<j_index_end)
414         {
415
416             /* Get j neighbor index, and coordinate index */
417             jnrlistA         = jjnr[jidx];
418             jnrlistB         = jjnr[jidx+1];
419             jnrlistC         = jjnr[jidx+2];
420             jnrlistD         = jjnr[jidx+3];
421             jnrlistE         = jjnr[jidx+4];
422             jnrlistF         = jjnr[jidx+5];
423             jnrlistG         = jjnr[jidx+6];
424             jnrlistH         = jjnr[jidx+7];
425             /* Sign of each element will be negative for non-real atoms.
426              * This mask will be 0xFFFFFFFF for dummy entries and 0x0 for real ones,
427              * so use it as val = _mm_andnot_ps(mask,val) to clear dummy entries.
428              */
429             dummy_mask = gmx_mm256_set_m128(gmx_mm_castsi128_ps(_mm_cmplt_epi32(_mm_loadu_si128((const __m128i *)(jjnr+jidx+4)),_mm_setzero_si128())),
430                                             gmx_mm_castsi128_ps(_mm_cmplt_epi32(_mm_loadu_si128((const __m128i *)(jjnr+jidx)),_mm_setzero_si128())));
431                                             
432             jnrA       = (jnrlistA>=0) ? jnrlistA : 0;
433             jnrB       = (jnrlistB>=0) ? jnrlistB : 0;
434             jnrC       = (jnrlistC>=0) ? jnrlistC : 0;
435             jnrD       = (jnrlistD>=0) ? jnrlistD : 0;
436             jnrE       = (jnrlistE>=0) ? jnrlistE : 0;
437             jnrF       = (jnrlistF>=0) ? jnrlistF : 0;
438             jnrG       = (jnrlistG>=0) ? jnrlistG : 0;
439             jnrH       = (jnrlistH>=0) ? jnrlistH : 0;
440             j_coord_offsetA  = DIM*jnrA;
441             j_coord_offsetB  = DIM*jnrB;
442             j_coord_offsetC  = DIM*jnrC;
443             j_coord_offsetD  = DIM*jnrD;
444             j_coord_offsetE  = DIM*jnrE;
445             j_coord_offsetF  = DIM*jnrF;
446             j_coord_offsetG  = DIM*jnrG;
447             j_coord_offsetH  = DIM*jnrH;
448
449             /* load j atom coordinates */
450             gmx_mm256_load_1rvec_8ptr_swizzle_ps(x+j_coord_offsetA,x+j_coord_offsetB,
451                                                  x+j_coord_offsetC,x+j_coord_offsetD,
452                                                  x+j_coord_offsetE,x+j_coord_offsetF,
453                                                  x+j_coord_offsetG,x+j_coord_offsetH,
454                                                  &jx0,&jy0,&jz0);
455
456             /* Calculate displacement vector */
457             dx00             = _mm256_sub_ps(ix0,jx0);
458             dy00             = _mm256_sub_ps(iy0,jy0);
459             dz00             = _mm256_sub_ps(iz0,jz0);
460             dx10             = _mm256_sub_ps(ix1,jx0);
461             dy10             = _mm256_sub_ps(iy1,jy0);
462             dz10             = _mm256_sub_ps(iz1,jz0);
463             dx20             = _mm256_sub_ps(ix2,jx0);
464             dy20             = _mm256_sub_ps(iy2,jy0);
465             dz20             = _mm256_sub_ps(iz2,jz0);
466
467             /* Calculate squared distance and things based on it */
468             rsq00            = gmx_mm256_calc_rsq_ps(dx00,dy00,dz00);
469             rsq10            = gmx_mm256_calc_rsq_ps(dx10,dy10,dz10);
470             rsq20            = gmx_mm256_calc_rsq_ps(dx20,dy20,dz20);
471
472             rinv00           = gmx_mm256_invsqrt_ps(rsq00);
473             rinv10           = gmx_mm256_invsqrt_ps(rsq10);
474             rinv20           = gmx_mm256_invsqrt_ps(rsq20);
475
476             rinvsq00         = _mm256_mul_ps(rinv00,rinv00);
477             rinvsq10         = _mm256_mul_ps(rinv10,rinv10);
478             rinvsq20         = _mm256_mul_ps(rinv20,rinv20);
479
480             /* Load parameters for j particles */
481             jq0              = gmx_mm256_load_8real_swizzle_ps(charge+jnrA+0,charge+jnrB+0,
482                                                                  charge+jnrC+0,charge+jnrD+0,
483                                                                  charge+jnrE+0,charge+jnrF+0,
484                                                                  charge+jnrG+0,charge+jnrH+0);
485             vdwjidx0A        = 2*vdwtype[jnrA+0];
486             vdwjidx0B        = 2*vdwtype[jnrB+0];
487             vdwjidx0C        = 2*vdwtype[jnrC+0];
488             vdwjidx0D        = 2*vdwtype[jnrD+0];
489             vdwjidx0E        = 2*vdwtype[jnrE+0];
490             vdwjidx0F        = 2*vdwtype[jnrF+0];
491             vdwjidx0G        = 2*vdwtype[jnrG+0];
492             vdwjidx0H        = 2*vdwtype[jnrH+0];
493
494             fjx0             = _mm256_setzero_ps();
495             fjy0             = _mm256_setzero_ps();
496             fjz0             = _mm256_setzero_ps();
497
498             /**************************
499              * CALCULATE INTERACTIONS *
500              **************************/
501
502             r00              = _mm256_mul_ps(rsq00,rinv00);
503             r00              = _mm256_andnot_ps(dummy_mask,r00);
504
505             /* Compute parameters for interactions between i and j atoms */
506             qq00             = _mm256_mul_ps(iq0,jq0);
507             gmx_mm256_load_8pair_swizzle_ps(vdwioffsetptr0+vdwjidx0A,
508                                             vdwioffsetptr0+vdwjidx0B,
509                                             vdwioffsetptr0+vdwjidx0C,
510                                             vdwioffsetptr0+vdwjidx0D,
511                                             vdwioffsetptr0+vdwjidx0E,
512                                             vdwioffsetptr0+vdwjidx0F,
513                                             vdwioffsetptr0+vdwjidx0G,
514                                             vdwioffsetptr0+vdwjidx0H,
515                                             &c6_00,&c12_00);
516
517             /* Calculate table index by multiplying r with table scale and truncate to integer */
518             rt               = _mm256_mul_ps(r00,vftabscale);
519             vfitab           = _mm256_cvttps_epi32(rt);
520             vfeps            = _mm256_sub_ps(rt,_mm256_round_ps(rt, _MM_FROUND_FLOOR));
521             /*         AVX1 does not support 256-bit integer operations, so now we go to 128-bit mode... */
522             vfitab_lo        = _mm256_extractf128_si256(vfitab,0x0);
523             vfitab_hi        = _mm256_extractf128_si256(vfitab,0x1);
524             vfitab_lo        = _mm_slli_epi32(vfitab_lo,3);
525             vfitab_hi        = _mm_slli_epi32(vfitab_hi,3);
526
527             /* COULOMB ELECTROSTATICS */
528             velec            = _mm256_mul_ps(qq00,rinv00);
529             felec            = _mm256_mul_ps(velec,rinvsq00);
530
531             /* CUBIC SPLINE TABLE DISPERSION */
532             Y                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,0)),
533                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,0)));
534             F                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,1)),
535                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,1)));
536             G                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,2)),
537                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,2)));
538             H                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,3)),
539                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,3)));
540             GMX_MM256_HALFTRANSPOSE4_PS(Y,F,G,H);
541             Heps             = _mm256_mul_ps(vfeps,H);
542             Fp               = _mm256_add_ps(F,_mm256_mul_ps(vfeps,_mm256_add_ps(G,Heps)));
543             VV               = _mm256_add_ps(Y,_mm256_mul_ps(vfeps,Fp));
544             vvdw6            = _mm256_mul_ps(c6_00,VV);
545             FF               = _mm256_add_ps(Fp,_mm256_mul_ps(vfeps,_mm256_add_ps(G,_mm256_add_ps(Heps,Heps))));
546             fvdw6            = _mm256_mul_ps(c6_00,FF);
547
548             /* CUBIC SPLINE TABLE REPULSION */
549             vfitab_lo        = _mm_add_epi32(vfitab_lo,ifour);
550             vfitab_hi        = _mm_add_epi32(vfitab_hi,ifour);
551             Y                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,0)),
552                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,0)));
553             F                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,1)),
554                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,1)));
555             G                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,2)),
556                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,2)));
557             H                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,3)),
558                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,3)));
559             GMX_MM256_HALFTRANSPOSE4_PS(Y,F,G,H);
560             Heps             = _mm256_mul_ps(vfeps,H);
561             Fp               = _mm256_add_ps(F,_mm256_mul_ps(vfeps,_mm256_add_ps(G,Heps)));
562             VV               = _mm256_add_ps(Y,_mm256_mul_ps(vfeps,Fp));
563             vvdw12           = _mm256_mul_ps(c12_00,VV);
564             FF               = _mm256_add_ps(Fp,_mm256_mul_ps(vfeps,_mm256_add_ps(G,_mm256_add_ps(Heps,Heps))));
565             fvdw12           = _mm256_mul_ps(c12_00,FF);
566             vvdw             = _mm256_add_ps(vvdw12,vvdw6);
567             fvdw             = _mm256_xor_ps(signbit,_mm256_mul_ps(_mm256_add_ps(fvdw6,fvdw12),_mm256_mul_ps(vftabscale,rinv00)));
568
569             /* Update potential sum for this i atom from the interaction with this j atom. */
570             velec            = _mm256_andnot_ps(dummy_mask,velec);
571             velecsum         = _mm256_add_ps(velecsum,velec);
572             vvdw             = _mm256_andnot_ps(dummy_mask,vvdw);
573             vvdwsum          = _mm256_add_ps(vvdwsum,vvdw);
574
575             fscal            = _mm256_add_ps(felec,fvdw);
576
577             fscal            = _mm256_andnot_ps(dummy_mask,fscal);
578
579             /* Calculate temporary vectorial force */
580             tx               = _mm256_mul_ps(fscal,dx00);
581             ty               = _mm256_mul_ps(fscal,dy00);
582             tz               = _mm256_mul_ps(fscal,dz00);
583
584             /* Update vectorial force */
585             fix0             = _mm256_add_ps(fix0,tx);
586             fiy0             = _mm256_add_ps(fiy0,ty);
587             fiz0             = _mm256_add_ps(fiz0,tz);
588
589             fjx0             = _mm256_add_ps(fjx0,tx);
590             fjy0             = _mm256_add_ps(fjy0,ty);
591             fjz0             = _mm256_add_ps(fjz0,tz);
592
593             /**************************
594              * CALCULATE INTERACTIONS *
595              **************************/
596
597             /* Compute parameters for interactions between i and j atoms */
598             qq10             = _mm256_mul_ps(iq1,jq0);
599
600             /* COULOMB ELECTROSTATICS */
601             velec            = _mm256_mul_ps(qq10,rinv10);
602             felec            = _mm256_mul_ps(velec,rinvsq10);
603
604             /* Update potential sum for this i atom from the interaction with this j atom. */
605             velec            = _mm256_andnot_ps(dummy_mask,velec);
606             velecsum         = _mm256_add_ps(velecsum,velec);
607
608             fscal            = felec;
609
610             fscal            = _mm256_andnot_ps(dummy_mask,fscal);
611
612             /* Calculate temporary vectorial force */
613             tx               = _mm256_mul_ps(fscal,dx10);
614             ty               = _mm256_mul_ps(fscal,dy10);
615             tz               = _mm256_mul_ps(fscal,dz10);
616
617             /* Update vectorial force */
618             fix1             = _mm256_add_ps(fix1,tx);
619             fiy1             = _mm256_add_ps(fiy1,ty);
620             fiz1             = _mm256_add_ps(fiz1,tz);
621
622             fjx0             = _mm256_add_ps(fjx0,tx);
623             fjy0             = _mm256_add_ps(fjy0,ty);
624             fjz0             = _mm256_add_ps(fjz0,tz);
625
626             /**************************
627              * CALCULATE INTERACTIONS *
628              **************************/
629
630             /* Compute parameters for interactions between i and j atoms */
631             qq20             = _mm256_mul_ps(iq2,jq0);
632
633             /* COULOMB ELECTROSTATICS */
634             velec            = _mm256_mul_ps(qq20,rinv20);
635             felec            = _mm256_mul_ps(velec,rinvsq20);
636
637             /* Update potential sum for this i atom from the interaction with this j atom. */
638             velec            = _mm256_andnot_ps(dummy_mask,velec);
639             velecsum         = _mm256_add_ps(velecsum,velec);
640
641             fscal            = felec;
642
643             fscal            = _mm256_andnot_ps(dummy_mask,fscal);
644
645             /* Calculate temporary vectorial force */
646             tx               = _mm256_mul_ps(fscal,dx20);
647             ty               = _mm256_mul_ps(fscal,dy20);
648             tz               = _mm256_mul_ps(fscal,dz20);
649
650             /* Update vectorial force */
651             fix2             = _mm256_add_ps(fix2,tx);
652             fiy2             = _mm256_add_ps(fiy2,ty);
653             fiz2             = _mm256_add_ps(fiz2,tz);
654
655             fjx0             = _mm256_add_ps(fjx0,tx);
656             fjy0             = _mm256_add_ps(fjy0,ty);
657             fjz0             = _mm256_add_ps(fjz0,tz);
658
659             fjptrA             = (jnrlistA>=0) ? f+j_coord_offsetA : scratch;
660             fjptrB             = (jnrlistB>=0) ? f+j_coord_offsetB : scratch;
661             fjptrC             = (jnrlistC>=0) ? f+j_coord_offsetC : scratch;
662             fjptrD             = (jnrlistD>=0) ? f+j_coord_offsetD : scratch;
663             fjptrE             = (jnrlistE>=0) ? f+j_coord_offsetE : scratch;
664             fjptrF             = (jnrlistF>=0) ? f+j_coord_offsetF : scratch;
665             fjptrG             = (jnrlistG>=0) ? f+j_coord_offsetG : scratch;
666             fjptrH             = (jnrlistH>=0) ? f+j_coord_offsetH : scratch;
667
668             gmx_mm256_decrement_1rvec_8ptr_swizzle_ps(fjptrA,fjptrB,fjptrC,fjptrD,fjptrE,fjptrF,fjptrG,fjptrH,fjx0,fjy0,fjz0);
669
670             /* Inner loop uses 120 flops */
671         }
672
673         /* End of innermost loop */
674
675         gmx_mm256_update_iforce_3atom_swizzle_ps(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
676                                                  f+i_coord_offset,fshift+i_shift_offset);
677
678         ggid                        = gid[iidx];
679         /* Update potential energies */
680         gmx_mm256_update_1pot_ps(velecsum,kernel_data->energygrp_elec+ggid);
681         gmx_mm256_update_1pot_ps(vvdwsum,kernel_data->energygrp_vdw+ggid);
682
683         /* Increment number of inner iterations */
684         inneriter                  += j_index_end - j_index_start;
685
686         /* Outer loop uses 20 flops */
687     }
688
689     /* Increment number of outer iterations */
690     outeriter        += nri;
691
692     /* Update outer/inner flops */
693
694     inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3_VF,outeriter*20 + inneriter*120);
695 }
696 /*
697  * Gromacs nonbonded kernel:   nb_kernel_ElecCoul_VdwCSTab_GeomW3P1_F_avx_256_single
698  * Electrostatics interaction: Coulomb
699  * VdW interaction:            CubicSplineTable
700  * Geometry:                   Water3-Particle
701  * Calculate force/pot:        Force
702  */
703 void
704 nb_kernel_ElecCoul_VdwCSTab_GeomW3P1_F_avx_256_single
705                     (t_nblist * gmx_restrict                nlist,
706                      rvec * gmx_restrict                    xx,
707                      rvec * gmx_restrict                    ff,
708                      t_forcerec * gmx_restrict              fr,
709                      t_mdatoms * gmx_restrict               mdatoms,
710                      nb_kernel_data_t * gmx_restrict        kernel_data,
711                      t_nrnb * gmx_restrict                  nrnb)
712 {
713     /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or 
714      * just 0 for non-waters.
715      * Suffixes A,B,C,D,E,F,G,H refer to j loop unrolling done with AVX, e.g. for the eight different
716      * jnr indices corresponding to data put in the four positions in the SIMD register.
717      */
718     int              i_shift_offset,i_coord_offset,outeriter,inneriter;
719     int              j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
720     int              jnrA,jnrB,jnrC,jnrD;
721     int              jnrE,jnrF,jnrG,jnrH;
722     int              jnrlistA,jnrlistB,jnrlistC,jnrlistD;
723     int              jnrlistE,jnrlistF,jnrlistG,jnrlistH;
724     int              j_coord_offsetA,j_coord_offsetB,j_coord_offsetC,j_coord_offsetD;
725     int              j_coord_offsetE,j_coord_offsetF,j_coord_offsetG,j_coord_offsetH;
726     int              *iinr,*jindex,*jjnr,*shiftidx,*gid;
727     real             rcutoff_scalar;
728     real             *shiftvec,*fshift,*x,*f;
729     real             *fjptrA,*fjptrB,*fjptrC,*fjptrD,*fjptrE,*fjptrF,*fjptrG,*fjptrH;
730     real             scratch[4*DIM];
731     __m256           tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
732     real *           vdwioffsetptr0;
733     __m256           ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
734     real *           vdwioffsetptr1;
735     __m256           ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
736     real *           vdwioffsetptr2;
737     __m256           ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
738     int              vdwjidx0A,vdwjidx0B,vdwjidx0C,vdwjidx0D,vdwjidx0E,vdwjidx0F,vdwjidx0G,vdwjidx0H;
739     __m256           jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
740     __m256           dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
741     __m256           dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
742     __m256           dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
743     __m256           velec,felec,velecsum,facel,crf,krf,krf2;
744     real             *charge;
745     int              nvdwtype;
746     __m256           rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
747     int              *vdwtype;
748     real             *vdwparam;
749     __m256           one_sixth   = _mm256_set1_ps(1.0/6.0);
750     __m256           one_twelfth = _mm256_set1_ps(1.0/12.0);
751     __m256i          vfitab;
752     __m128i          vfitab_lo,vfitab_hi;
753     __m128i          ifour       = _mm_set1_epi32(4);
754     __m256           rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
755     real             *vftab;
756     __m256           dummy_mask,cutoff_mask;
757     __m256           signbit = _mm256_castsi256_ps( _mm256_set1_epi32(0x80000000) );
758     __m256           one     = _mm256_set1_ps(1.0);
759     __m256           two     = _mm256_set1_ps(2.0);
760     x                = xx[0];
761     f                = ff[0];
762
763     nri              = nlist->nri;
764     iinr             = nlist->iinr;
765     jindex           = nlist->jindex;
766     jjnr             = nlist->jjnr;
767     shiftidx         = nlist->shift;
768     gid              = nlist->gid;
769     shiftvec         = fr->shift_vec[0];
770     fshift           = fr->fshift[0];
771     facel            = _mm256_set1_ps(fr->epsfac);
772     charge           = mdatoms->chargeA;
773     nvdwtype         = fr->ntype;
774     vdwparam         = fr->nbfp;
775     vdwtype          = mdatoms->typeA;
776
777     vftab            = kernel_data->table_vdw->data;
778     vftabscale       = _mm256_set1_ps(kernel_data->table_vdw->scale);
779
780     /* Setup water-specific parameters */
781     inr              = nlist->iinr[0];
782     iq0              = _mm256_mul_ps(facel,_mm256_set1_ps(charge[inr+0]));
783     iq1              = _mm256_mul_ps(facel,_mm256_set1_ps(charge[inr+1]));
784     iq2              = _mm256_mul_ps(facel,_mm256_set1_ps(charge[inr+2]));
785     vdwioffsetptr0   = vdwparam+2*nvdwtype*vdwtype[inr+0];
786
787     /* Avoid stupid compiler warnings */
788     jnrA = jnrB = jnrC = jnrD = jnrE = jnrF = jnrG = jnrH = 0;
789     j_coord_offsetA = 0;
790     j_coord_offsetB = 0;
791     j_coord_offsetC = 0;
792     j_coord_offsetD = 0;
793     j_coord_offsetE = 0;
794     j_coord_offsetF = 0;
795     j_coord_offsetG = 0;
796     j_coord_offsetH = 0;
797
798     outeriter        = 0;
799     inneriter        = 0;
800
801     for(iidx=0;iidx<4*DIM;iidx++)
802     {
803         scratch[iidx] = 0.0;
804     }
805
806     /* Start outer loop over neighborlists */
807     for(iidx=0; iidx<nri; iidx++)
808     {
809         /* Load shift vector for this list */
810         i_shift_offset   = DIM*shiftidx[iidx];
811
812         /* Load limits for loop over neighbors */
813         j_index_start    = jindex[iidx];
814         j_index_end      = jindex[iidx+1];
815
816         /* Get outer coordinate index */
817         inr              = iinr[iidx];
818         i_coord_offset   = DIM*inr;
819
820         /* Load i particle coords and add shift vector */
821         gmx_mm256_load_shift_and_3rvec_broadcast_ps(shiftvec+i_shift_offset,x+i_coord_offset,
822                                                     &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
823
824         fix0             = _mm256_setzero_ps();
825         fiy0             = _mm256_setzero_ps();
826         fiz0             = _mm256_setzero_ps();
827         fix1             = _mm256_setzero_ps();
828         fiy1             = _mm256_setzero_ps();
829         fiz1             = _mm256_setzero_ps();
830         fix2             = _mm256_setzero_ps();
831         fiy2             = _mm256_setzero_ps();
832         fiz2             = _mm256_setzero_ps();
833
834         /* Start inner kernel loop */
835         for(jidx=j_index_start; jidx<j_index_end && jjnr[jidx+7]>=0; jidx+=8)
836         {
837
838             /* Get j neighbor index, and coordinate index */
839             jnrA             = jjnr[jidx];
840             jnrB             = jjnr[jidx+1];
841             jnrC             = jjnr[jidx+2];
842             jnrD             = jjnr[jidx+3];
843             jnrE             = jjnr[jidx+4];
844             jnrF             = jjnr[jidx+5];
845             jnrG             = jjnr[jidx+6];
846             jnrH             = jjnr[jidx+7];
847             j_coord_offsetA  = DIM*jnrA;
848             j_coord_offsetB  = DIM*jnrB;
849             j_coord_offsetC  = DIM*jnrC;
850             j_coord_offsetD  = DIM*jnrD;
851             j_coord_offsetE  = DIM*jnrE;
852             j_coord_offsetF  = DIM*jnrF;
853             j_coord_offsetG  = DIM*jnrG;
854             j_coord_offsetH  = DIM*jnrH;
855
856             /* load j atom coordinates */
857             gmx_mm256_load_1rvec_8ptr_swizzle_ps(x+j_coord_offsetA,x+j_coord_offsetB,
858                                                  x+j_coord_offsetC,x+j_coord_offsetD,
859                                                  x+j_coord_offsetE,x+j_coord_offsetF,
860                                                  x+j_coord_offsetG,x+j_coord_offsetH,
861                                                  &jx0,&jy0,&jz0);
862
863             /* Calculate displacement vector */
864             dx00             = _mm256_sub_ps(ix0,jx0);
865             dy00             = _mm256_sub_ps(iy0,jy0);
866             dz00             = _mm256_sub_ps(iz0,jz0);
867             dx10             = _mm256_sub_ps(ix1,jx0);
868             dy10             = _mm256_sub_ps(iy1,jy0);
869             dz10             = _mm256_sub_ps(iz1,jz0);
870             dx20             = _mm256_sub_ps(ix2,jx0);
871             dy20             = _mm256_sub_ps(iy2,jy0);
872             dz20             = _mm256_sub_ps(iz2,jz0);
873
874             /* Calculate squared distance and things based on it */
875             rsq00            = gmx_mm256_calc_rsq_ps(dx00,dy00,dz00);
876             rsq10            = gmx_mm256_calc_rsq_ps(dx10,dy10,dz10);
877             rsq20            = gmx_mm256_calc_rsq_ps(dx20,dy20,dz20);
878
879             rinv00           = gmx_mm256_invsqrt_ps(rsq00);
880             rinv10           = gmx_mm256_invsqrt_ps(rsq10);
881             rinv20           = gmx_mm256_invsqrt_ps(rsq20);
882
883             rinvsq00         = _mm256_mul_ps(rinv00,rinv00);
884             rinvsq10         = _mm256_mul_ps(rinv10,rinv10);
885             rinvsq20         = _mm256_mul_ps(rinv20,rinv20);
886
887             /* Load parameters for j particles */
888             jq0              = gmx_mm256_load_8real_swizzle_ps(charge+jnrA+0,charge+jnrB+0,
889                                                                  charge+jnrC+0,charge+jnrD+0,
890                                                                  charge+jnrE+0,charge+jnrF+0,
891                                                                  charge+jnrG+0,charge+jnrH+0);
892             vdwjidx0A        = 2*vdwtype[jnrA+0];
893             vdwjidx0B        = 2*vdwtype[jnrB+0];
894             vdwjidx0C        = 2*vdwtype[jnrC+0];
895             vdwjidx0D        = 2*vdwtype[jnrD+0];
896             vdwjidx0E        = 2*vdwtype[jnrE+0];
897             vdwjidx0F        = 2*vdwtype[jnrF+0];
898             vdwjidx0G        = 2*vdwtype[jnrG+0];
899             vdwjidx0H        = 2*vdwtype[jnrH+0];
900
901             fjx0             = _mm256_setzero_ps();
902             fjy0             = _mm256_setzero_ps();
903             fjz0             = _mm256_setzero_ps();
904
905             /**************************
906              * CALCULATE INTERACTIONS *
907              **************************/
908
909             r00              = _mm256_mul_ps(rsq00,rinv00);
910
911             /* Compute parameters for interactions between i and j atoms */
912             qq00             = _mm256_mul_ps(iq0,jq0);
913             gmx_mm256_load_8pair_swizzle_ps(vdwioffsetptr0+vdwjidx0A,
914                                             vdwioffsetptr0+vdwjidx0B,
915                                             vdwioffsetptr0+vdwjidx0C,
916                                             vdwioffsetptr0+vdwjidx0D,
917                                             vdwioffsetptr0+vdwjidx0E,
918                                             vdwioffsetptr0+vdwjidx0F,
919                                             vdwioffsetptr0+vdwjidx0G,
920                                             vdwioffsetptr0+vdwjidx0H,
921                                             &c6_00,&c12_00);
922
923             /* Calculate table index by multiplying r with table scale and truncate to integer */
924             rt               = _mm256_mul_ps(r00,vftabscale);
925             vfitab           = _mm256_cvttps_epi32(rt);
926             vfeps            = _mm256_sub_ps(rt,_mm256_round_ps(rt, _MM_FROUND_FLOOR));
927             /*         AVX1 does not support 256-bit integer operations, so now we go to 128-bit mode... */
928             vfitab_lo        = _mm256_extractf128_si256(vfitab,0x0);
929             vfitab_hi        = _mm256_extractf128_si256(vfitab,0x1);
930             vfitab_lo        = _mm_slli_epi32(vfitab_lo,3);
931             vfitab_hi        = _mm_slli_epi32(vfitab_hi,3);
932
933             /* COULOMB ELECTROSTATICS */
934             velec            = _mm256_mul_ps(qq00,rinv00);
935             felec            = _mm256_mul_ps(velec,rinvsq00);
936
937             /* CUBIC SPLINE TABLE DISPERSION */
938             Y                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,0)),
939                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,0)));
940             F                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,1)),
941                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,1)));
942             G                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,2)),
943                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,2)));
944             H                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,3)),
945                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,3)));
946             GMX_MM256_HALFTRANSPOSE4_PS(Y,F,G,H);
947             Heps             = _mm256_mul_ps(vfeps,H);
948             Fp               = _mm256_add_ps(F,_mm256_mul_ps(vfeps,_mm256_add_ps(G,Heps)));
949             FF               = _mm256_add_ps(Fp,_mm256_mul_ps(vfeps,_mm256_add_ps(G,_mm256_add_ps(Heps,Heps))));
950             fvdw6            = _mm256_mul_ps(c6_00,FF);
951
952             /* CUBIC SPLINE TABLE REPULSION */
953             vfitab_lo        = _mm_add_epi32(vfitab_lo,ifour);
954             vfitab_hi        = _mm_add_epi32(vfitab_hi,ifour);
955             Y                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,0)),
956                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,0)));
957             F                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,1)),
958                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,1)));
959             G                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,2)),
960                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,2)));
961             H                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,3)),
962                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,3)));
963             GMX_MM256_HALFTRANSPOSE4_PS(Y,F,G,H);
964             Heps             = _mm256_mul_ps(vfeps,H);
965             Fp               = _mm256_add_ps(F,_mm256_mul_ps(vfeps,_mm256_add_ps(G,Heps)));
966             FF               = _mm256_add_ps(Fp,_mm256_mul_ps(vfeps,_mm256_add_ps(G,_mm256_add_ps(Heps,Heps))));
967             fvdw12           = _mm256_mul_ps(c12_00,FF);
968             fvdw             = _mm256_xor_ps(signbit,_mm256_mul_ps(_mm256_add_ps(fvdw6,fvdw12),_mm256_mul_ps(vftabscale,rinv00)));
969
970             fscal            = _mm256_add_ps(felec,fvdw);
971
972             /* Calculate temporary vectorial force */
973             tx               = _mm256_mul_ps(fscal,dx00);
974             ty               = _mm256_mul_ps(fscal,dy00);
975             tz               = _mm256_mul_ps(fscal,dz00);
976
977             /* Update vectorial force */
978             fix0             = _mm256_add_ps(fix0,tx);
979             fiy0             = _mm256_add_ps(fiy0,ty);
980             fiz0             = _mm256_add_ps(fiz0,tz);
981
982             fjx0             = _mm256_add_ps(fjx0,tx);
983             fjy0             = _mm256_add_ps(fjy0,ty);
984             fjz0             = _mm256_add_ps(fjz0,tz);
985
986             /**************************
987              * CALCULATE INTERACTIONS *
988              **************************/
989
990             /* Compute parameters for interactions between i and j atoms */
991             qq10             = _mm256_mul_ps(iq1,jq0);
992
993             /* COULOMB ELECTROSTATICS */
994             velec            = _mm256_mul_ps(qq10,rinv10);
995             felec            = _mm256_mul_ps(velec,rinvsq10);
996
997             fscal            = felec;
998
999             /* Calculate temporary vectorial force */
1000             tx               = _mm256_mul_ps(fscal,dx10);
1001             ty               = _mm256_mul_ps(fscal,dy10);
1002             tz               = _mm256_mul_ps(fscal,dz10);
1003
1004             /* Update vectorial force */
1005             fix1             = _mm256_add_ps(fix1,tx);
1006             fiy1             = _mm256_add_ps(fiy1,ty);
1007             fiz1             = _mm256_add_ps(fiz1,tz);
1008
1009             fjx0             = _mm256_add_ps(fjx0,tx);
1010             fjy0             = _mm256_add_ps(fjy0,ty);
1011             fjz0             = _mm256_add_ps(fjz0,tz);
1012
1013             /**************************
1014              * CALCULATE INTERACTIONS *
1015              **************************/
1016
1017             /* Compute parameters for interactions between i and j atoms */
1018             qq20             = _mm256_mul_ps(iq2,jq0);
1019
1020             /* COULOMB ELECTROSTATICS */
1021             velec            = _mm256_mul_ps(qq20,rinv20);
1022             felec            = _mm256_mul_ps(velec,rinvsq20);
1023
1024             fscal            = felec;
1025
1026             /* Calculate temporary vectorial force */
1027             tx               = _mm256_mul_ps(fscal,dx20);
1028             ty               = _mm256_mul_ps(fscal,dy20);
1029             tz               = _mm256_mul_ps(fscal,dz20);
1030
1031             /* Update vectorial force */
1032             fix2             = _mm256_add_ps(fix2,tx);
1033             fiy2             = _mm256_add_ps(fiy2,ty);
1034             fiz2             = _mm256_add_ps(fiz2,tz);
1035
1036             fjx0             = _mm256_add_ps(fjx0,tx);
1037             fjy0             = _mm256_add_ps(fjy0,ty);
1038             fjz0             = _mm256_add_ps(fjz0,tz);
1039
1040             fjptrA             = f+j_coord_offsetA;
1041             fjptrB             = f+j_coord_offsetB;
1042             fjptrC             = f+j_coord_offsetC;
1043             fjptrD             = f+j_coord_offsetD;
1044             fjptrE             = f+j_coord_offsetE;
1045             fjptrF             = f+j_coord_offsetF;
1046             fjptrG             = f+j_coord_offsetG;
1047             fjptrH             = f+j_coord_offsetH;
1048
1049             gmx_mm256_decrement_1rvec_8ptr_swizzle_ps(fjptrA,fjptrB,fjptrC,fjptrD,fjptrE,fjptrF,fjptrG,fjptrH,fjx0,fjy0,fjz0);
1050
1051             /* Inner loop uses 108 flops */
1052         }
1053
1054         if(jidx<j_index_end)
1055         {
1056
1057             /* Get j neighbor index, and coordinate index */
1058             jnrlistA         = jjnr[jidx];
1059             jnrlistB         = jjnr[jidx+1];
1060             jnrlistC         = jjnr[jidx+2];
1061             jnrlistD         = jjnr[jidx+3];
1062             jnrlistE         = jjnr[jidx+4];
1063             jnrlistF         = jjnr[jidx+5];
1064             jnrlistG         = jjnr[jidx+6];
1065             jnrlistH         = jjnr[jidx+7];
1066             /* Sign of each element will be negative for non-real atoms.
1067              * This mask will be 0xFFFFFFFF for dummy entries and 0x0 for real ones,
1068              * so use it as val = _mm_andnot_ps(mask,val) to clear dummy entries.
1069              */
1070             dummy_mask = gmx_mm256_set_m128(gmx_mm_castsi128_ps(_mm_cmplt_epi32(_mm_loadu_si128((const __m128i *)(jjnr+jidx+4)),_mm_setzero_si128())),
1071                                             gmx_mm_castsi128_ps(_mm_cmplt_epi32(_mm_loadu_si128((const __m128i *)(jjnr+jidx)),_mm_setzero_si128())));
1072                                             
1073             jnrA       = (jnrlistA>=0) ? jnrlistA : 0;
1074             jnrB       = (jnrlistB>=0) ? jnrlistB : 0;
1075             jnrC       = (jnrlistC>=0) ? jnrlistC : 0;
1076             jnrD       = (jnrlistD>=0) ? jnrlistD : 0;
1077             jnrE       = (jnrlistE>=0) ? jnrlistE : 0;
1078             jnrF       = (jnrlistF>=0) ? jnrlistF : 0;
1079             jnrG       = (jnrlistG>=0) ? jnrlistG : 0;
1080             jnrH       = (jnrlistH>=0) ? jnrlistH : 0;
1081             j_coord_offsetA  = DIM*jnrA;
1082             j_coord_offsetB  = DIM*jnrB;
1083             j_coord_offsetC  = DIM*jnrC;
1084             j_coord_offsetD  = DIM*jnrD;
1085             j_coord_offsetE  = DIM*jnrE;
1086             j_coord_offsetF  = DIM*jnrF;
1087             j_coord_offsetG  = DIM*jnrG;
1088             j_coord_offsetH  = DIM*jnrH;
1089
1090             /* load j atom coordinates */
1091             gmx_mm256_load_1rvec_8ptr_swizzle_ps(x+j_coord_offsetA,x+j_coord_offsetB,
1092                                                  x+j_coord_offsetC,x+j_coord_offsetD,
1093                                                  x+j_coord_offsetE,x+j_coord_offsetF,
1094                                                  x+j_coord_offsetG,x+j_coord_offsetH,
1095                                                  &jx0,&jy0,&jz0);
1096
1097             /* Calculate displacement vector */
1098             dx00             = _mm256_sub_ps(ix0,jx0);
1099             dy00             = _mm256_sub_ps(iy0,jy0);
1100             dz00             = _mm256_sub_ps(iz0,jz0);
1101             dx10             = _mm256_sub_ps(ix1,jx0);
1102             dy10             = _mm256_sub_ps(iy1,jy0);
1103             dz10             = _mm256_sub_ps(iz1,jz0);
1104             dx20             = _mm256_sub_ps(ix2,jx0);
1105             dy20             = _mm256_sub_ps(iy2,jy0);
1106             dz20             = _mm256_sub_ps(iz2,jz0);
1107
1108             /* Calculate squared distance and things based on it */
1109             rsq00            = gmx_mm256_calc_rsq_ps(dx00,dy00,dz00);
1110             rsq10            = gmx_mm256_calc_rsq_ps(dx10,dy10,dz10);
1111             rsq20            = gmx_mm256_calc_rsq_ps(dx20,dy20,dz20);
1112
1113             rinv00           = gmx_mm256_invsqrt_ps(rsq00);
1114             rinv10           = gmx_mm256_invsqrt_ps(rsq10);
1115             rinv20           = gmx_mm256_invsqrt_ps(rsq20);
1116
1117             rinvsq00         = _mm256_mul_ps(rinv00,rinv00);
1118             rinvsq10         = _mm256_mul_ps(rinv10,rinv10);
1119             rinvsq20         = _mm256_mul_ps(rinv20,rinv20);
1120
1121             /* Load parameters for j particles */
1122             jq0              = gmx_mm256_load_8real_swizzle_ps(charge+jnrA+0,charge+jnrB+0,
1123                                                                  charge+jnrC+0,charge+jnrD+0,
1124                                                                  charge+jnrE+0,charge+jnrF+0,
1125                                                                  charge+jnrG+0,charge+jnrH+0);
1126             vdwjidx0A        = 2*vdwtype[jnrA+0];
1127             vdwjidx0B        = 2*vdwtype[jnrB+0];
1128             vdwjidx0C        = 2*vdwtype[jnrC+0];
1129             vdwjidx0D        = 2*vdwtype[jnrD+0];
1130             vdwjidx0E        = 2*vdwtype[jnrE+0];
1131             vdwjidx0F        = 2*vdwtype[jnrF+0];
1132             vdwjidx0G        = 2*vdwtype[jnrG+0];
1133             vdwjidx0H        = 2*vdwtype[jnrH+0];
1134
1135             fjx0             = _mm256_setzero_ps();
1136             fjy0             = _mm256_setzero_ps();
1137             fjz0             = _mm256_setzero_ps();
1138
1139             /**************************
1140              * CALCULATE INTERACTIONS *
1141              **************************/
1142
1143             r00              = _mm256_mul_ps(rsq00,rinv00);
1144             r00              = _mm256_andnot_ps(dummy_mask,r00);
1145
1146             /* Compute parameters for interactions between i and j atoms */
1147             qq00             = _mm256_mul_ps(iq0,jq0);
1148             gmx_mm256_load_8pair_swizzle_ps(vdwioffsetptr0+vdwjidx0A,
1149                                             vdwioffsetptr0+vdwjidx0B,
1150                                             vdwioffsetptr0+vdwjidx0C,
1151                                             vdwioffsetptr0+vdwjidx0D,
1152                                             vdwioffsetptr0+vdwjidx0E,
1153                                             vdwioffsetptr0+vdwjidx0F,
1154                                             vdwioffsetptr0+vdwjidx0G,
1155                                             vdwioffsetptr0+vdwjidx0H,
1156                                             &c6_00,&c12_00);
1157
1158             /* Calculate table index by multiplying r with table scale and truncate to integer */
1159             rt               = _mm256_mul_ps(r00,vftabscale);
1160             vfitab           = _mm256_cvttps_epi32(rt);
1161             vfeps            = _mm256_sub_ps(rt,_mm256_round_ps(rt, _MM_FROUND_FLOOR));
1162             /*         AVX1 does not support 256-bit integer operations, so now we go to 128-bit mode... */
1163             vfitab_lo        = _mm256_extractf128_si256(vfitab,0x0);
1164             vfitab_hi        = _mm256_extractf128_si256(vfitab,0x1);
1165             vfitab_lo        = _mm_slli_epi32(vfitab_lo,3);
1166             vfitab_hi        = _mm_slli_epi32(vfitab_hi,3);
1167
1168             /* COULOMB ELECTROSTATICS */
1169             velec            = _mm256_mul_ps(qq00,rinv00);
1170             felec            = _mm256_mul_ps(velec,rinvsq00);
1171
1172             /* CUBIC SPLINE TABLE DISPERSION */
1173             Y                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,0)),
1174                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,0)));
1175             F                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,1)),
1176                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,1)));
1177             G                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,2)),
1178                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,2)));
1179             H                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,3)),
1180                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,3)));
1181             GMX_MM256_HALFTRANSPOSE4_PS(Y,F,G,H);
1182             Heps             = _mm256_mul_ps(vfeps,H);
1183             Fp               = _mm256_add_ps(F,_mm256_mul_ps(vfeps,_mm256_add_ps(G,Heps)));
1184             FF               = _mm256_add_ps(Fp,_mm256_mul_ps(vfeps,_mm256_add_ps(G,_mm256_add_ps(Heps,Heps))));
1185             fvdw6            = _mm256_mul_ps(c6_00,FF);
1186
1187             /* CUBIC SPLINE TABLE REPULSION */
1188             vfitab_lo        = _mm_add_epi32(vfitab_lo,ifour);
1189             vfitab_hi        = _mm_add_epi32(vfitab_hi,ifour);
1190             Y                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,0)),
1191                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,0)));
1192             F                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,1)),
1193                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,1)));
1194             G                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,2)),
1195                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,2)));
1196             H                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,3)),
1197                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,3)));
1198             GMX_MM256_HALFTRANSPOSE4_PS(Y,F,G,H);
1199             Heps             = _mm256_mul_ps(vfeps,H);
1200             Fp               = _mm256_add_ps(F,_mm256_mul_ps(vfeps,_mm256_add_ps(G,Heps)));
1201             FF               = _mm256_add_ps(Fp,_mm256_mul_ps(vfeps,_mm256_add_ps(G,_mm256_add_ps(Heps,Heps))));
1202             fvdw12           = _mm256_mul_ps(c12_00,FF);
1203             fvdw             = _mm256_xor_ps(signbit,_mm256_mul_ps(_mm256_add_ps(fvdw6,fvdw12),_mm256_mul_ps(vftabscale,rinv00)));
1204
1205             fscal            = _mm256_add_ps(felec,fvdw);
1206
1207             fscal            = _mm256_andnot_ps(dummy_mask,fscal);
1208
1209             /* Calculate temporary vectorial force */
1210             tx               = _mm256_mul_ps(fscal,dx00);
1211             ty               = _mm256_mul_ps(fscal,dy00);
1212             tz               = _mm256_mul_ps(fscal,dz00);
1213
1214             /* Update vectorial force */
1215             fix0             = _mm256_add_ps(fix0,tx);
1216             fiy0             = _mm256_add_ps(fiy0,ty);
1217             fiz0             = _mm256_add_ps(fiz0,tz);
1218
1219             fjx0             = _mm256_add_ps(fjx0,tx);
1220             fjy0             = _mm256_add_ps(fjy0,ty);
1221             fjz0             = _mm256_add_ps(fjz0,tz);
1222
1223             /**************************
1224              * CALCULATE INTERACTIONS *
1225              **************************/
1226
1227             /* Compute parameters for interactions between i and j atoms */
1228             qq10             = _mm256_mul_ps(iq1,jq0);
1229
1230             /* COULOMB ELECTROSTATICS */
1231             velec            = _mm256_mul_ps(qq10,rinv10);
1232             felec            = _mm256_mul_ps(velec,rinvsq10);
1233
1234             fscal            = felec;
1235
1236             fscal            = _mm256_andnot_ps(dummy_mask,fscal);
1237
1238             /* Calculate temporary vectorial force */
1239             tx               = _mm256_mul_ps(fscal,dx10);
1240             ty               = _mm256_mul_ps(fscal,dy10);
1241             tz               = _mm256_mul_ps(fscal,dz10);
1242
1243             /* Update vectorial force */
1244             fix1             = _mm256_add_ps(fix1,tx);
1245             fiy1             = _mm256_add_ps(fiy1,ty);
1246             fiz1             = _mm256_add_ps(fiz1,tz);
1247
1248             fjx0             = _mm256_add_ps(fjx0,tx);
1249             fjy0             = _mm256_add_ps(fjy0,ty);
1250             fjz0             = _mm256_add_ps(fjz0,tz);
1251
1252             /**************************
1253              * CALCULATE INTERACTIONS *
1254              **************************/
1255
1256             /* Compute parameters for interactions between i and j atoms */
1257             qq20             = _mm256_mul_ps(iq2,jq0);
1258
1259             /* COULOMB ELECTROSTATICS */
1260             velec            = _mm256_mul_ps(qq20,rinv20);
1261             felec            = _mm256_mul_ps(velec,rinvsq20);
1262
1263             fscal            = felec;
1264
1265             fscal            = _mm256_andnot_ps(dummy_mask,fscal);
1266
1267             /* Calculate temporary vectorial force */
1268             tx               = _mm256_mul_ps(fscal,dx20);
1269             ty               = _mm256_mul_ps(fscal,dy20);
1270             tz               = _mm256_mul_ps(fscal,dz20);
1271
1272             /* Update vectorial force */
1273             fix2             = _mm256_add_ps(fix2,tx);
1274             fiy2             = _mm256_add_ps(fiy2,ty);
1275             fiz2             = _mm256_add_ps(fiz2,tz);
1276
1277             fjx0             = _mm256_add_ps(fjx0,tx);
1278             fjy0             = _mm256_add_ps(fjy0,ty);
1279             fjz0             = _mm256_add_ps(fjz0,tz);
1280
1281             fjptrA             = (jnrlistA>=0) ? f+j_coord_offsetA : scratch;
1282             fjptrB             = (jnrlistB>=0) ? f+j_coord_offsetB : scratch;
1283             fjptrC             = (jnrlistC>=0) ? f+j_coord_offsetC : scratch;
1284             fjptrD             = (jnrlistD>=0) ? f+j_coord_offsetD : scratch;
1285             fjptrE             = (jnrlistE>=0) ? f+j_coord_offsetE : scratch;
1286             fjptrF             = (jnrlistF>=0) ? f+j_coord_offsetF : scratch;
1287             fjptrG             = (jnrlistG>=0) ? f+j_coord_offsetG : scratch;
1288             fjptrH             = (jnrlistH>=0) ? f+j_coord_offsetH : scratch;
1289
1290             gmx_mm256_decrement_1rvec_8ptr_swizzle_ps(fjptrA,fjptrB,fjptrC,fjptrD,fjptrE,fjptrF,fjptrG,fjptrH,fjx0,fjy0,fjz0);
1291
1292             /* Inner loop uses 109 flops */
1293         }
1294
1295         /* End of innermost loop */
1296
1297         gmx_mm256_update_iforce_3atom_swizzle_ps(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
1298                                                  f+i_coord_offset,fshift+i_shift_offset);
1299
1300         /* Increment number of inner iterations */
1301         inneriter                  += j_index_end - j_index_start;
1302
1303         /* Outer loop uses 18 flops */
1304     }
1305
1306     /* Increment number of outer iterations */
1307     outeriter        += nri;
1308
1309     /* Update outer/inner flops */
1310
1311     inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3_F,outeriter*18 + inneriter*109);
1312 }