9.8 Using C++ and Fortran 90

9.8 Using C++ and Fortran 90

MPI-1 defined bindings to C and Fortran 77. These bindings were very similar; the only major difference was the handling of the error code (returned in C, set through the last argument in Fortran 77). In MPI-2, a binding was added for C++, and an MPI module was defined for Fortran 90.

The C++ binding provides a lightweight model that is more than just a C++ version of the C binding but not a no-holds-barred object-oriented model. MPI objects are defined in the MPI namespace. Most MPI objects have corresponding classes, such as Datatype for MPI_Datatype. Communicators and requests are slightly different. There is an abstract base class Comm for general communicators with four derived classes: Intracomm, Intercomm, Graphcomm, and Cartcomm. Most communicators are Intracomms; GraphComm and CartComm are derived from Intracomm. Requests have two derived classes: Prequest for persistent requests and Grequest for generalized requests (new in MPI-2). Most MPI operations are methods on the appropriate objects; for example, most point-to-point and collective communications are methods on the communicator. A few routines, such as Init and Finalize, stand alone. A simple MPI program in C++ is shown in Figure 9.14.

Start Figure
#include "mpi.h"
#include <iostream.h>

int main( int argc, char *argv[] )
{
    int data;
    MPI::Init();

    if (MPI::COMM_WORLD.Get_rank() == 0) {
        // Broadcast data from process 0 to all others
        cout << "Enter an int" << endl;
        data << cin;
    }
    MPI::COMM_WORLD.Bcast( data, 1, MPI::INT, 0 );

    MPI::Finalize();
    return 0;
}
End Figure

Figure 9.14: Simple MPI program in C++.

The C++ binding for MPI has a few quirks. One is the C++ analogue to MPI_Comm_dup. In the C++ binding, MPI::Comm is an abstract base class (ABC). Since it is impossible to create an instance of an abstract base class, there can be no general "dup" function that returns a new MPI::Comm. Since it is possible in C++ to create a reference to an ABC, however, MPI defines the routine (available only in the C++ binding) MPI::Clone that returns a reference to a new communicator.

Two levels of Fortran 90 support are provided in MPI. The basic support provides an 'mpif.h' include file. The extended support provides an MPI module. The module makes it easy to detect the two most common errors in Fortran MPI programs: forgetting to provide the variable for the error return value and forgetting to declare status as an array of size MPI_STATUS_SIZE. There are a few drawbacks. Fortran derived datatypes cannot be directly supported (the Fortran 90 language provides no way to handle an arbitrary type). Often, you can use the first element of the Fortran 90 derived type. Array sections should not be used in receive operations, particularly nonblocking communication (see Section 10.2.2 in the MPI-2 standard for more information). Another problem is that while Fortran 90 enables the user to define MPI interfaces in the MPI module, a different Fortran 90 interface file must be used for each combination of Fortran datatype and array dimension (scalars are different from arrays of dimension one, etc.). This leads to a Fortran 90 MPI module library that is often (depending on the Fortran 90 compiler) far larger than the entire MPI library. However, particularly during program development, the MPI module can be very helpful.




Part III: Managing Clusters