err 7621. How to use REDUCTION for derived-type in Fortran?

General OpenMP discussion

err 7621. How to use REDUCTION for derived-type in Fortran?

Postby UlrichVonRekkenin » Wed Jan 25, 2012 10:19 am

Good day,

I would like to implement something like this.

Code: Select all

MODULE foo_module
    IMPLICIT NONE
!
!
    PRIVATE
!
type, public :: foo
  double precision :: xx
    CONTAINS
      procedure :: init => init_sub
      generic :: operator(+) => foo_plus_foo_fn
      procedure, private :: foo_plus_foo_fn
end type foo

!
    CONTAINS
!
subroutine init_sub(this, xx)
    implicit none
    class(foo), intent(INOUT) :: this
    double precision, intent(IN) :: xx
this%xx = xx
return
end subroutine init_sub
!
!
ELEMENTAL type(foo) function foo_plus_foo_fn(f1, f2) RESULT(res)
    implicit none
    class(foo), intent(IN) :: f1, f2
res%xx = f1%xx + f2%xx
return
end function foo_plus_foo_fn
!
!
END MODULE foo_module


PROGRAM main
    USE foo_module
    IMPLICIT NONE
    type(foo) :: f, f_sum
    double precision :: y = 0.
    integer :: i

!$OMP parallel

!$OMP do PRIVATE(i,f) REDUCTION(+:y)
  do i = 1, 5
    call f%init(dble(i))
    y = y + f%xx
    f_sum = f_sum + f ! I would like to implement this behaviour.
  end do
!$OMP end do

!$OMP single
  write( *, '( :, 1X, 3(1X, A, f17.10) )' ) 'f_sum is ', f_sum%xx, 'y_sum is ', y, 'abs', abs(y-f_sum%xx)
!$OMP end single

!$OMP end parallel

END PROGRAM main


An answer is different run by run.
If I add REDUCTION(+:f_sum) I get error #7621: The data type of the variable is not defined for the operator or intrinsic specified on the OpenMP* REDUCTION clause.


Best, Oleg.
UlrichVonRekkenin
 
Posts: 1
Joined: Wed Jan 25, 2012 10:14 am

Re: err 7621. How to use REDUCTION for derived-type in Fortr

Postby ftinetti » Wed Jan 25, 2012 2:54 pm

Hi,

An answer is different run by run.

Because there are race conditions on f_sum.

If I add REDUCTION(+:f_sum) I get error #7621: The data type of the variable is not defined for the operator or intrinsic specified on the OpenMP* REDUCTION clause.

This is explained in section 2.9.3.6 of the 3.1 Specification. More specifically:
Operators specified must be intrinsic operators and any intrinsic_procedure_name
must refer to one of the allowed intrinsic procedures. Assignment to the reduction list
Fortran items must be via intrinsic assignment.

I think there are two possibilities to compute f_sum in parallel:
1) Enclose the assignment in a critical construct, preventing race conditions and, also, limiting parallel processing
2) Instead of having a single f_sum, declare an array of length OMP_GET_NUM_THREADS(), where each thread computes its own sum, and after the parallel region aggregate the results in a sequential DO or something similar. Well, in the extreme case (maybe with tens of thousands of threads) you could aggregate the results in another parallel region...

HTH.
ftinetti
 
Posts: 580
Joined: Wed Feb 10, 2010 2:44 pm


Return to Using OpenMP

Who is online

Users browsing this forum: No registered users and 6 guests