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 );
33 /* Simple cyclic with 1-dim global array */
35 distribs[0] = MPI_DISTRIBUTE_CYCLIC;
38 MPI_Type_create_darray( wsize, wrank, 1,
39 gsizes, distribs, dargs, psizes,
40 MPI_ORDER_C, MPI_INT, &darraytype );
42 /* Check the created datatype. Because cyclic, should represent
44 if (PackUnpack( darraytype, srcArray, destArray, 3 )) {
45 fprintf( stderr, "Error in pack/unpack check\n" );
46 MPI_Abort( MPI_COMM_WORLD, 1 );
48 /* Now, check for correct data */
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] );
59 MPI_Type_free( &darraytype );
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 );
66 /* Simple cyclic with 1-dim global array */
68 distribs[0] = MPI_DISTRIBUTE_CYCLIC;
71 MPI_Type_create_darray( wsize, wrank, 1,
72 gsizes, distribs, dargs, psizes,
73 MPI_ORDER_C, MPI_INT, &darraytype );
75 /* Check the created datatype. Because cyclic, should represent
77 if (PackUnpack( darraytype, srcArray, destArray, 4 )) {
78 fprintf( stderr, "Error in pack/unpack check\n" );
79 MPI_Abort( MPI_COMM_WORLD, 1 );
82 /* for each cyclic element */
84 /* For each element in block */
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] );
97 MPI_Type_free( &darraytype );
99 /* 2D: Create some 2-D decompositions */
105 if (px * py != wsize) {
106 fprintf( stderr, "An even number of processes is required\n" );
107 MPI_Abort( MPI_COMM_WORLD, 1 );
111 if (AllocateGrid( 5*px, 7*py, &srcArray, &destArray )) {
112 MPI_Abort( MPI_COMM_WORLD, 1 );
115 /* Simple cyclic/cyclic. Note in C order, the [1] index varies most
117 gsizes[0] = ny = 7*py;
118 gsizes[1] = nx = 5*px;
119 distribs[0] = MPI_DISTRIBUTE_CYCLIC;
120 distribs[1] = MPI_DISTRIBUTE_CYCLIC;
125 MPI_Type_create_darray( wsize, wrank, 2,
126 gsizes, distribs, dargs, psizes,
127 MPI_ORDER_C, MPI_INT, &darraytype );
129 /* Check the created datatype. Because cyclic, should represent
131 if (PackUnpack( darraytype, srcArray, destArray, 5*7 )) {
132 fprintf( stderr, "Error in pack/unpack check\n" );
133 MPI_Abort( MPI_COMM_WORLD, 1 );
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) {
142 fprintf( stderr, "2D(cc): [%d,%d] = %d, expected %d\n",
143 i, j, destArray[loc], expected );
151 MPI_Type_free( &darraytype );
153 /* Cyclic(2)/Cyclic(3) */
154 if (AllocateGrid( 6*px, 4*py, &srcArray, &destArray )) {
155 MPI_Abort( MPI_COMM_WORLD, 1 );
158 /* Block cyclic/cyclic. Note in C order, the [1] index varies most
160 gsizes[0] = ny = 4*py;
161 gsizes[1] = nx = 6*px;
162 distribs[0] = MPI_DISTRIBUTE_CYCLIC;
163 distribs[1] = MPI_DISTRIBUTE_CYCLIC;
168 MPI_Type_create_darray( wsize, wrank, 2,
169 gsizes, distribs, dargs, psizes,
170 MPI_ORDER_C, MPI_INT, &darraytype );
172 /* Check the created datatype. Because cyclic, should represent
174 if (PackUnpack( darraytype, srcArray, destArray, 4*6 )) {
175 fprintf( stderr, "Error in pack/unpack check\n" );
176 MPI_Abort( MPI_COMM_WORLD, 1 );
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) {
188 fprintf( stderr, "2D(c(2)c(3)): [%d,%d] = %d, expected %d\n",
189 i*bx+ii, j*by+jj, destArray[loc], expected );
199 MPI_Type_free( &darraytype );
201 MTest_Finalize( errs );
207 int AllocateGrid( int nx, int ny, int **srcArray, int **destArray )
211 src = (int *)malloc( nx*ny*sizeof(int) );
212 dest = (int *)malloc( nx*ny*sizeof(int) );
214 fprintf( stderr, "Unable to allocate test arrays of size (%d x %d)\n",
218 for (i=0; i<nx*ny; i++) {
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[],
232 int packsize, position;
235 MPI_Type_commit( &darraytype );
236 MPI_Pack_size( 1, darraytype, MPI_COMM_SELF, &packsize );
237 packArray = (int *)malloc( packsize );
239 fprintf( stderr, "Unable to allocate pack array of size %d\n",
241 MPI_Abort( MPI_COMM_WORLD, 1 );
244 MPI_Pack( (int*)srcArray, 1, darraytype, packArray, packsize, &position,
248 MPI_Unpack( packArray, packsize, &position, destArray, count, MPI_INT,