【问题标题】:Trouble with MPI Allgatherv functionMPI Allgatherv 功能出现问题
【发布时间】:2018-04-21 18:56:08
【问题描述】:

我一直在努力尝试并行计算粒子之间相互作用的这个函数。我有一个使用 Allgatherv 的想法,它应该将我的原始缓冲区分配给所有其他进程。然后使用“rank”创建一个循环,其中每个进程将计算其部分。在这个程序中,MPI 被覆盖以显示统计信息,这就是我称之为 mpi->function 的原因。不幸的是,当我运行它时,我收到以下错误。有人可以建议什么问题吗?

void calcInteraction() {
    totalInteraction = 0.0;
    int procs_number;
    int rank;
    int particle_amount = particles;

    mpi->MPI_Comm_size(MPI_COMM_WORLD,&procs_number);
    mpi->MPI_Comm_rank(MPI_COMM_WORLD,&rank);
    //long sendBuffer[particle_amount];
    //int *displs[procs_number];
    //long send_counts[procs_number+mod];
    int mod = (particle_amount%procs_number);
    int elements_per_process = particle_amount/procs_number;
    int *send_buffer = new int[particle_amount]; //data to send
    int *displs = new int[procs_number]; //displacement
    int *send_counts = new int[procs_number];

    if(rank == 0)
    {
        for(int i = 0; i < particle_amount; i++)
        {
            send_buffer[i] = i; // filling buffer with particles
        }
    }
    for (int i = 0; i < procs_number;i++)
    {
        send_counts[i] = elements_per_process; // filling buffer since it can't be empty
    }

    // calculating displacement
    displs[ 0 ] = 0;
    for ( int i = 1; i < procs_number; i++ )
        displs[ i ] = displs[ i - 1 ] + send_counts[ i - 1 ];
    int allData = displs[ procs_number - 1 ] + send_counts[ procs_number - 1 ];

    int * endBuffer = new int[allData];

    int start,end; // initializing indices

    cout<<"entering allgather"<<endl;
    mpi->MPI_Allgatherv(send_buffer,particle_amount,MPI_INT,endBuffer,send_counts,displs,MPI_INT,MPI_COMM_WORLD);
    //                   ^from      ^how many        ^send   ^receive  ^how many  ^displ ^send    ^communicator
    //                               to  send         type    buffer    receive           type
    start = rank*elements_per_process;
    cout<<"start = "<< start <<endl;
    if(rank == procs_number) //in case that particle_amount is not even
    {
        end = (rank+1)*elements_per_process + mod;
    }
    else
    {
        end = (rank+1)*elements_per_process;
    }

    cout<<"end = "<< end <<endl;
    cout << "calcInteraction" << endl;

        for (long idx = start; idx < end; idx++) {
            for (long idxB = start; idxB < end; idxB++) {
                if (idx != idxB) {
                    totalInteraction += physics->interaction(x[idx], y[idx], z[idx], age[idx], x[idxB], y[idxB],
                                                             z[idxB], age[idxB]);
                }
            }
        }



    cout << "calcInteraction - done" << endl;
}

【问题讨论】:

    标签: c++ mpi


    【解决方案1】:

    你没有正确使用MPI_Allgatherv()

    我想使用 Allgatherv 来分发我的原件 缓冲到所有其他进程。

    该描述建议您需要MPI_Scatter[v]() 才能从给定等级分割您的数组,并将块分配给所有 MPI 任务。 如果所有任务都应该收到完整的数组,那么MPI_Bcast() 就是您所需要的。

    无论如何,让我们假设你需要一个全集。

    首先,您必须确保所有任务都具有相同的particles 值。

    其次,由于您从每个 MPI 任务中收集相同数量的数据,并将它们存储在一个连续的位置,您可以使用 MPI_Allgather() 简化您的代码。如果只有最后一个任务的数据可能少一点,那么您可以使用MPI_Allgatherv()(但这不是您的代码当前正在执行的操作)或传输一些幽灵数据,以便您可以使用简单的(并且可能更优化)@987654327 @。

    最后但同样重要的是,您应该发送elements_per_process 元素(而不是particle_amount)。这应该足以摆脱崩溃(例如MPI_ERR_TRUNCATE)。但话虽如此,我不确定这会达到您需要或期望的结果。

    【讨论】:

      猜你喜欢
      • 2021-03-18
      • 1970-01-01
      • 1970-01-01
      • 2017-03-23
      • 1970-01-01
      • 2017-08-12
      • 1970-01-01
      • 2021-10-27
      • 2021-04-30
      相关资源
      最近更新 更多