使用MPI将可分配数组传递给Fortran中的子例程

时间:2017-05-26 02:16:17

标签: arrays fortran mpi

我正在尝试将可分配数组传递给子例程。当我使用How to pass allocatable arrays to subroutines in Fortran中提到的串行版本时,它工作正常。下面是我的代码序列版。

module test
contains
subroutine func(a,sqa,n)
    implicit none
    integer, intent(in) :: n
    integer, intent(in), dimension(:,:) :: a
    integer, intent(out), dimension(:,:):: sqa
    !local variables
    integer :: i,j
    do i= 1,n
        do j = 1,2
            sqa(i,j) = a(i,j)*a(i,j)
            print *, 'i',i, 'j', j,'sqa(i,j)',sqa(i,j)
        end do
    end do
end subroutine func
end module test

program main
use test
implicit none
integer :: n,i,j
integer, dimension(:,:), allocatable :: a, sqa
print *, 'enter no of rows'
read *, n

allocate(a(1:n,2))
allocate(sqa(1:n,2))
do i = 1,n
    do j = 1, 2
        a(i,j) = i +j
        print *, 'i =',i,'j =',j, a(i,j)
    end do
end do
call func(a,  sqa,n)
deallocate(a,sqa)
end program main

当我开始使用MPI实现时,我的并行版本的代码是

module test
 contains
 subroutine func(a,sqa,istart,iend)
    implicit none
    integer, intent(in) :: istart, iend
    integer, intent(in), dimension(:,:) :: a
    integer, intent(out),dimension(:,:) :: sqa
    !local variables
    integer :: i,j
    do i= istart, iend
        do j = 1,2
            sqa(i,j) = a(i,j)*a(i,j)
            print *, 'i',i, 'j', j,'sqa(i,j)',sqa(i,j)
        end do
    end do
end subroutine func
end module test

program main
use test
use mpi
implicit none
integer :: istart, iend, ierr,nproc, procnum, n,&
points_per_thread, i,j
integer, dimension(:,:), allocatable :: a, sqa
integer,dimension(mpi_status_size) :: status
call mpi_init(ierr)
call mpi_comm_size(mpi_comm_world, nproc, ierr)
call mpi_comm_rank(mpi_comm_world,procnum, ierr)
if(procnum  == 0)then
    print *, 'enter no of rows'
    read *, n
end if
call mpi_bcast(n,1,mpi_integer,0,mpi_comm_world, ierr)
points_per_thread = (n + nproc - 1)/nproc
istart = procnum*points_per_thread + 1
iend = min((procnum + 1)*points_per_thread,n)
print *, 'istart ', istart, 'iend', iend, 'procnum', procnum
call mpi_barrier(mpi_comm_world, ierr)
allocate(a(istart:iend,2))
allocate(sqa(istart:iend,2))
do i = istart,iend
    do j = 1, 2
        a(i,j) = i +j
        print *, 'i =',i,'j =',j, a(i,j)
    end do
end do
call mpi_barrier(mpi_comm_world, ierr)
call func(a(istart:iend,:), sqa(istart:iend,:),istart,iend)
deallocate(a,sqa)
call mpi_finalize(ierr)
end program main

上面的代码给出了分段错误错误。我不明白这个的原因。

接下来,在我的子程序func中,我将数组a和sqa的声明更改为

integer,intent(in):: a(istart:iend,2)
integer, intent(out)::sqa(istart:iend,2)

现在它运作正常。我请求帮助我理解错误的原因。

1 个答案:

答案 0 :(得分:1)

假设形状虚拟数组使函数内部的实际参数的扩展可用,而不是它们的边界。如果函数内部需要实际边界,则必须使用显式形状虚拟数组。