program fortran_mpi_alltoallv
include 'mpif.h'
integer ierr
integer myrank, nprocs
integer numsend, numrecv
integer :: status(MPI_STATUS_SIZE) 
integer, dimension(:), allocatable :: asend, arecv , sendcounts, sdispls


    call MPI_INIT ( ierr )
    !print *, "Hello world"

    call MPI_Comm_rank(MPI_COMM_WORLD, myrank, ierr);
    call MPI_Comm_size(MPI_COMM_WORLD, nprocs, ierr);
    !print *, "Hello World! I am rank ",myrank," of ", size

    allocate(asend(2*nprocs))
    allocate(arecv(2*nprocs))
    allocate(sendcounts(nprocs))
    allocate(sdispls(nprocs))

    do i = 1,nprocs
      asend(2*i)=i+myrank*10
      asend(2*i-1)=-1*(i+myrank*10)
    end do
    !numsend=33
    !numrecv=50
    if (myrank==0) then
    sendcounts= (/1, 2, 3, 2/)
    sdispls= (/0, 1, 3, 6/)
    !recvcounts=sendcounts
    !recvdispls=
    else if (myrank==1) then
    sendcounts= (/2, 3, 2, 1/)
    sdispls= (/0, 2, 5, 7/)
    else if (myrank==2) then
    sendcounts= (/3, 2, 1, 2/)
    sdispls= (/0, 3, 5, 6/)
    else if (myrank==3) then
    sendcounts= (/2, 1, 2, 3/)
    sdispls= (/0, 2, 3, 5/)
    end if

    print*,'myrank=',myrank,'asend:',asend

    call MPI_AlltoAllv(asend, sendcounts, &
         sdispls, MPI_INT, arecv, &
         sendcounts, sdispls, MPI_INT, &
         MPI_COMM_WORLD,ierr)

    print*,'myrank=',myrank,'arecv:',arecv

    !if (myrank==1) then
    !print *," I am rank",myrank," of ", nprocs
    !print *,"Received value numrecv= ", numrecv
    !end if

    deallocate(asend, arecv)
call MPI_FINALIZE ( ierr )

end program fortran_mpi_alltoallv
