Logo AND Algorithmique Numérique Distribuée

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