Unless said otherwise, opaque objects are ``the same'' in all languages: they carry the same information, and have the same meaning in both languages. The mechanism described in the previous section can be used to pass references to MPI objects from language to language. An object created in one language can be accessed, modified or freed in another language.
We examine below in more detail, issues that arise for each type of MPI object.
Datatypes encode the same information in all languages. E.g., a datatype accessor like MPI_TYPE_GET_EXTENT will return the same information in all languages. If a datatype defined in one language is used for a communication call in another language, then the message sent will be identical to the message that would be sent from the first language: the same communication buffer is accessed, and the same representation conversion is performed, if needed. All predefined datatypes can be used in datatype constructors in any language. If a datatype is committed, it can be used for communication in any language.
The function MPI_GET_ADDRESS returns the same value in all languages. Note that we do not require that the constant MPI_BOTTOM have the same value in all languages (see Constants , page Constants ).
Example
! FORTRAN CODE REAL R(5) INTEGER TYPE, IERR, AOBLEN(1), AOTYPE(1) INTEGER (KIND=MPI_ADDRESS_KIND) AODISP(1) ! create an absolute datatype for array R AOBLEN(1) = 5 CALL MPI_GET_ADDRESS( R, AODISP(1), IERR) AOTYPE(1) = MPI_REAL CALL MPI_TYPE_CREATE_STRUCT(1, AOBLEN,AODISP,AOTYPE, TYPE, IERR) CALL C_ROUTINE(TYPE)
/* C code */ void C_ROUTINE(MPI_Fint *ftype) { int count = 5; int lens[2] = {1,1}; MPI_Aint displs[2]; MPI_Datatype types[2], newtype; /* create an absolute datatype for buffer that consists */ /* of count, followed by R(5) */ MPI_Get_address(&count, &displs[0]); displs[1] = 0; types[0] = MPI_INT; types[1] = MPI_Type_f2c(*ftype); MPI_Type_create_struct(2, lens, displs, types, &newtype); MPI_Type_commit(&newtype); MPI_Send(MPI_BOTTOM, 1, newtype, 1, 0, MPI_COMM_WORLD); /* the message sent contains an int count of 5, followed */ /* by the 5 REAL entries of the Fortran array R. */ }
Advice
to implementors.
The following implementation can be used: MPI addresses, as returned by MPI_GET_ADDRESS, will have the same value in all languages. One obvious choice is that MPI addresses be identical to regular addresses. The address is stored in the datatype, when datatypes with absolute addresses are constructed. When a send or receive operation is performed, then addresses stored in a datatype are interpreted as displacements that are all augmented by a base address. This base address is (the address of) buf, or zero, if buf = MPI_BOTTOM. Thus, if MPI_BOTTOM is zero then a send or receive call with buf = MPI_BOTTOM is implemented exactly as a call with a regular buffer argument: in both cases the base address is buf. On the other hand, if MPI_BOTTOM is not zero, then the implementation has to be slightly different. A test is performed to check whether buf = MPI_BOTTOM. If true, then the base address is zero, otherwise it is buf. In particular, if MPI_BOTTOM does not have the same value in Fortran and C/C++, then an additional test for buf = MPI_BOTTOM is needed in at least one of the languages.
It may be desirable to use a value other than zero for
MPI_BOTTOM even in C/C++, so as to distinguish it from a NULL
pointer.
If MPI_BOTTOM = c then one can still avoid the test
buf = MPI_BOTTOM, by using the displacement from
MPI_BOTTOM, i.e., the regular address - c, as the MPI address
returned by MPI_GET_ADDRESS and stored in absolute datatypes.
( End of advice to implementors.)
MPI calls may associate callback functions with MPI objects: error handlers are associated with communicators and files, attribute copy and delete functions are associated with attribute keys, reduce operations are associated with operation objects, etc. In a multilanguage environment, a function passed in an MPI call in one language may be invoked by an MPI call in another language. MPI implementations must make sure that such invocation will use the calling convention of the language the function is bound to.
Advice
to implementors.
Callback functions need to have a language tag. This tag is set
when the callback function is passed in by the library function (which
is presumably different for each language), and is used to generate
the right calling sequence when the callback function is invoked.
( End of advice to implementors.)
Advice
to implementors.
Error handlers, have,
in C and C++, a `` stdargs'' argument list.
It might be useful to
provide to the handler information on the language environment where
the error occurred.
( End of advice to implementors.)
Advice to users.
Reduce operations receive as one of their arguments the datatype of the
operands.
Thus, one can define ``polymorphic'' reduce
operations that work for C, C++, and Fortran datatypes.
( End of advice to users.)
Some of the datatype accessors and constructors have arguments of type MPI_Aint (in C) or MPI::Aint in C++, to hold addresses. The corresponding arguments, in Fortran, have type INTEGER. This causes Fortran and C/C++ to be incompatible, in an environment where addresses have 64 bits, but Fortran INTEGERs have 32 bits.
This is a problem, irrespective of interlanguage issues. Suppose that a Fortran process has an address space of 4 GB. What should be the value returned in Fortran by MPI_ADDRESS, for a variable with an address above 232? The design described here addresses this issue, while maintaining compatibility with current Fortran codes.
The constant MPI_ADDRESS_KIND is defined so that, in Fortran
90,
INTEGER(KIND=MPI_ADDRESS_KIND))
is an address sized integer type (typically, but not necessarily,
the size of an INTEGER(KIND=MPI_ADDRESS_KIND) is 4 on 32 bit address machines and 8 on 64
bit address machines).
Similarly, the constant
MPI_INTEGER_KIND is defined so that
INTEGER(KIND=MPI_INTEGER_KIND) is a default size
INTEGER.
There are seven functions that have address arguments:
MPI_TYPE_HVECTOR,
MPI_TYPE_HINDEXED,
MPI_TYPE_STRUCT,
MPI_ADDRESS,
MPI_TYPE_EXTENT
MPI_TYPE_LB and
MPI_TYPE_UB.
Four new functions are provided to supplement the first four functions in this list. These functions are described in Section Type Constructors with Explicit Addresses on page Type Constructors with Explicit Addresses . The remaining three functions are supplemented by the new function MPI_TYPE_GET_EXTENT, described in that same section. The new functions have the same functionality as the old functions in C/C++, or on Fortran systems where default INTEGERs are address sized. In Fortran, they accept arguments of type INTEGER(KIND=MPI_ADDRESS_KIND), wherever arguments of type MPI_Aint and MPI::Aint are used in C and C++. On Fortran 77 systems that do not support the Fortran 90 KIND notation, and where addresses are 64 bits whereas default INTEGERs are 32 bits, these arguments will be of an appropriate integer type. The old functions will continue to be provided, for backward compatibility. However, users are encouraged to switch to the new functions, in Fortran, so as to avoid problems on systems with an address range > 232, and to provide compatibility across languages.