Logo AND Algorithmique Numérique Distribuée

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