From f6b711a8dff3e8fbd35a4020740313ca979cdacf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=B8rgen=20S=2E=20Dokken?= <dokken@simula.no>
Date: Fri, 5 Jan 2024 14:26:20 +0100
Subject: [PATCH 1/2] Update environment (and pin dolfinx to subrelease)

---
 .github/workflows/build_docs.yml         |  10 +-
 docker/Dockerfile                        |   2 +-
 environment.yml                          |   8 +-
 notebooks/dolfinx_MPI_tutorial.ipynb     | 262 +++++++++++------------
 notebooks/intro-mpi/intro-mpi.ipynb      |  59 +++--
 notebooks/intro-mpi/scatter-gather.ipynb | 250 +++++++++++++++++++--
 notebooks/intro-mpi/send-recv.ipynb      |  22 +-
 notebooks/send-vs-send.ipynb             | 134 +++++++-----
 8 files changed, 486 insertions(+), 261 deletions(-)

diff --git a/.github/workflows/build_docs.yml b/.github/workflows/build_docs.yml
index fb09390..5438622 100644
--- a/.github/workflows/build_docs.yml
+++ b/.github/workflows/build_docs.yml
@@ -20,11 +20,10 @@ jobs:
     container: ubuntu:22.04
     env:
       PYVISTA_OFF_SCREEN: false
-      PYVISTA_JUPYTER_BACKEND: "panel"
+      PYVISTA_JUPYTER_BACKEND: "html"
 
     steps:
-
-      - uses: actions/checkout@v3
+      - uses: actions/checkout@v4
 
       - name: Install common packages
         uses: ./.github/actions/install-dependencies
@@ -36,10 +35,9 @@ jobs:
           key: jupyter-cache-${{ hashFiles('environment.yml') }}
 
       - name: Build the book
-        run:
-          jupyter-book build . -W
+        run: jupyter-book build . -W
 
-      - uses: actions/upload-artifact@v3
+      - uses: actions/upload-artifact@v4
         # always upload artifact, which can include error messages
         if: always()
         with:
diff --git a/docker/Dockerfile b/docker/Dockerfile
index 91ee6bf..e5efa84 100644
--- a/docker/Dockerfile
+++ b/docker/Dockerfile
@@ -1,7 +1,7 @@
 FROM condaforge/mambaforge 
 
 ENV DEBIAN_FRONTEND=noninteractive
-ENV PYVISTA_JUPYTER_BACKEND=panel
+ENV PYVISTA_JUPYTER_BACKEND=html
 ENV PYVISTA_OFF_SCREEN=False
 
 # Install ssh (missing dependency to run conda envs)
diff --git a/environment.yml b/environment.yml
index 2060eb2..1cba4ab 100644
--- a/environment.yml
+++ b/environment.yml
@@ -6,14 +6,14 @@ dependencies:
   - cycler
   - mpich
   - ipyparallel>=8.6
-  - ipywidgets
   - jupyter-book
   - matplotlib-base
   - mpi4py
   - numpy
   - pandas
-  - pyvista
+  - pyvista>=0.43.*
   - autopep8
-  - fenics-dolfinx
+  - jupyterlab
+  - fenics-dolfinx==0.6.*
   - petsc4py
-  - panel
+  - trame
diff --git a/notebooks/dolfinx_MPI_tutorial.ipynb b/notebooks/dolfinx_MPI_tutorial.ipynb
index 2b36f15..7aabfa5 100644
--- a/notebooks/dolfinx_MPI_tutorial.ipynb
+++ b/notebooks/dolfinx_MPI_tutorial.ipynb
@@ -45,7 +45,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 3,
+   "execution_count": 2,
    "id": "3c140fdc",
    "metadata": {
     "tags": []
@@ -61,7 +61,7 @@
     {
      "data": {
       "application/vnd.jupyter.widget-view+json": {
-       "model_id": "340f7a76cd4641e1bf4685025a2d9508",
+       "model_id": "3824c33e82734ec2a08e71231230b548",
        "version_major": 2,
        "version_minor": 0
       },
@@ -91,7 +91,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 4,
+   "execution_count": 3,
    "id": "09fec8d4-2f90-4c5c-89fe-b32e8c78cdf8",
    "metadata": {
     "tags": []
@@ -124,7 +124,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 5,
+   "execution_count": 4,
    "id": "6d77bdc4-d4c2-4326-b2ca-ed9b43272229",
    "metadata": {
     "tags": []
@@ -133,13 +133,13 @@
     {
      "data": {
       "text/plain": [
-       "[stdout:0] Cell (dim = 2) to facet (dim = 1) connectivity:\n",
-       "Rank 0: <AdjacencyList> with 6 nodes\n",
-       "  0: [5 4 0 ]\n",
-       "  1: [6 1 5 ]\n",
-       "  2: [3 1 2 ]\n",
-       "  3: [7 8 6 ]\n",
-       "  4: [10 4 9 ]\n",
+       "[stdout:1] Cell (dim = 2) to facet (dim = 1) connectivity:\n",
+       "Rank 1: <AdjacencyList> with 6 nodes\n",
+       "  0: [1 7 0 ]\n",
+       "  1: [3 2 1 ]\n",
+       "  2: [5 2 4 ]\n",
+       "  3: [6 8 3 ]\n",
+       "  4: [10 7 9 ]\n",
        "  5: [12 8 11 ]\n",
        "\n"
       ]
@@ -150,14 +150,14 @@
     {
      "data": {
       "text/plain": [
-       "[stdout:1] Cell (dim = 2) to facet (dim = 1) connectivity:\n",
-       "Rank 1: <AdjacencyList> with 6 nodes\n",
-       "  0: [0 8 7 ]\n",
-       "  1: [2 1 0 ]\n",
-       "  2: [4 1 3 ]\n",
-       "  3: [6 5 2 ]\n",
-       "  4: [9 8 10 ]\n",
-       "  5: [12 5 11 ]\n",
+       "[stdout:0] Cell (dim = 2) to facet (dim = 1) connectivity:\n",
+       "Rank 0: <AdjacencyList> with 6 nodes\n",
+       "  0: [5 8 4 ]\n",
+       "  1: [6 0 5 ]\n",
+       "  2: [2 0 1 ]\n",
+       "  3: [3 7 6 ]\n",
+       "  4: [10 8 9 ]\n",
+       "  5: [11 7 12 ]\n",
        "\n"
       ]
      },
@@ -182,7 +182,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 6,
+   "execution_count": 5,
    "id": "8d8e71e5-ba72-4aa3-83df-24692e01cab6",
    "metadata": {
     "tags": []
@@ -191,7 +191,7 @@
     {
      "data": {
       "text/plain": [
-       "[stdout:1] Rank 1: Ghost cells (global numbering): [0 3]\n"
+       "[stdout:0] Rank 0: Ghost cells (global numbering): [4 7]\n"
       ]
      },
      "metadata": {},
@@ -200,7 +200,7 @@
     {
      "data": {
       "text/plain": [
-       "[stdout:0] Rank 0: Ghost cells (global numbering): [4 7]\n"
+       "[stdout:1] Rank 1: Ghost cells (global numbering): [0 3]\n"
       ]
      },
      "metadata": {},
@@ -225,7 +225,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 7,
+   "execution_count": 6,
    "id": "ca8b487d-09e4-45c4-bd90-784f511f74d3",
    "metadata": {
     "tags": []
@@ -236,7 +236,7 @@
       "text/plain": [
        "[stdout:0] Rank 0: Global dofmap size: 9\n",
        "Rank 0: Local dofmap size: 4\n",
-       "Rank 0: Ghosts: [5 8 4 6]\n"
+       "Rank 0: Ghosts: [4 6 5 7]\n"
       ]
      },
      "metadata": {},
@@ -247,7 +247,7 @@
       "text/plain": [
        "[stdout:1] Rank 1: Global dofmap size: 9\n",
        "Rank 1: Local dofmap size: 5\n",
-       "Rank 1: Ghosts: [0 1 2]\n"
+       "Rank 1: Ghosts: [3 0 1]\n"
       ]
      },
      "metadata": {},
@@ -274,7 +274,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 8,
+   "execution_count": 7,
    "id": "8fa7a806-d9ee-405c-965e-6fec591e028c",
    "metadata": {
     "tags": []
@@ -283,8 +283,8 @@
     {
      "data": {
       "text/plain": [
-       "[stdout:1] Rank 1: Local size of array: 5\n",
-       "Rank 1: Global size of array: 9\n"
+       "[stdout:0] Rank 0: Local size of array: 4\n",
+       "Rank 0: Global size of array: 9\n"
       ]
      },
      "metadata": {},
@@ -293,8 +293,8 @@
     {
      "data": {
       "text/plain": [
-       "[stdout:0] Rank 0: Local size of array: 4\n",
-       "Rank 0: Global size of array: 9\n"
+       "[stdout:1] Rank 1: Local size of array: 5\n",
+       "Rank 1: Global size of array: 9\n"
       ]
      },
      "metadata": {},
@@ -320,7 +320,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 9,
+   "execution_count": 8,
    "id": "0699659e-9d73-48d2-a0be-36f3288dedea",
    "metadata": {
     "tags": []
@@ -329,7 +329,7 @@
     {
      "data": {
       "text/plain": [
-       "[stdout:0] Rank 0: Ghosts: [5 8 4 6]\n",
+       "[stdout:0] Rank 0: Ghosts: [4 6 5 7]\n",
        "Rank 0: Ghost owners: [1 1 1 1]\n"
       ]
      },
@@ -339,7 +339,7 @@
     {
      "data": {
       "text/plain": [
-       "[stdout:1] Rank 1: Ghosts: [0 1 2]\n",
+       "[stdout:1] Rank 1: Ghosts: [3 0 1]\n",
        "Rank 1: Ghost owners: [0 0 0]\n"
       ]
      },
@@ -364,7 +364,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 10,
+   "execution_count": 9,
    "id": "230c3bb9-3b52-4450-870a-f2d8541b6457",
    "metadata": {
     "tags": []
@@ -392,7 +392,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 11,
+   "execution_count": 10,
    "id": "3f8dbf3b-12ac-428e-a078-906277074abc",
    "metadata": {
     "tags": []
@@ -401,7 +401,7 @@
     {
      "data": {
       "text/plain": [
-       "\u001b[0;31mOut[0:8]: \u001b[0m<petsc4py.PETSc.Vec at 0x124cb6020>"
+       "\u001b[0;31mOut[0:8]: \u001b[0m<petsc4py.PETSc.Vec at 0x7f2fa92d0130>"
       ]
      },
      "metadata": {
@@ -409,12 +409,12 @@
       "completed": null,
       "data": {},
       "engine_id": 0,
-      "engine_uuid": "ab8ab8ad-ea13d585d7987ff2f39f3103",
+      "engine_uuid": "a3acd193-f5de95f14ec6420dd3d690db",
       "error": null,
       "execute_input": "\nimport ufl\n\n# UFL form of right-hand side\nL = ufl.inner(1.0, v) * ufl.dx\nL = dfx.fem.form(L)\n\n# Assemble UFL form into a vector\n_b = dfx.fem.Function(V)\ndfx.fem.petsc.assemble_vector(_b.vector, L)\n",
       "execute_result": {
        "data": {
-        "text/plain": "<petsc4py.PETSc.Vec at 0x124cb6020>"
+        "text/plain": "<petsc4py.PETSc.Vec at 0x7f2fa92d0130>"
        },
        "execution_count": 8,
        "metadata": {}
@@ -427,14 +427,14 @@
       "status": null,
       "stderr": "",
       "stdout": "",
-      "submitted": "2023-04-17T10:43:51.863477Z"
+      "submitted": "2024-01-05T13:24:08.239508Z"
      },
      "output_type": "display_data"
     },
     {
      "data": {
       "text/plain": [
-       "\u001b[0;31mOut[1:8]: \u001b[0m<petsc4py.PETSc.Vec at 0x105c3f650>"
+       "\u001b[0;31mOut[1:8]: \u001b[0m<petsc4py.PETSc.Vec at 0x7f5975dc6980>"
       ]
      },
      "metadata": {
@@ -442,12 +442,12 @@
       "completed": null,
       "data": {},
       "engine_id": 1,
-      "engine_uuid": "c786becc-278c25074ac2c61bc33ce670",
+      "engine_uuid": "a29d2826-5c940569d592fb790538480e",
       "error": null,
       "execute_input": "\nimport ufl\n\n# UFL form of right-hand side\nL = ufl.inner(1.0, v) * ufl.dx\nL = dfx.fem.form(L)\n\n# Assemble UFL form into a vector\n_b = dfx.fem.Function(V)\ndfx.fem.petsc.assemble_vector(_b.vector, L)\n",
       "execute_result": {
        "data": {
-        "text/plain": "<petsc4py.PETSc.Vec at 0x105c3f650>"
+        "text/plain": "<petsc4py.PETSc.Vec at 0x7f5975dc6980>"
        },
        "execution_count": 8,
        "metadata": {}
@@ -460,7 +460,7 @@
       "status": null,
       "stderr": "",
       "stdout": "",
-      "submitted": "2023-04-17T10:43:51.863538Z"
+      "submitted": "2024-01-05T13:24:08.239653Z"
      },
      "output_type": "display_data"
     }
@@ -489,7 +489,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 12,
+   "execution_count": 11,
    "id": "b2a21284-0e1e-4c60-ac48-4018c36e0681",
    "metadata": {
     "tags": []
@@ -498,8 +498,8 @@
     {
      "data": {
       "text/plain": [
-       "[stdout:1] After assembly, prior to communication\n",
-       "Rank 1: [0.125      0.125      0.125      0.04166667 0.04166667 0.04166667\n",
+       "[stdout:0] After assembly, prior to communication\n",
+       "Rank 0: [0.125      0.125      0.04166667 0.04166667 0.04166667 0.125\n",
        " 0.         0.        ]\n"
       ]
      },
@@ -509,8 +509,8 @@
     {
      "data": {
       "text/plain": [
-       "[stdout:0] After assembly, prior to communication\n",
-       "Rank 0: [0.04166667 0.125      0.125      0.04166667 0.125      0.04166667\n",
+       "[stdout:1] After assembly, prior to communication\n",
+       "Rank 1: [0.04166667 0.125      0.125      0.125      0.04166667 0.04166667\n",
        " 0.         0.        ]\n"
       ]
      },
@@ -534,7 +534,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 13,
+   "execution_count": 12,
    "id": "e8e1b2fe-944b-4944-970d-908ec9ab068b",
    "metadata": {
     "tags": []
@@ -543,8 +543,8 @@
     {
      "data": {
       "text/plain": [
-       "[stdout:1] After ADD/REVERSE update\n",
-       "Rank 1: [0.125      0.25       0.125      0.04166667 0.08333333 0.04166667\n",
+       "[stdout:0] After ADD/REVERSE update\n",
+       "Rank 0: [0.125      0.125      0.04166667 0.08333333 0.04166667 0.125\n",
        " 0.         0.        ]\n"
       ]
      },
@@ -554,8 +554,8 @@
     {
      "data": {
       "text/plain": [
-       "[stdout:0] After ADD/REVERSE update\n",
-       "Rank 0: [0.08333333 0.125      0.125      0.04166667 0.125      0.04166667\n",
+       "[stdout:1] After ADD/REVERSE update\n",
+       "Rank 1: [0.08333333 0.125      0.25       0.125      0.04166667 0.04166667\n",
        " 0.         0.        ]\n"
       ]
      },
@@ -583,7 +583,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 14,
+   "execution_count": 13,
    "id": "6f7059a8-e73c-49d7-8b0c-417f80a8f065",
    "metadata": {
     "tags": []
@@ -593,7 +593,7 @@
      "data": {
       "text/plain": [
        "[stdout:1] After INSERT/FORWARD update\n",
-       "Rank 1: [0.125      0.25       0.125      0.04166667 0.08333333 0.08333333\n",
+       "Rank 1: [0.08333333 0.125      0.25       0.125      0.04166667 0.08333333\n",
        " 0.125      0.125     ]\n"
       ]
      },
@@ -604,7 +604,7 @@
      "data": {
       "text/plain": [
        "[stdout:0] After INSERT/FORWARD update\n",
-       "Rank 0: [0.08333333 0.125      0.125      0.04166667 0.25       0.08333333\n",
+       "Rank 0: [0.125      0.125      0.04166667 0.08333333 0.08333333 0.25\n",
        " 0.125      0.125     ]\n"
       ]
      },
@@ -673,75 +673,25 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 26,
+   "execution_count": 14,
    "id": "1bd0b245-b1e4-4d1f-9e11-a12e652a4bcb",
    "metadata": {
     "tags": []
    },
    "outputs": [
     {
-     "name": "stderr",
-     "output_type": "stream",
-     "text": [
-      "[0:execute]\n",
-      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n",
-      "\u001b[0;31mOSError\u001b[0m                                   Traceback (most recent call last)\n",
-      "Cell \u001b[0;32mIn[22], line 4\u001b[0m\n",
-      "\u001b[1;32m      2\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mpetsc4py\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m PETSc\n",
-      "\u001b[1;32m      3\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mpyvista\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m \u001b[38;5;21;01mpv\u001b[39;00m\n",
-      "\u001b[0;32m----> 4\u001b[0m \u001b[43mpv\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mstart_xvfb\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n",
-      "\u001b[1;32m      5\u001b[0m comm \u001b[38;5;241m=\u001b[39m MPI\u001b[38;5;241m.\u001b[39mCOMM_WORLD \u001b[38;5;66;03m# MPI communicator\u001b[39;00m\n",
-      "\u001b[1;32m      7\u001b[0m Nx, Ny \u001b[38;5;241m=\u001b[39m \u001b[38;5;241m2\u001b[39m, \u001b[38;5;241m2\u001b[39m \u001b[38;5;66;03m# Mesh size\u001b[39;00m\n",
-      "\n",
-      "File \u001b[0;32m/opt/anaconda3/envs/fenicsx/lib/python3.10/site-packages/pyvista/utilities/xvfb.py:47\u001b[0m, in \u001b[0;36mstart_xvfb\u001b[0;34m(wait, window_size)\u001b[0m\n",
-      "\u001b[1;32m     44\u001b[0m     \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mOSError\u001b[39;00m(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m`start_xvfb` is only supported on Linux\u001b[39m\u001b[38;5;124m'\u001b[39m)\n",
-      "\u001b[1;32m     46\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m os\u001b[38;5;241m.\u001b[39msystem(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mwhich Xvfb > /dev/null\u001b[39m\u001b[38;5;124m'\u001b[39m):\n",
-      "\u001b[0;32m---> 47\u001b[0m     \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mOSError\u001b[39;00m(XVFB_INSTALL_NOTES)\n",
-      "\u001b[1;32m     49\u001b[0m \u001b[38;5;66;03m# use current default window size\u001b[39;00m\n",
-      "\u001b[1;32m     50\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m window_size \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n",
-      "\n",
-      "\u001b[0;31mOSError\u001b[0m: Please install Xvfb with:\n",
-      "\n",
-      "Debian\n",
-      "$ sudo apt install libgl1-mesa-glx xvfb\n",
-      "\n",
-      "CentOS / RHL\n",
-      "$ sudo yum install libgl1-mesa-glx xvfb\n",
-      "\n",
-      "[1:execute]\n",
-      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n",
-      "\u001b[0;31mOSError\u001b[0m                                   Traceback (most recent call last)\n",
-      "Cell \u001b[0;32mIn[22], line 4\u001b[0m\n",
-      "\u001b[1;32m      2\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mpetsc4py\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m PETSc\n",
-      "\u001b[1;32m      3\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mpyvista\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m \u001b[38;5;21;01mpv\u001b[39;00m\n",
-      "\u001b[0;32m----> 4\u001b[0m \u001b[43mpv\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mstart_xvfb\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n",
-      "\u001b[1;32m      5\u001b[0m comm \u001b[38;5;241m=\u001b[39m MPI\u001b[38;5;241m.\u001b[39mCOMM_WORLD \u001b[38;5;66;03m# MPI communicator\u001b[39;00m\n",
-      "\u001b[1;32m      7\u001b[0m Nx, Ny \u001b[38;5;241m=\u001b[39m \u001b[38;5;241m2\u001b[39m, \u001b[38;5;241m2\u001b[39m \u001b[38;5;66;03m# Mesh size\u001b[39;00m\n",
-      "\n",
-      "File \u001b[0;32m/opt/anaconda3/envs/fenicsx/lib/python3.10/site-packages/pyvista/utilities/xvfb.py:47\u001b[0m, in \u001b[0;36mstart_xvfb\u001b[0;34m(wait, window_size)\u001b[0m\n",
-      "\u001b[1;32m     44\u001b[0m     \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mOSError\u001b[39;00m(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m`start_xvfb` is only supported on Linux\u001b[39m\u001b[38;5;124m'\u001b[39m)\n",
-      "\u001b[1;32m     46\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m os\u001b[38;5;241m.\u001b[39msystem(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mwhich Xvfb > /dev/null\u001b[39m\u001b[38;5;124m'\u001b[39m):\n",
-      "\u001b[0;32m---> 47\u001b[0m     \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mOSError\u001b[39;00m(XVFB_INSTALL_NOTES)\n",
-      "\u001b[1;32m     49\u001b[0m \u001b[38;5;66;03m# use current default window size\u001b[39;00m\n",
-      "\u001b[1;32m     50\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m window_size \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n",
-      "\n",
-      "\u001b[0;31mOSError\u001b[0m: Please install Xvfb with:\n",
-      "\n",
-      "Debian\n",
-      "$ sudo apt install libgl1-mesa-glx xvfb\n",
-      "\n",
-      "CentOS / RHL\n",
-      "$ sudo yum install libgl1-mesa-glx xvfb\n",
-      "\n"
-     ]
-    },
-    {
-     "ename": "AlreadyDisplayedError",
-     "evalue": "2 errors",
-     "output_type": "error",
-     "traceback": [
-      "2 errors"
-     ]
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "88ccb6e2923645158224db0e634205f7",
+       "version_major": 2,
+       "version_minor": 0
+      },
+      "text/plain": [
+       "%px:   0%|          | 0/2 [00:00<?, ?tasks/s]"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
     }
    ],
    "source": [
@@ -769,7 +719,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 16,
+   "execution_count": 15,
    "id": "c0b6c0e2-c61d-41de-9ac9-cc65c7312eae",
    "metadata": {
     "tags": []
@@ -793,7 +743,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 17,
+   "execution_count": 16,
    "id": "e367aa2a-2470-4e6b-b004-c1cf05ebf44f",
    "metadata": {
     "tags": []
@@ -822,7 +772,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 18,
+   "execution_count": 17,
    "id": "b23e1a12-a624-4fe3-91ea-55ec93be5180",
    "metadata": {
     "tags": []
@@ -852,7 +802,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 19,
+   "execution_count": 18,
    "id": "d1578746-f56d-49b0-8c3a-5509e395b54e",
    "metadata": {
     "tags": []
@@ -882,7 +832,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 20,
+   "execution_count": 19,
    "id": "92f21316-ab63-444e-81de-92c16923df8a",
    "metadata": {
     "tags": []
@@ -891,7 +841,7 @@
     {
      "data": {
       "text/plain": [
-       "[stdout:0] Rank 0: [0.         0.         0.         0.         0.25       0.08333333]\n"
+       "[stdout:0] Rank 0: [0.         0.         0.         0.         0.08333333 0.25      ]\n"
       ]
      },
      "metadata": {},
@@ -900,7 +850,7 @@
     {
      "data": {
       "text/plain": [
-       "[stdout:1] Rank 1: [0.         0.25       0.         0.         0.         0.08333333]\n"
+       "[stdout:1] Rank 1: [0.         0.         0.25       0.         0.         0.08333333]\n"
       ]
      },
      "metadata": {},
@@ -936,7 +886,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 21,
+   "execution_count": 20,
    "id": "be89390b-ca0c-4b47-b3d3-bdab4a9f6ec3",
    "metadata": {
     "tags": []
@@ -963,7 +913,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 22,
+   "execution_count": 21,
    "id": "65d71d42-60b9-499c-ad92-0554b15f6ed7",
    "metadata": {
     "tags": []
@@ -985,7 +935,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 23,
+   "execution_count": 22,
    "id": "6fe0266f-7b4f-466f-9350-44c7c54d09d5",
    "metadata": {
     "tags": []
@@ -995,9 +945,9 @@
      "data": {
       "text/plain": [
        "[stdout:1] Prior to communication\n",
-       "Rank 1: [0.     0.0625 0.     0.     0.     0.    ]\n",
+       "Rank 1: [0.     0.     0.0625 0.     0.     0.    ]\n",
        "After scatter_forward() update\n",
-       "Rank: 1: [0.     0.0625 0.     0.     0.     0.    ]\n"
+       "Rank: 1: [0.     0.     0.0625 0.     0.     0.    ]\n"
       ]
      },
      "metadata": {},
@@ -1009,7 +959,7 @@
        "[stdout:0] Prior to communication\n",
        "Rank 0: [0. 0. 0. 0. 0. 0.]\n",
        "After scatter_forward() update\n",
-       "Rank: 0: [0.     0.     0.     0.     0.0625 0.    ]\n"
+       "Rank: 0: [0.     0.     0.     0.     0.     0.0625]\n"
       ]
      },
      "metadata": {},
@@ -1039,12 +989,40 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 24,
+   "execution_count": 23,
    "id": "66f36a31-9ca7-404d-ab08-d0a6cd13a283",
    "metadata": {
     "tags": []
    },
    "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[stderr:1] ERROR:asyncio:Exception in callback Task.task_wakeup(<Future finis...ture pending>>)\n",
+       "handle: <Handle Task.task_wakeup(<Future finis...ture pending>>)>\n",
+       "Traceback (most recent call last):\n",
+       "  File \"/home/dokken/src/mambaforge/envs/mpi-tutorial/lib/python3.10/asyncio/events.py\", line 80, in _run\n",
+       "    self._context.run(self._callback, *self._args)\n",
+       "RuntimeError: Cannot enter into task <Task pending name='Task-2' coro=<Kernel.poll_control_queue() running at /home/dokken/.local/lib/python3.10/site-packages/ipykernel/kernelbase.py:279> wait_for=<Future finished result=<Future pending>> cb=[_chain_future.<locals>._call_set_state() at /home/dokken/src/mambaforge/envs/mpi-tutorial/lib/python3.10/asyncio/futures.py:392]> while another task <Task pending name='Task-1' coro=<Kernel.dispatch_queue() running at /home/dokken/.local/lib/python3.10/site-packages/ipykernel/kernelbase.py:510> cb=[IOLoop.add_future.<locals>.<lambda>() at /home/dokken/.local/lib/python3.10/site-packages/tornado/ioloop.py:687]> is being executed.\n"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "[stderr:0] ERROR:asyncio:Exception in callback Task.task_wakeup(<Future finis...ture pending>>)\n",
+       "handle: <Handle Task.task_wakeup(<Future finis...ture pending>>)>\n",
+       "Traceback (most recent call last):\n",
+       "  File \"/home/dokken/src/mambaforge/envs/mpi-tutorial/lib/python3.10/asyncio/events.py\", line 80, in _run\n",
+       "    self._context.run(self._callback, *self._args)\n",
+       "RuntimeError: Cannot enter into task <Task pending name='Task-2' coro=<Kernel.poll_control_queue() running at /home/dokken/.local/lib/python3.10/site-packages/ipykernel/kernelbase.py:279> wait_for=<Future finished result=<Future pending>> cb=[_chain_future.<locals>._call_set_state() at /home/dokken/src/mambaforge/envs/mpi-tutorial/lib/python3.10/asyncio/futures.py:392]> while another task <Task pending name='Task-1' coro=<Kernel.dispatch_queue() running at /home/dokken/.local/lib/python3.10/site-packages/ipykernel/kernelbase.py:510> cb=[IOLoop.add_future.<locals>.<lambda>() at /home/dokken/.local/lib/python3.10/site-packages/tornado/ioloop.py:687]> is being executed.\n"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
     {
      "data": {
       "text/plain": [
@@ -1057,12 +1035,12 @@
     {
      "data": {
       "application/vnd.jupyter.widget-view+json": {
-       "model_id": "94aeb5b8783d441f8ef39c0f2a7c25b0",
+       "model_id": "f68788b8f4624d1eab2ceb9243f3d19e",
        "version_major": 2,
        "version_minor": 0
       },
       "text/plain": [
-       "ViewInteractiveWidget(height=768, layout=Layout(height='auto', width='100%'), width=1024)"
+       "EmbeddableWidget(value='<iframe srcdoc=\"<!DOCTYPE html>\\n<html>\\n  <head>\\n    <meta http-equiv=&quot;Content-…"
       ]
      },
      "metadata": {
@@ -1082,12 +1060,12 @@
     {
      "data": {
       "application/vnd.jupyter.widget-view+json": {
-       "model_id": "410bb76c0cbf4e62a9853a7721f2d6a1",
+       "model_id": "693681b11d7542648c841533b64ad0cd",
        "version_major": 2,
        "version_minor": 0
       },
       "text/plain": [
-       "ViewInteractiveWidget(height=768, layout=Layout(height='auto', width='100%'), width=1024)"
+       "EmbeddableWidget(value='<iframe srcdoc=\"<!DOCTYPE html>\\n<html>\\n  <head>\\n    <meta http-equiv=&quot;Content-…"
       ]
      },
      "metadata": {
@@ -1116,7 +1094,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 25,
+   "execution_count": 24,
    "id": "1cb52086-b014-4ab3-8e6d-09f71eb2bb99",
    "metadata": {},
    "outputs": [
@@ -1125,9 +1103,9 @@
      "output_type": "stream",
      "text": [
       "Stopping controller\n",
-      "Controller stopped: {'exit_code': 0, 'pid': 45557, 'identifier': 'ipcontroller-1681728224-si4p-45405'}\n",
-      "Stopping engine(s): 1681728225\n",
-      "engine set stopped 1681728225: {'exit_code': 0, 'pid': 45571, 'identifier': 'ipengine-1681728224-si4p-1681728225-45405'}\n"
+      "Controller stopped: {'exit_code': 0, 'pid': 339096, 'identifier': 'ipcontroller-1704461040-7b3g-339027'}\n",
+      "Stopping engine(s): 1704461041\n",
+      "engine set stopped 1704461041: {'exit_code': 1, 'pid': 339158, 'identifier': 'ipengine-1704461040-7b3g-1704461041-339027'}\n"
      ]
     }
    ],
@@ -1161,7 +1139,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.10.7"
+   "version": "3.10.13"
   }
  },
  "nbformat": 4,
diff --git a/notebooks/intro-mpi/intro-mpi.ipynb b/notebooks/intro-mpi/intro-mpi.ipynb
index 460e9c0..4763787 100644
--- a/notebooks/intro-mpi/intro-mpi.ipynb
+++ b/notebooks/intro-mpi/intro-mpi.ipynb
@@ -30,9 +30,22 @@
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "Starting 2 engines with <class 'ipyparallel.cluster.launcher.MPIEngineSetLauncher'>\n",
-      "100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 2/2 [00:01<00:00,  1.51engine/s]\n"
+      "Starting 2 engines with <class 'ipyparallel.cluster.launcher.MPIEngineSetLauncher'>\n"
      ]
+    },
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "a8d0a3c3bbac454baa843b27eaf3834d",
+       "version_major": 2,
+       "version_minor": 0
+      },
+      "text/plain": [
+       "  0%|          | 0/2 [00:00<?, ?engine/s]"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
     }
    ],
    "source": [
@@ -70,7 +83,7 @@
        "['mpiexec',\n",
        " '-n',\n",
        " '2',\n",
-       " '/Users/minrk/conda/envs/scan/bin/python',\n",
+       " '/home/dokken/src/mambaforge/envs/mpi-tutorial/bin/python',\n",
        " '-m',\n",
        " 'ipyparallel.engine',\n",
        " '--mpi']"
@@ -129,7 +142,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 7,
+   "execution_count": 4,
    "id": "9d606eeb-b45c-4611-9490-80cc182c081d",
    "metadata": {
     "tags": []
@@ -138,7 +151,7 @@
     {
      "data": {
       "text/plain": [
-       "\u001b[0;31mOut[0:5]: \u001b[0m37246"
+       "\u001b[0;31mOut[0:1]: \u001b[0m330874"
       ]
      },
      "metadata": {
@@ -146,14 +159,14 @@
       "completed": null,
       "data": {},
       "engine_id": 0,
-      "engine_uuid": "59435fd5-fa5a7daceae7d4f7308a42e0",
+      "engine_uuid": "8ab04344-a7b3d8f30f12e1e65f4762b6",
       "error": null,
       "execute_input": "import os\npid = os.getpid()\npid\n",
       "execute_result": {
        "data": {
-        "text/plain": "37246"
+        "text/plain": "330874"
        },
-       "execution_count": 5,
+       "execution_count": 1,
        "metadata": {}
       },
       "follow": null,
@@ -164,14 +177,14 @@
       "status": null,
       "stderr": "",
       "stdout": "",
-      "submitted": "2023-04-12T07:36:50.848128Z"
+      "submitted": "2024-01-05T13:18:42.165661Z"
      },
      "output_type": "display_data"
     },
     {
      "data": {
       "text/plain": [
-       "\u001b[0;31mOut[1:5]: \u001b[0m37247"
+       "\u001b[0;31mOut[1:1]: \u001b[0m330875"
       ]
      },
      "metadata": {
@@ -179,14 +192,14 @@
       "completed": null,
       "data": {},
       "engine_id": 1,
-      "engine_uuid": "35610757-3e903e1a636a9a24d1811bee",
+      "engine_uuid": "d687aa54-fee5fe04fd410792b9918338",
       "error": null,
       "execute_input": "import os\npid = os.getpid()\npid\n",
       "execute_result": {
        "data": {
-        "text/plain": "37247"
+        "text/plain": "330875"
        },
-       "execution_count": 5,
+       "execution_count": 1,
        "metadata": {}
       },
       "follow": null,
@@ -197,7 +210,7 @@
       "status": null,
       "stderr": "",
       "stdout": "",
-      "submitted": "2023-04-12T07:36:50.848409Z"
+      "submitted": "2024-01-05T13:18:42.166096Z"
      },
      "output_type": "display_data"
     }
@@ -237,7 +250,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 6,
+   "execution_count": 5,
    "id": "1184e9f8-27aa-43b8-b758-28a4bd3ae1c0",
    "metadata": {
     "tags": []
@@ -285,7 +298,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 9,
+   "execution_count": 6,
    "id": "ab69bedd-4c50-4138-9f02-1988190d9956",
    "metadata": {
     "tags": []
@@ -294,7 +307,7 @@
     {
      "data": {
       "text/plain": [
-       "[stdout:0] Rank 0 has PID 37246\n"
+       "[stdout:0] Rank 0 has PID 330874\n"
       ]
      },
      "metadata": {},
@@ -303,7 +316,7 @@
     {
      "data": {
       "text/plain": [
-       "[stdout:1] Rank 1 has PID 37247\n"
+       "[stdout:1] Rank 1 has PID 330875\n"
       ]
      },
      "metadata": {},
@@ -329,7 +342,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 11,
+   "execution_count": 7,
    "id": "6a387fa4-5f74-41b4-8018-6af8ebd9c4a3",
    "metadata": {
     "tags": []
@@ -340,9 +353,9 @@
      "output_type": "stream",
      "text": [
       "Stopping controller\n",
-      "Controller stopped: {'exit_code': 0, 'pid': 37230, 'identifier': 'ipcontroller-1681284456-mwao-37042'}\n",
-      "Stopping engine(s): 1681284457\n",
-      "engine set stopped 1681284457: {'exit_code': 0, 'pid': 37244, 'identifier': 'ipengine-1681284456-mwao-1681284457-37042'}\n"
+      "Controller stopped: {'exit_code': 0, 'pid': 330799, 'identifier': 'ipcontroller-1704460714-uyr9-330712'}\n",
+      "Stopping engine(s): 1704460716\n",
+      "engine set stopped 1704460716: {'exit_code': 0, 'pid': 330869, 'identifier': 'ipengine-1704460714-uyr9-1704460716-330712'}\n"
      ]
     }
    ],
@@ -367,7 +380,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.10.10"
+   "version": "3.10.13"
   },
   "widgets": {
    "application/vnd.jupyter.widget-state+json": {
diff --git a/notebooks/intro-mpi/scatter-gather.ipynb b/notebooks/intro-mpi/scatter-gather.ipynb
index 4a3a1e7..aaf1bab 100644
--- a/notebooks/intro-mpi/scatter-gather.ipynb
+++ b/notebooks/intro-mpi/scatter-gather.ipynb
@@ -14,10 +14,32 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
+   "execution_count": 1,
    "id": "6b50a74a-5b21-4109-b629-b8bb7860810b",
    "metadata": {},
-   "outputs": [],
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Starting 3 engines with <class 'ipyparallel.cluster.launcher.MPIEngineSetLauncher'>\n"
+     ]
+    },
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "833eb3f3a4d046c39fa6c45327716167",
+       "version_major": 2,
+       "version_minor": 0
+      },
+      "text/plain": [
+       "  0%|          | 0/3 [00:00<?, ?engine/s]"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
    "source": [
     "import ipyparallel as ipp\n",
     "cluster = ipp.Cluster(engines=\"mpi\", n=3)\n",
@@ -35,7 +57,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
+   "execution_count": 2,
    "id": "2e480f55",
    "metadata": {},
    "outputs": [],
@@ -58,10 +80,20 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
+   "execution_count": 3,
    "id": "37bbde90",
    "metadata": {},
-   "outputs": [],
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[stdout:0] Process 0 will send [1, 4, 9] to the other processes\n"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
    "source": [
     "%%px\n",
     "root = 0\n",
@@ -84,10 +116,38 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
+   "execution_count": 4,
    "id": "cf2f8245",
    "metadata": {},
-   "outputs": [],
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[stdout:2] Process 2 received 9\n"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "[stdout:1] Process 1 received 4\n"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "[stdout:0] Process 0 received 1\n"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
    "source": [
     "%%px\n",
     "print(f\"Process {rank} received {scattered_data}\")"
@@ -104,10 +164,38 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
+   "execution_count": 5,
    "id": "2670135e",
    "metadata": {},
-   "outputs": [],
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[stdout:1] Process 1 got None\n"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "[stdout:2] Process 2 got None\n"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "[stdout:0] Process 0 got [1, 5, 11]\n"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
    "source": [
     "%%px\n",
     "modified_data = scattered_data + rank\n",
@@ -129,7 +217,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
+   "execution_count": 6,
    "id": "3ca8b291",
    "metadata": {},
    "outputs": [],
@@ -152,10 +240,52 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
+   "execution_count": 7,
    "id": "d89cf2da",
    "metadata": {},
-   "outputs": [],
+   "outputs": [
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "3e9471add8654f1798e99ab0642dae7d",
+       "version_major": 2,
+       "version_minor": 0
+      },
+      "text/plain": [
+       "%px:   0%|          | 0/3 [00:00<?, ?tasks/s]"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "[stdout:1] 97.5 µs ± 1.29 µs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)\n"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "[stdout:0] 97.5 µs ± 1.29 µs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)\n"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "[stdout:2] 97.5 µs ± 1.29 µs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)\n"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
    "source": [
     "%%px\n",
     "%%timeit\n",
@@ -175,10 +305,52 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
+   "execution_count": 8,
    "id": "d96484f3",
    "metadata": {},
-   "outputs": [],
+   "outputs": [
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "8467b52794294b2581034439db607fb6",
+       "version_major": 2,
+       "version_minor": 0
+      },
+      "text/plain": [
+       "%px:   0%|          | 0/3 [00:00<?, ?tasks/s]"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "[stdout:1] 733 ns ± 12.3 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)\n"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "[stdout:2] 802 ns ± 14.1 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)\n"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "[stdout:0] 877 ns ± 22.3 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)\n"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
    "source": [
     "%%px\n",
     "%%timeit\n",
@@ -198,7 +370,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
+   "execution_count": 9,
    "id": "de126dc6",
    "metadata": {},
    "outputs": [],
@@ -220,10 +392,52 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
+   "execution_count": 10,
    "id": "aa57f0fc",
    "metadata": {},
-   "outputs": [],
+   "outputs": [
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "732b930a401b486a8e3b7315882a7529",
+       "version_major": 2,
+       "version_minor": 0
+      },
+      "text/plain": [
+       "%px:   0%|          | 0/3 [00:00<?, ?tasks/s]"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "[stdout:0] 15.1 µs ± 406 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)\n"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "[stdout:2] 15.1 µs ± 406 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)\n"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "[stdout:1] 15.1 µs ± 406 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)\n"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
    "source": [
     "%%px\n",
     "%%timeit\n",
@@ -258,7 +472,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.10.6"
+   "version": "3.10.13"
   }
  },
  "nbformat": 4,
diff --git a/notebooks/intro-mpi/send-recv.ipynb b/notebooks/intro-mpi/send-recv.ipynb
index 7a087fc..1170463 100644
--- a/notebooks/intro-mpi/send-recv.ipynb
+++ b/notebooks/intro-mpi/send-recv.ipynb
@@ -31,7 +31,7 @@
     {
      "data": {
       "application/vnd.jupyter.widget-view+json": {
-       "model_id": "148907b736fb4982809a522d17795d1a",
+       "model_id": "0b466b066b6749dc84a6c13aaae30b43",
        "version_major": 2,
        "version_minor": 0
       },
@@ -314,7 +314,7 @@
     {
      "data": {
       "application/vnd.jupyter.widget-view+json": {
-       "model_id": "e93a7bb3720f41adb62184472d304edd",
+       "model_id": "aa64fb1e56824d6091464af77d498b6e",
        "version_major": 2,
        "version_minor": 0
       },
@@ -358,7 +358,7 @@
     {
      "data": {
       "text/plain": [
-       "[stdout:2] 2 received b'01' from 1\n"
+       "[stdout:3] 3 received b'012' from 2\n"
       ]
      },
      "metadata": {},
@@ -367,7 +367,7 @@
     {
      "data": {
       "text/plain": [
-       "[stdout:0] 0 received b'0123' from 3\n"
+       "[stdout:2] 2 received b'01' from 1\n"
       ]
      },
      "metadata": {},
@@ -376,7 +376,7 @@
     {
      "data": {
       "text/plain": [
-       "[stdout:3] 3 received b'012' from 2\n"
+       "[stdout:0] 0 received b'0123' from 3\n"
       ]
      },
      "metadata": {},
@@ -443,7 +443,7 @@
     {
      "data": {
       "text/plain": [
-       "[stdout:3] 3 received [0 1 2] from 2\n"
+       "[stdout:0] 0 received [0 1 2 3] from 3\n"
       ]
      },
      "metadata": {},
@@ -452,7 +452,7 @@
     {
      "data": {
       "text/plain": [
-       "[stdout:0] 0 received [0 1 2 3] from 3\n"
+       "[stdout:3] 3 received [0 1 2] from 2\n"
       ]
      },
      "metadata": {},
@@ -498,9 +498,9 @@
      "output_type": "stream",
      "text": [
       "Stopping controller\n",
-      "Controller stopped: {'exit_code': 0, 'pid': 67206, 'identifier': 'ipcontroller-1681449587-3424-67147'}\n",
-      "Stopping engine(s): 1681449588\n",
-      "engine set stopped 1681449588: {'exit_code': 0, 'pid': 67220, 'identifier': 'ipengine-1681449587-3424-1681449588-67147'}\n"
+      "Controller stopped: {'exit_code': 0, 'pid': 333009, 'identifier': 'ipcontroller-1704460808-ikmy-332566'}\n",
+      "Stopping engine(s): 1704460809\n",
+      "engine set stopped 1704460809: {'exit_code': 0, 'pid': 333060, 'identifier': 'ipengine-1704460808-ikmy-1704460809-332566'}\n"
      ]
     }
    ],
@@ -525,7 +525,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.10.10"
+   "version": "3.10.13"
   },
   "widgets": {
    "application/vnd.jupyter.widget-state+json": {
diff --git a/notebooks/send-vs-send.ipynb b/notebooks/send-vs-send.ipynb
index f428f54..bad483f 100644
--- a/notebooks/send-vs-send.ipynb
+++ b/notebooks/send-vs-send.ipynb
@@ -230,10 +230,10 @@
     {
      "data": {
       "text/plain": [
-       "[stdout:0] send\n",
-       "339 µs ± 16.2 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)\n",
+       "[stdout:1] send\n",
+       "545 µs ± 6.64 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)\n",
        "Send\n",
-       "55.5 µs ± 646 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)\n"
+       "245 µs ± 3.82 µs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)\n"
       ]
      },
      "metadata": {},
@@ -242,10 +242,10 @@
     {
      "data": {
       "text/plain": [
-       "[stdout:1] send\n",
-       "339 µs ± 16.1 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)\n",
+       "[stdout:0] send\n",
+       "545 µs ± 6.37 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)\n",
        "Send\n",
-       "55.5 µs ± 646 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)\n"
+       "245 µs ± 3.82 µs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)\n"
       ]
      },
      "metadata": {},
@@ -254,7 +254,7 @@
     {
      "data": {
       "application/vnd.jupyter.widget-view+json": {
-       "model_id": "96bac589e7224069b0f6c1c3c042c619",
+       "model_id": "795cb69359f24a94953cf5ded42ff525",
        "version_major": 2,
        "version_minor": 0
       },
@@ -297,7 +297,7 @@
     {
      "data": {
       "application/vnd.jupyter.widget-view+json": {
-       "model_id": "5e88f962f09c46948738b4c0e25c41ac",
+       "model_id": "efeed8a95ffd4d00a8c0f899073cef03",
        "version_major": 2,
        "version_minor": 0
       },
@@ -333,7 +333,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 9,
+   "execution_count": 7,
    "id": "8c7a5a5b-bfab-4bd8-a93b-6997761aab24",
    "metadata": {
     "tags": []
@@ -369,31 +369,31 @@
        "    <tr>\n",
        "      <th>0</th>\n",
        "      <td>send</td>\n",
-       "      <td>0.000020</td>\n",
+       "      <td>0.000058</td>\n",
        "      <td>1000</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>1</th>\n",
        "      <td>Send</td>\n",
-       "      <td>0.000003</td>\n",
+       "      <td>0.000008</td>\n",
        "      <td>1000</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>2</th>\n",
        "      <td>send</td>\n",
-       "      <td>0.000022</td>\n",
+       "      <td>0.000063</td>\n",
        "      <td>1412</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>3</th>\n",
        "      <td>Send</td>\n",
-       "      <td>0.000003</td>\n",
+       "      <td>0.000010</td>\n",
        "      <td>1412</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>4</th>\n",
        "      <td>send</td>\n",
-       "      <td>0.000023</td>\n",
+       "      <td>0.000068</td>\n",
        "      <td>1995</td>\n",
        "    </tr>\n",
        "  </tbody>\n",
@@ -402,14 +402,14 @@
       ],
       "text/plain": [
        "   kind  per_call  size\n",
-       "0  send  0.000020  1000\n",
-       "1  Send  0.000003  1000\n",
-       "2  send  0.000022  1412\n",
-       "3  Send  0.000003  1412\n",
-       "4  send  0.000023  1995"
+       "0  send  0.000058  1000\n",
+       "1  Send  0.000008  1000\n",
+       "2  send  0.000063  1412\n",
+       "3  Send  0.000010  1412\n",
+       "4  send  0.000068  1995"
       ]
      },
-     "execution_count": 9,
+     "execution_count": 7,
      "metadata": {},
      "output_type": "execute_result"
     }
@@ -432,7 +432,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 10,
+   "execution_count": 8,
    "id": "7191a56d-6048-4e21-9ef7-94778bc14484",
    "metadata": {
     "tags": []
@@ -442,20 +442,20 @@
      "data": {
       "text/plain": [
        "size  kind\n",
-       "1000  Send    0.000003\n",
-       "      send    0.000020\n",
-       "1412  Send    0.000003\n",
-       "      send    0.000022\n",
-       "1995  Send    0.000003\n",
-       "      send    0.000023\n",
-       "2818  Send    0.000004\n",
-       "      send    0.000035\n",
-       "3981  Send    0.000005\n",
-       "      send    0.000036\n",
+       "1000  Send    0.000008\n",
+       "      send    0.000058\n",
+       "1412  Send    0.000010\n",
+       "      send    0.000063\n",
+       "1995  Send    0.000012\n",
+       "      send    0.000068\n",
+       "2818  Send    0.000016\n",
+       "      send    0.000083\n",
+       "3981  Send    0.000017\n",
+       "      send    0.000083\n",
        "Name: per_call, dtype: float64"
       ]
      },
-     "execution_count": 10,
+     "execution_count": 8,
      "metadata": {},
      "output_type": "execute_result"
     }
@@ -474,7 +474,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 11,
+   "execution_count": 9,
    "id": "a331197b-490d-41e2-8240-1d8768d27268",
    "metadata": {
     "tags": []
@@ -484,19 +484,30 @@
      "data": {
       "text/html": [
        "\n",
-       "<div id=\"altair-viz-cc648467f6bd42a5b953e74f54c8c1b6\"></div>\n",
+       "<style>\n",
+       "  #altair-viz-612b2785fe7d4b8b8bd5caa9fd83ae33.vega-embed {\n",
+       "    width: 100%;\n",
+       "    display: flex;\n",
+       "  }\n",
+       "\n",
+       "  #altair-viz-612b2785fe7d4b8b8bd5caa9fd83ae33.vega-embed details,\n",
+       "  #altair-viz-612b2785fe7d4b8b8bd5caa9fd83ae33.vega-embed details summary {\n",
+       "    position: relative;\n",
+       "  }\n",
+       "</style>\n",
+       "<div id=\"altair-viz-612b2785fe7d4b8b8bd5caa9fd83ae33\"></div>\n",
        "<script type=\"text/javascript\">\n",
        "  var VEGA_DEBUG = (typeof VEGA_DEBUG == \"undefined\") ? {} : VEGA_DEBUG;\n",
        "  (function(spec, embedOpt){\n",
        "    let outputDiv = document.currentScript.previousElementSibling;\n",
-       "    if (outputDiv.id !== \"altair-viz-cc648467f6bd42a5b953e74f54c8c1b6\") {\n",
-       "      outputDiv = document.getElementById(\"altair-viz-cc648467f6bd42a5b953e74f54c8c1b6\");\n",
+       "    if (outputDiv.id !== \"altair-viz-612b2785fe7d4b8b8bd5caa9fd83ae33\") {\n",
+       "      outputDiv = document.getElementById(\"altair-viz-612b2785fe7d4b8b8bd5caa9fd83ae33\");\n",
        "    }\n",
        "    const paths = {\n",
-       "      \"vega\": \"https://cdn.jsdelivr.net/npm//vega@5?noext\",\n",
-       "      \"vega-lib\": \"https://cdn.jsdelivr.net/npm//vega-lib?noext\",\n",
-       "      \"vega-lite\": \"https://cdn.jsdelivr.net/npm//vega-lite@4.17.0?noext\",\n",
-       "      \"vega-embed\": \"https://cdn.jsdelivr.net/npm//vega-embed@6?noext\",\n",
+       "      \"vega\": \"https://cdn.jsdelivr.net/npm/vega@5?noext\",\n",
+       "      \"vega-lib\": \"https://cdn.jsdelivr.net/npm/vega-lib?noext\",\n",
+       "      \"vega-lite\": \"https://cdn.jsdelivr.net/npm/vega-lite@5.8.0?noext\",\n",
+       "      \"vega-embed\": \"https://cdn.jsdelivr.net/npm/vega-embed@6?noext\",\n",
        "    };\n",
        "\n",
        "    function maybeLoadScript(lib, version) {\n",
@@ -531,19 +542,19 @@
        "      require([\"vega-embed\"], displayChart, err => showError(`Error loading script: ${err.message}`));\n",
        "    } else {\n",
        "      maybeLoadScript(\"vega\", \"5\")\n",
-       "        .then(() => maybeLoadScript(\"vega-lite\", \"4.17.0\"))\n",
+       "        .then(() => maybeLoadScript(\"vega-lite\", \"5.8.0\"))\n",
        "        .then(() => maybeLoadScript(\"vega-embed\", \"6\"))\n",
        "        .catch(showError)\n",
        "        .then(() => displayChart(vegaEmbed));\n",
        "    }\n",
-       "  })({\"config\": {\"view\": {\"continuousWidth\": 400, \"continuousHeight\": 300}}, \"data\": {\"name\": \"data-6c0b5d6b8f463d3bcbc85a5f2a93e820\"}, \"mark\": \"line\", \"encoding\": {\"color\": {\"field\": \"kind\", \"type\": \"nominal\"}, \"x\": {\"field\": \"size\", \"scale\": {\"type\": \"log\"}, \"type\": \"quantitative\"}, \"y\": {\"field\": \"per_call\", \"scale\": {\"type\": \"log\"}, \"type\": \"quantitative\"}}, \"$schema\": \"https://vega.github.io/schema/vega-lite/v4.17.0.json\", \"datasets\": {\"data-6c0b5d6b8f463d3bcbc85a5f2a93e820\": [{\"kind\": \"send\", \"per_call\": 2.020675095207844e-05, \"size\": 1000}, {\"kind\": \"Send\", \"per_call\": 3.0870292867897743e-06, \"size\": 1000}, {\"kind\": \"send\", \"per_call\": 2.2346984050790973e-05, \"size\": 1412}, {\"kind\": \"Send\", \"per_call\": 3.3788511805170788e-06, \"size\": 1412}, {\"kind\": \"send\", \"per_call\": 2.3456618405803366e-05, \"size\": 1995}, {\"kind\": \"Send\", \"per_call\": 3.3854537332141717e-06, \"size\": 1995}, {\"kind\": \"send\", \"per_call\": 3.4737834202998504e-05, \"size\": 2818}, {\"kind\": \"Send\", \"per_call\": 4.219438110201153e-06, \"size\": 2818}, {\"kind\": \"send\", \"per_call\": 3.5858951768036726e-05, \"size\": 3981}, {\"kind\": \"Send\", \"per_call\": 4.921354083906208e-06, \"size\": 3981}, {\"kind\": \"send\", \"per_call\": 4.719736385864711e-05, \"size\": 5623}, {\"kind\": \"Send\", \"per_call\": 7.989859993040042e-06, \"size\": 5623}, {\"kind\": \"send\", \"per_call\": 5.553769420904415e-05, \"size\": 7943}, {\"kind\": \"Send\", \"per_call\": 1.4378647498870615e-05, \"size\": 7943}, {\"kind\": \"send\", \"per_call\": 3.814401479378502e-05, \"size\": 11220}, {\"kind\": \"Send\", \"per_call\": 1.910177757509189e-05, \"size\": 11220}, {\"kind\": \"send\", \"per_call\": 4.6419370815891255e-05, \"size\": 15848}, {\"kind\": \"Send\", \"per_call\": 1.3004492370499789e-05, \"size\": 15848}, {\"kind\": \"send\", \"per_call\": 5.6328019847210166e-05, \"size\": 22387}, {\"kind\": \"Send\", \"per_call\": 1.401790919613646e-05, \"size\": 22387}, {\"kind\": \"send\", \"per_call\": 7.961705644669147e-05, \"size\": 31622}, {\"kind\": \"Send\", \"per_call\": 1.8953036221015888e-05, \"size\": 31622}, {\"kind\": \"send\", \"per_call\": 0.00011440758775496414, \"size\": 44668}, {\"kind\": \"Send\", \"per_call\": 2.7108923095113303e-05, \"size\": 44668}, {\"kind\": \"send\", \"per_call\": 0.00017292215140479581, \"size\": 63095}, {\"kind\": \"Send\", \"per_call\": 3.632928019787558e-05, \"size\": 63095}, {\"kind\": \"send\", \"per_call\": 0.0002441615301166252, \"size\": 89125}, {\"kind\": \"Send\", \"per_call\": 5.164305774779278e-05, \"size\": 89125}, {\"kind\": \"send\", \"per_call\": 0.00042067172782275694, \"size\": 125892}, {\"kind\": \"Send\", \"per_call\": 7.808946040941506e-05, \"size\": 125892}, {\"kind\": \"send\", \"per_call\": 0.000490088216958652, \"size\": 177827}, {\"kind\": \"Send\", \"per_call\": 0.00010467158517773959, \"size\": 177827}, {\"kind\": \"send\", \"per_call\": 0.0011289094827588997, \"size\": 251188}, {\"kind\": \"Send\", \"per_call\": 0.00015621106668468402, \"size\": 251188}, {\"kind\": \"send\", \"per_call\": 0.0016048344999971824, \"size\": 354813}, {\"kind\": \"Send\", \"per_call\": 0.00021542584238380585, \"size\": 354813}, {\"kind\": \"send\", \"per_call\": 0.002235219254458436, \"size\": 501187}, {\"kind\": \"Send\", \"per_call\": 0.0003272414756852268, \"size\": 501187}, {\"kind\": \"send\", \"per_call\": 0.0023459379449614006, \"size\": 707945}, {\"kind\": \"Send\", \"per_call\": 0.0004380627889064392, \"size\": 707945}, {\"kind\": \"send\", \"per_call\": 0.0034954222689115907, \"size\": 1000000}, {\"kind\": \"Send\", \"per_call\": 0.0006739356312303235, \"size\": 1000000}]}}, {\"mode\": \"vega-lite\"});\n",
+       "  })({\"config\": {\"view\": {\"continuousWidth\": 300, \"continuousHeight\": 300}}, \"data\": {\"name\": \"data-4c4fc92e0e1a424bd3227b2c54273213\"}, \"mark\": {\"type\": \"line\"}, \"encoding\": {\"color\": {\"field\": \"kind\", \"type\": \"nominal\"}, \"x\": {\"field\": \"size\", \"scale\": {\"type\": \"log\"}, \"type\": \"quantitative\"}, \"y\": {\"field\": \"per_call\", \"scale\": {\"type\": \"log\"}, \"type\": \"quantitative\"}}, \"$schema\": \"https://vega.github.io/schema/vega-lite/v5.8.0.json\", \"datasets\": {\"data-4c4fc92e0e1a424bd3227b2c54273213\": [{\"kind\": \"send\", \"per_call\": 5.775506150274818e-05, \"size\": 1000}, {\"kind\": \"Send\", \"per_call\": 8.281185842745932e-06, \"size\": 1000}, {\"kind\": \"send\", \"per_call\": 6.328053811435435e-05, \"size\": 1412}, {\"kind\": \"Send\", \"per_call\": 9.508815068343479e-06, \"size\": 1412}, {\"kind\": \"send\", \"per_call\": 6.75969483644748e-05, \"size\": 1995}, {\"kind\": \"Send\", \"per_call\": 1.1758442144843051e-05, \"size\": 1995}, {\"kind\": \"send\", \"per_call\": 8.300558815722279e-05, \"size\": 2818}, {\"kind\": \"Send\", \"per_call\": 1.637751941812932e-05, \"size\": 2818}, {\"kind\": \"send\", \"per_call\": 8.281956860129583e-05, \"size\": 3981}, {\"kind\": \"Send\", \"per_call\": 1.690232344500721e-05, \"size\": 3981}, {\"kind\": \"send\", \"per_call\": 8.380267487183417e-05, \"size\": 5623}, {\"kind\": \"Send\", \"per_call\": 2.0582310722414074e-05, \"size\": 5623}, {\"kind\": \"send\", \"per_call\": 0.00010358554911099405, \"size\": 7943}, {\"kind\": \"Send\", \"per_call\": 2.7573683670128988e-05, \"size\": 7943}, {\"kind\": \"send\", \"per_call\": 0.00011518810723602257, \"size\": 11220}, {\"kind\": \"Send\", \"per_call\": 3.0144625418479654e-05, \"size\": 11220}, {\"kind\": \"send\", \"per_call\": 0.00012362355272942942, \"size\": 15848}, {\"kind\": \"Send\", \"per_call\": 4.031957284451116e-05, \"size\": 15848}, {\"kind\": \"send\", \"per_call\": 0.00016430253301396097, \"size\": 22387}, {\"kind\": \"Send\", \"per_call\": 7.134116819515344e-05, \"size\": 22387}, {\"kind\": \"send\", \"per_call\": 0.00023901268096617696, \"size\": 31622}, {\"kind\": \"Send\", \"per_call\": 9.310301743805337e-05, \"size\": 31622}, {\"kind\": \"send\", \"per_call\": 0.0003215485679677578, \"size\": 44668}, {\"kind\": \"Send\", \"per_call\": 0.00010438555285050414, \"size\": 44668}, {\"kind\": \"send\", \"per_call\": 0.00039898201007878756, \"size\": 63095}, {\"kind\": \"Send\", \"per_call\": 0.0001457235241283505, \"size\": 63095}, {\"kind\": \"send\", \"per_call\": 0.0006034406932697654, \"size\": 89125}, {\"kind\": \"Send\", \"per_call\": 0.00022296708809156016, \"size\": 89125}, {\"kind\": \"send\", \"per_call\": 0.0011970003393591384, \"size\": 125892}, {\"kind\": \"Send\", \"per_call\": 0.00035065685339637014, \"size\": 125892}, {\"kind\": \"send\", \"per_call\": 0.00478046732211204, \"size\": 177827}, {\"kind\": \"Send\", \"per_call\": 0.0004945417780747411, \"size\": 177827}, {\"kind\": \"send\", \"per_call\": 0.004879202392308239, \"size\": 251188}, {\"kind\": \"Send\", \"per_call\": 0.0006860629585895947, \"size\": 251188}, {\"kind\": \"send\", \"per_call\": 0.010131335505123847, \"size\": 354813}, {\"kind\": \"Send\", \"per_call\": 0.0009442910743845542, \"size\": 354813}, {\"kind\": \"send\", \"per_call\": 0.01309982619999833, \"size\": 501187}, {\"kind\": \"Send\", \"per_call\": 0.0014706970000063918, \"size\": 501187}, {\"kind\": \"send\", \"per_call\": 0.020363317022161532, \"size\": 707945}, {\"kind\": \"Send\", \"per_call\": 0.001933314012863933, \"size\": 707945}, {\"kind\": \"send\", \"per_call\": 0.022532234484859862, \"size\": 1000000}, {\"kind\": \"Send\", \"per_call\": 0.003498196634009406, \"size\": 1000000}]}}, {\"mode\": \"vega-lite\"});\n",
        "</script>"
       ],
       "text/plain": [
        "alt.Chart(...)"
       ]
      },
-     "execution_count": 11,
+     "execution_count": 9,
      "metadata": {},
      "output_type": "execute_result"
     }
@@ -566,7 +577,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 12,
+   "execution_count": 10,
    "id": "aaeef9b8-5145-4f65-b6f3-5797665d79d0",
    "metadata": {
     "tags": []
@@ -576,19 +587,30 @@
      "data": {
       "text/html": [
        "\n",
-       "<div id=\"altair-viz-5657093710794d1bb0a77d3b908edd6f\"></div>\n",
+       "<style>\n",
+       "  #altair-viz-f202a84303004f368109b5895bf5061c.vega-embed {\n",
+       "    width: 100%;\n",
+       "    display: flex;\n",
+       "  }\n",
+       "\n",
+       "  #altair-viz-f202a84303004f368109b5895bf5061c.vega-embed details,\n",
+       "  #altair-viz-f202a84303004f368109b5895bf5061c.vega-embed details summary {\n",
+       "    position: relative;\n",
+       "  }\n",
+       "</style>\n",
+       "<div id=\"altair-viz-f202a84303004f368109b5895bf5061c\"></div>\n",
        "<script type=\"text/javascript\">\n",
        "  var VEGA_DEBUG = (typeof VEGA_DEBUG == \"undefined\") ? {} : VEGA_DEBUG;\n",
        "  (function(spec, embedOpt){\n",
        "    let outputDiv = document.currentScript.previousElementSibling;\n",
-       "    if (outputDiv.id !== \"altair-viz-5657093710794d1bb0a77d3b908edd6f\") {\n",
-       "      outputDiv = document.getElementById(\"altair-viz-5657093710794d1bb0a77d3b908edd6f\");\n",
+       "    if (outputDiv.id !== \"altair-viz-f202a84303004f368109b5895bf5061c\") {\n",
+       "      outputDiv = document.getElementById(\"altair-viz-f202a84303004f368109b5895bf5061c\");\n",
        "    }\n",
        "    const paths = {\n",
-       "      \"vega\": \"https://cdn.jsdelivr.net/npm//vega@5?noext\",\n",
-       "      \"vega-lib\": \"https://cdn.jsdelivr.net/npm//vega-lib?noext\",\n",
-       "      \"vega-lite\": \"https://cdn.jsdelivr.net/npm//vega-lite@4.17.0?noext\",\n",
-       "      \"vega-embed\": \"https://cdn.jsdelivr.net/npm//vega-embed@6?noext\",\n",
+       "      \"vega\": \"https://cdn.jsdelivr.net/npm/vega@5?noext\",\n",
+       "      \"vega-lib\": \"https://cdn.jsdelivr.net/npm/vega-lib?noext\",\n",
+       "      \"vega-lite\": \"https://cdn.jsdelivr.net/npm/vega-lite@5.8.0?noext\",\n",
+       "      \"vega-embed\": \"https://cdn.jsdelivr.net/npm/vega-embed@6?noext\",\n",
        "    };\n",
        "\n",
        "    function maybeLoadScript(lib, version) {\n",
@@ -623,19 +645,19 @@
        "      require([\"vega-embed\"], displayChart, err => showError(`Error loading script: ${err.message}`));\n",
        "    } else {\n",
        "      maybeLoadScript(\"vega\", \"5\")\n",
-       "        .then(() => maybeLoadScript(\"vega-lite\", \"4.17.0\"))\n",
+       "        .then(() => maybeLoadScript(\"vega-lite\", \"5.8.0\"))\n",
        "        .then(() => maybeLoadScript(\"vega-embed\", \"6\"))\n",
        "        .catch(showError)\n",
        "        .then(() => displayChart(vegaEmbed));\n",
        "    }\n",
-       "  })({\"config\": {\"view\": {\"continuousWidth\": 400, \"continuousHeight\": 300}}, \"data\": {\"name\": \"data-71c7123c470766abadc02b5bd0ac8a79\"}, \"mark\": \"line\", \"encoding\": {\"x\": {\"field\": \"size\", \"scale\": {\"type\": \"log\"}, \"type\": \"quantitative\"}, \"y\": {\"field\": \"speedup\", \"type\": \"quantitative\"}}, \"$schema\": \"https://vega.github.io/schema/vega-lite/v4.17.0.json\", \"datasets\": {\"data-71c7123c470766abadc02b5bd0ac8a79\": [{\"size\": 1000, \"Send\": 3.0870292867897743e-06, \"send\": 2.020675095207844e-05, \"speedup\": 6.545694606315704}, {\"size\": 1412, \"Send\": 3.3788511805170788e-06, \"send\": 2.2346984050790973e-05, \"speedup\": 6.613781684037096}, {\"size\": 1995, \"Send\": 3.3854537332141717e-06, \"send\": 2.3456618405803366e-05, \"speedup\": 6.928648345028039}, {\"size\": 2818, \"Send\": 4.219438110201153e-06, \"send\": 3.4737834202998504e-05, \"speedup\": 8.232810458580811}, {\"size\": 3981, \"Send\": 4.921354083906208e-06, \"send\": 3.5858951768036726e-05, \"speedup\": 7.2863994658101365}, {\"size\": 5623, \"Send\": 7.989859993040042e-06, \"send\": 4.719736385864711e-05, \"speedup\": 5.907157809994253}, {\"size\": 7943, \"Send\": 1.4378647498870615e-05, \"send\": 5.553769420904415e-05, \"speedup\": 3.862511701007095}, {\"size\": 11220, \"Send\": 1.910177757509189e-05, \"send\": 3.814401479378502e-05, \"speedup\": 1.9968829939431187}, {\"size\": 15848, \"Send\": 1.3004492370499789e-05, \"send\": 4.6419370815891255e-05, \"speedup\": 3.5694873350990526}, {\"size\": 22387, \"Send\": 1.401790919613646e-05, \"send\": 5.6328019847210166e-05, \"speedup\": 4.01828967922941}, {\"size\": 31622, \"Send\": 1.8953036221015888e-05, \"send\": 7.961705644669147e-05, \"speedup\": 4.2007547243754475}, {\"size\": 44668, \"Send\": 2.7108923095113303e-05, \"send\": 0.00011440758775496414, \"speedup\": 4.220292608214578}, {\"size\": 63095, \"Send\": 3.632928019787558e-05, \"send\": 0.00017292215140479581, \"speedup\": 4.759856249915674}, {\"size\": 89125, \"Send\": 5.164305774779278e-05, \"send\": 0.0002441615301166252, \"speedup\": 4.727867418482993}, {\"size\": 125892, \"Send\": 7.808946040941506e-05, \"send\": 0.00042067172782275694, \"speedup\": 5.387048721008162}, {\"size\": 177827, \"Send\": 0.00010467158517773959, \"send\": 0.000490088216958652, \"speedup\": 4.682151475268558}, {\"size\": 251188, \"Send\": 0.00015621106668468402, \"send\": 0.0011289094827588997, \"speedup\": 7.226821420006253}, {\"size\": 354813, \"Send\": 0.00021542584238380585, \"send\": 0.0016048344999971824, \"speedup\": 7.449591387174365}, {\"size\": 501187, \"Send\": 0.0003272414756852268, \"send\": 0.002235219254458436, \"speedup\": 6.830488860796151}, {\"size\": 707945, \"Send\": 0.0004380627889064392, \"send\": 0.0023459379449614006, \"speedup\": 5.355255009944345}, {\"size\": 1000000, \"Send\": 0.0006739356312303235, \"send\": 0.0034954222689115907, \"speedup\": 5.18658178456957}]}}, {\"mode\": \"vega-lite\"});\n",
+       "  })({\"config\": {\"view\": {\"continuousWidth\": 300, \"continuousHeight\": 300}}, \"data\": {\"name\": \"data-0eab53a9aa95bb68aeee16e2fa5351ae\"}, \"mark\": {\"type\": \"line\"}, \"encoding\": {\"x\": {\"field\": \"size\", \"scale\": {\"type\": \"log\"}, \"type\": \"quantitative\"}, \"y\": {\"field\": \"speedup\", \"type\": \"quantitative\"}}, \"$schema\": \"https://vega.github.io/schema/vega-lite/v5.8.0.json\", \"datasets\": {\"data-0eab53a9aa95bb68aeee16e2fa5351ae\": [{\"size\": 1000, \"Send\": 8.281185842745932e-06, \"send\": 5.775506150274818e-05, \"speedup\": 6.974250137537954}, {\"size\": 1412, \"Send\": 9.508815068343479e-06, \"send\": 6.328053811435435e-05, \"speedup\": 6.654934148948422}, {\"size\": 1995, \"Send\": 1.1758442144843051e-05, \"send\": 6.75969483644748e-05, \"speedup\": 5.748801374518909}, {\"size\": 2818, \"Send\": 1.637751941812932e-05, \"send\": 8.300558815722279e-05, \"speedup\": 5.068263760709612}, {\"size\": 3981, \"Send\": 1.690232344500721e-05, \"send\": 8.281956860129583e-05, \"speedup\": 4.8998925426291}, {\"size\": 5623, \"Send\": 2.0582310722414074e-05, \"send\": 8.380267487183417e-05, \"speedup\": 4.071587296589265}, {\"size\": 7943, \"Send\": 2.7573683670128988e-05, \"send\": 0.00010358554911099405, \"speedup\": 3.7566815645749188}, {\"size\": 11220, \"Send\": 3.0144625418479654e-05, \"send\": 0.00011518810723602257, \"speedup\": 3.8211822385229723}, {\"size\": 15848, \"Send\": 4.031957284451116e-05, \"send\": 0.00012362355272942942, \"speedup\": 3.0660928181499503}, {\"size\": 22387, \"Send\": 7.134116819515344e-05, \"send\": 0.00016430253301396097, \"speedup\": 2.3030535828136727}, {\"size\": 31622, \"Send\": 9.310301743805337e-05, \"send\": 0.00023901268096617696, \"speedup\": 2.5671851197003948}, {\"size\": 44668, \"Send\": 0.00010438555285050414, \"send\": 0.0003215485679677578, \"speedup\": 3.0803933991542283}, {\"size\": 63095, \"Send\": 0.0001457235241283505, \"send\": 0.00039898201007878756, \"speedup\": 2.737938246177548}, {\"size\": 89125, \"Send\": 0.00022296708809156016, \"send\": 0.0006034406932697654, \"speedup\": 2.7064115086885194}, {\"size\": 125892, \"Send\": 0.00035065685339637014, \"send\": 0.0011970003393591384, \"speedup\": 3.413594594730739}, {\"size\": 177827, \"Send\": 0.0004945417780747411, \"send\": 0.00478046732211204, \"speedup\": 9.666457990106467}, {\"size\": 251188, \"Send\": 0.0006860629585895947, \"send\": 0.004879202392308239, \"speedup\": 7.111887227287248}, {\"size\": 354813, \"Send\": 0.0009442910743845542, \"send\": 0.010131335505123847, \"speedup\": 10.729038725402535}, {\"size\": 501187, \"Send\": 0.0014706970000063918, \"send\": 0.01309982619999833, \"speedup\": 8.907223037744279}, {\"size\": 707945, \"Send\": 0.001933314012863933, \"send\": 0.020363317022161532, \"speedup\": 10.532855442348001}, {\"size\": 1000000, \"Send\": 0.003498196634009406, \"send\": 0.022532234484859862, \"speedup\": 6.44110004160483}]}}, {\"mode\": \"vega-lite\"});\n",
        "</script>"
       ],
       "text/plain": [
        "alt.Chart(...)"
       ]
      },
-     "execution_count": 12,
+     "execution_count": 10,
      "metadata": {},
      "output_type": "execute_result"
     }
@@ -660,7 +682,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 13,
+   "execution_count": 11,
    "id": "1ef0812d-9661-40f2-8858-b1d0c3eba578",
    "metadata": {
     "tags": []
@@ -695,7 +717,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.10.7"
+   "version": "3.10.13"
   },
   "widgets": {
    "application/vnd.jupyter.widget-state+json": {

From f27116dd7a18c3ba202fcd6d3d8a26b9da38f1a8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=B8rgen=20S=2E=20Dokken?= <dokken@simula.no>
Date: Fri, 5 Jan 2024 14:31:55 +0100
Subject: [PATCH 2/2] Add back ipywidgets

---
 environment.yml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/environment.yml b/environment.yml
index 1cba4ab..c6e9364 100644
--- a/environment.yml
+++ b/environment.yml
@@ -17,3 +17,4 @@ dependencies:
   - fenics-dolfinx==0.6.*
   - petsc4py
   - trame
+  - ipywidgets