Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
first commit to add the mpich-test suite to smpi tesh suite. Obviously all tests...
[simgrid.git] / teshsuite / smpi / mpich-test / pt2pt / typetest.c
1 /* 
2  * Patrick Bridges * bridges@mcs.anl.gov * patrick@CS.MsState.Edu 
3  *
4  * Modified by William Gropp
5  */
6
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include "test.h"
10 #include "mpi.h"
11 #include <string.h>
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
14    string.h) */
15 /* #include <memory.h> */
16
17 struct struct1 {
18     double d1;
19     char   c1[8];
20 };
21
22
23 struct struct2 {
24     double d1;
25     double d2;
26     char   c1[8];
27     char   c2[8];
28     double d3;
29     char   c3[8];
30     double d4;
31     char   c4[8];
32 };
33
34 struct struct3 {
35     double d1[2];
36     char  c1[2][8];
37     struct struct1 s1[2];
38 };
39
40 /* Structure with probable gap */
41 struct struct4 {
42     int a1;
43     char c1, c2;
44     int a2;
45 };   
46
47 int main( int argc, char **argv )
48 {
49     int rank, size, ret; 
50     MPI_Status Status;
51     MPI_Datatype struct1_t, struct2_t, struct3_t, struct4_t, struct4a_t,
52         astruct1_t, carray_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;
67
68     MPI_Init(&argc, &argv);
69     MPI_Comm_rank(MPI_COMM_WORLD, &rank);
70     MPI_Comm_size(MPI_COMM_WORLD, &size);
71
72     for (i=1; i<argc; i++) {
73         if (argv[i] && strcmp("-alt",argv[i]) == 0) {
74             master_rank = 1;
75             slave_rank  = 0;
76             printf( "[%d] setting master rank to 1\n", rank );
77             }
78         }
79
80     Test_Init("typetest", rank);
81
82     /* Create some types to try out */
83
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 );
90     }
91
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];
96     disp1[0] = 0;
97     type1[0] = MPI_DOUBLE;
98     type1[1] = carray_t;
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 );
104     }
105
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 );
112     }
113
114     
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];
124     }
125     disp2[0] = 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 );
133     }
134
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] );
139     for (i=1; i<3; i++) 
140       disp3[i] = disp3[i] - disp3[0];
141     disp3[0] = 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 );
148     }
149
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] );
155     for (i=1; i<4; i++) 
156         disp4[i] = disp4[i] - disp4[0];
157     disp4[0] = 0;
158     MPI_Type_struct(4, block4, disp4, type4, &struct4_t);
159     ret = MPI_Type_commit(&struct4_t);
160
161
162     MPI_Address( &dummy4.a1, &disp4a[0] );
163     MPI_Address( &dummy4.c1, &disp4a[1] );
164     MPI_Address( &dummy4.a2, &disp4a[2] );
165     for (i=1; i<3; i++) 
166         disp4a[i] = disp4a[i] - disp4a[0];
167     disp4a[0] = 0;
168     MPI_Type_struct(3, block4a, disp4a, type4a, &struct4a_t);
169     ret = MPI_Type_commit(&struct4a_t);
170
171     /* Wait for everyone to be ready */
172     MPI_Barrier(MPI_COMM_WORLD);
173     if (rank == master_rank) {  
174
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);
181         
182         /* Send the type */
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, 
188                  &Status);
189         
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 );
201 #endif
202         } else {
203             Test_Passed("Complex Type Round Trip Test");
204         }
205
206
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);
213         
214         /* Send the type */
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, 
220                  &Status);
221         
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");
228         else
229             Test_Passed("Compatible Complex Type Round Trip Test");
230
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;
234         dummy4.c1 = 'c';
235         dummy4.c2 = 'F';
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, 
240                   &Status );
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" );
245             }
246         else {
247             Test_Passed( "Padded Structure Type Round Trip Test" );
248             }
249
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");
258         else
259             Test_Passed("Type Free test");
260         
261         Test_Waitforall( );
262     } else {
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);
266
267         MPI_Recv(&dummy3, 1, struct3_t, master_rank, 2000, MPI_COMM_WORLD, 
268                  &Status);
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)) {
275
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 \
279 return message.");
280         }
281         MPI_Send(&dummy3, 1, struct3_t, master_rank, 2000, MPI_COMM_WORLD);
282
283         /* Use same structure type */
284         MPI_Recv( &dummy4, 1, struct4_t, master_rank, 2004, MPI_COMM_WORLD, 
285                   &Status );
286         MPI_Send( &dummy4, 1, struct4_t, master_rank, 2004, MPI_COMM_WORLD );
287
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");
296         else
297             Test_Passed("Type Free test");
298
299         Test_Waitforall( );
300     }
301
302     if (rank == master_rank) {  
303         (void)Summarize_Test_Results();
304         }
305
306     Test_Finalize();
307     MPI_Finalize();
308
309 return 0;
310 }