Skip to content

mpi_f08 user-defined reductions #3409

@nathanweeks

Description

@nathanweeks

I'm trying to implement a driver program that uses the user-defined reduction from example 5.21 in the MPI 3.1 standard. However, I encounter a compile-time error. It looks like it could be an issue with the OpenMPI implementation, though it also may be just my misunderstanding of how this is supposed to be represented in Fortran.

subroutine my_user_function( invec, inoutvec, len, type )
  use, intrinsic :: iso_c_binding, only : c_ptr, c_f_pointer
  use mpi_f08
  type(c_ptr), value :: invec, inoutvec
  integer :: len 
  type(MPI_Datatype) :: type
  real, pointer :: invec_r(:), inoutvec_r(:)
  if (type%MPI_VAL == MPI_REAL%MPI_VAL) then
     call c_f_pointer(invec, invec_r, (/ len /) )
     call c_f_pointer(inoutvec, inoutvec_r, (/ len /) )
  inoutvec_r = invec_r + inoutvec_r
  end if
end subroutine

program mpi_example_5_21
   use mpi_f08
#ifdef USE_MPI_F08_INTERFACES_CALLBACKS
   use mpi_f08_interfaces_callbacks, only : MPI_User_function
#endif
   implicit none

   type(MPI_Op) :: myOp
   procedure(MPI_User_function) :: my_user_function
   integer :: rank, nproc
   real :: R(100), S(100) = 1.0 

   call MPI_Init
   call MPI_Comm_rank(comm=MPI_COMM_WORLD, rank=rank)
   call MPI_Comm_size(comm=MPI_COMM_WORLD, size=nproc)

   call MPI_Op_create(user_fn=my_user_function, commute=.true., op=myOp)
   call MPI_Reduce(sendbuf=S, recvbuf=R, count=size(S), datatype=MPI_REAL, op=myOp, root=0, comm=MPI_COMM_WORLD)

   call MPI_Finalize

   if (rank == 0) write (*,*) merge('PASS', 'FAIL', all(R == S(1)*nproc))
end program mpi_example_5_21

Using Open-MPI 1.10.3 (MacPorts openmpi-gcc6 OS X 10.11.6, with gfortran 6.3.0), the following compile-time error results:

$ /opt/local/bin/mpif90 -o mpi_example_5_21.mac mpi_example_5_21.F90
mpi_example_5_21.F90:23:51:

    procedure(MPI_User_function) :: my_user_function
                                                   1
Error: Interface 'mpi_user_function' at (1) must be explicit
mpi_example_5_21.F90:31:72:

    call MPI_Op_create(user_fn=my_user_function, commute=.true., op=myOp)
                                                                        1
Error: There is no specific subroutine for the generic 'mpi_op_create' at (1)

However, adding the OpenMPI-specific use mpi_f08_interfaces_callbacks, only : MPI_User_function, the code compiles and runs:

$ /opt/local/bin/mpif90 -DUSE_MPI_F08_INTERFACES_CALLBACKS -o mpi_example_5_21.mac mpi_example_5_21.F90
$ /opt/local/bin/mpiexec -n 2 mpi_example_5_21.mac
 PASS

Using a self-compiled OpenMPI 2.1.0 with Intel 17.0.2 20170213 in a Cray XC environment (NERSC Cori), a compile-time error also results when mpi_f08_interfaces_callbacks is not used (note that I wasn't able to run the example due to a missing library that present on the login node when I built Open MPI, but not on the compute nodes):

$ mpifort -o mpi_example_5_21.cray mpi_example_5_21.F90
mpi_example_5_21.F90(23): error #8169: The specified interface is not declared.   [MPI_USER_FUNCTION]
   procedure(MPI_User_function) :: my_user_function
-------------^
compilation aborted for mpi_example_5_21.F90 (code 1)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions