Я изменяю существующий код на Фортране, который использует библиотеку openmp.Исходная версия этого кода прекрасно работает параллельно.
Я получаю ошибку сегментации, когда к многопоточному запуску обращаются к определенной переменной (я проверял, устанавливая флаги во всем коде).Этот массив определяется как выделяемый, затем как threadprivate, а затем размещается, в то время как в исходной версии он не является размещаемым, и его размер устанавливается немедленно.Я изменил эту часть из-за рабочего плана, который мне дали.
Вот базовый фрагмент кода, который воспроизводит ошибку.Переменная guilty - это массив, который называется здесь "var".
program testparallel
use omp_lib
implicit none
integer :: thread_id, thread_num
integer :: i,N
integer,dimension(:),allocatable,save :: var
!$omp threadprivate(var)
N = 20
allocate(var(5))
!$omp parallel default(shared) private(thread_id)
thread_id = omp_get_thread_num()
thread_num = omp_get_num_threads()
write(*,*)'Parallel execution on ',thread_num, ' Threads'
!$omp do
do i=1,N
var = 0
write(*,*) thread_id,i
end do
!$omp end do
!$omp end parallel
end program testparallel
Так более или менее структурирован исходный код, я не изменял эту часть напрямую.var инициализируется в цикле, и, согласно входным данным, его значения позже используются другими подпрограммами.
Это трассировка ошибки, которую я получил:
Parallel execution on 2 Threads
0 1
0 2
Parallel execution on 2 Threads
0 3
0 4
0 5
Program received signal SIGSEGV: Segmentation fault - invalid memory reference.
0 6
Backtrace for this error:
0 7
0 8
0 9
0 10
#0 0x7F0149194697
#1 0x7F0149194CDE
#2 0x7F014824E33F
#3 0x400FB2 in MAIN__._omp_fn.0 at testparallel.F90:?
#4 0x7F0148C693C4
#5 0x7F01485ECDD4
#6 0x7F0148315F6C
#7 0xFFFFFFFFFFFFFFFF
Segfault непроисходит, если я не определяю var как выделяемый, но сразу определяю его размер (как в исходном коде).Если я выделю его перед тем, как установить его как threadprivate, я получу ошибку компиляции.
Как можно избежать этой ошибки, но сохранить var как выделяемую (что необходимо)?
РЕДАКТИРОВАТЬ: я исправил описаниеоригинального кода.