Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Include directory is in source_dir, not in binary_dir.
[simgrid.git] / teshsuite / smpi / mpich3-test / datatype / hindexed_block.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 #if !defined(USE_STRICT_MPI) && defined(MPICH)
15 #define TEST_HINDEXED_BLOCK 1
16 #endif
17
18 static int verbose = 0;
19
20 /* tests */
21 int hindexed_block_contig_test(void);
22 int hindexed_block_vector_test(void);
23
24 /* helper functions */
25 int parse_args(int argc, char **argv);
26 static int pack_and_unpack(char *typebuf, int count, MPI_Datatype datatype, int typebufsz);
27
28 int main(int argc, char **argv)
29 {
30     int err, errs = 0;
31     int rank;
32
33     MPI_Init(&argc, &argv);     /* MPI-1.2 doesn't allow for MPI_Init(0,0) */
34     MPI_Comm_rank(MPI_COMM_WORLD, &rank);
35 #if defined(TEST_HINDEXED_BLOCK)
36     parse_args(argc, argv);
37
38     /* To improve reporting of problems about operations, we
39      * change the error handler to errors return */
40     MPI_Comm_set_errhandler(MPI_COMM_WORLD, MPI_ERRORS_RETURN);
41
42     /* perform some tests */
43     err = hindexed_block_contig_test();
44     if (err && verbose)
45         fprintf(stderr, "%d errors in hindexed_block test.\n", err);
46     errs += err;
47
48     err = hindexed_block_vector_test();
49     if (err && verbose)
50         fprintf(stderr, "%d errors in hindexed_block vector test.\n", err);
51     errs += err;
52 #endif /*defined(TEST_HINDEXED_BLOCK)*/
53
54     /* print message and exit */
55     if (rank == 0) {
56         if (errs) {
57             fprintf(stderr, "Found %d errors\n", errs);
58         }
59         else {
60             printf(" No Errors\n");
61         }
62     }
63     MPI_Finalize();
64     return 0;
65 }
66
67 #if defined(TEST_HINDEXED_BLOCK)
68
69 /* hindexed_block_contig_test()
70  *
71  * Tests behavior with a hindexed_block that can be converted to a
72  * contig easily.  This is specifically for coverage.
73  *
74  * Returns the number of errors encountered.
75  */
76 int hindexed_block_contig_test(void)
77 {
78     int buf[4] = { 7, -1, -2, -3 };
79     int err, errs = 0;
80
81     int i, count = 1;
82     MPI_Aint disp = 0;
83     MPI_Datatype newtype;
84
85     int size, int_size;
86     MPI_Aint extent;
87
88     err = MPI_Type_create_hindexed_block(count, 1, &disp, MPI_INT, &newtype);
89     if (err != MPI_SUCCESS) {
90         if (verbose) {
91             fprintf(stderr, "error creating struct type in hindexed_block_contig_test()\n");
92         }
93         errs++;
94     }
95
96     MPI_Type_size(MPI_INT, &int_size);
97
98     err = MPI_Type_size(newtype, &size);
99     if (err != MPI_SUCCESS) {
100         if (verbose) {
101             fprintf(stderr, "error obtaining type size in hindexed_block_contig_test()\n");
102         }
103         errs++;
104     }
105
106     if (size != int_size) {
107         if (verbose) {
108             fprintf(stderr, "error: size != int_size in hindexed_block_contig_test()\n");
109         }
110         errs++;
111     }
112
113     err = MPI_Type_extent(newtype, &extent);
114     if (err != MPI_SUCCESS) {
115         if (verbose) {
116             fprintf(stderr, "error obtaining type extent in hindexed_block_contig_test()\n");
117         }
118         errs++;
119     }
120
121     if (extent != int_size) {
122         if (verbose) {
123             fprintf(stderr, "error: extent != int_size in hindexed_block_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, "error packing/unpacking in hindexed_block_contig_test()\n");
134         }
135         errs += err;
136     }
137
138     for (i = 0; i < 4; i++) {
139         int goodval;
140
141         switch (i) {
142         case 0:
143             goodval = 7;
144             break;
145         default:
146             goodval = 0;        /* pack_and_unpack() zeros before unpack */
147             break;
148         }
149         if (buf[i] != goodval) {
150             errs++;
151             if (verbose)
152                 fprintf(stderr, "buf[%d] = %d; should be %d\n", i, buf[i], goodval);
153         }
154     }
155
156     MPI_Type_free(&newtype);
157
158     return errs;
159 }
160
161 /* hindexed_block_vector_test()
162  *
163  * Tests behavior with a hindexed_block of some vector types;
164  * this shouldn't be easily convertable into anything else.
165  *
166  * Returns the number of errors encountered.
167  */
168 int hindexed_block_vector_test(void)
169 {
170 #define NELT (18)
171     int buf[NELT] = {
172         -1, -1, -1,
173          1, -2,  2,
174         -3, -3, -3,
175         -4, -4, -4,
176          3, -5,  4,
177          5, -6,  6
178     };
179     int expected[NELT] = {
180          0,  0,  0,
181          1,  0,  2,
182          0,  0,  0,
183          0,  0,  0,
184          3,  0,  4,
185          5,  0,  6
186     };
187     int err, errs = 0;
188
189     int i, count = 3;
190     MPI_Aint disp[] = { 1, 4, 5 };
191     MPI_Datatype vectype, newtype;
192
193     int size, int_size;
194     MPI_Aint extent;
195
196     /* create a vector type of 2 ints, skipping one in between */
197     err = MPI_Type_vector(2, 1, 2, MPI_INT, &vectype);
198     if (err != MPI_SUCCESS) {
199         if (verbose) {
200             fprintf(stderr, "error creating vector type in hindexed_block_contig_test()\n");
201         }
202         errs++;
203     }
204
205     MPI_Type_commit(&vectype);
206
207     MPI_Type_extent(vectype, &extent);
208     for (i = 0; i < count; i++)
209         disp[i] *= extent;
210
211     err = MPI_Type_create_hindexed_block(count, 1, disp, vectype, &newtype);
212     if (err != MPI_SUCCESS) {
213         if (verbose) {
214             fprintf(stderr,
215                     "error creating hindexed_block type in hindexed_block_contig_test()\n");
216         }
217         errs++;
218     }
219
220     MPI_Type_commit(&newtype);
221
222     err = MPI_Type_size(newtype, &size);
223     if (err != MPI_SUCCESS) {
224         if (verbose) {
225             fprintf(stderr, "error obtaining type size in hindexed_block_contig_test()\n");
226         }
227         errs++;
228     }
229
230     MPI_Type_size(MPI_INT, &int_size);
231
232     if (size != 6 * int_size) {
233         if (verbose) {
234             fprintf(stderr, "error: size != 6 * int_size in hindexed_block_contig_test()\n");
235         }
236         errs++;
237     }
238
239     MPI_Type_extent(newtype, &extent);
240
241     err = pack_and_unpack((char *) buf, 1, newtype, NELT * sizeof(int));
242     if (err != 0) {
243         if (verbose) {
244             fprintf(stderr, "error packing/unpacking in hindexed_block_vector_test()\n");
245         }
246         errs += err;
247     }
248
249     for (i = 0; i < NELT; i++) {
250         if (buf[i] != expected[i]) {
251             errs++;
252             if (verbose)
253                 fprintf(stderr, "buf[%d] = %d; should be %d\n", i, buf[i], expected[i]);
254         }
255     }
256
257     MPI_Type_free(&vectype);
258     MPI_Type_free(&newtype);
259     return errs;
260 }
261
262
263 /* pack_and_unpack()
264  *
265  * Perform packing and unpacking of a buffer for the purposes of checking
266  * to see if we are processing a type correctly.  Zeros the buffer between
267  * these two operations, so the data described by the type should be in
268  * place upon return but all other regions of the buffer should be zero.
269  *
270  * Parameters:
271  * typebuf - pointer to buffer described by datatype and count that
272  *           will be packed and then unpacked into
273  * count, datatype - description of typebuf
274  * typebufsz - size of typebuf; used specifically to zero the buffer
275  *             between the pack and unpack steps
276  *
277  */
278 static int pack_and_unpack(char *typebuf, int count, MPI_Datatype datatype, 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, "error in MPI_Type_size call; aborting after %d errors\n", errs);
288         }
289         return errs;
290     }
291
292     type_size *= count;
293
294     err = MPI_Pack_size(count, datatype, MPI_COMM_SELF, &pack_size);
295     if (err != MPI_SUCCESS) {
296         errs++;
297         if (verbose) {
298             fprintf(stderr, "error in MPI_Pack_size call; aborting after %d errors\n", errs);
299         }
300         return errs;
301     }
302     packbuf = (char *) malloc(pack_size);
303     if (packbuf == NULL) {
304         errs++;
305         if (verbose) {
306             fprintf(stderr, "error in malloc call; aborting after %d errors\n", errs);
307         }
308         return errs;
309     }
310
311     position = 0;
312     err = MPI_Pack(typebuf, count, datatype, packbuf, type_size, &position, MPI_COMM_SELF);
313
314     if (position != type_size) {
315         errs++;
316         if (verbose)
317             fprintf(stderr, "position = %d; should be %d (pack)\n", position, type_size);
318     }
319
320     memset(typebuf, 0, typebufsz);
321     position = 0;
322     err = MPI_Unpack(packbuf, type_size, &position, typebuf, count, datatype, MPI_COMM_SELF);
323     if (err != MPI_SUCCESS) {
324         errs++;
325         if (verbose) {
326             fprintf(stderr, "error in MPI_Unpack call; aborting after %d errors\n", errs);
327         }
328         return errs;
329     }
330     free(packbuf);
331
332     if (position != type_size) {
333         errs++;
334         if (verbose)
335             fprintf(stderr, "position = %d; should be %d (unpack)\n", position, type_size);
336     }
337
338     return errs;
339 }
340
341 int parse_args(int argc, char **argv)
342 {
343     if (argc > 1 && strcmp(argv[1], "-v") == 0)
344         verbose = 1;
345     return 0;
346 }
347 #endif /*defined(TEST_HINDEXED_BLOCK)*/