1 /* -*- Mode: C; c-basic-offset:4 ; -*- */
3 * (C) 2012 by Argonne National Laboratory.
4 * See COPYRIGHT in top-level directory.
11 int AllocateGrid(int nx, int ny, int **srcArray, int **destArray);
12 int PackUnpack(MPI_Datatype, const int[], int[], int);
14 int main(int argc, char *argv[])
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;
25 MPI_Comm_rank(MPI_COMM_WORLD, &wrank);
26 MPI_Comm_size(MPI_COMM_WORLD, &wsize);
28 /* Test 1: Simple, 1-D cyclic decomposition */
29 if (AllocateGrid(1, 3 * wsize, &srcArray, &destArray)) {
30 MPI_Abort(MPI_COMM_WORLD, 1);
33 /* Simple cyclic with 1-dim global array */
34 gsizes[0] = 3 * wsize;
35 distribs[0] = MPI_DISTRIBUTE_CYCLIC;
38 MPI_Type_create_darray(wsize, wrank, 1,
39 gsizes, distribs, dargs, psizes, MPI_ORDER_C, MPI_INT, &darraytype);
41 /* Check the created datatype. Because cyclic, should represent
43 if (PackUnpack(darraytype, srcArray, destArray, 3)) {
44 fprintf(stderr, "Error in pack/unpack check\n");
45 MPI_Abort(MPI_COMM_WORLD, 1);
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]);
57 MPI_Type_free(&darraytype);
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);
64 /* Simple cyclic with 1-dim global array */
65 gsizes[0] = 4 * wsize;
66 distribs[0] = MPI_DISTRIBUTE_CYCLIC;
69 MPI_Type_create_darray(wsize, wrank, 1,
70 gsizes, distribs, dargs, psizes, MPI_ORDER_C, MPI_INT, &darraytype);
72 /* Check the created datatype. Because cyclic, should represent
74 if (PackUnpack(darraytype, srcArray, destArray, 4)) {
75 fprintf(stderr, "Error in pack/unpack check\n");
76 MPI_Abort(MPI_COMM_WORLD, 1);
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]);
94 MPI_Type_free(&darraytype);
96 /* 2D: Create some 2-D decompositions */
102 if (px * py != wsize) {
103 fprintf(stderr, "An even number of processes is required\n");
104 MPI_Abort(MPI_COMM_WORLD, 1);
108 if (AllocateGrid(5 * px, 7 * py, &srcArray, &destArray)) {
109 MPI_Abort(MPI_COMM_WORLD, 1);
112 /* Simple cyclic/cyclic. Note in C order, the [1] index varies most
114 gsizes[0] = ny = 7 * py;
115 gsizes[1] = nx = 5 * px;
116 distribs[0] = MPI_DISTRIBUTE_CYCLIC;
117 distribs[1] = MPI_DISTRIBUTE_CYCLIC;
122 MPI_Type_create_darray(wsize, wrank, 2,
123 gsizes, distribs, dargs, psizes, MPI_ORDER_C, MPI_INT, &darraytype);
125 /* Check the created datatype. Because cyclic, should represent
127 if (PackUnpack(darraytype, srcArray, destArray, 5 * 7)) {
128 fprintf(stderr, "Error in pack/unpack check\n");
129 MPI_Abort(MPI_COMM_WORLD, 1);
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) {
138 fprintf(stderr, "2D(cc): [%d,%d] = %d, expected %d\n",
139 i, j, destArray[loc], expected);
147 MPI_Type_free(&darraytype);
149 /* Cyclic(2)/Cyclic(3) */
150 if (AllocateGrid(6 * px, 4 * py, &srcArray, &destArray)) {
151 MPI_Abort(MPI_COMM_WORLD, 1);
154 /* Block cyclic/cyclic. Note in C order, the [1] index varies most
156 gsizes[0] = ny = 4 * py;
157 gsizes[1] = nx = 6 * px;
158 distribs[0] = MPI_DISTRIBUTE_CYCLIC;
159 distribs[1] = MPI_DISTRIBUTE_CYCLIC;
164 MPI_Type_create_darray(wsize, wrank, 2,
165 gsizes, distribs, dargs, psizes, MPI_ORDER_C, MPI_INT, &darraytype);
167 /* Check the created datatype. Because cyclic, should represent
169 if (PackUnpack(darraytype, srcArray, destArray, 4 * 6)) {
170 fprintf(stderr, "Error in pack/unpack check\n");
171 MPI_Abort(MPI_COMM_WORLD, 1);
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) {
183 fprintf(stderr, "2D(c(2)c(3)): [%d,%d] = %d, expected %d\n",
184 i * bx + ii, j * by + jj, destArray[loc], expected);
194 MPI_Type_free(&darraytype);
196 MTest_Finalize(errs);
202 int AllocateGrid(int nx, int ny, int **srcArray, int **destArray)
206 src = (int *) malloc(nx * ny * sizeof(int));
207 dest = (int *) malloc(nx * ny * sizeof(int));
209 fprintf(stderr, "Unable to allocate test arrays of size (%d x %d)\n", nx, ny);
212 for (i = 0; i < nx * ny; i++) {
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)
225 int packsize, position;
228 MPI_Type_commit(&darraytype);
229 MPI_Pack_size(1, darraytype, MPI_COMM_SELF, &packsize);
230 packArray = (int *) malloc(packsize);
232 fprintf(stderr, "Unable to allocate pack array of size %d\n", packsize);
233 MPI_Abort(MPI_COMM_WORLD, 1);
236 MPI_Pack((int *) srcArray, 1, darraytype, packArray, packsize, &position, MPI_COMM_SELF);
239 MPI_Unpack(packArray, packsize, &position, destArray, count, MPI_INT, MPI_COMM_SELF);