Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
play with mpich3 cmake files
[simgrid.git] / teshsuite / smpi / mpich3-test / datatype / blockindexed-misc.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 "mpi.h"
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include "mpitestconf.h"
10 #ifdef HAVE_STRING_H
11 #include <string.h>
12 #endif
13
14 static int verbose = 0;
15
16 /* tests */
17 int blockindexed_contig_test(void);
18 int blockindexed_vector_test(void);
19
20 /* helper functions */
21 int parse_args(int argc, char **argv);
22 static int pack_and_unpack(char *typebuf,
23                            int count,
24                            MPI_Datatype datatype,
25                            int typebufsz);
26
27 int main(int argc, char **argv)
28 {
29     int err, errs = 0;
30
31     MPI_Init(&argc, &argv); /* MPI-1.2 doesn't allow for MPI_Init(0,0) */
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     /* perform some tests */
39     err = blockindexed_contig_test();
40     if (err && verbose) fprintf(stderr, "%d errors in blockindexed test.\n",
41                                 err);
42     errs += err;
43
44     err = blockindexed_vector_test();
45     if (err && verbose) fprintf(stderr, "%d errors in blockindexed vector test.\n",
46                                 err);
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 /* blockindexed_contig_test()
61  *
62  * Tests behavior with a blockindexed that can be converted to a 
63  * contig easily.  This is specifically for coverage.
64  *
65  * Returns the number of errors encountered.
66  */
67 int blockindexed_contig_test(void)
68 {
69     int buf[4] = {7, -1, -2, -3};
70     int err, errs = 0;
71
72     int i, count = 1;
73     int disp = 0;
74     MPI_Datatype newtype;
75
76     int size, int_size;
77     MPI_Aint extent;
78
79     err = MPI_Type_create_indexed_block(count,
80                                         1,
81                                         &disp,
82                                         MPI_INT,
83                                         &newtype);
84     if (err != MPI_SUCCESS) {
85         if (verbose) {
86             fprintf(stderr,
87                     "error creating struct type in blockindexed_contig_test()\n");
88         }
89         errs++;
90     }
91
92     MPI_Type_size(MPI_INT, &int_size);
93
94     err = MPI_Type_size(newtype, &size);
95     if (err != MPI_SUCCESS) {
96         if (verbose) {
97             fprintf(stderr,
98                     "error obtaining type size in blockindexed_contig_test()\n");
99         }
100         errs++;
101     }
102     
103     if (size != int_size) {
104         if (verbose) {
105             fprintf(stderr,
106                     "error: size != int_size in blockindexed_contig_test()\n");
107         }
108         errs++;
109     }    
110
111     err = MPI_Type_extent(newtype, &extent);
112     if (err != MPI_SUCCESS) {
113         if (verbose) {
114             fprintf(stderr,
115                     "error obtaining type extent in blockindexed_contig_test()\n");
116         }
117         errs++;
118     }
119     
120     if (extent != int_size) {
121         if (verbose) {
122             fprintf(stderr,
123                     "error: extent != int_size in blockindexed_contig_test()\n");
124         }
125         errs++;
126     }    
127
128     MPI_Type_commit(&newtype);
129
130     err = pack_and_unpack((char *) buf, 1, newtype, 4 * sizeof(int));
131     if (err != 0) {
132         if (verbose) {
133             fprintf(stderr,
134                     "error packing/unpacking in blockindexed_contig_test()\n");
135         }
136         errs += err;
137     }
138
139     for (i=0; i < 4; i++) {
140         int goodval;
141
142         switch(i) {
143             case 0:
144                 goodval = 7;
145                 break;
146             default:
147                 goodval = 0; /* pack_and_unpack() zeros before unpack */
148                 break;
149         }
150         if (buf[i] != goodval) {
151             errs++;
152             if (verbose) fprintf(stderr, "buf[%d] = %d; should be %d\n",
153                                  i, buf[i], goodval);
154         }
155     }
156     
157     MPI_Type_free( &newtype );
158
159     return errs;
160 }
161
162 /* blockindexed_vector_test()
163  *
164  * Tests behavior with a blockindexed of some vector types;
165  * this shouldn't be easily convertable into anything else.
166  *
167  * Returns the number of errors encountered.
168  */
169 int blockindexed_vector_test(void)
170 {
171 #define NELT (18)
172     int buf[NELT] = { -1, -1, -1,
173                        1, -2,  2,
174                       -3, -3, -3,
175                       -4, -4, -4,
176                        3, -5,  4,
177                        5, -6,  6 };
178     int expected[NELT] = {
179                        0,  0,  0,
180                        1,  0,  2,
181                        0,  0,  0,
182                        0,  0,  0,
183                        3,  0,  4,
184                        5,  0,  6 };
185     int err, errs = 0;
186
187     int i, count = 3;
188     int disp[] = {1, 4, 5};
189     MPI_Datatype vectype, newtype;
190
191     int size, int_size;
192
193     /* create a vector type of 2 ints, skipping one in between */
194     err = MPI_Type_vector(2, 1, 2, MPI_INT, &vectype);
195     if (err != MPI_SUCCESS) {
196         if (verbose) {
197             fprintf(stderr,
198                     "error creating vector type in blockindexed_contig_test()\n");
199         }
200         errs++;
201     }
202
203     err = MPI_Type_create_indexed_block(count,
204                                         1,
205                                         disp,
206                                         vectype,
207                                         &newtype);
208     if (err != MPI_SUCCESS) {
209         if (verbose) {
210             fprintf(stderr,
211                     "error creating blockindexed type in blockindexed_contig_test()\n");
212         }
213         errs++;
214     }
215
216     MPI_Type_size(MPI_INT, &int_size);
217
218     err = MPI_Type_size(newtype, &size);
219     if (err != MPI_SUCCESS) {
220         if (verbose) {
221             fprintf(stderr,
222                     "error obtaining type size in blockindexed_contig_test()\n");
223         }
224         errs++;
225     }
226     
227     if (size != 6 * int_size) {
228         if (verbose) {
229             fprintf(stderr,
230                     "error: size != 6 * int_size in blockindexed_contig_test()\n");
231         }
232         errs++;
233     }    
234
235     MPI_Type_commit(&newtype);
236
237     err = pack_and_unpack((char *) buf, 1, newtype, NELT * sizeof(int));
238     if (err != 0) {
239         if (verbose) {
240             fprintf(stderr,
241                     "error packing/unpacking in blockindexed_vector_test()\n");
242         }
243         errs += err;
244     }
245
246     for (i=0; i < NELT; i++) {
247         if (buf[i] != expected[i]) {
248             errs++;
249             if (verbose) fprintf(stderr, "buf[%d] = %d; should be %d\n",
250                                  i, buf[i], expected[i]);
251         }
252     }
253
254     MPI_Type_free( &vectype );
255     MPI_Type_free( &newtype );
256     return errs;
257 }
258
259
260 /* pack_and_unpack()
261  *
262  * Perform packing and unpacking of a buffer for the purposes of checking
263  * to see if we are processing a type correctly.  Zeros the buffer between
264  * these two operations, so the data described by the type should be in
265  * place upon return but all other regions of the buffer should be zero.
266  *
267  * Parameters:
268  * typebuf - pointer to buffer described by datatype and count that
269  *           will be packed and then unpacked into
270  * count, datatype - description of typebuf
271  * typebufsz - size of typebuf; used specifically to zero the buffer
272  *             between the pack and unpack steps
273  *
274  */
275 static int pack_and_unpack(char *typebuf,
276                            int count,
277                            MPI_Datatype datatype,
278                            int typebufsz)
279 {
280     char *packbuf;
281     int err, errs = 0, pack_size, type_size, position;
282
283     err = MPI_Type_size(datatype, &type_size);
284     if (err != MPI_SUCCESS) {
285         errs++;
286         if (verbose) {
287             fprintf(stderr,
288                     "error in MPI_Type_size call; aborting after %d errors\n",
289                     errs);
290         }
291         return errs;
292     }
293
294     type_size *= count;
295
296     err = MPI_Pack_size(count, datatype, MPI_COMM_SELF, &pack_size);
297     if (err != MPI_SUCCESS) {
298         errs++;
299         if (verbose) {
300             fprintf(stderr,
301                     "error in MPI_Pack_size call; aborting after %d errors\n",
302                     errs);
303         }
304         return errs;
305     }
306     packbuf = (char *) malloc(pack_size);
307     if (packbuf == NULL) {
308         errs++;
309         if (verbose) {
310             fprintf(stderr,
311                     "error in malloc call; aborting after %d errors\n",
312                     errs);
313         }
314         return errs;
315     }
316
317     position = 0;
318     err = MPI_Pack(typebuf,
319                    count,
320                    datatype,
321                    packbuf,
322                    type_size,
323                    &position,
324                    MPI_COMM_SELF);
325
326     if (position != type_size) {
327         errs++;
328         if (verbose) fprintf(stderr, "position = %d; should be %d (pack)\n",
329                              position, type_size);
330     }
331
332     memset(typebuf, 0, typebufsz);
333     position = 0;
334     err = MPI_Unpack(packbuf,
335                      type_size,
336                      &position,
337                      typebuf,
338                      count,
339                      datatype,
340                      MPI_COMM_SELF);
341     if (err != MPI_SUCCESS) {
342         errs++;
343         if (verbose) {
344             fprintf(stderr,
345                     "error in MPI_Unpack call; aborting after %d errors\n",
346                     errs);
347         }
348         return errs;
349     }
350     free(packbuf);
351
352     if (position != type_size) {
353         errs++;
354         if (verbose) fprintf(stderr, "position = %d; should be %d (unpack)\n",
355                              position, type_size);
356     }
357
358     return errs;
359 }
360
361 int parse_args(int argc, char **argv)
362 {
363     /*
364     int ret;
365
366     while ((ret = getopt(argc, argv, "v")) >= 0)
367     {
368         switch (ret) {
369             case 'v':
370                 verbose = 1;
371                 break;
372         }
373     }
374     */
375     if (argc > 1 && strcmp(argv[1], "-v") == 0)
376         verbose = 1;
377     return 0;
378 }
379