Hey everyone, I have the following set of nested loops which I would like to vectorize. If you're familiar with molecular simulations, this is a linked cell energy calculation. I checked the requirements for intel vectorization, and I believe I satisfy them. There aren't multiple branch points. All array accessing, except for envar in the inner most loop, is unit stride. I believe the if statements in these loops can be interpreted as mask-constructs. I keep getting the error 'loop not vectorized: not inner loop," hence the addition of the !dir$ imp simd collapse(4). When i compile with -vec-report2 -guide -openmp the compiler still says "loop not vectorized: not inner loop," despite the collapse command. I would like to port this to the xeon phi coprocessor, so any help with the vectorization here would be greatly appreciated. I understand this is a fair amount of code, but i have tried to add many comments for explanation.
!$omp parallel do schedule(dynamic) reduction(+:energy) default(private) firstprivate(listvar), &
!$omp& shared(r,tr,cv,param,envar,alpha,GaussChar,pf)
!dir$ omp simd collapse(4)
!dir$ vector aligned
!--- loop over all cells present
do i = 0,listvar%ncellT-1
!--- these are pointers to array r which contains the positions of particles along with the particle type.
!--- c1s is the location in r where the first atom in cell i is stored. c1e is where the last atom is stored
c1s = tr(i)%start
c1e = tr(i)%end
!--- loop over cell neighbors
do k=1,26
!---determine this cell
cell_neigh = cv(k,i)%cnum
!--- only calculate energy between particle 1 and particle 2 once.
!---This is done by only calculating energies between cell pairs (i,cell_neigh) where cell_neigh is gt than i
if(cell_neigh.gt.i)then
!---minimum image criterion for distance calculation
minx =cv(k,i)%min_x
miny =cv(k,i)%min_y
minz =cv(k,i)%min_z
!---pointers to positions in array r. Tell where the atoms for cell cell_neigh are contained in r
c2s = tr(cell_neigh)%start
c2e = tr(cell_neigh)%end
!--- loop over particles in each cell
do j = c1s,c1e
x1 = r(j)%x
y1 = r(j)%y
z1 = r(j)%z
type1 = r(j)%type
do l= c2s,c2e
x2 = r(l)%x
y2 = r(l)%y
z2 = r(l)%z
type2 = r(l)%type
!--- obtain displacements
!--- apply minimum image here
dx = x2-x1-minx
dy = y2-y1-miny
dz = z2-z1-minz
dr2 = dx*dx+dy*dy+dz*dz
!--- is distance is less than cutoff, calculate energy
if(dr2.lt.param%rcut2)then
!--- obtain interaction parameters for atoms of type1 and type2
val(:)= envar(type1,type2)%val(:)
dr = sqrt(dr2)
dri = 1.0d0/dr
dr2i = val(1)/dr2
dr6i = dr2i*dr2i*dr2i
dr12i = dr6i*dr6i
!--- lennard jones energy
energy = energy + 4.0d0*val(2)*(dr12i - dr6i)
!--- electrostatic energy
!energy = energy + pf*charge*(erfc(alpha*dr)-GaussChar)
endif
enddo
enddo
endif
enddo
enddo
!$omp end parallel do