I am writing a program that multiplies two matrices A and B which are stored in text files, and which size could be variant, so my program has to identify the size of matrix A and B, determine if they can be multiplied etc.
Well that's not the problem the real trouble is when I pass the data from master process to slave process, in my program I pass rows from master to slaves and the number of rows depends on the number of the rows of the matrix and the number of processes.
The matrix A is stored by rows, but the matrixB is stored by columns.
matrixA[ 0 ] ----------------
matrixA[ 1 ] ----------------
matrixA[ 2 ] ----------------
matrixB[ 0 ] matrixB[ 1 ] matrixB[ 2 ] .........
| | | | | | | | | | | |
You can find the text files here (for input): matrixA matrixB.
After several days of 80's style debugging (means not debugger at all), I think the problem (the segmentation fault I get as output) is in these code-lines ( from the slave function):
void slave( int id, int slaves, double **matrixA, double **matrixB, double **matrixC )
{
int type, columnsA, columnsB, rowsA, rowsB, Btype, offset, rows, averageRows, extraRows;
MPI_Status status;
/* Recieves columns of A and B from master. */
type = 3;
MPI_Recv( &columnsA, 1, MPI_INT, 0, type, MPI_COMM_WORLD, &status );
MPI_Recv( &rowsA, 1, MPI_INT, 0, type, MPI_COMM_WORLD, &status );
MPI_Recv( &columnsB, 1, MPI_INT, 0, type, MPI_COMM_WORLD, &status );
MPI_Recv( &rowsB, 1, MPI_INT, 0, type, MPI_COMM_WORLD, &status );
printf( "%d slave recieved ColumnA = %d, RowsA = %d, ColumnB = %d, RowsB = %d.\n", id, columnsA, rowsA, columnsB, rowsB );
/* Recieve from master. */
type = 0;
MPI_Recv( &offset, 1, MPI_INT, 0, type, MPI_COMM_WORLD, &status );
MPI_Recv( &rows, 1, MPI_INT, 0, type, MPI_COMM_WORLD, &status );
matrixAllocate( &matrixA, columnsA, rows );
matrixAllocate( &matrixB, rowsB, columnsB );
matrixAllocate( &matrixC, columnsB, rows );
printf( "Correctly allocated.\n" );
/* This part is only to see if the mem was correctly allocated.*/
for( int i = 0; i < rows; i++ ){
for( int j = 0; j < columnsA; j++)
matrixA[ i ][ j ] = i + j;
}
for( int i = 0; i < columnsB; i++ ){
for( int j = 0; j < rowsB; j++)
matrixB[ i ][ j ] = i * j;
}
if ( id == 1 ){
matrixPrinter( "matrixA", matrixA, rows, columnsA );
matrixBPrinter( "matrixB", matrixB, rowsB, columnsB );
matrixPrinter( "matrixC", matrixC, rows, columnsB );
}
MPI_Recv( &matrixA, ( rows * columnsA ) , MPI_DOUBLE, 0, type, MPI_COMM_WORLD, &status );
MPI_Recv( &matrixB, ( rowsB * columnsB ), MPI_DOUBLE, 0, type, MPI_COMM_WORLD, &status );
printf( "Correctly recieved.\n" );
matrixPrinter( "matrixA", matrixA, rows, columnsA );
matrixBPrinter( "matrixB", matrixB, rowsB, columnsB );
matrixPrinter( "matrixC", matrixC, rows, columnsB );
if ( id == 1 ){
printf( "My id is %d.\n", id );
for ( int i = 0; i < rows; i++ ){
for( int j = 0; j < columnsA; j++ ){
printf( "%lf ", matrixA[ i ][ j ] );
}
printf( "\n" );
}
}
The whole code can be found here. MPI matrix multiplier in C.
The output of the terminal is:
sudo -E mpirun -np 2 xterm -e "gdb test multiply A B C"
, or use Bullet 6 in these debugging FAQ – sehe