-
Notifications
You must be signed in to change notification settings - Fork 926
Description
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)