Mpi_Send和Mpi_Recv发送矩阵的分区,而不是分散

Mpi_Send和Mpi_Recv发送矩阵的分区,而不是分散,c,mpi,C,Mpi,我正在尝试将NxN矩阵的分区发送到不同的进程。。正如您在下面的代码中所看到的,我使用MPI_Scatterv成功地实现了这一点,但是如果我尝试使用MPI_Send和MPI_Recv来代替,则结果是一个segfault。为什么? 我看到了不同的类似问题,像这个,但没有什么变化 n = N/nprocs; n0 = n + N - n*nprocs; int counts[nprocs], displs[nprocs]; counts[0] = n0*N; displs[0] = 0; for

我正在尝试将NxN矩阵的分区发送到不同的进程。。正如您在下面的代码中所看到的,我使用MPI_Scatterv成功地实现了这一点,但是如果我尝试使用MPI_Send和MPI_Recv来代替,则结果是一个segfault。为什么? 我看到了不同的类似问题,像这个,但没有什么变化

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);
n=n/nproc;
n0=n+n-n*NPROC;
整数计数[NPROC],显示[NPROC];
计数[0]=n0*N;
显示[0]=0;

对于(i=1;i这是一个非常小的问题;虽然我没有看到变量定义,但我强烈怀疑MPI_Recv行应该是
MPI_Recv(…,COMM,&status)

但是,还有一个问题;任务应该避免向自身发送消息,并且不能向自身发出阻塞发送(例如,
MPI_send
vs.
MPI_Isend
);对于足够大的消息,该发送将死锁,任务0正在发出阻塞发送,但尚未主动接收

类似这样的方法会奏效:

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);
}
if(myid==0){

对于(i=1;i感谢您,但不幸的是没有任何更改…状态变量是指针,因此这不是问题所在,即使任务0不发送和接收任何内容,我也有SEGFULT。我认为问题出在指针缓冲区(权重或分区)中在发送或接收原语中。我知道MPI_Scatterv速度更快,但是如果我尝试在不同版本的OpenMpi上使用它,我在上面遇到了一条错误消息。您可以帮助我吗?您所说的“状态是指针”是什么意思?您是否有
MPI_status*status;
?如果这样做不起作用,它将是指向任何地方的指针。您需要
>status=malloc(sizeof(MPI_status));
,或执行
MPI_status status;
及以上操作。
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);
}