Logo AND Algorithmique Numérique Distribuée

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