Logo AND Algorithmique Numérique Distribuée

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