Logo AND Algorithmique Numérique Distribuée

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