1

私の問題は非常に単純です。MPI_Sendrecvを使用すると、体系的にsegfaultが生成されます。以前、2D配列と基本的なMPI_Sendを使用して同じ問題が発生しましたが、最終的には解決しました。最後のケースで機能するのと同じソリューションを試したので、これは何も変わりませんでした。したがって、私は助けを求めています!

したがって、基本的に、このコードですべての行列を割り当てます。

    double**
    allocateMatrix(int rows, int cols)
    {
        double **M; // Row pointer
        double *Mdata; // Where data will be actually storde

        M = calloc(rows, sizeof *M);
        Mdata = calloc(rows*cols, sizeof(double));

        int i;
        for (i = 0; i < rows; ++i) 
            M[i] = Mdata+ i*rows;

        return M;
    }

MPI_Sendrecvは連続していないデータでは機能しないはずだと読んだので、これを行いました...

エラーが発生する場所は次のとおりです。

    double **submtx;
    submtx = allocateMatrix(submtx_dim, submtx_dim);

    /* 
    ...
    */

    MPI_Sendrecv(&(submtx[0][0]), 1, left_col, neighbours[0], LEFT_COL,
                 &tmp_rcol, SUB_MTX_SIZE, MPI_DOUBLE, neighbours[0], RIGHT_COL,
                 my_grid, MPI_STATUS_IGNORE);

エラーがMPI_Sendrecvに与えられた最初の引数の構文に起因することをテストしたことで私は知っています。MPIサブアレイとグリッドに加えてシフトを使用してネイバーをグリッドに配置しますが、このコードは、Send/Recvを個別に使用する基本バージョンですでに機能しています。唯一の変更点は、コードを単純化するためにSend / recv呼び出しをMPI_Sendrecv呼び出しに置き換えたことです。したがって、コード全体が必要になるとは思いません。

何か案は ?

私は試した :

    MPI_Sendrecv(&submtx, ...
    MPI_Sendrecv(submtx, ...

それはどれも機能せず、私はまだこのラインでセグメンテーション違反を起こします。

4

2 に答える 2

0

MPI_Sendrecvは、最初のパラメーターとしてデータのバッファーへのポインターを想定しています(void *)

http://www.mcs.anl.gov/research/projects/mpi/www/www3/MPI_Sendrecv.html

だから、これを試してみてください

double* // pointer to double (not pointer to pointer)
    allocateMatrix(int rows, int cols)
    {
        return calloc(rows * cols, sizeof(double));
    }

じゃあ後で

double *submtx;
submtx = allocateMatrix(submtx_dim, submtx_dim);

/* 
...
*/

MPI_Sendrecv(submtx,....

コメントされた領域がマトリックスに何かを書き込んでいると思います...

行rと列cの値にアクセスするには、これを実行します

smbmtx[c + r * submtx_dim] = 1.234;
于 2013-01-02T22:58:17.373 に答える
0

結局のところ、私はセグメンテーション違反を取り除きました。私の質問で書かれた構文は実際には良かったです、&(submtx [0] [0])は問題ではありませんでした...この投稿で指摘されているように、submtx [0]も機能しています(MPI_Type_create_subarrayとMPI_Send)。

これは実際には少し注意が必要です。実際の問題の前にいくつかの愚かなことをしなければならないことを除いて、実際の問題はまったくないからです。

コードが機能しない:

    MPI_Barrier(my_grid);

    do {

        MPI_Sendrecv(&(submtx[0][0], ...)

        /*
        ...
        */

    } while (cond);

および作業コード:

    MPI_Barrier(my_grid);

    double *stupid_allocation;
    stupid_allocation = calloc(submtx_dim*submtx_dim, sizeof(double));

    do {

        MPI_Sendrecv(&(submtx[0][0]), ...)

        /*
        ...
        */

    } while (cond);

問題が最終的に修正されたことを嬉しく思いますが、とにかく問題の答えを取得したいと思います。つまり、「役に立たない割り当て(または私が推測する他のもの)を削除すると、なぜそれが機能しないのですか? ??

于 2013-01-03T10:36:19.850 に答える