Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Add new entry in Release_Notes.
[simgrid.git] / teshsuite / smpi / mpich3-test / datatype / struct-pack.c
1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
2 /*
3  *  (C) 2001 by Argonne National Laboratory.
4  *      See COPYRIGHT in top-level directory.
5  */
6 #include <math.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include "mpi.h"
11
12 static int verbose = 0;
13
14 int main(int argc, char *argv[]);
15 int parse_args(int argc, char **argv);
16 int single_struct_test(void);
17 int array_of_structs_test(void);
18 int struct_of_structs_test(void);
19
20 struct test_struct_1 {
21     int a, b;
22     char c, d;
23     int e;
24 };
25
26 int main(int argc, char *argv[])
27 {
28     int err, errs = 0;
29
30     /* Initialize MPI */
31     MPI_Init(&argc, &argv);
32     parse_args(argc, argv);
33
34     /* To improve reporting of problems about operations, we
35      * change the error handler to errors return */
36     MPI_Comm_set_errhandler(MPI_COMM_WORLD, MPI_ERRORS_RETURN);
37
38     err = single_struct_test();
39     if (verbose && err)
40         fprintf(stderr, "error in single_struct_test\n");
41     errs += err;
42
43     err = array_of_structs_test();
44     if (verbose && err)
45         fprintf(stderr, "error in array_of_structs_test\n");
46     errs += err;
47
48     err = struct_of_structs_test();
49     if (verbose && err)
50         fprintf(stderr, "error in struct_of_structs_test\n");
51     errs += err;
52
53     /* print message and exit */
54     if (errs) {
55         fprintf(stderr, "Found %d errors\n", errs);
56     }
57     else {
58         printf(" No Errors\n");
59     }
60     MPI_Finalize();
61     return 0;
62 }
63
64 int single_struct_test(void)
65 {
66     int err, errs = 0;
67     int bufsize, position = 0;
68     struct test_struct_1 ts1, ts2;
69     MPI_Datatype mystruct;
70     char *buffer;
71
72     MPI_Aint disps[3] = { 0, 2 * sizeof(int), 3 * sizeof(int) };        /* guessing... */
73     int blks[3] = { 2, 2, 1 };
74     MPI_Datatype types[3] = { MPI_INT, MPI_CHAR, MPI_INT };
75
76     ts1.a = 1;
77     ts1.b = 2;
78     ts1.c = 3;
79     ts1.d = 4;
80     ts1.e = 5;
81
82     err = MPI_Type_struct(3, blks, disps, types, &mystruct);
83     if (err != MPI_SUCCESS) {
84         errs++;
85         if (verbose) {
86             fprintf(stderr, "MPI_Type_struct returned error\n");
87         }
88     }
89
90     MPI_Type_commit(&mystruct);
91
92     MPI_Pack_size(1, mystruct, MPI_COMM_WORLD, &bufsize);
93     buffer = (char *) malloc(bufsize);
94
95     err = MPI_Pack(&ts1, 1, mystruct, buffer, bufsize, &position, MPI_COMM_WORLD);
96     if (err != MPI_SUCCESS) {
97         errs++;
98         if (verbose) {
99             fprintf(stderr, "MPI_Pack returned error\n");
100         }
101     }
102
103     position = 0;
104     err = MPI_Unpack(buffer, bufsize, &position, &ts2, 1, mystruct, MPI_COMM_WORLD);
105     if (err != MPI_SUCCESS) {
106         errs++;
107         if (verbose) {
108             fprintf(stderr, "MPI_Unpack returned error\n");
109         }
110     }
111
112     MPI_Type_free(&mystruct);
113     free(buffer);
114
115     if (ts1.a != ts2.a) {
116         errs++;
117         if (verbose) {
118             fprintf(stderr, "ts2.a = %d; should be %d\n", ts2.a, ts1.a);
119         }
120     }
121     if (ts1.b != ts2.b) {
122         errs++;
123         if (verbose) {
124             fprintf(stderr, "ts2.b = %d; should be %d\n", ts2.b, ts1.b);
125         }
126     }
127     if (ts1.c != ts2.c) {
128         errs++;
129         if (verbose) {
130             fprintf(stderr, "ts2.c = %d; should be %d\n", (int) ts2.c, (int) ts1.c);
131         }
132     }
133     if (ts1.d != ts2.d) {
134         errs++;
135         if (verbose) {
136             fprintf(stderr, "ts2.d = %d; should be %d\n", (int) ts2.d, (int) ts1.d);
137         }
138     }
139     if (ts1.e != ts2.e) {
140         errs++;
141         if (verbose) {
142             fprintf(stderr, "ts2.e = %d; should be %d\n", ts2.e, ts1.e);
143         }
144     }
145
146     return errs;
147 }
148
149 int array_of_structs_test(void)
150 {
151     int i, err, errs = 0;
152     int bufsize, position = 0;
153     struct test_struct_1 ts1[10], ts2[10];
154     MPI_Datatype mystruct;
155     char *buffer;
156
157     MPI_Aint disps[3] = { 0, 2 * sizeof(int), 3 * sizeof(int) };        /* guessing... */
158     int blks[3] = { 2, 2, 1 };
159     MPI_Datatype types[3] = { MPI_INT, MPI_CHAR, MPI_INT };
160
161     for (i = 0; i < 10; i++) {
162         ts1[i].a = 10 * i + 1;
163         ts1[i].b = 10 * i + 2;
164         ts1[i].c = 10 * i + 3;
165         ts1[i].d = 10 * i + 4;
166         ts1[i].e = 10 * i + 5;
167
168         ts2[i].a = -13;
169         ts2[i].b = -13;
170         ts2[i].c = -13;
171         ts2[i].d = -13;
172         ts2[i].e = -13;
173     }
174
175     err = MPI_Type_struct(3, blks, disps, types, &mystruct);
176     if (err != MPI_SUCCESS) {
177         errs++;
178         if (verbose) {
179             fprintf(stderr, "MPI_Type_struct returned error\n");
180         }
181     }
182
183     MPI_Type_commit(&mystruct);
184
185     MPI_Pack_size(10, mystruct, MPI_COMM_WORLD, &bufsize);
186     buffer = (char *) malloc(bufsize);
187
188     err = MPI_Pack(ts1, 10, mystruct, buffer, bufsize, &position, MPI_COMM_WORLD);
189     if (err != MPI_SUCCESS) {
190         errs++;
191         if (verbose) {
192             fprintf(stderr, "MPI_Pack returned error\n");
193         }
194     }
195
196     position = 0;
197     err = MPI_Unpack(buffer, bufsize, &position, ts2, 10, mystruct, MPI_COMM_WORLD);
198     if (err != MPI_SUCCESS) {
199         errs++;
200         if (verbose) {
201             fprintf(stderr, "MPI_Unpack returned error\n");
202         }
203     }
204
205     MPI_Type_free(&mystruct);
206     free(buffer);
207
208     for (i = 0; i < 10; i++) {
209         if (ts1[i].a != ts2[i].a) {
210             errs++;
211             if (verbose) {
212                 fprintf(stderr, "ts2[%d].a = %d; should be %d\n", i, ts2[i].a, ts1[i].a);
213             }
214         }
215         if (ts1[i].b != ts2[i].b) {
216             errs++;
217             if (verbose) {
218                 fprintf(stderr, "ts2[%d].b = %d; should be %d\n", i, ts2[i].b, ts1[i].b);
219             }
220         }
221         if (ts1[i].c != ts2[i].c) {
222             errs++;
223             if (verbose) {
224                 fprintf(stderr, "ts2[%d].c = %d; should be %d\n",
225                         i, (int) ts2[i].c, (int) ts1[i].c);
226             }
227         }
228         if (ts1[i].d != ts2[i].d) {
229             errs++;
230             if (verbose) {
231                 fprintf(stderr, "ts2[%d].d = %d; should be %d\n",
232                         i, (int) ts2[i].d, (int) ts1[i].d);
233             }
234         }
235         if (ts1[i].e != ts2[i].e) {
236             errs++;
237             if (verbose) {
238                 fprintf(stderr, "ts2[%d].e = %d; should be %d\n", i, ts2[i].e, ts1[i].e);
239             }
240         }
241     }
242
243     return errs;
244 }
245
246 int struct_of_structs_test(void)
247 {
248     int i, j, err, errs = 0, bufsize, position;
249
250     char buf[50], buf2[50], *packbuf;
251
252     MPI_Aint disps[3] = { 0, 3, 0 };
253     int blks[3] = { 2, 1, 0 };
254     MPI_Datatype types[3], chartype, tiletype1, tiletype2, finaltype;
255
256     /* build a contig of one char to try to keep optimizations
257      * from being applied.
258      */
259     err = MPI_Type_contiguous(1, MPI_CHAR, &chartype);
260     if (err != MPI_SUCCESS) {
261         errs++;
262         if (verbose) {
263             fprintf(stderr, "chartype create failed\n");
264         }
265         return errs;
266     }
267
268     /* build a type that we can tile a few times */
269     types[0] = MPI_CHAR;
270     types[1] = chartype;
271
272     err = MPI_Type_struct(2, blks, disps, types, &tiletype1);
273     if (err != MPI_SUCCESS) {
274         errs++;
275         if (verbose) {
276             fprintf(stderr, "tiletype1 create failed\n");
277         }
278         return errs;
279     }
280
281     /* build the same type again, again to avoid optimizations */
282     err = MPI_Type_struct(2, blks, disps, types, &tiletype2);
283     if (err != MPI_SUCCESS) {
284         errs++;
285         if (verbose) {
286             fprintf(stderr, "tiletype2 create failed\n");
287         }
288         return errs;
289     }
290
291     /* build a combination of those two tiletypes */
292     disps[0] = 0;
293     disps[1] = 5;
294     disps[2] = 10;
295     blks[0] = 1;
296     blks[1] = 1;
297     blks[2] = 1;
298     types[0] = tiletype1;
299     types[1] = tiletype2;
300     types[2] = MPI_UB;
301     err = MPI_Type_struct(3, blks, disps, types, &finaltype);
302     if (err != MPI_SUCCESS) {
303         errs++;
304         if (verbose) {
305             fprintf(stderr, "finaltype create failed\n");
306         }
307         return errs;
308     }
309
310     MPI_Type_commit(&finaltype);
311     MPI_Type_free(&chartype);
312     MPI_Type_free(&tiletype1);
313     MPI_Type_free(&tiletype2);
314
315     MPI_Pack_size(5, finaltype, MPI_COMM_WORLD, &bufsize);
316
317     packbuf = malloc(bufsize);
318     if (packbuf == NULL) {
319         errs++;
320         if (verbose) {
321             fprintf(stderr, "pack buffer allocation (%d bytes) failed\n", bufsize);
322         }
323         return errs;
324     }
325
326     for (j = 0; j < 10; j++) {
327         for (i = 0; i < 5; i++) {
328             if (i == 2 || i == 4)
329                 buf[5 * j + i] = 0;
330             else
331                 buf[5 * j + i] = i;
332         }
333     }
334
335     position = 0;
336     err = MPI_Pack(buf, 5, finaltype, packbuf, bufsize, &position, MPI_COMM_WORLD);
337     if (err != MPI_SUCCESS) {
338         errs++;
339         if (verbose) {
340             fprintf(stderr, "pack failed\n");
341         }
342         return errs;
343     }
344
345     memset(buf2, 0, 50);
346     position = 0;
347     err = MPI_Unpack(packbuf, bufsize, &position, buf2, 5, finaltype, MPI_COMM_WORLD);
348     if (err != MPI_SUCCESS) {
349         errs++;
350         if (verbose) {
351             fprintf(stderr, "unpack failed\n");
352         }
353         return errs;
354     }
355
356     for (j = 0; j < 10; j++) {
357         for (i = 0; i < 5; i++) {
358             if (buf[5 * j + i] != buf2[5 * j + i]) {
359                 errs++;
360                 if (verbose) {
361                     fprintf(stderr,
362                             "buf2[%d] = %d; should be %d\n",
363                             5 * j + i, (int) buf2[5 * j + i], (int) buf[5 * j + i]);
364                 }
365             }
366         }
367     }
368
369     free(packbuf);
370     MPI_Type_free(&finaltype);
371     return errs;
372 }
373
374 int parse_args(int argc, char **argv)
375 {
376     /*
377      * int ret;
378      *
379      * while ((ret = getopt(argc, argv, "v")) >= 0)
380      * {
381      * switch (ret) {
382      * case 'v':
383      * verbose = 1;
384      * break;
385      * }
386      * }
387      */
388     if (argc > 1 && strcmp(argv[1], "-v") == 0)
389         verbose = 1;
390     return 0;
391 }