【问题标题】:Mpi_Send and Mpi_Recv to send partitions of a matrix instead of scatteringMpi_Send 和 Mpi_Recv 发送矩阵的分区而不是散射
【发布时间】:2012-01-24 12:00:00
【问题描述】:

我正在尝试将 NxN 矩阵的分区发送到不同的进程。我使用 MPI_Scatterv 成功了,正如您在下面的代码中看到的那样,但如果我尝试使用 MPI_Send 和 MPI_Recv 代替,结果是段错误.为什么? 我看到了与此类似的不同问题,例如MPI Matrix Multiplication with Dynamic Allocation: Seg. Fault,但没有任何变化...

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);

改为使用 send 和 recv 原语:

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.s.:对不起我的英语!

【问题讨论】:

    标签: c mpi


    【解决方案1】:

    这是一个非常小的问题;虽然我没有看到变量定义,但我强烈怀疑 MPI_Recv 行应该是MPI_Recv(..., COMM, &amp;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);
    }
    

    请注意,实际上,MPI_Scatterv 应该与循环发送一样快或更快。

    【讨论】:

    • 谢谢你,但不幸的是没有任何改变......状态变量是一个指针,所以这不是问题,即使任务 0 没有发送和接收任何东西,我也有段错误。我认为问题出在发送或接收原语中的指针缓冲区(权重或分区)中。我知道 MPI_Scatterv 更快,但如果我尝试在不同版本的 OpenMpi 上使用它,我会遇到错误消息。你能帮帮我吗?
    • “状态是指针”是什么意思?你有MPI_Status *status;吗?如果是这样,那将不起作用,它是一个指向无处的指针。你需要status = malloc(sizeof(MPI_Status));,或者MPI_Status status;,如上。
    猜你喜欢
    • 1970-01-01
    • 2013-04-22
    • 2021-08-17
    • 2011-11-11
    • 2015-05-18
    • 1970-01-01
    • 2016-02-01
    • 1970-01-01
    • 2015-05-14
    相关资源
    最近更新 更多