Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Pointers 使用OpenMP时,如何在子例程中分配指针?_Pointers_Fortran_Openmp_Allocation_Fortran2003 - Fatal编程技术网

Pointers 使用OpenMP时,如何在子例程中分配指针?

Pointers 使用OpenMP时,如何在子例程中分配指针?,pointers,fortran,openmp,allocation,fortran2003,Pointers,Fortran,Openmp,Allocation,Fortran2003,如下面的代码示例所示,主程序尝试利用OpenMP调用子例程。在该子例程中,创建并迭代局部指针变量。程序生成数组PTEMPINTLIST的下标#1的值208大于207个错误的上限(具体数字各不相同)。我已经将包含用户的派生类型omp private,但似乎调用的子例程中的局部变量也应该声明为omp private,但我不确定这是否正确,我不知道如何实现这一点 你能帮我解释一下为什么程序会出现这样的错误吗?更重要的是,在使用OpenMP时,您能否帮助评论有关如何在子例程中分配指针的最佳实践 不知道为

如下面的代码示例所示,主程序尝试利用OpenMP调用子例程。在该子例程中,创建并迭代局部指针变量。程序生成数组PTEMPINTLIST的
下标#1的值208大于207个
错误的上限(具体数字各不相同)。我已经将包含用户的派生类型
omp private
,但似乎调用的子例程中的局部变量也应该声明为
omp private
,但我不确定这是否正确,我不知道如何实现这一点

你能帮我解释一下为什么程序会出现这样的错误吗?更重要的是,在使用OpenMP时,您能否帮助评论有关如何在子例程中分配指针的最佳实践

不知道为什么fortran代码没有着色。有人能帮我评论一下如何给代码上色,这样代码更可读吗? 编译器为英特尔Fortran编译器,版本如下: 错误消息如下所示: 代码示例为:
对于主程序中包含的子程序,gfortran给出错误消息:“在文件test_OpenMP.f90/Fortran运行时错误:已修改循环变量的第36行”

显然,“pTempIntList”的大小总是设置为相同的值(在运行之间变化),显然是对随机线程使用大小(aInstance%pIntList)。对于通过该线程的线程来说,它太小。下面是一个有效的版本。对于gfortran和ifort来说,删除“=>null()”似乎是必要的。我不知道是否应该是这样,但由于两个编译器需要它

请尝试以下版本:

module MyModule
  type :: MyType
      integer, dimension(:), pointer :: pIntList
  end type

contains
   subroutine IterateList(aInstance)
      use omp_lib
      integer :: I
      type(MyType) :: aInstance
      integer, dimension(:), pointer :: pTempIntList
      integer :: threadId
      threadId = OMP_GET_THREAD_NUM()
      allocate (pTempIntList(size(aInstance%pIntList)))
      do I = 1, size(pTempIntList)
          write (*, *) i, threadID, size(aInstance%pIntList), size (pTempIntList)
          pTempIntList(I) = I
      end do
   end subroutine IterateList

end module MyModule

program TestOpenMP_1_AllocationWithinSubroutines

   use MyModule
   use omp_lib
   implicit none

   type(MyType) :: instance
   integer :: threadCount
   integer :: threadId
   integer :: I

   !$omp parallel private (instance, threadCount, threadId, I)
   threadCount = OMP_GET_NUM_THREADS()
   write (*,*) 'Thread numbers are: ', threadCount
   threadId = OMP_GET_THREAD_NUM()
   allocate (instance%pIntList(200 + threadId))
   CALL IterateList(instance)
   !$omp end parallel

end program TestOpenMP_1_AllocationWithinSubroutines

对于主程序中包含的子程序,gfortran给出错误消息:“在文件test_OpenMP.f90/Fortran运行时错误:已修改循环变量的第36行”

显然,“pTempIntList”的大小总是设置为相同的值(在运行之间变化),显然是对随机线程使用大小(aInstance%pIntList)。对于通过该线程的线程来说,它太小。下面是一个有效的版本。对于gfortran和ifort来说,删除“=>null()”似乎是必要的。我不知道是否应该是这样,但由于两个编译器需要它

请尝试以下版本:

module MyModule
  type :: MyType
      integer, dimension(:), pointer :: pIntList
  end type

contains
   subroutine IterateList(aInstance)
      use omp_lib
      integer :: I
      type(MyType) :: aInstance
      integer, dimension(:), pointer :: pTempIntList
      integer :: threadId
      threadId = OMP_GET_THREAD_NUM()
      allocate (pTempIntList(size(aInstance%pIntList)))
      do I = 1, size(pTempIntList)
          write (*, *) i, threadID, size(aInstance%pIntList), size (pTempIntList)
          pTempIntList(I) = I
      end do
   end subroutine IterateList

end module MyModule

program TestOpenMP_1_AllocationWithinSubroutines

   use MyModule
   use omp_lib
   implicit none

   type(MyType) :: instance
   integer :: threadCount
   integer :: threadId
   integer :: I

   !$omp parallel private (instance, threadCount, threadId, I)
   threadCount = OMP_GET_NUM_THREADS()
   write (*,*) 'Thread numbers are: ', threadCount
   threadId = OMP_GET_THREAD_NUM()
   allocate (instance%pIntList(200 + threadId))
   CALL IterateList(instance)
   !$omp end parallel

end program TestOpenMP_1_AllocationWithinSubroutines

我认为您遇到了这样一个问题:变量的初始化赋予它
save
属性。使用null指针初始化
pTempIntList
,意味着它会在子例程的不同调用之间保存。我不确定实现的细节,但可以猜测的是,子例程的所有调用实际上都共享该变量的内存


你也应该认真考虑任何谷歌的评论。使用可分配变量通常比使用指针安全得多。如果可以使用allocatables,那么就使用它们。

我认为您遇到了一个问题,即变量的初始化赋予它
save
属性。使用null指针初始化
pTempIntList
,意味着它会在子例程的不同调用之间保存。我不确定实现的细节,但可以猜测的是,子例程的所有调用实际上都共享该变量的内存


你也应该认真考虑任何谷歌的评论。使用可分配变量通常比使用指针安全得多。如果可以使用可分配表,请使用它们。

非常感谢您的解决方案!然而,你知道问题的原因吗?我的意思是,在真实的代码中(比示例更真实一点),仍然会发生这种奇怪的异常。我想知道我是否可以在不破坏你耐心的情况下发布代码(~1000行)…不,我不知道原因。您需要指针还是可以使用可分配的指针?如果一个可分配的将工作,我建议尝试。非常感谢您的解决办法!然而,你知道问题的原因吗?我的意思是,在真实的代码中(比示例更真实一点),仍然会发生这种奇怪的异常。我想知道我是否可以在不破坏你耐心的情况下发布代码(~1000行)…不,我不知道原因。您需要指针还是可以使用可分配的指针?如果一个可分配的将工作,我建议尝试。你不应该有可分配的关键字吗?原因已经写在开始。你说的
是什么意思另一个已经被回答了…?
?奇怪错误的原因仍然不清楚,如果你已经阅读了问题,没有官方或可靠的信息来学习如何应对未来的错误。此外,在这里,重点更明确地放在OpenMP如何管理指针类型的分配上。这样做可能会导致你的帖子被标记,这可能会导致版主采取进一步的行动。你不应该有可分配的关键字吗?原因已经在开头写好了。你说的
是什么意思另一个已经被回答了…?
?奇怪错误的原因仍然不清楚,如果你已经阅读了问题,没有官方或可靠的信息来学习如何应对未来的错误。此外,在这里,重点更明确地放在OpenMP如何管理指针类型的分配上。这样做可能会导致您的帖子被标记,从而导致版主采取进一步的行动。
    module MyModule
        type :: MyType
            integer, dimension(:), pointer :: pIntList => null ()
        end type 
    end module MyModule

    program TestOpenMP_1_AllocationWithinSubroutines

        use MyModule
        use omp_lib
        implicit none

        type(MyType) :: instance
        integer :: threadCount 
        integer :: threadId 
        integer :: I

!$omp parallel private (instance, threadCount, threadId, I)
        threadCount = OMP_GET_NUM_THREADS()
        write (*,*) 'Thread numbers are: ', threadCount
        threadId = OMP_GET_THREAD_NUM()
        allocate (instance%pIntList(200 + threadId))
        CALL IterateList(instance) 
!$omp end parallel

        read (*,*)

    contains

        subroutine IterateList(aInstance)
            type(MyType) :: aInstance
            integer, dimension(:), pointer :: pTempIntList => null()
            integer :: threadId
            threadId = OMP_GET_THREAD_NUM()
            allocate (pTempIntList(size(aInstance%pIntList)))
            do I = 1, size(pTempIntList)
                pTempIntList(I) = I 
                !write (*,*) pTempIntList(I)
                write (*,*) 'Thread ',threadId, ' - ',pTempIntList(I)
            end do          
        end subroutine 

    end program TestOpenMP_1_AllocationWithinSubroutines
module MyModule
  type :: MyType
      integer, dimension(:), pointer :: pIntList
  end type

contains
   subroutine IterateList(aInstance)
      use omp_lib
      integer :: I
      type(MyType) :: aInstance
      integer, dimension(:), pointer :: pTempIntList
      integer :: threadId
      threadId = OMP_GET_THREAD_NUM()
      allocate (pTempIntList(size(aInstance%pIntList)))
      do I = 1, size(pTempIntList)
          write (*, *) i, threadID, size(aInstance%pIntList), size (pTempIntList)
          pTempIntList(I) = I
      end do
   end subroutine IterateList

end module MyModule

program TestOpenMP_1_AllocationWithinSubroutines

   use MyModule
   use omp_lib
   implicit none

   type(MyType) :: instance
   integer :: threadCount
   integer :: threadId
   integer :: I

   !$omp parallel private (instance, threadCount, threadId, I)
   threadCount = OMP_GET_NUM_THREADS()
   write (*,*) 'Thread numbers are: ', threadCount
   threadId = OMP_GET_THREAD_NUM()
   allocate (instance%pIntList(200 + threadId))
   CALL IterateList(instance)
   !$omp end parallel

end program TestOpenMP_1_AllocationWithinSubroutines