微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么在尝试使用锁定例程时会出现分段错误?

如何解决为什么在尝试使用锁定例程时会出现分段错误?

我有 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 举报,一经查实,本站将立刻删除。