Сокращение OpenMP для определенного пользователем типа Fortran, содержащего размещаемый массив - PullRequest
1 голос
/ 10 апреля 2020

Я хочу сделать сокращение OpenMP для определенного пользователем типа Fortran. Я знаю, что OpenMP не поддерживает типы Fortran в предложениях сокращения, но можно определить собственные сокращения. Это сделано в следующем примере. Это также работает и делает то, что ожидается от

 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

Моя проблема теперь в размещаемом массиве.

Поскольку я жестко закодировал инициализатор массива для оператора сокращения OpenMP как initializer (omp_priv = my_type ([0,0,0,0,0,0,0,0,0,0])) I нужно поставить 10 нулей, поскольку массив выделен длиной 10. Возможно ли это с именем переменной N (длина массива) ??

1 Ответ

3 голосов
/ 10 апреля 2020

Внутри предложения инициализатора сокращения мы имеем ограниченный доступ к переменным, что затрудняет конструктор массива переменной длины. Тем не менее, у нас есть Фортранская версия C ++ подхода .

. Мы можем использовать переменную omp_orig для ссылки на «хранилище исходной переменной, которая будет сокращена»:

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

Оператор присваивания здесь успешно выделяет компонент массива каждой частной копии.

...