MPI_Get_elements
Get the number of basic elements receivedint MPI_Get_elements( MPI_Status *status, MPI_Datatype datatype, int *elements );
Parameters
- status
- [in] status
- datatype
- [in] datatype
- elements
- [out] elements
Remarks
The number of basic elements received can be retrieved from status using the query function MPI_GET_ELEMENTS. If the size of the datatype is zero and the amount of data returned as determined by status is also zero, this routine will return a count of zero. This is consistent with a clarification made by the MPI Forum.
Usage of
MPI_GET_COUNT and MPI_GET_ELEMENT.
... CALL MPI_TYPE_CONTIGUOUS(2, MPI_REAL, Type2, ierr) CALL MPI_TYPE_COMMIT(Type2, ierr) ... CALL MPI_COMM_RANK(comm, rank, ierr) IF(rank.EQ.0) THEN CALL MPI_SEND(a, 2, MPI_REAL, 1, 0, comm, ierr) CALL MPI_SEND(a, 3, MPI_REAL, 1, 0, comm, ierr) ELSE CALL MPI_RECV(a, 2, Type2, 0, 0, comm, stat, ierr) CALL MPI_GET_COUNT(stat, Type2, i, ierr) ! returns i=1 CALL MPI_GET_ELEMENTS(stat, Type2, i, ierr) ! returns i=2 CALL MPI_RECV(a, 2, Type2, 0, 0, comm, stat, ierr) CALL MPI_GET_COUNT(stat, Type2, i, ierr) ! returns i=MPI_UNDEFINED CALL MPI_GET_ELEMENTS(stat, Type2, i, ierr) ! returns i=3 END IF
The function MPI_GET_ELEMENTS can also be used after a probe to find the number of elements in the probed message. Note that the two functions MPI_GET_COUNT and MPI_GET_ELEMENTS return the same values when they are used with basic datatypes.
Rationale.
The extension given to the definition of MPI_GET_COUNT seems natural: one would expect this function to return the value of the count argument, when the receive buffer is filled. Sometimes datatype represents a basic unit of data one wants to transfer, for example, a record in an array of records (structures). One should be able to find out how many components were received without bothering to divide by the number of elements in each component. However, on other occasions, datatype is used to define a complex layout of data in the receiver memory, and does not represent a basic unit of data for transfers. In such cases, one needs to use the function MPI_GET_ELEMENTS.
Notes for Fortran
All MPI routines in Fortran (except for MPI_WTIME and MPI_WTICK) have an additional argument ierr at the end of the argument list. ierr is an integer and has the same meaning as the return value of the routine in C. In Fortran, MPI routines are subroutines, and are invoked with the call statement.All MPI objects (e.g., MPI_Datatype, MPI_Comm) are of type INTEGER in Fortran.
Errors
All MPI routines (except MPI_Wtime and MPI_Wtick) return an error value; C routines as the value of the function and Fortran routines in the last argument. Before the value is returned, the current MPI error handler is called. By default, this error handler aborts the MPI job. The error handler may be changed with MPI_Comm_set_errhandler (for communicators), MPI_File_set_errhandler (for files), and MPI_Win_set_errhandler (for RMA windows). The MPI-1 routine MPI_Errhandler_set may be used but its use is deprecated. The predefined error handler MPI_ERRORS_RETURN may be used to cause error values to be returned. Note that MPI does not guarentee that an MPI program can continue past an error; however, MPI implementations will attempt to continue whenever possible.
- MPI_SUCCESS
- No error; MPI routine completed successfully.
Example Code
The following sample code illustrates MPI_Get_elemenets.
#include "mpi.h"
#include <stdio.h>
/* Receive partial datatypes and check that MPI_Getelements gives the correct
version */
int main( int
argc, char *argv[] )
{
int errs = 0;
MPI_Datatype outtype, oldtypes[2];
MPI_Aint offsets[2];
int blklens[2];
MPI_Comm comm;
int size, rank,
src, dest, tag;
MPI_Init( &argc, &argv );
comm = MPI_COMM_WORLD;
MPI_Comm_rank( comm, &rank );
MPI_Comm_size( comm, &size );
if (size < 2) {
printf( "This test requires at least 2 processes\n" );fflush(stdout);
MPI_Abort( MPI_COMM_WORLD, 1 );
}
src = 0;
dest = 1;
if (rank == src)
{
int buf[128],
position, cnt;
/* sender */
/* Create a datatype and send it
(multiple of sizeof(int)) */
/* Create a send struct type */
oldtypes[0] = MPI_INT;
oldtypes[1] = MPI_CHAR;
blklens[0] = 1;
blklens[1] = 4*sizeof(int);
offsets[0] = 0;
offsets[1] = sizeof(int);
MPI_Type_struct( 2, blklens, offsets, oldtypes, &outtype );
MPI_Type_commit( &outtype );
buf[0] = 4*sizeof(int);
MPI_Send( buf, 1, outtype, dest, 0, comm );
MPI_Type_free( &outtype );
/* Create a datatype and send it (not a
multiple of sizeof(int)) */
/* Create a send struct type */
oldtypes[0] = MPI_INT;
oldtypes[1] = MPI_CHAR;
blklens[0] = 1;
blklens[1] = 4*sizeof(int)+1;
offsets[0] = 0;
offsets[1] = sizeof(int);
MPI_Type_struct( 2, blklens, offsets, oldtypes, &outtype );
MPI_Type_commit( &outtype );
buf[0] = 4*sizeof(int)
+ 1;
MPI_Send( buf, 1, outtype, dest, 1, comm );
MPI_Type_free( &outtype );
/* Pack data and send as packed */
position = 0;
cnt = 7;
MPI_Pack( &cnt, 1, MPI_INT, buf, 128*sizeof(int),
&position, comm );
MPI_Pack( "message", 7, MPI_CHAR, buf, 128*sizeof(int),
&position, comm );
MPI_Send( buf, position, MPI_PACKED, dest, 2, comm );
}
else
if (rank == dest) {
MPI_Status status;
int buf[128], i,
elms, count;
/* Receiver */
/* Create a receive struct type */
oldtypes[0] = MPI_INT;
oldtypes[1] = MPI_CHAR;
blklens[0] = 1;
blklens[1] = 256;
offsets[0] = 0;
offsets[1] = sizeof(int);
MPI_Type_struct( 2, blklens, offsets, oldtypes, &outtype );
MPI_Type_commit( &outtype );
for (i=0; i<3; i++)
{
tag = i;
MPI_Recv( buf, 1, outtype, src, tag, comm, &status );
MPI_Get_elements( &status, outtype, &elms );
if (elms !=
buf[0] + 1) {
errs++;
printf( "For test %d, Get elements gave %d but should be %d\n", i, elms,
buf[0] + 1 );fflush(stdout);
}
MPI_Get_count( &status, outtype, &count );
if (count !=
MPI_UNDEFINED) {
errs++;
printf( "For partial send, Get_count did not return MPI_UNDEFINED\n" );fflush(stdout);
}
}
MPI_Type_free( &outtype );
}
MPI_Finalize();
return errs;
}
DOWNLOAD
Win32 DeinoMPI.2.0.1.msi
Win64 DeinoMPI.x64.2.0.1.msi