Conditional General Status in OpenMP

In the code I'm trying to connect to OpenMP, I have a parallel loop nested in an outer loop. Depending on the iteration of the outer loop, I would like a particular array to be either sharedor reduction(+). Is there a way to do this in Fortran?

Here is the layout of what I want:

do i = 1, 2
  !$omp if(i.eq.1) parallel do reduction(+:foo)
  !$omp if(i.eq.2) parallel do shared(foo)
  do j = 1,j_max
    work on foo
  enddo
  !$omp end parallel
enddo

A discussion of the openMP conditional pragma "if else" suggests that scheduling cannot be changed at run time. Does this also apply to general / private / abbreviation / etc.?

One obvious way to do this is to create foo_1 (abbreviation: +) and foo_2 (generic), copy foo_1 to foo_2 after the first iteration in i, and then have if statements in a loop over j to access the correct array, but it's not very elegant. I hope there will be a better / smarter / cleaner way to do this.

Edit: for the unimaginable, here's the pseudocode version of my alternative

do i = 1, 2
  !$omp parallel do reduction(+:foo_1), shared(foo_2)
  do j = 1,j_max

    if( i .eq. 1 ) then
      work on foo_1
    else
      work on foo_2
    endif

  enddo
  !$omp end parallel

  foo_2 = foo_1
enddo
+4
source share
1 answer

As you do not mind, if you have two parallel areas, you can use orphaned directives - I find them excellent for organizing the general structure of large OpenMP codes. I mean something like

    i = 1
    !$omp parallel shared( i, foo, ... )
    Call do_the_work( i, foo, ... )
    !$omp end parallel
    i = 2
    !$omp parallel shared( i, ... ) reduction( +:foo )
    Call do_the_work( i, foo, ... )
    !$omp end parallel

...

    Subroutine do_the_work( i, foo, ... )
      !$omp do
      do j = 1,j_max
        work on foo
      enddo
    End Subroutine do_the_work

, , , , .

+1

Source: https://habr.com/ru/post/1606626/


All Articles