2016-03-20 4 views
1

Я хочу сделать некоторые элементарные вычисления на массивах в Fortran 90, а также распараллелить мой код с помощью openmp. У меня сейчас следующий код:OpenMP параллельная работа для выделенного массива

program test 
implicit none 

integer,parameter :: n=50 
integer :: i 
integer(8) :: t1,t2,freq 
real(8) :: seq(n),r(n,n,n,n) 
real(8),dimension(n,n,n,n) :: x 

call system_clock(COUNT_RATE=freq) 

seq=[(i,i=1,n)] 
x=spread(spread(spread(seq,2,n),3,n),4,n) 

call system_clock(t1) 

!$omp parallel workshare 
! do some array calculation 
r=atan(exp(-x)) 
!$omp end parallel workshare 

call system_clock(t2) 

print*, sum(r) 
print '(f6.3)',(t2-t1)/real(freq) 

end program test 

Я хочу сейчас, чтобы заменить статические массивы х и р с размещаемыми массивами, так что я тип:

real(8),dimension(:,:,:,:),allocatable :: x,r 
allocate(x(n,n,n,n)) 
allocate(r(n,n,n,n)) 

но что запуск программы в серийном без ошибок и компилятор не учитывает строку «! $ omp parallel workhare».

Какие варианты следует использовать для распараллеливания в этом случае? Я пробовал с omp parallel do с петлями, но он намного медленнее.

Я компиляции моего кода с gfortran 5.1.0 на окнах:

gfortran -ffree-form test.f -o main.exe -O3 -fopenmp -fno-automatic 
+0

* "но кажется, что! $ Omp parallel workhare не работает для выделяемого массива." * Почему? Что значит * «кажется» *? Что значит * «это не работает» *? Не используйте эту фразу, которая ничего не значит. Сообщите нам, что вы пробовали, и с какими ошибками вы столкнулись. BTW, 'real (8)' является уродливым: http://stackoverflow.com/questions/838310/fortran-90-kind-parameter/856243#856243 http://stackoverflow.com/questions/3170239/fortran-integer4- vs-integer4-vs-integerkind-4/3170438 # 3170438 –

+0

Это означает, что программа запускается серийно без ошибок, а компилятор не учитывает строку «! $ omp parallel workhare». – x1hgg1x

+1

Связанный: https://stackoverflow.com/questions/17812003/parallelization-of-elementwise-matrix-multiplication/17832699#17832699 –

ответ

4

Я сталкивалась с этим вопросом в gfortran раньше. Решение состоит в том, чтобы указать массив в следующем виде:

!$omp parallel workshare 
! do some array calculation 
r(:,:,:,:) = atan(exp(-x)) 
!$omp end parallel workshare 

Вот reference.

+0

Это работает для меня. На самом деле я уже пробовал это со статическими массивами, но я не видел разницы, поэтому я удалил его. Таким образом, разница наблюдается только для распределяемого массива. – x1hgg1x

+0

@VladimirF На моей машине с gfortran 5.3.1 проблема все еще присутствует. –

+3

Возможно, причина, по которой версия в ответе работает, в то время как версия 'r = atan (exp (-x)) не является тем, что r является allocatable _and_ назначается в целом. Это означает, что может потребоваться перераспределение, что может вызвать дезактивацию параллельной работы. С другой стороны, использование 'r (:,:,:, :)' заставляет результат выражения присваиваться массиву _existing_ r - возможно, повышение ошибки, если границы несовместимы в зависимости от вашей конфигурации сборки. –