1

I am trying to pass the allocatable array to the subroutine. When I am using the serial version as mentioned in How to pass allocatable arrays to subroutines in Fortran it is working fine. Below is my serial version of code.

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

When I start to implement using MPI, my parallel version of code is

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

The above code gives the segmentation fault error. I don't understand the reason for this.

Next, when in my subroutine func I change the declaration of arrays a and sqa to

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

Now it works fine. I request to kindly help me understand the reason for the error.

Mohit
  • 11
  • 3

1 Answers1

1

Assumed shape dummy arrays make available the extension of the actual arguments inside the function but not their bounds. If the actual bounds are needed inside the function, explicit-shape dummy arrays must be used.

  • I don't understand what you are saying. – Vladimir F Героям слава May 26 '17 at 06:57
  • Now I got it, but it is not very clear. We should have a duplicate. – Vladimir F Героям слава May 26 '17 at 07:01
  • It isn't true that explicit shape arrays must be used for bound information to be available. – francescalus May 26 '17 at 09:16
  • It is true that passing the lower bound as argument (say lb) and declaring the array as dimension(lb:) keeps its syntactical nature of assumed shape array as defined in the standard. So, I was wrong writing that one has to use explicit-shape arrays. However, this is a corner where the language loses part of its neat consistency, even more if one think that in the case of a pointer the bounds are passed to the procedure, and it happens to me to consider differently the case where a lower bound passed as argument. – GiorgioP-DoomsdayClockIsAt-90 May 27 '17 at 10:50