我一直在努力尝试并行计算这个计算粒子之间相互作用的函数。我有一个使用 Allgatherv 的想法,它应该将我的原始缓冲区分发给所有其他进程。然后使用“rank”创建一个循环,其中每个进程将计算它的部分。在这个程序中,MPI 被覆盖以显示统计信息,这就是我将其称为 mpi-> 函数的原因。不幸的是,当我运行它时,我收到以下错误。有人可以告诉我哪里出了问题吗?
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;
}
最佳答案
您没有正确使用 MPI_Allgatherv()
。
I had an idea to use Allgatherv which should distribute my original buffer to all other processes.
描述表明您需要 MPI_Scatter[v]()
以便从给定的等级切分您的数组,并将这些 block 分配给所有 MPI 任务。
如果所有任务都应接收完整数组,那么 MPI_Bcast()
就是您所需要的。
无论如何,我们假设您需要全体集合。
首先,您必须确保所有任务都具有相同的 particles
值。
其次,由于您从每个 MPI 任务收集相同数量的数据,并将它们存储在连续的位置,您可以使用 MPI_Allgather()
简化您的代码。如果只有最后一个任务的数据可能少一点,那么您可以使用 MPI_Allgatherv()
(但这不是您的代码当前正在执行的操作)或传输一些幻影数据,以便您可以使用简单的 (并且可能更优化)MPI_Allgather()
。
最后但同样重要的是,您应该发送 elements_per_process
元素(而不是 particle_amount
)。这应该足以摆脱崩溃(例如 MPI_ERR_TRUNCATE
)。但话虽如此,我不确定这是否会达到您需要或期望的结果。
关于c++ - MPI Allgatherv 函数出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47190698/