У меня был серийный код, в котором я объявлял кучу переменных в модулях, а затем use
эти модули в остальной части моей программы и подпрограмм.Сейчас я пытаюсь распараллелить этот код.Есть часть кода, которую я хочу запустить параллельно, которая, кажется, работает, за исключением одного массива, gtmp
.Я хочу, чтобы у каждого потока была своя собственная версия gtmp
, и я хочу, чтобы эта версия была приватной для соответствующего потока, поэтому я использовал директиву threadprivate
.gtmp
используется только внутри параллельной области кода или внутри подпрограмм, которые вызываются только из параллельной части кода.
Сначала я выделил gtmp
в последовательной части кода передпараллельной части, но это было проблемой, потому что тогда только «версия» главного потока gtmp
была выделена, а «версии» другого потока gtmp
имели size
1
, а не ожидаемый выделенный размерgtmp
, (это было показано оператором "test" print
).Я думаю, что это произошло, потому что главный поток - единственный поток, выполняющий код в последовательных частях.Итак, я переместил линию allocate
в параллельную область, что позволило всем потокам иметь соответствующие размеры / распределенные массивы gtmp
, но, поскольку моя параллельная область находится внутри цикла, я получаю ошибку, когда программа пытается выделить gtmp
второй раз во второй итерации цикла r
.
Примечание: в других местах кода все остальные переменные в mymod
имеют заданные значения.
Вот упрощенная часть кода, в которой возникла проблема:
module mymod
integer :: xBins, zBins, rBins, histCosThBins, histPhiBins, cfgRBins
real(kind=dp),allocatable :: gtmp(:,:,:)
end module mymod
subroutine compute_avg_force
use mymod
implicit none
integer :: r, i, j, ip
integer :: omp_get_thread_num, tid
! I used to allocate 'gtmp' here.
do r = 1, cfgRBins
!$omp PARALLEL DEFAULT( none ) &
!$omp PRIVATE( ip, i, j, tid ) &
!$omp SHARED( r, xBins, zBins, histCosThBins, histPhiBins )
allocate( gtmp(4,0:histCosThBins+1,0:histPhiBins+1) )
tid = omp_get_thread_num() !debug
print*, 'test', tid, histCosThBins, histPhiBins, size(gtmp)
!$omp DO SCHEDULE( guided )
do ip = 1, (xBins*zBins)
call subroutine_where_i_alter_gtmp(...)
...code to be executed in parallel using gtmp...
end do !ip
!$omp END DO
!$omp END PARALLEL
end do !r
end subroutine compute_avg_force
Итак, проблема заключается в том, что мне нужно, чтобы все потоки были активными (т.е. в параллельной области), чтобы надлежащим образом инициализировать все «версии» gtmp
, но моя параллельная область находится внутри цикла иЯ не могу выделить gtmp
более одного раза.
Короче говоря, как правильно распределить gtmp
в этом коде?Я думал, что мог бы просто сделать еще одну область omp parallel
перед циклом и использовать ее для выделения gtmp
, но это кажется неуклюжим, поэтому мне интересно, каков "правильный" способ сделать что-то подобное.
Спасибо за помощь!