分段错误,使用MPI库乘以矩阵

Alb*_*nto 2 c c++ mpi segmentation-fault multidimensional-array

我正在编写一个程序,它将存储在文本文件中的两个矩阵A和B相乘,并且哪个大小可能是变体的,所以我的程序必须识别矩阵A和B的大小,确定它们是否可以相乘等.

那么这不是问题,当我将数据从主进程传递到从进程时真正的问题是,在我的程序中,我将行从主进行传递给从进程,并且行数取决于矩阵的行数和数量流程.

矩阵A按行存储,但矩阵B按列存储.

matrixA [0] ----------------

matrixA [1] ----------------

matrixA [2] ----------------

matrixB [0] matrixB [1] matrixB [2] .........

|           |         |     |
|           |         |     |
|           |         |     |    
Run Code Online (Sandbox Code Playgroud)

您可以在此处找到文本文件(用于输入):matrixA matrixB.

经过几天80的样式调试(完全不是调试器),我认为问题(我得到的分段错误是输出)是在这些代码行中(来自slave函数):

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" );
    }
}
Run Code Online (Sandbox Code Playgroud)

整个代码可以在这里找到.C中的MPI矩阵乘数

终端的输出是:

在此输入图像描述

小智 6

问题是,矩阵的类型为"double**",在"matrixAllocate"中分配.在发送和接收数据时,MPI假定buf包含数据连续作为1-d数组,但情况并非如此.(您可以通过打印出每个矩阵条目的地址轻松检查)

我认为这是C中一个着名的陷阱:指针和数组是不同的.如果矩阵是2-d数组,则所有条目都连续布局.

我的建议是将矩阵分配为1-d并且不使用multidim下标.