我正在尝试循环调用子例程。该子例程具有局部协同数组。以下是我正在使用的代码:
! Test local coarray in procedure called in a loop.
!
program main
use, intrinsic :: iso_fortran_env, only : input_unit, output_unit, error_unit
implicit none
! Variable declaration.
integer :: me, ti
integer :: GHOST_WIDTH, TSTART, TSTEPS
sync all
! Initialize.
GHOST_WIDTH = 1
TSTART = 0
TSTEPS = 100000
me = this_image()
! Iterate.
do ti = TSTART + 1, TSTART + TSTEPS
call Aldeal( GHOST_WIDTH )
if ( me == 1 ) write( output_unit, * ) ti
end do
if ( me == 1 ) write( output_unit, * ) "All done!"
contains
subroutine Aldeal( width )
integer, intent(in) :: width
integer, allocatable, codimension[:] :: shell1_Co, shell2_Co, shell3_Co
allocate( shell1_Co[*], shell2_Co[*], shell3_Co[*] )
deallocate( shell1_Co, shell2_Co, shell3_Co )
return
end subroutine Aldeal
end program main
现在,子例程除了分配本地协数组并取消分配之外,没有执行其他任何操作。但是即使这样做,在某些迭代之后,程序也会向我抛出以下错误:
forrtl: severe (174): SIGSEGV, segmentation fault occurred
In coarray image 1
Image PC Routine Line Source
coarray_main 0000000000406063 Unknown Unknown Unknown
libpthread-2.17.s 00007F21D8B845F0 Unknown Unknown Unknown
libicaf.so 00007F21D90970D5 for_rtl_ICAF_CO_D Unknown Unknown
coarray_main 0000000000405054 main_IP_aldeal_ 37 coarray_main.f90
coarray_main 0000000000404AEC MAIN__ 23 coarray_main.f90
coarray_main 0000000000404A22 Unknown Unknown Unknown
libc-2.17.so 00007F21D85C5505 __libc_start_main Unknown Unknown
coarray_main 0000000000404929 Unknown Unknown Unknown
Abort(0) on node 0 (rank 0 in comm 496): application called MPI_Abort(comm=0x84000003, 0) - process 0
并且对于其他图像也重复相同的错误。
第23行是主程序的do循环内的call Aldeal( GHOST_WIDTH )
。并且第37行对应于子例程中的deallocate( shell1_Co, shell2_Co, shell3_Co )
语句。
另外,如果我从子例程中删除deallocate语句,它将引发相同的错误,但是这次错误语句中的行号是23和39。第39行对应于end subroutine Aldeal
语句。
我无法理解我到底在做什么错。请帮助。
P.S。我正在将Centos 7与Intel(R)Parallel Studio XE 2019 Update 4 for Linux一起使用。
观察:
如果我将代码修改为具有可分配组件的派生类型,并使用它在子例程中创建协数组,则代码将运行更长的时间,但最终会因错误而中止。以下是修改:
module mod_coarray_error
implicit none
type :: int_t
integer, allocatable, dimension(:) :: var
end type int_t
contains
subroutine Aldeal_type( width )
integer, intent(in) :: width
type(int_t), allocatable, codimension[:] :: int_t_Co
allocate( int_t_Co[*] )
allocate( int_t_Co%var(width) )
sync all
! deallocate( int_t_Co%var )
deallocate( int_t_Co )
return
end subroutine Aldeal_type
end module mod_coarray_error
program main
use, intrinsic :: iso_fortran_env, only : input_unit, output_unit, error_unit
use :: mod_coarray_error
implicit none
! Variable declaration.
integer :: me, ti
integer :: GHOST_WIDTH, TSTART, TSTEPS, SAVET
sync all
! Initialize.
GHOST_WIDTH = 3
TSTART = 0
TSTEPS = 100000
SAVET = 1000
me = this_image()
! Iterate.
do ti = TSTART + 1, TSTART + TSTEPS
sync all
call Aldeal_type( GHOST_WIDTH )
if ( mod( ti, SAVET ) == 0 ) then
if ( me == 1 ) write( output_unit, * ) ti
end if
end do
sync all
if ( me == 1 ) write( output_unit, * ) "All done!"
end program main
此外,此代码在Windows中编译时可以正常运行到最后。
现在,如果我添加编译器选项heap-arrays 0
,即使在Linux中,代码似乎也可以运行到最后。
我试图将循环数(即代码中的TSTEPS
增加到1e7
)。即使这样,它也可以成功运行到最后。但我观察到以下效果:
ti = 1e6
运行到ti = 2e6
所花费的时间比从ti = 1
运行到ti = 1e6
所花费的时间要多。2GB
的每个图像,在3.5GB
处消耗ti = 2e6
,在4.7GB
处消耗ti = 4e6
,在6GB
处消耗ti = 6e6
C0]。100MB
,在1.5GB
消耗ti = 2e6
,在2.5GB
消耗ti = 4e6
和3.5GB
消耗ti = 6e6
的图像。/heap-arrays0
对运行(由于没有它已经成功运行)或运行时消耗的内存量都没有影响。最终,我仍然对所发生的事情感到困惑。
P.S。我在英特尔论坛上发布了问题,但尚未收到任何回复。