2011-03-01 4 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에서 중단됩니다. 또한, 경우는 N> (256)는 버퍼 사이즈가 256 이상이면 그냥 MPI_Send 멈춘 어떤 원인이 되더라도, 다른 프로세스 완벽 데이터를 수신 (MPI_Send 제), 다른 방법으로 배열 행 청크를 전송?버퍼 크기가 256을 넘으면 두 번째 MPI_Send가 걸려 있습니다.

+0

전체 코드를 게시 할 수 있습니까? 내가 게시 한 스 니펫에 문제가 보이지 않습니다. – powerrox

답변

6

메시지가 전혀 수신되지 않으므로 코드가 로컬 MPI 버퍼 공간을 채운 다음 MPI_Recv (또는 비슷한) 호출이 실행될 때까지 대기합니다. 메시지가 실제로 수신자에서 전송되고 처리되도록 수신 조작을 삽입해야합니다.

+0

코드가 불완전합니다. MPI_Send는 루트에 의해서만 호출됩니다. 마지막 줄에서 볼 수 있듯이 나머지 코드는 생략했습니다. 당신은 답을 다시 말해야 할 수도 있습니다. – powerrox

0

MPI_Send "는 메시지가 수신 될 때까지 차단된다."는 매칭에 도달하지 못한 가능성 그래서. MPI_Recv이 올바른 순서로 배치되어 있는지 확인해야합니다. 귀하가 수신 한 부분을 게시하지 않았으므로 세부 사항을 말할 수 없습니다.

당신은 확실히 일치가 순서대로 수신하려면 응용 프로그램을 재구성 할 수있다. 당신이 결합 된 MPI_Sendrecv 또는 비 블로킹 MPI_Isend, MPI_IrecvMPI_Wait을 사용하는 것도 편리 할 수 ​​있습니다.

1

MPI_Send는 차단 호출입니다. 표준은 메시지 버퍼가 안전하게 수정 될 수 있기 때문에 MPI_Send가 컨트롤을 조기에 반환 할 수 있도록 요구합니다. 또는 MPI_Send는 MPI_Recv가 시작되거나 완료된 후 어느 정도 시간이 될 때까지 기다릴 수 있습니다.

메시지가 < 256 카운트 (MPI_INT 데이터 유형의 경우 1K 메시지) 인 경우 사용중인 MPI의 구현이 "열망하는"메시지 진행을 수행 할 가능성이 큽니다. 메시지가 다른 버퍼에 복사되고 컨트롤이 "일찍"반환됩니다. 큰 (r) 메시지의 경우 MPI_Send 호출은 (적어도) 일치하는 MPI_Recv 호출이 실행될 때까지 반환되지 않습니다.

당신이 완전한 재생기를 게시 할 경우, 당신은 가능성이 더 나은 해답을 얻을 것이다.

관련 문제