在 Jupyter notebook 中使用 `mpirun`

Using `mpirun` within a Jupyter notebook

我有一个简单的 C/MPI 代码:

/* File: demo.c */
#include <stdio.h>
#include <mpi.h>

void main(int argc, char** argv)
{
    int my_rank,nprocs;
    MPI_Init(&argc, &argv);
    MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
    MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
    printf("Processor [%d] : Hello, World! (world=%d processor(s))\n",my_rank,nprocs);
    MPI_Finalize();
}

当我在交互式 Python shell 中 运行 时,我得到了预期的输出:

In [1]: !mpirun -n 4 demo
Processor [1] : Hello, World! (world=4 processor(s))
Processor [3] : Hello, World! (world=4 processor(s))
Processor [2] : Hello, World! (world=4 processor(s))
Processor [0] : Hello, World! (world=4 processor(s))

In [2]: 

但是,当我 运行 在 Jupyter notebook 中执行相同的命令时,我得到了四个串行作业:

是否有更好的方法从笔记本中调用 mpirun 脚本?我试过 %%bash 魔术和子流程,但它们产生了相同的结果。

我对 运行ning 来自笔记本的 MPI 代码很感兴趣,作为一种收集 运行 时间数据进行存储和显示的简单方法。我对编写并行 Python 程序不太感兴趣。

我正在 运行宁 Python 3.6.3 (Anaconda),在 OSX 10.13.2

(部分)答案如下。由于我不完全理解的原因,Jupyter notebook 和交互式 shell 使用不同的搜索路径来查找 mpirun

在 IPython 中:

In [1]: !type mpirun
mpirun is /opt/local/bin/mpirun

但是在笔记本中,我有:

在 bash 提示符下使用此版本的 mpirun,我得到:

(bash) $ /usr/local/Anaconda3/bin/mpirun -n 4 demo
Processor [0] : Hello, World! (world=1 processor(s))
Processor [0] : Hello, World! (world=1 processor(s))
Processor [0] : Hello, World! (world=1 processor(s))
Processor [0] : Hello, World! (world=1 processor(s))

运行笔记本上的正确版本,我得到了预期的结果。

我发现这两个版本(OpenMPI,由 Anaconda 安装)和 MPICH(由 MacPorts 安装)不兼容。使用一个版本的 mpicc 进行编译,而使用另一个版本的 mpirun 运行 似乎不是一个好主意。

感谢@jakevdp blog post 为我指明了正确的方向!