[MPIWG Fortran] proper modern Fortran support for user-defined reductions
Jeff Hammond
jeff.science at gmail.com
Mon Nov 21 01:22:46 CST 2022
Thanks, Malcolm. I suspected this was the case.
>
> No, my_function is not compatible with MPI_User_function_f18 as it has different characteristics.
>
Is any of the following not load-bearing? For example, is “target” an essential part of signature compatibility? It’s fine if it is, I just don’t want to over-specify in MPI.
subroutine MPI_User_function_f18(invec, inoutvec, len, datatype)
use mpi_f08, only : MPI_Datatype
implicit none
type(*), dimension(..), target, intent(in) :: invec
type(*), dimension(..), target, intent(inout) :: inoutvec
integer, intent(in) :: len
type(MPI_Datatype), intent(in) :: datatype
end subroutine
The following is compatible and does the same thing, albeit with more work. Is this acceptable? Because users write this code, they usually know what the arguments are going to be and don’t need to do any type inquiry, but since there can be only one callback signature, it needs to be completely general.
subroutine X_function(invec, inoutvec, len, datatype)
use, intrinsic :: iso_c_binding, only : c_ptr, c_loc, c_f_pointer
use mpi_f08, only : MPI_Datatype
implicit none
type(*), dimension(..), target, intent(in) :: invec
type(*), dimension(..), target, intent(inout) :: inoutvec
integer, intent(in) :: len
type(MPI_Datatype), intent(in) :: datatype
!
type(c_ptr) :: cpi, cpo
integer, dimension(:), pointer :: fpi, fpo
cpi = c_loc(invec)
cpo = c_loc(inoutvec)
call c_f_pointer(cpi,fpi,[size(invec)])
call c_f_pointer(cpo,fpo,[size(inoutvec)])
fpo = fpo + fpi
end subroutine
> It is also unlikely to work in practice despite the Intel acceptance at compile time, as an assumed-rank descriptor is unlikely to be exactly the same as a Fortran-90 assumed-shapee array descriptor.
Indeed, I forgot this, and I know it’s true for GCC.
>
> Also REAL is not compatible with TYPE(*) so it fails on that front too.
>
> On a more philosophical note, I don’t quite see what purpose LEN is meant to achieve. Surely you just pass it the array slice you want to be reduced, no need to tell it the size separately, no?
>
Yes, you are not the first to note this. However, all MPI functions have a buffer, size and type argument. For better or worse, MPI insists on symmetry across languages, and C is clearly the limiter here. Furthermore, the when MPI_Reduce invokes MPI_User_function, it provides a size and a type, and we need a way to handle that, if the user decides to use them.
I have considered proposing a new sentinel for MPI that causes the implementation to ignore size and type and instead infer them from the Fortran descriptor but I don’t know if the MPI Forum has the appetite for this right now.
I have a project [1] to make a more natural MPI Fortran interface that does not use the unnecessary size and type arguments that are redundant with array descriptors but I’m not sure if it belongs in MPI when an open-source library solves the problem. We’ve had enough trouble with Fortran support in MPI implementations already.
Jeff
1. https://github.com/jeffhammond/galaxy-brain - sorry, there is no documentation.
> Cheers,
> --
> ..............Malcolm Cohen, NAG Oxford/Tokyo.
>
> From: mpiwg-fortran <mpiwg-fortran-bounces at lists.mpi-forum.org> On Behalf Of Jeff Hammond via mpiwg-fortran
> Sent: Monday, November 21, 2022 12:09 AM
> To: MPI Forum <mpiwg-fortran at lists.mpi-forum.org>
> Cc: Jeff Hammond <jeff.science at gmail.com>
> Subject: [MPIWG Fortran] Fwd: proper modern Fortran support for user-defined reductions
>
> Brandon Cook raised an interesting issue w.r.t. user-defined reductions and Fortran 2008 in https://github.com/mpi-forum/mpi-issues/issues/576.
>
> I looked at this and it appears we can do something better (https://github.com/mpi-forum/mpi-issues/issues/576#issuecomment-1317157138), namely:
>
> abstract interface
>
> subroutine MPI_User_function_f18(invec, inoutvec, len, datatype)
> use mpi_f08, only : MPI_Datatype
> implicit none
> type(*), dimension(..), target, intent(in) :: invec
> type(*), dimension(..), target, intent(inout) :: inoutvec
> integer, intent(in) :: len
> type(MPI_Datatype), intent(in) :: datatype
> end subroutine
>
> end interface
>
> which allows the user to create their own reduce functions, e.g.:
>
> subroutine MY_function(invec, inoutvec, len, datatype)
> use mpi_f08, only : MPI_Datatype
> implicit none
> real, dimension(:), target, intent(in) :: invec
> real, dimension(:), target, intent(inout) :: inoutvec
> integer, intent(in) :: len
> type(MPI_Datatype), intent(in) :: datatype
> inoutvec = inoutvec + invec
> end subroutine
>
> Do people think this is worth proposing for MPI-5? It would require a new MPI_Op_create function, but already did one for large-count.
>
> Also, can a proper Fortran language lawyer like Bill Long confirm that MY_function is compatible with the abstract interface above? Intel Fortran doesn't complain, but I want to be sure.
>
> Thanks!
>
> Jeff
>
> --
> Jeff Hammond
> jeff.science at gmail.com
> http://jeffhammond.github.io/
>
> _______________________________________________
> mpiwg-fortran mailing list
> mpiwg-fortran at lists.mpi-forum.org
> https://lists.mpi-forum.org/mailman/listinfo/mpiwg-fortran
More information about the mpiwg-fortran
mailing list