mirror of
https://github.com/fverdugo/XM_40017.git
synced 2025-11-09 00:24:25 +01:00
build based on 567534f
This commit is contained in:
parent
4d93e76dbf
commit
dad32dba25
@ -1 +1 @@
|
||||
{"documenter":{"julia_version":"1.10.4","generation_timestamp":"2024-08-22T08:36:00","documenter_version":"1.6.0"}}
|
||||
{"documenter":{"julia_version":"1.10.4","generation_timestamp":"2024-08-26T11:01:02","documenter_version":"1.6.0"}}
|
||||
@ -14,4 +14,4 @@
|
||||
var myIframe = document.getElementById("notebook");
|
||||
iFrameResize({log:true}, myIframe);
|
||||
});
|
||||
</script></article><nav class="docs-footer"><p class="footer-message">Powered by <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> and the <a href="https://julialang.org/">Julia Programming Language</a>.</p></nav></div><div class="modal" id="documenter-settings"><div class="modal-background"></div><div class="modal-card"><header class="modal-card-head"><p class="modal-card-title">Settings</p><button class="delete"></button></header><section class="modal-card-body"><p><label class="label">Theme</label><div class="select"><select id="documenter-themepicker"><option value="auto">Automatic (OS)</option><option value="documenter-light">documenter-light</option><option value="documenter-dark">documenter-dark</option><option value="catppuccin-latte">catppuccin-latte</option><option value="catppuccin-frappe">catppuccin-frappe</option><option value="catppuccin-macchiato">catppuccin-macchiato</option><option value="catppuccin-mocha">catppuccin-mocha</option></select></div></p><hr/><p>This document was generated with <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> version 1.6.0 on <span class="colophon-date" title="Thursday 22 August 2024 08:36">Thursday 22 August 2024</span>. Using Julia version 1.10.4.</p></section><footer class="modal-card-foot"></footer></div></div></div></body></html>
|
||||
</script></article><nav class="docs-footer"><p class="footer-message">Powered by <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> and the <a href="https://julialang.org/">Julia Programming Language</a>.</p></nav></div><div class="modal" id="documenter-settings"><div class="modal-background"></div><div class="modal-card"><header class="modal-card-head"><p class="modal-card-title">Settings</p><button class="delete"></button></header><section class="modal-card-body"><p><label class="label">Theme</label><div class="select"><select id="documenter-themepicker"><option value="auto">Automatic (OS)</option><option value="documenter-light">documenter-light</option><option value="documenter-dark">documenter-dark</option><option value="catppuccin-latte">catppuccin-latte</option><option value="catppuccin-frappe">catppuccin-frappe</option><option value="catppuccin-macchiato">catppuccin-macchiato</option><option value="catppuccin-mocha">catppuccin-mocha</option></select></div></p><hr/><p>This document was generated with <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> version 1.6.0 on <span class="colophon-date" title="Monday 26 August 2024 11:01">Monday 26 August 2024</span>. Using Julia version 1.10.4.</p></section><footer class="modal-card-foot"></footer></div></div></div></body></html>
|
||||
|
||||
@ -14,4 +14,4 @@
|
||||
var myIframe = document.getElementById("notebook");
|
||||
iFrameResize({log:true}, myIframe);
|
||||
});
|
||||
</script></article><nav class="docs-footer"><p class="footer-message">Powered by <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> and the <a href="https://julialang.org/">Julia Programming Language</a>.</p></nav></div><div class="modal" id="documenter-settings"><div class="modal-background"></div><div class="modal-card"><header class="modal-card-head"><p class="modal-card-title">Settings</p><button class="delete"></button></header><section class="modal-card-body"><p><label class="label">Theme</label><div class="select"><select id="documenter-themepicker"><option value="auto">Automatic (OS)</option><option value="documenter-light">documenter-light</option><option value="documenter-dark">documenter-dark</option><option value="catppuccin-latte">catppuccin-latte</option><option value="catppuccin-frappe">catppuccin-frappe</option><option value="catppuccin-macchiato">catppuccin-macchiato</option><option value="catppuccin-mocha">catppuccin-mocha</option></select></div></p><hr/><p>This document was generated with <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> version 1.6.0 on <span class="colophon-date" title="Thursday 22 August 2024 08:36">Thursday 22 August 2024</span>. Using Julia version 1.10.4.</p></section><footer class="modal-card-foot"></footer></div></div></div></body></html>
|
||||
</script></article><nav class="docs-footer"><p class="footer-message">Powered by <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> and the <a href="https://julialang.org/">Julia Programming Language</a>.</p></nav></div><div class="modal" id="documenter-settings"><div class="modal-background"></div><div class="modal-card"><header class="modal-card-head"><p class="modal-card-title">Settings</p><button class="delete"></button></header><section class="modal-card-body"><p><label class="label">Theme</label><div class="select"><select id="documenter-themepicker"><option value="auto">Automatic (OS)</option><option value="documenter-light">documenter-light</option><option value="documenter-dark">documenter-dark</option><option value="catppuccin-latte">catppuccin-latte</option><option value="catppuccin-frappe">catppuccin-frappe</option><option value="catppuccin-macchiato">catppuccin-macchiato</option><option value="catppuccin-mocha">catppuccin-mocha</option></select></div></p><hr/><p>This document was generated with <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> version 1.6.0 on <span class="colophon-date" title="Monday 26 August 2024 11:01">Monday 26 August 2024</span>. Using Julia version 1.10.4.</p></section><footer class="modal-card-foot"></footer></div></div></div></body></html>
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -14,4 +14,4 @@
|
||||
var myIframe = document.getElementById("notebook");
|
||||
iFrameResize({log:true}, myIframe);
|
||||
});
|
||||
</script></article><nav class="docs-footer"><p class="footer-message">Powered by <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> and the <a href="https://julialang.org/">Julia Programming Language</a>.</p></nav></div><div class="modal" id="documenter-settings"><div class="modal-background"></div><div class="modal-card"><header class="modal-card-head"><p class="modal-card-title">Settings</p><button class="delete"></button></header><section class="modal-card-body"><p><label class="label">Theme</label><div class="select"><select id="documenter-themepicker"><option value="auto">Automatic (OS)</option><option value="documenter-light">documenter-light</option><option value="documenter-dark">documenter-dark</option><option value="catppuccin-latte">catppuccin-latte</option><option value="catppuccin-frappe">catppuccin-frappe</option><option value="catppuccin-macchiato">catppuccin-macchiato</option><option value="catppuccin-mocha">catppuccin-mocha</option></select></div></p><hr/><p>This document was generated with <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> version 1.6.0 on <span class="colophon-date" title="Thursday 22 August 2024 08:36">Thursday 22 August 2024</span>. Using Julia version 1.10.4.</p></section><footer class="modal-card-foot"></footer></div></div></div></body></html>
|
||||
</script></article><nav class="docs-footer"><p class="footer-message">Powered by <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> and the <a href="https://julialang.org/">Julia Programming Language</a>.</p></nav></div><div class="modal" id="documenter-settings"><div class="modal-background"></div><div class="modal-card"><header class="modal-card-head"><p class="modal-card-title">Settings</p><button class="delete"></button></header><section class="modal-card-body"><p><label class="label">Theme</label><div class="select"><select id="documenter-themepicker"><option value="auto">Automatic (OS)</option><option value="documenter-light">documenter-light</option><option value="documenter-dark">documenter-dark</option><option value="catppuccin-latte">catppuccin-latte</option><option value="catppuccin-frappe">catppuccin-frappe</option><option value="catppuccin-macchiato">catppuccin-macchiato</option><option value="catppuccin-mocha">catppuccin-mocha</option></select></div></p><hr/><p>This document was generated with <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> version 1.6.0 on <span class="colophon-date" title="Monday 26 August 2024 11:01">Monday 26 August 2024</span>. Using Julia version 1.10.4.</p></section><footer class="modal-card-foot"></footer></div></div></div></body></html>
|
||||
|
||||
@ -27,9 +27,9 @@
|
||||
"\n",
|
||||
"In this notebook, we will learn\n",
|
||||
"\n",
|
||||
"- How to paralleize a Jacobi method\n",
|
||||
"- How to paralleize the Jacobi method\n",
|
||||
"- How the data partition can impact the performance of a distributed algorithm\n",
|
||||
"- How to use latency hiding\n",
|
||||
"- How to use latency hiding to improve parallel performance\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
@ -93,9 +93,12 @@
|
||||
"id": "93e84ff8",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"When solving a Laplace equation in 1D, the Jacobi method leads to the following iterative scheme: The entry $i$ of vector $u$ at iteration $t+1$ is computed as:\n",
|
||||
"When solving a [Laplace equation](https://en.wikipedia.org/wiki/Laplace%27s_equation) in 1D, the Jacobi method leads to the following iterative scheme: The entry $i$ of vector $u$ at iteration $t+1$ is computed as:\n",
|
||||
"\n",
|
||||
"$u^{t+1}_i = \\dfrac{u^t_{i-1}+u^t_{i+1}}{2}$"
|
||||
"$u^{t+1}_i = \\dfrac{u^t_{i-1}+u^t_{i+1}}{2}$\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"This iterative is yet simple but shares fundamental challenges with many other algorithms used in scientific computing. This is why we are studying it here.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -130,6 +133,14 @@
|
||||
"end"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "432bd862",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"If you run it for zero iterations, we will see the initial condition."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
@ -140,14 +151,78 @@
|
||||
"jacobi(5,0)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "c75cb9a6",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"If you run it for enough iterations, you will see the expected solution of the Laplace equation: values that vary linearly form -1 to 1."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "b52be374",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"jacobi(5,100)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "22fda724",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"In our version of the jacobi method, we return after a given number of iterations. Other stopping criteria are possible. For instance, iterate until the difference between u and u_new is below a tolerance:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "15de7bf5",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"using LinearAlgebra: norm\n",
|
||||
"function jacobi_with_tol(n,tol)\n",
|
||||
" u = zeros(n+2)\n",
|
||||
" u[1] = -1\n",
|
||||
" u[end] = 1\n",
|
||||
" u_new = copy(u)\n",
|
||||
" increment = similar(u)\n",
|
||||
" while true\n",
|
||||
" for i in 2:(n+1)\n",
|
||||
" u_new[i] = 0.5*(u[i-1]+u[i+1])\n",
|
||||
" end\n",
|
||||
" increment .= u_new .- u\n",
|
||||
" if norm(increment)/norm(u_new) < tol\n",
|
||||
" return u_new\n",
|
||||
" end\n",
|
||||
" u, u_new = u_new, u\n",
|
||||
" end\n",
|
||||
" u\n",
|
||||
"end"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "697ad307",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"n = 5\n",
|
||||
"tol = 1e-9\n",
|
||||
"jacobi_with_tol(n,tol)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "6e085701",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<div class=\"alert alert-block alert-info\">\n",
|
||||
"<b>Note:</b> In our version of the jacobi method, we return after a given number of iterations. Other stopping criteria are possible. For instance, iterate until the difference between u and u_new is below a tolerance.\n",
|
||||
"</div>"
|
||||
"However, we are not going to parallelize this more complex in this notebook (we will consider it later in this course)."
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -156,7 +231,7 @@
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"\n",
|
||||
"### Where can we exploit parallelism?\n",
|
||||
"## Where can we exploit parallelism?\n",
|
||||
"\n",
|
||||
"Look at the two nested loops in the sequential implementation:\n",
|
||||
"\n",
|
||||
@ -169,8 +244,8 @@
|
||||
"end\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"- The outer loop cannot be parallelized. The value of `u` at step `t+1` depends on the value at the previous step `t`.\n",
|
||||
"- The inner loop can be parallelized.\n",
|
||||
"- The outer loop over `t` cannot be parallelized. The value of `u` at step `t+1` depends on the value at the previous step `t`.\n",
|
||||
"- The inner loop is trivially parallel. The loop iterations are independent (any order is possible).\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
@ -386,19 +461,11 @@
|
||||
"source": [
|
||||
"### Communication overhead\n",
|
||||
"- We update $N/P$ entries in each process at each iteration, where $N$ is the total length of the vector and $P$ the number of processes\n",
|
||||
"- Thus, computation complexity is $O(N/P)$\n",
|
||||
"- We need to get remote entries from 2 neighbors (2 messages per iteration)\n",
|
||||
"- We need to communicate 1 entry per message\n",
|
||||
"- Communication/computation ration is $O(P/N)$ (potentially scalable if $P<<N$)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "f6b54b7b",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 1D Implementation\n",
|
||||
"\n",
|
||||
"We consider the implementation using MPI. The programming model of MPI is generally better suited for data-parallel algorithms like this one than the task-based model provided by Distributed.jl. In any case, one can also implement it using Distributed, but it requires some extra effort to setup the remote channels right for the communication between neighbor processes."
|
||||
"- Thus, communication complexity is $O(1)$\n",
|
||||
"- Communication/computation ration is $O(P/N)$, making the algorithm potentially scalable if $P<<N$.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -457,8 +524,10 @@
|
||||
"id": "8ed4129c",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### MPI Code\n",
|
||||
"## MPI implementation\n",
|
||||
"\n",
|
||||
"We consider the implementation using MPI. The programming model of MPI is generally better suited for data-parallel algorithms like this one than the task-based model provided by Distributed.jl. In any case, one can also implement it using Distributed.jl, but it requires some extra effort to setup the remote channels right for the communication between neighbor processes.\n",
|
||||
" \n",
|
||||
"Take a look at the implementation below and try to understand it.\n"
|
||||
]
|
||||
},
|
||||
@ -749,7 +818,7 @@
|
||||
"```\n",
|
||||
"\n",
|
||||
"- The outer loop cannot be parallelized (like in the 1d case). \n",
|
||||
"- The two inner loops can be parallelized\n"
|
||||
"- The two inner loops are trivially parallel\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@ -14,4 +14,4 @@
|
||||
var myIframe = document.getElementById("notebook");
|
||||
iFrameResize({log:true}, myIframe);
|
||||
});
|
||||
</script></article><nav class="docs-footer"><a class="docs-footer-prevpage" href="../julia_mpi/">« MPI (point-to-point)</a><a class="docs-footer-nextpage" href="../solutions_for_all_notebooks/">Solutions »</a><div class="flexbox-break"></div><p class="footer-message">Powered by <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> and the <a href="https://julialang.org/">Julia Programming Language</a>.</p></nav></div><div class="modal" id="documenter-settings"><div class="modal-background"></div><div class="modal-card"><header class="modal-card-head"><p class="modal-card-title">Settings</p><button class="delete"></button></header><section class="modal-card-body"><p><label class="label">Theme</label><div class="select"><select id="documenter-themepicker"><option value="auto">Automatic (OS)</option><option value="documenter-light">documenter-light</option><option value="documenter-dark">documenter-dark</option><option value="catppuccin-latte">catppuccin-latte</option><option value="catppuccin-frappe">catppuccin-frappe</option><option value="catppuccin-macchiato">catppuccin-macchiato</option><option value="catppuccin-mocha">catppuccin-mocha</option></select></div></p><hr/><p>This document was generated with <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> version 1.6.0 on <span class="colophon-date" title="Thursday 22 August 2024 08:36">Thursday 22 August 2024</span>. Using Julia version 1.10.4.</p></section><footer class="modal-card-foot"></footer></div></div></div></body></html>
|
||||
</script></article><nav class="docs-footer"><a class="docs-footer-prevpage" href="../julia_mpi/">« MPI (point-to-point)</a><a class="docs-footer-nextpage" href="../solutions_for_all_notebooks/">Solutions »</a><div class="flexbox-break"></div><p class="footer-message">Powered by <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> and the <a href="https://julialang.org/">Julia Programming Language</a>.</p></nav></div><div class="modal" id="documenter-settings"><div class="modal-background"></div><div class="modal-card"><header class="modal-card-head"><p class="modal-card-title">Settings</p><button class="delete"></button></header><section class="modal-card-body"><p><label class="label">Theme</label><div class="select"><select id="documenter-themepicker"><option value="auto">Automatic (OS)</option><option value="documenter-light">documenter-light</option><option value="documenter-dark">documenter-dark</option><option value="catppuccin-latte">catppuccin-latte</option><option value="catppuccin-frappe">catppuccin-frappe</option><option value="catppuccin-macchiato">catppuccin-macchiato</option><option value="catppuccin-mocha">catppuccin-mocha</option></select></div></p><hr/><p>This document was generated with <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> version 1.6.0 on <span class="colophon-date" title="Monday 26 August 2024 11:01">Monday 26 August 2024</span>. Using Julia version 1.10.4.</p></section><footer class="modal-card-foot"></footer></div></div></div></body></html>
|
||||
|
||||
@ -7543,9 +7543,9 @@ a.anchor-link {
|
||||
</div><div class="jp-RenderedHTMLCommon jp-RenderedMarkdown jp-MarkdownOutput" data-mime-type="text/markdown">
|
||||
<h2 id="Contents">Contents<a class="anchor-link" href="#Contents">¶</a></h2><p>In this notebook, we will learn</p>
|
||||
<ul>
|
||||
<li>How to paralleize a Jacobi method</li>
|
||||
<li>How to paralleize the Jacobi method</li>
|
||||
<li>How the data partition can impact the performance of a distributed algorithm</li>
|
||||
<li>How to use latency hiding</li>
|
||||
<li>How to use latency hiding to improve parallel performance</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@ -7621,8 +7621,9 @@ a.anchor-link {
|
||||
</div>
|
||||
<div class="jp-InputArea jp-Cell-inputArea"><div class="jp-InputPrompt jp-InputArea-prompt">
|
||||
</div><div class="jp-RenderedHTMLCommon jp-RenderedMarkdown jp-MarkdownOutput" data-mime-type="text/markdown">
|
||||
<p>When solving a Laplace equation in 1D, the Jacobi method leads to the following iterative scheme: The entry $i$ of vector $u$ at iteration $t+1$ is computed as:</p>
|
||||
<p>When solving a <a href="https://en.wikipedia.org/wiki/Laplace%27s_equation">Laplace equation</a> in 1D, the Jacobi method leads to the following iterative scheme: The entry $i$ of vector $u$ at iteration $t+1$ is computed as:</p>
|
||||
<p>$u^{t+1}_i = \dfrac{u^t_{i-1}+u^t_{i+1}}{2}$</p>
|
||||
<p>This iterative is yet simple but shares fundamental challenges with many other algorithms used in scientific computing. This is why we are studying it here.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -7663,6 +7664,17 @@ a.anchor-link {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="jp-Cell jp-MarkdownCell jp-Notebook-cell" id="cell-id=432bd862">
|
||||
<div class="jp-Cell-inputWrapper" tabindex="0">
|
||||
<div class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser">
|
||||
</div>
|
||||
<div class="jp-InputArea jp-Cell-inputArea"><div class="jp-InputPrompt jp-InputArea-prompt">
|
||||
</div><div class="jp-RenderedHTMLCommon jp-RenderedMarkdown jp-MarkdownOutput" data-mime-type="text/markdown">
|
||||
<p>If you run it for zero iterations, we will see the initial condition.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div><div class="jp-Cell jp-CodeCell jp-Notebook-cell jp-mod-noOutputs" id="cell-id=76e1eba1">
|
||||
<div class="jp-Cell-inputWrapper" tabindex="0">
|
||||
<div class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser">
|
||||
@ -7678,15 +7690,97 @@ a.anchor-link {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="jp-Cell jp-MarkdownCell jp-Notebook-cell" id="cell-id=c75cb9a6">
|
||||
<div class="jp-Cell-inputWrapper" tabindex="0">
|
||||
<div class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser">
|
||||
</div>
|
||||
<div class="jp-InputArea jp-Cell-inputArea"><div class="jp-InputPrompt jp-InputArea-prompt">
|
||||
</div><div class="jp-RenderedHTMLCommon jp-RenderedMarkdown jp-MarkdownOutput" data-mime-type="text/markdown">
|
||||
<p>If you run it for enough iterations, you will see the expected solution of the Laplace equation: values that vary linearly form -1 to 1.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div><div class="jp-Cell jp-CodeCell jp-Notebook-cell jp-mod-noOutputs" id="cell-id=b52be374">
|
||||
<div class="jp-Cell-inputWrapper" tabindex="0">
|
||||
<div class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser">
|
||||
</div>
|
||||
<div class="jp-InputArea jp-Cell-inputArea">
|
||||
<div class="jp-InputPrompt jp-InputArea-prompt">In [ ]:</div>
|
||||
<div class="jp-CodeMirrorEditor jp-Editor jp-InputArea-editor" data-type="inline">
|
||||
<div class="cm-editor cm-s-jupyter">
|
||||
<div class="highlight hl-julia"><pre><span></span><span class="n">jacobi</span><span class="p">(</span><span class="mi">5</span><span class="p">,</span><span class="mi">100</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="jp-Cell jp-MarkdownCell jp-Notebook-cell" id="cell-id=22fda724">
|
||||
<div class="jp-Cell-inputWrapper" tabindex="0">
|
||||
<div class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser">
|
||||
</div>
|
||||
<div class="jp-InputArea jp-Cell-inputArea"><div class="jp-InputPrompt jp-InputArea-prompt">
|
||||
</div><div class="jp-RenderedHTMLCommon jp-RenderedMarkdown jp-MarkdownOutput" data-mime-type="text/markdown">
|
||||
<p>In our version of the jacobi method, we return after a given number of iterations. Other stopping criteria are possible. For instance, iterate until the difference between u and u_new is below a tolerance:</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div><div class="jp-Cell jp-CodeCell jp-Notebook-cell jp-mod-noOutputs" id="cell-id=15de7bf5">
|
||||
<div class="jp-Cell-inputWrapper" tabindex="0">
|
||||
<div class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser">
|
||||
</div>
|
||||
<div class="jp-InputArea jp-Cell-inputArea">
|
||||
<div class="jp-InputPrompt jp-InputArea-prompt">In [ ]:</div>
|
||||
<div class="jp-CodeMirrorEditor jp-Editor jp-InputArea-editor" data-type="inline">
|
||||
<div class="cm-editor cm-s-jupyter">
|
||||
<div class="highlight hl-julia"><pre><span></span><span class="k">using</span><span class="w"> </span><span class="n">LinearAlgebra</span><span class="o">:</span><span class="w"> </span><span class="n">norm</span>
|
||||
<span class="k">function</span><span class="w"> </span><span class="n">jacobi_with_tol</span><span class="p">(</span><span class="n">n</span><span class="p">,</span><span class="n">tol</span><span class="p">)</span>
|
||||
<span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">zeros</span><span class="p">(</span><span class="n">n</span><span class="o">+</span><span class="mi">2</span><span class="p">)</span>
|
||||
<span class="w"> </span><span class="n">u</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">-</span><span class="mi">1</span>
|
||||
<span class="w"> </span><span class="n">u</span><span class="p">[</span><span class="k">end</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span>
|
||||
<span class="w"> </span><span class="n">u_new</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">copy</span><span class="p">(</span><span class="n">u</span><span class="p">)</span>
|
||||
<span class="w"> </span><span class="n">increment</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">similar</span><span class="p">(</span><span class="n">u</span><span class="p">)</span>
|
||||
<span class="w"> </span><span class="k">while</span><span class="w"> </span><span class="nb">true</span>
|
||||
<span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="mi">2</span><span class="o">:</span><span class="p">(</span><span class="n">n</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span>
|
||||
<span class="w"> </span><span class="n">u_new</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.5</span><span class="o">*</span><span class="p">(</span><span class="n">u</span><span class="p">[</span><span class="n">i</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span><span class="o">+</span><span class="n">u</span><span class="p">[</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">])</span>
|
||||
<span class="w"> </span><span class="k">end</span>
|
||||
<span class="w"> </span><span class="n">increment</span><span class="w"> </span><span class="o">.=</span><span class="w"> </span><span class="n">u_new</span><span class="w"> </span><span class="o">.-</span><span class="w"> </span><span class="n">u</span>
|
||||
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="n">norm</span><span class="p">(</span><span class="n">increment</span><span class="p">)</span><span class="o">/</span><span class="n">norm</span><span class="p">(</span><span class="n">u_new</span><span class="p">)</span><span class="w"> </span><span class="o"><</span><span class="w"> </span><span class="n">tol</span>
|
||||
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">u_new</span>
|
||||
<span class="w"> </span><span class="k">end</span>
|
||||
<span class="w"> </span><span class="n">u</span><span class="p">,</span><span class="w"> </span><span class="n">u_new</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">u_new</span><span class="p">,</span><span class="w"> </span><span class="n">u</span>
|
||||
<span class="w"> </span><span class="k">end</span>
|
||||
<span class="w"> </span><span class="n">u</span>
|
||||
<span class="k">end</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div><div class="jp-Cell jp-CodeCell jp-Notebook-cell jp-mod-noOutputs" id="cell-id=697ad307">
|
||||
<div class="jp-Cell-inputWrapper" tabindex="0">
|
||||
<div class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser">
|
||||
</div>
|
||||
<div class="jp-InputArea jp-Cell-inputArea">
|
||||
<div class="jp-InputPrompt jp-InputArea-prompt">In [ ]:</div>
|
||||
<div class="jp-CodeMirrorEditor jp-Editor jp-InputArea-editor" data-type="inline">
|
||||
<div class="cm-editor cm-s-jupyter">
|
||||
<div class="highlight hl-julia"><pre><span></span><span class="n">n</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">5</span>
|
||||
<span class="n">tol</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">1e-9</span>
|
||||
<span class="n">jacobi_with_tol</span><span class="p">(</span><span class="n">n</span><span class="p">,</span><span class="n">tol</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="jp-Cell jp-MarkdownCell jp-Notebook-cell" id="cell-id=6e085701">
|
||||
<div class="jp-Cell-inputWrapper" tabindex="0">
|
||||
<div class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser">
|
||||
</div>
|
||||
<div class="jp-InputArea jp-Cell-inputArea"><div class="jp-InputPrompt jp-InputArea-prompt">
|
||||
</div><div class="jp-RenderedHTMLCommon jp-RenderedMarkdown jp-MarkdownOutput" data-mime-type="text/markdown">
|
||||
<div class="alert alert-block alert-info">
|
||||
<b>Note:</b> In our version of the jacobi method, we return after a given number of iterations. Other stopping criteria are possible. For instance, iterate until the difference between u and u_new is below a tolerance.
|
||||
</div>
|
||||
<p>However, we are not going to parallelize this more complex in this notebook (we will consider it later in this course).</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -7697,7 +7791,7 @@ a.anchor-link {
|
||||
</div>
|
||||
<div class="jp-InputArea jp-Cell-inputArea"><div class="jp-InputPrompt jp-InputArea-prompt">
|
||||
</div><div class="jp-RenderedHTMLCommon jp-RenderedMarkdown jp-MarkdownOutput" data-mime-type="text/markdown">
|
||||
<h3 id="Where-can-we-exploit-parallelism?">Where can we exploit parallelism?<a class="anchor-link" href="#Where-can-we-exploit-parallelism?">¶</a></h3><p>Look at the two nested loops in the sequential implementation:</p>
|
||||
<h2 id="Where-can-we-exploit-parallelism?">Where can we exploit parallelism?<a class="anchor-link" href="#Where-can-we-exploit-parallelism?">¶</a></h2><p>Look at the two nested loops in the sequential implementation:</p>
|
||||
<div class="highlight"><pre><span></span><span class="k">for</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="mi">1</span><span class="o">:</span><span class="n">nsteps</span>
|
||||
<span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="mi">2</span><span class="o">:</span><span class="p">(</span><span class="n">n</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span>
|
||||
<span class="w"> </span><span class="n">u_new</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.5</span><span class="o">*</span><span class="p">(</span><span class="n">u</span><span class="p">[</span><span class="n">i</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span><span class="o">+</span><span class="n">u</span><span class="p">[</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">])</span>
|
||||
@ -7706,8 +7800,8 @@ a.anchor-link {
|
||||
<span class="k">end</span>
|
||||
</pre></div>
|
||||
<ul>
|
||||
<li>The outer loop cannot be parallelized. The value of <code>u</code> at step <code>t+1</code> depends on the value at the previous step <code>t</code>.</li>
|
||||
<li>The inner loop can be parallelized.</li>
|
||||
<li>The outer loop over <code>t</code> cannot be parallelized. The value of <code>u</code> at step <code>t+1</code> depends on the value at the previous step <code>t</code>.</li>
|
||||
<li>The inner loop is trivially parallel. The loop iterations are independent (any order is possible).</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@ -7942,25 +8036,16 @@ d) The inner, but not the outer</code></pre>
|
||||
</div><div class="jp-RenderedHTMLCommon jp-RenderedMarkdown jp-MarkdownOutput" data-mime-type="text/markdown">
|
||||
<h3 id="Communication-overhead">Communication overhead<a class="anchor-link" href="#Communication-overhead">¶</a></h3><ul>
|
||||
<li>We update $N/P$ entries in each process at each iteration, where $N$ is the total length of the vector and $P$ the number of processes</li>
|
||||
<li>Thus, computation complexity is $O(N/P)$</li>
|
||||
<li>We need to get remote entries from 2 neighbors (2 messages per iteration)</li>
|
||||
<li>We need to communicate 1 entry per message</li>
|
||||
<li>Communication/computation ration is $O(P/N)$ (potentially scalable if $P<<N$)</li>
|
||||
<li>Thus, communication complexity is $O(1)$</li>
|
||||
<li>Communication/computation ration is $O(P/N)$, making the algorithm potentially scalable if $P<<N$.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="jp-Cell jp-MarkdownCell jp-Notebook-cell" id="cell-id=f6b54b7b">
|
||||
<div class="jp-Cell-inputWrapper" tabindex="0">
|
||||
<div class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser">
|
||||
</div>
|
||||
<div class="jp-InputArea jp-Cell-inputArea"><div class="jp-InputPrompt jp-InputArea-prompt">
|
||||
</div><div class="jp-RenderedHTMLCommon jp-RenderedMarkdown jp-MarkdownOutput" data-mime-type="text/markdown">
|
||||
<h2 id="1D-Implementation">1D Implementation<a class="anchor-link" href="#1D-Implementation">¶</a></h2><p>We consider the implementation using MPI. The programming model of MPI is generally better suited for data-parallel algorithms like this one than the task-based model provided by Distributed.jl. In any case, one can also implement it using Distributed, but it requires some extra effort to setup the remote channels right for the communication between neighbor processes.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="jp-Cell jp-MarkdownCell jp-Notebook-cell" id="cell-id=1b3c8c05">
|
||||
<div class="jp-Cell-inputWrapper" tabindex="0">
|
||||
<div class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser">
|
||||
@ -8019,7 +8104,8 @@ d) The inner, but not the outer</code></pre>
|
||||
</div>
|
||||
<div class="jp-InputArea jp-Cell-inputArea"><div class="jp-InputPrompt jp-InputArea-prompt">
|
||||
</div><div class="jp-RenderedHTMLCommon jp-RenderedMarkdown jp-MarkdownOutput" data-mime-type="text/markdown">
|
||||
<h3 id="MPI-Code">MPI Code<a class="anchor-link" href="#MPI-Code">¶</a></h3><p>Take a look at the implementation below and try to understand it.</p>
|
||||
<h2 id="MPI-implementation">MPI implementation<a class="anchor-link" href="#MPI-implementation">¶</a></h2><p>We consider the implementation using MPI. The programming model of MPI is generally better suited for data-parallel algorithms like this one than the task-based model provided by Distributed.jl. In any case, one can also implement it using Distributed.jl, but it requires some extra effort to setup the remote channels right for the communication between neighbor processes.</p>
|
||||
<p>Take a look at the implementation below and try to understand it.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -8329,7 +8415,7 @@ d) 4</code></pre>
|
||||
</pre></div>
|
||||
<ul>
|
||||
<li>The outer loop cannot be parallelized (like in the 1d case).</li>
|
||||
<li>The two inner loops can be parallelized</li>
|
||||
<li>The two inner loops are trivially parallel</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -14,4 +14,4 @@
|
||||
var myIframe = document.getElementById("notebook");
|
||||
iFrameResize({log:true}, myIframe);
|
||||
});
|
||||
</script></article><nav class="docs-footer"><a class="docs-footer-prevpage" href="../julia_basics/">« Julia Basics</a><a class="docs-footer-nextpage" href="../julia_distributed/">Distributed computing in Julia »</a><div class="flexbox-break"></div><p class="footer-message">Powered by <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> and the <a href="https://julialang.org/">Julia Programming Language</a>.</p></nav></div><div class="modal" id="documenter-settings"><div class="modal-background"></div><div class="modal-card"><header class="modal-card-head"><p class="modal-card-title">Settings</p><button class="delete"></button></header><section class="modal-card-body"><p><label class="label">Theme</label><div class="select"><select id="documenter-themepicker"><option value="auto">Automatic (OS)</option><option value="documenter-light">documenter-light</option><option value="documenter-dark">documenter-dark</option><option value="catppuccin-latte">catppuccin-latte</option><option value="catppuccin-frappe">catppuccin-frappe</option><option value="catppuccin-macchiato">catppuccin-macchiato</option><option value="catppuccin-mocha">catppuccin-mocha</option></select></div></p><hr/><p>This document was generated with <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> version 1.6.0 on <span class="colophon-date" title="Thursday 22 August 2024 08:36">Thursday 22 August 2024</span>. Using Julia version 1.10.4.</p></section><footer class="modal-card-foot"></footer></div></div></div></body></html>
|
||||
</script></article><nav class="docs-footer"><a class="docs-footer-prevpage" href="../julia_basics/">« Julia Basics</a><a class="docs-footer-nextpage" href="../julia_distributed/">Distributed computing in Julia »</a><div class="flexbox-break"></div><p class="footer-message">Powered by <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> and the <a href="https://julialang.org/">Julia Programming Language</a>.</p></nav></div><div class="modal" id="documenter-settings"><div class="modal-background"></div><div class="modal-card"><header class="modal-card-head"><p class="modal-card-title">Settings</p><button class="delete"></button></header><section class="modal-card-body"><p><label class="label">Theme</label><div class="select"><select id="documenter-themepicker"><option value="auto">Automatic (OS)</option><option value="documenter-light">documenter-light</option><option value="documenter-dark">documenter-dark</option><option value="catppuccin-latte">catppuccin-latte</option><option value="catppuccin-frappe">catppuccin-frappe</option><option value="catppuccin-macchiato">catppuccin-macchiato</option><option value="catppuccin-mocha">catppuccin-mocha</option></select></div></p><hr/><p>This document was generated with <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> version 1.6.0 on <span class="colophon-date" title="Monday 26 August 2024 11:01">Monday 26 August 2024</span>. Using Julia version 1.10.4.</p></section><footer class="modal-card-foot"></footer></div></div></div></body></html>
|
||||
|
||||
@ -14,4 +14,4 @@
|
||||
var myIframe = document.getElementById("notebook");
|
||||
iFrameResize({log:true}, myIframe);
|
||||
});
|
||||
</script></article><nav class="docs-footer"><a class="docs-footer-prevpage" href="../getting_started_with_julia/">« Getting started</a><a class="docs-footer-nextpage" href="../julia_async/">Asynchronous programming in Julia »</a><div class="flexbox-break"></div><p class="footer-message">Powered by <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> and the <a href="https://julialang.org/">Julia Programming Language</a>.</p></nav></div><div class="modal" id="documenter-settings"><div class="modal-background"></div><div class="modal-card"><header class="modal-card-head"><p class="modal-card-title">Settings</p><button class="delete"></button></header><section class="modal-card-body"><p><label class="label">Theme</label><div class="select"><select id="documenter-themepicker"><option value="auto">Automatic (OS)</option><option value="documenter-light">documenter-light</option><option value="documenter-dark">documenter-dark</option><option value="catppuccin-latte">catppuccin-latte</option><option value="catppuccin-frappe">catppuccin-frappe</option><option value="catppuccin-macchiato">catppuccin-macchiato</option><option value="catppuccin-mocha">catppuccin-mocha</option></select></div></p><hr/><p>This document was generated with <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> version 1.6.0 on <span class="colophon-date" title="Thursday 22 August 2024 08:36">Thursday 22 August 2024</span>. Using Julia version 1.10.4.</p></section><footer class="modal-card-foot"></footer></div></div></div></body></html>
|
||||
</script></article><nav class="docs-footer"><a class="docs-footer-prevpage" href="../getting_started_with_julia/">« Getting started</a><a class="docs-footer-nextpage" href="../julia_async/">Asynchronous programming in Julia »</a><div class="flexbox-break"></div><p class="footer-message">Powered by <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> and the <a href="https://julialang.org/">Julia Programming Language</a>.</p></nav></div><div class="modal" id="documenter-settings"><div class="modal-background"></div><div class="modal-card"><header class="modal-card-head"><p class="modal-card-title">Settings</p><button class="delete"></button></header><section class="modal-card-body"><p><label class="label">Theme</label><div class="select"><select id="documenter-themepicker"><option value="auto">Automatic (OS)</option><option value="documenter-light">documenter-light</option><option value="documenter-dark">documenter-dark</option><option value="catppuccin-latte">catppuccin-latte</option><option value="catppuccin-frappe">catppuccin-frappe</option><option value="catppuccin-macchiato">catppuccin-macchiato</option><option value="catppuccin-mocha">catppuccin-mocha</option></select></div></p><hr/><p>This document was generated with <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> version 1.6.0 on <span class="colophon-date" title="Monday 26 August 2024 11:01">Monday 26 August 2024</span>. Using Julia version 1.10.4.</p></section><footer class="modal-card-foot"></footer></div></div></div></body></html>
|
||||
|
||||
@ -14,4 +14,4 @@
|
||||
var myIframe = document.getElementById("notebook");
|
||||
iFrameResize({log:true}, myIframe);
|
||||
});
|
||||
</script></article><nav class="docs-footer"><a class="docs-footer-prevpage" href="../julia_async/">« Asynchronous programming in Julia</a><a class="docs-footer-nextpage" href="../matrix_matrix/">Matrix-matrix multiplication »</a><div class="flexbox-break"></div><p class="footer-message">Powered by <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> and the <a href="https://julialang.org/">Julia Programming Language</a>.</p></nav></div><div class="modal" id="documenter-settings"><div class="modal-background"></div><div class="modal-card"><header class="modal-card-head"><p class="modal-card-title">Settings</p><button class="delete"></button></header><section class="modal-card-body"><p><label class="label">Theme</label><div class="select"><select id="documenter-themepicker"><option value="auto">Automatic (OS)</option><option value="documenter-light">documenter-light</option><option value="documenter-dark">documenter-dark</option><option value="catppuccin-latte">catppuccin-latte</option><option value="catppuccin-frappe">catppuccin-frappe</option><option value="catppuccin-macchiato">catppuccin-macchiato</option><option value="catppuccin-mocha">catppuccin-mocha</option></select></div></p><hr/><p>This document was generated with <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> version 1.6.0 on <span class="colophon-date" title="Thursday 22 August 2024 08:36">Thursday 22 August 2024</span>. Using Julia version 1.10.4.</p></section><footer class="modal-card-foot"></footer></div></div></div></body></html>
|
||||
</script></article><nav class="docs-footer"><a class="docs-footer-prevpage" href="../julia_async/">« Asynchronous programming in Julia</a><a class="docs-footer-nextpage" href="../matrix_matrix/">Matrix-matrix multiplication »</a><div class="flexbox-break"></div><p class="footer-message">Powered by <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> and the <a href="https://julialang.org/">Julia Programming Language</a>.</p></nav></div><div class="modal" id="documenter-settings"><div class="modal-background"></div><div class="modal-card"><header class="modal-card-head"><p class="modal-card-title">Settings</p><button class="delete"></button></header><section class="modal-card-body"><p><label class="label">Theme</label><div class="select"><select id="documenter-themepicker"><option value="auto">Automatic (OS)</option><option value="documenter-light">documenter-light</option><option value="documenter-dark">documenter-dark</option><option value="catppuccin-latte">catppuccin-latte</option><option value="catppuccin-frappe">catppuccin-frappe</option><option value="catppuccin-macchiato">catppuccin-macchiato</option><option value="catppuccin-mocha">catppuccin-mocha</option></select></div></p><hr/><p>This document was generated with <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> version 1.6.0 on <span class="colophon-date" title="Monday 26 August 2024 11:01">Monday 26 August 2024</span>. Using Julia version 1.10.4.</p></section><footer class="modal-card-foot"></footer></div></div></div></body></html>
|
||||
|
||||
@ -14,4 +14,4 @@
|
||||
var myIframe = document.getElementById("notebook");
|
||||
iFrameResize({log:true}, myIframe);
|
||||
});
|
||||
</script></article><nav class="docs-footer"><p class="footer-message">Powered by <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> and the <a href="https://julialang.org/">Julia Programming Language</a>.</p></nav></div><div class="modal" id="documenter-settings"><div class="modal-background"></div><div class="modal-card"><header class="modal-card-head"><p class="modal-card-title">Settings</p><button class="delete"></button></header><section class="modal-card-body"><p><label class="label">Theme</label><div class="select"><select id="documenter-themepicker"><option value="auto">Automatic (OS)</option><option value="documenter-light">documenter-light</option><option value="documenter-dark">documenter-dark</option><option value="catppuccin-latte">catppuccin-latte</option><option value="catppuccin-frappe">catppuccin-frappe</option><option value="catppuccin-macchiato">catppuccin-macchiato</option><option value="catppuccin-mocha">catppuccin-mocha</option></select></div></p><hr/><p>This document was generated with <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> version 1.6.0 on <span class="colophon-date" title="Thursday 22 August 2024 08:36">Thursday 22 August 2024</span>. Using Julia version 1.10.4.</p></section><footer class="modal-card-foot"></footer></div></div></div></body></html>
|
||||
</script></article><nav class="docs-footer"><p class="footer-message">Powered by <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> and the <a href="https://julialang.org/">Julia Programming Language</a>.</p></nav></div><div class="modal" id="documenter-settings"><div class="modal-background"></div><div class="modal-card"><header class="modal-card-head"><p class="modal-card-title">Settings</p><button class="delete"></button></header><section class="modal-card-body"><p><label class="label">Theme</label><div class="select"><select id="documenter-themepicker"><option value="auto">Automatic (OS)</option><option value="documenter-light">documenter-light</option><option value="documenter-dark">documenter-dark</option><option value="catppuccin-latte">catppuccin-latte</option><option value="catppuccin-frappe">catppuccin-frappe</option><option value="catppuccin-macchiato">catppuccin-macchiato</option><option value="catppuccin-mocha">catppuccin-mocha</option></select></div></p><hr/><p>This document was generated with <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> version 1.6.0 on <span class="colophon-date" title="Monday 26 August 2024 11:01">Monday 26 August 2024</span>. Using Julia version 1.10.4.</p></section><footer class="modal-card-foot"></footer></div></div></div></body></html>
|
||||
|
||||
@ -14,4 +14,4 @@
|
||||
var myIframe = document.getElementById("notebook");
|
||||
iFrameResize({log:true}, myIframe);
|
||||
});
|
||||
</script></article><nav class="docs-footer"><p class="footer-message">Powered by <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> and the <a href="https://julialang.org/">Julia Programming Language</a>.</p></nav></div><div class="modal" id="documenter-settings"><div class="modal-background"></div><div class="modal-card"><header class="modal-card-head"><p class="modal-card-title">Settings</p><button class="delete"></button></header><section class="modal-card-body"><p><label class="label">Theme</label><div class="select"><select id="documenter-themepicker"><option value="auto">Automatic (OS)</option><option value="documenter-light">documenter-light</option><option value="documenter-dark">documenter-dark</option><option value="catppuccin-latte">catppuccin-latte</option><option value="catppuccin-frappe">catppuccin-frappe</option><option value="catppuccin-macchiato">catppuccin-macchiato</option><option value="catppuccin-mocha">catppuccin-mocha</option></select></div></p><hr/><p>This document was generated with <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> version 1.6.0 on <span class="colophon-date" title="Thursday 22 August 2024 08:36">Thursday 22 August 2024</span>. Using Julia version 1.10.4.</p></section><footer class="modal-card-foot"></footer></div></div></div></body></html>
|
||||
</script></article><nav class="docs-footer"><p class="footer-message">Powered by <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> and the <a href="https://julialang.org/">Julia Programming Language</a>.</p></nav></div><div class="modal" id="documenter-settings"><div class="modal-background"></div><div class="modal-card"><header class="modal-card-head"><p class="modal-card-title">Settings</p><button class="delete"></button></header><section class="modal-card-body"><p><label class="label">Theme</label><div class="select"><select id="documenter-themepicker"><option value="auto">Automatic (OS)</option><option value="documenter-light">documenter-light</option><option value="documenter-dark">documenter-dark</option><option value="catppuccin-latte">catppuccin-latte</option><option value="catppuccin-frappe">catppuccin-frappe</option><option value="catppuccin-macchiato">catppuccin-macchiato</option><option value="catppuccin-mocha">catppuccin-mocha</option></select></div></p><hr/><p>This document was generated with <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> version 1.6.0 on <span class="colophon-date" title="Monday 26 August 2024 11:01">Monday 26 August 2024</span>. Using Julia version 1.10.4.</p></section><footer class="modal-card-foot"></footer></div></div></div></body></html>
|
||||
|
||||
@ -687,7 +687,12 @@
|
||||
"* `rcvbuf` space to store the incoming data.\n",
|
||||
"* `source` rank of the sender.\n",
|
||||
"* `dest` rank of the receiver.\n",
|
||||
"* `tag`. Might be used to distinguish between different kinds of messages from the same sender to the same receiver (similar to the \"subject\" in an email).\n"
|
||||
"* `tag`. Might be used to distinguish between different kinds of messages from the same sender to the same receiver (similar to the \"subject\" in an email).\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"<div class=\"alert alert-block alert-info\">\n",
|
||||
"<b>Note:</b> Note that the C interface provides additional arguments `MPI_Datatype` (type of data to send/receive) and `count` (number of items to send/receive). In Julia, send and receive buffers are usually arrays or references, from which the data type and the count can be inferred. This is true for many other MPI functions.\n",
|
||||
"</div>"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@ -14,4 +14,4 @@
|
||||
var myIframe = document.getElementById("notebook");
|
||||
iFrameResize({log:true}, myIframe);
|
||||
});
|
||||
</script></article><nav class="docs-footer"><a class="docs-footer-prevpage" href="../matrix_matrix/">« Matrix-matrix multiplication</a><a class="docs-footer-nextpage" href="../jacobi_method/">Jacobi method »</a><div class="flexbox-break"></div><p class="footer-message">Powered by <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> and the <a href="https://julialang.org/">Julia Programming Language</a>.</p></nav></div><div class="modal" id="documenter-settings"><div class="modal-background"></div><div class="modal-card"><header class="modal-card-head"><p class="modal-card-title">Settings</p><button class="delete"></button></header><section class="modal-card-body"><p><label class="label">Theme</label><div class="select"><select id="documenter-themepicker"><option value="auto">Automatic (OS)</option><option value="documenter-light">documenter-light</option><option value="documenter-dark">documenter-dark</option><option value="catppuccin-latte">catppuccin-latte</option><option value="catppuccin-frappe">catppuccin-frappe</option><option value="catppuccin-macchiato">catppuccin-macchiato</option><option value="catppuccin-mocha">catppuccin-mocha</option></select></div></p><hr/><p>This document was generated with <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> version 1.6.0 on <span class="colophon-date" title="Thursday 22 August 2024 08:36">Thursday 22 August 2024</span>. Using Julia version 1.10.4.</p></section><footer class="modal-card-foot"></footer></div></div></div></body></html>
|
||||
</script></article><nav class="docs-footer"><a class="docs-footer-prevpage" href="../matrix_matrix/">« Matrix-matrix multiplication</a><a class="docs-footer-nextpage" href="../jacobi_method/">Jacobi method »</a><div class="flexbox-break"></div><p class="footer-message">Powered by <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> and the <a href="https://julialang.org/">Julia Programming Language</a>.</p></nav></div><div class="modal" id="documenter-settings"><div class="modal-background"></div><div class="modal-card"><header class="modal-card-head"><p class="modal-card-title">Settings</p><button class="delete"></button></header><section class="modal-card-body"><p><label class="label">Theme</label><div class="select"><select id="documenter-themepicker"><option value="auto">Automatic (OS)</option><option value="documenter-light">documenter-light</option><option value="documenter-dark">documenter-dark</option><option value="catppuccin-latte">catppuccin-latte</option><option value="catppuccin-frappe">catppuccin-frappe</option><option value="catppuccin-macchiato">catppuccin-macchiato</option><option value="catppuccin-mocha">catppuccin-mocha</option></select></div></p><hr/><p>This document was generated with <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> version 1.6.0 on <span class="colophon-date" title="Monday 26 August 2024 11:01">Monday 26 August 2024</span>. Using Julia version 1.10.4.</p></section><footer class="modal-card-foot"></footer></div></div></div></body></html>
|
||||
|
||||
@ -8291,6 +8291,9 @@ a.anchor-link {
|
||||
<li><code>dest</code> rank of the receiver.</li>
|
||||
<li><code>tag</code>. Might be used to distinguish between different kinds of messages from the same sender to the same receiver (similar to the "subject" in an email).</li>
|
||||
</ul>
|
||||
<div class="alert alert-block alert-info">
|
||||
<b>Note:</b> Note that the C interface provides additional arguments `MPI_Datatype` (type of data to send/receive) and `count` (number of items to send/receive). In Julia, send and receive buffers are usually arrays or references, from which the data type and the count can be inferred. This is true for many other MPI functions.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -14,4 +14,4 @@
|
||||
var myIframe = document.getElementById("notebook");
|
||||
iFrameResize({log:true}, myIframe);
|
||||
});
|
||||
</script></article><nav class="docs-footer"><p class="footer-message">Powered by <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> and the <a href="https://julialang.org/">Julia Programming Language</a>.</p></nav></div><div class="modal" id="documenter-settings"><div class="modal-background"></div><div class="modal-card"><header class="modal-card-head"><p class="modal-card-title">Settings</p><button class="delete"></button></header><section class="modal-card-body"><p><label class="label">Theme</label><div class="select"><select id="documenter-themepicker"><option value="auto">Automatic (OS)</option><option value="documenter-light">documenter-light</option><option value="documenter-dark">documenter-dark</option><option value="catppuccin-latte">catppuccin-latte</option><option value="catppuccin-frappe">catppuccin-frappe</option><option value="catppuccin-macchiato">catppuccin-macchiato</option><option value="catppuccin-mocha">catppuccin-mocha</option></select></div></p><hr/><p>This document was generated with <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> version 1.6.0 on <span class="colophon-date" title="Thursday 22 August 2024 08:36">Thursday 22 August 2024</span>. Using Julia version 1.10.4.</p></section><footer class="modal-card-foot"></footer></div></div></div></body></html>
|
||||
</script></article><nav class="docs-footer"><p class="footer-message">Powered by <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> and the <a href="https://julialang.org/">Julia Programming Language</a>.</p></nav></div><div class="modal" id="documenter-settings"><div class="modal-background"></div><div class="modal-card"><header class="modal-card-head"><p class="modal-card-title">Settings</p><button class="delete"></button></header><section class="modal-card-body"><p><label class="label">Theme</label><div class="select"><select id="documenter-themepicker"><option value="auto">Automatic (OS)</option><option value="documenter-light">documenter-light</option><option value="documenter-dark">documenter-dark</option><option value="catppuccin-latte">catppuccin-latte</option><option value="catppuccin-frappe">catppuccin-frappe</option><option value="catppuccin-macchiato">catppuccin-macchiato</option><option value="catppuccin-mocha">catppuccin-mocha</option></select></div></p><hr/><p>This document was generated with <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> version 1.6.0 on <span class="colophon-date" title="Monday 26 August 2024 11:01">Monday 26 August 2024</span>. Using Julia version 1.10.4.</p></section><footer class="modal-card-foot"></footer></div></div></div></body></html>
|
||||
|
||||
@ -29,7 +29,8 @@
|
||||
"\n",
|
||||
"- Parallelize a simple algorithm\n",
|
||||
"- Study the performance of different parallelization strategies\n",
|
||||
"- Implement them using Julia"
|
||||
"- Learn the importance of \"grain size\" in a parallel algorithm\n",
|
||||
"- Implement and measure the performance of parallel algorithms"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -54,10 +55,18 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"execution_count": 8,
|
||||
"id": "2f8ba040",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"🥳 Well done! \n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"using Distributed\n",
|
||||
"using BenchmarkTools\n",
|
||||
@ -79,7 +88,8 @@
|
||||
"alg_2_complex_check(answer) = answer_checker(answer, \"b\")\n",
|
||||
"alg_2_deps_check(answer) = answer_checker(answer,\"d\")\n",
|
||||
"alg_3_deps_check(answer) = answer_checker(answer, \"c\")\n",
|
||||
"alg_3_complex_check(answer) = answer_checker(answer, \"b\")"
|
||||
"alg_3_complex_check(answer) = answer_checker(answer, \"b\")\n",
|
||||
"println(\"🥳 Well done! \")"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -89,6 +99,8 @@
|
||||
"source": [
|
||||
"## Problem Statement\n",
|
||||
"\n",
|
||||
"We consider matrix-matrix multiplication as our first algorithm to parallelize. The problem we want so solve is defined as follows.\n",
|
||||
"\n",
|
||||
"Given $A$ and $B$ two $N$-by-$N$ matrices, compute the matrix-matrix product $C=AB$. Compute it in parallel and efficiently."
|
||||
]
|
||||
},
|
||||
@ -113,7 +125,7 @@
|
||||
"\n",
|
||||
"- compute the product in parallel using more than one process (distributed implementation)\n",
|
||||
"- study the performance of different parallelization alternatives\n",
|
||||
"- implement the algorithms using Julia\n"
|
||||
"- implement the algorithms using Julia's task-based programming model\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -124,7 +136,7 @@
|
||||
"### Assumptions\n",
|
||||
"\n",
|
||||
"- All matrices `A`,`B`, and `C` are initially stored in the master process\n",
|
||||
"- The result will be overwritten in `C`"
|
||||
"- The result will be overwritten in `C` (in the master process)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -148,7 +160,8 @@
|
||||
"\n",
|
||||
"- Identify the parts of the sequential algorithm that can be parallelized\n",
|
||||
"- Consider different parallelization strategies\n",
|
||||
"- Discuss the (theoretical) performance of these implementations\n"
|
||||
"- Discuss the (theoretical) performance of these implementations\n",
|
||||
"- Measure the actual performance of these implementations\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -222,7 +235,7 @@
|
||||
"<b>Note:</b> The matrix-matrix multiplication naively implemented with 3 nested loops as above is known to be very inefficient (memory bound). Libraries such as BLAS provide much more efficient implementations, which are the ones used in practice (e.g., by the `*` operator in Julia). We consider our hand-written implementation as a simple way of expressing the algorithm we are interested in.\n",
|
||||
"</div>\n",
|
||||
"\n",
|
||||
"Run the following cell to compare the performance of our hand-written function with respect to the built in function `mul!`.\n"
|
||||
"Just to satisfy your curiosity, run the following cell to compare the performance of our hand-written function with respect to the built in function `mul!`.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -272,9 +285,14 @@
|
||||
"id": "0eedd28a",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Where can we exploit parallelism?\n",
|
||||
"## Where can we exploit parallelism?\n",
|
||||
"\n",
|
||||
"Look at the three nested loops in the sequential implementation:\n",
|
||||
"\n",
|
||||
"The matrix-matrix multiplication is an example of [embarrassingly parallel algorithm](https://en.wikipedia.org/wiki/Embarrassingly_parallel). An embarrassingly parallel (also known as trivially parallel) algorithm is an algorithm that can be split in parallel tasks with no (or very few) dependences between them. Such algorithms are typically easy to parallelize.\n",
|
||||
"\n",
|
||||
"Which parts of an algorithm are completely independent and thus trivially parallel? To answer this question, it is useful to inspect the for loops, which are potential sources parallelism. If the iterations are independent of each other, then they are trivial to parallelize. An easy check to find out if the iterations are dependent or not is to change their order (for instance changing `for j in 1:n` by `for j in n:-1:1`, i.e. doing the loop in reverse). If the result changes, then the iterations are not independent.\n",
|
||||
"\n",
|
||||
"Look at the three nested loops in the sequential implementation of the matrix-matrix product:\n",
|
||||
"\n",
|
||||
"```julia\n",
|
||||
"for j in 1:n\n",
|
||||
@ -287,8 +305,12 @@
|
||||
" end\n",
|
||||
"end\n",
|
||||
"```\n",
|
||||
"- Loops over `i` and `j` are trivially parallelizable.\n",
|
||||
"- The loop over `k` can be parallelized but it requires a reduction."
|
||||
"\n",
|
||||
"Note that:\n",
|
||||
"\n",
|
||||
"- Loops over `i` and `j` are trivially parallel.\n",
|
||||
"- The loop over `k` is not trivially parallel. The accumulation into the reduction variable `Cij` introduces extra dependences. In addition, remember that the addition of floating point numbers is not strictly associative due to rounding errors. Thus, the result of this loop may change with the loop order when using floating point numbers. In any case, this loop can also be parallelized, but it requires a parallel *fold* or a parallel *reduction*.\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -298,7 +320,7 @@
|
||||
"source": [
|
||||
"### Parallel algorithms\n",
|
||||
"\n",
|
||||
"All the entries of matrix C can be potentially computed in parallel, but *is it the most efficient solution to solve all these entries in parallel in a distributed system?* To find this we will consider different parallelization strategies:\n",
|
||||
"Parallelizing the loops over `i` and `j` means that all the entries of matrix C can be potentially computed in parallel. However, *which it the most efficient solution to solve all these entries in parallel in a distributed system?* To find this we will consider different parallelization strategies:\n",
|
||||
"\n",
|
||||
"- Algorithm 1: each worker computes a single entry of C\n",
|
||||
"- Algorithm 2: each worker computes a single row of C\n",
|
||||
@ -330,7 +352,7 @@
|
||||
"source": [
|
||||
"### Data dependencies\n",
|
||||
"\n",
|
||||
"Moving data through the network is expensive and reducing data movement is one of the key points in a distributed algorithm. To this end, we determine which is the minimum data needed by a worker to perform its computations.\n",
|
||||
"Moving data through the network is expensive and reducing data movement is one of the key points in a distributed algorithm. To this end, we need to determine which is the minimum data needed by a worker to perform its computations. These are called the *data dependencies*. This will give us later information about the performance of the parallel algorithm.\n",
|
||||
"\n",
|
||||
"In algorithm 1, each worker computes only an entry of the result matrix C."
|
||||
]
|
||||
@ -380,7 +402,7 @@
|
||||
"\n",
|
||||
"Taking into account the data dependencies, the parallel algorithm 1 can be efficiently implemented following these steps from the worker perspective:\n",
|
||||
"\n",
|
||||
"1. The worker receives the corresponding row A[i,:] and column B[:,j] from the master process\n",
|
||||
"1. The worker receives the data dependencies, i.e., the corresponding row A[i,:] and column B[:,j] from the master process\n",
|
||||
"2. The worker computes the dot product of A[i,:] and B[:,j]\n",
|
||||
"3. The worker sends back the result of C[i,j] to the master process"
|
||||
]
|
||||
@ -471,19 +493,19 @@
|
||||
"source": [
|
||||
"### Performance\n",
|
||||
"\n",
|
||||
"Let us study the performance of this algorithm. To this end, we will analyze if algorithm 1 is able to achieve the optimal parallel *speedup*. The parallel speedup on $P$ processes is defined as \n",
|
||||
"We have a first parallel algorithm, but how efficient is this algorithm? Let us study its performance. To this end we need to consider a performance baseline as reference. In this case, we will use the so-called optimal parallel *speedup*. The parallel speedup on $P$ processes is defined as \n",
|
||||
"\n",
|
||||
"$$\n",
|
||||
"S_P = \\frac{T_1}{T_P},\n",
|
||||
"$$\n",
|
||||
"\n",
|
||||
"where $T_1$ denotes the runtime of the sequential algorithm on one node and $T_P$ denotes the runtime of the parallel algorithm on $P$ processes. If we run an optimal parallel algorithm with $P$ processes we expect it to run $p$ times faster than the sequential implementation. I.e., the *optimal* speedup of a parallel algorithm on $p$ processes is equal to $P$:\n",
|
||||
"where $T_1$ denotes the runtime of the sequential algorithm and $T_P$ denotes the runtime of the parallel algorithm on $P$ processes. If we run an optimal parallel algorithm with $P$ processes we expect it to run $p$ times faster than the sequential implementation. I.e., the *optimal* speedup of a parallel algorithm on $p$ processes is equal to $P$:\n",
|
||||
"\n",
|
||||
"$$\n",
|
||||
"S^{*}_p = P.\n",
|
||||
"$$\n",
|
||||
"\n",
|
||||
"The ratio of the actual speedup over the optimal one is called the parallel efficiency\n",
|
||||
"The ratio of the actual speedup over the optimal one is called the parallel efficiency (the closer to one the better).\n",
|
||||
"\n",
|
||||
"$$\n",
|
||||
"E_p = \\frac{S_p}{S^{*}_p} = \\frac{T_1/T_P}{P}.\n",
|
||||
@ -754,7 +776,9 @@
|
||||
"id": "f1f30faf",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Experimental speedup"
|
||||
"### Experimental speedup\n",
|
||||
"\n",
|
||||
"Measure the speedup with the following cell. Is this time better?"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -964,7 +988,9 @@
|
||||
"\n",
|
||||
"- Matrix-matrix multiplication is trivially parallelizable (all entries in the result matrix can be computed in parallel, at least in theory)\n",
|
||||
"- However, we cannot exploit all the potential parallelism in a distributed system due to communication overhead\n",
|
||||
"- We need a sufficiently large grain size to obtain a near optimal speedup\n"
|
||||
"- We need a sufficiently large grain size to obtain a near optimal speedup\n",
|
||||
"- We measured the theoretical parallel performance by computing the complexity of communication over computation\n",
|
||||
"- We measured the actual performance using the parallel speedup and parallel efficiency\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@ -14,4 +14,4 @@
|
||||
var myIframe = document.getElementById("notebook");
|
||||
iFrameResize({log:true}, myIframe);
|
||||
});
|
||||
</script></article><nav class="docs-footer"><a class="docs-footer-prevpage" href="../julia_distributed/">« Distributed computing in Julia</a><a class="docs-footer-nextpage" href="../julia_mpi/">MPI (point-to-point) »</a><div class="flexbox-break"></div><p class="footer-message">Powered by <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> and the <a href="https://julialang.org/">Julia Programming Language</a>.</p></nav></div><div class="modal" id="documenter-settings"><div class="modal-background"></div><div class="modal-card"><header class="modal-card-head"><p class="modal-card-title">Settings</p><button class="delete"></button></header><section class="modal-card-body"><p><label class="label">Theme</label><div class="select"><select id="documenter-themepicker"><option value="auto">Automatic (OS)</option><option value="documenter-light">documenter-light</option><option value="documenter-dark">documenter-dark</option><option value="catppuccin-latte">catppuccin-latte</option><option value="catppuccin-frappe">catppuccin-frappe</option><option value="catppuccin-macchiato">catppuccin-macchiato</option><option value="catppuccin-mocha">catppuccin-mocha</option></select></div></p><hr/><p>This document was generated with <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> version 1.6.0 on <span class="colophon-date" title="Thursday 22 August 2024 08:36">Thursday 22 August 2024</span>. Using Julia version 1.10.4.</p></section><footer class="modal-card-foot"></footer></div></div></div></body></html>
|
||||
</script></article><nav class="docs-footer"><a class="docs-footer-prevpage" href="../julia_distributed/">« Distributed computing in Julia</a><a class="docs-footer-nextpage" href="../julia_mpi/">MPI (point-to-point) »</a><div class="flexbox-break"></div><p class="footer-message">Powered by <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> and the <a href="https://julialang.org/">Julia Programming Language</a>.</p></nav></div><div class="modal" id="documenter-settings"><div class="modal-background"></div><div class="modal-card"><header class="modal-card-head"><p class="modal-card-title">Settings</p><button class="delete"></button></header><section class="modal-card-body"><p><label class="label">Theme</label><div class="select"><select id="documenter-themepicker"><option value="auto">Automatic (OS)</option><option value="documenter-light">documenter-light</option><option value="documenter-dark">documenter-dark</option><option value="catppuccin-latte">catppuccin-latte</option><option value="catppuccin-frappe">catppuccin-frappe</option><option value="catppuccin-macchiato">catppuccin-macchiato</option><option value="catppuccin-mocha">catppuccin-mocha</option></select></div></p><hr/><p>This document was generated with <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> version 1.6.0 on <span class="colophon-date" title="Monday 26 August 2024 11:01">Monday 26 August 2024</span>. Using Julia version 1.10.4.</p></section><footer class="modal-card-foot"></footer></div></div></div></body></html>
|
||||
|
||||
@ -7545,7 +7545,8 @@ a.anchor-link {
|
||||
<ul>
|
||||
<li>Parallelize a simple algorithm</li>
|
||||
<li>Study the performance of different parallelization strategies</li>
|
||||
<li>Implement them using Julia</li>
|
||||
<li>Learn the importance of "grain size" in a parallel algorithm</li>
|
||||
<li>Implement and measure the performance of parallel algorithms</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@ -7577,12 +7578,12 @@ a.anchor-link {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div><div class="jp-Cell jp-CodeCell jp-Notebook-cell jp-mod-noOutputs" id="cell-id=2f8ba040">
|
||||
</div><div class="jp-Cell jp-CodeCell jp-Notebook-cell" id="cell-id=2f8ba040">
|
||||
<div class="jp-Cell-inputWrapper" tabindex="0">
|
||||
<div class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser">
|
||||
</div>
|
||||
<div class="jp-InputArea jp-Cell-inputArea">
|
||||
<div class="jp-InputPrompt jp-InputArea-prompt">In [ ]:</div>
|
||||
<div class="jp-InputPrompt jp-InputArea-prompt">In [8]:</div>
|
||||
<div class="jp-CodeMirrorEditor jp-Editor jp-InputArea-editor" data-type="inline">
|
||||
<div class="cm-editor cm-s-jupyter">
|
||||
<div class="highlight hl-julia"><pre><span></span><span class="k">using</span><span class="w"> </span><span class="n">Distributed</span>
|
||||
@ -7606,11 +7607,25 @@ a.anchor-link {
|
||||
<span class="n">alg_2_deps_check</span><span class="p">(</span><span class="n">answer</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">answer_checker</span><span class="p">(</span><span class="n">answer</span><span class="p">,</span><span class="s">"d"</span><span class="p">)</span>
|
||||
<span class="n">alg_3_deps_check</span><span class="p">(</span><span class="n">answer</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">answer_checker</span><span class="p">(</span><span class="n">answer</span><span class="p">,</span><span class="w"> </span><span class="s">"c"</span><span class="p">)</span>
|
||||
<span class="n">alg_3_complex_check</span><span class="p">(</span><span class="n">answer</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">answer_checker</span><span class="p">(</span><span class="n">answer</span><span class="p">,</span><span class="w"> </span><span class="s">"b"</span><span class="p">)</span>
|
||||
<span class="n">println</span><span class="p">(</span><span class="s">"🥳 Well done! "</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="jp-Cell-outputWrapper">
|
||||
<div class="jp-Collapser jp-OutputCollapser jp-Cell-outputCollapser">
|
||||
</div>
|
||||
<div class="jp-OutputArea jp-Cell-outputArea">
|
||||
<div class="jp-OutputArea-child">
|
||||
<div class="jp-OutputPrompt jp-OutputArea-prompt"></div>
|
||||
<div class="jp-RenderedText jp-OutputArea-output" data-mime-type="text/plain" tabindex="0">
|
||||
<pre>🥳 Well done!
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="jp-Cell jp-MarkdownCell jp-Notebook-cell" id="cell-id=96d2693d">
|
||||
<div class="jp-Cell-inputWrapper" tabindex="0">
|
||||
@ -7618,7 +7633,8 @@ a.anchor-link {
|
||||
</div>
|
||||
<div class="jp-InputArea jp-Cell-inputArea"><div class="jp-InputPrompt jp-InputArea-prompt">
|
||||
</div><div class="jp-RenderedHTMLCommon jp-RenderedMarkdown jp-MarkdownOutput" data-mime-type="text/markdown">
|
||||
<h2 id="Problem-Statement">Problem Statement<a class="anchor-link" href="#Problem-Statement">¶</a></h2><p>Given $A$ and $B$ two $N$-by-$N$ matrices, compute the matrix-matrix product $C=AB$. Compute it in parallel and efficiently.</p>
|
||||
<h2 id="Problem-Statement">Problem Statement<a class="anchor-link" href="#Problem-Statement">¶</a></h2><p>We consider matrix-matrix multiplication as our first algorithm to parallelize. The problem we want so solve is defined as follows.</p>
|
||||
<p>Given $A$ and $B$ two $N$-by-$N$ matrices, compute the matrix-matrix product $C=AB$. Compute it in parallel and efficiently.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -7646,7 +7662,7 @@ a.anchor-link {
|
||||
<ul>
|
||||
<li>compute the product in parallel using more than one process (distributed implementation)</li>
|
||||
<li>study the performance of different parallelization alternatives</li>
|
||||
<li>implement the algorithms using Julia</li>
|
||||
<li>implement the algorithms using Julia's task-based programming model</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@ -7660,7 +7676,7 @@ a.anchor-link {
|
||||
</div><div class="jp-RenderedHTMLCommon jp-RenderedMarkdown jp-MarkdownOutput" data-mime-type="text/markdown">
|
||||
<h3 id="Assumptions">Assumptions<a class="anchor-link" href="#Assumptions">¶</a></h3><ul>
|
||||
<li>All matrices <code>A</code>,<code>B</code>, and <code>C</code> are initially stored in the master process</li>
|
||||
<li>The result will be overwritten in <code>C</code></li>
|
||||
<li>The result will be overwritten in <code>C</code> (in the master process)</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@ -7690,6 +7706,7 @@ a.anchor-link {
|
||||
<li>Identify the parts of the sequential algorithm that can be parallelized</li>
|
||||
<li>Consider different parallelization strategies</li>
|
||||
<li>Discuss the (theoretical) performance of these implementations</li>
|
||||
<li>Measure the actual performance of these implementations</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@ -7778,7 +7795,7 @@ a.anchor-link {
|
||||
<div class="alert alert-block alert-info">
|
||||
<b>Note:</b> The matrix-matrix multiplication naively implemented with 3 nested loops as above is known to be very inefficient (memory bound). Libraries such as BLAS provide much more efficient implementations, which are the ones used in practice (e.g., by the `*` operator in Julia). We consider our hand-written implementation as a simple way of expressing the algorithm we are interested in.
|
||||
</div>
|
||||
<p>Run the following cell to compare the performance of our hand-written function with respect to the built in function <code>mul!</code>.</p>
|
||||
<p>Just to satisfy your curiosity, run the following cell to compare the performance of our hand-written function with respect to the built in function <code>mul!</code>.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -7841,7 +7858,9 @@ d) O(N³)</code></pre>
|
||||
</div>
|
||||
<div class="jp-InputArea jp-Cell-inputArea"><div class="jp-InputPrompt jp-InputArea-prompt">
|
||||
</div><div class="jp-RenderedHTMLCommon jp-RenderedMarkdown jp-MarkdownOutput" data-mime-type="text/markdown">
|
||||
<h3 id="Where-can-we-exploit-parallelism?">Where can we exploit parallelism?<a class="anchor-link" href="#Where-can-we-exploit-parallelism?">¶</a></h3><p>Look at the three nested loops in the sequential implementation:</p>
|
||||
<h2 id="Where-can-we-exploit-parallelism?">Where can we exploit parallelism?<a class="anchor-link" href="#Where-can-we-exploit-parallelism?">¶</a></h2><p>The matrix-matrix multiplication is an example of <a href="https://en.wikipedia.org/wiki/Embarrassingly_parallel">embarrassingly parallel algorithm</a>. An embarrassingly parallel (also known as trivially parallel) algorithm is an algorithm that can be split in parallel tasks with no (or very few) dependences between them. Such algorithms are typically easy to parallelize.</p>
|
||||
<p>Which parts of an algorithm are completely independent and thus trivially parallel? To answer this question, it is useful to inspect the for loops, which are potential sources parallelism. If the iterations are independent of each other, then they are trivial to parallelize. An easy check to find out if the iterations are dependent or not is to change their order (for instance changing <code>for j in 1:n</code> by <code>for j in n:-1:1</code>, i.e. doing the loop in reverse). If the result changes, then the iterations are not independent.</p>
|
||||
<p>Look at the three nested loops in the sequential implementation of the matrix-matrix product:</p>
|
||||
<div class="highlight"><pre><span></span><span class="k">for</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="mi">1</span><span class="o">:</span><span class="n">n</span>
|
||||
<span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="mi">1</span><span class="o">:</span><span class="n">m</span>
|
||||
<span class="w"> </span><span class="n">Cij</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">z</span>
|
||||
@ -7852,9 +7871,10 @@ d) O(N³)</code></pre>
|
||||
<span class="w"> </span><span class="k">end</span>
|
||||
<span class="k">end</span>
|
||||
</pre></div>
|
||||
<p>Note that:</p>
|
||||
<ul>
|
||||
<li>Loops over <code>i</code> and <code>j</code> are trivially parallelizable.</li>
|
||||
<li>The loop over <code>k</code> can be parallelized but it requires a reduction.</li>
|
||||
<li>Loops over <code>i</code> and <code>j</code> are trivially parallel.</li>
|
||||
<li>The loop over <code>k</code> is not trivially parallel. The accumulation into the reduction variable <code>Cij</code> introduces extra dependences. In addition, remember that the addition of floating point numbers is not strictly associative due to rounding errors. Thus, the result of this loop may change with the loop order when using floating point numbers. In any case, this loop can also be parallelized, but it requires a parallel <em>fold</em> or a parallel <em>reduction</em>.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@ -7866,7 +7886,7 @@ d) O(N³)</code></pre>
|
||||
</div>
|
||||
<div class="jp-InputArea jp-Cell-inputArea"><div class="jp-InputPrompt jp-InputArea-prompt">
|
||||
</div><div class="jp-RenderedHTMLCommon jp-RenderedMarkdown jp-MarkdownOutput" data-mime-type="text/markdown">
|
||||
<h3 id="Parallel-algorithms">Parallel algorithms<a class="anchor-link" href="#Parallel-algorithms">¶</a></h3><p>All the entries of matrix C can be potentially computed in parallel, but <em>is it the most efficient solution to solve all these entries in parallel in a distributed system?</em> To find this we will consider different parallelization strategies:</p>
|
||||
<h3 id="Parallel-algorithms">Parallel algorithms<a class="anchor-link" href="#Parallel-algorithms">¶</a></h3><p>Parallelizing the loops over <code>i</code> and <code>j</code> means that all the entries of matrix C can be potentially computed in parallel. However, <em>which it the most efficient solution to solve all these entries in parallel in a distributed system?</em> To find this we will consider different parallelization strategies:</p>
|
||||
<ul>
|
||||
<li>Algorithm 1: each worker computes a single entry of C</li>
|
||||
<li>Algorithm 2: each worker computes a single row of C</li>
|
||||
@ -7906,7 +7926,7 @@ d) O(N³)</code></pre>
|
||||
</div>
|
||||
<div class="jp-InputArea jp-Cell-inputArea"><div class="jp-InputPrompt jp-InputArea-prompt">
|
||||
</div><div class="jp-RenderedHTMLCommon jp-RenderedMarkdown jp-MarkdownOutput" data-mime-type="text/markdown">
|
||||
<h3 id="Data-dependencies">Data dependencies<a class="anchor-link" href="#Data-dependencies">¶</a></h3><p>Moving data through the network is expensive and reducing data movement is one of the key points in a distributed algorithm. To this end, we determine which is the minimum data needed by a worker to perform its computations.</p>
|
||||
<h3 id="Data-dependencies">Data dependencies<a class="anchor-link" href="#Data-dependencies">¶</a></h3><p>Moving data through the network is expensive and reducing data movement is one of the key points in a distributed algorithm. To this end, we need to determine which is the minimum data needed by a worker to perform its computations. These are called the <em>data dependencies</em>. This will give us later information about the performance of the parallel algorithm.</p>
|
||||
<p>In algorithm 1, each worker computes only an entry of the result matrix C.</p>
|
||||
</div>
|
||||
</div>
|
||||
@ -7965,7 +7985,7 @@ d) row A[i,:] and the whole matrix B</code></pre>
|
||||
</div><div class="jp-RenderedHTMLCommon jp-RenderedMarkdown jp-MarkdownOutput" data-mime-type="text/markdown">
|
||||
<h3 id="Implementation">Implementation<a class="anchor-link" href="#Implementation">¶</a></h3><p>Taking into account the data dependencies, the parallel algorithm 1 can be efficiently implemented following these steps from the worker perspective:</p>
|
||||
<ol>
|
||||
<li>The worker receives the corresponding row A[i,:] and column B[:,j] from the master process</li>
|
||||
<li>The worker receives the data dependencies, i.e., the corresponding row A[i,:] and column B[:,j] from the master process</li>
|
||||
<li>The worker computes the dot product of A[i,:] and B[:,j]</li>
|
||||
<li>The worker sends back the result of C[i,j] to the master process</li>
|
||||
</ol>
|
||||
@ -8074,15 +8094,15 @@ d) row A[i,:] and the whole matrix B</code></pre>
|
||||
</div>
|
||||
<div class="jp-InputArea jp-Cell-inputArea"><div class="jp-InputPrompt jp-InputArea-prompt">
|
||||
</div><div class="jp-RenderedHTMLCommon jp-RenderedMarkdown jp-MarkdownOutput" data-mime-type="text/markdown">
|
||||
<h3 id="Performance">Performance<a class="anchor-link" href="#Performance">¶</a></h3><p>Let us study the performance of this algorithm. To this end, we will analyze if algorithm 1 is able to achieve the optimal parallel <em>speedup</em>. The parallel speedup on $P$ processes is defined as</p>
|
||||
<h3 id="Performance">Performance<a class="anchor-link" href="#Performance">¶</a></h3><p>We have a first parallel algorithm, but how efficient is this algorithm? Let us study its performance. To this end we need to consider a performance baseline as reference. In this case, we will use the so-called optimal parallel <em>speedup</em>. The parallel speedup on $P$ processes is defined as</p>
|
||||
<p>$$
|
||||
S_P = \frac{T_1}{T_P},
|
||||
$$</p>
|
||||
<p>where $T_1$ denotes the runtime of the sequential algorithm on one node and $T_P$ denotes the runtime of the parallel algorithm on $P$ processes. If we run an optimal parallel algorithm with $P$ processes we expect it to run $p$ times faster than the sequential implementation. I.e., the <em>optimal</em> speedup of a parallel algorithm on $p$ processes is equal to $P$:</p>
|
||||
<p>where $T_1$ denotes the runtime of the sequential algorithm and $T_P$ denotes the runtime of the parallel algorithm on $P$ processes. If we run an optimal parallel algorithm with $P$ processes we expect it to run $p$ times faster than the sequential implementation. I.e., the <em>optimal</em> speedup of a parallel algorithm on $p$ processes is equal to $P$:</p>
|
||||
<p>$$
|
||||
S^{*}_p = P.
|
||||
$$</p>
|
||||
<p>The ratio of the actual speedup over the optimal one is called the parallel efficiency</p>
|
||||
<p>The ratio of the actual speedup over the optimal one is called the parallel efficiency (the closer to one the better).</p>
|
||||
<p>$$
|
||||
E_p = \frac{S_p}{S^{*}_p} = \frac{T_1/T_P}{P}.
|
||||
$$</p>
|
||||
@ -8396,7 +8416,7 @@ d) row A[i,:] and the whole matrix B</code></pre>
|
||||
</div>
|
||||
<div class="jp-InputArea jp-Cell-inputArea"><div class="jp-InputPrompt jp-InputArea-prompt">
|
||||
</div><div class="jp-RenderedHTMLCommon jp-RenderedMarkdown jp-MarkdownOutput" data-mime-type="text/markdown">
|
||||
<h3 id="Experimental-speedup">Experimental speedup<a class="anchor-link" href="#Experimental-speedup">¶</a></h3>
|
||||
<h3 id="Experimental-speedup">Experimental speedup<a class="anchor-link" href="#Experimental-speedup">¶</a></h3><p>Measure the speedup with the following cell. Is this time better?</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -8671,6 +8691,8 @@ d) O(N²/P) communication and O(N³/P) computation</code></pre>
|
||||
<li>Matrix-matrix multiplication is trivially parallelizable (all entries in the result matrix can be computed in parallel, at least in theory)</li>
|
||||
<li>However, we cannot exploit all the potential parallelism in a distributed system due to communication overhead</li>
|
||||
<li>We need a sufficiently large grain size to obtain a near optimal speedup</li>
|
||||
<li>We measured the theoretical parallel performance by computing the complexity of communication over computation</li>
|
||||
<li>We measured the actual performance using the parallel speedup and parallel efficiency</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
901
dev/mpi_collectives.ipynb
Normal file
901
dev/mpi_collectives.ipynb
Normal file
File diff suppressed because one or more lines are too long
17
dev/mpi_collectives/index.html
Normal file
17
dev/mpi_collectives/index.html
Normal file
File diff suppressed because one or more lines are too long
8437
dev/mpi_collectives_src/index.html
Normal file
8437
dev/mpi_collectives_src/index.html
Normal file
File diff suppressed because one or more lines are too long
@ -14,4 +14,4 @@
|
||||
var myIframe = document.getElementById("notebook");
|
||||
iFrameResize({log:true}, myIframe);
|
||||
});
|
||||
</script></article><nav class="docs-footer"><p class="footer-message">Powered by <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> and the <a href="https://julialang.org/">Julia Programming Language</a>.</p></nav></div><div class="modal" id="documenter-settings"><div class="modal-background"></div><div class="modal-card"><header class="modal-card-head"><p class="modal-card-title">Settings</p><button class="delete"></button></header><section class="modal-card-body"><p><label class="label">Theme</label><div class="select"><select id="documenter-themepicker"><option value="auto">Automatic (OS)</option><option value="documenter-light">documenter-light</option><option value="documenter-dark">documenter-dark</option><option value="catppuccin-latte">catppuccin-latte</option><option value="catppuccin-frappe">catppuccin-frappe</option><option value="catppuccin-macchiato">catppuccin-macchiato</option><option value="catppuccin-mocha">catppuccin-mocha</option></select></div></p><hr/><p>This document was generated with <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> version 1.6.0 on <span class="colophon-date" title="Thursday 22 August 2024 08:36">Thursday 22 August 2024</span>. Using Julia version 1.10.4.</p></section><footer class="modal-card-foot"></footer></div></div></div></body></html>
|
||||
</script></article><nav class="docs-footer"><p class="footer-message">Powered by <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> and the <a href="https://julialang.org/">Julia Programming Language</a>.</p></nav></div><div class="modal" id="documenter-settings"><div class="modal-background"></div><div class="modal-card"><header class="modal-card-head"><p class="modal-card-title">Settings</p><button class="delete"></button></header><section class="modal-card-body"><p><label class="label">Theme</label><div class="select"><select id="documenter-themepicker"><option value="auto">Automatic (OS)</option><option value="documenter-light">documenter-light</option><option value="documenter-dark">documenter-dark</option><option value="catppuccin-latte">catppuccin-latte</option><option value="catppuccin-frappe">catppuccin-frappe</option><option value="catppuccin-macchiato">catppuccin-macchiato</option><option value="catppuccin-mocha">catppuccin-mocha</option></select></div></p><hr/><p>This document was generated with <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> version 1.6.0 on <span class="colophon-date" title="Monday 26 August 2024 11:01">Monday 26 August 2024</span>. Using Julia version 1.10.4.</p></section><footer class="modal-card-foot"></footer></div></div></div></body></html>
|
||||
|
||||
@ -14,4 +14,4 @@
|
||||
var myIframe = document.getElementById("notebook");
|
||||
iFrameResize({log:true}, myIframe);
|
||||
});
|
||||
</script></article><nav class="docs-footer"><p class="footer-message">Powered by <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> and the <a href="https://julialang.org/">Julia Programming Language</a>.</p></nav></div><div class="modal" id="documenter-settings"><div class="modal-background"></div><div class="modal-card"><header class="modal-card-head"><p class="modal-card-title">Settings</p><button class="delete"></button></header><section class="modal-card-body"><p><label class="label">Theme</label><div class="select"><select id="documenter-themepicker"><option value="auto">Automatic (OS)</option><option value="documenter-light">documenter-light</option><option value="documenter-dark">documenter-dark</option><option value="catppuccin-latte">catppuccin-latte</option><option value="catppuccin-frappe">catppuccin-frappe</option><option value="catppuccin-macchiato">catppuccin-macchiato</option><option value="catppuccin-mocha">catppuccin-mocha</option></select></div></p><hr/><p>This document was generated with <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> version 1.6.0 on <span class="colophon-date" title="Thursday 22 August 2024 08:36">Thursday 22 August 2024</span>. Using Julia version 1.10.4.</p></section><footer class="modal-card-foot"></footer></div></div></div></body></html>
|
||||
</script></article><nav class="docs-footer"><p class="footer-message">Powered by <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> and the <a href="https://julialang.org/">Julia Programming Language</a>.</p></nav></div><div class="modal" id="documenter-settings"><div class="modal-background"></div><div class="modal-card"><header class="modal-card-head"><p class="modal-card-title">Settings</p><button class="delete"></button></header><section class="modal-card-body"><p><label class="label">Theme</label><div class="select"><select id="documenter-themepicker"><option value="auto">Automatic (OS)</option><option value="documenter-light">documenter-light</option><option value="documenter-dark">documenter-dark</option><option value="catppuccin-latte">catppuccin-latte</option><option value="catppuccin-frappe">catppuccin-frappe</option><option value="catppuccin-macchiato">catppuccin-macchiato</option><option value="catppuccin-mocha">catppuccin-mocha</option></select></div></p><hr/><p>This document was generated with <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> version 1.6.0 on <span class="colophon-date" title="Monday 26 August 2024 11:01">Monday 26 August 2024</span>. Using Julia version 1.10.4.</p></section><footer class="modal-card-foot"></footer></div></div></div></body></html>
|
||||
|
||||
BIN
dev/objects.inv
BIN
dev/objects.inv
Binary file not shown.
@ -14,4 +14,4 @@
|
||||
var myIframe = document.getElementById("notebook");
|
||||
iFrameResize({log:true}, myIframe);
|
||||
});
|
||||
</script></article><nav class="docs-footer"><p class="footer-message">Powered by <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> and the <a href="https://julialang.org/">Julia Programming Language</a>.</p></nav></div><div class="modal" id="documenter-settings"><div class="modal-background"></div><div class="modal-card"><header class="modal-card-head"><p class="modal-card-title">Settings</p><button class="delete"></button></header><section class="modal-card-body"><p><label class="label">Theme</label><div class="select"><select id="documenter-themepicker"><option value="auto">Automatic (OS)</option><option value="documenter-light">documenter-light</option><option value="documenter-dark">documenter-dark</option><option value="catppuccin-latte">catppuccin-latte</option><option value="catppuccin-frappe">catppuccin-frappe</option><option value="catppuccin-macchiato">catppuccin-macchiato</option><option value="catppuccin-mocha">catppuccin-mocha</option></select></div></p><hr/><p>This document was generated with <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> version 1.6.0 on <span class="colophon-date" title="Thursday 22 August 2024 08:36">Thursday 22 August 2024</span>. Using Julia version 1.10.4.</p></section><footer class="modal-card-foot"></footer></div></div></div></body></html>
|
||||
</script></article><nav class="docs-footer"><p class="footer-message">Powered by <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> and the <a href="https://julialang.org/">Julia Programming Language</a>.</p></nav></div><div class="modal" id="documenter-settings"><div class="modal-background"></div><div class="modal-card"><header class="modal-card-head"><p class="modal-card-title">Settings</p><button class="delete"></button></header><section class="modal-card-body"><p><label class="label">Theme</label><div class="select"><select id="documenter-themepicker"><option value="auto">Automatic (OS)</option><option value="documenter-light">documenter-light</option><option value="documenter-dark">documenter-dark</option><option value="catppuccin-latte">catppuccin-latte</option><option value="catppuccin-frappe">catppuccin-frappe</option><option value="catppuccin-macchiato">catppuccin-macchiato</option><option value="catppuccin-mocha">catppuccin-mocha</option></select></div></p><hr/><p>This document was generated with <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> version 1.6.0 on <span class="colophon-date" title="Monday 26 August 2024 11:01">Monday 26 August 2024</span>. Using Julia version 1.10.4.</p></section><footer class="modal-card-foot"></footer></div></div></div></body></html>
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -14,4 +14,4 @@
|
||||
var myIframe = document.getElementById("notebook");
|
||||
iFrameResize({log:true}, myIframe);
|
||||
});
|
||||
</script></article><nav class="docs-footer"><p class="footer-message">Powered by <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> and the <a href="https://julialang.org/">Julia Programming Language</a>.</p></nav></div><div class="modal" id="documenter-settings"><div class="modal-background"></div><div class="modal-card"><header class="modal-card-head"><p class="modal-card-title">Settings</p><button class="delete"></button></header><section class="modal-card-body"><p><label class="label">Theme</label><div class="select"><select id="documenter-themepicker"><option value="auto">Automatic (OS)</option><option value="documenter-light">documenter-light</option><option value="documenter-dark">documenter-dark</option><option value="catppuccin-latte">catppuccin-latte</option><option value="catppuccin-frappe">catppuccin-frappe</option><option value="catppuccin-macchiato">catppuccin-macchiato</option><option value="catppuccin-mocha">catppuccin-mocha</option></select></div></p><hr/><p>This document was generated with <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> version 1.6.0 on <span class="colophon-date" title="Thursday 22 August 2024 08:36">Thursday 22 August 2024</span>. Using Julia version 1.10.4.</p></section><footer class="modal-card-foot"></footer></div></div></div></body></html>
|
||||
</script></article><nav class="docs-footer"><p class="footer-message">Powered by <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> and the <a href="https://julialang.org/">Julia Programming Language</a>.</p></nav></div><div class="modal" id="documenter-settings"><div class="modal-background"></div><div class="modal-card"><header class="modal-card-head"><p class="modal-card-title">Settings</p><button class="delete"></button></header><section class="modal-card-body"><p><label class="label">Theme</label><div class="select"><select id="documenter-themepicker"><option value="auto">Automatic (OS)</option><option value="documenter-light">documenter-light</option><option value="documenter-dark">documenter-dark</option><option value="catppuccin-latte">catppuccin-latte</option><option value="catppuccin-frappe">catppuccin-frappe</option><option value="catppuccin-macchiato">catppuccin-macchiato</option><option value="catppuccin-mocha">catppuccin-mocha</option></select></div></p><hr/><p>This document was generated with <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> version 1.6.0 on <span class="colophon-date" title="Monday 26 August 2024 11:01">Monday 26 August 2024</span>. Using Julia version 1.10.4.</p></section><footer class="modal-card-foot"></footer></div></div></div></body></html>
|
||||
|
||||
@ -172,4 +172,4 @@ end</code></pre><h2 id="Jacobi-method"><a class="docs-heading-anchor" href="#Jac
|
||||
end
|
||||
end
|
||||
return u_all
|
||||
end</code></pre></article><nav class="docs-footer"><a class="docs-footer-prevpage" href="../jacobi_method/">« Jacobi method</a><div class="flexbox-break"></div><p class="footer-message">Powered by <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> and the <a href="https://julialang.org/">Julia Programming Language</a>.</p></nav></div><div class="modal" id="documenter-settings"><div class="modal-background"></div><div class="modal-card"><header class="modal-card-head"><p class="modal-card-title">Settings</p><button class="delete"></button></header><section class="modal-card-body"><p><label class="label">Theme</label><div class="select"><select id="documenter-themepicker"><option value="auto">Automatic (OS)</option><option value="documenter-light">documenter-light</option><option value="documenter-dark">documenter-dark</option><option value="catppuccin-latte">catppuccin-latte</option><option value="catppuccin-frappe">catppuccin-frappe</option><option value="catppuccin-macchiato">catppuccin-macchiato</option><option value="catppuccin-mocha">catppuccin-mocha</option></select></div></p><hr/><p>This document was generated with <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> version 1.6.0 on <span class="colophon-date" title="Thursday 22 August 2024 08:36">Thursday 22 August 2024</span>. Using Julia version 1.10.4.</p></section><footer class="modal-card-foot"></footer></div></div></div></body></html>
|
||||
end</code></pre></article><nav class="docs-footer"><a class="docs-footer-prevpage" href="../jacobi_method/">« Jacobi method</a><div class="flexbox-break"></div><p class="footer-message">Powered by <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> and the <a href="https://julialang.org/">Julia Programming Language</a>.</p></nav></div><div class="modal" id="documenter-settings"><div class="modal-background"></div><div class="modal-card"><header class="modal-card-head"><p class="modal-card-title">Settings</p><button class="delete"></button></header><section class="modal-card-body"><p><label class="label">Theme</label><div class="select"><select id="documenter-themepicker"><option value="auto">Automatic (OS)</option><option value="documenter-light">documenter-light</option><option value="documenter-dark">documenter-dark</option><option value="catppuccin-latte">catppuccin-latte</option><option value="catppuccin-frappe">catppuccin-frappe</option><option value="catppuccin-macchiato">catppuccin-macchiato</option><option value="catppuccin-mocha">catppuccin-mocha</option></select></div></p><hr/><p>This document was generated with <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> version 1.6.0 on <span class="colophon-date" title="Monday 26 August 2024 11:01">Monday 26 August 2024</span>. Using Julia version 1.10.4.</p></section><footer class="modal-card-foot"></footer></div></div></div></body></html>
|
||||
|
||||
@ -14,4 +14,4 @@
|
||||
var myIframe = document.getElementById("notebook");
|
||||
iFrameResize({log:true}, myIframe);
|
||||
});
|
||||
</script></article><nav class="docs-footer"><p class="footer-message">Powered by <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> and the <a href="https://julialang.org/">Julia Programming Language</a>.</p></nav></div><div class="modal" id="documenter-settings"><div class="modal-background"></div><div class="modal-card"><header class="modal-card-head"><p class="modal-card-title">Settings</p><button class="delete"></button></header><section class="modal-card-body"><p><label class="label">Theme</label><div class="select"><select id="documenter-themepicker"><option value="auto">Automatic (OS)</option><option value="documenter-light">documenter-light</option><option value="documenter-dark">documenter-dark</option><option value="catppuccin-latte">catppuccin-latte</option><option value="catppuccin-frappe">catppuccin-frappe</option><option value="catppuccin-macchiato">catppuccin-macchiato</option><option value="catppuccin-mocha">catppuccin-mocha</option></select></div></p><hr/><p>This document was generated with <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> version 1.6.0 on <span class="colophon-date" title="Thursday 22 August 2024 08:36">Thursday 22 August 2024</span>. Using Julia version 1.10.4.</p></section><footer class="modal-card-foot"></footer></div></div></div></body></html>
|
||||
</script></article><nav class="docs-footer"><p class="footer-message">Powered by <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> and the <a href="https://julialang.org/">Julia Programming Language</a>.</p></nav></div><div class="modal" id="documenter-settings"><div class="modal-background"></div><div class="modal-card"><header class="modal-card-head"><p class="modal-card-title">Settings</p><button class="delete"></button></header><section class="modal-card-body"><p><label class="label">Theme</label><div class="select"><select id="documenter-themepicker"><option value="auto">Automatic (OS)</option><option value="documenter-light">documenter-light</option><option value="documenter-dark">documenter-dark</option><option value="catppuccin-latte">catppuccin-latte</option><option value="catppuccin-frappe">catppuccin-frappe</option><option value="catppuccin-macchiato">catppuccin-macchiato</option><option value="catppuccin-mocha">catppuccin-mocha</option></select></div></p><hr/><p>This document was generated with <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> version 1.6.0 on <span class="colophon-date" title="Monday 26 August 2024 11:01">Monday 26 August 2024</span>. Using Julia version 1.10.4.</p></section><footer class="modal-card-foot"></footer></div></div></div></body></html>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user