Gauss
Gauss
/*
/*
/*
/*
/*
/*
/*
/*
/*
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
#include <stdio.h>
#include <stdlib.h>
#include "mpi.h"
// This program was writting in the Centre of Advanced Calculations in
// Engineering Science (ACES).
#define TAG_MATRIX_PARTITION
44261 // Try to calculate hex value :-)
// Type definitions
typedef struct
{ unsigned int m, n; // Rows, cols
double
*data; // Data, ordered by row, then by col
double
**rows; // Pointers to rows in data
} TMatrix;
// Global variables
int processor_rank = 0;
int processor_count = 1;
// Function declaractions
TMatrix createMatrix (const unsigned int rows, const unsigned int cols);
void
freeMatrix (TMatrix *matrix);
int
validMatrix (TMatrix matrix);
TMatrix initMatrix (void);
void
sweepMatrix (TMatrix A, TMatrix B, unsigned int pivotRow, unsigned int
pivotCol,
double *rowA, double *rowB);
void
printMatrix (TMatrix A);
int
readMatrix (char *filename, TMatrix *A);
int
writeMatrix (char *filename, TMatrix A);
/* ------------------------------------------------------------------------ */
int main (int argc, char *argv[])
/* ------------------------------------------------------------------------ */
{ MPI_Status status;
TMatrix
A,B,C,D;
unsigned int m, p, i, i0;
unsigned int offset, size[4] = {0};
double
time0, time1;
double
d;
// Initiate all matrices to 0 x 0 matrices.
A = initMatrix();
B = initMatrix();
C = initMatrix();
D = initMatrix();
A
B
C
D
=
=
=
=
createMatrix(m,
createMatrix(m,
createMatrix(1,
createMatrix(1,
size[1]);
size[3]);
size[1]);
size[3]);
// Sweep matrix
offset = size[0] - m * (processor_count - 1);
for (i = 0; i < size[0]; i++)
{
if (i < offset)
p = 0;
else p = (i - offset) / m + 1;
if (processor_rank == p)
{ // Send row
MPI_Bcast((void *)A.rows[i - i0], A.n, MPI_DOUBLE, p, MPI_COMM_WORLD
);
MPI_Bcast((void *)B.rows[i - i0], B.n, MPI_DOUBLE, p, MPI_COMM_WORLD
);
sweepMatrix(A, B, i - i0, i, A.rows[i - i0], B.rows[i - i0]);
}
else
{ // Receive
MPI_Bcast((void *)C.rows[0], C.n, MPI_DOUBLE, p, MPI_COMM_WORLD);
MPI_Bcast((void *)D.rows[0], D.n, MPI_DOUBLE, p, MPI_COMM_WORLD);
sweepMatrix(A, B, -1, i, C.rows[0], D.rows[0]);
}
}
// Send back all results to processor 0
if (processor_rank == 0)
{
// Restore original matrix sizes of A and B
A.m = size[0];
B.m = size[2];
// Receive part of B matrix f (result) rom each process
offset = A.m - m * (processor_count - 1);
for (i = 1; i < processor_count; i++)
{ MPI_Recv((void *)B.rows[offset], m*B.n, MPI_DOUBLE,
i, TAG_MATRIX_PARTITION, MPI_COMM_WORLD, &status);
offset += m;
}
// Record finish time
time1 = MPI_Wtime();
// Write result into file
writeMatrix(argv[3],B);
matrix -> n = 0;
}
/* ------------------------------------------------------------------------ */
int validMatrix (TMatrix matrix)
/* ------------------------------------------------------------------------ */
{ if ((matrix.data == NULL) || (matrix.rows == NULL) ||
(matrix.m == 0) || (matrix.n == 0))
return 0;
else return 1;
}
/* ------------------------------------------------------------------------ */
TMatrix initMatrix()
/* ------------------------------------------------------------------------ */
{ TMatrix matrix;
matrix.m = 0;
matrix.n = 0;
matrix.data = NULL;
matrix.rows = NULL;
return matrix;
}
/* ------------------------------------------------------------------------ */
void sweepMatrix (TMatrix A, TMatrix B, unsigned int pivotRow, unsigned int pivo
tCol,
double *rowA, double *rowB)
/* ------------------------------------------------------------------------ */
{ unsigned int i, j;
double d;
// Normalize row
d = rowA[pivotCol]; if (d == 0) return; // Please replace by proper error han
dling
for (j = 0; j < A.n; j++) rowA[j] /= d;
for (j = 0; j < B.n; j++) rowB[j] /= d;
// Error checking goes here!
for (i = 0; i < A.m; i++)
{ if (i == pivotRow) continue;
d = A.rows[i][pivotCol]; if (d == 0) continue; // Please replace by proper
error handling
for (j = 0; j < A.n; j++) A.rows[i][j] -= d * rowA[j];
for (j = 0; j < B.n; j++) B.rows[i][j] -= d * rowB[j];
}
}
/* ------------------------------------------------------------------------ */
void printMatrix(TMatrix A)
/* ------------------------------------------------------------------------ */
{ unsigned int i, j;
if (validMatrix(A))
fclose(fp);
return 1;
}