Lets take an example. Assume I have a structure "S" at address
1000 and "S" has integer fields i1,i2,i3,i4. I want a datatype to
use on S.i2 and S.i4. Here are two ways I could construct the type.
(My numbers below presume MPI_BOTTOM==0 and addr() is the functional
equivelent of MPI_Address. This examples still work even if
MPI_BOTTOM!=0 and MPI_Address factors that in, the offsets just shift.)
1) MPI_Type_struct: D=(addr(S.i2)-addr(S),addr(S.i4)-addr(S))
The resulting datatype would have offsets 4 and 12, trueLB of
4, trueUB of 16 and true_extent of 16-4. A send would be coded
MPI_Send(&S,1,mytype,....). The origin_offset (virtual origin
in my first note was not a good name) would be -4. To create
a temp buffer and receive the type I would do:
tempbuf = (char*) malloc(true_extent)
2) MPI_Type_struct: D=(addr(S.i2),addr(S.i4))
The resulting datatype would have offsets 1004 and 1012, trueLB of
1004, trueUB of 1016 and true extent of 1016-1004. (i.e. 12 as
above). A send would be coded MPI_Send(MPI_BOTTOM,1,mytype,....).
This time, the origin_offset would be -1004. The code to make a
temp buffer and receive into it would be the same as above.
In both cases, the buffer is 12 bytes. In case one, the virtual buffer
address given for MPI_Recv is tempbuf-4 and the first byte of the
data lands at virtual_buffer_addr+4 (i.e. at tempbuf). In case two,
the virtual buffer address is tempbuf-1004 and the data lands at
virtual_buffer_addr+1004. Again, right in tempbuf.