Open MPI logo

Open MPI Development Mailing List Archives

  |   Home   |   Support   |   FAQ   |   all Development mailing list

Subject: [OMPI devel] [patch] Bugs in mpi-f90-interfaces.h and its bridge implementation
From: Kawashima (t-kawashima_at_[hidden])
Date: 2012-04-03 22:56:34


Hi Open MPI developers,

I and my coworkers checked mpi-f90-interfaces.h against MPI 2.2 standard
and found many bugs in it. Attached patches fix them for trunk.
Though some of them are trivial, others are not so trivial.
So I'll explain them below.

1. incorrect parameter types

  Two trivial parameter type mismatches.
  Fixed in my mpi-f90-interface.type-mismatch.patch.

  MPI_Cart_map periods: integer -> logical
  MPI_Reduce_scatter recvcounts: missing "dimension(*)"

2. incorrect intent against MPI 2.2 standard

  This is a somewhat complex issue.
  First, I'll cite MPI 2.2 standard below.

  2.3 in MPI 2.2 standard says:
    There is one special case - if an argument is a handle to an opaque
    object (these terms are defined in Section 2.5.1), and the object is
    updated by the procedure call, then the argument is marked INOUT or OUT.
    It is marked this way even though the handle itself is not modified -
    we use the INOUT or OUT attribute to denote that what the handle
    references is updated. Thus, in C++, IN arguments are usually either
    references or pointers to const objects.

  2.3 in MPI 2.2 standard also says:
    MPI's use of IN, OUT and INOUT is intended to indicate to the user
    how an argument is to be used, but does not provide a rigorous
    classification that can be translated directly into all language
    bindings (e.g., INTENT in Fortran 90 bindings or const in C bindings).
    For instance, the "constant" MPI_BOTTOM can usually be passed to
    OUT buffer arguments. Similarly, MPI_STATUS_IGNORE can be passed as
    the OUT status argument.

  16.2.4 in MPI 2.2 standard says:
    Advice to implementors.
    The appropriate INTENT may be different from what is given in the
    MPI generic interface. Implementations must choose INTENT so that
    the function adheres to the MPI standard.

  Hmm. intent in mpi-f90-interfaces.h does not necessarily match
  IN/OUT/INOUT in MPI 2.2, especially regarding opaque objects.
  mpi-f90-interfaces.h seems to have consideration of opaque objects
  partially, which is handled in r9922 and r23098.

  I compared MPI 2.2 ("standard") and mpi-f90-interfaces.h ("header")
  and classified problematic parameters into four types.

  Type A. Trivial error.

  These are fixed in my mpi-f90-interface.intent-error-a.patch to match
  the standard.

         subroutine | parameter | standard | header
  -----------------------------+-------------+----------+--------
  MPI_Bcast | buffer | inout | in
  MPI_Pack | outsize | in | out
  MPI_Comm_test_inter | comm | in | inout
                               | flag | out | in
  MPI_Add_error_class | errorclass | out | in
  MPI_Win_create | win | out | in
  MPI_Get | origin_addr | out | in

  Type B. Not match but not error (opaque object).

  Though these parameters in the header don't match the standard,
  it's OK because these are opaque object and should not be INOUT
  for Fortran. Some of these are fixed in r9922 and r23098.
  These should not be changed.

         subroutine | parameter | standard | header
  -----------------------------+-------------+----------+--------
  MPI_Comm_set_attr | comm | inout | in
  MPI_Win_set_attr | win | inout | in
  MPI_Type_set_attr | type | inout | in
  MPI_Comm_set_errhandler | comm | inout | in
  MPI_Win_set_errhandler | win | inout | in
  MPI_File_set_errhandler | file | inout | in
  MPI_File_set_view | fh | inout | in
  MPI_Attr_put | comm | inout | in
  MPI_Attr_delete | comm | inout | in
  MPI_Errhandler_set | comm | inout | in

  Type C. Not match and yet error (opaque object).

  This parameter is similar to Type B but it should be IN, not OUT.
  This is fixed in my mpi-f90-interface.intent-error-c.patch to match
  intent that it should be.

         subroutine | parameter | standard | header | should be
  -----------------------------+-------------+----------+--------+-----------
  MPI_Info_delete | info | inout | out | in

  Type D. Match but error (opaque object).

  Though these parameters in the header match the standard,
  they should be IN for Fortran because these are opaque objects and
  their handles themselves are not changed.
  These are fixed in my mpi-f90-interface.intent-error-d.patch to match
  intent that they should be for Fortran.

         subroutine | parameter | standard | header | should be
  -----------------------------+-------------+----------+--------+-----------
  MPI_Comm_delete_attr | comm | inout | inout | in
  MPI_Win_delete_attr | win | inout | inout | in
  MPI_Type_delete_attr | type | inout | inout | in
  MPI_Comm_set_name | comm | inout | inout | in
  MPI_Type_set_name | type | inout | inout | in
  MPI_Win_set_name | win | inout | inout | in
  MPI_Info_set | info | inout | inout | in
  MPI_Grequest_complete | request | inout | inout | in
  MPI_File_set_size | fh | inout | inout | in
  MPI_File_preallocate | fh | inout | inout | in
  MPI_File_set_info | fh | inout | inout | in
  MPI_File_write_at | fh | inout | inout | in
  MPI_File_write_at_all | fh | inout | inout | in
  MPI_File_iwrite_at | fh | inout | inout | in
  MPI_File_read | fh | inout | inout | in
  MPI_File_read_all | fh | inout | inout | in
  MPI_File_write | fh | inout | inout | in
  MPI_File_write_all | fh | inout | inout | in
  MPI_File_iread | fh | inout | inout | in
  MPI_File_iwrite | fh | inout | inout | in
  MPI_File_seek | fh | inout | inout | in
  MPI_File_read_shared | fh | inout | inout | in
  MPI_File_write_shared | fh | inout | inout | in
  MPI_File_iread_shared | fh | inout | inout | in
  MPI_File_iwrite_shared | fh | inout | inout | in
  MPI_File_read_ordered | fh | inout | inout | in
  MPI_File_write_ordered | fh | inout | inout | in
  MPI_File_seek_shared | fh | inout | inout | in
  MPI_File_write_at_all_begin | fh | inout | inout | in
  MPI_File_write_at_all_end | fh | inout | inout | in
  MPI_File_read_all_begin | fh | inout | inout | in
  MPI_File_read_all_end | fh | inout | inout | in
  MPI_File_write_all_begin | fh | inout | inout | in
  MPI_File_write_all_end | fh | inout | inout | in
  MPI_File_read_ordered_begin | fh | inout | inout | in
  MPI_File_read_ordered_end | fh | inout | inout | in
  MPI_File_write_ordered_begin | fh | inout | inout | in
  MPI_File_write_ordered_end | fh | inout | inout | in
  MPI_File_set_atomicity | fh | inout | inout | in
  MPI_File_sync | fh | inout | inout | in

3. incorrect intent for MPI_IN_PLACE

  5.2.1 in MPI 2.2 standard says:
    Advice to users.
    By allowing the "in place" option, the receive buffer in many of the
    collective calls becomes a send-and-receive buffer. For this reason,
    a Fortran binding that includes INTENT must mark these as INOUT,
    not OUT. Note that MPI_IN_PLACE is a special kind of value; it has
    the same restrictions on its use that MPI_BOTTOM has.

  My mpi-f90-interfaces.intent-inplace.patch adapt intent parameters
  to match intent for Fortran regarding MPI_IN_PLACE.
  Note that intent of MPI_Scatter(v) should not be changed because
  MPI_IN_PLACE can be specified for recvbuf instead of sendbuf and
  no data are modified in sendbuf.

         subroutine | parameter | standard | header | should be
  -----------------------------+-----------+----------+--------+-----------
  MPI_Gather(v) | recvbuf | out | out | inout
  MPI_Scatter(v) | sendbuf | in | in | in
  MPI_Allgather(v) | recvbuf | out | out | inout
  MPI_Alltoall(v,w) | recvbuf | out | out | inout
  MPI_Reduce | recvbuf | out | out | inout
  MPI_Allreduce | recvbuf | out | out | inout
  MPI_Reduce_scatter | recvbuf | out | out | inout
  MPI_Scan | recvbuf | out | out | inout
  MPI_Exscan | recvbuf | out | out | inout

  It seems that MPI_Reduce_scatter_block, which appears in MPI 2.2, is not
  implemented in trunk yet. So my patch doesn't include modification for it.

  If you merge this patch to v1.4 branch, don't merge modification of
  MPI_Alltoall(v,w) and MPI_Exscan. MPI 2.1 doesn't allow to use MPI_IN_PLACE
  for these functions yet.

  This modification is necessary for some compilers. For example, consider
  the following code.

    double, dimension(1) :: buf
    buf(1) = value
    call mpi_allreduce(mpi_in_place, buf, 1, mpi_double, mpi_sum, comm)

  If recvbuf is declared as "intent(out)" in mpi.mod, a compiler may
  remove substitution of value for optimization because it is considered
  not to be read in mpi_allreduce subroutine.

4. mismatched interface and bridge

  I compared ompi/mpi/f90/scripts/mpi-f90-interfaces.h ("interface") and
  ompi/mpi/f90/scripts/mpi_*_f90.f90.sh ("bridge") and found some mismatches
  between them. The interfaces (except MPI_Mrecv) seems to be modifed in
  r11057 but (I imagine) the bridges are forgotten to be modified at that
  time.
  These are fixed in my mpi-f90-interfaces.mismatched-bridge.patch to match
  the interface.

         subroutine | parameter | interface | bridge
  -----------------------------+-----------+-----------+--------
  MPI_Recv | status | out | inout
  MPI_Sendrecv | status | out | inout
  MPI_Sendrecv_replace | status | out | inout
  MPI_Mrecv | status | out | inout

I also attached a patch mpi-f90-interfaces.all-in-one.patch that includes
all 6 patches described above.

Regards,

Takahiro Kawashima,
MPI development team,
Fujitsu