条件跳转或移动取决于未初始化的值(分段错误/Fortran)
Conditional jump or move depends on uninitialised value(s) (Segmentation Fault / Fortran)
我遇到了分段错误。所以,我决定使用 valgrind。
对于编译,我使用了:
gfortran -fopenmp -g HECESE_openmp.f90
为了执行,我使用了:
valgrind --track-origins=yes ./a.out
我得到的一个错误是“条件跳转或移动取决于未初始化的值”,然后是“未初始化的值是由堆栈分配创建的”。你可以在下面看到它。
==13202== Conditional jump or move depends on uninitialised value(s)
==13202== at 0x1159DC: __procedures_MOD_grad._omp_fn.4 (HECESE_openmp.f90:690)
==13202== by 0x4C78E75: GOMP_parallel (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==13202== by 0x10BF25: __procedures_MOD_grad (HECESE_openmp.f90:660)
==13202== by 0x1123FF: MAIN__ (HECESE_openmp.f90:1063)
==13202== by 0x113E89: main (HECESE_openmp.f90:721)
==13202== Uninitialised value was created by a stack allocation
==13202== at 0x10B211: __procedures_MOD_grad (HECESE_openmp.f90:482)
==13202==
==13202== Conditional jump or move depends on uninitialised value(s)
==13202== at 0x1159E2: __procedures_MOD_grad._omp_fn.4 (HECESE_openmp.f90:690)
==13202== by 0x4C78E75: GOMP_parallel (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==13202== by 0x10BF25: __procedures_MOD_grad (HECESE_openmp.f90:660)
==13202== by 0x1123FF: MAIN__ (HECESE_openmp.f90:1063)
==13202== by 0x113E89: main (HECESE_openmp.f90:721)
==13202== Uninitialised value was created by a stack allocation
==13202== at 0x10B211: __procedures_MOD_grad (HECESE_openmp.f90:482)
==13202==
==13202== Jump to the invalid address stated on the next line
==13202== at 0x0: ???
==13202== by 0x4C7BD7A: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==13202== by 0x4C846A7: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==13202== by 0x4C8304C: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==13202== by 0x10BF25: __procedures_MOD_grad (HECESE_openmp.f90:660)
==13202== by 0x1123FF: MAIN__ (HECESE_openmp.f90:1063)
==13202== by 0x113E89: main (HECESE_openmp.f90:721)
==13202== Address 0x0 is not stack'd, malloc'd or (recently) free'd
这是我编译的代码:
tasklist_GRAD(5)%f_ptr => u_prime_2 !5
tasklist_GRAD(6)%f_ptr => taux_ !6
tasklist_GRAD(7)%f_ptr => u_prime_gauche_2 !7
tasklist_GRAD(8)%f_ptr => u_prime_droite_2 !8
tasklist_GRAD(9)%f_ptr => ax_droite_1 !9
tasklist_GRAD(10)%f_ptr => ax_gauche_1 !10
tasklist_GRAD(11)%f_ptr => ux_droite_1 !11
tasklist_GRAD(12)%f_ptr => ux_gauche_1 !12
tasklist_GRAD(13)%f_ptr => u_grad_x_2 !13
tasklist_GRAD(14)%f_ptr => u_prime_gauche_3 !14
tasklist_GRAD(15)%f_ptr => u_prime_droite_3 !15
tasklist_GRAD(16)%f_ptr => ax_droite_2 !16
tasklist_GRAD(17)%f_ptr => ax_gauche_2 !17
tasklist_GRAD(18)%f_ptr => ux_droite_2 !18
tasklist_GRAD(19)%f_ptr => ux_gauche_2 !19
tasklist_GRAD(20)%f_ptr => u_grad_x_3 !20
!$OMP PARALLEL PRIVATE(num_thread,nthreads) &
!$OMP SHARED(tasklist_GRAD,threads_list,threads_list_all,tasks_ready_master) &
!$OMP SHARED(threads_list_part1,threads_list_part2,threads_list_part3)
num_thread=OMP_GET_THREAD_NUM()
nthreads=OMP_GET_NUM_THREADS()
!Thread Application Master
if (num_thread==1) then
do ff=5,20
if (associated(tasklist_GRAD(ff)%f_ptr) .eqv. .true.) then
tasks_ready_master(ff) = tasklist_GRAD(ff)
end if
end do
do ff=5,20
if (associated(tasks_ready_master(ff)%f_ptr) .eqv. .true.) then
tasks_ready_master(ff)%state=STATE_READY
end if
end do
end if
!Thread Master
if (num_thread==0) then
allocate(threads_list(nthreads-2))
do ff=1,nthreads-2
threads_list(ff)=ff+1
end do
do ff=5,20,nthreads-2
if (tasks_ready_master(ff)%state==STATE_READY) then
threads_list_all(ff:ff+nthreads-3)=threads_list(:)
end if
end do
threads_list_part3=threads_list_all(5:20)
end if
!$OMP BARRIER
!Threads workers
do ff=5,20
if (num_thread==threads_list_part3(ff-4)) then
!$OMP TASK
call tasks_ready_master(ff)%f_ptr(self,ww,pas,cpt ,nb_element,cpt1,dt,dx,p_element,u_prime,u_prime_moins,u_prime_plus,&
&taux,grad_x_u,grad_t_u,grad_x_f,grad_t_f,ax_plus,ax_moins,ux_plus,ux_moins,sm,flux,tab0,tab)
!$OMP END TASK
end if
end do
!$OMP END PARALLEL
第 690 行是:if (tasks_ready_master(ff)%state==STATE_READY)
然后
对于使用的列表:
type(tcb),dimension(20)::tasklist_GRAD,tasks_ready_master
integer,allocatable,dimension(:)::threads_list
integer,dimension(30)::threads_list_all
integer,dimension(3)::threads_list_part1
integer::threads_list_part2
integer,dimension(16)::threads_list_part3
我忽略错误的来源。你能帮我吗 ?这是我第一次使用Valgrind,也是第一次在这个网站上提问。
不幸的是,您将代码编辑为工作版本,这掩盖了问题所在。早期代码的相关部分读取
!Thread Master
if (num_thread==0) then
...
threads_list_part3=threads_list_all(5:20)
end if
!Threads workers
do ff=5,20
if (num_thread==threads_list_part3(ff-4)) then
你有竞争条件。线程零执行括号中的块,但其他线程仍然是 运行 并继续进入 do 循环,因此 threads_list_part3
可能在主线程初始化之前被非主线程访问它。最简单的解决方法是使用屏障来确保非主线程等待主线程完成其工作。您可以明确地执行此操作
!Thread Master
if (num_thread==0) then
...
threads_list_part3=threads_list_all(5:20)
end if
!$omp barrier
!Threads workers
do ff=5,20
if (num_thread==threads_list_part3(ff-4)) then
或隐式地通过工作共享结构,例如 !$omp single
!$omp single
!Thread Master
...
threads_list_part3=threads_list_all(5:20)
!$omp end single
!Threads workers
do ff=5,20
if (num_thread==threads_list_part3(ff-4)) then
我个人认为我更喜欢第二种形式。
我遇到了分段错误。所以,我决定使用 valgrind。 对于编译,我使用了:
gfortran -fopenmp -g HECESE_openmp.f90
为了执行,我使用了:
valgrind --track-origins=yes ./a.out
我得到的一个错误是“条件跳转或移动取决于未初始化的值”,然后是“未初始化的值是由堆栈分配创建的”。你可以在下面看到它。
==13202== Conditional jump or move depends on uninitialised value(s)
==13202== at 0x1159DC: __procedures_MOD_grad._omp_fn.4 (HECESE_openmp.f90:690)
==13202== by 0x4C78E75: GOMP_parallel (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==13202== by 0x10BF25: __procedures_MOD_grad (HECESE_openmp.f90:660)
==13202== by 0x1123FF: MAIN__ (HECESE_openmp.f90:1063)
==13202== by 0x113E89: main (HECESE_openmp.f90:721)
==13202== Uninitialised value was created by a stack allocation
==13202== at 0x10B211: __procedures_MOD_grad (HECESE_openmp.f90:482)
==13202==
==13202== Conditional jump or move depends on uninitialised value(s)
==13202== at 0x1159E2: __procedures_MOD_grad._omp_fn.4 (HECESE_openmp.f90:690)
==13202== by 0x4C78E75: GOMP_parallel (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==13202== by 0x10BF25: __procedures_MOD_grad (HECESE_openmp.f90:660)
==13202== by 0x1123FF: MAIN__ (HECESE_openmp.f90:1063)
==13202== by 0x113E89: main (HECESE_openmp.f90:721)
==13202== Uninitialised value was created by a stack allocation
==13202== at 0x10B211: __procedures_MOD_grad (HECESE_openmp.f90:482)
==13202==
==13202== Jump to the invalid address stated on the next line
==13202== at 0x0: ???
==13202== by 0x4C7BD7A: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==13202== by 0x4C846A7: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==13202== by 0x4C8304C: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==13202== by 0x10BF25: __procedures_MOD_grad (HECESE_openmp.f90:660)
==13202== by 0x1123FF: MAIN__ (HECESE_openmp.f90:1063)
==13202== by 0x113E89: main (HECESE_openmp.f90:721)
==13202== Address 0x0 is not stack'd, malloc'd or (recently) free'd
这是我编译的代码:
tasklist_GRAD(5)%f_ptr => u_prime_2 !5
tasklist_GRAD(6)%f_ptr => taux_ !6
tasklist_GRAD(7)%f_ptr => u_prime_gauche_2 !7
tasklist_GRAD(8)%f_ptr => u_prime_droite_2 !8
tasklist_GRAD(9)%f_ptr => ax_droite_1 !9
tasklist_GRAD(10)%f_ptr => ax_gauche_1 !10
tasklist_GRAD(11)%f_ptr => ux_droite_1 !11
tasklist_GRAD(12)%f_ptr => ux_gauche_1 !12
tasklist_GRAD(13)%f_ptr => u_grad_x_2 !13
tasklist_GRAD(14)%f_ptr => u_prime_gauche_3 !14
tasklist_GRAD(15)%f_ptr => u_prime_droite_3 !15
tasklist_GRAD(16)%f_ptr => ax_droite_2 !16
tasklist_GRAD(17)%f_ptr => ax_gauche_2 !17
tasklist_GRAD(18)%f_ptr => ux_droite_2 !18
tasklist_GRAD(19)%f_ptr => ux_gauche_2 !19
tasklist_GRAD(20)%f_ptr => u_grad_x_3 !20
!$OMP PARALLEL PRIVATE(num_thread,nthreads) &
!$OMP SHARED(tasklist_GRAD,threads_list,threads_list_all,tasks_ready_master) &
!$OMP SHARED(threads_list_part1,threads_list_part2,threads_list_part3)
num_thread=OMP_GET_THREAD_NUM()
nthreads=OMP_GET_NUM_THREADS()
!Thread Application Master
if (num_thread==1) then
do ff=5,20
if (associated(tasklist_GRAD(ff)%f_ptr) .eqv. .true.) then
tasks_ready_master(ff) = tasklist_GRAD(ff)
end if
end do
do ff=5,20
if (associated(tasks_ready_master(ff)%f_ptr) .eqv. .true.) then
tasks_ready_master(ff)%state=STATE_READY
end if
end do
end if
!Thread Master
if (num_thread==0) then
allocate(threads_list(nthreads-2))
do ff=1,nthreads-2
threads_list(ff)=ff+1
end do
do ff=5,20,nthreads-2
if (tasks_ready_master(ff)%state==STATE_READY) then
threads_list_all(ff:ff+nthreads-3)=threads_list(:)
end if
end do
threads_list_part3=threads_list_all(5:20)
end if
!$OMP BARRIER
!Threads workers
do ff=5,20
if (num_thread==threads_list_part3(ff-4)) then
!$OMP TASK
call tasks_ready_master(ff)%f_ptr(self,ww,pas,cpt ,nb_element,cpt1,dt,dx,p_element,u_prime,u_prime_moins,u_prime_plus,&
&taux,grad_x_u,grad_t_u,grad_x_f,grad_t_f,ax_plus,ax_moins,ux_plus,ux_moins,sm,flux,tab0,tab)
!$OMP END TASK
end if
end do
!$OMP END PARALLEL
第 690 行是:if (tasks_ready_master(ff)%state==STATE_READY)
然后
对于使用的列表:
type(tcb),dimension(20)::tasklist_GRAD,tasks_ready_master
integer,allocatable,dimension(:)::threads_list
integer,dimension(30)::threads_list_all
integer,dimension(3)::threads_list_part1
integer::threads_list_part2
integer,dimension(16)::threads_list_part3
我忽略错误的来源。你能帮我吗 ?这是我第一次使用Valgrind,也是第一次在这个网站上提问。
不幸的是,您将代码编辑为工作版本,这掩盖了问题所在。早期代码的相关部分读取
!Thread Master
if (num_thread==0) then
...
threads_list_part3=threads_list_all(5:20)
end if
!Threads workers
do ff=5,20
if (num_thread==threads_list_part3(ff-4)) then
你有竞争条件。线程零执行括号中的块,但其他线程仍然是 运行 并继续进入 do 循环,因此 threads_list_part3
可能在主线程初始化之前被非主线程访问它。最简单的解决方法是使用屏障来确保非主线程等待主线程完成其工作。您可以明确地执行此操作
!Thread Master
if (num_thread==0) then
...
threads_list_part3=threads_list_all(5:20)
end if
!$omp barrier
!Threads workers
do ff=5,20
if (num_thread==threads_list_part3(ff-4)) then
或隐式地通过工作共享结构,例如 !$omp single
!$omp single
!Thread Master
...
threads_list_part3=threads_list_all(5:20)
!$omp end single
!Threads workers
do ff=5,20
if (num_thread==threads_list_part3(ff-4)) then
我个人认为我更喜欢第二种形式。