2

テキストファイルに保存されている2つの行列AとBを乗算するプログラムを作成していますが、どちらのサイズも変化する可能性があるため、プログラムは行列AとBのサイズを識別し、それらを乗算できるかどうかを判断する必要があります。

それは問題ではありません。実際の問題は、マスタープロセスからスレーブプロセスにデータを渡すときです。私のプログラムでは、マスターからスレーブに行を渡します。行の数は、マトリックスの行の数とプロセス。

行列Aは行ごとに格納されますが、行列Bは列ごとに格納されます。

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

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

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

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

|           |         |     |
|           |         |     |
|           |         |     |    

ここにテキストファイルがあります(入力用)matrixAmatrixB

80年代のスタイルのデバッグ(デバッガーではないことを意味します)を数日行った後、問題(出力として取得するセグメンテーション違反)は次のコード行(スレーブ関数から)にあると思います。

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" );
    }
}

コード全体はここにありますCのMPI行列乗数。

端末の出力は次のとおりです。

ここに画像の説明を入力してください

4

2 に答える 2

6

問題は、マトリックスが「matrixAllocate」で割り当てられた「double**」タイプであるということです。MPIは、データを送受信するときに、bufにデータが1次元配列として継続的に含まれていると想定しますが、そうではありません(各行列エントリのアドレスを出力することで簡単に確認できます)。

これはCの有名な落とし穴だと思います。ポインタと配列が異なります。行列が2次元配列の場合、すべてのエントリが連続して配置されます。

私の提案は、行列を1-dとして割り当て、multidim添え字を使用しないことです。

于 2013-03-14T22:09:06.150 に答える
1

すべてのコードを掘り下げることなくMPI、このような回答を投稿するのは嫌ですが-Wall、将来的にはコンパイラコマンドを使用することをお勧めします。それは助けになり、このようなエラーを拾うかもしれません。MPIや計算に関連するものについては、ほとんどの場合、-Wallコンパイラコマンドが必要です。

コードからの出力と警告のリストを見てください。

$ mpic++ test.cpp -Wall -o  test
test.cpp:30:63: warning: unused variable 'rank' [-Wunused-variable]
    int lineA, lineB, columnA, columnB, id, size, rc, slaves, rank, source;
                                                              ^
test.cpp:30:69: warning: unused variable 'source' [-Wunused-variable]
    int lineA, lineB, columnA, columnB, id, size, rc, slaves, rank, source;
                                                                    ^
test.cpp:126:50: warning: variable 'matrixC' is uninitialized when used here [-Wuninitialized]
            slave( id, slaves, matrixA, matrixB, matrixC );
                                                 ^~~~~~~
test.cpp:34:21: note: initialize the variable 'matrixC' to silence this warning
           **matrixC;
                    ^
                     = NULL
test.cpp:126:41: warning: variable 'matrixB' is uninitialized when used here [-Wuninitialized]
            slave( id, slaves, matrixA, matrixB, matrixC );
                                        ^~~~~~~
test.cpp:33:21: note: initialize the variable 'matrixB' to silence this warning
           **matrixB,
                    ^
                     = NULL
test.cpp:85:44: warning: variable 'rc' is uninitialized when used here [-Wuninitialized]
                MPI_Abort( MPI_COMM_WORLD, rc );
                                           ^~
test.cpp:30:53: note: initialize the variable 'rc' to silence this warning
    int lineA, lineB, columnA, columnB, id, size, rc, slaves, rank, source;
                                                    ^
                                                     = 0
test.cpp:126:32: warning: variable 'matrixA' is uninitialized when used here [-Wuninitialized]
            slave( id, slaves, matrixA, matrixB, matrixC );
                               ^~~~~~~
test.cpp:32:21: note: initialize the variable 'matrixA' to silence this warning
    double **matrixA,
                    ^
                     = NULL
test.cpp:398:20: warning: conversion from string literal to 'char *' is deprecated [-Wdeprecated-writable-strings]
    matrixPrinter( "matrixA", matrixA, rows, columnsA );
                   ^
test.cpp:399:21: warning: conversion from string literal to 'char *' is deprecated [-Wdeprecated-writable-strings]
    matrixBPrinter( "matrixB", matrixB, rowsB, columnsB );
                    ^
test.cpp:400:20: warning: conversion from string literal to 'char *' is deprecated [-Wdeprecated-writable-strings]
    matrixPrinter( "matrixC", matrixC, rows, columnsB );
                   ^
test.cpp:407:20: warning: conversion from string literal to 'char *' is deprecated [-Wdeprecated-writable-strings]
    matrixPrinter( "matrixA", matrixA, rows, columnsA );
                   ^
test.cpp:408:21: warning: conversion from string literal to 'char *' is deprecated [-Wdeprecated-writable-strings]
    matrixBPrinter( "matrixB", matrixB, rowsB, columnsB );
                    ^
test.cpp:409:20: warning: conversion from string literal to 'char *' is deprecated [-Wdeprecated-writable-strings]
    matrixPrinter( "matrixC", matrixC, rows, columnsB );
                   ^
test.cpp:363:70: warning: unused variable 'averageRows' [-Wunused-variable]
    int type, columnsA, columnsB, rowsA, rowsB, Btype, offset, rows, averageRows, extraRows;
                                                                     ^
test.cpp:363:83: warning: unused variable 'extraRows' [-Wunused-variable]
    int type, columnsA, columnsB, rowsA, rowsB, Btype, offset, rows, averageRows, extraRows;
                                                                                  ^
test.cpp:363:49: warning: unused variable 'Btype' [-Wunused-variable]
    int type, columnsA, columnsB, rowsA, rowsB, Btype, offset, rows, averageRows, extraRows;
                                                ^
15 warnings generated.
于 2013-03-15T02:31:45.927 に答える