Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29593 Diskussionen

parallelizing do loop to assign array elements

dsmanoli
Einsteiger
1.068Aufrufe
Hi,

I am using Microsoft Visual Studio 2005 and the Intel Visual Fortran Compiler 10.1. I am also using OpenMP for parallel programming.

I am having problems parallelizing a loop of the following form:

do i=1,100

call my_subroutine(output(i),input(i))

end do


I had been using !$omp parallel do shared(output, input) but this seems to have led to errors because the assignment was not always correct. I also tried using !$omp flush(output,input) before and after the call statement, but this didn't seem to work either. I think the problem stems from having multiple threads reading and writing to the same variable at the same time, even though different elements in the array are being written. Is this correct? Does any one have any suggestions to get around this? Ideally I would like a way to have thread 1 assign elements 1 through 20 for example, thread 2 assign elements 21-40, thread 3 elements 41-60, etc and I would like the assignments to be able to occur simultaneously.

I appreciate any advice. Thank you!
0 Kudos
5 Antworten
jimdempseyatthecove
Geehrter Beitragender III
1.068Aufrufe

ds,

If
[cpp]!$omp parallel do shared(output, input)
do i=1,100
  call my_subroutine(output(i),input(i))
end do
!$omp end parallel do
[/cpp]

is not working (giving erronious results)

Then there are a few possible culptits:

a) the subroutine has temporal dependencies e.g.
output(i) depends on new value in output(i-1)
output(i) depends on old value in output(i+1)

b) the size of the data elements are not a multiple of the processor's atomic store capability (multiple of 32-bits)

What are input and output?

Jim Dempsey

TimP
Geehrter Beitragender III
1.068Aufrufe
When you write to a shared array, you have serious problems at the boundaries between threads when there are references to elements of the array across the chunk boundaries, e.g. a(i)=.5*(a(i+1)+a(i-1)). Correct OpenMP static scheduled (default) parallelization of a shared array does very well what you requested.
If you fail to compile all the subroutines in the parallel region with OpenMP compatible options,such that you have the effect of SAVE variables, that also creates a race condition.
Intel Thread Checker is designed to analyze your application for the occurrence of such conditions when run with data sets you supply.
dsmanoli
Einsteiger
1.068Aufrufe

Hi,

Thanks for the responses, but I'm still not sure what to do. There are no intertemporal dependencies in the loop I'm trying to parallelize (ouput(i) does not depend on output(i-1), input(i-1) or anything else except input(i). In terms of what input and output are, these arereal(8), allocatable, dimension(N,1) arrays.

Also, how can I use the Intel thread checker? I have not changed the default scheduling, so I think it is static.

Perhaps there is something common that I am missing?

Is there a way I can use the flush directive? I have also tried !$omp parallel do shared(output, input)
do i=1,100
call my_subroutine(output(i),input(i))
!$omp flush(output,input)
end do
!$omp end parallel do

but this also doesn't give the desired result.

Any other suggestions or advice? Thanks!


ds,

If
[cpp]!$omp parallel do shared(output, input)
do i=1,100
  call my_subroutine(output(i),input(i))
end do
!$omp end parallel do
[/cpp]

is not working (giving erronious results)

Then there are a few possible culptits:

a) the subroutine has temporal dependencies e.g.
output(i) depends on new value in output(i-1)
output(i) depends on old value in output(i+1)

b) the size of the data elements are not a multiple of the processor's atomic store capability (multiple of 32-bits)

What are input and output?

Jim Dempsey


dsmanoli
Einsteiger
1.068Aufrufe
Hi,

I thought I should further explain my setting to see if the problem can be diagnosed.

I am trying to parallelize a loop like the following:

startobs(1)=1
startobs(2)=11
startobs(3)=21
endobs(1) = 10
endobs(2) = 20
endobs(3) = 30

!omp parallel do shared(output,input)
do group=1,3
call my_subroutine(output(startobs(group):endobs(group),1), input(startobs(group):endobs(group),1))
end do
!$end parallel do

However, the output I get from the parallelized loop does not match the output I get from doing the loop serially. Please let me know if I am doing something incorrectly or if you have any suggestions for things to change. Thanks.



TimP
Geehrter Beitragender III
1.068Aufrufe
Intel thread checker is a separate software product. You set its environment variables in addition to those for ifort. It has both automatic instrumentation, and (more reliable) the option to compile and link with -tcheck option set (which implicitly sets -Od -Zi). It performs an interpretive run with your data, thus you need short test cases. It checks for all possibilities where changing number of threads would change the result from the serial case. In principle, it should work with pre-compiled released libraries, but it is preferable, e.g. to use open source BLAS rather than MKL. Windows thread checker probably requires Intel VTune.
Antworten