While these tutorials are typically meant to be visualized in serial, viskex
also runs in parallel. To exemplify this, we will show a parallel case using ipyparallel
.
First of all, we start a ipyparallel
MPI cluster with 2 processes.
import ipyparallel as ipp
cluster = ipp.Cluster(engines="MPI", profile="mpi", n=2)
cluster.start_and_connect_sync()
Starting 2 engines with <class 'ipyparallel.cluster.launcher.MPIEngineSetLauncher'>
<ipyparallel.client.client.Client at 0x7fa2a4927320>
The jupyter magic %%px
will run the following cells on the ipyparallel
cluster.
%%px
import firedrake # noqa: E402
import mpi4py.MPI # noqa: E402
%%px
import viskex # noqa: E402
To confirm that we are running in parallel, we can print the rank of the current process and the total number of processes.
%%px
comm_world = mpi4py.MPI.COMM_WORLD
print(f"rank = {comm_world.rank}, size = {comm_world.size}")
[stdout:0] rank = 0, size = 2
[stdout:1] rank = 1, size = 2
Generate a mesh on MPI_COMM_WORLD
of the unit square by dividing each edge of the square in 6 segments.
%%px
square_world = firedrake.UnitSquareMesh(
6, 6, comm=comm_world, distribution_parameters={"partitioner_type": "simple"})
Plot the mesh defined on MPI_COMM_WORLD
. Each rank will plot its local cells, and their neighbors (called halos in firedrake
).
%%px
viskex.firedrake.plot_mesh(square_world)
[output:1]
[output:0]
For comparison, we can generate a similar mesh on MPI_COMM_SELF
. Each rank will have its own copy of the whole mesh.
%%px
comm_self = mpi4py.MPI.COMM_SELF
square_self = firedrake.UnitSquareMesh(
6, 6, comm=comm_self, distribution_parameters={"partitioner_type": "simple"})
Plot the mesh defined on MPI_COMM_SELF
. Each rank will produce a plot which is visually the same, since each rank has its own copy of the same mesh.
%%px
viskex.firedrake.plot_mesh(square_self)
[output:0]
[output:1]
We finally stop the ipyparallel
cluster. Note that when running with Run -> Run all cells
all interactive plots will be closed when the kernel executes this cell.
cluster.stop_cluster_sync()
Stopping controller
Controller stopped: {'exit_code': 0, 'pid': 4861, 'identifier': 'ipcontroller-1756699139-4lqh-4843'}
Stopping engine(s): 1756699140
Output for ipengine-1756699139-4lqh-1756699140-4843: 2025-09-01 04:59:01.433 [IPEngine] Loading connection info from $IPP_CONNECTION_INFO 2025-09-01 04:59:01.433 [IPEngine] WARNING | Not using CurveZMQ security 2025-09-01 04:59:01.438 [IPEngine] Loading connection info from $IPP_CONNECTION_INFO 2025-09-01 04:59:01.438 [IPEngine] WARNING | Not using CurveZMQ security 2025-09-01 04:59:01.676 [IPEngine.0] Registering with controller at tcp://127.0.0.1:51283 2025-09-01 04:59:01.676 [IPEngine.1] Registering with controller at tcp://127.0.0.1:51283 2025-09-01 04:59:01.677 [IPEngine.1] Requesting id: 1 2025-09-01 04:59:01.677 [IPEngine.0] Requesting id: 0 2025-09-01 04:59:01.679 [IPEngine.1.1] Shell_addrs: ['tcp://127.0.0.1:44013', 'tcp://127.0.0.1:43251', 'tcp://127.0.0.1:35595'] 2025-09-01 04:59:01.679 [IPEngine.1.1] Connecting shell to tcp://127.0.0.1:44013 2025-09-01 04:59:01.679 [IPEngine.1.1] Connecting shell to tcp://127.0.0.1:43251 2025-09-01 04:59:01.680 [IPEngine.0.0] Shell_addrs: ['tcp://127.0.0.1:44013', 'tcp://127.0.0.1:43251', 'tcp://127.0.0.1:47289'] 2025-09-01 04:59:01.679 [IPEngine.1.1] Connecting shell to tcp://127.0.0.1:35595 2025-09-01 04:59:01.679 [IPEngine.1.1] Starting nanny 2025-09-01 04:59:01.680 [IPEngine.0.0] Connecting shell to tcp://127.0.0.1:44013 2025-09-01 04:59:01.680 [IPEngine.0.0] Connecting shell to tcp://127.0.0.1:43251 2025-09-01 04:59:01.680 [IPEngine.0.0] Connecting shell to tcp://127.0.0.1:47289 2025-09-01 04:59:01.680 [IPEngine.0.0] Starting nanny 2025-09-01 04:59:02.124 [KernelNanny.0] Starting kernel nanny for engine 0, pid=4896, nanny pid=4908 2025-09-01 04:59:02.124 [KernelNanny.0] Nanny watching parent pid 4896. 2025-09-01 04:59:02.124 [KernelNanny.1] Starting kernel nanny for engine 1, pid=4897, nanny pid=4907 2025-09-01 04:59:02.124 [KernelNanny.1] Nanny watching parent pid 4897. 2025-09-01 04:59:02.191 [IPEngine.0.0] Loading IPython extension: storemagic 2025-09-01 04:59:02.191 [IPEngine.1.1] Loading IPython extension: storemagic 2025-09-01 04:59:02.192 [IPEngine.0.0] Running code in user namespace: from mpi4py import MPI mpi_rank = MPI.COMM_WORLD.Get_rank() mpi_size = MPI.COMM_WORLD.Get_size() 2025-09-01 04:59:02.192 [IPEngine.1.1] Running code in user namespace: from mpi4py import MPI mpi_rank = MPI.COMM_WORLD.Get_rank() mpi_size = MPI.COMM_WORLD.Get_size() 2025-09-01 04:59:02.193 [IPEngine.0.0] WARNING | debugpy_stream undefined, debugging will not be enabled 2025-09-01 04:59:02.193 [IPEngine.1.1] WARNING | debugpy_stream undefined, debugging will not be enabled 2025-09-01 04:59:02.195 [IPEngine.1.1] Starting to monitor the heartbeat signal from the hub every 3500 ms. 2025-09-01 04:59:02.195 [IPEngine.0.0] Starting to monitor the heartbeat signal from the hub every 3500 ms. 2025-09-01 04:59:02.196 [IPEngine.0.0] Completed registration with id 0 2025-09-01 04:59:02.196 [IPEngine.1.1] Completed registration with id 1 2025-09-01 04:59:06.688 [IPEngine.0.0] Handling execute_request: 688a35c9-e0949e354555354e8818dc07_4843_1 2025-09-01 04:59:06.688 [IPEngine.1.1] Handling execute_request: 688a35c9-e0949e354555354e8818dc07_4843_2 2025-09-01 04:59:08.565 [IPEngine.0.0] Handling execute_request: 688a35c9-e0949e354555354e8818dc07_4843_3 2025-09-01 04:59:08.566 [IPEngine.1.1] Handling execute_request: 688a35c9-e0949e354555354e8818dc07_4843_4 2025-09-01 04:59:09.263 [IPEngine.0.0] Handling execute_request: 688a35c9-e0949e354555354e8818dc07_4843_5 2025-09-01 04:59:09.263 [IPEngine.1.1] Handling execute_request: 688a35c9-e0949e354555354e8818dc07_4843_6 2025-09-01 04:59:09.274 [IPEngine.0.0] Handling execute_request: 688a35c9-e0949e354555354e8818dc07_4843_7 2025-09-01 04:59:09.275 [IPEngine.1.1] Handling execute_request: 688a35c9-e0949e354555354e8818dc07_4843_8 2025-09-01 04:59:09.288 [IPEngine.0.0] Handling execute_request: 688a35c9-e0949e354555354e8818dc07_4843_9 2025-09-01 04:59:09.288 [IPEngine.1.1] Handling execute_request: 688a35c9-e0949e354555354e8818dc07_4843_10 2025-09-01 04:59:10.193 [IPEngine.0.0] Handling execute_request: 688a35c9-e0949e354555354e8818dc07_4843_11 2025-09-01 04:59:10.194 [IPEngine.1.1] Handling execute_request: 688a35c9-e0949e354555354e8818dc07_4843_12 2025-09-01 04:59:10.206 [IPEngine.0.0] Handling execute_request: 688a35c9-e0949e354555354e8818dc07_4843_13 2025-09-01 04:59:10.206 [IPEngine.1.1] Handling execute_request: 688a35c9-e0949e354555354e8818dc07_4843_14
engine set stopped 1756699140: {'exit_code': 1, 'pid': 4889, 'identifier': 'ipengine-1756699139-4lqh-1756699140-4843'}