/* Testing for bundle pack and unpack which invloves a flexible way of reading and writing arrays. This example may still not cover all possible cases. Anyone can add more send and receive pairs for different cases. */ #include #include CMPI_Gcomm Gcomm; $input int N; $input int inputs1[3][N]; $input int inputs2[N][3]; $assume N > 4; void main(){ /* Process function */ void Process(int i){ MPI_Comm comm = CMPI_Comm_create($here, Gcomm, i); int rank; __MPI_Init(&comm); MPI_Comm_rank(comm, &rank); /* In total 2 processes, 0 sends and 1 receives */ if (rank == 0){ int integerObj = 1; int * p; int ** pp; int a3d[3][4][5]; int counter = 0; //Initialization of message data p = (int *)$malloc($root, sizeof(int) * 4); pp = (int **)$malloc($root, sizeof(int *) * 4); for(int i=0; i<4; i++){ p[i] = i; pp[i] = (int *)$malloc($root, sizeof(int) * 2); for(int j=0; j<2; j++) pp[i][j] = i * 4 + j; } //p -> p[4]; pp -> pp[4][2]; for(int i=0; i<3; i++) for(int j=0; j<4; j++) for(int k=0; k<5; k++) a3d[i][j][k] = counter++; // send integer object "1" MPI_Send(&integerObj, 1, MPI_INT, 1, 0, comm); // send p[0], p[1] and p[2] with values "0" ,"1" and "2" MPI_Send(p, 3, MPI_INT, 1, 0, comm); // send pp[1][0], pp[1][1] with values "4" and "5" MPI_Send(pp[1], 2, MPI_INT, 1, 0, comm); // send "23...30" MPI_Send(&a3d[1][0][3], 8, MPI_INT, 1, 0, comm); // send "23...30" again MPI_Send(&a3d[1][0][3], 8, MPI_INT, 1, 0, comm); // send inputs2[1][1] and inputs2[1][2] MPI_Send(&inputs2[1][1], 2, MPI_INT, 1, 0, comm); // send inputs1[0][0]...inputs1[0][3] MPI_Send(inputs1[0], 4, MPI_INT, 1, 0, comm); $free(p); for(int i=0; i<4; i++) $free(pp[i]); $free(pp); } else{ int integerObj; int * buf; int a4d[2][2][2][2]; buf = (int *)$malloc($root, sizeof(int) * 8); MPI_Recv(&integerObj, 1, MPI_INT, 0, 0, comm, MPI_STATUS_IGNORE); $assert(integerObj == 1, "first assertion"); MPI_Recv(buf, 3, MPI_INT, 0, 0, comm, MPI_STATUS_IGNORE); $assert((buf[0] == 0 && buf[1] == 1 && buf[2] == 2), "second assertion"); MPI_Recv(buf, 2, MPI_INT, 0, 0, comm, MPI_STATUS_IGNORE); $assert((buf[0] == 4 && buf[1] == 5), "third assertion"); MPI_Recv(&a4d[0][1][1], 8, MPI_INT, 0, 0, comm, MPI_STATUS_IGNORE); for(int i=0; i<8; i++) $assert(*(&a4d[0][1][1][0] + i) == (23 + i), "forth assertion"); // pointer type is different from the previous one MPI_Recv(a4d[0][1][1], 8, MPI_INT, 0, 0, comm, MPI_STATUS_IGNORE); for(int i=0; i<8; i++) $assert(*(&a4d[0][1][1][0] + i) == (23 + i), "fifth assertion"); MPI_Recv((buf+1), 2, MPI_INT, 0, 0, comm, MPI_STATUS_IGNORE); for(int i=0; i<2; i++) $assert(*(buf + 1 + i) == inputs2[1][i+1], "sixth assertion"); MPI_Recv((buf+1), 8, MPI_INT, 0, 0, comm, MPI_STATUS_IGNORE); for(int i=0; i<4; i++) $assert(*(buf + 1 + i) == inputs1[0][i], "seventh assertion"); $free(buf); } CMPI_Comm_destroy(comm); __MPI_Finalize(&comm); } $proc procs[2]; Gcomm = CMPI_Gcomm_create($root, 2); for(int i=0; i<2; i++) procs[i] = $spawn Process(i); for(int i=0; i<2; i++) $wait(procs[i]); CMPI_Gcomm_destroy(Gcomm); }