Open MPI logo

Open MPI Development Mailing List Archives

  |   Home   |   Support   |   FAQ   |   all Development mailing list

Subject: Re: [OMPI devel] [patch] Bugs in mpi-f90-interfaces.h and its bridge implementation
From: Kawashima (t-kawashima_at_[hidden])
Date: 2012-04-04 21:07:16


Hi Jeff,

Jeffrey Squyres wrote:
>
> On Apr 3, 2012, at 10:56 PM, Kawashima wrote:
>
> > 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.
>
> Excellent -- many thanks for these!
>
> I have some notes on the specific patches, below, but first note the following: Craig Rasmussen and I have been working on revamping the Open MPI Fortran bindings for quite a while. Here's a quick summary of the changes:
>
> 1. two prototypes of the new MPI-3 mpi_f08 module
> a. Full implementation of all functions, not using F08 descriptors
> b. 6-function MPI using F08 descriptors (showing that it can be done) for ifort
> 2. for the existing mpi module:
> a. New implementation using "ignore TKR" directives
> b. If your fortran compiler doesn't support "ignore TKR" directives (e.g., gfortran), fall back and use the old mpi module implementation
> 3. wrapper compiler changes
> a. New "mpifort" wrapper compiler; all Fortran interfaces are available
> b. mpif77 and mpif90 are sym links to mpifort (and may disappear someday)
>
> All of this work is available in a public bitbucket here:
>
> https://bitbucket.org/jsquyres/mpi3-fortran

Great. I'll see it later.

> There's a linker error in there at the tip at the moment; Craig is working on fixing it. When that's done, we'll likely put out a final public test tarball, and assuming that goes well, merge all this stuff into the OMPI SVN trunk. The SVN merge will likely be a little disruptive because the directory structure of the Fortran bindings changed a bit (e.g., all 5 implementations are now under ompi/mpi/fortran).
>
> The point is that I plan to bring in all your fixes to this bitbucket branch so that all the new stuff and all your fixes come in to the trunk at the same time.
>
> 1.4 is dead; I doubt we'll be applying your fixes there.
>
> 1.5 has transitioned to 1.6 (yesterday); I can look into making a patch for the v1.6 series. The tricky part is preserving the mpi module ABI between 1.5.5 and 1.6. We've done this before, though, so I think it'll be do-able.

Thanks for your explanation.
I know we are preparing v1.6 and v1.4 is not active.

> > 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(*)"
>
> Applied, and also made corresponding fixes to my ignore TKR mpi module (the f08 module didn't have these issues).
>
> > 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
>
> Bcast is a little tricky. I think the real solution is to remove the intent altogether from the buffer argument. We talked about this issue a LOT in the MPI-3 Fortran WG.
>
> Here's the short version:
>
> - intent(in): obvious
> - intent(out): the compiler is actually allowed to zero the buffer (!), which we clearly don't want
> - intent(inout): ...there is a reason that this is not desirable, but I don't remember what it is :-(
> - no intent at all: this one is safe

Oh, I didn't know intent(out) is so dangerous.
Thanks for your explanation.

> I honestly don't remember why intent(inout) is not good here, but there is very definitely a reason.
>
> *** Craig -- do you remember?
>
> However, I hadn't back-ported the removal of the intent to the mpi modules because we had intended to leave those alone as much as possible when implementing the mpi_f08 and ignore-TKR-style mpi module. But since you raise this issue, I think you're right -- the fix should be back-ported. So I did.
>
> > 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
>
> Applied all of these.
>
> > MPI_Get | origin_addr | out | in
>
> MPI_Get is actually very much like MPI_Irecv -- it asynchronously fills the buffer (it *may* be filled in when you return, but it may not). So you could make it intent(out), but intent(out) may also make some fortran compilers zero out the buffer first, which we don't want to do. So just like we did for MPI_Irecv in mpi_f08, I removed the intent here.
>
> More specifically, we removed the "intent" clause from all OUT choice buffers, and for all asynchronously-filled choice buffers in the mpi_f08 module. I'm thinking that we should probably do the same for the OMPI's 2 implementations of the mpi module.

I agree. Removing intent seems best for us.

> > 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
>
> I agree: these all look ok to me. No change necessary.
>
> > 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
>
> Applied to both the TKR and ignore TKR mpi modules.
>
> > 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
>
> Some of patch d failed to apply; I *think* because those interfaces were already updated (but I didn't check -- I only checked that the end result was correct). I updated the ignore TKR implementation, too.

I'll check it in bitbucket.

> The mpi_f08 implementation didn't have this issue; it had the intents correct already.
>
> > 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
>
> Per the above general rule, we should remove the intent for all OUT parameters. I *think* that the intent(in) should be ok for Scatter(v).

I agree.

> > 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.
>
> Correct; we haven't implemented yet. We're waiting for ORNL's new collective improvements (which, as I understand it, includes reduce_scatter_block).
>
> > 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
>
> Per above, I think the real solution is to remove the intent for the OUT params.

I agree.

> I've pushed all these changes to my bitbucket -- could you double check what I pushed? I can make you a tarball if that would be easier than grabbing my mercurial tree.

Thanks, no tarball needed. I'll check them in bitbucket in a few days.

Regards,

Takahiro Kawashima,
MPI development team,
Fujitsu