parallelizing a simple code by openacc ?

Hi, I’m a beginner in openacc and trying to parallelize the code below. Is there any way to do so? It looks simple, but I can’t think of any idea.

i_new = 0
do i = 1, 100
do j = 1, 100
	i_new(i_rule(i,j),j) = i_new(i_rule(i,j),j) + i_old(i,j)*temp(i,j)
end do
end do

Thanks,
AJ

Hi AJ,

The only tricky part here is that you’re using an array to look-up the first index. This will prevent the compiler from automatically parallelizing the “i” loop since it must assume that multiple “i_rule” elements map to the same “i”. If this is not the case, you can still parallelize the loops by either adding the “independent” clause to the “kernels loop” directive, or use the “parallel” directive instead. Something like:

! create and copy the device data
!$acc data copyout(i_new) copyin(i_rule,i_old)

! initialize i_new on the device
!$acc kernels
i_new = 0 
!$acc end kernels

! use parallel to off load the compute regions
!$acc parallel loop gang
do j = 1, 100      ! interchange the loops so "i" is the vector loop
!$acc loop vector
do i = 1, 100 
   i_new(i_rule(i,j),j) = i_new(i_rule(i,j),j) + i_old(i,j)*temp(i,j) 
end do 
end do 
!$acc end parallel

!$ acc end data

Hope this helps,
Mat

Dear Mat,

Thanks for your explanation. The case I am faced with is indeed that multiple “i_rule” elements often map to the same “i”. If ths is the case, from what I understand, I cant parallelize the code by following your suggestion, can I?

AJ

You still can, but will need to use the “atomic” directive to ensure correct answers.

Something like:

! use parallel to off load the compute regions 
!$acc parallel loop gang 
do j = 1, 100      ! interchange the loops so "i" is the vector loop 
!$acc loop vector 
do i = 1, 100 
!$acc atomic update
   i_new(i_rule(i,j),j) = i_new(i_rule(i,j),j) + i_old(i,j)*temp(i,j) 
end do 
end do 
!$acc end parallel

-Mat