Sorry for a naïve question. For example, if I want to define a function func(x)
, its behavior depends on the type of the input x
. I mean I can use module procedure to define several functions, then overload them to func. However, is it possible to do such things more easily? like
function func(x)
real :: func
if ( x is real .or. x is complex .or. x is integer) then
do something
end if
So that I do not need to write several do something
functions which are the same actually, and then overload them to func
?
PS.
The real two functions are my scattervi1d
and scattervr1d
which are mpi_scatterv
wrapper as shown below, one deal with integer array scatterv, the other deal with real array scatterv. I overload them to scatterv
. However the content of the scattervi1d
and scattervr1d
are almost exactly the same. The only difference is just type of the input variables r,rscatter
(scattervi1d
deals with integer input, scattervr1d
deals with real input). I feel it is a little bit redundant to define basically the same functions twice.
interface scatterv ! scatterv from process 0 to all process, evenly scatter. inverse of gather
module procedure scattervi1d
module procedure scattervr1d
end interface scatterv
! https://stackoverflow.com/questions/17508647/sending-2d-arrays-in-fortran-with-mpi-gather/17530368#17530368
subroutine scattervi1d(r,rscatter,scounts,displs)
integer(kind=i4) :: r(:),rscatter(:)
integer :: i,ierror,scounts_default(iproc),displs_default(iproc)
integer, optional :: scounts(iproc),displs(iproc)
if (.not.(present(scounts).and.present(displs))) then ! here assume no scounts and no displs.
call gather(size(rscatter),scounts_default)
if (myrank()==0) then
displs_default(1)=0
do i=2,iproc
displs_default(i)=displs_default(i-1)+scounts_default(i-1)
enddo
endif
call mpi_scatterv(r,scounts_default,displs_default,mpir8,rscatter,size(rscatter),mpir8,0, &
mpi_comm_world,ierror)
else
call mpi_scatterv(r,scounts,displs,mpir8,rscatter,size(rscatter),mpir8,0, &
mpi_comm_world,ierror)
endif
return
end subroutine scattervi1d
subroutine scattervr1d(r,rscatter,scounts,displs)
real(kind=r8) :: r(:),rscatter(:)
integer :: i,ierror,scounts_default(iproc),displs_default(iproc)
integer, optional :: scounts(iproc),displs(iproc)
if (.not.(present(scounts).and.present(displs))) then ! here assume no scounts and no displs.
call gather(size(rscatter),scounts_default)
if (myrank()==0) then
displs_default(1)=0
do i=2,iproc
displs_default(i)=displs_default(i-1)+scounts_default(i-1)
enddo
endif
call mpi_scatterv(r,scounts_default,displs_default,mpir8,rscatter,size(rscatter),mpir8,0, &
mpi_comm_world,ierror)
else
call mpi_scatterv(r,scounts,displs,mpir8,rscatter,size(rscatter),mpir8,0, &
mpi_comm_world,ierror)
endif
return
end subroutine scattervr1d