1

MPIプロセス間のパターン通信のようなパイプラインがあります。ここで、プロセスはパイプラインステージとして相互にメッセージを送信します。次の例は、このようなパターンで通信する3つのプロセスを示しています。

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

    //declare stage function
    void* testcall(void* d);

    int main(int args, char** argv){
        int rank, size;
        MPI_Status status;
        MPI_Init(&args,&argv);
        MPI_Comm_rank(MPI_COMM_WORLD,&rank);
        MPI_Comm_size(MPI_COMM_WORLD,&size);

        if(rank==0){ 
            int k;  
            int x[3] = {10,11,12};
            void* data = malloc(sizeof(int));             
            for( k=0 ; k< 3;k++){           
                data = &x[k];           
                MPI_Send(data,4,MPI_BYTE,1,0,MPI_COMM_WORLD);   
            }
        }

        if(rank==1){                                
            void* rcv = malloc(sizeof(int));
            void* snd = malloc(sizeof(int));
            int k;
            for( k=0 ; k< 3;k++){
                MPI_Recv(rcv,4,MPI_BYTE,0,0,MPI_COMM_WORLD,&status);              
                snd = testcall(rcv);                        
                int z = *(int *) snd;  
                printf("RCV 1: %d \n",z);
                MPI_Send(&snd,4,MPI_BYTE,2,0,MPI_COMM_WORLD);
            }
        }

        if(rank==2){
            void* rcv2 = malloc(sizeof(int));
            void* snd2 = malloc(sizeof(int));
            int k;
            for( k=0 ; k< 3;k++){
                MPI_Recv(rcv2,4,MPI_BYTE,1,0,MPI_COMM_WORLD,&status);
                snd2 = testcall(rcv2);
                int z = *(int *) snd2;
                printf("RCV 2: %d \n",z);
            }
        }

        MPI_Finalize();
        return 0;
    }

    void* testcall(void* d){
        int z = *(int *) d;
        int k = z * 2;
        void* rslt = malloc(sizeof(int));
        rslt = &k;
        return rslt;
    }

出力:

RCV1:20

RCV1:22

RCV1:24

RCV:2136566600

RCV:2136566600

RCV:2136566600

ただし、コードに1つの問題があります。プロセス0からプロセス1への送信は成功し、印刷時に正しいものを教えてください。

プロセス1からプロセス2への送信は成功したように見えますが、印刷しようとすると、予期しない数値になります(上記の出力に示されているように)。

この2つの送信の動作が異なる理由がわかりません。(どちらもvoidポインターが指す値を送信しています。2番目の送信が誤っているのはなぜですか)??

助けてください。

4

1 に答える 1

2
void* testcall(void* d){
    int z = *(int *) d;
    int k = z * 2;
    void* rslt = malloc(sizeof(int));
    rslt = &k;
    return rslt;
}

このコードはあなたが期待することをしません。この行は、ポインターrslt = &k;の値をのアドレスで上書きします(これは他のいくつかのステートメントで行います)。まず、によって割り当てられたメモリ領域のアドレスが失われるため、これによりメモリリークが発生します。第二に、その場所にある自動(スタック)変数は、戻ったときに他の目的に使用されます。との間に他の関数呼び出しが存在しないため、これはあなたの場合にのみ機能します。正しい関数は次のとおりです。rsltkmallocktestcalltestcall()int z = *(int *) snd;

void* testcall(void* d){
    int z = *(int *) d;
    int k = z * 2;
    int* rslt = malloc(sizeof(int));
    *rslt = k;
    return rslt;
}

次に、ランク1コードからのこの行:

MPI_Send(&snd,4,MPI_BYTE,2,0,MPI_COMM_WORLD);

sndポインタそのものです。ポインタのアドレスを送信しているので、ランク2は奇妙な値を出力します。正しいステートメントは次のようになります。

MPI_Send(snd,4,MPI_BYTE,2,0,MPI_COMM_WORLD);

出力:

RCV 1: 20
RCV 1: 22
RCV 1: 24
RCV 2: 40
RCV 2: 44
RCV 2: 48
于 2012-10-01T10:43:39.030 に答える