/*
* This tests that the reduce operation respects the noncommutative flag.
- * and that can distinguish between P_{root} P_{root+1}
+ * and that can distinguish between P_{root} P_{root+1}
* ... P_{root-1} and P_0 ... P_{size-1} . The MPI standard clearly
- * specifies that the result is P_0 ... P_{size-1}, independent of the root
+ * specifies that the result is P_0 ... P_{size-1}, independent of the root
* (see 4.9.4 in MPI-1)
*/
c(i,j) is cin[j+i*matSize]
*/
#define MAXCOL 256
-static int matSize = 0; /* Must be < MAXCOL */
+static int matSize = 0; /* Must be < MAXCOL */
-void uop( void *cinPtr, void *coutPtr, int *count, MPI_Datatype *dtype );
-void uop( void *cinPtr, void *coutPtr, int *count, MPI_Datatype *dtype )
+void uop(void *cinPtr, void *coutPtr, int *count, MPI_Datatype * dtype);
+void uop(void *cinPtr, void *coutPtr, int *count, MPI_Datatype * dtype)
{
const int *cin;
- int *cout;
- int i, j, k, nmat;
- int tempCol[MAXCOL];
+ int *cout;
+ int i, j, k, nmat;
+ int tempCol[MAXCOL];
- if (*count != 1) printf( "Panic!\n" );
+ if (*count != 1)
+ printf("Panic!\n");
for (nmat = 0; nmat < *count; nmat++) {
- cin = (const int *)cinPtr;
- cout = (int *)coutPtr;
- for (j=0; j<matSize; j++) {
- for (i=0; i<matSize; i++) {
- tempCol[i] = 0;
- for (k=0; k<matSize; k++) {
- /* col[i] += cin(i,k) * cout(k,j) */
- tempCol[i] += cin[k+i*matSize] * cout[j+k*matSize];
- }
- }
- for (i=0; i<matSize; i++) {
- cout[j+i*matSize] = tempCol[i];
- }
- }
- cinPtr = (int *)cinPtr + matSize*matSize;
- coutPtr = (int *)coutPtr + matSize*matSize;
+ cin = (const int *) cinPtr;
+ cout = (int *) coutPtr;
+ for (j = 0; j < matSize; j++) {
+ for (i = 0; i < matSize; i++) {
+ tempCol[i] = 0;
+ for (k = 0; k < matSize; k++) {
+ /* col[i] += cin(i,k) * cout(k,j) */
+ tempCol[i] += cin[k + i * matSize] * cout[j + k * matSize];
+ }
+ }
+ for (i = 0; i < matSize; i++) {
+ cout[j + i * matSize] = tempCol[i];
+ }
+ }
+ cinPtr = (int *) cinPtr + matSize * matSize;
+ coutPtr = (int *) coutPtr + matSize * matSize;
}
}
If we call this matrix P_r, we know that product of P_0 P_1 ... P_{size-1}
is the matrix with rows ordered as
1,size,2,3,4,...,size-1
- (The matrix is basically a circular shift right,
+ (The matrix is basically a circular shift right,
shifting right n-1 steps for an n x n dimensional matrix, with the last
step swapping rows 1 and size)
-*/
+*/
-static void initMat( MPI_Comm comm, int mat[] )
+static void initMat(MPI_Comm comm, int mat[])
{
int i, size, rank;
-
- MPI_Comm_rank( comm, &rank );
- MPI_Comm_size( comm, &size );
+
+ MPI_Comm_rank(comm, &rank);
+ MPI_Comm_size(comm, &size);
/* Remember the matrix size */
matSize = size;
- for (i=0; i<matSize*matSize; i++) mat[i] = 0;
+ for (i = 0; i < matSize * matSize; i++)
+ mat[i] = 0;
- for (i=0; i<matSize; i++) {
- if (i == rank)
- mat[((i+1)%matSize) + i * matSize] = 1;
- else if (i == ((rank + 1)%matSize))
- mat[((i+matSize-1)%matSize) + i * matSize] = 1;
- else
- mat[i+i*matSize] = 1;
+ for (i = 0; i < matSize; i++) {
+ if (i == rank)
+ mat[((i + 1) % matSize) + i * matSize] = 1;
+ else if (i == ((rank + 1) % matSize))
+ mat[((i + matSize - 1) % matSize) + i * matSize] = 1;
+ else
+ mat[i + i * matSize] = 1;
}
}
/* Compare a matrix with the identity matrix */
/*
-static int isIdentity( MPI_Comm comm, int mat[] )
+static int isIdentity(MPI_Comm comm, int mat[])
{
int i, j, size, rank, errs = 0;
-
- MPI_Comm_rank( comm, &rank );
- MPI_Comm_size( comm, &size );
+
+ MPI_Comm_rank(comm, &rank);
+ MPI_Comm_size(comm, &size);
for (i=0; i<size; i++) {
for (j=0; j<size; j++) {
if (j == i) {
if (mat[j+i*size] != 1) {
- printf( "mat(%d,%d) = %d, should = 1\n",
- i, j, mat[j+i*size] );
+ printf("mat(%d,%d) = %d, should = 1\n",
+ i, j, mat[j+i*size]);
errs++;
}
}
else {
if (mat[j+i*size] != 0) {
- printf( "mat(%d,%d) = %d, should = 0\n",
- i, j, mat[j+i*size] );
+ printf("mat(%d,%d) = %d, should = 0\n",
+ i, j, mat[j+i*size]);
errs++;
}
}
/* Compare a matrix with the identity matrix with rows permuted to as rows
1,size,2,3,4,5,...,size-1 */
-static int isPermutedIdentity( MPI_Comm comm, int mat[] )
+static int isPermutedIdentity(MPI_Comm comm, int mat[])
{
int i, j, size, rank, errs = 0;
-
- MPI_Comm_rank( comm, &rank );
- MPI_Comm_size( comm, &size );
+
+ MPI_Comm_rank(comm, &rank);
+ MPI_Comm_size(comm, &size);
/* Check the first two last rows */
i = 0;
- for (j=0; j<size; j++) {
- if (j==0) {
- if (mat[j] != 1) {
- printf( "mat(%d,%d) = %d, should = 1\n",
- i, j, mat[j] );
- errs++;
- }
- }
- else {
- if (mat[j] != 0) {
- printf( "mat(%d,%d) = %d, should = 0\n",
- i, j, mat[j] );
- errs++;
- }
- }
+ for (j = 0; j < size; j++) {
+ if (j == 0) {
+ if (mat[j] != 1) {
+ printf("mat(%d,%d) = %d, should = 1\n", i, j, mat[j]);
+ errs++;
+ }
+ }
+ else {
+ if (mat[j] != 0) {
+ printf("mat(%d,%d) = %d, should = 0\n", i, j, mat[j]);
+ errs++;
+ }
+ }
}
i = 1;
- for (j=0; j<size; j++) {
- if (j==size-1) {
- if (mat[j+i*size] != 1) {
- printf( "mat(%d,%d) = %d, should = 1\n",
- i, j, mat[j+i*size] );
- errs++;
- }
- }
- else {
- if (mat[j+i*size] != 0) {
- printf( "mat(%d,%d) = %d, should = 0\n",
- i, j, mat[j+i*size] );
- errs++;
- }
- }
+ for (j = 0; j < size; j++) {
+ if (j == size - 1) {
+ if (mat[j + i * size] != 1) {
+ printf("mat(%d,%d) = %d, should = 1\n", i, j, mat[j + i * size]);
+ errs++;
+ }
+ }
+ else {
+ if (mat[j + i * size] != 0) {
+ printf("mat(%d,%d) = %d, should = 0\n", i, j, mat[j + i * size]);
+ errs++;
+ }
+ }
}
/* The remaint rows are shifted down by one */
- for (i=2; i<size; i++) {
- for (j=0; j<size; j++) {
- if (j == i-1) {
- if (mat[j+i*size] != 1) {
- printf( "mat(%d,%d) = %d, should = 1\n",
- i, j, mat[j+i*size] );
- errs++;
- }
- }
- else {
- if (mat[j+i*size] != 0) {
- printf( "mat(%d,%d) = %d, should = 0\n",
- i, j, mat[j+i*size] );
- errs++;
- }
- }
- }
+ for (i = 2; i < size; i++) {
+ for (j = 0; j < size; j++) {
+ if (j == i - 1) {
+ if (mat[j + i * size] != 1) {
+ printf("mat(%d,%d) = %d, should = 1\n", i, j, mat[j + i * size]);
+ errs++;
+ }
+ }
+ else {
+ if (mat[j + i * size] != 0) {
+ printf("mat(%d,%d) = %d, should = 0\n", i, j, mat[j + i * size]);
+ errs++;
+ }
+ }
+ }
}
return errs;
}
-int main( int argc, char *argv[] )
+int main(int argc, char *argv[])
{
int errs = 0;
int rank, size, root;
- int minsize = 2, count;
- MPI_Comm comm;
+ int minsize = 2, count;
+ MPI_Comm comm;
int *buf, *bufout;
MPI_Op op;
MPI_Datatype mattype;
- MTest_Init( &argc, &argv );
+ MTest_Init(&argc, &argv);
- MPI_Op_create( uop, 0, &op );
-
- while (MTestGetIntracommGeneral( &comm, minsize, 1 )) {
- if (comm == MPI_COMM_NULL) continue;
- MPI_Comm_size( comm, &size );
- MPI_Comm_rank( comm, &rank );
+ MPI_Op_create(uop, 0, &op);
- if (size > MAXCOL) {
- /* Skip because there are too many processes */
- MTestFreeComm( &comm );
- continue;
- }
+ while (MTestGetIntracommGeneral(&comm, minsize, 1)) {
+ if (comm == MPI_COMM_NULL)
+ continue;
+ MPI_Comm_size(comm, &size);
+ MPI_Comm_rank(comm, &rank);
- /* Only one matrix for now */
- count = 1;
+ if (size > MAXCOL) {
+ /* Skip because there are too many processes */
+ MTestFreeComm(&comm);
+ continue;
+ }
- /* A single matrix, the size of the communicator */
- MPI_Type_contiguous( size*size, MPI_INT, &mattype );
- MPI_Type_commit( &mattype );
-
- buf = (int *)malloc( count * size * size * sizeof(int) );
- if (!buf) MPI_Abort( MPI_COMM_WORLD, 1 );
- bufout = (int *)malloc( count * size * size * sizeof(int) );
- if (!bufout) MPI_Abort( MPI_COMM_WORLD, 1 );
+ /* Only one matrix for now */
+ count = 1;
- for (root = 0; root < size; root ++) {
- initMat( comm, buf );
- MPI_Reduce( buf, bufout, count, mattype, op, root, comm );
- if (rank == root) {
- errs += isPermutedIdentity( comm, bufout );
- }
+ /* A single matrix, the size of the communicator */
+ MPI_Type_contiguous(size * size, MPI_INT, &mattype);
+ MPI_Type_commit(&mattype);
- /* Try the same test, but using MPI_IN_PLACE */
- initMat( comm, bufout );
- if (rank == root) {
- MPI_Reduce( MPI_IN_PLACE, bufout, count, mattype, op, root, comm );
- }
- else {
- MPI_Reduce( bufout, NULL, count, mattype, op, root, comm );
- }
- if (rank == root) {
- errs += isPermutedIdentity( comm, bufout );
- }
- }
- MPI_Type_free( &mattype );
+ buf = (int *) malloc(count * size * size * sizeof(int));
+ if (!buf)
+ MPI_Abort(MPI_COMM_WORLD, 1);
+ bufout = (int *) malloc(count * size * size * sizeof(int));
+ if (!bufout)
+ MPI_Abort(MPI_COMM_WORLD, 1);
+
+ for (root = 0; root < size; root++) {
+ initMat(comm, buf);
+ MPI_Reduce(buf, bufout, count, mattype, op, root, comm);
+ if (rank == root) {
+ errs += isPermutedIdentity(comm, bufout);
+ }
+
+ /* Try the same test, but using MPI_IN_PLACE */
+ initMat(comm, bufout);
+ if (rank == root) {
+ MPI_Reduce(MPI_IN_PLACE, bufout, count, mattype, op, root, comm);
+ }
+ else {
+ MPI_Reduce(bufout, NULL, count, mattype, op, root, comm);
+ }
+ if (rank == root) {
+ errs += isPermutedIdentity(comm, bufout);
+ }
+ }
+ MPI_Type_free(&mattype);
- free( buf );
- free( bufout );
+ free(buf);
+ free(bufout);
- MTestFreeComm( &comm );
+ MTestFreeComm(&comm);
}
- MPI_Op_free( &op );
+ MPI_Op_free(&op);
- MTest_Finalize( errs );
+ MTest_Finalize(errs);
MPI_Finalize();
return 0;
}