【问题标题】:How to receive data from MPI_BCast如何从 MPI_BCast 接收数据
【发布时间】:2011-12-27 14:30:29
【问题描述】:

问题是重力相互作用。一个系统中有 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 与进程一起工作,而不是线程 btw)与其他人共享其结果? Bcast 是一对多的呼叫,而不是对所有的呼叫。
  • g.inozemtsev 的 MPI_Allgather 答案是您问题的正确答案,但您真的根本不想对生产代码采用这种方法;如果您打算将这种方法用于真实的 n 体模拟,还有其他方法可以利用更远的粒子对引力的贡献较小这一事实 - barnes-hut、快速多极方法、粒子网格等. 即使对于使用 n^2 方法的直接 nbody 计算器,它们通常也使用“流水线”类型的通信方法。

标签: mpi parallel-processing


【解决方案1】:

MPI_Bcast 会将数据从根广播到通信器中的其他等级。 MPI_Bcast 调用中的所有进程都必须使用相同的根参数,因为它们都从同一个进程接收数据。

我认为您正在寻找的功能是MPI_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_Barrier,当然除非您出于其他原因需要同步。

【讨论】:

  • +1;不过稍作修正,recvcount 是每个进程的,所以它不会是 nParticles 它会与 sendcount 相同 endForProcess-startForProcess (=numberOfParticlesPerThread)。
猜你喜欢
  • 2021-06-17
  • 2011-01-22
  • 2019-04-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-06
  • 2019-09-26
  • 2019-06-02
  • 2015-03-02
相关资源
最近更新 更多