6

I read that is recommended to use the MPI module rather than include mpif.h file. However, I get the following error

Error: There is no specific subroutine for the generic ‘mpi_comm_split’

when I run this program

program hello_world
  use mpi_f08
  implicit none
  ! include 'mpif.h'
  integer :: ierr, num_procs, my_id,newcomm
  integer :: color,key

  call MPI_INIT ( ierr )
  color =1; key=0
  call MPI_COMM_RANK (MPI_COMM_WORLD, my_id, ierr)
  call MPI_COMM_SIZE (MPI_COMM_WORLD, num_procs, ierr)

  call MPI_Comm_split(MPI_COMM_WORLD, color,key,newcomm, ierr)

  call MPI_FINALIZE ( ierr )

end

The error disappears if I include 'mpif.h' instead of using the MPI module. Why is that?

Tarek
  • 1,060
  • 4
  • 17
  • 38
  • 3
    Never tried it, but it looks like the type to use for f08 interface uses `type(MPI_comm)` for `newcomm`... – Gilles Jan 06 '17 at 15:24
  • Related to what Gilles has said what happens if you simple "use mpi"? What compiler and version and what mpi and version might be useful as well. – Ian Bush Jan 06 '17 at 15:25
  • 2
    *The error disappears if I include 'mpif.h' instead of using the MPI module. Why is that?* Because, by using the mpi module you are enabling the compiler to check that routine formal and actual arguments match at compile time. The `include` approach lets all sorts of nonsense happen at run time. – High Performance Mark Jan 06 '17 at 16:35

1 Answers1

6

The use mpi_f08 interface introduces different wrapper types for the different MPI handle objects. While in mpif.h and the use mpi interfaces all handles are simply INTEGERs, in the use mpi_f08 interface there are TYPE(MPI_Comm), TYPE(MPI_File), etc. This allows the compiler to perform checks for things like passing a communicator handle where a file handle is expected.

This is a breaking change on the source level as code must be rewritten, e.g.,

INTEGER :: newcomm

becomes

TYPE(MPI_Comm) :: newcomm

On the binary level there is no change since all those MPI_Xyz types are simply an INTEGER wrapped in a TYPE specifier, which makes them layout compatible. Old Fortran code can still exchange MPI handles with modern Fortran code and vice versa - the INTEGER handle value can be set or extracted via newcomm%MPI_VAL.

Hristo Iliev
  • 72,659
  • 12
  • 135
  • 186
  • Thank you! I am getting another error when using MPI_types in reduce function such as `call MPI_Allreduce( x,y , N, MPI_DOUBLE, MPI_SUM, newcomm, ierr )` that Symbol ‘mpi_double’ at (1) has no IMPLICIT type. How should this be modified? using `type(MPI_DOUBLE)` doesn't help. – Tarek Jan 06 '17 at 16:57
  • 5
    `MPI_DOUBLE` corresponds to the C/C++ `double` type. It must not be used in Fortran code. Use `MPI_REAL` or whatever the type of `x` and `y` is (`MPI_DOUBLE_PRECISION`, etc.) – Hristo Iliev Jan 06 '17 at 17:01
  • 1
    However if I have a real(c_double) I would hope a corresponding MPI type is available... – Vladimir F Героям слава Jan 06 '17 at 18:21
  • 1
    Isn't `real(c_double)` only meant to be used when interfacing to C/C++ code? – Hristo Iliev Jan 06 '17 at 22:51
  • Not really@HristoIliev but it is one way to get the number of bytes consistent, so for interfacing with c it is nice. On Intel then (KIND=8) works, but if and when one wants to use gfortran then it can be easier to replace that with c_double which is more portable by design. Whether there are other implications I am not sure, but it works in pure fortran find-n-dandy. – Holmz Jan 08 '17 at 00:07