6
#if defined(NEEDS_STDLIB_PROTOTYPES)
12
This program is from mpich/tsuite/pt2pt and should be changed there only.
13
It needs gcomm and dtype from mpich/tsuite, and can be run with
14
any number of processes > 1.
16
This version sends and receives EVERYTHING from MPI_BOTTOM, by putting
17
the data into a structure.
19
This code isn't quite correct, since the MPI_Type_struct that is
20
created for the type may not have the correct extent.
21
One possible change is to make the struct type include the count, and
22
send/receive one instance of the data item.
24
The GenerateData call should return extents; when the extent of the
25
created structure doesn't match, we can at least issue an error message.
27
int main( int argc, char **argv )
30
void **inbufs, **outbufs;
32
int *counts, *bytesize, ntype;
34
int ncomm = 20, rank, np, partner, tag, count;
35
int i, j, k, err, toterr, world_rank, errloc;
38
MPI_Datatype offsettype;
40
MPI_Aint displ, extent, natural_extent;
42
MPI_Init( &argc, &argv );
44
AllocateForData( &types, &inbufs, &outbufs, &counts, &bytesize,
46
GenerateData( types, inbufs, outbufs, counts, bytesize, names, &ntype );
48
MPI_Comm_rank( MPI_COMM_WORLD, &world_rank );
49
MakeComms( comms, 20, &ncomm, 0 );
51
/* Test over a wide range of datatypes and communicators */
53
for (i=0; i<ncomm; i++) {
54
MPI_Comm_rank( comms[i], &rank );
55
MPI_Comm_size( comms[i], &np );
58
for (j=0; j<ntype; j++) {
59
if (world_rank == 0 && verbose)
60
fprintf( stdout, "Testing type %s\n", names[j] );
62
MPI_Address( inbufs[j], &displ );
64
MPI_Type_struct( 1, &blen, &displ, types + j, &offsettype );
65
MPI_Type_commit( &offsettype );
66
/* Warning: if the type has an explicit MPI_UB, then using a
67
simple shift of the offset won't work. For now, we skip
68
types whose extents are negative; the correct solution is
69
to add, where required, an explicit MPI_UB */
70
MPI_Type_extent( offsettype, &extent );
74
"... skipping (appears to have explicit MPI_UB\n" );
75
MPI_Type_free( &offsettype );
78
MPI_Type_extent( types[j], &natural_extent );
79
if (natural_extent != extent) {
80
MPI_Type_free( &offsettype );
85
MPIR_PrintDatatypePack( stdout, counts[j], offsettype,
88
MPI_Send( MPI_BOTTOM, counts[j], offsettype, partner, tag,
90
MPI_Type_free( &offsettype );
92
else if (rank == np-1) {
95
for (k=0; k<bytesize[j]; k++)
97
MPI_Address( outbufs[j], &displ );
99
MPI_Type_struct( 1, &blen, &displ, types + j, &offsettype );
100
MPI_Type_commit( &offsettype );
101
/* Warning: if the type has an explicit MPI_UB, then using a
102
simple shift of the offset won't work. For now, we skip
103
types whose extents are negative; the correct solution is
104
to add, where required, an explicit MPI_UB */
105
MPI_Type_extent( offsettype, &extent );
107
MPI_Type_free( &offsettype );
110
MPI_Type_extent( types[j], &natural_extent );
111
if (natural_extent != extent) {
112
MPI_Type_free( &offsettype );
115
MPI_Recv( MPI_BOTTOM, counts[j], offsettype,
116
partner, tag, comms[i], &status );
118
MPI_Get_count( &status, types[j], &count );
119
if (count != counts[j]) {
121
"Error in counts (got %d expected %d) with type %s\n",
122
count, counts[j], names[j] );
125
if (status.MPI_SOURCE != partner) {
127
"Error in source (got %d expected %d) with type %s\n",
128
status.MPI_SOURCE, partner, names[j] );
131
if ((errloc = CheckData( inbufs[j], outbufs[j], bytesize[j] ))) {
133
"Error in data with type %s (type %d on %d) at byte %d\n",
134
names[j], j, world_rank, errloc - 1 );
136
/* Give details on only the first 10 errors */
137
unsigned char *in_p = (unsigned char *)inbufs[j],
138
*out_p = (unsigned char *)outbufs[j];
141
jj &= 0xfffffffc; /* lop off a few bits */
144
fprintf( stderr, "%02x%02x%02x%02x should be %02x%02x%02x%02x\n",
145
out_p[0], out_p[1], out_p[2], out_p[3],
146
in_p[0], in_p[1], in_p[2], in_p[3] );
150
MPIR_PrintDatatypeUnpack( stdout, counts[j], offsettype,
154
MPI_Type_free( &offsettype );
159
fprintf( stderr, "%d errors on %d\n", err, rank );
161
MPI_Allreduce( &err, &toterr, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD );
162
if (world_rank == 0) {
164
printf( " No Errors\n" );
167
printf (" Found %d errors\n", toterr );
171
FreeDatatypes( types, inbufs, outbufs, counts, bytesize, names, ntype );
172
FreeComms( comms, ncomm );