2 * Patrick Bridges * bridges@mcs.anl.gov * patrick@CS.MsState.Edu
4 * Modified by William Gropp
12 /* CM5 users need to comment out the next include (memory.h) because
13 of an error in the CM5 include file (memory.h is inconsistent with
15 /* #include <memory.h> */
40 /* Structure with probable gap */
47 int main( int argc, char **argv )
51 MPI_Datatype struct1_t, struct2_t, struct3_t, struct4_t, struct4a_t,
53 static int block1[2] = {1, 1};
54 static int block2[6] = {2, 2, 1, 1, 1, 1};
55 static int block3[3] = {2, 2, 1};
56 static int block4[4] = {1, 1, 1, 1};
57 static int block4a[3] = {1, 2, 1};
58 MPI_Aint disp1[2], disp2[6], disp3[6], disp4[4], disp4a[3];
59 MPI_Datatype type1[2], type2[6], type3[3];
60 MPI_Datatype type4[4] = {MPI_INT, MPI_CHAR, MPI_CHAR, MPI_INT};
61 MPI_Datatype type4a[3] = {MPI_INT, MPI_CHAR, MPI_INT};
62 struct struct1 dummy1;
63 struct struct2 dummy2;
64 struct struct3 dummy3;
65 struct struct4 dummy4;
66 int i, master_rank = 0, slave_rank = 1;
68 MPI_Init(&argc, &argv);
69 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
70 MPI_Comm_size(MPI_COMM_WORLD, &size);
72 for (i=1; i<argc; i++) {
73 if (argv[i] && strcmp("-alt",argv[i]) == 0) {
76 printf( "[%d] setting master rank to 1\n", rank );
80 Test_Init("typetest", rank);
82 /* Create some types to try out */
84 /* A simple array of characters */
85 MPI_Type_contiguous(8, MPI_CHAR, &carray_t);
86 ret = MPI_Type_commit(&carray_t);
87 if (ret != MPI_SUCCESS) {
88 fprintf(stderr, "Could not make char array type."), fflush(stderr);
89 MPI_Abort( MPI_COMM_WORLD, 1 );
92 /* A fairly simple structure */
93 MPI_Address( &dummy1, &disp1[0] );
94 MPI_Address( &dummy1.c1[0], &disp1[1] );
95 disp1[1] = disp1[1] - disp1[0];
97 type1[0] = MPI_DOUBLE;
99 MPI_Type_struct(2, block1, disp1, type1, &struct1_t);
100 ret = MPI_Type_commit(&struct1_t);
101 if (ret != MPI_SUCCESS) {
102 fprintf(stderr, "Could not make struct 1."); fflush(stderr);
103 MPI_Abort( MPI_COMM_WORLD, 1 );
106 /* And a short array of this type */
107 MPI_Type_contiguous(2, struct1_t, &astruct1_t);
108 ret = MPI_Type_commit(&astruct1_t);
109 if (ret != MPI_SUCCESS) {
110 fprintf(stderr, "Could not make struct 1 array."); fflush(stderr);
111 MPI_Abort( MPI_COMM_WORLD, 1 );
115 /* A more complex structure */
116 MPI_Address( &dummy2, &disp2[0] );
117 MPI_Address( &dummy2.c1[0], &disp2[1] );
118 MPI_Address( &dummy2.d3, &disp2[2] );
119 MPI_Address( &dummy2.c3[0], &disp2[3] );
120 MPI_Address( &dummy2.d4, &disp2[4] );
121 MPI_Address( &dummy2.c4[0], &disp2[5] );
122 for (i=1; i<6; i++) {
123 disp2[i] = disp2[i] - disp2[0];
126 type2[0] = MPI_DOUBLE; type2[1] = carray_t; type2[2] = MPI_DOUBLE;
127 type2[3] = carray_t; type2[4] = MPI_DOUBLE; type2[5] = carray_t;
128 MPI_Type_struct(6, block2, disp2, type2, &struct2_t);
129 ret = MPI_Type_commit(&struct2_t);
130 if (ret != MPI_SUCCESS) {
131 fprintf(stderr, "Could not make struct 2."), fflush(stderr);
132 MPI_Abort( MPI_COMM_WORLD, 1 );
135 /* Another (hopefully compatible) complex structure */
136 MPI_Address( &dummy3, &disp3[0] );
137 MPI_Address( &dummy3.c1[0][0], &disp3[1] );
138 MPI_Address( &dummy3.s1[0], &disp3[2] );
140 disp3[i] = disp3[i] - disp3[0];
142 type3[0] = MPI_DOUBLE; type3[1] = carray_t; type3[2] = astruct1_t;
143 MPI_Type_struct(3, block3, disp3, type3, &struct3_t);
144 ret = MPI_Type_commit(&struct3_t);
145 if (ret != MPI_SUCCESS) {
146 fprintf(stderr, "Could not make struct 3."), fflush(stderr);
147 MPI_Abort( MPI_COMM_WORLD, 1 );
150 /* A structure with gaps (invokes padding) */
151 MPI_Address( &dummy4.a1, &disp4[0] );
152 MPI_Address( &dummy4.c1, &disp4[1] );
153 MPI_Address( &dummy4.c2, &disp4[2] );
154 MPI_Address( &dummy4.a2, &disp4[3] );
156 disp4[i] = disp4[i] - disp4[0];
158 MPI_Type_struct(4, block4, disp4, type4, &struct4_t);
159 ret = MPI_Type_commit(&struct4_t);
162 MPI_Address( &dummy4.a1, &disp4a[0] );
163 MPI_Address( &dummy4.c1, &disp4a[1] );
164 MPI_Address( &dummy4.a2, &disp4a[2] );
166 disp4a[i] = disp4a[i] - disp4a[0];
168 MPI_Type_struct(3, block4a, disp4a, type4a, &struct4a_t);
169 ret = MPI_Type_commit(&struct4a_t);
171 /* Wait for everyone to be ready */
172 MPI_Barrier(MPI_COMM_WORLD);
173 if (rank == master_rank) {
175 /* Fill up the type */
176 dummy2.d1 = 11.0; dummy2.d2 = 12.0; dummy2.d3 = 13.0; dummy2.d4 = 14.0;
177 strncpy(dummy2.c1, "two", 8);
178 strncpy(dummy2.c2, "four", 8);
179 strncpy(dummy2.c3, "six", 8);
180 strncpy(dummy2.c4, "eight", 8);
183 MPI_Send(&dummy2, 1, struct2_t, slave_rank, 2000, MPI_COMM_WORLD);
184 /* Clear out the type */
185 memset(&dummy2, 0, sizeof(dummy2));
186 /* And receive it back */
187 MPI_Recv(&dummy2, 1, struct2_t, slave_rank, 2000, MPI_COMM_WORLD,
190 /* Did it make it OK? */
191 if ((dummy2.d1 != 11.0) || (dummy2.d2 != 12.0) ||
192 (dummy2.d3 != 13.0) || (dummy2.d4 != 14.0) ||
193 strncmp(dummy2.c1, "two", 8) || strncmp(dummy2.c2, "four", 8) ||
194 strncmp(dummy2.c3, "six", 8) || strncmp(dummy2.c4, "eight", 8)) {
195 Test_Failed("Complex Type Round Trip Test");
196 #ifdef MPE_USE_EXTENSIONS
197 printf( "Pack action is\n" );
198 MPIR_PrintDatatypePack( stdout, 1, struct2_t, (long)&dummy2, 0 );
199 printf( "Unpack action is\n" );
200 MPIR_PrintDatatypeUnpack( stdout, 1, struct2_t, 0, (long)&dummy2 );
203 Test_Passed("Complex Type Round Trip Test");
207 /* Fill up the type again */
208 dummy2.d1 = 11.0; dummy2.d2 = 12.0; dummy2.d3 = 13.0; dummy2.d4 = 14.0;
209 strncpy(dummy2.c1, "two", 8);
210 strncpy(dummy2.c2, "four", 8);
211 strncpy(dummy2.c3, "six", 8);
212 strncpy(dummy2.c4, "eight", 8);
215 MPI_Send(&dummy2, 1, struct2_t, slave_rank, 2000, MPI_COMM_WORLD);
216 /* Clear out the type */
217 memset(&dummy2, 0, sizeof(dummy2));
218 /* And receive it back */
219 MPI_Recv(&dummy2, 1, struct2_t, slave_rank, 2000, MPI_COMM_WORLD,
222 /* Did it make it OK? */
223 if ((dummy2.d1 != 11.0) || (dummy2.d2 != 12.0) ||
224 (dummy2.d3 != 13.0) || (dummy2.d4 != 14.0) ||
225 strncmp(dummy2.c1, "two", 8) || strncmp(dummy2.c2, "four", 8) ||
226 strncmp(dummy2.c3, "six", 8) || strncmp(dummy2.c4, "eight", 8))
227 Test_Failed("Compatible Complex Type Round Trip Test");
229 Test_Passed("Compatible Complex Type Round Trip Test");
231 /* Expect ints to be at least 4 bytes. Make sure that the MSbit is
232 0 so that there are no sign-extension suprises. */
233 dummy4.a1 = 0x17faec2b;
236 dummy4.a2 = 0x91fb8354;
237 MPI_Send( &dummy4, 1, struct4_t, slave_rank, 2004, MPI_COMM_WORLD );
238 memset( &dummy4, 0, sizeof(dummy4) );
239 MPI_Recv( &dummy4, 1, struct4a_t, slave_rank, 2004, MPI_COMM_WORLD,
241 /* Check for correct data */
242 if (dummy4.a1 != 0x17faec2b || dummy4.c1 != 'c' ||
243 dummy4.c2 != 'F' || dummy4.a2 != 0x91fb8354) {
244 Test_Failed( "Padded Structure Type Round Trip Test" );
247 Test_Passed( "Padded Structure Type Round Trip Test" );
250 if ((MPI_Type_free(&struct3_t) != MPI_SUCCESS) ||
251 (MPI_Type_free(&struct1_t) != MPI_SUCCESS) ||
252 (MPI_Type_free(&struct2_t) != MPI_SUCCESS) ||
253 (MPI_Type_free(&struct4_t) != MPI_SUCCESS) ||
254 (MPI_Type_free(&struct4a_t) != MPI_SUCCESS) ||
255 (MPI_Type_free(&astruct1_t) != MPI_SUCCESS) ||
256 (MPI_Type_free(&carray_t) != MPI_SUCCESS))
257 Test_Failed("Type Free test");
259 Test_Passed("Type Free test");
263 MPI_Recv(&dummy2, 1, struct2_t, master_rank, 2000,
264 MPI_COMM_WORLD, &Status);
265 MPI_Send(&dummy2, 1, struct2_t, master_rank, 2000, MPI_COMM_WORLD);
267 MPI_Recv(&dummy3, 1, struct3_t, master_rank, 2000, MPI_COMM_WORLD,
269 if ((dummy3.d1[0] != 11.0) || (dummy3.d1[1] != 12.0) ||
270 (dummy3.s1[0].d1 != 13.0) || (dummy3.s1[1].d1 != 14.0) ||
271 strncmp(dummy3.c1[0], "two", 8) ||
272 strncmp(dummy3.c1[1], "four", 8) ||
273 strncmp(dummy3.s1[0].c1, "six", 8) ||
274 strncmp(dummy3.s1[1].c1, "eight", 8)) {
276 /* Kill dummy3 so it will die after it's sent back */
277 memset(&dummy3, 0, sizeof(dummy3));
278 Test_Message("Message didn't convert properly. Hosing \
281 MPI_Send(&dummy3, 1, struct3_t, master_rank, 2000, MPI_COMM_WORLD);
283 /* Use same structure type */
284 MPI_Recv( &dummy4, 1, struct4_t, master_rank, 2004, MPI_COMM_WORLD,
286 MPI_Send( &dummy4, 1, struct4_t, master_rank, 2004, MPI_COMM_WORLD );
288 if ((MPI_Type_free(&struct3_t) != MPI_SUCCESS) ||
289 (MPI_Type_free(&struct1_t) != MPI_SUCCESS) ||
290 (MPI_Type_free(&struct2_t) != MPI_SUCCESS) ||
291 (MPI_Type_free(&struct4_t) != MPI_SUCCESS) ||
292 (MPI_Type_free(&struct4a_t) != MPI_SUCCESS) ||
293 (MPI_Type_free(&astruct1_t) != MPI_SUCCESS) ||
294 (MPI_Type_free(&carray_t) != MPI_SUCCESS))
295 Test_Failed("Type Free test");
297 Test_Passed("Type Free test");
302 if (rank == master_rank) {
303 (void)Summarize_Test_Results();