0

I have trouble applying openmp to a nested loop in Fortran like this:

!$omp parallel do default(none) private(irow,mm,iparm,jrow) shared(nsrow,nparm,zvec,bvec,brx,zdense) 
    do irow = 2, nsrow 
               mm = irow -1
               do iparm = 1, nparm
                  do jrow = 1, mm
                     zvec(jrow) = zdense( ijdense(jrow,irow,nsrow) )
                  end do
                  bvec(iparm) = ddot( mm, zvec, 1, brx(:,iparm), 1)
               end do
               brx(irow,:) = (brx(irow,:)-bvec)/zdense(ijdense(irow,irow,nsrow)) 
     end do
 !$omp end parallel do

When I compare the serial with the openmp version, the last one gives weird results. do you know why or can point to a good tutorial explicit about nested loops and openmp? Thank you in advance

1
  • did any of the answer below help solving your problem? If it helped, please accept it to help those who have similar problem. If it did not help, please let me know so that I can delete it to save people from wasting their time looking at it. Commented Jan 26, 2016 at 17:35

2 Answers 2

2

The loop that is explicitly parallelized is the outer loop (irow loop). This parallelization makes it possible to have disjoint set of index irow for each thread. When it comes to other indices, iparm and jrow, each thread at some point gets jrow = 1, meaning that all the thread set zvec(1), and since zvec is shared, you will definitly get a weird result. Because you will never know what is in zvec(1). The same thing hold for iparm and brx. So as Gilles suggested, zvec must be private for you to get the same result as in the sequential run.

As I see the iparm loop, it is better to parrallelize the iparm loop and keep brx shared. or have the reduction clause on brx but it will still be tricky.

    do irow = 2, nsrow 
        mm = irow -1
        !$omp parallel do default(none) private(irow,mm,iparm,jrow,zvec) shared(nsrow,nparm,bvec,brx,zdense) 
        do iparm = 1, nparm
            do jrow = 1, mm
                zvec(jrow) = zdense( ijdense(jrow,irow,nsrow) )
            end do
            bvec(iparm) = ddot( mm, zvec, 1, brx(:,iparm), 1)
        end do
        !$omp end parallel do
        brx(irow,:) = (brx(irow,:)-bvec)/zdense(ijdense(irow,irow,nsrow)) 
    end do
Sign up to request clarification or add additional context in comments.

Comments

0

The first thing I see here is that zvec is shared whereas it should be private. Same story for bvec I guess. Try that first and let us know.

2 Comments

Thanks you for your reply, but it doesn't work. Is it the problem about dependence?
Ok I hadn't see that you also have indeed a dependence in brx: you need all irow values of it for computing bvec and then you update brx using bvec. So if you update in parallel brx, you change the ordering of the operations and therefore the evaluation of bvec. This won't work.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.