Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Update datatype mpich tests
[simgrid.git] / teshsuite / smpi / mpich3-test / datatype / darray-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 "mpi.h"
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include "mpitest.h"
11
12 /*
13    The default behavior of the test routines should be to briefly indicate
14    the cause of any errors - in this test, that means that verbose needs
15    to be set. Verbose should turn on output that is independent of error
16    levels.
17 */
18 static int verbose = 1;
19
20 /* tests */
21 int darray_2d_c_test1(void);
22 int darray_4d_c_test1(void);
23
24 /* helper functions */
25 static 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
32     MTest_Init(&argc, &argv);
33     parse_args(argc, argv);
34
35     /* To improve reporting of problems about operations, we
36      * change the error handler to errors return */
37     MPI_Comm_set_errhandler(MPI_COMM_WORLD, MPI_ERRORS_RETURN);
38
39     /* perform some tests */
40     err = darray_2d_c_test1();
41     if (err && verbose)
42         fprintf(stderr, "%d errors in 2d darray c test 1.\n", err);
43     errs += err;
44
45     err = darray_4d_c_test1();
46     if (err && verbose)
47         fprintf(stderr, "%d errors in 4d darray c test 1.\n", err);
48     errs += err;
49
50     /* print message and exit */
51     /* Allow the use of more than one process - some MPI implementations
52      * (including IBM's) check that the number of processes given to
53      * Type_create_darray is no larger than MPI_COMM_WORLD */
54
55     MTest_Finalize(errs);
56     MPI_Finalize();
57     return 0;
58 }
59
60 /* darray_2d_test1()
61  *
62  * Performs a sequence of tests building darrays with single-element
63  * blocks, running through all the various positions that the element might
64  * come from.
65  *
66  * Returns the number of errors encountered.
67  */
68 int darray_2d_c_test1(void)
69 {
70     MPI_Datatype darray;
71     int array[9];               /* initialized below */
72     int array_size[2] = { 3, 3 };
73     int array_distrib[2] = { MPI_DISTRIBUTE_BLOCK, MPI_DISTRIBUTE_BLOCK };
74     int array_dargs[2] = { MPI_DISTRIBUTE_DFLT_DARG, MPI_DISTRIBUTE_DFLT_DARG };
75     int array_psizes[2] = { 3, 3 };
76
77     int i, rank, err, errs = 0, sizeoftype;
78
79     /* pretend we are each rank, one at a time */
80     for (rank = 0; rank < 9; rank++) {
81         /* set up buffer */
82         for (i = 0; i < 9; i++) {
83             array[i] = i;
84         }
85
86         /* set up type */
87         err = MPI_Type_create_darray(9, /* size */
88                                      rank, 2,   /* dims */
89                                      array_size,
90                                      array_distrib,
91                                      array_dargs, array_psizes, MPI_ORDER_C, MPI_INT, &darray);
92         if (err != MPI_SUCCESS) {
93             errs++;
94             if (verbose) {
95                 fprintf(stderr,
96                         "error in MPI_Type_create_darray call; aborting after %d errors\n", errs);
97             }
98             MTestPrintError(err);
99             return errs;
100         }
101
102         MPI_Type_commit(&darray);
103
104         MPI_Type_size(darray, &sizeoftype);
105         if (sizeoftype != sizeof(int)) {
106             errs++;
107             if (verbose)
108                 fprintf(stderr, "size of type = %d; should be %d\n", sizeoftype, (int) sizeof(int));
109             return errs;
110         }
111
112         err = pack_and_unpack((char *) array, 1, darray, 9 * sizeof(int));
113
114         for (i = 0; i < 9; i++) {
115
116             if ((i == rank) && (array[i] != rank)) {
117                 errs++;
118                 if (verbose)
119                     fprintf(stderr, "[2d array rank=%d]:array[%d] = %d; should be %d\n",
120                             rank, i, array[i], rank);
121             }
122             else if ((i != rank) && (array[i] != 0)) {
123                 errs++;
124                 if (verbose)
125                     fprintf(stderr, "[2d array rank=%d]:array[%d] = %d; should be %d\n",
126                             rank, i, array[i], 0);
127             }
128         }
129         MPI_Type_free(&darray);
130     }
131
132     return errs;
133 }
134
135 /* darray_4d_c_test1()
136  *
137  * Returns the number of errors encountered.
138  */
139 int darray_4d_c_test1(void)
140 {
141     MPI_Datatype darray;
142     int array[72];
143     int array_size[4] = { 6, 3, 2, 2 };
144     int array_distrib[4] = { MPI_DISTRIBUTE_BLOCK,
145         MPI_DISTRIBUTE_BLOCK,
146         MPI_DISTRIBUTE_NONE,
147         MPI_DISTRIBUTE_NONE
148     };
149     int array_dargs[4] = { MPI_DISTRIBUTE_DFLT_DARG,
150         MPI_DISTRIBUTE_DFLT_DARG,
151         MPI_DISTRIBUTE_DFLT_DARG,
152         MPI_DISTRIBUTE_DFLT_DARG
153     };
154     int array_psizes[4] = { 6, 3, 1, 1 };
155
156     int i, rank, err, errs = 0, sizeoftype;
157
158     for (rank = 0; rank < 18; rank++) {
159         /* set up array */
160         for (i = 0; i < 72; i++) {
161             array[i] = i;
162         }
163
164         /* set up type */
165         err = MPI_Type_create_darray(18,        /* size */
166                                      rank, 4,   /* dims */
167                                      array_size,
168                                      array_distrib,
169                                      array_dargs, array_psizes, MPI_ORDER_C, MPI_INT, &darray);
170         if (err != MPI_SUCCESS) {
171             errs++;
172             if (verbose) {
173                 fprintf(stderr,
174                         "error in MPI_Type_create_darray call; aborting after %d errors\n", errs);
175             }
176             MTestPrintError(err);
177             return errs;
178         }
179
180         MPI_Type_commit(&darray);
181
182         /* verify the size of the type */
183         MPI_Type_size(darray, &sizeoftype);
184         if (sizeoftype != 4 * sizeof(int)) {
185             errs++;
186             if (verbose)
187                 fprintf(stderr, "size of type = %d; should be %d\n",
188                         sizeoftype, (int) (4 * sizeof(int)));
189             return errs;
190         }
191
192         /* pack and unpack the type, zero'ing out all other values */
193         err = pack_and_unpack((char *) array, 1, darray, 72 * sizeof(int));
194
195         for (i = 0; i < 4 * rank; i++) {
196             if (array[i] != 0) {
197                 errs++;
198                 if (verbose)
199                     fprintf(stderr, "[4d array rank=%d]:array[%d] = %d; should be %d\n",
200                             rank, i, array[i], 0);
201             }
202         }
203
204         for (i = 4 * rank; i < 4 * rank + 4; i++) {
205             if (array[i] != i) {
206                 errs++;
207                 if (verbose)
208                     fprintf(stderr, "[4d array rank=%d]:array[%d] = %d; should be %d\n",
209                             rank, i, array[i], i);
210             }
211         }
212         for (i = 4 * rank + 4; i < 72; i++) {
213             if (array[i] != 0) {
214                 errs++;
215                 if (verbose)
216                     fprintf(stderr, "[4d array rank=%d]:array[%d] = %d; should be %d\n",
217                             rank, i, array[i], 0);
218             }
219         }
220
221         MPI_Type_free(&darray);
222     }
223     return errs;
224 }
225
226 /******************************************************************/
227
228 /* pack_and_unpack()
229  *
230  * Perform packing and unpacking of a buffer for the purposes of checking
231  * to see if we are processing a type correctly.  Zeros the buffer between
232  * these two operations, so the data described by the type should be in
233  * place upon return but all other regions of the buffer should be zero.
234  *
235  * Parameters:
236  * typebuf - pointer to buffer described by datatype and count that
237  *           will be packed and then unpacked into
238  * count, datatype - description of typebuf
239  * typebufsz - size of typebuf; used specifically to zero the buffer
240  *             between the pack and unpack steps
241  *
242  */
243 static int pack_and_unpack(char *typebuf, int count, MPI_Datatype datatype, int typebufsz)
244 {
245     char *packbuf;
246     int err, errs = 0, pack_size, type_size, position;
247
248     err = MPI_Type_size(datatype, &type_size);
249     if (err != MPI_SUCCESS) {
250         errs++;
251         if (verbose) {
252             fprintf(stderr, "error in MPI_Type_size call; aborting after %d errors\n", errs);
253         }
254         MTestPrintError(err);
255         return errs;
256     }
257
258     type_size *= count;
259
260     err = MPI_Pack_size(count, datatype, MPI_COMM_SELF, &pack_size);
261     if (err != MPI_SUCCESS) {
262         errs++;
263         if (verbose) {
264             fprintf(stderr, "error in MPI_Pack_size call; aborting after %d errors\n", errs);
265         }
266         MTestPrintError(err);
267         return errs;
268     }
269     packbuf = (char *) malloc(pack_size);
270     if (packbuf == NULL) {
271         errs++;
272         if (verbose) {
273             fprintf(stderr, "error in malloc call; aborting after %d errors\n", errs);
274         }
275         return errs;
276     }
277
278     /* FIXME: the pack size returned need not be the type_size - this will
279      * only be true if the pack routine simply moves the bytes but does
280      * no other transformations of the data */
281     position = 0;
282     err = MPI_Pack(typebuf, count, datatype, packbuf, type_size, &position, MPI_COMM_SELF);
283
284     if (position != type_size) {
285         errs++;
286         if (verbose)
287             fprintf(stderr, "position = %d; should be %d (pack)\n", position, type_size);
288     }
289
290     memset(typebuf, 0, typebufsz);
291     position = 0;
292     err = MPI_Unpack(packbuf, type_size, &position, typebuf, count, datatype, MPI_COMM_SELF);
293     if (err != MPI_SUCCESS) {
294         errs++;
295         if (verbose) {
296             fprintf(stderr, "error in MPI_Unpack call; aborting after %d errors\n", errs);
297         }
298         MTestPrintError(err);
299         return errs;
300     }
301     free(packbuf);
302
303     if (position != type_size) {
304         errs++;
305         if (verbose)
306             fprintf(stderr, "position = %d; should be %d (unpack)\n", position, type_size);
307     }
308
309     return errs;
310 }
311
312 static int parse_args(int argc, char **argv)
313 {
314     /*
315      * int ret;
316      *
317      * while ((ret = getopt(argc, argv, "v")) >= 0)
318      * {
319      * switch (ret) {
320      * case 'v':
321      * verbose = 1;
322      * break;
323      * }
324      * }
325      */
326     if (argc > 1 && strcmp(argv[1], "-v") == 0)
327         verbose = 1;
328     return 0;
329 }