2012-01-24 3 views
0

NxN 매트릭스의 파티션을 다른 프로세스로 보내려고합니다. 아래 코드에서 볼 수 있듯이 MPI_Scatterv를 사용하여 succed했습니다.하지만 대신 MPI_Send 및 MPI_Recv를 사용하려고하면 결과가 segfault입니다. 왜? 나는이 일 MPI Matrix Multiplication with Dynamic Allocation: Seg. Fault처럼,이 서로 다른 유사한 질문을했다,하지만 아무것도 송신 및 RECV 프리미티브 사용Mpi_Send 및 Mpi_Recv가 분산 대신 매트릭스의 파티션을 전송합니다.

n = N/nprocs; 
n0 = n + N - n*nprocs; 
int counts[nprocs], displs[nprocs]; 
counts[0] = n0*N; 
displs[0] = 0; 
for(i=1;i<nprocs;i++){ 
    counts[i]=n*N; 
    displs[i]=(n0+(i-1)*n)*N; 
}  
double * weights = (double *)calloc(N*N, (sizeof(double))); 
if(myid == 0){ 
    n = n0;  
    for(i=0; i<N; i++){ 
     for(j=i; j<N; j++){ 
      if(i==j) *(weights+i*N+j) = 0; 
      else { 
       *(weights+i*N+j) = rand()/(RAND_MAX+1.0); 
       *(weights+j*N+i) = *(weights+i*N+j); 
      } 
     } 
    } 
} 
double * partition = (double *)calloc(n*N, (sizeof(double))); 
MPI_Scatterv(weights, counts, displs, MPI_DOUBLE, partition, n*N, MPI_DOUBLE, 0, COMM); 

대신 ... 변경되지 않습니다 :

if(myid==0){ 
    for(i=0; i<nprocs; i++) 
     MPI_Send(weights+displs[i], counts[i], MPI_DOUBLE, i, 0, COMM); 
} 
MPI_Recv(partition, counts[myid], MPI_DOUBLE, 0, 0, COMM, status); 

잘못 무엇입니까? 미리 감사드립니다 ... p .: 죄송합니다.

답변

0

아주 사소한 문제입니다. 변수 정의가 보이지 않지만 MPI_Recv 행은 MPI_Recv(..., COMM, &status)이어야합니다.

그러나 한 가지 더 많은 문제가 있습니다. 작업은 자신에게 메시지를 보내지 말아야하며 은 을 차단하지 말아야합니다. (예 : MPI_SendMPI_Isend)을 차단합니다. 충분히 큰 메시지의 경우 전송은 교착 상태가되며 작업 0은 차단 된 전송을 보내지 만 아직는 수신하지 않습니다. 이 같은

뭔가 작동합니다 : 실제적인 문제로서, MPI_Scatterv 최대한 빨리 또는 이상이 전송 루프보다 더 빨리해야한다는

if(myid==0){ 
    for(i=1; i<nprocs; i++) 
     MPI_Send(weights+displs[i], counts[i], MPI_DOUBLE, i, 0, COMM); 

    memcpy(weights+displs[0], partition, counts[0]*sizeof(double)); 
} else { 
    MPI_Recv(partition, counts[myid], MPI_DOUBLE, 0, 0, COMM, &status); 
} 

참고.

+0

고맙지 만 불행히도 아무것도 바뀌지 않습니다 ... 상태 변수는 포인터이므로 문제가 아니며 작업 0이 아무 것도 보내고받지 못하는 경우에도 segfault가 있습니다. 문제는 내 포인터 버퍼 (가중치 또는 파티션)의 송신 또는 수신 프리미티브에 있다고 생각합니다. 다른 버전의 OpenMpi에서 사용하려고하면 MPI_Scatterv가 빠르지 만 오류 메시지가 나타납니다. 도와 주시겠습니까? –

+0

'상태가 포인터입니까?'란 무엇을 의미합니까? 'MPI_Status * status; '가 있습니까? 그렇게해도 작동하지 않는다면 아무데도 쓸모가 없습니다. 'status = malloc (sizeof (MPI_Status));'또는'MPI_Status status;'와 같이해야합니다. –