1

これは非常に奇妙な問題だと思います: 私はこのコードを持っています: サイズ チャンクと幅の 2D マトリックスを受け取ることになっています。行列は以下を使用して割り当てられます:

int **alloc2d(int n, int m) {
    int i = 0;
    int *data = malloc(n * m * sizeof(int));
    int **array = malloc(n * sizeof(int *));
    for (i = 0; i < n; i++) {
        array[i] = &(data[i * m]);
    }
    return array;
}

したがって、それは連続メモリブロックです。

私は次のコードを持っています:

MPI_Status st;
int worker;
       for(i = 1; i < size; i++) {
        MPI_Recv(&(recmat[0][0]), chunk*width, MPI_INT, MPI_ANY_SOURCE, 1,
                                 MPI_COMM_WORLD, &st);

        worker = st.MPI_SOURCE;
      /*  for(k = worker * chunk; k < (worker + 1) * chunk; k++){
            for(j = 0; j < width; j++) {
                mat[k][j] = recmat[k - worker * chunk][j];
                }
            }*/
        }

コードがこのようなものである場合、すべてが停止し、正常に動作します。リージョンのコメントを外すと:

for(k = worker * chunk; k < (worker + 1) * chunk; k++){
                for(j = 0; j < width; j++) {
                    mat[k][j] = recmat[k - worker * chunk][j];
                    }
                }

このコードを実行しているスレッドは停止しません。これについての論理的な説明が見つかりません。おそらく、誰かがエラーまたは問題を確認できます。ありがとうございました!

recmat 割り当てとチャンク計算:

int **recmat;
recmat = alloc2d(chunk,width);
int chunk;
chunk = height / size;
4

3 に答える 3

2

申し訳ありませんが、これは長すぎてコメントに収まりません:

投稿したコードは問題ありません。たとえば、実行するのに十分なコードを配置すると、正しい結果が得られます (以下)。したがって、問題はあなたが考えている場所ではありません。

ロックしてはならないはずの場所でコードがロックしている場合は、多くの場合、異常なメモリ エラーまたはその他の原因が考えられます。デバッガーを介して実行するか、valgrind などを使用してメモリの問題をチェックするのが最善です。

#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>

int **alloc2d(int n, int m) {
    int i = 0;
    int *data = malloc(n * m * sizeof(int));
    int **array = malloc(n * sizeof(int *));
    for (i = 0; i < n; i++) {
        array[i] = &(data[i * m]);
    }
    return array;
}

int main(int argc, char **argv) {

    int rank, size;
    const int height=10, width=10;

    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);

    int **recmat;
    int chunk;
    chunk = height / size;

    if (chunk*size != height) {
        fprintf(stderr, "%s: number of ranks %d does not divide size %d\n",
                     argv[0], size, height);
        MPI_Finalize();
        exit(1);
    }

    if (rank == 0) {
        int **recmat = alloc2d(chunk,width);
        int **mat = alloc2d(height,width);
        int worker;
        int i,j,k;
        MPI_Status st;

        /* deal with my own submatrix */
        for (k=0; k<chunk; k++) {
            for (j=0; j<width; j++) {
                mat[k][j] = 0;
            }
        }

        for(i = 1; i < size; i++) {
            MPI_Recv(&(recmat[0][0]), chunk*width, MPI_INT, MPI_ANY_SOURCE, 1,
                                     MPI_COMM_WORLD, &st);

            worker = st.MPI_SOURCE;
            for(k = worker * chunk; k < (worker + 1) * chunk; k++){
                for(j = 0; j < width; j++) {
                    mat[k][j] = recmat[k - worker * chunk][j];
                }
            }
        }

        free(&(recmat[0][0]));
        free(recmat);

        printf("Rank 0: mat is \n");
        for (int i=0; i<height; i++) {
            for (int j=0; j<width; j++) {
                printf("%2d ", mat[i][j]);
            }
            printf("\n");
        }

        free(&(mat[0][0]));
        free(mat);

    } else {
        int **sendmat = alloc2d(chunk,width);
        for (int i=0; i<chunk; i++)
            for (int j=0; j<width; j++)
                sendmat[i][j] = rank;

        MPI_Send(&(sendmat[0][0]), chunk*width, MPI_INT, 0, 1, MPI_COMM_WORLD);

        free(&(sendmat[0][0]));
        free(sendmat);
    }


    MPI_Finalize();

    return 0;
}
于 2012-12-17T21:02:14.853 に答える
0

私のコードには言及する価値のないほど多くのエラーやバグがありました。この役に立たない質問で申し訳ありません...

于 2012-12-17T21:17:09.927 に答える
0

こちらも長めのコメントです。最初にメッセージをプローブし、次にステータスからのランクを使用してメッセージの内容を大きなマトリックスに直接受信すると、受信データの二重コピーを防ぐことができます。

for(i = 1; i < size; i++) {
    MPI_Probe(MPI_ANY_SOURCE, 1, MPI_COMM_WORLD, &st);
    worker = st.MPI_SOURCE;
    MPI_Recv(&(mat[worker*chunk][0]), chunk*width, MPI_INT,
             worker, 1, MPI_COMM_WORLD, &st);
}

コードが少なくなり、より速く動作するはずです。

于 2012-12-18T08:35:22.977 に答える