3. 多进程并行 (MPI)#
在终端使用 mpiexec -n <np>
运行 python 文件即可:
mpiexec -n 2 python myscript.py
3.1. Run code parallelly in jupyter#
我们使用 ipyparallel
介绍并行程序的一些内容, 需要先安装 ipyparallel
3.1.1. Install ipyparallel#
Install ipyparallel in firedrake env:
pip install ipyparallel
create profile mpi
ipython profile create --parallel --profile=mpi
Your will see the following output
[ProfileCreate] Generating default config file: PosixPath('/home/<your-user-name>/.ipython/profile_mpi/ipython_config.py') [ProfileCreate] Generating default config file: PosixPath('/home/<your-user-name>/.ipython/profile_mpi/ipython_kernel_config.py') [ProfileCreate] Generating default config file: PosixPath('/home/<your-user-name>/.ipython/profile_mpi/ipcontroller_config.py') [ProfileCreate] Generating default config file: PosixPath('/home/<your-user-name>/.ipython/profile_mpi/ipengine_config.py') [ProfileCreate] Generating default config file: PosixPath('/home/<your-user-name>/.ipython/profile_mpi/ipcluster_config.py')
Edit file
.ipython/profile_mpi/ipengine_config.py
. Add the following code at the begining of the file:from firedrake import * from firedrake.petsc import PETSc
Set the default engines to mpi in file
.ipython/profile_mpi/ipcluster_config.py
. You can searchengine_launcher_class
in the file, and the result file should looks like this:# - sshproxy: ipyparallel.cluster.launcher.SSHProxyEngineSetLauncher # - winhpc: ipyparallel.cluster.launcher.WindowsHPCEngineSetLauncher # Default: 'ipyparallel.cluster.launcher.LocalEngineSetLauncher' c.Cluster.engine_launcher_class = 'mpi'
Test:
import ipyparallel as ipp import os cluster = ipp.Cluster(profile="mpi", n=2) client = cluster.start_and_connect_sync()
The output should looks like
Starting 2 engines with <class 'ipyparallel.cluster.launcher.MPIEngineSetLauncher'>
%%px --block from firedrake import * from firedrake.petsc import PETSc from mpi4py import MPI mesh = RectangleMesh(8, 8, 1, 1) PETSc.Sys.syncPrint(mesh.comm.rank, mesh.comm.size) PETSc.Sys.syncFlush()
The output should looks like:
[stdout:0] 0 2 1 2
3.1.2. Example#
import ipyparallel as ipp
import os
cluster = ipp.Cluster(profile="mpi", n=2)
client = cluster.start_and_connect_sync()
Starting 2 engines with <class 'ipyparallel.cluster.launcher.MPIEngineSetLauncher'>
%%px --block
from firedrake import *
from firedrake.petsc import PETSc
from mpi4py import MPI
mesh = RectangleMesh(8, 8, 1, 1)
PETSc.Sys.syncPrint(mesh.comm.rank, mesh.comm.size)
PETSc.Sys.syncFlush()
[stdout:0] 0 2
1 2
%%px --block
PETSc.Sys.syncPrint(COMM_WORLD.rank, COMM_WORLD.size)
PETSc.Sys.syncFlush()
[stdout:0] 0 2
1 2
有些时候需要在某个进程上, 做指定的操作或运算, 如只在第0个进程上画图
if COMM_WORLD.rank == 0:
plot(...)
3.2. 并行输出#
%%px --block
from firedrake import *
from firedrake.petsc import PETSc
from mpi4py import MPI
PETSc.Sys.Print('This is first line (from rank 0)')
[stdout:0] This is first line (from rank 0)
%%px --block
PETSc.Sys.syncPrint('This is second line (from all rank)')
PETSc.Sys.syncFlush()
[stdout:0] This is second line (from all rank)
This is second line (from all rank)
%%px --block
print('This msg from all rank')
[stdout:0] This msg from all rank
[stdout:1] This msg from all rank