Looking at limitations of the following:

  --with-mpi-f90-size=SIZE
specify the types of functions in the Fortran 90 MPI
                          module, where size is one of: trivial (MPI-2
F90-specific functions only), small (trivial + all MPI functions without choice buffers), medium (small + all MPI functions with one choice buffer), large (medium + all MPI functions with 2 choice buffers,
                          but only when both buffers are the same type)

Not sure what "same type" was intended to mean here, if same type than reasonable, but if same type and dimension (and as implemented) then I can't see where any generic installation, i.e. more than one user, could use --with-mpi-f90-size=large. If fact I found one case where a bunch of the generated interfaces are a waste of space and a really bad idea as far as I can tell.

------------------------------------------------------------------------ ------------------------------------------------ subroutine MPI_Gather0DI4(sendbuf, sendcount, sendtype, recvbuf, recvcount, &
        recvtype, root, comm, ierr)
  include 'mpif-common.h'
  integer*4, intent(in) :: sendbuf
  integer, intent(in) :: sendcount
  integer, intent(in) :: sendtype
  integer*4, intent(out) :: recvbuf
  integer, intent(in) :: recvcount
  integer, intent(in) :: recvtype
  integer, intent(in) :: root
  integer, intent(in) :: comm
  integer, intent(out) :: ierr
end subroutine MPI_Gather0DI4

Think about it, all processes are sending data back to root, if each sends a single integer where does the second, third, fourth, etc. integer go? ------------------------------------------------------------------------ ------------------------------------------------

The interfaces for MPI_GATHER do not include the possibility that the sendbuf is an integer and the recvbuffer is an integer array, for example the following does not exist but seems legal or should be legal (and should at the very least replace the above interface): ------------------------------------------------------------------------ ------------------------------------------------ subroutine MPI_Gather01DI4(sendbuf, sendcount, sendtype, recvbuf, recvcount, &
        recvtype, root, comm, ierr)
  include 'mpif-common.h'
  integer*4, intent(in) :: sendbuf
  integer, intent(in) :: sendcount
  integer, intent(in) :: sendtype
  integer*4, dimension(:), intent(out) :: recvbuf
  integer, intent(in) :: recvcount
  integer, intent(in) :: recvtype
  integer, intent(in) :: root
  integer, intent(in) :: comm
  integer, intent(out) :: ierr
end subroutine MPI_Gather01DI4
------------------------------------------------------------------------ ------------------------------------------------

Also, consider that there may be no reason to restrict sendbuf and recvbuf have the same number of dimensions, but it is reasonable to expect sendbuf to have the same or less dimensions as recvbuf (except both being a scalar seems unreasonable). This does complicate the issue from an order (N+1) problem to an order (N+1)*(N+2)/2 problem, where is N = 4 unless otherwise restricted, but should be doable and certain functions should have the 0,0 case eliminated.

Testing OpenMPI 1.2a1r10111 (g95 on OS X 10.4.6), configured with "./ configure F77=g95 FC=g95 LDFLAGS=-lSystemStubs --with-mpi-f90- size=large --enable-static"

------------
call MPI_GATHER(nn,1,MPI_INTEGER,nno,1,MPI_INTEGER,0,allmpi,ier)

 1
Error: Generic subroutine 'mpi_gather' at (1) is not consistent with a specific subroutine interface
----------

I'm doing my development on four different machines each with a different compiler and a different MPI library, one of those (not OpenMPI) spotted that I had forgotten ierr so it definitely was checking the interfaces but was able to handle this problem (and quickly too). In my Fortran 90 experience I'm not aware of a better way to handle these generic interfaces but I have not studied this issue closely enough.

Below is my solution for the generating scripts for MPI_Gather for F90 (also switched to --with-f90-max-array-dim=2). It might be acceptable to reduce the combinations to just equal or one dimension less (00,01,11,12,22) but I pushed the limits of my shell scripting abilities.

Michael

---------- mpi-f90-interfaces.h.sh
#----------------------------------------------------------------------- -

output_120() {
    if test "$output" = "0"; then
        return 0
    fi
    procedure=$1
    rank=$2
    rank2=$3
    type=$5
    type2=$6
    proc="$1$2$3D$4"
    cat <<EOF

subroutine ${proc}(sendbuf, sendcount, sendtype, recvbuf, recvcount, &
        recvtype, root, comm, ierr)
  include 'mpif-common.h'
  ${type}, intent(in) :: sendbuf
  integer, intent(in) :: sendcount
  integer, intent(in) :: sendtype
  ${type2}, intent(out) :: recvbuf
  integer, intent(in) :: recvcount
  integer, intent(in) :: recvtype
  integer, intent(in) :: root
  integer, intent(in) :: comm
  integer, intent(out) :: ierr
end subroutine ${proc}

EOF
}

start MPI_Gather large

for rank in $allranks
do
  case "$rank" in  0)  dim=''  ;  esac
  case "$rank" in  1)  dim=', dimension(:)'  ;  esac
  case "$rank" in  2)  dim=', dimension(:,:)'  ;  esac
  case "$rank" in  3)  dim=', dimension(:,:,:)'  ;  esac
  case "$rank" in  4)  dim=', dimension(:,:,:,:)'  ;  esac
  case "$rank" in  5)  dim=', dimension(:,:,:,:,:)'  ;  esac
  case "$rank" in  6)  dim=', dimension(:,:,:,:,:,:)'  ;  esac
  case "$rank" in  7)  dim=', dimension(:,:,:,:,:,:,:)'  ;  esac

  for rank2 in $allranks
  do
    case "$rank2" in  0)  dim2=''  ;  esac
    case "$rank2" in  1)  dim2=', dimension(:)'  ;  esac
    case "$rank2" in  2)  dim2=', dimension(:,:)'  ;  esac
    case "$rank2" in  3)  dim2=', dimension(:,:,:)'  ;  esac
    case "$rank2" in  4)  dim2=', dimension(:,:,:,:)'  ;  esac
    case "$rank2" in  5)  dim2=', dimension(:,:,:,:,:)'  ;  esac
    case "$rank2" in  6)  dim2=', dimension(:,:,:,:,:,:)'  ;  esac
    case "$rank2" in  7)  dim2=', dimension(:,:,:,:,:,:,:)'  ;  esac

    if [ ${rank2} != "0" ] && [ ${rank2} -ge ${rank} ]; then

output_120 MPI_Gather ${rank} ${rank2} CH "character${dim}" "character${dim2}" output_120 MPI_Gather ${rank} ${rank2} L "logical${dim}" "logical ${dim2}"
    for kind in $ikinds
    do
output_120 MPI_Gather ${rank} ${rank2} I${kind} "integer*$ {kind}${dim}" "integer*${kind}${dim2}"
    done
    for kind in $rkinds
    do
output_120 MPI_Gather ${rank} ${rank2} R${kind} "real*${kind}$ {dim}" "real*${kind}${dim2}"
    done
    for kind in $ckinds
    do
output_120 MPI_Gather ${rank} ${rank2} C${kind} "complex*$ {kind}${dim}" "complex*${kind}${dim2}"
    done

    fi
  done
done
end MPI_Gather
----------
--- mpi_gather_f90.f90.sh
output() {
    procedure=$1
    rank=$2
    rank2=$3
    type=$5
    type2=$6
    proc="$1$2$3D$4"
    cat <<EOF

subroutine ${proc}(sendbuf, sendcount, sendtype, recvbuf, recvcount, &
        recvtype, root, comm, ierr)
  include "mpif-common.h"
  ${type}, intent(in) :: sendbuf
  integer, intent(in) :: sendcount
  integer, intent(in) :: sendtype
  ${type2}, intent(out) :: recvbuf
  integer, intent(in) :: recvcount
  integer, intent(in) :: recvtype
  integer, intent(in) :: root
  integer, intent(in) :: comm
  integer, intent(out) :: ierr
  call ${procedure}(sendbuf, sendcount, sendtype, recvbuf, recvcount, &
        recvtype, root, comm, ierr)
end subroutine ${proc}

EOF
}

for rank in $allranks
do
  case "$rank" in  0)  dim=''  ;  esac
  case "$rank" in  1)  dim=', dimension(:)'  ;  esac
  case "$rank" in  2)  dim=', dimension(:,:)'  ;  esac
  case "$rank" in  3)  dim=', dimension(:,:,:)'  ;  esac
  case "$rank" in  4)  dim=', dimension(:,:,:,:)'  ;  esac
  case "$rank" in  5)  dim=', dimension(:,:,:,:,:)'  ;  esac
  case "$rank" in  6)  dim=', dimension(:,:,:,:,:,:)'  ;  esac
  case "$rank" in  7)  dim=', dimension(:,:,:,:,:,:,:)'  ;  esac

  for rank2 in $allranks
  do
    case "$rank2" in  0)  dim2=''  ;  esac
    case "$rank2" in  1)  dim2=', dimension(:)'  ;  esac
    case "$rank2" in  2)  dim2=', dimension(:,:)'  ;  esac
    case "$rank2" in  3)  dim2=', dimension(:,:,:)'  ;  esac
    case "$rank2" in  4)  dim2=', dimension(:,:,:,:)'  ;  esac
    case "$rank2" in  5)  dim2=', dimension(:,:,:,:,:)'  ;  esac
    case "$rank2" in  6)  dim2=', dimension(:,:,:,:,:,:)'  ;  esac
    case "$rank2" in  7)  dim2=', dimension(:,:,:,:,:,:,:)'  ;  esac

    if [ ${rank2} != "0" ] && [ ${rank2} -ge ${rank} ]; then

output MPI_Gather ${rank} ${rank2} CH "character${dim}" "character${dim2}" output MPI_Gather ${rank} ${rank2} L "logical${dim}" "logical$ {dim2}"
      for kind in $ikinds
      do
output MPI_Gather ${rank} ${rank2} I${kind} "integer*${kind}$ {dim}" "integer*${kind}${dim2}"
      done
      for kind in $rkinds
      do
output MPI_Gather ${rank} ${rank2} R${kind} "real*${kind}$ {dim}" "real*${kind}${dim2}"
      done
      for kind in $ckinds
      do
output MPI_Gather ${rank} ${rank2} C${kind} "complex*${kind}$ {dim}" "complex*${kind}${dim2}"
      done

    fi
  done
done

Reply via email to