2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 2012,2013,2014, by the GROMACS development team, led by
5 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
6 * and including many others, as listed in the AUTHORS file in the
7 * top-level source directory and at http://www.gromacs.org.
9 * GROMACS is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1
12 * of the License, or (at your option) any later version.
14 * GROMACS is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with GROMACS; if not, see
21 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 * If you want to redistribute modifications to GROMACS, please
25 * consider that scientific software is very special. Version
26 * control is crucial - bugs must be traceable. We will be happy to
27 * consider code for inclusion in the official distribution, but
28 * derived work must not be called official GROMACS. Details are found
29 * in the README & COPYING files - if they are missing, get the
30 * official version at http://www.gromacs.org.
32 * To help us fund GROMACS development, we humbly ask that you cite
33 * the research papers on the package. Check out http://www.gromacs.org.
36 * Note: this file was generated by the GROMACS avx_256_single kernel generator.
44 #include "../nb_kernel.h"
45 #include "types/simple.h"
46 #include "gromacs/math/vec.h"
49 #include "gromacs/simd/math_x86_avx_256_single.h"
50 #include "kernelutil_x86_avx_256_single.h"
53 * Gromacs nonbonded kernel: nb_kernel_ElecRFCut_VdwCSTab_GeomW4W4_VF_avx_256_single
54 * Electrostatics interaction: ReactionField
55 * VdW interaction: CubicSplineTable
56 * Geometry: Water4-Water4
57 * Calculate force/pot: PotentialAndForce
60 nb_kernel_ElecRFCut_VdwCSTab_GeomW4W4_VF_avx_256_single
61 (t_nblist * gmx_restrict nlist,
62 rvec * gmx_restrict xx,
63 rvec * gmx_restrict ff,
64 t_forcerec * gmx_restrict fr,
65 t_mdatoms * gmx_restrict mdatoms,
66 nb_kernel_data_t gmx_unused * gmx_restrict kernel_data,
67 t_nrnb * gmx_restrict nrnb)
69 /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
70 * just 0 for non-waters.
71 * Suffixes A,B,C,D,E,F,G,H refer to j loop unrolling done with AVX, e.g. for the eight different
72 * jnr indices corresponding to data put in the four positions in the SIMD register.
74 int i_shift_offset,i_coord_offset,outeriter,inneriter;
75 int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
76 int jnrA,jnrB,jnrC,jnrD;
77 int jnrE,jnrF,jnrG,jnrH;
78 int jnrlistA,jnrlistB,jnrlistC,jnrlistD;
79 int jnrlistE,jnrlistF,jnrlistG,jnrlistH;
80 int j_coord_offsetA,j_coord_offsetB,j_coord_offsetC,j_coord_offsetD;
81 int j_coord_offsetE,j_coord_offsetF,j_coord_offsetG,j_coord_offsetH;
82 int *iinr,*jindex,*jjnr,*shiftidx,*gid;
84 real *shiftvec,*fshift,*x,*f;
85 real *fjptrA,*fjptrB,*fjptrC,*fjptrD,*fjptrE,*fjptrF,*fjptrG,*fjptrH;
87 __m256 tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
88 real * vdwioffsetptr0;
89 __m256 ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
90 real * vdwioffsetptr1;
91 __m256 ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
92 real * vdwioffsetptr2;
93 __m256 ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
94 real * vdwioffsetptr3;
95 __m256 ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
96 int vdwjidx0A,vdwjidx0B,vdwjidx0C,vdwjidx0D,vdwjidx0E,vdwjidx0F,vdwjidx0G,vdwjidx0H;
97 __m256 jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
98 int vdwjidx1A,vdwjidx1B,vdwjidx1C,vdwjidx1D,vdwjidx1E,vdwjidx1F,vdwjidx1G,vdwjidx1H;
99 __m256 jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
100 int vdwjidx2A,vdwjidx2B,vdwjidx2C,vdwjidx2D,vdwjidx2E,vdwjidx2F,vdwjidx2G,vdwjidx2H;
101 __m256 jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
102 int vdwjidx3A,vdwjidx3B,vdwjidx3C,vdwjidx3D,vdwjidx3E,vdwjidx3F,vdwjidx3G,vdwjidx3H;
103 __m256 jx3,jy3,jz3,fjx3,fjy3,fjz3,jq3,isaj3;
104 __m256 dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
105 __m256 dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
106 __m256 dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
107 __m256 dx13,dy13,dz13,rsq13,rinv13,rinvsq13,r13,qq13,c6_13,c12_13;
108 __m256 dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
109 __m256 dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
110 __m256 dx23,dy23,dz23,rsq23,rinv23,rinvsq23,r23,qq23,c6_23,c12_23;
111 __m256 dx31,dy31,dz31,rsq31,rinv31,rinvsq31,r31,qq31,c6_31,c12_31;
112 __m256 dx32,dy32,dz32,rsq32,rinv32,rinvsq32,r32,qq32,c6_32,c12_32;
113 __m256 dx33,dy33,dz33,rsq33,rinv33,rinvsq33,r33,qq33,c6_33,c12_33;
114 __m256 velec,felec,velecsum,facel,crf,krf,krf2;
117 __m256 rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
120 __m256 one_sixth = _mm256_set1_ps(1.0/6.0);
121 __m256 one_twelfth = _mm256_set1_ps(1.0/12.0);
123 __m128i vfitab_lo,vfitab_hi;
124 __m128i ifour = _mm_set1_epi32(4);
125 __m256 rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
127 __m256 dummy_mask,cutoff_mask;
128 __m256 signbit = _mm256_castsi256_ps( _mm256_set1_epi32(0x80000000) );
129 __m256 one = _mm256_set1_ps(1.0);
130 __m256 two = _mm256_set1_ps(2.0);
136 jindex = nlist->jindex;
138 shiftidx = nlist->shift;
140 shiftvec = fr->shift_vec[0];
141 fshift = fr->fshift[0];
142 facel = _mm256_set1_ps(fr->epsfac);
143 charge = mdatoms->chargeA;
144 krf = _mm256_set1_ps(fr->ic->k_rf);
145 krf2 = _mm256_set1_ps(fr->ic->k_rf*2.0);
146 crf = _mm256_set1_ps(fr->ic->c_rf);
147 nvdwtype = fr->ntype;
149 vdwtype = mdatoms->typeA;
151 vftab = kernel_data->table_vdw->data;
152 vftabscale = _mm256_set1_ps(kernel_data->table_vdw->scale);
154 /* Setup water-specific parameters */
155 inr = nlist->iinr[0];
156 iq1 = _mm256_mul_ps(facel,_mm256_set1_ps(charge[inr+1]));
157 iq2 = _mm256_mul_ps(facel,_mm256_set1_ps(charge[inr+2]));
158 iq3 = _mm256_mul_ps(facel,_mm256_set1_ps(charge[inr+3]));
159 vdwioffsetptr0 = vdwparam+2*nvdwtype*vdwtype[inr+0];
161 jq1 = _mm256_set1_ps(charge[inr+1]);
162 jq2 = _mm256_set1_ps(charge[inr+2]);
163 jq3 = _mm256_set1_ps(charge[inr+3]);
164 vdwjidx0A = 2*vdwtype[inr+0];
165 c6_00 = _mm256_set1_ps(vdwioffsetptr0[vdwjidx0A]);
166 c12_00 = _mm256_set1_ps(vdwioffsetptr0[vdwjidx0A+1]);
167 qq11 = _mm256_mul_ps(iq1,jq1);
168 qq12 = _mm256_mul_ps(iq1,jq2);
169 qq13 = _mm256_mul_ps(iq1,jq3);
170 qq21 = _mm256_mul_ps(iq2,jq1);
171 qq22 = _mm256_mul_ps(iq2,jq2);
172 qq23 = _mm256_mul_ps(iq2,jq3);
173 qq31 = _mm256_mul_ps(iq3,jq1);
174 qq32 = _mm256_mul_ps(iq3,jq2);
175 qq33 = _mm256_mul_ps(iq3,jq3);
177 /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
178 rcutoff_scalar = fr->rcoulomb;
179 rcutoff = _mm256_set1_ps(rcutoff_scalar);
180 rcutoff2 = _mm256_mul_ps(rcutoff,rcutoff);
182 /* Avoid stupid compiler warnings */
183 jnrA = jnrB = jnrC = jnrD = jnrE = jnrF = jnrG = jnrH = 0;
196 for(iidx=0;iidx<4*DIM;iidx++)
201 /* Start outer loop over neighborlists */
202 for(iidx=0; iidx<nri; iidx++)
204 /* Load shift vector for this list */
205 i_shift_offset = DIM*shiftidx[iidx];
207 /* Load limits for loop over neighbors */
208 j_index_start = jindex[iidx];
209 j_index_end = jindex[iidx+1];
211 /* Get outer coordinate index */
213 i_coord_offset = DIM*inr;
215 /* Load i particle coords and add shift vector */
216 gmx_mm256_load_shift_and_4rvec_broadcast_ps(shiftvec+i_shift_offset,x+i_coord_offset,
217 &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
219 fix0 = _mm256_setzero_ps();
220 fiy0 = _mm256_setzero_ps();
221 fiz0 = _mm256_setzero_ps();
222 fix1 = _mm256_setzero_ps();
223 fiy1 = _mm256_setzero_ps();
224 fiz1 = _mm256_setzero_ps();
225 fix2 = _mm256_setzero_ps();
226 fiy2 = _mm256_setzero_ps();
227 fiz2 = _mm256_setzero_ps();
228 fix3 = _mm256_setzero_ps();
229 fiy3 = _mm256_setzero_ps();
230 fiz3 = _mm256_setzero_ps();
232 /* Reset potential sums */
233 velecsum = _mm256_setzero_ps();
234 vvdwsum = _mm256_setzero_ps();
236 /* Start inner kernel loop */
237 for(jidx=j_index_start; jidx<j_index_end && jjnr[jidx+7]>=0; jidx+=8)
240 /* Get j neighbor index, and coordinate index */
249 j_coord_offsetA = DIM*jnrA;
250 j_coord_offsetB = DIM*jnrB;
251 j_coord_offsetC = DIM*jnrC;
252 j_coord_offsetD = DIM*jnrD;
253 j_coord_offsetE = DIM*jnrE;
254 j_coord_offsetF = DIM*jnrF;
255 j_coord_offsetG = DIM*jnrG;
256 j_coord_offsetH = DIM*jnrH;
258 /* load j atom coordinates */
259 gmx_mm256_load_4rvec_8ptr_swizzle_ps(x+j_coord_offsetA,x+j_coord_offsetB,
260 x+j_coord_offsetC,x+j_coord_offsetD,
261 x+j_coord_offsetE,x+j_coord_offsetF,
262 x+j_coord_offsetG,x+j_coord_offsetH,
263 &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
264 &jy2,&jz2,&jx3,&jy3,&jz3);
266 /* Calculate displacement vector */
267 dx00 = _mm256_sub_ps(ix0,jx0);
268 dy00 = _mm256_sub_ps(iy0,jy0);
269 dz00 = _mm256_sub_ps(iz0,jz0);
270 dx11 = _mm256_sub_ps(ix1,jx1);
271 dy11 = _mm256_sub_ps(iy1,jy1);
272 dz11 = _mm256_sub_ps(iz1,jz1);
273 dx12 = _mm256_sub_ps(ix1,jx2);
274 dy12 = _mm256_sub_ps(iy1,jy2);
275 dz12 = _mm256_sub_ps(iz1,jz2);
276 dx13 = _mm256_sub_ps(ix1,jx3);
277 dy13 = _mm256_sub_ps(iy1,jy3);
278 dz13 = _mm256_sub_ps(iz1,jz3);
279 dx21 = _mm256_sub_ps(ix2,jx1);
280 dy21 = _mm256_sub_ps(iy2,jy1);
281 dz21 = _mm256_sub_ps(iz2,jz1);
282 dx22 = _mm256_sub_ps(ix2,jx2);
283 dy22 = _mm256_sub_ps(iy2,jy2);
284 dz22 = _mm256_sub_ps(iz2,jz2);
285 dx23 = _mm256_sub_ps(ix2,jx3);
286 dy23 = _mm256_sub_ps(iy2,jy3);
287 dz23 = _mm256_sub_ps(iz2,jz3);
288 dx31 = _mm256_sub_ps(ix3,jx1);
289 dy31 = _mm256_sub_ps(iy3,jy1);
290 dz31 = _mm256_sub_ps(iz3,jz1);
291 dx32 = _mm256_sub_ps(ix3,jx2);
292 dy32 = _mm256_sub_ps(iy3,jy2);
293 dz32 = _mm256_sub_ps(iz3,jz2);
294 dx33 = _mm256_sub_ps(ix3,jx3);
295 dy33 = _mm256_sub_ps(iy3,jy3);
296 dz33 = _mm256_sub_ps(iz3,jz3);
298 /* Calculate squared distance and things based on it */
299 rsq00 = gmx_mm256_calc_rsq_ps(dx00,dy00,dz00);
300 rsq11 = gmx_mm256_calc_rsq_ps(dx11,dy11,dz11);
301 rsq12 = gmx_mm256_calc_rsq_ps(dx12,dy12,dz12);
302 rsq13 = gmx_mm256_calc_rsq_ps(dx13,dy13,dz13);
303 rsq21 = gmx_mm256_calc_rsq_ps(dx21,dy21,dz21);
304 rsq22 = gmx_mm256_calc_rsq_ps(dx22,dy22,dz22);
305 rsq23 = gmx_mm256_calc_rsq_ps(dx23,dy23,dz23);
306 rsq31 = gmx_mm256_calc_rsq_ps(dx31,dy31,dz31);
307 rsq32 = gmx_mm256_calc_rsq_ps(dx32,dy32,dz32);
308 rsq33 = gmx_mm256_calc_rsq_ps(dx33,dy33,dz33);
310 rinv00 = gmx_mm256_invsqrt_ps(rsq00);
311 rinv11 = gmx_mm256_invsqrt_ps(rsq11);
312 rinv12 = gmx_mm256_invsqrt_ps(rsq12);
313 rinv13 = gmx_mm256_invsqrt_ps(rsq13);
314 rinv21 = gmx_mm256_invsqrt_ps(rsq21);
315 rinv22 = gmx_mm256_invsqrt_ps(rsq22);
316 rinv23 = gmx_mm256_invsqrt_ps(rsq23);
317 rinv31 = gmx_mm256_invsqrt_ps(rsq31);
318 rinv32 = gmx_mm256_invsqrt_ps(rsq32);
319 rinv33 = gmx_mm256_invsqrt_ps(rsq33);
321 rinvsq11 = _mm256_mul_ps(rinv11,rinv11);
322 rinvsq12 = _mm256_mul_ps(rinv12,rinv12);
323 rinvsq13 = _mm256_mul_ps(rinv13,rinv13);
324 rinvsq21 = _mm256_mul_ps(rinv21,rinv21);
325 rinvsq22 = _mm256_mul_ps(rinv22,rinv22);
326 rinvsq23 = _mm256_mul_ps(rinv23,rinv23);
327 rinvsq31 = _mm256_mul_ps(rinv31,rinv31);
328 rinvsq32 = _mm256_mul_ps(rinv32,rinv32);
329 rinvsq33 = _mm256_mul_ps(rinv33,rinv33);
331 fjx0 = _mm256_setzero_ps();
332 fjy0 = _mm256_setzero_ps();
333 fjz0 = _mm256_setzero_ps();
334 fjx1 = _mm256_setzero_ps();
335 fjy1 = _mm256_setzero_ps();
336 fjz1 = _mm256_setzero_ps();
337 fjx2 = _mm256_setzero_ps();
338 fjy2 = _mm256_setzero_ps();
339 fjz2 = _mm256_setzero_ps();
340 fjx3 = _mm256_setzero_ps();
341 fjy3 = _mm256_setzero_ps();
342 fjz3 = _mm256_setzero_ps();
344 /**************************
345 * CALCULATE INTERACTIONS *
346 **************************/
348 if (gmx_mm256_any_lt(rsq00,rcutoff2))
351 r00 = _mm256_mul_ps(rsq00,rinv00);
353 /* Calculate table index by multiplying r with table scale and truncate to integer */
354 rt = _mm256_mul_ps(r00,vftabscale);
355 vfitab = _mm256_cvttps_epi32(rt);
356 vfeps = _mm256_sub_ps(rt,_mm256_round_ps(rt, _MM_FROUND_FLOOR));
357 /* AVX1 does not support 256-bit integer operations, so now we go to 128-bit mode... */
358 vfitab_lo = _mm256_extractf128_si256(vfitab,0x0);
359 vfitab_hi = _mm256_extractf128_si256(vfitab,0x1);
360 vfitab_lo = _mm_slli_epi32(vfitab_lo,3);
361 vfitab_hi = _mm_slli_epi32(vfitab_hi,3);
363 /* CUBIC SPLINE TABLE DISPERSION */
364 Y = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,0)),
365 _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,0)));
366 F = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,1)),
367 _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,1)));
368 G = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,2)),
369 _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,2)));
370 H = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,3)),
371 _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,3)));
372 GMX_MM256_HALFTRANSPOSE4_PS(Y,F,G,H);
373 Heps = _mm256_mul_ps(vfeps,H);
374 Fp = _mm256_add_ps(F,_mm256_mul_ps(vfeps,_mm256_add_ps(G,Heps)));
375 VV = _mm256_add_ps(Y,_mm256_mul_ps(vfeps,Fp));
376 vvdw6 = _mm256_mul_ps(c6_00,VV);
377 FF = _mm256_add_ps(Fp,_mm256_mul_ps(vfeps,_mm256_add_ps(G,_mm256_add_ps(Heps,Heps))));
378 fvdw6 = _mm256_mul_ps(c6_00,FF);
380 /* CUBIC SPLINE TABLE REPULSION */
381 vfitab_lo = _mm_add_epi32(vfitab_lo,ifour);
382 vfitab_hi = _mm_add_epi32(vfitab_hi,ifour);
383 Y = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,0)),
384 _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,0)));
385 F = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,1)),
386 _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,1)));
387 G = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,2)),
388 _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,2)));
389 H = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,3)),
390 _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,3)));
391 GMX_MM256_HALFTRANSPOSE4_PS(Y,F,G,H);
392 Heps = _mm256_mul_ps(vfeps,H);
393 Fp = _mm256_add_ps(F,_mm256_mul_ps(vfeps,_mm256_add_ps(G,Heps)));
394 VV = _mm256_add_ps(Y,_mm256_mul_ps(vfeps,Fp));
395 vvdw12 = _mm256_mul_ps(c12_00,VV);
396 FF = _mm256_add_ps(Fp,_mm256_mul_ps(vfeps,_mm256_add_ps(G,_mm256_add_ps(Heps,Heps))));
397 fvdw12 = _mm256_mul_ps(c12_00,FF);
398 vvdw = _mm256_add_ps(vvdw12,vvdw6);
399 fvdw = _mm256_xor_ps(signbit,_mm256_mul_ps(_mm256_add_ps(fvdw6,fvdw12),_mm256_mul_ps(vftabscale,rinv00)));
401 cutoff_mask = _mm256_cmp_ps(rsq00,rcutoff2,_CMP_LT_OQ);
403 /* Update potential sum for this i atom from the interaction with this j atom. */
404 vvdw = _mm256_and_ps(vvdw,cutoff_mask);
405 vvdwsum = _mm256_add_ps(vvdwsum,vvdw);
409 fscal = _mm256_and_ps(fscal,cutoff_mask);
411 /* Calculate temporary vectorial force */
412 tx = _mm256_mul_ps(fscal,dx00);
413 ty = _mm256_mul_ps(fscal,dy00);
414 tz = _mm256_mul_ps(fscal,dz00);
416 /* Update vectorial force */
417 fix0 = _mm256_add_ps(fix0,tx);
418 fiy0 = _mm256_add_ps(fiy0,ty);
419 fiz0 = _mm256_add_ps(fiz0,tz);
421 fjx0 = _mm256_add_ps(fjx0,tx);
422 fjy0 = _mm256_add_ps(fjy0,ty);
423 fjz0 = _mm256_add_ps(fjz0,tz);
427 /**************************
428 * CALCULATE INTERACTIONS *
429 **************************/
431 if (gmx_mm256_any_lt(rsq11,rcutoff2))
434 /* REACTION-FIELD ELECTROSTATICS */
435 velec = _mm256_mul_ps(qq11,_mm256_sub_ps(_mm256_add_ps(rinv11,_mm256_mul_ps(krf,rsq11)),crf));
436 felec = _mm256_mul_ps(qq11,_mm256_sub_ps(_mm256_mul_ps(rinv11,rinvsq11),krf2));
438 cutoff_mask = _mm256_cmp_ps(rsq11,rcutoff2,_CMP_LT_OQ);
440 /* Update potential sum for this i atom from the interaction with this j atom. */
441 velec = _mm256_and_ps(velec,cutoff_mask);
442 velecsum = _mm256_add_ps(velecsum,velec);
446 fscal = _mm256_and_ps(fscal,cutoff_mask);
448 /* Calculate temporary vectorial force */
449 tx = _mm256_mul_ps(fscal,dx11);
450 ty = _mm256_mul_ps(fscal,dy11);
451 tz = _mm256_mul_ps(fscal,dz11);
453 /* Update vectorial force */
454 fix1 = _mm256_add_ps(fix1,tx);
455 fiy1 = _mm256_add_ps(fiy1,ty);
456 fiz1 = _mm256_add_ps(fiz1,tz);
458 fjx1 = _mm256_add_ps(fjx1,tx);
459 fjy1 = _mm256_add_ps(fjy1,ty);
460 fjz1 = _mm256_add_ps(fjz1,tz);
464 /**************************
465 * CALCULATE INTERACTIONS *
466 **************************/
468 if (gmx_mm256_any_lt(rsq12,rcutoff2))
471 /* REACTION-FIELD ELECTROSTATICS */
472 velec = _mm256_mul_ps(qq12,_mm256_sub_ps(_mm256_add_ps(rinv12,_mm256_mul_ps(krf,rsq12)),crf));
473 felec = _mm256_mul_ps(qq12,_mm256_sub_ps(_mm256_mul_ps(rinv12,rinvsq12),krf2));
475 cutoff_mask = _mm256_cmp_ps(rsq12,rcutoff2,_CMP_LT_OQ);
477 /* Update potential sum for this i atom from the interaction with this j atom. */
478 velec = _mm256_and_ps(velec,cutoff_mask);
479 velecsum = _mm256_add_ps(velecsum,velec);
483 fscal = _mm256_and_ps(fscal,cutoff_mask);
485 /* Calculate temporary vectorial force */
486 tx = _mm256_mul_ps(fscal,dx12);
487 ty = _mm256_mul_ps(fscal,dy12);
488 tz = _mm256_mul_ps(fscal,dz12);
490 /* Update vectorial force */
491 fix1 = _mm256_add_ps(fix1,tx);
492 fiy1 = _mm256_add_ps(fiy1,ty);
493 fiz1 = _mm256_add_ps(fiz1,tz);
495 fjx2 = _mm256_add_ps(fjx2,tx);
496 fjy2 = _mm256_add_ps(fjy2,ty);
497 fjz2 = _mm256_add_ps(fjz2,tz);
501 /**************************
502 * CALCULATE INTERACTIONS *
503 **************************/
505 if (gmx_mm256_any_lt(rsq13,rcutoff2))
508 /* REACTION-FIELD ELECTROSTATICS */
509 velec = _mm256_mul_ps(qq13,_mm256_sub_ps(_mm256_add_ps(rinv13,_mm256_mul_ps(krf,rsq13)),crf));
510 felec = _mm256_mul_ps(qq13,_mm256_sub_ps(_mm256_mul_ps(rinv13,rinvsq13),krf2));
512 cutoff_mask = _mm256_cmp_ps(rsq13,rcutoff2,_CMP_LT_OQ);
514 /* Update potential sum for this i atom from the interaction with this j atom. */
515 velec = _mm256_and_ps(velec,cutoff_mask);
516 velecsum = _mm256_add_ps(velecsum,velec);
520 fscal = _mm256_and_ps(fscal,cutoff_mask);
522 /* Calculate temporary vectorial force */
523 tx = _mm256_mul_ps(fscal,dx13);
524 ty = _mm256_mul_ps(fscal,dy13);
525 tz = _mm256_mul_ps(fscal,dz13);
527 /* Update vectorial force */
528 fix1 = _mm256_add_ps(fix1,tx);
529 fiy1 = _mm256_add_ps(fiy1,ty);
530 fiz1 = _mm256_add_ps(fiz1,tz);
532 fjx3 = _mm256_add_ps(fjx3,tx);
533 fjy3 = _mm256_add_ps(fjy3,ty);
534 fjz3 = _mm256_add_ps(fjz3,tz);
538 /**************************
539 * CALCULATE INTERACTIONS *
540 **************************/
542 if (gmx_mm256_any_lt(rsq21,rcutoff2))
545 /* REACTION-FIELD ELECTROSTATICS */
546 velec = _mm256_mul_ps(qq21,_mm256_sub_ps(_mm256_add_ps(rinv21,_mm256_mul_ps(krf,rsq21)),crf));
547 felec = _mm256_mul_ps(qq21,_mm256_sub_ps(_mm256_mul_ps(rinv21,rinvsq21),krf2));
549 cutoff_mask = _mm256_cmp_ps(rsq21,rcutoff2,_CMP_LT_OQ);
551 /* Update potential sum for this i atom from the interaction with this j atom. */
552 velec = _mm256_and_ps(velec,cutoff_mask);
553 velecsum = _mm256_add_ps(velecsum,velec);
557 fscal = _mm256_and_ps(fscal,cutoff_mask);
559 /* Calculate temporary vectorial force */
560 tx = _mm256_mul_ps(fscal,dx21);
561 ty = _mm256_mul_ps(fscal,dy21);
562 tz = _mm256_mul_ps(fscal,dz21);
564 /* Update vectorial force */
565 fix2 = _mm256_add_ps(fix2,tx);
566 fiy2 = _mm256_add_ps(fiy2,ty);
567 fiz2 = _mm256_add_ps(fiz2,tz);
569 fjx1 = _mm256_add_ps(fjx1,tx);
570 fjy1 = _mm256_add_ps(fjy1,ty);
571 fjz1 = _mm256_add_ps(fjz1,tz);
575 /**************************
576 * CALCULATE INTERACTIONS *
577 **************************/
579 if (gmx_mm256_any_lt(rsq22,rcutoff2))
582 /* REACTION-FIELD ELECTROSTATICS */
583 velec = _mm256_mul_ps(qq22,_mm256_sub_ps(_mm256_add_ps(rinv22,_mm256_mul_ps(krf,rsq22)),crf));
584 felec = _mm256_mul_ps(qq22,_mm256_sub_ps(_mm256_mul_ps(rinv22,rinvsq22),krf2));
586 cutoff_mask = _mm256_cmp_ps(rsq22,rcutoff2,_CMP_LT_OQ);
588 /* Update potential sum for this i atom from the interaction with this j atom. */
589 velec = _mm256_and_ps(velec,cutoff_mask);
590 velecsum = _mm256_add_ps(velecsum,velec);
594 fscal = _mm256_and_ps(fscal,cutoff_mask);
596 /* Calculate temporary vectorial force */
597 tx = _mm256_mul_ps(fscal,dx22);
598 ty = _mm256_mul_ps(fscal,dy22);
599 tz = _mm256_mul_ps(fscal,dz22);
601 /* Update vectorial force */
602 fix2 = _mm256_add_ps(fix2,tx);
603 fiy2 = _mm256_add_ps(fiy2,ty);
604 fiz2 = _mm256_add_ps(fiz2,tz);
606 fjx2 = _mm256_add_ps(fjx2,tx);
607 fjy2 = _mm256_add_ps(fjy2,ty);
608 fjz2 = _mm256_add_ps(fjz2,tz);
612 /**************************
613 * CALCULATE INTERACTIONS *
614 **************************/
616 if (gmx_mm256_any_lt(rsq23,rcutoff2))
619 /* REACTION-FIELD ELECTROSTATICS */
620 velec = _mm256_mul_ps(qq23,_mm256_sub_ps(_mm256_add_ps(rinv23,_mm256_mul_ps(krf,rsq23)),crf));
621 felec = _mm256_mul_ps(qq23,_mm256_sub_ps(_mm256_mul_ps(rinv23,rinvsq23),krf2));
623 cutoff_mask = _mm256_cmp_ps(rsq23,rcutoff2,_CMP_LT_OQ);
625 /* Update potential sum for this i atom from the interaction with this j atom. */
626 velec = _mm256_and_ps(velec,cutoff_mask);
627 velecsum = _mm256_add_ps(velecsum,velec);
631 fscal = _mm256_and_ps(fscal,cutoff_mask);
633 /* Calculate temporary vectorial force */
634 tx = _mm256_mul_ps(fscal,dx23);
635 ty = _mm256_mul_ps(fscal,dy23);
636 tz = _mm256_mul_ps(fscal,dz23);
638 /* Update vectorial force */
639 fix2 = _mm256_add_ps(fix2,tx);
640 fiy2 = _mm256_add_ps(fiy2,ty);
641 fiz2 = _mm256_add_ps(fiz2,tz);
643 fjx3 = _mm256_add_ps(fjx3,tx);
644 fjy3 = _mm256_add_ps(fjy3,ty);
645 fjz3 = _mm256_add_ps(fjz3,tz);
649 /**************************
650 * CALCULATE INTERACTIONS *
651 **************************/
653 if (gmx_mm256_any_lt(rsq31,rcutoff2))
656 /* REACTION-FIELD ELECTROSTATICS */
657 velec = _mm256_mul_ps(qq31,_mm256_sub_ps(_mm256_add_ps(rinv31,_mm256_mul_ps(krf,rsq31)),crf));
658 felec = _mm256_mul_ps(qq31,_mm256_sub_ps(_mm256_mul_ps(rinv31,rinvsq31),krf2));
660 cutoff_mask = _mm256_cmp_ps(rsq31,rcutoff2,_CMP_LT_OQ);
662 /* Update potential sum for this i atom from the interaction with this j atom. */
663 velec = _mm256_and_ps(velec,cutoff_mask);
664 velecsum = _mm256_add_ps(velecsum,velec);
668 fscal = _mm256_and_ps(fscal,cutoff_mask);
670 /* Calculate temporary vectorial force */
671 tx = _mm256_mul_ps(fscal,dx31);
672 ty = _mm256_mul_ps(fscal,dy31);
673 tz = _mm256_mul_ps(fscal,dz31);
675 /* Update vectorial force */
676 fix3 = _mm256_add_ps(fix3,tx);
677 fiy3 = _mm256_add_ps(fiy3,ty);
678 fiz3 = _mm256_add_ps(fiz3,tz);
680 fjx1 = _mm256_add_ps(fjx1,tx);
681 fjy1 = _mm256_add_ps(fjy1,ty);
682 fjz1 = _mm256_add_ps(fjz1,tz);
686 /**************************
687 * CALCULATE INTERACTIONS *
688 **************************/
690 if (gmx_mm256_any_lt(rsq32,rcutoff2))
693 /* REACTION-FIELD ELECTROSTATICS */
694 velec = _mm256_mul_ps(qq32,_mm256_sub_ps(_mm256_add_ps(rinv32,_mm256_mul_ps(krf,rsq32)),crf));
695 felec = _mm256_mul_ps(qq32,_mm256_sub_ps(_mm256_mul_ps(rinv32,rinvsq32),krf2));
697 cutoff_mask = _mm256_cmp_ps(rsq32,rcutoff2,_CMP_LT_OQ);
699 /* Update potential sum for this i atom from the interaction with this j atom. */
700 velec = _mm256_and_ps(velec,cutoff_mask);
701 velecsum = _mm256_add_ps(velecsum,velec);
705 fscal = _mm256_and_ps(fscal,cutoff_mask);
707 /* Calculate temporary vectorial force */
708 tx = _mm256_mul_ps(fscal,dx32);
709 ty = _mm256_mul_ps(fscal,dy32);
710 tz = _mm256_mul_ps(fscal,dz32);
712 /* Update vectorial force */
713 fix3 = _mm256_add_ps(fix3,tx);
714 fiy3 = _mm256_add_ps(fiy3,ty);
715 fiz3 = _mm256_add_ps(fiz3,tz);
717 fjx2 = _mm256_add_ps(fjx2,tx);
718 fjy2 = _mm256_add_ps(fjy2,ty);
719 fjz2 = _mm256_add_ps(fjz2,tz);
723 /**************************
724 * CALCULATE INTERACTIONS *
725 **************************/
727 if (gmx_mm256_any_lt(rsq33,rcutoff2))
730 /* REACTION-FIELD ELECTROSTATICS */
731 velec = _mm256_mul_ps(qq33,_mm256_sub_ps(_mm256_add_ps(rinv33,_mm256_mul_ps(krf,rsq33)),crf));
732 felec = _mm256_mul_ps(qq33,_mm256_sub_ps(_mm256_mul_ps(rinv33,rinvsq33),krf2));
734 cutoff_mask = _mm256_cmp_ps(rsq33,rcutoff2,_CMP_LT_OQ);
736 /* Update potential sum for this i atom from the interaction with this j atom. */
737 velec = _mm256_and_ps(velec,cutoff_mask);
738 velecsum = _mm256_add_ps(velecsum,velec);
742 fscal = _mm256_and_ps(fscal,cutoff_mask);
744 /* Calculate temporary vectorial force */
745 tx = _mm256_mul_ps(fscal,dx33);
746 ty = _mm256_mul_ps(fscal,dy33);
747 tz = _mm256_mul_ps(fscal,dz33);
749 /* Update vectorial force */
750 fix3 = _mm256_add_ps(fix3,tx);
751 fiy3 = _mm256_add_ps(fiy3,ty);
752 fiz3 = _mm256_add_ps(fiz3,tz);
754 fjx3 = _mm256_add_ps(fjx3,tx);
755 fjy3 = _mm256_add_ps(fjy3,ty);
756 fjz3 = _mm256_add_ps(fjz3,tz);
760 fjptrA = f+j_coord_offsetA;
761 fjptrB = f+j_coord_offsetB;
762 fjptrC = f+j_coord_offsetC;
763 fjptrD = f+j_coord_offsetD;
764 fjptrE = f+j_coord_offsetE;
765 fjptrF = f+j_coord_offsetF;
766 fjptrG = f+j_coord_offsetG;
767 fjptrH = f+j_coord_offsetH;
769 gmx_mm256_decrement_4rvec_8ptr_swizzle_ps(fjptrA,fjptrB,fjptrC,fjptrD,fjptrE,fjptrF,fjptrG,fjptrH,
770 fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,
771 fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
773 /* Inner loop uses 387 flops */
779 /* Get j neighbor index, and coordinate index */
780 jnrlistA = jjnr[jidx];
781 jnrlistB = jjnr[jidx+1];
782 jnrlistC = jjnr[jidx+2];
783 jnrlistD = jjnr[jidx+3];
784 jnrlistE = jjnr[jidx+4];
785 jnrlistF = jjnr[jidx+5];
786 jnrlistG = jjnr[jidx+6];
787 jnrlistH = jjnr[jidx+7];
788 /* Sign of each element will be negative for non-real atoms.
789 * This mask will be 0xFFFFFFFF for dummy entries and 0x0 for real ones,
790 * so use it as val = _mm_andnot_ps(mask,val) to clear dummy entries.
792 dummy_mask = gmx_mm256_set_m128(gmx_mm_castsi128_ps(_mm_cmplt_epi32(_mm_loadu_si128((const __m128i *)(jjnr+jidx+4)),_mm_setzero_si128())),
793 gmx_mm_castsi128_ps(_mm_cmplt_epi32(_mm_loadu_si128((const __m128i *)(jjnr+jidx)),_mm_setzero_si128())));
795 jnrA = (jnrlistA>=0) ? jnrlistA : 0;
796 jnrB = (jnrlistB>=0) ? jnrlistB : 0;
797 jnrC = (jnrlistC>=0) ? jnrlistC : 0;
798 jnrD = (jnrlistD>=0) ? jnrlistD : 0;
799 jnrE = (jnrlistE>=0) ? jnrlistE : 0;
800 jnrF = (jnrlistF>=0) ? jnrlistF : 0;
801 jnrG = (jnrlistG>=0) ? jnrlistG : 0;
802 jnrH = (jnrlistH>=0) ? jnrlistH : 0;
803 j_coord_offsetA = DIM*jnrA;
804 j_coord_offsetB = DIM*jnrB;
805 j_coord_offsetC = DIM*jnrC;
806 j_coord_offsetD = DIM*jnrD;
807 j_coord_offsetE = DIM*jnrE;
808 j_coord_offsetF = DIM*jnrF;
809 j_coord_offsetG = DIM*jnrG;
810 j_coord_offsetH = DIM*jnrH;
812 /* load j atom coordinates */
813 gmx_mm256_load_4rvec_8ptr_swizzle_ps(x+j_coord_offsetA,x+j_coord_offsetB,
814 x+j_coord_offsetC,x+j_coord_offsetD,
815 x+j_coord_offsetE,x+j_coord_offsetF,
816 x+j_coord_offsetG,x+j_coord_offsetH,
817 &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
818 &jy2,&jz2,&jx3,&jy3,&jz3);
820 /* Calculate displacement vector */
821 dx00 = _mm256_sub_ps(ix0,jx0);
822 dy00 = _mm256_sub_ps(iy0,jy0);
823 dz00 = _mm256_sub_ps(iz0,jz0);
824 dx11 = _mm256_sub_ps(ix1,jx1);
825 dy11 = _mm256_sub_ps(iy1,jy1);
826 dz11 = _mm256_sub_ps(iz1,jz1);
827 dx12 = _mm256_sub_ps(ix1,jx2);
828 dy12 = _mm256_sub_ps(iy1,jy2);
829 dz12 = _mm256_sub_ps(iz1,jz2);
830 dx13 = _mm256_sub_ps(ix1,jx3);
831 dy13 = _mm256_sub_ps(iy1,jy3);
832 dz13 = _mm256_sub_ps(iz1,jz3);
833 dx21 = _mm256_sub_ps(ix2,jx1);
834 dy21 = _mm256_sub_ps(iy2,jy1);
835 dz21 = _mm256_sub_ps(iz2,jz1);
836 dx22 = _mm256_sub_ps(ix2,jx2);
837 dy22 = _mm256_sub_ps(iy2,jy2);
838 dz22 = _mm256_sub_ps(iz2,jz2);
839 dx23 = _mm256_sub_ps(ix2,jx3);
840 dy23 = _mm256_sub_ps(iy2,jy3);
841 dz23 = _mm256_sub_ps(iz2,jz3);
842 dx31 = _mm256_sub_ps(ix3,jx1);
843 dy31 = _mm256_sub_ps(iy3,jy1);
844 dz31 = _mm256_sub_ps(iz3,jz1);
845 dx32 = _mm256_sub_ps(ix3,jx2);
846 dy32 = _mm256_sub_ps(iy3,jy2);
847 dz32 = _mm256_sub_ps(iz3,jz2);
848 dx33 = _mm256_sub_ps(ix3,jx3);
849 dy33 = _mm256_sub_ps(iy3,jy3);
850 dz33 = _mm256_sub_ps(iz3,jz3);
852 /* Calculate squared distance and things based on it */
853 rsq00 = gmx_mm256_calc_rsq_ps(dx00,dy00,dz00);
854 rsq11 = gmx_mm256_calc_rsq_ps(dx11,dy11,dz11);
855 rsq12 = gmx_mm256_calc_rsq_ps(dx12,dy12,dz12);
856 rsq13 = gmx_mm256_calc_rsq_ps(dx13,dy13,dz13);
857 rsq21 = gmx_mm256_calc_rsq_ps(dx21,dy21,dz21);
858 rsq22 = gmx_mm256_calc_rsq_ps(dx22,dy22,dz22);
859 rsq23 = gmx_mm256_calc_rsq_ps(dx23,dy23,dz23);
860 rsq31 = gmx_mm256_calc_rsq_ps(dx31,dy31,dz31);
861 rsq32 = gmx_mm256_calc_rsq_ps(dx32,dy32,dz32);
862 rsq33 = gmx_mm256_calc_rsq_ps(dx33,dy33,dz33);
864 rinv00 = gmx_mm256_invsqrt_ps(rsq00);
865 rinv11 = gmx_mm256_invsqrt_ps(rsq11);
866 rinv12 = gmx_mm256_invsqrt_ps(rsq12);
867 rinv13 = gmx_mm256_invsqrt_ps(rsq13);
868 rinv21 = gmx_mm256_invsqrt_ps(rsq21);
869 rinv22 = gmx_mm256_invsqrt_ps(rsq22);
870 rinv23 = gmx_mm256_invsqrt_ps(rsq23);
871 rinv31 = gmx_mm256_invsqrt_ps(rsq31);
872 rinv32 = gmx_mm256_invsqrt_ps(rsq32);
873 rinv33 = gmx_mm256_invsqrt_ps(rsq33);
875 rinvsq11 = _mm256_mul_ps(rinv11,rinv11);
876 rinvsq12 = _mm256_mul_ps(rinv12,rinv12);
877 rinvsq13 = _mm256_mul_ps(rinv13,rinv13);
878 rinvsq21 = _mm256_mul_ps(rinv21,rinv21);
879 rinvsq22 = _mm256_mul_ps(rinv22,rinv22);
880 rinvsq23 = _mm256_mul_ps(rinv23,rinv23);
881 rinvsq31 = _mm256_mul_ps(rinv31,rinv31);
882 rinvsq32 = _mm256_mul_ps(rinv32,rinv32);
883 rinvsq33 = _mm256_mul_ps(rinv33,rinv33);
885 fjx0 = _mm256_setzero_ps();
886 fjy0 = _mm256_setzero_ps();
887 fjz0 = _mm256_setzero_ps();
888 fjx1 = _mm256_setzero_ps();
889 fjy1 = _mm256_setzero_ps();
890 fjz1 = _mm256_setzero_ps();
891 fjx2 = _mm256_setzero_ps();
892 fjy2 = _mm256_setzero_ps();
893 fjz2 = _mm256_setzero_ps();
894 fjx3 = _mm256_setzero_ps();
895 fjy3 = _mm256_setzero_ps();
896 fjz3 = _mm256_setzero_ps();
898 /**************************
899 * CALCULATE INTERACTIONS *
900 **************************/
902 if (gmx_mm256_any_lt(rsq00,rcutoff2))
905 r00 = _mm256_mul_ps(rsq00,rinv00);
906 r00 = _mm256_andnot_ps(dummy_mask,r00);
908 /* Calculate table index by multiplying r with table scale and truncate to integer */
909 rt = _mm256_mul_ps(r00,vftabscale);
910 vfitab = _mm256_cvttps_epi32(rt);
911 vfeps = _mm256_sub_ps(rt,_mm256_round_ps(rt, _MM_FROUND_FLOOR));
912 /* AVX1 does not support 256-bit integer operations, so now we go to 128-bit mode... */
913 vfitab_lo = _mm256_extractf128_si256(vfitab,0x0);
914 vfitab_hi = _mm256_extractf128_si256(vfitab,0x1);
915 vfitab_lo = _mm_slli_epi32(vfitab_lo,3);
916 vfitab_hi = _mm_slli_epi32(vfitab_hi,3);
918 /* CUBIC SPLINE TABLE DISPERSION */
919 Y = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,0)),
920 _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,0)));
921 F = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,1)),
922 _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,1)));
923 G = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,2)),
924 _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,2)));
925 H = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,3)),
926 _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,3)));
927 GMX_MM256_HALFTRANSPOSE4_PS(Y,F,G,H);
928 Heps = _mm256_mul_ps(vfeps,H);
929 Fp = _mm256_add_ps(F,_mm256_mul_ps(vfeps,_mm256_add_ps(G,Heps)));
930 VV = _mm256_add_ps(Y,_mm256_mul_ps(vfeps,Fp));
931 vvdw6 = _mm256_mul_ps(c6_00,VV);
932 FF = _mm256_add_ps(Fp,_mm256_mul_ps(vfeps,_mm256_add_ps(G,_mm256_add_ps(Heps,Heps))));
933 fvdw6 = _mm256_mul_ps(c6_00,FF);
935 /* CUBIC SPLINE TABLE REPULSION */
936 vfitab_lo = _mm_add_epi32(vfitab_lo,ifour);
937 vfitab_hi = _mm_add_epi32(vfitab_hi,ifour);
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 VV = _mm256_add_ps(Y,_mm256_mul_ps(vfeps,Fp));
950 vvdw12 = _mm256_mul_ps(c12_00,VV);
951 FF = _mm256_add_ps(Fp,_mm256_mul_ps(vfeps,_mm256_add_ps(G,_mm256_add_ps(Heps,Heps))));
952 fvdw12 = _mm256_mul_ps(c12_00,FF);
953 vvdw = _mm256_add_ps(vvdw12,vvdw6);
954 fvdw = _mm256_xor_ps(signbit,_mm256_mul_ps(_mm256_add_ps(fvdw6,fvdw12),_mm256_mul_ps(vftabscale,rinv00)));
956 cutoff_mask = _mm256_cmp_ps(rsq00,rcutoff2,_CMP_LT_OQ);
958 /* Update potential sum for this i atom from the interaction with this j atom. */
959 vvdw = _mm256_and_ps(vvdw,cutoff_mask);
960 vvdw = _mm256_andnot_ps(dummy_mask,vvdw);
961 vvdwsum = _mm256_add_ps(vvdwsum,vvdw);
965 fscal = _mm256_and_ps(fscal,cutoff_mask);
967 fscal = _mm256_andnot_ps(dummy_mask,fscal);
969 /* Calculate temporary vectorial force */
970 tx = _mm256_mul_ps(fscal,dx00);
971 ty = _mm256_mul_ps(fscal,dy00);
972 tz = _mm256_mul_ps(fscal,dz00);
974 /* Update vectorial force */
975 fix0 = _mm256_add_ps(fix0,tx);
976 fiy0 = _mm256_add_ps(fiy0,ty);
977 fiz0 = _mm256_add_ps(fiz0,tz);
979 fjx0 = _mm256_add_ps(fjx0,tx);
980 fjy0 = _mm256_add_ps(fjy0,ty);
981 fjz0 = _mm256_add_ps(fjz0,tz);
985 /**************************
986 * CALCULATE INTERACTIONS *
987 **************************/
989 if (gmx_mm256_any_lt(rsq11,rcutoff2))
992 /* REACTION-FIELD ELECTROSTATICS */
993 velec = _mm256_mul_ps(qq11,_mm256_sub_ps(_mm256_add_ps(rinv11,_mm256_mul_ps(krf,rsq11)),crf));
994 felec = _mm256_mul_ps(qq11,_mm256_sub_ps(_mm256_mul_ps(rinv11,rinvsq11),krf2));
996 cutoff_mask = _mm256_cmp_ps(rsq11,rcutoff2,_CMP_LT_OQ);
998 /* Update potential sum for this i atom from the interaction with this j atom. */
999 velec = _mm256_and_ps(velec,cutoff_mask);
1000 velec = _mm256_andnot_ps(dummy_mask,velec);
1001 velecsum = _mm256_add_ps(velecsum,velec);
1005 fscal = _mm256_and_ps(fscal,cutoff_mask);
1007 fscal = _mm256_andnot_ps(dummy_mask,fscal);
1009 /* Calculate temporary vectorial force */
1010 tx = _mm256_mul_ps(fscal,dx11);
1011 ty = _mm256_mul_ps(fscal,dy11);
1012 tz = _mm256_mul_ps(fscal,dz11);
1014 /* Update vectorial force */
1015 fix1 = _mm256_add_ps(fix1,tx);
1016 fiy1 = _mm256_add_ps(fiy1,ty);
1017 fiz1 = _mm256_add_ps(fiz1,tz);
1019 fjx1 = _mm256_add_ps(fjx1,tx);
1020 fjy1 = _mm256_add_ps(fjy1,ty);
1021 fjz1 = _mm256_add_ps(fjz1,tz);
1025 /**************************
1026 * CALCULATE INTERACTIONS *
1027 **************************/
1029 if (gmx_mm256_any_lt(rsq12,rcutoff2))
1032 /* REACTION-FIELD ELECTROSTATICS */
1033 velec = _mm256_mul_ps(qq12,_mm256_sub_ps(_mm256_add_ps(rinv12,_mm256_mul_ps(krf,rsq12)),crf));
1034 felec = _mm256_mul_ps(qq12,_mm256_sub_ps(_mm256_mul_ps(rinv12,rinvsq12),krf2));
1036 cutoff_mask = _mm256_cmp_ps(rsq12,rcutoff2,_CMP_LT_OQ);
1038 /* Update potential sum for this i atom from the interaction with this j atom. */
1039 velec = _mm256_and_ps(velec,cutoff_mask);
1040 velec = _mm256_andnot_ps(dummy_mask,velec);
1041 velecsum = _mm256_add_ps(velecsum,velec);
1045 fscal = _mm256_and_ps(fscal,cutoff_mask);
1047 fscal = _mm256_andnot_ps(dummy_mask,fscal);
1049 /* Calculate temporary vectorial force */
1050 tx = _mm256_mul_ps(fscal,dx12);
1051 ty = _mm256_mul_ps(fscal,dy12);
1052 tz = _mm256_mul_ps(fscal,dz12);
1054 /* Update vectorial force */
1055 fix1 = _mm256_add_ps(fix1,tx);
1056 fiy1 = _mm256_add_ps(fiy1,ty);
1057 fiz1 = _mm256_add_ps(fiz1,tz);
1059 fjx2 = _mm256_add_ps(fjx2,tx);
1060 fjy2 = _mm256_add_ps(fjy2,ty);
1061 fjz2 = _mm256_add_ps(fjz2,tz);
1065 /**************************
1066 * CALCULATE INTERACTIONS *
1067 **************************/
1069 if (gmx_mm256_any_lt(rsq13,rcutoff2))
1072 /* REACTION-FIELD ELECTROSTATICS */
1073 velec = _mm256_mul_ps(qq13,_mm256_sub_ps(_mm256_add_ps(rinv13,_mm256_mul_ps(krf,rsq13)),crf));
1074 felec = _mm256_mul_ps(qq13,_mm256_sub_ps(_mm256_mul_ps(rinv13,rinvsq13),krf2));
1076 cutoff_mask = _mm256_cmp_ps(rsq13,rcutoff2,_CMP_LT_OQ);
1078 /* Update potential sum for this i atom from the interaction with this j atom. */
1079 velec = _mm256_and_ps(velec,cutoff_mask);
1080 velec = _mm256_andnot_ps(dummy_mask,velec);
1081 velecsum = _mm256_add_ps(velecsum,velec);
1085 fscal = _mm256_and_ps(fscal,cutoff_mask);
1087 fscal = _mm256_andnot_ps(dummy_mask,fscal);
1089 /* Calculate temporary vectorial force */
1090 tx = _mm256_mul_ps(fscal,dx13);
1091 ty = _mm256_mul_ps(fscal,dy13);
1092 tz = _mm256_mul_ps(fscal,dz13);
1094 /* Update vectorial force */
1095 fix1 = _mm256_add_ps(fix1,tx);
1096 fiy1 = _mm256_add_ps(fiy1,ty);
1097 fiz1 = _mm256_add_ps(fiz1,tz);
1099 fjx3 = _mm256_add_ps(fjx3,tx);
1100 fjy3 = _mm256_add_ps(fjy3,ty);
1101 fjz3 = _mm256_add_ps(fjz3,tz);
1105 /**************************
1106 * CALCULATE INTERACTIONS *
1107 **************************/
1109 if (gmx_mm256_any_lt(rsq21,rcutoff2))
1112 /* REACTION-FIELD ELECTROSTATICS */
1113 velec = _mm256_mul_ps(qq21,_mm256_sub_ps(_mm256_add_ps(rinv21,_mm256_mul_ps(krf,rsq21)),crf));
1114 felec = _mm256_mul_ps(qq21,_mm256_sub_ps(_mm256_mul_ps(rinv21,rinvsq21),krf2));
1116 cutoff_mask = _mm256_cmp_ps(rsq21,rcutoff2,_CMP_LT_OQ);
1118 /* Update potential sum for this i atom from the interaction with this j atom. */
1119 velec = _mm256_and_ps(velec,cutoff_mask);
1120 velec = _mm256_andnot_ps(dummy_mask,velec);
1121 velecsum = _mm256_add_ps(velecsum,velec);
1125 fscal = _mm256_and_ps(fscal,cutoff_mask);
1127 fscal = _mm256_andnot_ps(dummy_mask,fscal);
1129 /* Calculate temporary vectorial force */
1130 tx = _mm256_mul_ps(fscal,dx21);
1131 ty = _mm256_mul_ps(fscal,dy21);
1132 tz = _mm256_mul_ps(fscal,dz21);
1134 /* Update vectorial force */
1135 fix2 = _mm256_add_ps(fix2,tx);
1136 fiy2 = _mm256_add_ps(fiy2,ty);
1137 fiz2 = _mm256_add_ps(fiz2,tz);
1139 fjx1 = _mm256_add_ps(fjx1,tx);
1140 fjy1 = _mm256_add_ps(fjy1,ty);
1141 fjz1 = _mm256_add_ps(fjz1,tz);
1145 /**************************
1146 * CALCULATE INTERACTIONS *
1147 **************************/
1149 if (gmx_mm256_any_lt(rsq22,rcutoff2))
1152 /* REACTION-FIELD ELECTROSTATICS */
1153 velec = _mm256_mul_ps(qq22,_mm256_sub_ps(_mm256_add_ps(rinv22,_mm256_mul_ps(krf,rsq22)),crf));
1154 felec = _mm256_mul_ps(qq22,_mm256_sub_ps(_mm256_mul_ps(rinv22,rinvsq22),krf2));
1156 cutoff_mask = _mm256_cmp_ps(rsq22,rcutoff2,_CMP_LT_OQ);
1158 /* Update potential sum for this i atom from the interaction with this j atom. */
1159 velec = _mm256_and_ps(velec,cutoff_mask);
1160 velec = _mm256_andnot_ps(dummy_mask,velec);
1161 velecsum = _mm256_add_ps(velecsum,velec);
1165 fscal = _mm256_and_ps(fscal,cutoff_mask);
1167 fscal = _mm256_andnot_ps(dummy_mask,fscal);
1169 /* Calculate temporary vectorial force */
1170 tx = _mm256_mul_ps(fscal,dx22);
1171 ty = _mm256_mul_ps(fscal,dy22);
1172 tz = _mm256_mul_ps(fscal,dz22);
1174 /* Update vectorial force */
1175 fix2 = _mm256_add_ps(fix2,tx);
1176 fiy2 = _mm256_add_ps(fiy2,ty);
1177 fiz2 = _mm256_add_ps(fiz2,tz);
1179 fjx2 = _mm256_add_ps(fjx2,tx);
1180 fjy2 = _mm256_add_ps(fjy2,ty);
1181 fjz2 = _mm256_add_ps(fjz2,tz);
1185 /**************************
1186 * CALCULATE INTERACTIONS *
1187 **************************/
1189 if (gmx_mm256_any_lt(rsq23,rcutoff2))
1192 /* REACTION-FIELD ELECTROSTATICS */
1193 velec = _mm256_mul_ps(qq23,_mm256_sub_ps(_mm256_add_ps(rinv23,_mm256_mul_ps(krf,rsq23)),crf));
1194 felec = _mm256_mul_ps(qq23,_mm256_sub_ps(_mm256_mul_ps(rinv23,rinvsq23),krf2));
1196 cutoff_mask = _mm256_cmp_ps(rsq23,rcutoff2,_CMP_LT_OQ);
1198 /* Update potential sum for this i atom from the interaction with this j atom. */
1199 velec = _mm256_and_ps(velec,cutoff_mask);
1200 velec = _mm256_andnot_ps(dummy_mask,velec);
1201 velecsum = _mm256_add_ps(velecsum,velec);
1205 fscal = _mm256_and_ps(fscal,cutoff_mask);
1207 fscal = _mm256_andnot_ps(dummy_mask,fscal);
1209 /* Calculate temporary vectorial force */
1210 tx = _mm256_mul_ps(fscal,dx23);
1211 ty = _mm256_mul_ps(fscal,dy23);
1212 tz = _mm256_mul_ps(fscal,dz23);
1214 /* Update vectorial force */
1215 fix2 = _mm256_add_ps(fix2,tx);
1216 fiy2 = _mm256_add_ps(fiy2,ty);
1217 fiz2 = _mm256_add_ps(fiz2,tz);
1219 fjx3 = _mm256_add_ps(fjx3,tx);
1220 fjy3 = _mm256_add_ps(fjy3,ty);
1221 fjz3 = _mm256_add_ps(fjz3,tz);
1225 /**************************
1226 * CALCULATE INTERACTIONS *
1227 **************************/
1229 if (gmx_mm256_any_lt(rsq31,rcutoff2))
1232 /* REACTION-FIELD ELECTROSTATICS */
1233 velec = _mm256_mul_ps(qq31,_mm256_sub_ps(_mm256_add_ps(rinv31,_mm256_mul_ps(krf,rsq31)),crf));
1234 felec = _mm256_mul_ps(qq31,_mm256_sub_ps(_mm256_mul_ps(rinv31,rinvsq31),krf2));
1236 cutoff_mask = _mm256_cmp_ps(rsq31,rcutoff2,_CMP_LT_OQ);
1238 /* Update potential sum for this i atom from the interaction with this j atom. */
1239 velec = _mm256_and_ps(velec,cutoff_mask);
1240 velec = _mm256_andnot_ps(dummy_mask,velec);
1241 velecsum = _mm256_add_ps(velecsum,velec);
1245 fscal = _mm256_and_ps(fscal,cutoff_mask);
1247 fscal = _mm256_andnot_ps(dummy_mask,fscal);
1249 /* Calculate temporary vectorial force */
1250 tx = _mm256_mul_ps(fscal,dx31);
1251 ty = _mm256_mul_ps(fscal,dy31);
1252 tz = _mm256_mul_ps(fscal,dz31);
1254 /* Update vectorial force */
1255 fix3 = _mm256_add_ps(fix3,tx);
1256 fiy3 = _mm256_add_ps(fiy3,ty);
1257 fiz3 = _mm256_add_ps(fiz3,tz);
1259 fjx1 = _mm256_add_ps(fjx1,tx);
1260 fjy1 = _mm256_add_ps(fjy1,ty);
1261 fjz1 = _mm256_add_ps(fjz1,tz);
1265 /**************************
1266 * CALCULATE INTERACTIONS *
1267 **************************/
1269 if (gmx_mm256_any_lt(rsq32,rcutoff2))
1272 /* REACTION-FIELD ELECTROSTATICS */
1273 velec = _mm256_mul_ps(qq32,_mm256_sub_ps(_mm256_add_ps(rinv32,_mm256_mul_ps(krf,rsq32)),crf));
1274 felec = _mm256_mul_ps(qq32,_mm256_sub_ps(_mm256_mul_ps(rinv32,rinvsq32),krf2));
1276 cutoff_mask = _mm256_cmp_ps(rsq32,rcutoff2,_CMP_LT_OQ);
1278 /* Update potential sum for this i atom from the interaction with this j atom. */
1279 velec = _mm256_and_ps(velec,cutoff_mask);
1280 velec = _mm256_andnot_ps(dummy_mask,velec);
1281 velecsum = _mm256_add_ps(velecsum,velec);
1285 fscal = _mm256_and_ps(fscal,cutoff_mask);
1287 fscal = _mm256_andnot_ps(dummy_mask,fscal);
1289 /* Calculate temporary vectorial force */
1290 tx = _mm256_mul_ps(fscal,dx32);
1291 ty = _mm256_mul_ps(fscal,dy32);
1292 tz = _mm256_mul_ps(fscal,dz32);
1294 /* Update vectorial force */
1295 fix3 = _mm256_add_ps(fix3,tx);
1296 fiy3 = _mm256_add_ps(fiy3,ty);
1297 fiz3 = _mm256_add_ps(fiz3,tz);
1299 fjx2 = _mm256_add_ps(fjx2,tx);
1300 fjy2 = _mm256_add_ps(fjy2,ty);
1301 fjz2 = _mm256_add_ps(fjz2,tz);
1305 /**************************
1306 * CALCULATE INTERACTIONS *
1307 **************************/
1309 if (gmx_mm256_any_lt(rsq33,rcutoff2))
1312 /* REACTION-FIELD ELECTROSTATICS */
1313 velec = _mm256_mul_ps(qq33,_mm256_sub_ps(_mm256_add_ps(rinv33,_mm256_mul_ps(krf,rsq33)),crf));
1314 felec = _mm256_mul_ps(qq33,_mm256_sub_ps(_mm256_mul_ps(rinv33,rinvsq33),krf2));
1316 cutoff_mask = _mm256_cmp_ps(rsq33,rcutoff2,_CMP_LT_OQ);
1318 /* Update potential sum for this i atom from the interaction with this j atom. */
1319 velec = _mm256_and_ps(velec,cutoff_mask);
1320 velec = _mm256_andnot_ps(dummy_mask,velec);
1321 velecsum = _mm256_add_ps(velecsum,velec);
1325 fscal = _mm256_and_ps(fscal,cutoff_mask);
1327 fscal = _mm256_andnot_ps(dummy_mask,fscal);
1329 /* Calculate temporary vectorial force */
1330 tx = _mm256_mul_ps(fscal,dx33);
1331 ty = _mm256_mul_ps(fscal,dy33);
1332 tz = _mm256_mul_ps(fscal,dz33);
1334 /* Update vectorial force */
1335 fix3 = _mm256_add_ps(fix3,tx);
1336 fiy3 = _mm256_add_ps(fiy3,ty);
1337 fiz3 = _mm256_add_ps(fiz3,tz);
1339 fjx3 = _mm256_add_ps(fjx3,tx);
1340 fjy3 = _mm256_add_ps(fjy3,ty);
1341 fjz3 = _mm256_add_ps(fjz3,tz);
1345 fjptrA = (jnrlistA>=0) ? f+j_coord_offsetA : scratch;
1346 fjptrB = (jnrlistB>=0) ? f+j_coord_offsetB : scratch;
1347 fjptrC = (jnrlistC>=0) ? f+j_coord_offsetC : scratch;
1348 fjptrD = (jnrlistD>=0) ? f+j_coord_offsetD : scratch;
1349 fjptrE = (jnrlistE>=0) ? f+j_coord_offsetE : scratch;
1350 fjptrF = (jnrlistF>=0) ? f+j_coord_offsetF : scratch;
1351 fjptrG = (jnrlistG>=0) ? f+j_coord_offsetG : scratch;
1352 fjptrH = (jnrlistH>=0) ? f+j_coord_offsetH : scratch;
1354 gmx_mm256_decrement_4rvec_8ptr_swizzle_ps(fjptrA,fjptrB,fjptrC,fjptrD,fjptrE,fjptrF,fjptrG,fjptrH,
1355 fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,
1356 fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
1358 /* Inner loop uses 388 flops */
1361 /* End of innermost loop */
1363 gmx_mm256_update_iforce_4atom_swizzle_ps(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
1364 f+i_coord_offset,fshift+i_shift_offset);
1367 /* Update potential energies */
1368 gmx_mm256_update_1pot_ps(velecsum,kernel_data->energygrp_elec+ggid);
1369 gmx_mm256_update_1pot_ps(vvdwsum,kernel_data->energygrp_vdw+ggid);
1371 /* Increment number of inner iterations */
1372 inneriter += j_index_end - j_index_start;
1374 /* Outer loop uses 26 flops */
1377 /* Increment number of outer iterations */
1380 /* Update outer/inner flops */
1382 inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4W4_VF,outeriter*26 + inneriter*388);
1385 * Gromacs nonbonded kernel: nb_kernel_ElecRFCut_VdwCSTab_GeomW4W4_F_avx_256_single
1386 * Electrostatics interaction: ReactionField
1387 * VdW interaction: CubicSplineTable
1388 * Geometry: Water4-Water4
1389 * Calculate force/pot: Force
1392 nb_kernel_ElecRFCut_VdwCSTab_GeomW4W4_F_avx_256_single
1393 (t_nblist * gmx_restrict nlist,
1394 rvec * gmx_restrict xx,
1395 rvec * gmx_restrict ff,
1396 t_forcerec * gmx_restrict fr,
1397 t_mdatoms * gmx_restrict mdatoms,
1398 nb_kernel_data_t gmx_unused * gmx_restrict kernel_data,
1399 t_nrnb * gmx_restrict nrnb)
1401 /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
1402 * just 0 for non-waters.
1403 * Suffixes A,B,C,D,E,F,G,H refer to j loop unrolling done with AVX, e.g. for the eight different
1404 * jnr indices corresponding to data put in the four positions in the SIMD register.
1406 int i_shift_offset,i_coord_offset,outeriter,inneriter;
1407 int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
1408 int jnrA,jnrB,jnrC,jnrD;
1409 int jnrE,jnrF,jnrG,jnrH;
1410 int jnrlistA,jnrlistB,jnrlistC,jnrlistD;
1411 int jnrlistE,jnrlistF,jnrlistG,jnrlistH;
1412 int j_coord_offsetA,j_coord_offsetB,j_coord_offsetC,j_coord_offsetD;
1413 int j_coord_offsetE,j_coord_offsetF,j_coord_offsetG,j_coord_offsetH;
1414 int *iinr,*jindex,*jjnr,*shiftidx,*gid;
1415 real rcutoff_scalar;
1416 real *shiftvec,*fshift,*x,*f;
1417 real *fjptrA,*fjptrB,*fjptrC,*fjptrD,*fjptrE,*fjptrF,*fjptrG,*fjptrH;
1418 real scratch[4*DIM];
1419 __m256 tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
1420 real * vdwioffsetptr0;
1421 __m256 ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
1422 real * vdwioffsetptr1;
1423 __m256 ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
1424 real * vdwioffsetptr2;
1425 __m256 ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
1426 real * vdwioffsetptr3;
1427 __m256 ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
1428 int vdwjidx0A,vdwjidx0B,vdwjidx0C,vdwjidx0D,vdwjidx0E,vdwjidx0F,vdwjidx0G,vdwjidx0H;
1429 __m256 jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
1430 int vdwjidx1A,vdwjidx1B,vdwjidx1C,vdwjidx1D,vdwjidx1E,vdwjidx1F,vdwjidx1G,vdwjidx1H;
1431 __m256 jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
1432 int vdwjidx2A,vdwjidx2B,vdwjidx2C,vdwjidx2D,vdwjidx2E,vdwjidx2F,vdwjidx2G,vdwjidx2H;
1433 __m256 jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
1434 int vdwjidx3A,vdwjidx3B,vdwjidx3C,vdwjidx3D,vdwjidx3E,vdwjidx3F,vdwjidx3G,vdwjidx3H;
1435 __m256 jx3,jy3,jz3,fjx3,fjy3,fjz3,jq3,isaj3;
1436 __m256 dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
1437 __m256 dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
1438 __m256 dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
1439 __m256 dx13,dy13,dz13,rsq13,rinv13,rinvsq13,r13,qq13,c6_13,c12_13;
1440 __m256 dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
1441 __m256 dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
1442 __m256 dx23,dy23,dz23,rsq23,rinv23,rinvsq23,r23,qq23,c6_23,c12_23;
1443 __m256 dx31,dy31,dz31,rsq31,rinv31,rinvsq31,r31,qq31,c6_31,c12_31;
1444 __m256 dx32,dy32,dz32,rsq32,rinv32,rinvsq32,r32,qq32,c6_32,c12_32;
1445 __m256 dx33,dy33,dz33,rsq33,rinv33,rinvsq33,r33,qq33,c6_33,c12_33;
1446 __m256 velec,felec,velecsum,facel,crf,krf,krf2;
1449 __m256 rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
1452 __m256 one_sixth = _mm256_set1_ps(1.0/6.0);
1453 __m256 one_twelfth = _mm256_set1_ps(1.0/12.0);
1455 __m128i vfitab_lo,vfitab_hi;
1456 __m128i ifour = _mm_set1_epi32(4);
1457 __m256 rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
1459 __m256 dummy_mask,cutoff_mask;
1460 __m256 signbit = _mm256_castsi256_ps( _mm256_set1_epi32(0x80000000) );
1461 __m256 one = _mm256_set1_ps(1.0);
1462 __m256 two = _mm256_set1_ps(2.0);
1468 jindex = nlist->jindex;
1470 shiftidx = nlist->shift;
1472 shiftvec = fr->shift_vec[0];
1473 fshift = fr->fshift[0];
1474 facel = _mm256_set1_ps(fr->epsfac);
1475 charge = mdatoms->chargeA;
1476 krf = _mm256_set1_ps(fr->ic->k_rf);
1477 krf2 = _mm256_set1_ps(fr->ic->k_rf*2.0);
1478 crf = _mm256_set1_ps(fr->ic->c_rf);
1479 nvdwtype = fr->ntype;
1480 vdwparam = fr->nbfp;
1481 vdwtype = mdatoms->typeA;
1483 vftab = kernel_data->table_vdw->data;
1484 vftabscale = _mm256_set1_ps(kernel_data->table_vdw->scale);
1486 /* Setup water-specific parameters */
1487 inr = nlist->iinr[0];
1488 iq1 = _mm256_mul_ps(facel,_mm256_set1_ps(charge[inr+1]));
1489 iq2 = _mm256_mul_ps(facel,_mm256_set1_ps(charge[inr+2]));
1490 iq3 = _mm256_mul_ps(facel,_mm256_set1_ps(charge[inr+3]));
1491 vdwioffsetptr0 = vdwparam+2*nvdwtype*vdwtype[inr+0];
1493 jq1 = _mm256_set1_ps(charge[inr+1]);
1494 jq2 = _mm256_set1_ps(charge[inr+2]);
1495 jq3 = _mm256_set1_ps(charge[inr+3]);
1496 vdwjidx0A = 2*vdwtype[inr+0];
1497 c6_00 = _mm256_set1_ps(vdwioffsetptr0[vdwjidx0A]);
1498 c12_00 = _mm256_set1_ps(vdwioffsetptr0[vdwjidx0A+1]);
1499 qq11 = _mm256_mul_ps(iq1,jq1);
1500 qq12 = _mm256_mul_ps(iq1,jq2);
1501 qq13 = _mm256_mul_ps(iq1,jq3);
1502 qq21 = _mm256_mul_ps(iq2,jq1);
1503 qq22 = _mm256_mul_ps(iq2,jq2);
1504 qq23 = _mm256_mul_ps(iq2,jq3);
1505 qq31 = _mm256_mul_ps(iq3,jq1);
1506 qq32 = _mm256_mul_ps(iq3,jq2);
1507 qq33 = _mm256_mul_ps(iq3,jq3);
1509 /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
1510 rcutoff_scalar = fr->rcoulomb;
1511 rcutoff = _mm256_set1_ps(rcutoff_scalar);
1512 rcutoff2 = _mm256_mul_ps(rcutoff,rcutoff);
1514 /* Avoid stupid compiler warnings */
1515 jnrA = jnrB = jnrC = jnrD = jnrE = jnrF = jnrG = jnrH = 0;
1516 j_coord_offsetA = 0;
1517 j_coord_offsetB = 0;
1518 j_coord_offsetC = 0;
1519 j_coord_offsetD = 0;
1520 j_coord_offsetE = 0;
1521 j_coord_offsetF = 0;
1522 j_coord_offsetG = 0;
1523 j_coord_offsetH = 0;
1528 for(iidx=0;iidx<4*DIM;iidx++)
1530 scratch[iidx] = 0.0;
1533 /* Start outer loop over neighborlists */
1534 for(iidx=0; iidx<nri; iidx++)
1536 /* Load shift vector for this list */
1537 i_shift_offset = DIM*shiftidx[iidx];
1539 /* Load limits for loop over neighbors */
1540 j_index_start = jindex[iidx];
1541 j_index_end = jindex[iidx+1];
1543 /* Get outer coordinate index */
1545 i_coord_offset = DIM*inr;
1547 /* Load i particle coords and add shift vector */
1548 gmx_mm256_load_shift_and_4rvec_broadcast_ps(shiftvec+i_shift_offset,x+i_coord_offset,
1549 &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
1551 fix0 = _mm256_setzero_ps();
1552 fiy0 = _mm256_setzero_ps();
1553 fiz0 = _mm256_setzero_ps();
1554 fix1 = _mm256_setzero_ps();
1555 fiy1 = _mm256_setzero_ps();
1556 fiz1 = _mm256_setzero_ps();
1557 fix2 = _mm256_setzero_ps();
1558 fiy2 = _mm256_setzero_ps();
1559 fiz2 = _mm256_setzero_ps();
1560 fix3 = _mm256_setzero_ps();
1561 fiy3 = _mm256_setzero_ps();
1562 fiz3 = _mm256_setzero_ps();
1564 /* Start inner kernel loop */
1565 for(jidx=j_index_start; jidx<j_index_end && jjnr[jidx+7]>=0; jidx+=8)
1568 /* Get j neighbor index, and coordinate index */
1570 jnrB = jjnr[jidx+1];
1571 jnrC = jjnr[jidx+2];
1572 jnrD = jjnr[jidx+3];
1573 jnrE = jjnr[jidx+4];
1574 jnrF = jjnr[jidx+5];
1575 jnrG = jjnr[jidx+6];
1576 jnrH = jjnr[jidx+7];
1577 j_coord_offsetA = DIM*jnrA;
1578 j_coord_offsetB = DIM*jnrB;
1579 j_coord_offsetC = DIM*jnrC;
1580 j_coord_offsetD = DIM*jnrD;
1581 j_coord_offsetE = DIM*jnrE;
1582 j_coord_offsetF = DIM*jnrF;
1583 j_coord_offsetG = DIM*jnrG;
1584 j_coord_offsetH = DIM*jnrH;
1586 /* load j atom coordinates */
1587 gmx_mm256_load_4rvec_8ptr_swizzle_ps(x+j_coord_offsetA,x+j_coord_offsetB,
1588 x+j_coord_offsetC,x+j_coord_offsetD,
1589 x+j_coord_offsetE,x+j_coord_offsetF,
1590 x+j_coord_offsetG,x+j_coord_offsetH,
1591 &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
1592 &jy2,&jz2,&jx3,&jy3,&jz3);
1594 /* Calculate displacement vector */
1595 dx00 = _mm256_sub_ps(ix0,jx0);
1596 dy00 = _mm256_sub_ps(iy0,jy0);
1597 dz00 = _mm256_sub_ps(iz0,jz0);
1598 dx11 = _mm256_sub_ps(ix1,jx1);
1599 dy11 = _mm256_sub_ps(iy1,jy1);
1600 dz11 = _mm256_sub_ps(iz1,jz1);
1601 dx12 = _mm256_sub_ps(ix1,jx2);
1602 dy12 = _mm256_sub_ps(iy1,jy2);
1603 dz12 = _mm256_sub_ps(iz1,jz2);
1604 dx13 = _mm256_sub_ps(ix1,jx3);
1605 dy13 = _mm256_sub_ps(iy1,jy3);
1606 dz13 = _mm256_sub_ps(iz1,jz3);
1607 dx21 = _mm256_sub_ps(ix2,jx1);
1608 dy21 = _mm256_sub_ps(iy2,jy1);
1609 dz21 = _mm256_sub_ps(iz2,jz1);
1610 dx22 = _mm256_sub_ps(ix2,jx2);
1611 dy22 = _mm256_sub_ps(iy2,jy2);
1612 dz22 = _mm256_sub_ps(iz2,jz2);
1613 dx23 = _mm256_sub_ps(ix2,jx3);
1614 dy23 = _mm256_sub_ps(iy2,jy3);
1615 dz23 = _mm256_sub_ps(iz2,jz3);
1616 dx31 = _mm256_sub_ps(ix3,jx1);
1617 dy31 = _mm256_sub_ps(iy3,jy1);
1618 dz31 = _mm256_sub_ps(iz3,jz1);
1619 dx32 = _mm256_sub_ps(ix3,jx2);
1620 dy32 = _mm256_sub_ps(iy3,jy2);
1621 dz32 = _mm256_sub_ps(iz3,jz2);
1622 dx33 = _mm256_sub_ps(ix3,jx3);
1623 dy33 = _mm256_sub_ps(iy3,jy3);
1624 dz33 = _mm256_sub_ps(iz3,jz3);
1626 /* Calculate squared distance and things based on it */
1627 rsq00 = gmx_mm256_calc_rsq_ps(dx00,dy00,dz00);
1628 rsq11 = gmx_mm256_calc_rsq_ps(dx11,dy11,dz11);
1629 rsq12 = gmx_mm256_calc_rsq_ps(dx12,dy12,dz12);
1630 rsq13 = gmx_mm256_calc_rsq_ps(dx13,dy13,dz13);
1631 rsq21 = gmx_mm256_calc_rsq_ps(dx21,dy21,dz21);
1632 rsq22 = gmx_mm256_calc_rsq_ps(dx22,dy22,dz22);
1633 rsq23 = gmx_mm256_calc_rsq_ps(dx23,dy23,dz23);
1634 rsq31 = gmx_mm256_calc_rsq_ps(dx31,dy31,dz31);
1635 rsq32 = gmx_mm256_calc_rsq_ps(dx32,dy32,dz32);
1636 rsq33 = gmx_mm256_calc_rsq_ps(dx33,dy33,dz33);
1638 rinv00 = gmx_mm256_invsqrt_ps(rsq00);
1639 rinv11 = gmx_mm256_invsqrt_ps(rsq11);
1640 rinv12 = gmx_mm256_invsqrt_ps(rsq12);
1641 rinv13 = gmx_mm256_invsqrt_ps(rsq13);
1642 rinv21 = gmx_mm256_invsqrt_ps(rsq21);
1643 rinv22 = gmx_mm256_invsqrt_ps(rsq22);
1644 rinv23 = gmx_mm256_invsqrt_ps(rsq23);
1645 rinv31 = gmx_mm256_invsqrt_ps(rsq31);
1646 rinv32 = gmx_mm256_invsqrt_ps(rsq32);
1647 rinv33 = gmx_mm256_invsqrt_ps(rsq33);
1649 rinvsq11 = _mm256_mul_ps(rinv11,rinv11);
1650 rinvsq12 = _mm256_mul_ps(rinv12,rinv12);
1651 rinvsq13 = _mm256_mul_ps(rinv13,rinv13);
1652 rinvsq21 = _mm256_mul_ps(rinv21,rinv21);
1653 rinvsq22 = _mm256_mul_ps(rinv22,rinv22);
1654 rinvsq23 = _mm256_mul_ps(rinv23,rinv23);
1655 rinvsq31 = _mm256_mul_ps(rinv31,rinv31);
1656 rinvsq32 = _mm256_mul_ps(rinv32,rinv32);
1657 rinvsq33 = _mm256_mul_ps(rinv33,rinv33);
1659 fjx0 = _mm256_setzero_ps();
1660 fjy0 = _mm256_setzero_ps();
1661 fjz0 = _mm256_setzero_ps();
1662 fjx1 = _mm256_setzero_ps();
1663 fjy1 = _mm256_setzero_ps();
1664 fjz1 = _mm256_setzero_ps();
1665 fjx2 = _mm256_setzero_ps();
1666 fjy2 = _mm256_setzero_ps();
1667 fjz2 = _mm256_setzero_ps();
1668 fjx3 = _mm256_setzero_ps();
1669 fjy3 = _mm256_setzero_ps();
1670 fjz3 = _mm256_setzero_ps();
1672 /**************************
1673 * CALCULATE INTERACTIONS *
1674 **************************/
1676 if (gmx_mm256_any_lt(rsq00,rcutoff2))
1679 r00 = _mm256_mul_ps(rsq00,rinv00);
1681 /* Calculate table index by multiplying r with table scale and truncate to integer */
1682 rt = _mm256_mul_ps(r00,vftabscale);
1683 vfitab = _mm256_cvttps_epi32(rt);
1684 vfeps = _mm256_sub_ps(rt,_mm256_round_ps(rt, _MM_FROUND_FLOOR));
1685 /* AVX1 does not support 256-bit integer operations, so now we go to 128-bit mode... */
1686 vfitab_lo = _mm256_extractf128_si256(vfitab,0x0);
1687 vfitab_hi = _mm256_extractf128_si256(vfitab,0x1);
1688 vfitab_lo = _mm_slli_epi32(vfitab_lo,3);
1689 vfitab_hi = _mm_slli_epi32(vfitab_hi,3);
1691 /* CUBIC SPLINE TABLE DISPERSION */
1692 Y = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,0)),
1693 _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,0)));
1694 F = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,1)),
1695 _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,1)));
1696 G = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,2)),
1697 _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,2)));
1698 H = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,3)),
1699 _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,3)));
1700 GMX_MM256_HALFTRANSPOSE4_PS(Y,F,G,H);
1701 Heps = _mm256_mul_ps(vfeps,H);
1702 Fp = _mm256_add_ps(F,_mm256_mul_ps(vfeps,_mm256_add_ps(G,Heps)));
1703 FF = _mm256_add_ps(Fp,_mm256_mul_ps(vfeps,_mm256_add_ps(G,_mm256_add_ps(Heps,Heps))));
1704 fvdw6 = _mm256_mul_ps(c6_00,FF);
1706 /* CUBIC SPLINE TABLE REPULSION */
1707 vfitab_lo = _mm_add_epi32(vfitab_lo,ifour);
1708 vfitab_hi = _mm_add_epi32(vfitab_hi,ifour);
1709 Y = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,0)),
1710 _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,0)));
1711 F = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,1)),
1712 _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,1)));
1713 G = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,2)),
1714 _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,2)));
1715 H = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,3)),
1716 _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,3)));
1717 GMX_MM256_HALFTRANSPOSE4_PS(Y,F,G,H);
1718 Heps = _mm256_mul_ps(vfeps,H);
1719 Fp = _mm256_add_ps(F,_mm256_mul_ps(vfeps,_mm256_add_ps(G,Heps)));
1720 FF = _mm256_add_ps(Fp,_mm256_mul_ps(vfeps,_mm256_add_ps(G,_mm256_add_ps(Heps,Heps))));
1721 fvdw12 = _mm256_mul_ps(c12_00,FF);
1722 fvdw = _mm256_xor_ps(signbit,_mm256_mul_ps(_mm256_add_ps(fvdw6,fvdw12),_mm256_mul_ps(vftabscale,rinv00)));
1724 cutoff_mask = _mm256_cmp_ps(rsq00,rcutoff2,_CMP_LT_OQ);
1728 fscal = _mm256_and_ps(fscal,cutoff_mask);
1730 /* Calculate temporary vectorial force */
1731 tx = _mm256_mul_ps(fscal,dx00);
1732 ty = _mm256_mul_ps(fscal,dy00);
1733 tz = _mm256_mul_ps(fscal,dz00);
1735 /* Update vectorial force */
1736 fix0 = _mm256_add_ps(fix0,tx);
1737 fiy0 = _mm256_add_ps(fiy0,ty);
1738 fiz0 = _mm256_add_ps(fiz0,tz);
1740 fjx0 = _mm256_add_ps(fjx0,tx);
1741 fjy0 = _mm256_add_ps(fjy0,ty);
1742 fjz0 = _mm256_add_ps(fjz0,tz);
1746 /**************************
1747 * CALCULATE INTERACTIONS *
1748 **************************/
1750 if (gmx_mm256_any_lt(rsq11,rcutoff2))
1753 /* REACTION-FIELD ELECTROSTATICS */
1754 felec = _mm256_mul_ps(qq11,_mm256_sub_ps(_mm256_mul_ps(rinv11,rinvsq11),krf2));
1756 cutoff_mask = _mm256_cmp_ps(rsq11,rcutoff2,_CMP_LT_OQ);
1760 fscal = _mm256_and_ps(fscal,cutoff_mask);
1762 /* Calculate temporary vectorial force */
1763 tx = _mm256_mul_ps(fscal,dx11);
1764 ty = _mm256_mul_ps(fscal,dy11);
1765 tz = _mm256_mul_ps(fscal,dz11);
1767 /* Update vectorial force */
1768 fix1 = _mm256_add_ps(fix1,tx);
1769 fiy1 = _mm256_add_ps(fiy1,ty);
1770 fiz1 = _mm256_add_ps(fiz1,tz);
1772 fjx1 = _mm256_add_ps(fjx1,tx);
1773 fjy1 = _mm256_add_ps(fjy1,ty);
1774 fjz1 = _mm256_add_ps(fjz1,tz);
1778 /**************************
1779 * CALCULATE INTERACTIONS *
1780 **************************/
1782 if (gmx_mm256_any_lt(rsq12,rcutoff2))
1785 /* REACTION-FIELD ELECTROSTATICS */
1786 felec = _mm256_mul_ps(qq12,_mm256_sub_ps(_mm256_mul_ps(rinv12,rinvsq12),krf2));
1788 cutoff_mask = _mm256_cmp_ps(rsq12,rcutoff2,_CMP_LT_OQ);
1792 fscal = _mm256_and_ps(fscal,cutoff_mask);
1794 /* Calculate temporary vectorial force */
1795 tx = _mm256_mul_ps(fscal,dx12);
1796 ty = _mm256_mul_ps(fscal,dy12);
1797 tz = _mm256_mul_ps(fscal,dz12);
1799 /* Update vectorial force */
1800 fix1 = _mm256_add_ps(fix1,tx);
1801 fiy1 = _mm256_add_ps(fiy1,ty);
1802 fiz1 = _mm256_add_ps(fiz1,tz);
1804 fjx2 = _mm256_add_ps(fjx2,tx);
1805 fjy2 = _mm256_add_ps(fjy2,ty);
1806 fjz2 = _mm256_add_ps(fjz2,tz);
1810 /**************************
1811 * CALCULATE INTERACTIONS *
1812 **************************/
1814 if (gmx_mm256_any_lt(rsq13,rcutoff2))
1817 /* REACTION-FIELD ELECTROSTATICS */
1818 felec = _mm256_mul_ps(qq13,_mm256_sub_ps(_mm256_mul_ps(rinv13,rinvsq13),krf2));
1820 cutoff_mask = _mm256_cmp_ps(rsq13,rcutoff2,_CMP_LT_OQ);
1824 fscal = _mm256_and_ps(fscal,cutoff_mask);
1826 /* Calculate temporary vectorial force */
1827 tx = _mm256_mul_ps(fscal,dx13);
1828 ty = _mm256_mul_ps(fscal,dy13);
1829 tz = _mm256_mul_ps(fscal,dz13);
1831 /* Update vectorial force */
1832 fix1 = _mm256_add_ps(fix1,tx);
1833 fiy1 = _mm256_add_ps(fiy1,ty);
1834 fiz1 = _mm256_add_ps(fiz1,tz);
1836 fjx3 = _mm256_add_ps(fjx3,tx);
1837 fjy3 = _mm256_add_ps(fjy3,ty);
1838 fjz3 = _mm256_add_ps(fjz3,tz);
1842 /**************************
1843 * CALCULATE INTERACTIONS *
1844 **************************/
1846 if (gmx_mm256_any_lt(rsq21,rcutoff2))
1849 /* REACTION-FIELD ELECTROSTATICS */
1850 felec = _mm256_mul_ps(qq21,_mm256_sub_ps(_mm256_mul_ps(rinv21,rinvsq21),krf2));
1852 cutoff_mask = _mm256_cmp_ps(rsq21,rcutoff2,_CMP_LT_OQ);
1856 fscal = _mm256_and_ps(fscal,cutoff_mask);
1858 /* Calculate temporary vectorial force */
1859 tx = _mm256_mul_ps(fscal,dx21);
1860 ty = _mm256_mul_ps(fscal,dy21);
1861 tz = _mm256_mul_ps(fscal,dz21);
1863 /* Update vectorial force */
1864 fix2 = _mm256_add_ps(fix2,tx);
1865 fiy2 = _mm256_add_ps(fiy2,ty);
1866 fiz2 = _mm256_add_ps(fiz2,tz);
1868 fjx1 = _mm256_add_ps(fjx1,tx);
1869 fjy1 = _mm256_add_ps(fjy1,ty);
1870 fjz1 = _mm256_add_ps(fjz1,tz);
1874 /**************************
1875 * CALCULATE INTERACTIONS *
1876 **************************/
1878 if (gmx_mm256_any_lt(rsq22,rcutoff2))
1881 /* REACTION-FIELD ELECTROSTATICS */
1882 felec = _mm256_mul_ps(qq22,_mm256_sub_ps(_mm256_mul_ps(rinv22,rinvsq22),krf2));
1884 cutoff_mask = _mm256_cmp_ps(rsq22,rcutoff2,_CMP_LT_OQ);
1888 fscal = _mm256_and_ps(fscal,cutoff_mask);
1890 /* Calculate temporary vectorial force */
1891 tx = _mm256_mul_ps(fscal,dx22);
1892 ty = _mm256_mul_ps(fscal,dy22);
1893 tz = _mm256_mul_ps(fscal,dz22);
1895 /* Update vectorial force */
1896 fix2 = _mm256_add_ps(fix2,tx);
1897 fiy2 = _mm256_add_ps(fiy2,ty);
1898 fiz2 = _mm256_add_ps(fiz2,tz);
1900 fjx2 = _mm256_add_ps(fjx2,tx);
1901 fjy2 = _mm256_add_ps(fjy2,ty);
1902 fjz2 = _mm256_add_ps(fjz2,tz);
1906 /**************************
1907 * CALCULATE INTERACTIONS *
1908 **************************/
1910 if (gmx_mm256_any_lt(rsq23,rcutoff2))
1913 /* REACTION-FIELD ELECTROSTATICS */
1914 felec = _mm256_mul_ps(qq23,_mm256_sub_ps(_mm256_mul_ps(rinv23,rinvsq23),krf2));
1916 cutoff_mask = _mm256_cmp_ps(rsq23,rcutoff2,_CMP_LT_OQ);
1920 fscal = _mm256_and_ps(fscal,cutoff_mask);
1922 /* Calculate temporary vectorial force */
1923 tx = _mm256_mul_ps(fscal,dx23);
1924 ty = _mm256_mul_ps(fscal,dy23);
1925 tz = _mm256_mul_ps(fscal,dz23);
1927 /* Update vectorial force */
1928 fix2 = _mm256_add_ps(fix2,tx);
1929 fiy2 = _mm256_add_ps(fiy2,ty);
1930 fiz2 = _mm256_add_ps(fiz2,tz);
1932 fjx3 = _mm256_add_ps(fjx3,tx);
1933 fjy3 = _mm256_add_ps(fjy3,ty);
1934 fjz3 = _mm256_add_ps(fjz3,tz);
1938 /**************************
1939 * CALCULATE INTERACTIONS *
1940 **************************/
1942 if (gmx_mm256_any_lt(rsq31,rcutoff2))
1945 /* REACTION-FIELD ELECTROSTATICS */
1946 felec = _mm256_mul_ps(qq31,_mm256_sub_ps(_mm256_mul_ps(rinv31,rinvsq31),krf2));
1948 cutoff_mask = _mm256_cmp_ps(rsq31,rcutoff2,_CMP_LT_OQ);
1952 fscal = _mm256_and_ps(fscal,cutoff_mask);
1954 /* Calculate temporary vectorial force */
1955 tx = _mm256_mul_ps(fscal,dx31);
1956 ty = _mm256_mul_ps(fscal,dy31);
1957 tz = _mm256_mul_ps(fscal,dz31);
1959 /* Update vectorial force */
1960 fix3 = _mm256_add_ps(fix3,tx);
1961 fiy3 = _mm256_add_ps(fiy3,ty);
1962 fiz3 = _mm256_add_ps(fiz3,tz);
1964 fjx1 = _mm256_add_ps(fjx1,tx);
1965 fjy1 = _mm256_add_ps(fjy1,ty);
1966 fjz1 = _mm256_add_ps(fjz1,tz);
1970 /**************************
1971 * CALCULATE INTERACTIONS *
1972 **************************/
1974 if (gmx_mm256_any_lt(rsq32,rcutoff2))
1977 /* REACTION-FIELD ELECTROSTATICS */
1978 felec = _mm256_mul_ps(qq32,_mm256_sub_ps(_mm256_mul_ps(rinv32,rinvsq32),krf2));
1980 cutoff_mask = _mm256_cmp_ps(rsq32,rcutoff2,_CMP_LT_OQ);
1984 fscal = _mm256_and_ps(fscal,cutoff_mask);
1986 /* Calculate temporary vectorial force */
1987 tx = _mm256_mul_ps(fscal,dx32);
1988 ty = _mm256_mul_ps(fscal,dy32);
1989 tz = _mm256_mul_ps(fscal,dz32);
1991 /* Update vectorial force */
1992 fix3 = _mm256_add_ps(fix3,tx);
1993 fiy3 = _mm256_add_ps(fiy3,ty);
1994 fiz3 = _mm256_add_ps(fiz3,tz);
1996 fjx2 = _mm256_add_ps(fjx2,tx);
1997 fjy2 = _mm256_add_ps(fjy2,ty);
1998 fjz2 = _mm256_add_ps(fjz2,tz);
2002 /**************************
2003 * CALCULATE INTERACTIONS *
2004 **************************/
2006 if (gmx_mm256_any_lt(rsq33,rcutoff2))
2009 /* REACTION-FIELD ELECTROSTATICS */
2010 felec = _mm256_mul_ps(qq33,_mm256_sub_ps(_mm256_mul_ps(rinv33,rinvsq33),krf2));
2012 cutoff_mask = _mm256_cmp_ps(rsq33,rcutoff2,_CMP_LT_OQ);
2016 fscal = _mm256_and_ps(fscal,cutoff_mask);
2018 /* Calculate temporary vectorial force */
2019 tx = _mm256_mul_ps(fscal,dx33);
2020 ty = _mm256_mul_ps(fscal,dy33);
2021 tz = _mm256_mul_ps(fscal,dz33);
2023 /* Update vectorial force */
2024 fix3 = _mm256_add_ps(fix3,tx);
2025 fiy3 = _mm256_add_ps(fiy3,ty);
2026 fiz3 = _mm256_add_ps(fiz3,tz);
2028 fjx3 = _mm256_add_ps(fjx3,tx);
2029 fjy3 = _mm256_add_ps(fjy3,ty);
2030 fjz3 = _mm256_add_ps(fjz3,tz);
2034 fjptrA = f+j_coord_offsetA;
2035 fjptrB = f+j_coord_offsetB;
2036 fjptrC = f+j_coord_offsetC;
2037 fjptrD = f+j_coord_offsetD;
2038 fjptrE = f+j_coord_offsetE;
2039 fjptrF = f+j_coord_offsetF;
2040 fjptrG = f+j_coord_offsetG;
2041 fjptrH = f+j_coord_offsetH;
2043 gmx_mm256_decrement_4rvec_8ptr_swizzle_ps(fjptrA,fjptrB,fjptrC,fjptrD,fjptrE,fjptrF,fjptrG,fjptrH,
2044 fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,
2045 fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
2047 /* Inner loop uses 324 flops */
2050 if(jidx<j_index_end)
2053 /* Get j neighbor index, and coordinate index */
2054 jnrlistA = jjnr[jidx];
2055 jnrlistB = jjnr[jidx+1];
2056 jnrlistC = jjnr[jidx+2];
2057 jnrlistD = jjnr[jidx+3];
2058 jnrlistE = jjnr[jidx+4];
2059 jnrlistF = jjnr[jidx+5];
2060 jnrlistG = jjnr[jidx+6];
2061 jnrlistH = jjnr[jidx+7];
2062 /* Sign of each element will be negative for non-real atoms.
2063 * This mask will be 0xFFFFFFFF for dummy entries and 0x0 for real ones,
2064 * so use it as val = _mm_andnot_ps(mask,val) to clear dummy entries.
2066 dummy_mask = gmx_mm256_set_m128(gmx_mm_castsi128_ps(_mm_cmplt_epi32(_mm_loadu_si128((const __m128i *)(jjnr+jidx+4)),_mm_setzero_si128())),
2067 gmx_mm_castsi128_ps(_mm_cmplt_epi32(_mm_loadu_si128((const __m128i *)(jjnr+jidx)),_mm_setzero_si128())));
2069 jnrA = (jnrlistA>=0) ? jnrlistA : 0;
2070 jnrB = (jnrlistB>=0) ? jnrlistB : 0;
2071 jnrC = (jnrlistC>=0) ? jnrlistC : 0;
2072 jnrD = (jnrlistD>=0) ? jnrlistD : 0;
2073 jnrE = (jnrlistE>=0) ? jnrlistE : 0;
2074 jnrF = (jnrlistF>=0) ? jnrlistF : 0;
2075 jnrG = (jnrlistG>=0) ? jnrlistG : 0;
2076 jnrH = (jnrlistH>=0) ? jnrlistH : 0;
2077 j_coord_offsetA = DIM*jnrA;
2078 j_coord_offsetB = DIM*jnrB;
2079 j_coord_offsetC = DIM*jnrC;
2080 j_coord_offsetD = DIM*jnrD;
2081 j_coord_offsetE = DIM*jnrE;
2082 j_coord_offsetF = DIM*jnrF;
2083 j_coord_offsetG = DIM*jnrG;
2084 j_coord_offsetH = DIM*jnrH;
2086 /* load j atom coordinates */
2087 gmx_mm256_load_4rvec_8ptr_swizzle_ps(x+j_coord_offsetA,x+j_coord_offsetB,
2088 x+j_coord_offsetC,x+j_coord_offsetD,
2089 x+j_coord_offsetE,x+j_coord_offsetF,
2090 x+j_coord_offsetG,x+j_coord_offsetH,
2091 &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
2092 &jy2,&jz2,&jx3,&jy3,&jz3);
2094 /* Calculate displacement vector */
2095 dx00 = _mm256_sub_ps(ix0,jx0);
2096 dy00 = _mm256_sub_ps(iy0,jy0);
2097 dz00 = _mm256_sub_ps(iz0,jz0);
2098 dx11 = _mm256_sub_ps(ix1,jx1);
2099 dy11 = _mm256_sub_ps(iy1,jy1);
2100 dz11 = _mm256_sub_ps(iz1,jz1);
2101 dx12 = _mm256_sub_ps(ix1,jx2);
2102 dy12 = _mm256_sub_ps(iy1,jy2);
2103 dz12 = _mm256_sub_ps(iz1,jz2);
2104 dx13 = _mm256_sub_ps(ix1,jx3);
2105 dy13 = _mm256_sub_ps(iy1,jy3);
2106 dz13 = _mm256_sub_ps(iz1,jz3);
2107 dx21 = _mm256_sub_ps(ix2,jx1);
2108 dy21 = _mm256_sub_ps(iy2,jy1);
2109 dz21 = _mm256_sub_ps(iz2,jz1);
2110 dx22 = _mm256_sub_ps(ix2,jx2);
2111 dy22 = _mm256_sub_ps(iy2,jy2);
2112 dz22 = _mm256_sub_ps(iz2,jz2);
2113 dx23 = _mm256_sub_ps(ix2,jx3);
2114 dy23 = _mm256_sub_ps(iy2,jy3);
2115 dz23 = _mm256_sub_ps(iz2,jz3);
2116 dx31 = _mm256_sub_ps(ix3,jx1);
2117 dy31 = _mm256_sub_ps(iy3,jy1);
2118 dz31 = _mm256_sub_ps(iz3,jz1);
2119 dx32 = _mm256_sub_ps(ix3,jx2);
2120 dy32 = _mm256_sub_ps(iy3,jy2);
2121 dz32 = _mm256_sub_ps(iz3,jz2);
2122 dx33 = _mm256_sub_ps(ix3,jx3);
2123 dy33 = _mm256_sub_ps(iy3,jy3);
2124 dz33 = _mm256_sub_ps(iz3,jz3);
2126 /* Calculate squared distance and things based on it */
2127 rsq00 = gmx_mm256_calc_rsq_ps(dx00,dy00,dz00);
2128 rsq11 = gmx_mm256_calc_rsq_ps(dx11,dy11,dz11);
2129 rsq12 = gmx_mm256_calc_rsq_ps(dx12,dy12,dz12);
2130 rsq13 = gmx_mm256_calc_rsq_ps(dx13,dy13,dz13);
2131 rsq21 = gmx_mm256_calc_rsq_ps(dx21,dy21,dz21);
2132 rsq22 = gmx_mm256_calc_rsq_ps(dx22,dy22,dz22);
2133 rsq23 = gmx_mm256_calc_rsq_ps(dx23,dy23,dz23);
2134 rsq31 = gmx_mm256_calc_rsq_ps(dx31,dy31,dz31);
2135 rsq32 = gmx_mm256_calc_rsq_ps(dx32,dy32,dz32);
2136 rsq33 = gmx_mm256_calc_rsq_ps(dx33,dy33,dz33);
2138 rinv00 = gmx_mm256_invsqrt_ps(rsq00);
2139 rinv11 = gmx_mm256_invsqrt_ps(rsq11);
2140 rinv12 = gmx_mm256_invsqrt_ps(rsq12);
2141 rinv13 = gmx_mm256_invsqrt_ps(rsq13);
2142 rinv21 = gmx_mm256_invsqrt_ps(rsq21);
2143 rinv22 = gmx_mm256_invsqrt_ps(rsq22);
2144 rinv23 = gmx_mm256_invsqrt_ps(rsq23);
2145 rinv31 = gmx_mm256_invsqrt_ps(rsq31);
2146 rinv32 = gmx_mm256_invsqrt_ps(rsq32);
2147 rinv33 = gmx_mm256_invsqrt_ps(rsq33);
2149 rinvsq11 = _mm256_mul_ps(rinv11,rinv11);
2150 rinvsq12 = _mm256_mul_ps(rinv12,rinv12);
2151 rinvsq13 = _mm256_mul_ps(rinv13,rinv13);
2152 rinvsq21 = _mm256_mul_ps(rinv21,rinv21);
2153 rinvsq22 = _mm256_mul_ps(rinv22,rinv22);
2154 rinvsq23 = _mm256_mul_ps(rinv23,rinv23);
2155 rinvsq31 = _mm256_mul_ps(rinv31,rinv31);
2156 rinvsq32 = _mm256_mul_ps(rinv32,rinv32);
2157 rinvsq33 = _mm256_mul_ps(rinv33,rinv33);
2159 fjx0 = _mm256_setzero_ps();
2160 fjy0 = _mm256_setzero_ps();
2161 fjz0 = _mm256_setzero_ps();
2162 fjx1 = _mm256_setzero_ps();
2163 fjy1 = _mm256_setzero_ps();
2164 fjz1 = _mm256_setzero_ps();
2165 fjx2 = _mm256_setzero_ps();
2166 fjy2 = _mm256_setzero_ps();
2167 fjz2 = _mm256_setzero_ps();
2168 fjx3 = _mm256_setzero_ps();
2169 fjy3 = _mm256_setzero_ps();
2170 fjz3 = _mm256_setzero_ps();
2172 /**************************
2173 * CALCULATE INTERACTIONS *
2174 **************************/
2176 if (gmx_mm256_any_lt(rsq00,rcutoff2))
2179 r00 = _mm256_mul_ps(rsq00,rinv00);
2180 r00 = _mm256_andnot_ps(dummy_mask,r00);
2182 /* Calculate table index by multiplying r with table scale and truncate to integer */
2183 rt = _mm256_mul_ps(r00,vftabscale);
2184 vfitab = _mm256_cvttps_epi32(rt);
2185 vfeps = _mm256_sub_ps(rt,_mm256_round_ps(rt, _MM_FROUND_FLOOR));
2186 /* AVX1 does not support 256-bit integer operations, so now we go to 128-bit mode... */
2187 vfitab_lo = _mm256_extractf128_si256(vfitab,0x0);
2188 vfitab_hi = _mm256_extractf128_si256(vfitab,0x1);
2189 vfitab_lo = _mm_slli_epi32(vfitab_lo,3);
2190 vfitab_hi = _mm_slli_epi32(vfitab_hi,3);
2192 /* CUBIC SPLINE TABLE DISPERSION */
2193 Y = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,0)),
2194 _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,0)));
2195 F = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,1)),
2196 _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,1)));
2197 G = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,2)),
2198 _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,2)));
2199 H = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,3)),
2200 _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,3)));
2201 GMX_MM256_HALFTRANSPOSE4_PS(Y,F,G,H);
2202 Heps = _mm256_mul_ps(vfeps,H);
2203 Fp = _mm256_add_ps(F,_mm256_mul_ps(vfeps,_mm256_add_ps(G,Heps)));
2204 FF = _mm256_add_ps(Fp,_mm256_mul_ps(vfeps,_mm256_add_ps(G,_mm256_add_ps(Heps,Heps))));
2205 fvdw6 = _mm256_mul_ps(c6_00,FF);
2207 /* CUBIC SPLINE TABLE REPULSION */
2208 vfitab_lo = _mm_add_epi32(vfitab_lo,ifour);
2209 vfitab_hi = _mm_add_epi32(vfitab_hi,ifour);
2210 Y = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,0)),
2211 _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,0)));
2212 F = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,1)),
2213 _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,1)));
2214 G = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,2)),
2215 _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,2)));
2216 H = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,3)),
2217 _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,3)));
2218 GMX_MM256_HALFTRANSPOSE4_PS(Y,F,G,H);
2219 Heps = _mm256_mul_ps(vfeps,H);
2220 Fp = _mm256_add_ps(F,_mm256_mul_ps(vfeps,_mm256_add_ps(G,Heps)));
2221 FF = _mm256_add_ps(Fp,_mm256_mul_ps(vfeps,_mm256_add_ps(G,_mm256_add_ps(Heps,Heps))));
2222 fvdw12 = _mm256_mul_ps(c12_00,FF);
2223 fvdw = _mm256_xor_ps(signbit,_mm256_mul_ps(_mm256_add_ps(fvdw6,fvdw12),_mm256_mul_ps(vftabscale,rinv00)));
2225 cutoff_mask = _mm256_cmp_ps(rsq00,rcutoff2,_CMP_LT_OQ);
2229 fscal = _mm256_and_ps(fscal,cutoff_mask);
2231 fscal = _mm256_andnot_ps(dummy_mask,fscal);
2233 /* Calculate temporary vectorial force */
2234 tx = _mm256_mul_ps(fscal,dx00);
2235 ty = _mm256_mul_ps(fscal,dy00);
2236 tz = _mm256_mul_ps(fscal,dz00);
2238 /* Update vectorial force */
2239 fix0 = _mm256_add_ps(fix0,tx);
2240 fiy0 = _mm256_add_ps(fiy0,ty);
2241 fiz0 = _mm256_add_ps(fiz0,tz);
2243 fjx0 = _mm256_add_ps(fjx0,tx);
2244 fjy0 = _mm256_add_ps(fjy0,ty);
2245 fjz0 = _mm256_add_ps(fjz0,tz);
2249 /**************************
2250 * CALCULATE INTERACTIONS *
2251 **************************/
2253 if (gmx_mm256_any_lt(rsq11,rcutoff2))
2256 /* REACTION-FIELD ELECTROSTATICS */
2257 felec = _mm256_mul_ps(qq11,_mm256_sub_ps(_mm256_mul_ps(rinv11,rinvsq11),krf2));
2259 cutoff_mask = _mm256_cmp_ps(rsq11,rcutoff2,_CMP_LT_OQ);
2263 fscal = _mm256_and_ps(fscal,cutoff_mask);
2265 fscal = _mm256_andnot_ps(dummy_mask,fscal);
2267 /* Calculate temporary vectorial force */
2268 tx = _mm256_mul_ps(fscal,dx11);
2269 ty = _mm256_mul_ps(fscal,dy11);
2270 tz = _mm256_mul_ps(fscal,dz11);
2272 /* Update vectorial force */
2273 fix1 = _mm256_add_ps(fix1,tx);
2274 fiy1 = _mm256_add_ps(fiy1,ty);
2275 fiz1 = _mm256_add_ps(fiz1,tz);
2277 fjx1 = _mm256_add_ps(fjx1,tx);
2278 fjy1 = _mm256_add_ps(fjy1,ty);
2279 fjz1 = _mm256_add_ps(fjz1,tz);
2283 /**************************
2284 * CALCULATE INTERACTIONS *
2285 **************************/
2287 if (gmx_mm256_any_lt(rsq12,rcutoff2))
2290 /* REACTION-FIELD ELECTROSTATICS */
2291 felec = _mm256_mul_ps(qq12,_mm256_sub_ps(_mm256_mul_ps(rinv12,rinvsq12),krf2));
2293 cutoff_mask = _mm256_cmp_ps(rsq12,rcutoff2,_CMP_LT_OQ);
2297 fscal = _mm256_and_ps(fscal,cutoff_mask);
2299 fscal = _mm256_andnot_ps(dummy_mask,fscal);
2301 /* Calculate temporary vectorial force */
2302 tx = _mm256_mul_ps(fscal,dx12);
2303 ty = _mm256_mul_ps(fscal,dy12);
2304 tz = _mm256_mul_ps(fscal,dz12);
2306 /* Update vectorial force */
2307 fix1 = _mm256_add_ps(fix1,tx);
2308 fiy1 = _mm256_add_ps(fiy1,ty);
2309 fiz1 = _mm256_add_ps(fiz1,tz);
2311 fjx2 = _mm256_add_ps(fjx2,tx);
2312 fjy2 = _mm256_add_ps(fjy2,ty);
2313 fjz2 = _mm256_add_ps(fjz2,tz);
2317 /**************************
2318 * CALCULATE INTERACTIONS *
2319 **************************/
2321 if (gmx_mm256_any_lt(rsq13,rcutoff2))
2324 /* REACTION-FIELD ELECTROSTATICS */
2325 felec = _mm256_mul_ps(qq13,_mm256_sub_ps(_mm256_mul_ps(rinv13,rinvsq13),krf2));
2327 cutoff_mask = _mm256_cmp_ps(rsq13,rcutoff2,_CMP_LT_OQ);
2331 fscal = _mm256_and_ps(fscal,cutoff_mask);
2333 fscal = _mm256_andnot_ps(dummy_mask,fscal);
2335 /* Calculate temporary vectorial force */
2336 tx = _mm256_mul_ps(fscal,dx13);
2337 ty = _mm256_mul_ps(fscal,dy13);
2338 tz = _mm256_mul_ps(fscal,dz13);
2340 /* Update vectorial force */
2341 fix1 = _mm256_add_ps(fix1,tx);
2342 fiy1 = _mm256_add_ps(fiy1,ty);
2343 fiz1 = _mm256_add_ps(fiz1,tz);
2345 fjx3 = _mm256_add_ps(fjx3,tx);
2346 fjy3 = _mm256_add_ps(fjy3,ty);
2347 fjz3 = _mm256_add_ps(fjz3,tz);
2351 /**************************
2352 * CALCULATE INTERACTIONS *
2353 **************************/
2355 if (gmx_mm256_any_lt(rsq21,rcutoff2))
2358 /* REACTION-FIELD ELECTROSTATICS */
2359 felec = _mm256_mul_ps(qq21,_mm256_sub_ps(_mm256_mul_ps(rinv21,rinvsq21),krf2));
2361 cutoff_mask = _mm256_cmp_ps(rsq21,rcutoff2,_CMP_LT_OQ);
2365 fscal = _mm256_and_ps(fscal,cutoff_mask);
2367 fscal = _mm256_andnot_ps(dummy_mask,fscal);
2369 /* Calculate temporary vectorial force */
2370 tx = _mm256_mul_ps(fscal,dx21);
2371 ty = _mm256_mul_ps(fscal,dy21);
2372 tz = _mm256_mul_ps(fscal,dz21);
2374 /* Update vectorial force */
2375 fix2 = _mm256_add_ps(fix2,tx);
2376 fiy2 = _mm256_add_ps(fiy2,ty);
2377 fiz2 = _mm256_add_ps(fiz2,tz);
2379 fjx1 = _mm256_add_ps(fjx1,tx);
2380 fjy1 = _mm256_add_ps(fjy1,ty);
2381 fjz1 = _mm256_add_ps(fjz1,tz);
2385 /**************************
2386 * CALCULATE INTERACTIONS *
2387 **************************/
2389 if (gmx_mm256_any_lt(rsq22,rcutoff2))
2392 /* REACTION-FIELD ELECTROSTATICS */
2393 felec = _mm256_mul_ps(qq22,_mm256_sub_ps(_mm256_mul_ps(rinv22,rinvsq22),krf2));
2395 cutoff_mask = _mm256_cmp_ps(rsq22,rcutoff2,_CMP_LT_OQ);
2399 fscal = _mm256_and_ps(fscal,cutoff_mask);
2401 fscal = _mm256_andnot_ps(dummy_mask,fscal);
2403 /* Calculate temporary vectorial force */
2404 tx = _mm256_mul_ps(fscal,dx22);
2405 ty = _mm256_mul_ps(fscal,dy22);
2406 tz = _mm256_mul_ps(fscal,dz22);
2408 /* Update vectorial force */
2409 fix2 = _mm256_add_ps(fix2,tx);
2410 fiy2 = _mm256_add_ps(fiy2,ty);
2411 fiz2 = _mm256_add_ps(fiz2,tz);
2413 fjx2 = _mm256_add_ps(fjx2,tx);
2414 fjy2 = _mm256_add_ps(fjy2,ty);
2415 fjz2 = _mm256_add_ps(fjz2,tz);
2419 /**************************
2420 * CALCULATE INTERACTIONS *
2421 **************************/
2423 if (gmx_mm256_any_lt(rsq23,rcutoff2))
2426 /* REACTION-FIELD ELECTROSTATICS */
2427 felec = _mm256_mul_ps(qq23,_mm256_sub_ps(_mm256_mul_ps(rinv23,rinvsq23),krf2));
2429 cutoff_mask = _mm256_cmp_ps(rsq23,rcutoff2,_CMP_LT_OQ);
2433 fscal = _mm256_and_ps(fscal,cutoff_mask);
2435 fscal = _mm256_andnot_ps(dummy_mask,fscal);
2437 /* Calculate temporary vectorial force */
2438 tx = _mm256_mul_ps(fscal,dx23);
2439 ty = _mm256_mul_ps(fscal,dy23);
2440 tz = _mm256_mul_ps(fscal,dz23);
2442 /* Update vectorial force */
2443 fix2 = _mm256_add_ps(fix2,tx);
2444 fiy2 = _mm256_add_ps(fiy2,ty);
2445 fiz2 = _mm256_add_ps(fiz2,tz);
2447 fjx3 = _mm256_add_ps(fjx3,tx);
2448 fjy3 = _mm256_add_ps(fjy3,ty);
2449 fjz3 = _mm256_add_ps(fjz3,tz);
2453 /**************************
2454 * CALCULATE INTERACTIONS *
2455 **************************/
2457 if (gmx_mm256_any_lt(rsq31,rcutoff2))
2460 /* REACTION-FIELD ELECTROSTATICS */
2461 felec = _mm256_mul_ps(qq31,_mm256_sub_ps(_mm256_mul_ps(rinv31,rinvsq31),krf2));
2463 cutoff_mask = _mm256_cmp_ps(rsq31,rcutoff2,_CMP_LT_OQ);
2467 fscal = _mm256_and_ps(fscal,cutoff_mask);
2469 fscal = _mm256_andnot_ps(dummy_mask,fscal);
2471 /* Calculate temporary vectorial force */
2472 tx = _mm256_mul_ps(fscal,dx31);
2473 ty = _mm256_mul_ps(fscal,dy31);
2474 tz = _mm256_mul_ps(fscal,dz31);
2476 /* Update vectorial force */
2477 fix3 = _mm256_add_ps(fix3,tx);
2478 fiy3 = _mm256_add_ps(fiy3,ty);
2479 fiz3 = _mm256_add_ps(fiz3,tz);
2481 fjx1 = _mm256_add_ps(fjx1,tx);
2482 fjy1 = _mm256_add_ps(fjy1,ty);
2483 fjz1 = _mm256_add_ps(fjz1,tz);
2487 /**************************
2488 * CALCULATE INTERACTIONS *
2489 **************************/
2491 if (gmx_mm256_any_lt(rsq32,rcutoff2))
2494 /* REACTION-FIELD ELECTROSTATICS */
2495 felec = _mm256_mul_ps(qq32,_mm256_sub_ps(_mm256_mul_ps(rinv32,rinvsq32),krf2));
2497 cutoff_mask = _mm256_cmp_ps(rsq32,rcutoff2,_CMP_LT_OQ);
2501 fscal = _mm256_and_ps(fscal,cutoff_mask);
2503 fscal = _mm256_andnot_ps(dummy_mask,fscal);
2505 /* Calculate temporary vectorial force */
2506 tx = _mm256_mul_ps(fscal,dx32);
2507 ty = _mm256_mul_ps(fscal,dy32);
2508 tz = _mm256_mul_ps(fscal,dz32);
2510 /* Update vectorial force */
2511 fix3 = _mm256_add_ps(fix3,tx);
2512 fiy3 = _mm256_add_ps(fiy3,ty);
2513 fiz3 = _mm256_add_ps(fiz3,tz);
2515 fjx2 = _mm256_add_ps(fjx2,tx);
2516 fjy2 = _mm256_add_ps(fjy2,ty);
2517 fjz2 = _mm256_add_ps(fjz2,tz);
2521 /**************************
2522 * CALCULATE INTERACTIONS *
2523 **************************/
2525 if (gmx_mm256_any_lt(rsq33,rcutoff2))
2528 /* REACTION-FIELD ELECTROSTATICS */
2529 felec = _mm256_mul_ps(qq33,_mm256_sub_ps(_mm256_mul_ps(rinv33,rinvsq33),krf2));
2531 cutoff_mask = _mm256_cmp_ps(rsq33,rcutoff2,_CMP_LT_OQ);
2535 fscal = _mm256_and_ps(fscal,cutoff_mask);
2537 fscal = _mm256_andnot_ps(dummy_mask,fscal);
2539 /* Calculate temporary vectorial force */
2540 tx = _mm256_mul_ps(fscal,dx33);
2541 ty = _mm256_mul_ps(fscal,dy33);
2542 tz = _mm256_mul_ps(fscal,dz33);
2544 /* Update vectorial force */
2545 fix3 = _mm256_add_ps(fix3,tx);
2546 fiy3 = _mm256_add_ps(fiy3,ty);
2547 fiz3 = _mm256_add_ps(fiz3,tz);
2549 fjx3 = _mm256_add_ps(fjx3,tx);
2550 fjy3 = _mm256_add_ps(fjy3,ty);
2551 fjz3 = _mm256_add_ps(fjz3,tz);
2555 fjptrA = (jnrlistA>=0) ? f+j_coord_offsetA : scratch;
2556 fjptrB = (jnrlistB>=0) ? f+j_coord_offsetB : scratch;
2557 fjptrC = (jnrlistC>=0) ? f+j_coord_offsetC : scratch;
2558 fjptrD = (jnrlistD>=0) ? f+j_coord_offsetD : scratch;
2559 fjptrE = (jnrlistE>=0) ? f+j_coord_offsetE : scratch;
2560 fjptrF = (jnrlistF>=0) ? f+j_coord_offsetF : scratch;
2561 fjptrG = (jnrlistG>=0) ? f+j_coord_offsetG : scratch;
2562 fjptrH = (jnrlistH>=0) ? f+j_coord_offsetH : scratch;
2564 gmx_mm256_decrement_4rvec_8ptr_swizzle_ps(fjptrA,fjptrB,fjptrC,fjptrD,fjptrE,fjptrF,fjptrG,fjptrH,
2565 fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,
2566 fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
2568 /* Inner loop uses 325 flops */
2571 /* End of innermost loop */
2573 gmx_mm256_update_iforce_4atom_swizzle_ps(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
2574 f+i_coord_offset,fshift+i_shift_offset);
2576 /* Increment number of inner iterations */
2577 inneriter += j_index_end - j_index_start;
2579 /* Outer loop uses 24 flops */
2582 /* Increment number of outer iterations */
2585 /* Update outer/inner flops */
2587 inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4W4_F,outeriter*24 + inneriter*325);