2012-11-22 24 views
4

我有一個靜態分配的二維數組NxN,並且我想發送i th列(使用i = 0 ... N-1)。在C中使用MPI_Type_vector接收

我寫:

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

    int myrank, nprocs; 
    int i,j; 

    int matrix[N][N]={{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}}; 
    int col[N]; 

    ... 

    // Define type "column" 
    MPI_Datatype column; 
    MPI_Type_vector(N,1,N,MPI_INT,&column); 
    MPI_Type_commit(&column); 

    if(myrank==0){ 
     j=0; 
     MPI_Send(&matrix[0][j],1,column,1,99,MPI_COMM_WORLD); 
    } 

    if(myrank==1){ 
     // **** FIRST MODE: Don't use "column" type ***** 
     MPI_Recv(col,N,MPI_INT,0,99,MPI_COMM_WORLD,&info); 

     // **** SECOND MODE: Use "column" type ***** 
     // MPI_Recv(col,1,column_INT,0,99,MPI_COMM_WORLD,&info); 

     printf("\nColumn: "); 
     for(j=0;j<N;j++) 
      printf("\n %d",col[j]); 
    } 

    MPI_Type_free(&column); 
    MPI_Finalize(); 

    return 0; 
} 

爲什麼第一種模式正確返回:

1 5 9 13 

而第二返回不正確?

1 -2 1980804601 1980804675 
+0

請接受Jonathan Dursi的回答:http://stackoverflow.com/a/13523051/281545 –

回答

5

MPI數據類型描述了數據的佈局和數據的大小。因此,舉例來說,您的列類型中的1個計數描述了N個整數,但計數N MPI_INT s也是如此。區別在於您的列類型(正確)描述了在NxN大小的數組中跳轉以提取列。使用該類型發送提取N個ints,並將它們捆綁到一條消息中。

所以當你發送時,你發送一個列類型來發送特定的N個ints,它們組成一個列。但是,當需要接收時,您仍然希望獲得N個輸入,但是您將它接收到一個連續的1d整數數組(您的col[]數組),因此您只需要接收N MPI_INT s。如果你收到一個列數據類型,你仍然會收到N個輸入,但是它們會被放入相隔N ints的內存中(事實上,如果N足夠大,你會得到一個段錯誤,因爲你寫的很好你的col數組的邊界)。這就是爲什麼當你收到一個列類型時,只有第一個數字是正確的;其餘的都是垃圾,因爲陣列的其餘部分仍未初始化。你的第二部分數據,5,將寫在你的col數組的末尾。

+0

謝謝Jonhatan!現在,我嘗試對這個論點進行一些練習。 – FedericoCappabianca

+0

+1很好的解釋。 – dreamcrash