2012-09-30 104 views
1

我有一個像MPI進程之間的模式通信管道。其中進程將消息作爲流水線階段發送給對方。 以下示例顯示了以這種模式進行通信的三個進程。爲什麼這兩個MPI發送行爲有所不同?

#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

雖然我有一個代碼問題。從進程0發送到進程1成功,並在打印時給出正確的值。

雖然從進程1發送到進程2似乎成功了,但是當我嘗試打印它時,它只是一個意外數字(如上面的輸出所示)。

我不明白爲什麼這兩個發送行爲有所不同。 (都發送一個無效指針指向的值,爲什麼第二次發送是錯誤的)?

請幫忙。

+0

有,爲什麼你使用'void'指針和'MPI_BYTE',而不是'int'和'MPI_INT'什麼特別的原因? – suszterpatt

+0

是的,我試圖使每個階段調用通用的函數。每個函數將接受void *參數並返回void * 假設是用戶將使用此原型定義一個函數,並指定輸入和輸出的字節大小。 – LeTex

回答

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

此代碼沒有達到您的預期。 rslt = &k;行將覆蓋rslt指針的地址爲k的值(並在其他幾個語句中執行此操作)。首先,這導致內存泄漏,因爲由malloc分配的內存區域的地址丟失。其次,k是一個自動(堆棧)變量在其位置將被用於其他目的,一旦testcall返回。它只適用於您的情況,因爲在testcall()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 
相關問題