2017-05-26 46 views
1

我正在嘗試將可分配數組傳遞給子例程。當我使用How to pass allocatable arrays to subroutines in Fortran中提到的串行版本時,它工作正常。以下是我的代碼串行版本。將可分配數組傳遞給Fortran中的MPI子程序

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我改變陣列和SQA的聲明

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

現在它工作正常。我請求幫助我理解錯誤的原因。

+0

歡迎。對於apl Fortran問題,使用標籤[tag:fortran]。 –

+0

在哪一行會崩潰?它打印什麼?學習編譯器的調試功能(例如gfortran中的'-g -fbacktrace -fcheck = all'和ifort中的'-g -traceback -check')。 –

+0

默認情況下,假定形狀數組的下限爲1。如果你希望它是istart,你需要聲明它爲'array(istart:)'。查看更多的重複鏈接。或者只是將環路更改爲'i = 1,尺寸(a,1)' –

回答

1

假定的形狀虛擬數組使得函數內部的實際參數的擴展可用,但不是它們的邊界。如果函數內部需要實際邊界,則必須使用顯式形狀的虛擬數組。

+0

我不明白你在說什麼。 –

+0

現在我明白了,但不是很清楚。我們應該有一個副本。 –

+0

確實必須使用顯式形狀數組使綁定信息可用。 – francescalus

相關問題