<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>MPI | Hailin Liu</title><link>https://hailin.ai/tags/mpi/</link><atom:link href="https://hailin.ai/tags/mpi/index.xml" rel="self" type="application/rss+xml"/><description>MPI</description><generator>HugoBlox Kit (https://hugoblox.com)</generator><language>en-us</language><lastBuildDate>Mon, 15 Dec 2025 00:00:00 +0000</lastBuildDate><image><url>https://hailin.ai/media/icon_hu_76af94951e63d377.png</url><title>MPI</title><link>https://hailin.ai/tags/mpi/</link></image><item><title>Building a Parallel Poisson Solver with OpenMP, MPI, and CUDA</title><link>https://hailin.ai/projects/parallel-poisson-solver/</link><pubDate>Mon, 15 Dec 2025 00:00:00 +0000</pubDate><guid>https://hailin.ai/projects/parallel-poisson-solver/</guid><description>
&lt;div class="hb-cards mt-4 grid gap-4 not-prose" style="--hb-cols: 1;"&gt;
&lt;a
class="hb-card group"href="grading/" &gt;
&lt;span class="hb-card-title pt-4 px-4"&gt;
&lt;svg style="height: 1em; width: 1em;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"&gt;&lt;path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M4.26 10.147a60 60 0 0 0-.491 6.347A48.6 48.6 0 0 1 12 20.904a48.6 48.6 0 0 1 8.232-4.41a61 61 0 0 0-.491-6.347m-15.482 0a51 51 0 0 0-2.658-.813A60 60 0 0 1 12 3.493a60 60 0 0 1 10.399 5.84q-1.345.372-2.658.814m-15.482 0A51 51 0 0 1 12 13.489a50.7 50.7 0 0 1 7.74-3.342M6.75 15a.75.75 0 1 0 0-1.5a.75.75 0 0 0 0 1.5m0 0v-3.675A55 55 0 0 1 12 8.443m-7.007 11.55A5.98 5.98 0 0 0 6.75 15.75v-1.5"/&gt;&lt;/svg&gt;How This Coursework Is Graded in Practice&lt;/span&gt;&lt;div class="hb-card-subtitle"&gt;Exam exemption, CUDA grading, and the final report submission.&lt;/div&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;h2 id="what-are-we-asked-to-build"&gt;What Are We Asked to Build?&lt;/h2&gt;
&lt;p&gt;The SM25 coursework follows one numerical problem through several stages of
parallelization. We begin with a two-dimensional Poisson equation with
Dirichlet boundary conditions, construct a finite-difference approximation,
and solve the resulting linear system with a preconditioned conjugate-gradient
method. From that common numerical core, the two assignments together gradually
introduce shared-memory parallelism with OpenMP, distributed-memory execution with MPI,
a hybrid MPI+OpenMP implementation, and finally GPU acceleration with
MPI+CUDA.&lt;/p&gt;
&lt;p&gt;The important part is to keep these stages connected. The OpenMP version
should grow from a verified sequential solver; the MPI version needs a
two-dimensional decomposition of the same computational grid; and the CUDA
stage continues from the distributed implementation by moving suitable local
operations to the GPU. Along the way, the two assignments also require
correctness checks, timing breakdowns, speedup and efficiency measurements, cluster job
configuration, and a final report that explains the observed performance.&lt;/p&gt;
&lt;p&gt;This walkthrough follows that development path from beginning to end. Each
stage focuses on the new responsibility introduced by the next execution
model: first getting the numerical method right, then parallelizing local
loops, distributing the grid across processes, coordinating MPI and OpenMP,
moving computational kernels to CUDA, and finally running and evaluating the
program on IBM Polus. The accompanying SM25 repository provides a working
reference implementation covering this development path, including the solver
code, build scripts, cluster configuration, numerical outputs, plots, and the
course report.&lt;/p&gt;
&lt;h3 id="steps-to-follow"&gt;Steps to Follow&lt;/h3&gt;
&lt;div class="hb-cards mt-4 grid gap-4 not-prose" style="--hb-cols: 1;"&gt;
&lt;a
class="hb-card group"href="steps/step-1" &gt;
&lt;span class="hb-card-title pt-4 px-4"&gt;
&lt;svg style="height: 1em; width: 1em;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"&gt;&lt;path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M19.5 14.25v-2.625a3.375 3.375 0 0 0-3.375-3.375h-1.5A1.125 1.125 0 0 1 13.5 7.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H8.25m0 12.75h7.5m-7.5 3H12M10.5 2.25H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 0 0-9-9"/&gt;&lt;/svg&gt;Step 1 — From the Mathematical Problem to the Solver&lt;/span&gt;&lt;div class="hb-card-subtitle"&gt;Derive the numerical scheme, the fictitious-domain operator, and the PCG core.&lt;/div&gt;&lt;/a&gt;
&lt;a
class="hb-card group"href="steps/step-2" &gt;
&lt;span class="hb-card-title pt-4 px-4"&gt;
&lt;svg style="height: 1em; width: 1em;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"&gt;&lt;path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M19.5 14.25v-2.625a3.375 3.375 0 0 0-3.375-3.375h-1.5A1.125 1.125 0 0 1 13.5 7.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H8.25m0 12.75h7.5m-7.5 3H12M10.5 2.25H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 0 0-9-9"/&gt;&lt;/svg&gt;Step 2 — Build the Sequential Reference Solver&lt;/span&gt;&lt;div class="hb-card-subtitle"&gt;Assemble the sequential program, run the baseline cases, and validate it.&lt;/div&gt;&lt;/a&gt;
&lt;a
class="hb-card group"href="steps/step-3" &gt;
&lt;span class="hb-card-title pt-4 px-4"&gt;
&lt;svg style="height: 1em; width: 1em;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"&gt;&lt;path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M19.5 14.25v-2.625a3.375 3.375 0 0 0-3.375-3.375h-1.5A1.125 1.125 0 0 1 13.5 7.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H8.25m0 12.75h7.5m-7.5 3H12M10.5 2.25H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 0 0-9-9"/&gt;&lt;/svg&gt;Step 3 — Parallelize the Solver with OpenMP&lt;/span&gt;&lt;div class="hb-card-subtitle"&gt;Parallelize the pointwise, stencil, and reduction kernels with OpenMP, then measure speedup and efficiency.&lt;/div&gt;&lt;/a&gt;
&lt;a
class="hb-card group"href="steps/step-4" &gt;
&lt;span class="hb-card-title pt-4 px-4"&gt;
&lt;svg style="height: 1em; width: 1em;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"&gt;&lt;path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M19.5 14.25v-2.625a3.375 3.375 0 0 0-3.375-3.375h-1.5A1.125 1.125 0 0 1 13.5 7.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H8.25m0 12.75h7.5m-7.5 3H12M10.5 2.25H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 0 0-9-9"/&gt;&lt;/svg&gt;Step 4 — Decompose the Domain with MPI&lt;/span&gt;&lt;div class="hb-card-subtitle"&gt;Split the grid into MPI subdomains, exchange halo values, and combine reductions across processes.&lt;/div&gt;&lt;/a&gt;
&lt;a
class="hb-card group"href="steps/step-5" &gt;
&lt;span class="hb-card-title pt-4 px-4"&gt;
&lt;svg style="height: 1em; width: 1em;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"&gt;&lt;path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M19.5 14.25v-2.625a3.375 3.375 0 0 0-3.375-3.375h-1.5A1.125 1.125 0 0 1 13.5 7.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H8.25m0 12.75h7.5m-7.5 3H12M10.5 2.25H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 0 0-9-9"/&gt;&lt;/svg&gt;Step 5 — Combine MPI and OpenMP&lt;/span&gt;&lt;div class="hb-card-subtitle"&gt;Add OpenMP threads inside each MPI process to build the hybrid MPI+OpenMP solver.&lt;/div&gt;&lt;/a&gt;
&lt;a
class="hb-card group"href="steps/step-6" &gt;
&lt;span class="hb-card-title pt-4 px-4"&gt;
&lt;svg style="height: 1em; width: 1em;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"&gt;&lt;path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M19.5 14.25v-2.625a3.375 3.375 0 0 0-3.375-3.375h-1.5A1.125 1.125 0 0 1 13.5 7.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H8.25m0 12.75h7.5m-7.5 3H12M10.5 2.25H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 0 0-9-9"/&gt;&lt;/svg&gt;Step 6 — Extend the MPI Solver to CUDA&lt;/span&gt;&lt;div class="hb-card-subtitle"&gt;Move the local numerical kernels to the GPU while keeping the MPI decomposition.&lt;/div&gt;&lt;/a&gt;
&lt;a
class="hb-card group"href="steps/step-7" &gt;
&lt;span class="hb-card-title pt-4 px-4"&gt;
&lt;svg style="height: 1em; width: 1em;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"&gt;&lt;path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M19.5 14.25v-2.625a3.375 3.375 0 0 0-3.375-3.375h-1.5A1.125 1.125 0 0 1 13.5 7.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H8.25m0 12.75h7.5m-7.5 3H12M10.5 2.25H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 0 0-9-9"/&gt;&lt;/svg&gt;Step 7 — Run the Solver on IBM Polus&lt;/span&gt;&lt;div class="hb-card-subtitle"&gt;Configure, submit, and run every execution mode on the IBM Polus cluster.&lt;/div&gt;&lt;/a&gt;
&lt;a
class="hb-card group"href="steps/step-8" &gt;
&lt;span class="hb-card-title pt-4 px-4"&gt;
&lt;svg style="height: 1em; width: 1em;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"&gt;&lt;path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M19.5 14.25v-2.625a3.375 3.375 0 0 0-3.375-3.375h-1.5A1.125 1.125 0 0 1 13.5 7.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H8.25m0 12.75h7.5m-7.5 3H12M10.5 2.25H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 0 0-9-9"/&gt;&lt;/svg&gt;Step 8 — Verify Correctness and Measure Performance&lt;/span&gt;&lt;div class="hb-card-subtitle"&gt;Validate numerical correctness across all modes and report speedup and efficiency.&lt;/div&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;h2 id="sources"&gt;Sources&lt;/h2&gt;
&lt;p&gt;This walkthrough follows the SM25 coursework of the course
&lt;em&gt;Supercomputer Modeling and Technologies&lt;/em&gt; (MSU, 2025) and summarizes its
requirements in its own words. The official course materials, including the
assignment statements, submission deadlines, and the final-report format, are
available in the course&amp;rsquo;s shared folder:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item></channel></rss>