2015-10-04 127 views
-2

所以,這是我的任務。我應該在主進程中讀K - 1三元組(K - 是進程的數量)。三聯由兩個整數號碼和一個一。我必須使用MPI_Pack和一個集合操作將這個三元組發送到其他進程。但是,當使用MPI_Pack我得到一個錯誤:無效的緩衝區指針。 這是我的代碼:MPI_Pack:緩衝區指針無效

int flag; 
    MPI_Initialized(&flag); 
    if (flag == 0) 
     return; 
    int rank, size; 
    MPI_Comm_size(MPI_COMM_WORLD, &size); 
    MPI_Comm_rank(MPI_COMM_WORLD, &rank); 

    int* intbuf = new int[2]; 
    double doublebuf; 
    byte* rbuf = new byte[(size - 1)*(2 * sizeof(int)+sizeof(double))]; 
    if (rank == 0) { 
     int pos = 0; 
     for (int i = 0; i < size - 1; ++i){ 
      pt >> intbuf[1] >> intbuf[2] >> doublebuf; //pt is from the special library and it's okay 
      MPI_Pack(intbuf, 2, MPI_INT, rbuf, sizeof(int)* 2, &pos, MPI_COMM_WORLD); 
      MPI_Pack(&doublebuf, 1, MPI_DOUBLE, rbuf, sizeof(double), &pos, MPI_COMM_WORLD); 
     } 
    } 

    MPI_Bcast(rbuf, sizeof(rbuf), MPI_PACKED, 0, MPI_COMM_WORLD); 

    if (rank != 0){ 
     int pos = 0; 
     for (int i = 0; i < size - 1; ++i){ 
      MPI_Unpack(rbuf, sizeof(int)* 2, &pos, intbuf, 2, MPI_INT, MPI_COMM_WORLD); 
      MPI_Unpack(rbuf, sizeof(double), &pos, &doublebuf, 1, MPI_DOUBLE, MPI_COMM_WORLD); 
      pt << intbuf[1] << intbuf[2] << doublebuf; 
     } 

    } 

我在做什麼worng?

回答

0

所以我剛剛解決了我的錯誤。包裝數據時發生錯誤:第一個MPI_Pack並不意味着您打包的數據量多少,這意味着您的緩衝區大小(在我的情況下緩衝區是rbuf),第二個參數MPI_Unpack具有相同的語義。 這是固定的代碼。有用。

int* intbuf = new int[2]; 
    double doublebuf; 
    int N = (size - 1)*(2 * sizeof(int)+sizeof(double)); 
    byte* rbuf = new byte[N]; 
    int pos = 0; 
    if (rank == 0) { 
     for (int i = 0; i < size - 1; ++i){ 
      pt >> intbuf[0] >> intbuf[1] >> doublebuf; 
      MPI_Pack(intbuf, 2, MPI_INT, rbuf, N, &pos, MPI_COMM_WORLD); 
      MPI_Pack(&doublebuf, 1, MPI_DOUBLE, rbuf, N, &pos, MPI_COMM_WORLD); 
     } 
    } 
    MPI_Bcast(rbuf, N, MPI_PACKED, 0, MPI_COMM_WORLD); 

    if (rank != 0){ 
     int pos = 0; 
     for (int i = 0; i < size - 1; ++i){ 
      int* intbuf_out = new int[2]; 
      double doublebuf_out; 
      MPI_Unpack(rbuf, N, &pos, intbuf_out, 2, MPI_INT, MPI_COMM_WORLD); 
      MPI_Unpack(rbuf, N, &pos, &doublebuf_out, 1, MPI_DOUBLE, MPI_COMM_WORLD); 
      pt << intbuf_out[0] << intbuf_out[1] << doublebuf_out; 
      delete(intbuf_out); 
     } 

    } 
3

的主要問題來源於此行:

MPI_Bcast(rbuf, sizeof(rbuf), MPI_PACKED, 0, MPI_COMM_WORLD); 

更具體地說,它來自sizeof(rdbuf)應由pos更換。事實上,sizeof(rdbuf)是一個sizeof(byte*),根據你的操作系統可能是4或8,但這與你嘗試傳輸的數據的大小無關......這個固定的,你的代碼可能「工作」。

然而,這仍然有很多問題:

  1. 您分配帶有某種任意大小的,這使得很沒有意義的包裝緩衝。通常,要知道你需要打包多少數據,你應該使用MPI_Pack_size()
  2. 爲什麼你要在第一時間使用MPI_Pack()?這個函數是一種來自PVM(即並行虛擬機)的傳統,它是一個消息傳遞庫預先存在的MPI。此功能的目的是簡化從PVM到MPI的轉換,但肯定不會用於從頭開發。

爲了解決您的問題,我鼓勵您或者打電話給2個不同的MPI_Bcast(),其中一個使用2個整數,另一個使用雙精度。這非常簡單直接。

另一個(如果可擴展性更好)可能性是創建一個包含int和double的結構,並使用MPI_Type_create_struct()創建匹配的MPI結構類型。

無論如何,祝你的代碼好運。

+0

非常感謝這樣一個詳細的答案。我對MPI是一個新手。但有一點點不同的錯誤(我剛剛回答我自己的問題來解釋它)。 –

+1

@ O.Phillips主要錯誤是堅持使用MPI_Pack。 –