2016-03-01 33 views
1

我一直在嘗試學習MPI。當我嘗試運行下面的代碼時,我得到了錯誤的輸出。不能通過MPI_send發送整個矢量

if (world_rank == 0){ 

    vector<vector<double> > n(4,vector<double>(4)); 

    srand(time(NULL)); 

    for(int i=0; i<4 ;i++){ 
     for(int j=0;j<4;j++){ 
      n[i][j] = (double)rand()/RAND_MAX; 
      cout << n[i][j] << " "; 
     } 
     cout << endl; 
    } 
    MPI_Send((void*)&n[0][0],16*sizeof(double),MPI_BYTE,1,0,MPI_COMM_WORLD); 
}else{ 
    MPI_Status status; 

    vector<vector<double> > n(4,vector<double>(4)); 

    MPI_Probe(0,0,MPI_COMM_WORLD,&status); 

    int size; 

    MPI_Get_count(&status,MPI_BYTE,&size); 

    cout << endl << size << endl; 

    MPI_Recv((void*)&n[0][0],16*sizeof(n[0][0]),MPI_BYTE,0,0,MPI_COMM_WORLD,MPI_STATUS_IGNORE); 

    cout.flush(); 
    cout << endl; 

    for(int i=0; i<4 ;i++){ 
     for(int j=0;j<4;j++){ 
      cout << n[i][j] << " "; 
     } 
     cout << endl; 
    } 
} 

我得到除了最後3個以外的所有雙值。 這樣。

0.824468 0.752417 0.757125 0.470763 
0.251683 0.703306 0.157991 0.764423 
0.815327 0.0402807 0.897109 0.313816 
0.997203 0.796665 0.0522305 0.797733 

128 

0.824468 0.752417 0.757125 0.470763 
0.251683 0.703306 0.157991 0.764423 
0.815327 0.0402807 0.897109 0.313816 
0.997203 0 0 0 

誰能告訴我爲什麼會發生這種情況? 我跑來跑去一百倍相同的代碼,仍然可以得到相同的輸出(當然使用不同的值),但最後三個始終爲0

,但是當我從16改變了大小19我得到的所有值。

我也有另一個疑問。有些時候輸出(來自節點0和1的值)會重疊。任何人都可以告訴我如何阻止或至少解釋爲什麼會發生這種情況。我的意思是即使發送和recv阻塞功能。節點1的輸出如何在節點0之前打印

回答

3

您將2D數據n定義爲vector<vector<double> >使其在內存中不連續。因此,你不能簡單地使用MPI來傳輸它(有辦法做到這一點,但你最好只是使內存連續)。

爲了使您的連續內存,你可以宣佈你的n這樣的(未測試):

vector<double> ndata(4*4); //contiguous storage of the actual data 
vector<double*> n(4);  //vector of pointers to access the actual data 
for (int i=1; i<4; i++) //initialisation of the pointers to the data 
    n[i] = &ndata[4*i]; 

當然,也有定義在C++多維數組連續存儲的更好的方法,但這是隻是解決您的緊急問題。例如參見this answer以獲得更好的結構。

而且順便說一句,你MPI_Send()MPI_Recv()調用應採用的4*4MPI_DOUBLE代替4*4*sizeof(double)MPI_BYTE

+0

謝謝,我知道了,我只是在試驗它。你能告訴我關於我問的另一件事(這就是爲什麼兩個節點的輸出在屏幕上重疊的原因)。有沒有辦法阻止它。我知道這兩個節點可能在不同時間位於代碼的不同部分,但是由於send和recv命令都是阻塞的。如何在發送之前先打印某些內容後才能寫入內容。如果你能回答這個問題,我可以安息。謝謝。 –

+0

對於交錯打印,這只是各種進程之間競態條件的問題,以及操作系統緩衝輸出的問題。有關更多詳細信息,請參閱[this](http://stackoverflow.com/a/33665044/5239503) – Gilles

+0

我閱讀了您的鏈接。我知道那一部分。但正如所說的,我需要某種互相排斥或障礙來控制權利?這就是發生在這裏的事情。我在發送數據之前打印,然後在收到後再打印。所以只有在節點0打印後我纔會發送數據(在節點1保持阻塞期間),並且在節點1接收數據之後,它可以打印發送的數據。但有時我會在節點0打印之前獲取已發送的數據。 –