[mpi-21] C++ predefined MPI handles, const, IN/INOUT/OUT, etc.
Rolf Rabenseifner
rabenseifner at [hidden]
Wed Jan 23 03:33:47 CST 2008
Jeff,
you are referencing to MPI-1.1, Sect. 2.2.
The full Chapter 2 of MPI-1.1 is deprecated and substituted by
the full Chapter 2 of MPI-2.0.
In the substituting MPI-2.0 Sect. 2.3, there exist the
following new paragraph:
"MPIs 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."
My comments and alternative-proposal from Tue, 22 Jan 2008 17:29:51
was about this paragraph (updated text to reflect also the "IN" of "INOUT"):
>An alternative-proposal would be to add a clarifying sentence in
>Terms and Conventions, MPI-2.0 Sect. 2.5.1, page 9, line 7:
> Handle arguments can be marked at INOUT to indicate that the handle
> itself may be changed by the routine (e.g., in MPI_TYPE_COMMIT),
> or to indicate that the object referenced by the handle
already exists and
> may be changed but the handle itself is kept unchanged
> (e.g., MPI_TYPE_SET_NAME).
Best regards
Rolf
On Tue, 22 Jan 2008 20:07:05 -0500
Jeff Squyres <jsquyres_at_[hidden]> wrote:
>The 3 proposals that I sent about C++ issues are both intertwined and
>represent a very complex set of issues.
>
>Shorter version
>===============
>
>Does anyone know/remember why the "special case" for the definition of
>OUT parameters exists in MPI-1:2.2?
>
>I ask because the C++ bindings were modeled off the IN/OUT/INOUT
>designations of the language neutral bindings. MPI_COMM_SET_NAME (and
>others) use the "special case" definition of the [IN]OUT designation
>for the MPI communicator handle parameter. Two facts indicate that we
>should either override this INOUT designation for the C++ binding (and
>therefore make the method const) and/or revisit the "special case"
>language in MPI-1:2.2:
>
>1. The C binding does not allow the implementation to change the
>handle value
>2. The following is a valid MPI code:
>
> MPI::Intracomm cxx_comm = MPI::COMM_WORLD;
> cxx_comm.Set_name("foo");
> MPI::COMM_WORLD.Get_name(name, len);
> cout << name << endl;
>
> The output will be "foo" even though we set the name on cxx_comm
>and retrieved it from MPI::COMM_WORLD ***because the state changed on
>the underlying MPI object, not the upper-level handles*** (the same is
>true for error handlers).
>
>Hence, the Set_name() method should be const because the MPI handle
>will not (and cannot) change. Similar arguments apply to keeping the
>MPI predefined C++ handles as "const" (MPI::INT, etc.) -- their values
>must never change during execution. It then follows that unless there
>is a good reason for the "special case" language in MPI-1:2.2, it
>should be removed.
>
>Longer version / more details
>=============================
>
>At the heart of the issue seems to be text from MPI-1:2.2 about the
>definition of IN, OUT, and INOUT parameters to MPI functions. This
>text was used to guide many of the decisions about the C++ bindings,
>such as the const-ness (or not) of C++ methods and MPI predefined C++
>handles. The text states:
>
>-----
> * the call uses but does not update an argument marked IN
> * the call may update an argument marked OUT
> * the call both uses and updates an argument marked INOUT
>
>There is one special case -- if an argument is a handle to an opaque
>object (these terms are defined in Section 2.4.1) and the object is
>updated by the procedure call, then the argument is marked OUT. It is
>marked this way even though the handle itself is not modified -- we
>use the OUT attribute to denote that what the handle _references_ is
>updated.
>-----
>
>The special case for the OUT definition is important because the C++
>bindings were created to mimic the IN, OUT, and INOUT behavior in a
>language that is stricter than C and Fortran: C++ will fail to compile
>if an application violates the defined semantics (which is a good
>thing).
>
>*** The big question: does anyone know/remember why this special case
>*** for the "OUT" definition exists?
>
>The special case seems to imply that *explicit* changes to MPI objects
>should be marked as an [IN]OUT parameter (e.g., SET_NAME and
>SET_ERRHANDLER). Apparently, *implicit* changes to the underlying MPI
>object (such as MPI_ISEND) do not count / should be IN (i.e., many MPI
>implementation *do* change the state either on the communicator or
>something related to the communicator when a send or receive is
>initiated, even though the communicator is an IN argument).
>
>But remember that MPI clearly states that the handle is separate from
>the underlying MPI object. So why does the binding care if the back-
>end object is updated? (regardless of whether the change to the
>object is explicit or implicit)
>
>For example, the language-neutral binding for MPI_COMM_SET_NAME has
>the communicator as an INOUT argument. This clearly falls within the
>"special case" definition because the function semantics explicitly
>change state on the underlying MPI object.
>
>But note that the C binding is "int MPI_Comm_set_name(MPI_Comm
>comm, ...)". Notice that the comm is passed by value, not by
>reference. So even though the language neutral binding called that
>parameter INOUT, it's not possible for the MPI implementation to
>change the value of the handle.
>
>My claim is that if we want to ensure that the C++ bindings match the
>C bindings (i.e., that the implementation cannot change the value of
>the MPI handle), then the method should be const (i.e.,
>cxx_comm.Set_name(...)) *because the handle value will not, and
>***cannot***, change*.
>
>Simply put: regardless of language or implementation, MPI handles must
>have true handle semantics. For example:
>
> MPI::Intracomm cxx_comm = MPI::COMM_WORLD;
> cxx_comm.Set_name("C++ r00l3z!");
>
> MPI::COMM_WORLD.Get_name(name, len);
> cout << name << endl;
>
>The above will output "C++ r00l3z!" because cxx_comm and
>MPI::COMM_WORLD are handles referring to the same underlying
>communicator. Hence, the only state that the handles have is whatever
>refers to their back-end MPI object. Having Set_name() be const
>keeps the *handle* const, not the underlying MPI object.
>
>Tying this all together:
>
>1. cxx_comm.Set_name() *cannot* change state on the cxx_comm handle
>because cxx_comm.Get_name() and MPI::COMM_WORLD.Get_name() must return
>the same results (the same is true for error handlers). Hence,
>regardless of the implementation of the C++ bindings, the handle value
>cannot change. Therefore, this method (and all the others like it)
>should be const.
>
>2. As a related issue, if no one can remember why the "special case"
>exists for OUT, then I think we should remove this text and then
>change all those INOUT parameters for the functions I cited in my
>earlier proposal to IN. This would make the C++ bindings consistent
>with the IN/OUT/INOUT specifications of the language-neutral bindings.
>
>3. All the MPI C++ predefined handles should be const for many of the
>same reasons. Regardless of what happens to the underlying MPI
>object, the value of the handle cannot ever change. This is
>guaranteed by MPI-2:2.5.4 pages 10 lines 38-41:
>
>"All named constants, with the exceptions noted below for Fortran, can
>be used in initialization expressions or assignments. These constants
>do not change values during execution. Opaque objects accessed by
>constant handles are defined and do not change value between MPI
>initialization MPI_INIT and MPI completion MPI_FINALIZE."
>
>Hence, they should all be "const".
>
>-----
>
>In short: C++ gives us stronger protections to ensure that
>applications don't shoot themselves in the foot. If the MPI
>predefined handles are const, then statements like "MPI::INT =
>my_dtype;" will fail to compile. This is a Good Thing.
>
>The original C++ bindings tried to take advantage of const, but missed
>a few points. Ballot two and one of the items in ballot 3 incorrectly
>tried to fix these points by removing const in several places. That
>"fixes" the problem, but removes many of the good qualities that we
>can get in C++ with "const". So let's fix the real problem and leave
>"const" in the C++ bindings.
>
>Are you confused yet? :-)
>
>--
>Jeff Squyres
>Cisco Systems
>
>_______________________________________________
>mpi-21 mailing list
>mpi-21_at_[hidden]
>http://lists.cs.uiuc.edu/mailman/listinfo/mpi-21
Dr. Rolf Rabenseifner . . . . . . . . . .. email rabenseifner_at_[hidden]
High Performance Computing Center (HLRS) . phone ++49(0)711/685-65530
University of Stuttgart . . . . . . . . .. fax ++49(0)711 / 685-65832
Head of Dpmt Parallel Computing . . . www.hlrs.de/people/rabenseifner
Nobelstr. 19, D-70550 Stuttgart, Germany . (Office: Allmandring 30)
More information about the Mpi-21
mailing list