如何从MPI_BCast接收数据

如何从MPI_BCast接收数据,mpi,parallel-processing,Mpi,Parallel Processing,问题在于重力作用。一个系统中有N个粒子,M个过程。 我想计算当前进程中单个块中粒子的新位置(总共有11个参数),然后向所有其他进程广播新数据。 这是我的密码: double * particles; ... int startForProcess = numberOfParticlesPerThread * 11 * rank; int endForProcess = startForProcess + numberOfParticlesPerThread * 11; calculateNewP

问题在于重力作用。一个系统中有N个粒子,M个过程。 我想计算当前进程中单个块中粒子的新位置(总共有11个参数),然后向所有其他进程广播新数据。 这是我的密码:

double * particles;
...
int startForProcess = numberOfParticlesPerThread * 11 * rank;
int endForProcess = startForProcess + numberOfParticlesPerThread * 11;
calculateNewPosition(particles, startForProcess, endForProcess, nParticles, rank);
MPI_Barrier(MPI_COMM_WORLD);
MPI_Bcast(particles+startForProcess, endForProcess - startForProcess, MPI_DOUBLE, rank, MPI_COMM_WORLD);
不幸的是,在每个线程中,我都能看到仅在这个线程中进行的更改。进程之间没有通信


请告诉我,我做错了什么?

MPI\u Bcast
将从根目录向通信器中的其余列组广播数据。
MPI\u Bcast
调用中的所有进程都必须使用相同的根参数,因为它们都从同一进程接收数据

我认为您正在寻找的函数是
MPI\u Allgather
。它将在所有进程中收集和传播更新的数据

代码可能如下所示:

double * particles;
double * my_particles;
...
int startForProcess = numberOfParticlesPerThread * 11 * rank;
int endForProcess = startForProcess + numberOfParticlesPerThread * 11;
calculateNewPosition(particles, startForProcess, endForProcess, nParticles, rank);

memcpy(my_particles, particles + startForProcess * sizeof(double),
       (endForProcess - startForProcess) * sizeof(double));
MPI_Allgather(my_particles, endForProcess - startForProcess, MPI_DOUBLE,
              particles, endForProcess - startForProcess, MPI_DOUBLE, MPI_COMM_WORLD);

另一方面,在集体调用之前,您不需要使用
MPI\u屏障
,当然,除非您出于其他原因需要同步。

MPI\u Bcast
将从根目录向通信器中的其余列组广播数据。
MPI\u Bcast
调用中的所有进程都必须使用相同的根参数,因为它们都从同一进程接收数据

我认为您正在寻找的函数是
MPI\u Allgather
。它将在所有进程中收集和传播更新的数据

代码可能如下所示:

double * particles;
double * my_particles;
...
int startForProcess = numberOfParticlesPerThread * 11 * rank;
int endForProcess = startForProcess + numberOfParticlesPerThread * 11;
calculateNewPosition(particles, startForProcess, endForProcess, nParticles, rank);

memcpy(my_particles, particles + startForProcess * sizeof(double),
       (endForProcess - startForProcess) * sizeof(double));
MPI_Allgather(my_particles, endForProcess - startForProcess, MPI_DOUBLE,
              particles, endForProcess - startForProcess, MPI_DOUBLE, MPI_COMM_WORLD);

顺便说一句,在集体调用之前,您不需要
MPI\u屏障
,当然,除非您出于其他原因需要同步。

让我澄清一下:您希望每个进程(MPI与进程一起工作,而不是线程一起工作)与其他人共享其结果吗
Bcast
是一个一对所有的调用,而不是一对所有的调用。g.inozemtsev提供的MPI_Allgather答案是对您的问题的正确答案,但您确实不想在生产代码中使用这种方法;如果你打算在真实的n体模拟中使用这种方法,还有其他方法可以利用距离越远的粒子对引力的贡献越小的事实-巴恩斯小屋、快速多极方法、粒子网格等。即使是使用n^2方法的直接n体计算器,它们也通常使用“流水线”输入communications方法。让我直截了当地说:您希望每个进程(MPI与进程一起工作,而不是线程,顺便说一句)与其他所有人共享其结果吗
Bcast
是一个一对所有的调用,而不是一对所有的调用。g.inozemtsev提供的MPI_Allgather答案是对您的问题的正确答案,但您确实不想在生产代码中使用这种方法;如果你打算在真实的n体模拟中使用这种方法,还有其他方法可以利用距离越远的粒子对引力的贡献越小的事实-巴恩斯小屋、快速多极方法、粒子网格等。即使是使用n^2方法的直接n体计算器,它们也通常使用“流水线”类型通信方法+1;不过稍微更正一下,recvcount是每个进程的,因此它不会是
nParticle
,而是与sendcount相同的
endForProcess startForProcess
(=
numberOfParticlesPerThread
)。+1;不过稍微更正一下,recvcount是每个进程的,因此它不会是nParticle,而是与sendcount相同的进程启动或进程(=
numberOfParticlesPerThread
)。