2

I want to do an OpenMP reduction on a user defined Fortran type. I know OpenMP does not support Fortran types in reduction clauses but it is possible to define own reductions. This is done in the following example. This also works and does what it is expected to

 module types 
  !!! your type this can contain scalars and arrays
  type my_type
    Real*8,allocatable,dimension( : )  ::x
  end type

  !!! makes it possible to use the plus symbol for the reduction staement
  !!! replaces my_add by plus symbol
  interface operator(+)
     module procedure :: my_add
  end interface

 !$omp declare reduction (+ : my_type : omp_out = omp_out + omp_in) initializer (omp_priv = my_type ([0,0,0,0,0,0,0,0,0,0]))

 contains


  function my_add( a1 , a2 )
    type( my_type ),intent( in ) :: a1, a2
    type( my_type )              :: my_add
    my_add%x          =   a1%x + a2%x
    return
  end function my_add
 end module types 






program main
  use types
  use omp_lib
  type(my_type) :: my_var

  ! Initialize the reduction variable before entering the OpenMP region
  Allocate( my_var%x( 1:10 ) )  
  my_var%x = 0d0

  !$omp parallel reduction (+ : my_var) num_threads(4)
    my_var%x = omp_get_thread_num() + 6
    print*,omp_get_thread_num()
  !$omp end parallel

  print *, "sum of x is ", my_var%x
end program

My problem is now the allocatable array.

Because I hard coded the array initializer for the OpenMP reduction statement as initializer (omp_priv = my_type ([0,0,0,0,0,0,0,0,0,0])) I have to put 10 zeros there since the array is allocated with a length of 10. Is it possible to this with a variable name N (length of array)??

3
  • I am trying to figure out how to make this initializer (omp_priv = my_type ([0,0,0,0,0,0,0,0,0,0])) accessible for variable size. Commented Apr 10, 2020 at 16:04
  • Don't you just want to use omp_priv = omp_orig as the initializer clause? Commented Apr 10, 2020 at 19:52
  • Yes this does exactly what I want. Thank you!! Commented Apr 10, 2020 at 20:00

1 Answer 1

4

Inside the reduction initializer clause we have limited access to variables, making an array constructor of variable length difficult. However, we have available to us the Fortran version of the C++ approach.

We can use the variable omp_orig to refer to the "storage of the original variable to be reduced":

!$omp declare reduction (+ : my_type : omp_out = omp_out + omp_in) &
!$omp&   initializer (omp_priv=omp_orig)

The assignment statement here successfully allocates the array component of each private copy.

Sign up to request clarification or add additional context in comments.

Comments

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.