<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Help with vectorization in Software Archive</title>
    <link>https://community.intel.com/t5/Software-Archive/Help-with-vectorization/m-p/1009801#M33653</link>
    <description>&lt;P&gt;Hello everyone,&amp;nbsp;&lt;/P&gt;

&lt;P&gt;I have a subroutine that definitely has the computational load that could benefit from a MIC. The subroutine is being used in a molecular simulation. The idea behind the subroutine is to determine which particles are within a certain distance, and for each particle create an array that says which particles are within that distance. However because I am only updating the array inside an if statement, the compiler sees a vector dependence and won't vectorize. I am wondering if anyone here sees a way to vectorize this subroutine.&lt;/P&gt;

&lt;P&gt;&amp;nbsp;&lt;/P&gt;

&lt;PRE class="brush:fortran;"&gt;program neighbor
  use ifport

  implicit none
  double precision, allocatable :: x(:),y(:),z(:)
  double precision :: dx,dy,dz,dr2
  double precision :: dens,vol,box,rcut2
  double precision :: x1,y1,z1,x2,y2,z2
  integer :: np
  integer :: i,j
  integer,allocatable :: numNeigh(:),vlist(:,:)

  np = 600
  allocate(numNeigh(np))
  allocate(vlist(1000,np))
  allocate(x(np),y(np),z(np))

  dens  = 1.0d0
  vol   = real(np)/dens
  box   = vol**(1.0d0/3.0)
  rcut2 = 2.50d0*2.50d0
  call seed(10)

  numNeigh(:) = 0
  vlist(:,:)  = 0

&amp;nbsp; !--- create arbitrary initial coordinates. Not important
  do i = 1,np
     x(i) = box*rand(); y(i) = box*rand(); z(i) = box*rand()
  enddo

  do i = 1,np
     x1 = x(i); y1 = y(i); z1 = z(i)
     !---would like to vectorize this inner loop
     do j=1,np

        if(i.eq.j)then
           cycle
        endif
        
&amp;nbsp;       !---calcuate distance between particles i and j
        x2 = x(j); y2 = y(j); z2 = z(j)
        dx = x2-x1; dy = y2-y1; dz = z2-z1
        dr2 = dx**2 + dy**2 + dz**2

        if(dr2.lt.rcut2)then
&amp;nbsp;          !---if distance is less than cutoff distance, update number of neighbors and store particle j in vlist
           numNeigh(i) = numNeigh(i) + 1
           vlist(numNeigh(i),i) = j
        endif

     enddo
  enddo

  stop
end program neighbor
&lt;/PRE&gt;

&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
    <pubDate>Wed, 01 Oct 2014 17:55:39 GMT</pubDate>
    <dc:creator>conor_p_</dc:creator>
    <dc:date>2014-10-01T17:55:39Z</dc:date>
    <item>
      <title>Help with vectorization</title>
      <link>https://community.intel.com/t5/Software-Archive/Help-with-vectorization/m-p/1009801#M33653</link>
      <description>&lt;P&gt;Hello everyone,&amp;nbsp;&lt;/P&gt;

&lt;P&gt;I have a subroutine that definitely has the computational load that could benefit from a MIC. The subroutine is being used in a molecular simulation. The idea behind the subroutine is to determine which particles are within a certain distance, and for each particle create an array that says which particles are within that distance. However because I am only updating the array inside an if statement, the compiler sees a vector dependence and won't vectorize. I am wondering if anyone here sees a way to vectorize this subroutine.&lt;/P&gt;

&lt;P&gt;&amp;nbsp;&lt;/P&gt;

&lt;PRE class="brush:fortran;"&gt;program neighbor
  use ifport

  implicit none
  double precision, allocatable :: x(:),y(:),z(:)
  double precision :: dx,dy,dz,dr2
  double precision :: dens,vol,box,rcut2
  double precision :: x1,y1,z1,x2,y2,z2
  integer :: np
  integer :: i,j
  integer,allocatable :: numNeigh(:),vlist(:,:)

  np = 600
  allocate(numNeigh(np))
  allocate(vlist(1000,np))
  allocate(x(np),y(np),z(np))

  dens  = 1.0d0
  vol   = real(np)/dens
  box   = vol**(1.0d0/3.0)
  rcut2 = 2.50d0*2.50d0
  call seed(10)

  numNeigh(:) = 0
  vlist(:,:)  = 0

&amp;nbsp; !--- create arbitrary initial coordinates. Not important
  do i = 1,np
     x(i) = box*rand(); y(i) = box*rand(); z(i) = box*rand()
  enddo

  do i = 1,np
     x1 = x(i); y1 = y(i); z1 = z(i)
     !---would like to vectorize this inner loop
     do j=1,np

        if(i.eq.j)then
           cycle
        endif
        
&amp;nbsp;       !---calcuate distance between particles i and j
        x2 = x(j); y2 = y(j); z2 = z(j)
        dx = x2-x1; dy = y2-y1; dz = z2-z1
        dr2 = dx**2 + dy**2 + dz**2

        if(dr2.lt.rcut2)then
&amp;nbsp;          !---if distance is less than cutoff distance, update number of neighbors and store particle j in vlist
           numNeigh(i) = numNeigh(i) + 1
           vlist(numNeigh(i),i) = j
        endif

     enddo
  enddo

  stop
end program neighbor
&lt;/PRE&gt;

&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 01 Oct 2014 17:55:39 GMT</pubDate>
      <guid>https://community.intel.com/t5/Software-Archive/Help-with-vectorization/m-p/1009801#M33653</guid>
      <dc:creator>conor_p_</dc:creator>
      <dc:date>2014-10-01T17:55:39Z</dc:date>
    </item>
    <item>
      <title>A fairly standard approach to</title>
      <link>https://community.intel.com/t5/Software-Archive/Help-with-vectorization/m-p/1009802#M33654</link>
      <description>&lt;P&gt;A fairly standard approach to something like this is to treat it in two phases.&amp;nbsp;&lt;/P&gt;

&lt;OL&gt;
	&lt;LI&gt;Build a boolean vector showing which elements are near,&lt;/LI&gt;
	&lt;LI&gt;Compress that into your neighbour list as a separate operation.&lt;/LI&gt;
&lt;/OL&gt;

&lt;P&gt;Something like this.&lt;/P&gt;

&lt;PRE class="brush:fortran;"&gt;program neighbor
  use ifport

  implicit none
  double precision, allocatable :: x(:),y(:),z(:)
  double precision :: dx,dy,dz,dr2
  double precision :: dens,vol,box,rcut2
  double precision :: x1,y1,z1,x2,y2,z2
  integer :: np
  integer :: i,j
  integer,allocatable :: numNeigh(:),vlist(:,:)
  logical,allocatable :: nearEnough(:)

  np = 600

  allocate(numNeigh(np), nearEnough(np))                        !vlist can't need more than np items for each element.
  allocate(vlist(np,np))
  allocate(x(np),y(np),z(np))

  dens  = 1.0d0
  vol   = real(np)/dens
  box   = vol**(1.0d0/3.0)
  rcut2 = 2.50d0*2.50d0
  call seed(10)

  numNeigh(:) = 0
  vlist(:,:)  = 0

  !--- create arbitrary initial coordinates. Not important
  do i = 1,np
     x(i) = box*rand(); y(i) = box*rand(); z(i) = box*rand()
  enddo

! For each particle
  do i = 1,np
     x1 = x(i); y1 = y(i); z1 = z(i)
     !---would like to vectorize this inner loop
     do j=1,np                                  
        if (i .eq. j) then
           nearEnough(j) = .false.
           cycle
        endif
        !---calculate distance between particles i and j
        x2 = x(j); y2 = y(j); z2 = z(j)
        dx = x2-x1; dy = y2-y1; dz = z2-z1
        dr2 = dx**2 + dy**2 + dz**2

        nearEnough(j) = dr2 .lt. rcut2
     enddo

     ! Now reduce 
     do j=1,np
        if (nearEnough(j)) then
           numNeigh(i) = numNeigh(i) + 1
           vlist(numNeigh(i),i) = j
        endif
     enddo
  enddo

  stop
end program neighbor&lt;/PRE&gt;

&lt;P&gt;The first loop now vectorizes. There are a number of other issues here, though:-&lt;/P&gt;

&lt;OL&gt;
	&lt;LI&gt;Since distance(a,b) .eq. distance(b,a) you should be able to halve the amount of work (and remove the conditional from the interesting loop) by running it from i+1 to np, though you'll then need some more code to build the full neighbour list.&lt;/LI&gt;
	&lt;LI&gt;If you parallelize the outer loop and do the halving trick the work will be imbalanced, so play with either schedule(static,1), or schedule(dynamic)&lt;/LI&gt;
&lt;/OL&gt;

&lt;P&gt;HTH&lt;/P&gt;</description>
      <pubDate>Thu, 02 Oct 2014 09:27:00 GMT</pubDate>
      <guid>https://community.intel.com/t5/Software-Archive/Help-with-vectorization/m-p/1009802#M33654</guid>
      <dc:creator>James_C_Intel2</dc:creator>
      <dc:date>2014-10-02T09:27:00Z</dc:date>
    </item>
  </channel>
</rss>

