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