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=NULL, *destArray=NULL;
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 );
34 /* Simple cyclic with 1-dim global array */
36 distribs[0] = MPI_DISTRIBUTE_CYCLIC;
39 MPI_Type_create_darray( wsize, wrank, 1,
40 gsizes, distribs, dargs, psizes,
41 MPI_ORDER_C, MPI_INT, &darraytype );
43 /* Check the created datatype. Because cyclic, should represent
45 if (PackUnpack( darraytype, srcArray, destArray, 3 )) {
46 fprintf( stderr, "Error in pack/unpack check\n" );
47 MPI_Abort( MPI_COMM_WORLD, 1 );
50 /* Now, check for correct data */
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] );
61 MPI_Type_free( &darraytype );
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 );
69 /* Simple cyclic with 1-dim global array */
71 distribs[0] = MPI_DISTRIBUTE_CYCLIC;
74 MPI_Type_create_darray( wsize, wrank, 1,
75 gsizes, distribs, dargs, psizes,
76 MPI_ORDER_C, MPI_INT, &darraytype );
78 /* Check the created datatype. Because cyclic, should represent
80 if (PackUnpack( darraytype, srcArray, destArray, 4 )) {
81 fprintf( stderr, "Error in pack/unpack check\n" );
82 MPI_Abort( MPI_COMM_WORLD, 1 );
86 /* for each cyclic element */
88 /* For each element in block */
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] );
101 MPI_Type_free( &darraytype );
103 /* 2D: Create some 2-D decompositions */
109 if (px * py != wsize) {
110 fprintf( stderr, "An even number of processes is required\n" );
111 MPI_Abort( MPI_COMM_WORLD, 1 );
116 if (AllocateGrid( 5*px, 7*py, &srcArray, &destArray )) {
117 MPI_Abort( MPI_COMM_WORLD, 1 );
121 /* Simple cyclic/cyclic. Note in C order, the [1] index varies most
123 gsizes[0] = ny = 7*py;
124 gsizes[1] = nx = 5*px;
125 distribs[0] = MPI_DISTRIBUTE_CYCLIC;
126 distribs[1] = MPI_DISTRIBUTE_CYCLIC;
131 MPI_Type_create_darray( wsize, wrank, 2,
132 gsizes, distribs, dargs, psizes,
133 MPI_ORDER_C, MPI_INT, &darraytype );
135 /* Check the created datatype. Because cyclic, should represent
137 if (PackUnpack( darraytype, srcArray, destArray, 5*7 )) {
138 fprintf( stderr, "Error in pack/unpack check\n" );
139 MPI_Abort( MPI_COMM_WORLD, 1 );
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) {
149 fprintf( stderr, "2D(cc): [%d,%d] = %d, expected %d\n",
150 i, j, destArray[loc], expected );
158 MPI_Type_free( &darraytype );
160 /* Cyclic(2)/Cyclic(3) */
161 if (AllocateGrid( 6*px, 4*py, &srcArray, &destArray )) {
162 MPI_Abort( MPI_COMM_WORLD, 1 );
166 /* Block cyclic/cyclic. Note in C order, the [1] index varies most
168 gsizes[0] = ny = 4*py;
169 gsizes[1] = nx = 6*px;
170 distribs[0] = MPI_DISTRIBUTE_CYCLIC;
171 distribs[1] = MPI_DISTRIBUTE_CYCLIC;
176 MPI_Type_create_darray( wsize, wrank, 2,
177 gsizes, distribs, dargs, psizes,
178 MPI_ORDER_C, MPI_INT, &darraytype );
180 /* Check the created datatype. Because cyclic, should represent
182 if (PackUnpack( darraytype, srcArray, destArray, 4*6 )) {
183 fprintf( stderr, "Error in pack/unpack check\n" );
184 MPI_Abort( MPI_COMM_WORLD, 1 );
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) {
197 fprintf( stderr, "2D(c(2)c(3)): [%d,%d] = %d, expected %d\n",
198 i*bx+ii, j*by+jj, destArray[loc], expected );
208 MPI_Type_free( &darraytype );
210 MTest_Finalize( errs );
216 int AllocateGrid( int nx, int ny, int **srcArray, int **destArray )
220 src = (int *)malloc( nx*ny*sizeof(int) );
221 dest = (int *)malloc( nx*ny*sizeof(int) );
223 fprintf( stderr, "Unable to allocate test arrays of size (%d x %d)\n",
227 for (i=0; i<nx*ny; i++) {
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[],
241 int packsize, position;
244 MPI_Type_commit( &darraytype );
245 MPI_Pack_size( 1, darraytype, MPI_COMM_SELF, &packsize );
246 packArray = (int *)malloc( packsize );
248 fprintf( stderr, "Unable to allocate pack array of size %d\n",
250 MPI_Abort( MPI_COMM_WORLD, 1 );
254 MPI_Pack( (int*)srcArray, 1, darraytype, packArray, packsize, &position,
258 MPI_Unpack( packArray, packsize, &position, destArray, count, MPI_INT,