Fortran OpenMP с несколькими одновременными сокращениями приводит к ошибке seg

Некоторое время назад я использовал учебные пособия Intel OpenMP. Я написал сокращение программы pi и сейчас работаю над кодом на фортране, используя openMP. Я хочу суммировать 4 количества сразу с предложением о сокращении. код выглядит так:

call omp_set_num_threads(num_threads)
write(*,*) "number of parallel threads"
write(*,*) num_threads


N_init = 1200
N_t    = 1250

filename = 'POD_input/POD_avg.dat'

io = 0
nCell = 0
open(UNIT = 10, FILE = filename, STATUS = 'OLD', form = 'formatted')
    do
        read(10,*, end=67) nonsense, nonsense, nonsense, nonsense, nonsense, nonsense, nonsense, nonsense, nonsense, nonsense, nonsense
        nCell = nCell + 1
    end do
67 close(10)

allocate(eig(nCell))
allocate(wr(nCell))
allocate(wi(nCell))
allocate(work(4*nCell))

allocate(R_Corr(nCell, nCell))
allocate(U_Corr(nCell, nCell))
allocate(V_Corr(nCell, nCell))
allocate(P_Corr(nCell, nCell))

allocate(R_Tot(nCell, nCell))
allocate(U_Tot(nCell, nCell))
allocate(V_Tot(nCell, nCell))
allocate(P_Tot(nCell, nCell))

allocate(R_Fin(nCell, nCell))
allocate(U_Fin(nCell, nCell))
allocate(V_Fin(nCell, nCell))
allocate(P_Fin(nCell, nCell))

allocate(x(nCell))
allocate(y(nCell))
allocate(A(nCell))

allocate(Rho(nCell))
allocate(U(nCell))
allocate(V(nCell))
allocate(P(nCell))

allocate(R_x(nCell))
allocate(U_x(nCell))
allocate(V_x(nCell))
allocate(P_x(nCell))

allocate(R_c(nCell))
allocate(U_c(nCell))
allocate(V_c(nCell))
allocate(P_c(nCell))

allocate(R_av(nCell))
allocate(U_av(nCell))
allocate(V_av(nCell))
allocate(P_av(nCell))


open(UNIT = 10, FILE = filename, STATUS = 'OLD', form = 'formatted')
    do iCell = 1, nCell
        read(10,*)  x(iCell), y(iCell), A(iCell), nonsense, nonsense, nonsense, nonsense, R_av(iCell), U_av(iCell), V_av(iCell), P_av(iCell)
    end do
close(10)

filename = 'POD_output/POD_Mesh.dat'

open(UNIT = 10, FILE = filename, STATUS = 'unknown', form = 'unformatted', access='stream')
    write(10) nCell
    write(10) x(:)
    write(10) y(:)
close(10)

R_Tot = 0.0_dp
U_Tot = 0.0_dp
V_Tot = 0.0_dp
P_Tot = 0.0_dp

write(*,*) "begin correlation"

!$OMP PARALLEL DO REDUCTION(+:R_Tot, U_Tot, V_Tot, P_Tot) private(i, j, nonsense, filename, num, iCell, iTime, R_x, R_C, R_Corr, U_x, U_C, U_Corr, V_x, V_C, V_Corr, P_x, P_C, P_Corr)
   do iTime = N_init,N_t
       write(*,*) "inside loop"
       filename = 'POD_input/POD_input.'
       write(num,'(I6.6)') iTime
       filename = trim(adjustl(filename))//trim(adjustl(num))//trim(adjustl('.dat'))
       ! Read file

       write(*,*) "read file"
       open(UNIT = 10, FILE = filename, STATUS = 'OLD', form = 'formatted')
           do iCell = 1, nCell
               read(10,*) nonsense, nonsense, nonsense, R_x(iCell), U_x(iCell), V_x(iCell), P_x(iCell)
           end do
       close(10)

       R_x = R_x-R_av
       U_x = U_x-U_av
       V_x = V_x-V_av
       P_x = P_x-P_av

       R_C(:) = R_x(:)*sqrt(A(:))
       U_C(:) = U_x(:)*sqrt(A(:))
       V_C(:) = V_x(:)*sqrt(A(:))
       P_C(:) = P_x(:)*sqrt(A(:))


       do i = 1, nCell
           do j =1, nCell
               R_Corr(i,j) = R_C(i)*R_C(j)
               U_Corr(i,j) = U_C(i)*U_C(j)
               V_Corr(i,j) = V_C(i)*V_C(j)
               P_Corr(i,j) = P_C(i)*P_C(j)
           end do
       end do


       R_Tot =  R_Tot + R_Corr
       U_Tot =  U_Tot + U_Corr
       V_Tot =  V_Tot + V_Corr
       P_Tot =  P_Tot + P_Corr
   end do
!$OMP END PARALLEL DO 

Я получаю ошибку ошибки сегментации даже при работе с 1 потоком. что я могу сделать, чтобы отладить это или исправить это. благодарю вас.

РЕДАКТИРОВАТЬ: включено больше кода для облегчения помощи


person EMP    schedule 25.08.2017    source источник
comment
это работает с gfortran?   -  person M. Chinoune    schedule 25.08.2017
comment
Параметр компиляции Openmp может помешать компилятору исправить вложенность циклов. Сокращение массива здесь может не иметь смысла.   -  person tim18    schedule 25.08.2017
comment
Это не работает с gfortran для других проблем компиляции. Тим, как мне это исправить, чтобы я мог перебирать свои временные шаги и читать? Спасибо   -  person EMP    schedule 25.08.2017
comment
Без минимального воспроизводимого примера, показывающего иначе, я думаю, что ncell не имеет того значения, которое должно иметь.   -  person High Performance Mark    schedule 26.08.2017
comment
Привет, Марк, это не работает, даже если я жестко запрограммирую значение вместо nCell. Так что я не верю, что это проблема. Я отредактировал отправку, чтобы включить предыдущий код в текущий фрагмент.   -  person EMP    schedule 28.08.2017


Ответы (1)


Однажды я столкнулся с подобной проблемой. Используемые массивы могут быть большими, поэтому размер стека недостаточно велик для размещения этих данных. Я предлагаю вам увеличить размер стека. Я использую linux и обычно делаю это через cmd ulimit -s unlimited.

Кроме того, когда вы используете предложение сокращения с openMP, каждый поток создает частную копию переменных, на которые нацелено предложение сокращения. Эти данные помещаются в частный стек, размер которого обычно ограничен несколькими МБ. Чтобы отменить это ограничение, предполагая, что вы пользователь Linux, вы можете запустить, например, команду cmd export OMP_STACKSIZE=50m, чтобы установить размер частного стека в 50 МБ. Значение 50 м может быть изменено в зависимости от аппаратных ограничений и размера ваших массивов.

Важно отметить, что предложение сокращения может быть вообще неэффективным с большими массивами.

person Noureddine    schedule 11.08.2019