如何解决为什么在尝试使用锁定例程时会出现分段错误?
我有 tasklist_GRAD
,它是一个函数指针数组,我想使用 lock
例程来执行 tasks
(在另一个 module
中定义)。
这是我实施的 subroutine
:
module app_management
use OMP_LIB
use tasks
implicit none
!etats
integer,parameter:: STATE_RUNNING=0
integer,parameter:: STATE_READY=1
integer,parameter:: STATE_WAITING=2
!!$ integer,parameter:: STATE_INACTIVE=3
contains
subroutine management(tasklist_GRAD,var)
INTEGER ::ff
type(tcb)::self
type(variables)::var
!OpenMP variables
integer::num_thread,nthreads
integer,external :: OMP_GET_THREAD_NUM,OMP_GET_NUM_THREADS
type(tcb),dimension(20)::tasklist_GRAD,tasks_ready_master
!Variables pour gestion des threads
integer,allocatable,dimension(:)::threads_list !liste contenant les nums des threads workers
integer,dimension(100)::threads_list_all !liste contenant les nums des threads workers dans l'ordre selon les tâches
integer,dimension(3)::threads_list_part1 ! 3 premières tâches
integer,dimension(16)::threads_list_part3 ! le reste des tâches
integer::threads_list_part2 ! 4 eme tâche
INTEGER(KIND=omp_lock_kind),SAVE :: lock
CALL omp_init_lock (lock)
!=======================================================================================================================================================
!$OMP ParaLLEL PRIVATE(num_thread,threads_list_all,nthreads,ff) &
!$OMP SHARED(tasklist_GRAD,tasks_ready_master,threads_list,lock) &
!$OMP SHARED(threads_list_part1,threads_list_part2,threads_list_part3)
num_thread=OMP_GET_THREAD_NUM() ! le rang du thread
nthreads=OMP_GET_NUM_THREADS() ! le nombre de threads
Choisircese: select case (var%ww_t)
case(0) ! Old CESE
!Thread Application Master (numero 1)
if (num_thread==1) then
do ff=1,3 ! 3 tâches
if (associated(tasklist_GRAD(ff)%f_ptr) .eqv. .true. ) then ! Si tâche attribuée
tasks_ready_master(ff) = tasklist_GRAD(ff) ! égalité de pointeurs
tasks_ready_master(ff)%state=STATE_READY
end if
end do
end if
do while(.not.OMP_test_lock(lock))
!Threads workers
!$OMP DO PRIVATE(ff)
do ff=1,3
call tasks_ready_master(ff)%f_ptr(self,var)
tasks_ready_master(ff)%state=STATE_RUNNING
end do
!$OMP END DO
end do
do ff=1,3
if (tasks_ready_master(ff)%state==STATE_RUNNING) then
tasklist_GRAD(ff)%state=STATE_RUNNING
end if
end do
!Thread Master (numero 0)
if (num_thread==0) then
if(var%pas_t.eq.2)then
var%u_prime_t(2) = var%tab0_t(2,2)+var%dt_t/2.0d0*var%grad_x_u_t(2)!d_t_u(2)
var%u_prime_t(var%cpt_t-1) = var%tab0_t(var%cpt_t-1,2)+var%dt_t/2.0d0*var%grad_t_u_t(var%cpt_t-1)
var%u_prime_t(1) = var%tab0_t(1,2)+var%dt_t/2.0d0*var%grad_t_u_t(1)
var%u_prime_t(var%cpt_t) = var%tab0_t(var%cpt_t,2)+var%dt_t/2.0d0*var%grad_t_u_t(var%cpt_t)
var%u_prime_plus_t(1)= (var%u_prime_t(2)-var%tab_t(1,2))/(var%dx_t/2.0d0)
var%u_prime_moins_t(1)=-(var%u_prime_t(1)-var%tab_t(1,2))/(var%dx_t/2.0d0)
var%u_prime_plus_t(var%cpt_t)= (var%u_prime_t(var%cpt_t)-var%tab_t(var%cpt_t,2))/(var%dx_t/2.0d0)
var%u_prime_moins_t(var%cpt_t)= -(var%u_prime_t(var%cpt_t-1)-var%tab_t(var%cpt_t,2))/(var%dx_t/2.0d0)
endif
end if
!Thread Master (numero 0)
if (num_thread==0) then
call tasks_ready_master(4)%f_ptr(self,var)
tasks_ready_master(4)%state=STATE_RUNNING
end if
!$OMP BARRIER
if (num_thread==0) then
!-------Condition cyclique sur les gradients
if(var%pas_t.eq.1)then
var%grad_x_u_t(var%cpt_t)=var%grad_x_u_t(var%cpt_t-1)!w0(u_prime_plus(cpt),u_prime_moins(cpt),2.0d0,0.01d0)
var%grad_x_u_t(1)=var%grad_x_u_t(var%cpt_t)
endif
if(var%pas_t.eq.2)then
var%grad_x_u_t(1)=var%grad_x_u_t(2)!w0(u_prime_plus(1),u_prime_moins(1),0.0d0,1.0d0)!0.99d0)!
var%grad_x_u_t(var%cpt_t)=var%grad_x_u_t(1)!w0(u_prime_plus(cpt),1.0d0)!0.99d0)!
endif
end if
!------- En vrai,pas retesté avec ce type de gradient. M'est avis que ça ne fonctionne sans doute pas
case(2) ! W2
!Thread Application Master (numero 1)
if (num_thread==1) then
do ff=5,20 ! 16 tâches
if (associated(tasklist_GRAD(ff)%f_ptr) .eqv. .true.) then
tasks_ready_master(ff) = tasklist_GRAD(ff)
tasks_ready_master(ff)%state=STATE_READY
end if
end do
end if
do while(.not.OMP_test_lock(lock))
!Threads workers
!$OMP DO SCHEDULE(DYNAMIC) PRIVATE(ff)
do ff=5,20
call tasks_ready_master(ff)%f_ptr(self,var)
tasks_ready_master(ff)%state=STATE_RUNNING
end do
!$OMP END DO
end do
do ff=5,20
if (tasks_ready_master(ff)%state==STATE_RUNNING) then
tasklist_GRAD(ff)%state=STATE_RUNNING
end if
end do
if (num_thread==0) then
var%grad_x_u_t(var%cpt_t)=var%grad_x_u_t(var%cpt_t-1)
var%grad_x_u_t(1)=var%grad_x_u_t(var%cpt_t)
end if
end select choisircese
!$OMP END ParaLLEL
CALL omp_destroy_lock (lock)
end subroutine management
end module app_management
我收到一个 segmentation fault - invalid memory reference
错误。
这是因为我在代码中添加了以下部分:
do while(.not.OMP_test_lock(lock))
!Threads workers
!$OMP DO PRIVATE(ff)
do ff=1,3
if (tasks_ready_master(ff)%state==STATE_RUNNING) then
tasklist_GRAD(ff)%state=STATE_RUNNING
end if
end do
例如,我有 16 个 tasks
和 4 个 threads
(只有 2 个 workers
,这意味着只有 2 个会执行 tasks
)。我想使用 lock
例程来实现这一点,这就是我添加提到的部分的原因。每当 worker 之间的线程空闲时,它应该执行 tasklist_GRAD
的第一个元素。 master
线程应仅在工作人员空闲与否时才应执行。
我仍在探索 lock
例程。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。