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>() (binding deprecated, see Section Deprecated since MPI-2.2
) }
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.
The destructor for each MPI user level object does not invoke
the corresponding MPI_*_FREE function (if it exists).
MPI_*_FREE functions are not automatically invoked for
the following reasons:
Copy / Assignment The copy constructor and assignment operator are prototyped as follows:
{ MPI::<CLASS>(const MPI::<CLASS>& data) (binding deprecated, see Section Deprecated since MPI-2.2
) }
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.
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.)
Comparison
The comparison operators are prototyped as follows:
{ bool MPI::<CLASS>::operator==(const MPI::<CLASS>& data) const (binding deprecated, see Section Deprecated since MPI-2.2
) }
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.
{
MPI::<CLASS>() (binding deprecated, see Section Deprecated since MPI-2.2
) }
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;
}
Rationale.
1. Automatic destruction contradicts the shallow-copy semantics
of the MPI classes.
( End of rationale.)
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
}
{ MPI::<CLASS>& MPI::<CLASS>::operator=(const MPI::<CLASS>& data) (binding deprecated, see Section Deprecated since MPI-2.2
) }
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;
{ bool MPI::<CLASS>::operator!=(const MPI::<CLASS>& data) const (binding deprecated, see Section Deprecated since MPI-2.2
) }
Up: C++
Next: C++ Datatypes
Previous: Class Member Functions for MPI
Return to MPI-2.2 Standard Index
Return to MPI Forum Home Page
(Unofficial) MPI-2.2 of September 4, 2009
HTML Generated on September 10, 2009