Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'master' into clean_events
[simgrid.git] / teshsuite / smpi / mpich3-test / datatype / darray-cyclic.c
1 /* -*- Mode: C; c-basic-offset:4 ; -*- */
2 /*
3  *  (C) 2012 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 "mpitest.h"
10
11 int AllocateGrid(int nx, int ny, int **srcArray, int **destArray);
12 int PackUnpack(MPI_Datatype, const int[], int[], int);
13
14 int main(int argc, char *argv[])
15 {
16     int errs = 0;
17     int wrank, wsize;
18     int gsizes[3], distribs[3], dargs[3], psizes[3];
19     int px, py, nx, ny, rx, ry, bx, by;
20     int *srcArray, *destArray;
21     int i, j, ii, jj, loc;
22     MPI_Datatype darraytype;
23
24     MTest_Init(0, 0);
25     MPI_Comm_rank(MPI_COMM_WORLD, &wrank);
26     MPI_Comm_size(MPI_COMM_WORLD, &wsize);
27
28     /* Test 1: Simple, 1-D cyclic decomposition */
29     if (AllocateGrid(1, 3 * wsize, &srcArray, &destArray)) {
30         MPI_Abort(MPI_COMM_WORLD, 1);
31     }
32
33     /* Simple cyclic with 1-dim global array */
34     gsizes[0] = 3 * wsize;
35     distribs[0] = MPI_DISTRIBUTE_CYCLIC;
36     dargs[0] = 1;
37     psizes[0] = wsize;
38     MPI_Type_create_darray(wsize, wrank, 1,
39                            gsizes, distribs, dargs, psizes, MPI_ORDER_C, MPI_INT, &darraytype);
40
41     /* Check the created datatype.  Because cyclic, should represent
42      * a strided type */
43     if (PackUnpack(darraytype, srcArray, destArray, 3)) {
44         fprintf(stderr, "Error in pack/unpack check\n");
45         MPI_Abort(MPI_COMM_WORLD, 1);
46     }
47     /* Now, check for correct data */
48     for (i = 0; i < 3; i++) {
49         if (destArray[i] != wrank + i * wsize) {
50             fprintf(stderr, "1D: %d: Expected %d but saw %d\n", i, wrank + i * wsize, destArray[i]);
51             errs++;
52         }
53     }
54
55     free(destArray);
56     free(srcArray);
57     MPI_Type_free(&darraytype);
58
59     /* Test 2: Simple, 1-D cyclic decomposition, with block size=2 */
60     if (AllocateGrid(1, 4 * wsize, &srcArray, &destArray)) {
61         MPI_Abort(MPI_COMM_WORLD, 1);
62     }
63
64     /* Simple cyclic with 1-dim global array */
65     gsizes[0] = 4 * wsize;
66     distribs[0] = MPI_DISTRIBUTE_CYCLIC;
67     dargs[0] = 2;
68     psizes[0] = wsize;
69     MPI_Type_create_darray(wsize, wrank, 1,
70                            gsizes, distribs, dargs, psizes, MPI_ORDER_C, MPI_INT, &darraytype);
71
72     /* Check the created datatype.  Because cyclic, should represent
73      * a strided type */
74     if (PackUnpack(darraytype, srcArray, destArray, 4)) {
75         fprintf(stderr, "Error in pack/unpack check\n");
76         MPI_Abort(MPI_COMM_WORLD, 1);
77     }
78     loc = 0;
79     /* for each cyclic element */
80     for (i = 0; i < 2; i++) {
81         /* For each element in block */
82         for (j = 0; j < 2; j++) {
83             if (destArray[loc] != 2 * wrank + i * 2 * wsize + j) {
84                 fprintf(stderr, "1D(2): %d: Expected %d but saw %d\n",
85                         i, 2 * wrank + i * 2 * wsize + j, destArray[loc]);
86                 errs++;
87             }
88             loc++;
89         }
90     }
91
92     free(destArray);
93     free(srcArray);
94     MPI_Type_free(&darraytype);
95
96     /* 2D: Create some 2-D decompositions */
97     px = wsize / 2;
98     py = 2;
99     rx = wrank % px;
100     ry = wrank / px;
101
102     if (px * py != wsize) {
103         fprintf(stderr, "An even number of processes is required\n");
104         MPI_Abort(MPI_COMM_WORLD, 1);
105     }
106
107     /* Cyclic/Cyclic */
108     if (AllocateGrid(5 * px, 7 * py, &srcArray, &destArray)) {
109         MPI_Abort(MPI_COMM_WORLD, 1);
110     }
111
112     /* Simple cyclic/cyclic. Note in C order, the [1] index varies most
113      * rapidly */
114     gsizes[0] = ny = 7 * py;
115     gsizes[1] = nx = 5 * px;
116     distribs[0] = MPI_DISTRIBUTE_CYCLIC;
117     distribs[1] = MPI_DISTRIBUTE_CYCLIC;
118     dargs[0] = 1;
119     dargs[1] = 1;
120     psizes[0] = py;
121     psizes[1] = px;
122     MPI_Type_create_darray(wsize, wrank, 2,
123                            gsizes, distribs, dargs, psizes, MPI_ORDER_C, MPI_INT, &darraytype);
124
125     /* Check the created datatype.  Because cyclic, should represent
126      * a strided type */
127     if (PackUnpack(darraytype, srcArray, destArray, 5 * 7)) {
128         fprintf(stderr, "Error in pack/unpack check\n");
129         MPI_Abort(MPI_COMM_WORLD, 1);
130     }
131
132     loc = 0;
133     for (j = 0; j < 7; j++) {
134         for (i = 0; i < 5; i++) {
135             int expected = rx + ry * nx + i * px + j * nx * py;
136             if (destArray[loc] != expected) {
137                 errs++;
138                 fprintf(stderr, "2D(cc): [%d,%d] = %d, expected %d\n",
139                         i, j, destArray[loc], expected);
140             }
141             loc++;
142         }
143     }
144
145     free(srcArray);
146     free(destArray);
147     MPI_Type_free(&darraytype);
148
149     /* Cyclic(2)/Cyclic(3) */
150     if (AllocateGrid(6 * px, 4 * py, &srcArray, &destArray)) {
151         MPI_Abort(MPI_COMM_WORLD, 1);
152     }
153
154     /* Block cyclic/cyclic. Note in C order, the [1] index varies most
155      * rapidly */
156     gsizes[0] = ny = 4 * py;
157     gsizes[1] = nx = 6 * px;
158     distribs[0] = MPI_DISTRIBUTE_CYCLIC;
159     distribs[1] = MPI_DISTRIBUTE_CYCLIC;
160     dargs[0] = by = 2;
161     dargs[1] = bx = 3;
162     psizes[0] = py;
163     psizes[1] = px;
164     MPI_Type_create_darray(wsize, wrank, 2,
165                            gsizes, distribs, dargs, psizes, MPI_ORDER_C, MPI_INT, &darraytype);
166
167     /* Check the created datatype.  Because cyclic, should represent
168      * a strided type */
169     if (PackUnpack(darraytype, srcArray, destArray, 4 * 6)) {
170         fprintf(stderr, "Error in pack/unpack check\n");
171         MPI_Abort(MPI_COMM_WORLD, 1);
172     }
173
174     loc = 0;
175     for (j = 0; j < 4 / by; j++) {
176         for (jj = 0; jj < by; jj++) {
177             for (i = 0; i < 6 / bx; i++) {
178                 for (ii = 0; ii < bx; ii++) {
179                     int expected = rx * bx + ry * by * nx + i * bx * px + ii +
180                         (j * by * py + jj) * nx;
181                     if (destArray[loc] != expected) {
182                         errs++;
183                         fprintf(stderr, "2D(c(2)c(3)): [%d,%d] = %d, expected %d\n",
184                                 i * bx + ii, j * by + jj, destArray[loc], expected);
185                     }
186                     loc++;
187                 }
188             }
189         }
190     }
191
192     free(srcArray);
193     free(destArray);
194     MPI_Type_free(&darraytype);
195
196     MTest_Finalize(errs);
197     MPI_Finalize();
198
199     return 0;
200 }
201
202 int AllocateGrid(int nx, int ny, int **srcArray, int **destArray)
203 {
204     int *src, *dest;
205     int i, j;
206     src = (int *) malloc(nx * ny * sizeof(int));
207     dest = (int *) malloc(nx * ny * sizeof(int));
208     if (!src || !dest) {
209         fprintf(stderr, "Unable to allocate test arrays of size (%d x %d)\n", nx, ny);
210         return 1;
211     }
212     for (i = 0; i < nx * ny; i++) {
213         src[i] = i;
214         dest[i] = -i - 1;
215     }
216     *srcArray = src;
217     *destArray = dest;
218     return 0;
219 }
220
221 /* Extract the source array into the dest array using the DARRAY datatype.
222    "count" integers are returned in destArray */
223 int PackUnpack(MPI_Datatype darraytype, const int srcArray[], int destArray[], int count)
224 {
225     int packsize, position;
226     int *packArray;
227
228     MPI_Type_commit(&darraytype);
229     MPI_Pack_size(1, darraytype, MPI_COMM_SELF, &packsize);
230     packArray = (int *) malloc(packsize);
231     if (!packArray) {
232         fprintf(stderr, "Unable to allocate pack array of size %d\n", packsize);
233         MPI_Abort(MPI_COMM_WORLD, 1);
234     }
235     position = 0;
236     MPI_Pack((int *) srcArray, 1, darraytype, packArray, packsize, &position, MPI_COMM_SELF);
237     packsize = position;
238     position = 0;
239     MPI_Unpack(packArray, packsize, &position, destArray, count, MPI_INT, MPI_COMM_SELF);
240     free(packArray);
241     return 0;
242 }