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.

5
  • Welcome. Use tag fortran for apl Fortran questions. Commented May 26, 2017 at 6:56
  • In which line does it crash? What does it print? Learn the debugging features of your compiler (like -g -fbacktrace -fcheck=all in gfortran and -g -traceback -check in ifort). Commented May 26, 2017 at 7:00
  • The lower bound of an assumed shape array is 1 by default. If you want it to be istart, you need to declare it as array(istart:). See the duplicate link for more. Or just change the loop to i = 1, size(a, 1) Commented May 26, 2017 at 7:04
  • Would the use of coarrays provide any benefit here? Commented May 26, 2017 at 8:20
  • @VladimirF: Thank you. The duplicate link solves my problem. I was initially thinking that passing the array to subroutine is done somewhat similar to passing by reference and bounds need not to be specified. I was unaware of this bound limits Commented May 26, 2017 at 17:22

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

4 Comments

I don't understand what you are saying.
Now I got it, but it is not very clear. We should have a duplicate.
It isn't true that explicit shape arrays must be used for bound information to be available.
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.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.