I am trying to run this code, the error says 'there is no specific subroutine for the generic ‘mpi_scatterv'
program mpiscatterv
!implicit none
use mpi
real, dimension (:,:), allocatable :: r, rcv_buf
integer :: ierr, my_id, n_proc, rcv_id, snd_id, counter
integer, dimension (:), allocatable :: sendcounts, displs, rcv_count
integer, parameter :: master = 0
integer :: i,j,k
integer :: n = 0
integer :: ios_read = 0
integer :: rem ! remaining data
integer :: div
integer :: summ = 0
open (unit=99, file ='datatest1.dat',iostat=ios_read)
if (ios_read /=0) then
print*, 'could not be opened'
end if
!open (unit=99, file='rawdata2.dat',iostat=ios_read)
do
read (99, *, iostat=ios_read) i,x,y
if (ios_read > 0) then
print*,'something is wrong'
print*,ios_read
stop
else if (ios_read < 0) then
print*, 'end of file is reached'
exit
else
n = n+1
end if
end do
rewind(99)
open(unit=98, file='rawdata2.dat')
allocate(r(2,n))
do i=1,n
read(99,*, iostat=ios_read)j,x,y
r(1,j)= x
r(2,j)= y
write (98,*) x, y
end do
close (99)
close (98)
call mpi_init(ierr)
call mpi_comm_rank(mpi_comm_world, my_id, ierr)
call mpi_comm_size(mpi_comm_world, n_proc, ierr)
rem = mod(2*n,n_proc)
allocate (sendcounts(n_proc))
allocate (displs(n_proc))
allocate (rcv_count(n_proc))
allocate (rcv_buf(2,n_proc))
counter = 1
do while (counter<=n_proc)
sendcounts(counter) = int(2*n/n_proc)
if (rem > 0) then
sendcounts(counter)=int(2*n/n_proc)+2
rem = rem-2
end if
rcv_count=sendcounts
displs(counter)=summ
summ=summ+sendcounts(counter)
counter = counter + 1
end do
counter = 1
if (my_id==0) then
do while (counter<n_proc)
print*,sendcounts, displs
counter = counter + 1
end do
end if
call MPI_Scatterv(r,sendcounts,displs,mpi_real,rcv_buf,rcv_count,mpi_real,0,mpi_comm_world,ierr)
call mpi_finalize(ierr)
end program
I have r data that I want to scatter. r is a 2 coumns and n row. I use scatterv because the data is not divisable by n_proc. When I want to compile it, it shows error, as far as I concern I already do it according to the limited guidance that I got from internet, any website. Which parameter is wrong ?
There are several issues with your code. I managed to reproduce your error by trying to compile your code (main.f90
) with gfortran v6.3 and openMPI v3.1.4
mpifort main.f90
test3.f90:85:106:
call MPI_Scatterv(r(1,:),sendcounts,displs,mpi_real,rcv_buf(1,:),rcv_count,mpi_real,0,mpi_comm_world,ierr)
1
Error: There is no specific subroutine for the generic ‘mpi_scatterv’ at (1)
On openMPI's website you can see that MPI_Scatterv
requires the following:
Input Parameters
sendbuf
Address of send buffer (choice, significant only at root).
sendcounts
Integer array (of length group size) specifying the number of elements to send to each processor.
displs
Integer array (of length group size). Entry i specifies the displacement (relative to sendbuf) from which to take the outgoing data to process i.
sendtype
Datatype of send buffer elements (handle).
recvcount
Number of elements in receive buffer (integer).
recvtype
Datatype of receive buffer elements (handle).
root
Rank of sending process (integer).
comm
Communicator (handle).
The problems is recvcount
(or in your case rcv_count
) should just be a single integer.
I should point out there are several other issues you should address:
implicit none
x
and y
will be undefined when you do thisrcv_buf
is almost certainly the wrong size. I think it should be n/n_proc
at least.The following code compiles, but you need to check carefully. It probably doesn't work.
program mpiscatterv
use mpi
implicit none
real, dimension (:,:), allocatable :: r, rcv_buf
integer :: ierr, my_id, n_proc, rcv_id, snd_id, counter
integer, dimension (:), allocatable :: sendcounts, displs
integer, parameter :: master = 0
integer :: i,j,k, rcv_count
real :: x, y
integer :: n = 0
integer :: ios_read = 0
integer :: rem ! remaining data
integer :: div
integer :: summ = 0
open (unit=99, file ='datatest1.dat',iostat=ios_read)
if (ios_read /=0) then
print*, 'could not be opened'
end if
!open (unit=99, file='rawdata2.dat',iostat=ios_read)
do
read (99, *, iostat=ios_read) i,x,y
if (ios_read > 0) then
print*,'something is wrong'
print*,ios_read
stop
else if (ios_read < 0) then
print*, 'end of file is reached'
exit
else
n = n+1
end if
end do
rewind(99)
open(unit=98, file='rawdata2.dat')
allocate(r(2,n))
do i=1,n
read(99,*, iostat=ios_read)j,x,y
r(1,j)= x
r(2,j)= y
write (98,*) x, y
end do
close (99)
close (98)
call mpi_init(ierr)
call mpi_comm_rank(mpi_comm_world, my_id, ierr)
call mpi_comm_size(mpi_comm_world, n_proc, ierr)
rem = mod(2*n,n_proc)
allocate (sendcounts(n_proc))
allocate (displs(n_proc))
allocate (rcv_buf(2,n/n_proc))
counter = 1
do while (counter<=n_proc)
sendcounts(counter) = int(2*n/n_proc)
if (rem > 0) then
sendcounts(counter)=int(2*n/n_proc)+2
rem = rem-2
end if
displs(counter)=summ
summ=summ+sendcounts(counter)
counter = counter + 1
end do
counter = 1
if (my_id==0) then
do while (counter<n_proc)
print*,sendcounts, displs
counter = counter + 1
end do
end if
call MPI_Scatterv(r(1,:),sendcounts,displs,mpi_real,rcv_buf(1,:),rcv_count,mpi_real,0,mpi_comm_world,ierr)
call mpi_finalize(ierr)
end program