2011-03-01 57 views
2
int n, j, i, i2, i3, rank, size, rowChunk, **cells, **cellChunk; 


MPI_Status status; 

MPI_Init(&argc, &argv); 
MPI_Comm_rank(MPI_COMM_WORLD, &rank); 
MPI_Comm_size(MPI_COMM_WORLD, &size); 


if(!rank){ 
    printf("\nEnter board size:\n"); 
    fflush(stdout); 
    scanf("%d", &n); 

    printf("\nEnter the total iterations to play:\n"); 
    fflush(stdout); 
    scanf("%d", &j); 


    srand(3); 

    rowChunk = n/size; //how many rows each process will get 

    for(i=1; i<size; i++){ 

     MPI_Send(&n,1, MPI_INT, i, 0, MPI_COMM_WORLD); 
     MPI_Send(&j,1, MPI_INT, i, 7, MPI_COMM_WORLD); 
    } 

    cells = (int**) malloc(n*sizeof(int*)); //create main 2D array 

    for(i=0; i<n; i++){ 

     cells[i] = (int*) malloc(n*sizeof(int)); 
    } 

    for(i=0; i<n; i++){ 
     for(i2=0; i2<n; i2++){   //fill array with random data 

      cells[i][i2] = rand() % 2; 
     } 
    }  

    for(i=1; i<size; i++){  //send blocks of rows to each process 
     for(i2=0; i2<rowChunk; i2++){ //this works for all n 

      MPI_Send(cells[i2+(rowChunk*i)], n, MPI_INT, i, i2, MPI_COMM_WORLD); 
     } 
    } 

    cellChunk = (int**) malloc(rowChunk*sizeof(int*)); 

    for(i=0; i<rowChunk; i++){ //declare 2D array for process zero's array chunk 

     cellChunk[i] = (int*) malloc(n*sizeof(int)); 
    } 

    for(i=0; i<rowChunk; i++){ //give process zero it's proper chunk of the array 
     for(i2=0; i2<n; i2++){ 

      cellChunk[i][i2] = cells[i][i2]; 
     } 
    } 


    for(i3=1; i3<=j; i3++){ 

     MPI_Send(cellChunk[0], n, MPI_INT, size-1,1,MPI_COMM_WORLD); //Hangs here if n >256 
     MPI_Send(cellChunk[rowChunk-1], n, MPI_INT, 1,2,MPI_COMM_WORLD); //also hangs if n > 256 

      ... //Leaving out code that works 

此代碼的工作完全如果n(數組大小)小於或等於256的任何更大,它掛在第一MPI_SEND。另外,當向其他進程發送數組行塊時(第一MPI_Send),其他進程完全接收它們的數據,即使n> 256。如果緩衝區大小超過256,什麼會導致這個MPI_Send掛起?第二MPI_SEND懸掛如果緩衝器大小超過256

+0

你能發表完整的代碼嗎?我沒有看到您發佈的代碼段的任何問題。 – powerrox 2011-07-13 22:09:49

回答

6

您從未收到任何消息,因此代碼將填充本地MPI緩衝區空間,然後發生死鎖,等待要運行的MPI_Recv(或類似的)調用。您將需要插入接收操作,以便您的消息實際上將在接收器上發送和處理。 「

+0

代碼不完整。 MPI_Send僅由根調用。他在最後一行中看到了代碼的其餘部分。您可能想要重述您的答案。 – powerrox 2011-07-13 22:07:26

0

MPI_Send」可能會阻塞,直到收到消息。「,所以最有可能是未達到匹配接收。您需要確保MPI_Recv按照正確的順序排列。由於您沒有發佈您的接收部分,因此無法告訴詳細信息。

您可以重組您的應用程序,以確保匹配接收的順序。您也可以使用組合的MPI_Sendrecv或非阻塞MPI_IsendMPI_IrecvMPI_Wait

1

MPI_Send是一個阻塞呼叫。標準要求MPI_Send可以在消息緩衝區中儘可能早地返回控制權,這可以安全地修改。或者,MPI_Send可以等待返回,直到MPI_Recv開始或完成後的某段時間。

如果郵件是< 256 count(使用MPI_INT數據類型,這將是1k郵件),則您正在使用的MPI的實施可能會執行「熱切」的郵件進程。該消息被複制到另一個緩衝區,並且控件將「提前」返回。對於大型(r)消息,MPI_Send調用不會返回,直到(至少)執行匹配的MPI_Recv調用。

如果您發佈一個完整的重現器,您可能會得到一個更好的答案。