Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
moved a line for comprehension
[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, "error creating hindexed_block type in hindexed_block_contig_test()\n");
215         }
216         errs++;
217     }
218
219     MPI_Type_commit(&newtype);
220
221     err = MPI_Type_size(newtype, &size);
222     if (err != MPI_SUCCESS) {
223         if (verbose) {
224             fprintf(stderr, "error obtaining type size in hindexed_block_contig_test()\n");
225         }
226         errs++;
227     }
228
229     MPI_Type_size(MPI_INT, &int_size);
230
231     if (size != 6 * int_size) {
232         if (verbose) {
233             fprintf(stderr, "error: size != 6 * int_size in hindexed_block_contig_test()\n");
234         }
235         errs++;
236     }
237
238     MPI_Type_extent(newtype, &extent);
239
240     err = pack_and_unpack((char *) buf, 1, newtype, NELT * sizeof(int));
241     if (err != 0) {
242         if (verbose) {
243             fprintf(stderr, "error packing/unpacking in hindexed_block_vector_test()\n");
244         }
245         errs += err;
246     }
247
248     for (i = 0; i < NELT; i++) {
249         if (buf[i] != expected[i]) {
250             errs++;
251             if (verbose)
252                 fprintf(stderr, "buf[%d] = %d; should be %d\n", i, buf[i], expected[i]);
253         }
254     }
255
256     MPI_Type_free(&vectype);
257     MPI_Type_free(&newtype);
258     return errs;
259 }
260
261
262 /* pack_and_unpack()
263  *
264  * Perform packing and unpacking of a buffer for the purposes of checking
265  * to see if we are processing a type correctly.  Zeros the buffer between
266  * these two operations, so the data described by the type should be in
267  * place upon return but all other regions of the buffer should be zero.
268  *
269  * Parameters:
270  * typebuf - pointer to buffer described by datatype and count that
271  *           will be packed and then unpacked into
272  * count, datatype - description of typebuf
273  * typebufsz - size of typebuf; used specifically to zero the buffer
274  *             between the pack and unpack steps
275  *
276  */
277 static int pack_and_unpack(char *typebuf, int count, MPI_Datatype datatype, int typebufsz)
278 {
279     char *packbuf;
280     int err, errs = 0, pack_size, type_size, position;
281
282     err = MPI_Type_size(datatype, &type_size);
283     if (err != MPI_SUCCESS) {
284         errs++;
285         if (verbose) {
286             fprintf(stderr, "error in MPI_Type_size call; aborting after %d errors\n", errs);
287         }
288         return errs;
289     }
290
291     type_size *= count;
292
293     err = MPI_Pack_size(count, datatype, MPI_COMM_SELF, &pack_size);
294     if (err != MPI_SUCCESS) {
295         errs++;
296         if (verbose) {
297             fprintf(stderr, "error in MPI_Pack_size call; aborting after %d errors\n", errs);
298         }
299         return errs;
300     }
301     packbuf = (char *) malloc(pack_size);
302     if (packbuf == NULL) {
303         errs++;
304         if (verbose) {
305             fprintf(stderr, "error in malloc call; aborting after %d errors\n", errs);
306         }
307         return errs;
308     }
309
310     position = 0;
311     err = MPI_Pack(typebuf, count, datatype, packbuf, type_size, &position, MPI_COMM_SELF);
312
313     if (position != type_size) {
314         errs++;
315         if (verbose)
316             fprintf(stderr, "position = %d; should be %d (pack)\n", position, type_size);
317     }
318
319     memset(typebuf, 0, typebufsz);
320     position = 0;
321     err = MPI_Unpack(packbuf, type_size, &position, typebuf, count, datatype, MPI_COMM_SELF);
322     if (err != MPI_SUCCESS) {
323         errs++;
324         if (verbose) {
325             fprintf(stderr, "error in MPI_Unpack call; aborting after %d errors\n", errs);
326         }
327         return errs;
328     }
329     free(packbuf);
330
331     if (position != type_size) {
332         errs++;
333         if (verbose)
334             fprintf(stderr, "position = %d; should be %d (unpack)\n", position, type_size);
335     }
336
337     return errs;
338 }
339
340 int parse_args(int argc, char **argv)
341 {
342     if (argc > 1 && strcmp(argv[1], "-v") == 0)
343         verbose = 1;
344     return 0;
345 }
346 #endif /*defined(TEST_HINDEXED_BLOCK) */