program distribuite
  implicit none
  
  include 'mpif.h'

  character(LEN=50) :: stringa

  integer, parameter :: N = 17  

  integer ierr, error
  integer status(MPI_STATUS_SIZE)
  
  integer k, i, j, resto, iglob, Ncol, Nrow, sup
  integer me, nprocs

! array distribuito per colonne
  integer, allocatable, dimension(:,:) :: a
  
!--------- fine delle dichiarazioni

!-------- inizializzazioni MPI
  call MPI_INIT(ierr)
  call MPI_COMM_SIZE(MPI_COMM_WORLD, nprocs, ierr)
  call MPI_COMM_RANK(MPI_COMM_WORLD, me, ierr)

  Ncol = N 
  Nrow = N / nprocs

  resto = MOD(N, nprocs)
  if (me < resto) then
     Nrow = Nrow + 1 
  endif

  ALLOCATE(a(Ncol, Nrow))   

  iglob = (Nrow * me) + 1
  if (me >= resto) then
     iglob = iglob + resto
  endif

!---------- inizializzazione dell'array
  do j=1,Nrow
     do i=1,Ncol
        if (i == iglob) then
           A(i,j) = 1.0
        else
           A(i,j) = 0.0
        endif
     enddo
     iglob = iglob + 1;
  enddo

!-------- stampa tutto, per controllo

  write(stringa, *) Ncol

  if (me == 0) then
    do j=1,Nrow
       print '('//trim(stringa)//'(I2))', A(:,j)
    enddo
     
     do k=1, nprocs-1
        if (k==resto) then
           Nrow = Nrow - 1
!           deallocate(A)
!           allocate(A(Ncol,Nrow))
        endif

        call MPI_RECV(A, Nrow*Ncol, MPI_INTEGER, k, 0, MPI_COMM_WORLD, status, ierr)
        do j=1,Nrow
           print '('//trim(stringa)//'(I2))', A(:,j)
        enddo
     enddo
  else
     call MPI_SEND(A, Nrow*Ncol, MPI_INTEGER, 0, 0, MPI_COMM_WORLD, ierr)
  endif
  
  call MPI_FINALIZE(ierr)
  
end program distribuite

