10.1.5. Semantics


Up: C++ Next: C++ Datatypes Previous: Class Member Functions for MPI

The semantics of the member functions constituting the C++ language binding for MPI are specified by the MPI function description itself. Here, we specify the semantics for those portions of the C++ language interface that are not part of the language binding. In this subsection, functions are prototyped using the type MPI::<CLASS> rather than listing each function for every MPI class; the word <CLASS> can be replaced with any valid MPI class name (e.g., Group), except as noted.

Construction / Destruction The default constructor and destructor are prototyped as follows:

MPI::<CLASS>()
MPI::<CLASS>()

In terms of construction and destruction, opaque MPI user level objects behave like handles. Default constructors for all MPI objects except MPI::Status create corresponding MPI::*_NULL handles. That is, when an MPI object is instantiated, comparing it with its corresponding MPI::*_NULL object will return true. The default constructors do not create new MPI opaque objects. Some classes have a member function Create() for this purpose.


Example In the following code fragment, the test will return true and the message will be sent to cout.


void foo() 
{ 
  MPI::Intracomm bar; 

if (bar == MPI::COMM_NULL) cout << "bar is MPI::COMM_NULL" << endl; }

The destructor for each MPI user level object does not invoke the corresponding MPI_*_FREE function (if it exists).


[] Rationale.

MPI_*_FREE functions are not automatically invoked for the following reasons:

    1. Automatic destruction contradicts the shallow-copy semantics of the MPI classes.


    2. The model put forth in MPI makes memory allocation and deallocation the responsibility of the user, not the implementation.


    3. Calling MPI_*_FREE upon destruction could have unintended side effects, including triggering collective operations (this also affects the copy, assignment, and construction semantics). In the following example, we would want neither foo_comm nor bar_comm to automatically invoke MPI_*_FREE upon exit from the function.

    void example_function()  
    { 
      MPI::Intracomm foo_comm(MPI::COMM_WORLD), bar_comm; 
      bar_comm = MPI::COMM_WORLD.Dup(); 
      // rest of function 
    } 
    
( End of rationale.)

Copy / Assignment The copy constructor and assignment operator are prototyped as follows:

MPI::<CLASS>(const MPI::<CLASS>& data)
MPI::<CLASS>& MPI::<CLASS>::operator=(const MPI::<CLASS>& data)

In terms of copying and assignment, opaque MPI user level objects behave like handles. Copy constructors perform handle-based (shallow) copies. MPI::Status objects are exceptions to this rule. These objects perform deep copies for assignment and copy construction.


[] Advice to implementors.

Each MPI user level object is likely to contain, by value or by reference, implementation-dependent state information. The assignment and copying of MPI object handles may simply copy this value (or reference). ( End of advice to implementors.)

Example Example using assignment operator. In this example, MPI::Intracomm::Dup() is not called for foo_comm. The object foo_comm is simply an alias for MPI::COMM_WORLD. But bar_comm is created with a call to MPI::Intracomm::Dup() and is therefore a different communicator than foo_comm (and thus different from MPI::COMM_WORLD). baz_comm becomes an alias for bar_comm. If one of bar_comm or baz_comm is freed with MPI_COMM_FREE it will be set to MPI::COMM_NULL. The state of the other handle will be undefined --- it will be invalid, but not necessarily set to MPI::COMM_NULL.


MPI::Intracomm foo_comm, bar_comm, baz_comm; 

foo_comm = MPI::COMM_WORLD; bar_comm = MPI::COMM_WORLD.Dup(); baz_comm = bar_comm;

Comparison

The comparison operators are prototyped as follows:

bool MPI::<CLASS>::operator==(const MPI::<CLASS>& data) const
bool MPI::<CLASS>::operator!=(const MPI::<CLASS>& data) const

The member function operator==() returns true only when the handles reference the same internal MPI object, false otherwise. operator!=() returns the boolean complement of operator==(). However, since the Status class is not a handle to an underlying MPI object, it does not make sense to compare Status instances. Therefore, the operator==() and operator!=() functions are not defined on the Status class.

Constants Constants are singleton objects and are declared const. Note that not all globally defined MPI objects are constant. For example, MPI::COMM_WORLD and MPI::COMM_SELF are not const.



Up: C++ Next: C++ Datatypes Previous: Class Member Functions for MPI


Return to MPI-2 Standard Index

MPI-2.0 of July 18, 1997
HTML Generated on August 11, 1997