mirror of
https://github.com/fverdugo/XM_40017.git
synced 2025-12-29 10:18:31 +01:00
build based on abd74c8
This commit is contained in:
@@ -7333,7 +7333,8 @@ a.anchor-link {
|
||||
if (!diagrams.length) {
|
||||
return;
|
||||
}
|
||||
const mermaid = (await import("https://cdnjs.cloudflare.com/ajax/libs/mermaid/10.2.3/mermaid.esm.min.mjs")).default;
|
||||
const mermaid = (await import("https://cdnjs.cloudflare.com/ajax/libs/mermaid/10.3.1/mermaid.esm.min.mjs")).default;
|
||||
const parser = new DOMParser();
|
||||
|
||||
mermaid.initialize({
|
||||
maxTextSize: 100000,
|
||||
@@ -7349,39 +7350,52 @@ a.anchor-link {
|
||||
let _nextMermaidId = 0;
|
||||
|
||||
function makeMermaidImage(svg) {
|
||||
const img = document.createElement('img');
|
||||
const maxWidth = svg.match(/max-width: (\d+)/);
|
||||
if (maxWidth && maxWidth[1]) {
|
||||
const width = parseInt(maxWidth[1]);
|
||||
if (width && !Number.isNaN(width) && Number.isFinite(width)) {
|
||||
img.width = width;
|
||||
}
|
||||
const img = document.createElement("img");
|
||||
const doc = parser.parseFromString(svg, "image/svg+xml");
|
||||
const svgEl = doc.querySelector("svg");
|
||||
const { maxWidth } = svgEl?.style || {};
|
||||
const firstTitle = doc.querySelector("title");
|
||||
const firstDesc = doc.querySelector("desc");
|
||||
|
||||
img.setAttribute("src", `data:image/svg+xml,${encodeURIComponent(svg)}`);
|
||||
if (maxWidth) {
|
||||
img.width = parseInt(maxWidth);
|
||||
}
|
||||
img.setAttribute('src', `data:image/svg+xml,${encodeURIComponent(svg)}`);
|
||||
return img;
|
||||
if (firstTitle) {
|
||||
img.setAttribute("alt", firstTitle.textContent);
|
||||
}
|
||||
if (firstDesc) {
|
||||
const caption = document.createElement("figcaption");
|
||||
caption.className = "sr-only";
|
||||
caption.textContent = firstDesc.textContent;
|
||||
return [img, caption];
|
||||
}
|
||||
return [img];
|
||||
}
|
||||
|
||||
async function makeMermaidError(text) {
|
||||
let errorMessage = '';
|
||||
let errorMessage = "";
|
||||
try {
|
||||
await mermaid.parse(text);
|
||||
} catch (err) {
|
||||
errorMessage = `${err}`;
|
||||
}
|
||||
|
||||
const result = document.createElement('details');
|
||||
const summary = document.createElement('summary');
|
||||
const pre = document.createElement('pre');
|
||||
const code = document.createElement('code');
|
||||
const result = document.createElement("details");
|
||||
result.className = 'jp-RenderedMermaid-Details';
|
||||
const summary = document.createElement("summary");
|
||||
summary.className = 'jp-RenderedMermaid-Summary';
|
||||
const pre = document.createElement("pre");
|
||||
const code = document.createElement("code");
|
||||
code.innerText = text;
|
||||
pre.appendChild(code);
|
||||
summary.appendChild(pre);
|
||||
result.appendChild(summary);
|
||||
|
||||
const warning = document.createElement('pre');
|
||||
const warning = document.createElement("pre");
|
||||
warning.innerText = errorMessage;
|
||||
result.appendChild(warning);
|
||||
return result;
|
||||
return [result];
|
||||
}
|
||||
|
||||
async function renderOneMarmaid(src) {
|
||||
@@ -7391,30 +7405,41 @@ a.anchor-link {
|
||||
const el = document.createElement("div");
|
||||
el.style.visibility = "hidden";
|
||||
document.body.appendChild(el);
|
||||
let result = null;
|
||||
let results = null;
|
||||
let output = null;
|
||||
try {
|
||||
const { svg } = await mermaid.render(id, raw, el);
|
||||
result = makeMermaidImage(svg);
|
||||
results = makeMermaidImage(svg);
|
||||
output = document.createElement("figure");
|
||||
results.map(output.appendChild, output);
|
||||
} catch (err) {
|
||||
parent.classList.add("jp-mod-warning");
|
||||
result = await makeMermaidError(raw);
|
||||
results = await makeMermaidError(raw);
|
||||
output = results[0];
|
||||
} finally {
|
||||
el.remove();
|
||||
}
|
||||
parent.classList.add("jp-RenderedMermaid");
|
||||
parent.appendChild(result);
|
||||
parent.appendChild(output);
|
||||
}
|
||||
|
||||
void Promise.all([...diagrams].map(renderOneMarmaid));
|
||||
});
|
||||
</script>
|
||||
<style>
|
||||
.jp-RenderedMarkdown .jp-Mermaid:not(.jp-RenderedMermaid) {
|
||||
.jp-Mermaid:not(.jp-RenderedMermaid) {
|
||||
display: none;
|
||||
}
|
||||
.jp-RenderedMarkdown .jp-RenderedMermaid.jp-mod-warning {
|
||||
|
||||
.jp-RenderedMermaid {
|
||||
overflow: auto;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.jp-RenderedMermaid.jp-mod-warning {
|
||||
width: auto;
|
||||
padding: 10px;
|
||||
padding: 0.5em;
|
||||
margin-top: 0.5em;
|
||||
border: var(--jp-border-width) solid var(--jp-warn-color2);
|
||||
border-radius: var(--jp-border-radius);
|
||||
color: var(--jp-ui-font-color1);
|
||||
@@ -7422,18 +7447,33 @@ a.anchor-link {
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
.jp-RenderedMarkdown .jp-RenderedMermaid.jp-mod-warning details > pre {
|
||||
|
||||
.jp-RenderedMermaid figure {
|
||||
margin: 0;
|
||||
overflow: auto;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.jp-RenderedMermaid img {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.jp-RenderedMermaid-Details > pre {
|
||||
margin-top: 1em;
|
||||
}
|
||||
.jp-RenderedMarkdown .jp-RenderedMermaid.jp-mod-warning summary {
|
||||
|
||||
.jp-RenderedMermaid-Summary {
|
||||
color: var(--jp-warn-color2);
|
||||
}
|
||||
.jp-RenderedMarkdown .jp-RenderedMermaid.jp-mod-warning summary > pre {
|
||||
display: inline-block;
|
||||
}
|
||||
.jp-RenderedMermaid > .mermaid {
|
||||
|
||||
.jp-RenderedMermaid:not(.jp-mod-warning) pre {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.jp-RenderedMermaid-Summary > pre {
|
||||
display: inline-block;
|
||||
white-space: normal;
|
||||
}
|
||||
</style>
|
||||
<!-- End of mermaid configuration --></head>
|
||||
<body class="jp-Notebook" data-jp-theme-light="true" data-jp-theme-name="JupyterLab Light">
|
||||
@@ -7500,24 +7540,24 @@ 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="Floyd's-sequential-algoritm">Floyd's sequential algoritm<a class="anchor-link" href="#Floyd's-sequential-algoritm">¶</a></h3><p>The ASP problem can be solved with the <a href="https://en.wikipedia.org/wiki/Floyd%E2%80%93Warshall_algorithm">Floyd–Warshall algorithm</a>. A sequential implementation of this algorithm is given in this function.</p>
|
||||
<h3 id="Floyd's-sequential-algoritm">Floyd's sequential algoritm<a class="anchor-link" href="#Floyd's-sequential-algoritm">¶</a></h3><p>The ASP problem can be solved with the <a href="https://en.wikipedia.org/wiki/Floyd%E2%80%93Warshall_algorithm">Floyd–Warshall algorithm</a>. A sequential implementation of this algorithm is given in the following function:</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div><div class="jp-Cell jp-CodeCell jp-Notebook-cell" id="cell-id=4fe447c5">
|
||||
</div><div class="jp-Cell jp-CodeCell jp-Notebook-cell jp-mod-noOutputs" id="cell-id=4fe447c5">
|
||||
<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 [1]:</div>
|
||||
<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">function</span><span class="w"> </span><span class="n">floyd!</span><span class="p">(</span><span class="n">C</span><span class="p">)</span>
|
||||
<span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">size</span><span class="p">(</span><span class="n">C</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span>
|
||||
<span class="w"> </span><span class="nd">@assert</span><span class="w"> </span><span class="n">size</span><span class="p">(</span><span class="n">C</span><span class="p">,</span><span class="mi">2</span><span class="p">)</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">n</span>
|
||||
<span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">k</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">n</span>
|
||||
<span class="w"> </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">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">n</span>
|
||||
<span class="w"> </span><span class="nd">@inbounds</span><span class="w"> </span><span class="n">C</span><span class="p">[</span><span class="n">i</span><span class="p">,</span><span class="n">j</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">min</span><span class="p">(</span><span class="n">C</span><span class="p">[</span><span class="n">i</span><span class="p">,</span><span class="n">j</span><span class="p">],</span><span class="n">C</span><span class="p">[</span><span class="n">i</span><span class="p">,</span><span class="n">k</span><span class="p">]</span><span class="o">+</span><span class="n">C</span><span class="p">[</span><span class="n">k</span><span class="p">,</span><span class="n">j</span><span class="p">])</span>
|
||||
<span class="w"> </span><span class="k">end</span>
|
||||
<span class="w"> </span><span class="k">end</span>
|
||||
@@ -7529,18 +7569,6 @@ a.anchor-link {
|
||||
</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 jp-OutputArea-executeResult">
|
||||
<div class="jp-OutputPrompt jp-OutputArea-prompt">Out[1]:</div>
|
||||
<div class="jp-RenderedText jp-OutputArea-output jp-OutputArea-executeResult" data-mime-type="text/plain" tabindex="0">
|
||||
<pre>floyd! (generic function with 1 method)</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="jp-Cell jp-MarkdownCell jp-Notebook-cell" id="cell-id=b27707b9">
|
||||
<div class="jp-Cell-inputWrapper" tabindex="0">
|
||||
@@ -7552,12 +7580,12 @@ a.anchor-link {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div><div class="jp-Cell jp-CodeCell jp-Notebook-cell" id="cell-id=860e537c">
|
||||
</div><div class="jp-Cell jp-CodeCell jp-Notebook-cell jp-mod-noOutputs" id="cell-id=860e537c">
|
||||
<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 [2]:</div>
|
||||
<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">inf</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1000</span>
|
||||
@@ -7573,22 +7601,6 @@ a.anchor-link {
|
||||
</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 jp-OutputArea-executeResult">
|
||||
<div class="jp-OutputPrompt jp-OutputArea-prompt">Out[2]:</div>
|
||||
<div class="jp-RenderedText jp-OutputArea-output jp-OutputArea-executeResult" data-mime-type="text/plain" tabindex="0">
|
||||
<pre>4×4 Matrix{Int64}:
|
||||
0 9 6 1
|
||||
2 0 8 3
|
||||
5 3 0 6
|
||||
10 8 5 0</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="jp-Cell jp-MarkdownCell jp-Notebook-cell" id="cell-id=b9eeb64d">
|
||||
<div class="jp-Cell-inputWrapper" tabindex="0">
|
||||
@@ -7600,8 +7612,8 @@ a.anchor-link {
|
||||
<p>This process is cleverly done with three nested loops:</p>
|
||||
<div class="highlight"><pre><span></span><span class="n">n</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">size</span><span class="p">(</span><span class="n">C</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span>
|
||||
<span class="k">for</span><span class="w"> </span><span class="n">k</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">n</span>
|
||||
<span class="w"> </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">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">n</span>
|
||||
<span class="w"> </span><span class="n">C</span><span class="p">[</span><span class="n">i</span><span class="p">,</span><span class="n">j</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">min</span><span class="p">(</span><span class="n">C</span><span class="p">[</span><span class="n">i</span><span class="p">,</span><span class="n">j</span><span class="p">],</span><span class="n">C</span><span class="p">[</span><span class="n">i</span><span class="p">,</span><span class="n">k</span><span class="p">]</span><span class="o">+</span><span class="n">C</span><span class="p">[</span><span class="n">k</span><span class="p">,</span><span class="n">j</span><span class="p">])</span>
|
||||
<span class="w"> </span><span class="k">end</span>
|
||||
<span class="w"> </span><span class="k">end</span>
|
||||
@@ -7688,6 +7700,83 @@ a.anchor-link {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="jp-Cell jp-MarkdownCell jp-Notebook-cell" id="cell-id=c7027ac3">
|
||||
<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">
|
||||
<h3 id="Serial-performance">Serial performance<a class="anchor-link" href="#Serial-performance">¶</a></h3><p>This algorithm is memory bound, meaning that the main cost is in getting and setting data from the input matrix <code>C</code>. In this situations, the order in which we traverse the entries of matrix <code>C</code> has a significant performance impact.</p>
|
||||
<p>The following function computes the same result as for the previous function <code>floyd!</code>, but the nesting of loops over i and j is changed.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div><div class="jp-Cell jp-CodeCell jp-Notebook-cell jp-mod-noOutputs" id="cell-id=75cac17e">
|
||||
<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">function</span><span class="w"> </span><span class="n">floyd2!</span><span class="p">(</span><span class="n">C</span><span class="p">)</span>
|
||||
<span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">size</span><span class="p">(</span><span class="n">C</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span>
|
||||
<span class="w"> </span><span class="nd">@assert</span><span class="w"> </span><span class="n">size</span><span class="p">(</span><span class="n">C</span><span class="p">,</span><span class="mi">2</span><span class="p">)</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">n</span>
|
||||
<span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">k</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">n</span>
|
||||
<span class="w"> </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="nd">@inbounds</span><span class="w"> </span><span class="n">C</span><span class="p">[</span><span class="n">i</span><span class="p">,</span><span class="n">j</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">min</span><span class="p">(</span><span class="n">C</span><span class="p">[</span><span class="n">i</span><span class="p">,</span><span class="n">j</span><span class="p">],</span><span class="n">C</span><span class="p">[</span><span class="n">i</span><span class="p">,</span><span class="n">k</span><span class="p">]</span><span class="o">+</span><span class="n">C</span><span class="p">[</span><span class="n">k</span><span class="p">,</span><span class="n">j</span><span class="p">])</span>
|
||||
<span class="w"> </span><span class="k">end</span>
|
||||
<span class="w"> </span><span class="k">end</span>
|
||||
<span class="w"> </span><span class="k">end</span>
|
||||
<span class="w"> </span><span class="n">C</span>
|
||||
<span class="k">end</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="jp-Cell jp-MarkdownCell jp-Notebook-cell" id="cell-id=399385e8">
|
||||
<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>Compare the performance of both implementations (run the cell several times).</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div><div class="jp-Cell jp-CodeCell jp-Notebook-cell jp-mod-noOutputs" id="cell-id=907bc8c9">
|
||||
<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">1000</span>
|
||||
<span class="n">C</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">rand</span><span class="p">(</span><span class="n">n</span><span class="p">,</span><span class="n">n</span><span class="p">)</span>
|
||||
<span class="nd">@time</span><span class="w"> </span><span class="n">floyd!</span><span class="p">(</span><span class="n">C</span><span class="p">)</span>
|
||||
<span class="n">C</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">rand</span><span class="p">(</span><span class="n">n</span><span class="p">,</span><span class="n">n</span><span class="p">)</span>
|
||||
<span class="nd">@time</span><span class="w"> </span><span class="n">floyd2!</span><span class="p">(</span><span class="n">C</span><span class="p">);</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="jp-Cell jp-MarkdownCell jp-Notebook-cell" id="cell-id=ad811b10">
|
||||
<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>The performance difference is significant. Matrices in Julia are stored in memory in column-major order (like in Fortran, unlike in C). It means that it is more efficient to access the data also in column-major order (like in function <code>floyd!</code>). See this section of <a href="https://docs.julialang.org/en/v1/manual/performance-tips/#man-performance-column-major">Julia's performance tips</a> if you are interested in further details.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="jp-Cell jp-MarkdownCell jp-Notebook-cell" id="cell-id=0c95ea88">
|
||||
<div class="jp-Cell-inputWrapper" tabindex="0">
|
||||
<div class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser">
|
||||
@@ -7698,8 +7787,8 @@ a.anchor-link {
|
||||
<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>Recall:</p>
|
||||
<div class="highlight"><pre><span></span><span class="n">n</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">size</span><span class="p">(</span><span class="n">C</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span>
|
||||
<span class="k">for</span><span class="w"> </span><span class="n">k</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">n</span>
|
||||
<span class="w"> </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">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">n</span>
|
||||
<span class="w"> </span><span class="n">C</span><span class="p">[</span><span class="n">i</span><span class="p">,</span><span class="n">j</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">min</span><span class="p">(</span><span class="n">C</span><span class="p">[</span><span class="n">i</span><span class="p">,</span><span class="n">j</span><span class="p">],</span><span class="n">C</span><span class="p">[</span><span class="n">i</span><span class="p">,</span><span class="n">k</span><span class="p">]</span><span class="o">+</span><span class="n">C</span><span class="p">[</span><span class="n">k</span><span class="p">,</span><span class="n">j</span><span class="p">])</span>
|
||||
<span class="w"> </span><span class="k">end</span>
|
||||
<span class="w"> </span><span class="k">end</span>
|
||||
@@ -7845,8 +7934,12 @@ a.anchor-link {
|
||||
<ul>
|
||||
<li>Each process updates $N^2/P$ entries per iteration</li>
|
||||
<li>1 process broadcasts a message of length $N$ to $P-1$ processes per iteration</li>
|
||||
<li>The send cost in this process is $O(N P)$ per iteration (if we use send/receive instead of broadcast)</li>
|
||||
<li>$P-1$ processes receive one message of length $N$ per iteration</li>
|
||||
<li>The receive/computation ration is $O(P/N)$ which would be small if $P<<N$</li>
|
||||
<li>The receive cost is $O(N)$ per iteration at each process</li>
|
||||
<li>The send/computation ratio is $O(P^2/N)$</li>
|
||||
<li>The receive/computation ratio is $O(P/N)$</li>
|
||||
<li>The algorithm is potentially scalable if $P<<N$</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@@ -7876,60 +7969,6 @@ a.anchor-link {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="jp-Cell jp-MarkdownCell jp-Notebook-cell" id="cell-id=c624722a">
|
||||
<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">
|
||||
<h3 id="Generating-test-data">Generating test data<a class="anchor-link" href="#Generating-test-data">¶</a></h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div><div class="jp-Cell jp-CodeCell jp-Notebook-cell jp-mod-noOutputs" id="cell-id=09937668">
|
||||
<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">function</span><span class="w"> </span><span class="n">rand_distance_table</span><span class="p">(</span><span class="n">n</span><span class="p">)</span>
|
||||
<span class="w"> </span><span class="n">threshold</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.4</span>
|
||||
<span class="w"> </span><span class="n">mincost</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">3</span>
|
||||
<span class="w"> </span><span class="n">maxcost</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">10</span>
|
||||
<span class="w"> </span><span class="n">infinity</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">10000</span><span class="o">*</span><span class="n">maxcost</span>
|
||||
<span class="w"> </span><span class="n">C</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">fill</span><span class="p">(</span><span class="n">infinity</span><span class="p">,</span><span class="n">n</span><span class="p">,</span><span class="n">n</span><span class="p">)</span>
|
||||
<span class="w"> </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">n</span>
|
||||
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="n">rand</span><span class="p">()</span><span class="w"> </span><span class="o">></span><span class="w"> </span><span class="n">threshold</span>
|
||||
<span class="w"> </span><span class="n">C</span><span class="p">[</span><span class="n">i</span><span class="p">,</span><span class="n">j</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">rand</span><span class="p">(</span><span class="n">mincost</span><span class="o">:</span><span class="n">maxcost</span><span class="p">)</span>
|
||||
<span class="w"> </span><span class="k">end</span>
|
||||
<span class="w"> </span><span class="k">end</span>
|
||||
<span class="w"> </span><span class="n">C</span><span class="p">[</span><span class="n">j</span><span class="p">,</span><span class="n">j</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span>
|
||||
<span class="w"> </span><span class="k">end</span>
|
||||
<span class="w"> </span><span class="n">C</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=3116096c">
|
||||
<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">rand_distance_table</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="jp-Cell jp-MarkdownCell jp-Notebook-cell" id="cell-id=0b451628">
|
||||
<div class="jp-Cell-inputWrapper" tabindex="0">
|
||||
<div class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser">
|
||||
@@ -7982,7 +8021,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="Code">Code<a class="anchor-link" href="#Code">¶</a></h3>
|
||||
<h3 id="Code">Code<a class="anchor-link" href="#Code">¶</a></h3><p>We split the code in two functions. The first function is called on the main process (the process running this notebook). It splits the input matrix into blocks of rows. Then, we call <code>floyd_worker!</code> (see below) remotely on each worker using the corresponding block of rows.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -8010,6 +8049,17 @@ a.anchor-link {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="jp-Cell jp-MarkdownCell jp-Notebook-cell" id="cell-id=9fc3be11">
|
||||
<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>The second function is the one run on the workers. Note that we considered MPI for communication in this case.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div><div class="jp-Cell jp-CodeCell jp-Notebook-cell jp-mod-noOutputs" id="cell-id=d5a8d3a8">
|
||||
<div class="jp-Cell-inputWrapper" tabindex="0">
|
||||
<div class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser">
|
||||
@@ -8037,8 +8087,8 @@ a.anchor-link {
|
||||
<span class="w"> </span><span class="k">else</span>
|
||||
<span class="w"> </span><span class="n">MPI</span><span class="o">.</span><span class="n">Recv!</span><span class="p">(</span><span class="n">C_k</span><span class="p">,</span><span class="n">comm</span><span class="p">,</span><span class="n">source</span><span class="o">=</span><span class="n">MPI</span><span class="o">.</span><span class="n">ANY_SOURCE</span><span class="p">,</span><span class="n">tag</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>
|
||||
<span class="w"> </span><span class="k">end</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="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">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="nd">@inbounds</span><span class="w"> </span><span class="n">Cw</span><span class="p">[</span><span class="n">i</span><span class="p">,</span><span class="n">j</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">min</span><span class="p">(</span><span class="n">Cw</span><span class="p">[</span><span class="n">i</span><span class="p">,</span><span class="n">j</span><span class="p">],</span><span class="n">Cw</span><span class="p">[</span><span class="n">i</span><span class="p">,</span><span class="n">k</span><span class="p">]</span><span class="o">+</span><span class="n">C_k</span><span class="p">[</span><span class="n">j</span><span class="p">])</span>
|
||||
<span class="w"> </span><span class="k">end</span>
|
||||
<span class="w"> </span><span class="k">end</span>
|
||||
@@ -8050,6 +8100,46 @@ a.anchor-link {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="jp-Cell jp-MarkdownCell jp-Notebook-cell" id="cell-id=c624722a">
|
||||
<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">
|
||||
<h3 id="Testing-the-implementation">Testing the implementation<a class="anchor-link" href="#Testing-the-implementation">¶</a></h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div><div class="jp-Cell jp-CodeCell jp-Notebook-cell jp-mod-noOutputs" id="cell-id=09937668">
|
||||
<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">function</span><span class="w"> </span><span class="n">rand_distance_table</span><span class="p">(</span><span class="n">n</span><span class="p">)</span>
|
||||
<span class="w"> </span><span class="n">threshold</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.4</span>
|
||||
<span class="w"> </span><span class="n">mincost</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">3</span>
|
||||
<span class="w"> </span><span class="n">maxcost</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">10</span>
|
||||
<span class="w"> </span><span class="n">infinity</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">10000</span><span class="o">*</span><span class="n">maxcost</span>
|
||||
<span class="w"> </span><span class="n">C</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">fill</span><span class="p">(</span><span class="n">infinity</span><span class="p">,</span><span class="n">n</span><span class="p">,</span><span class="n">n</span><span class="p">)</span>
|
||||
<span class="w"> </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">n</span>
|
||||
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="n">rand</span><span class="p">()</span><span class="w"> </span><span class="o">></span><span class="w"> </span><span class="n">threshold</span>
|
||||
<span class="w"> </span><span class="n">C</span><span class="p">[</span><span class="n">i</span><span class="p">,</span><span class="n">j</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">rand</span><span class="p">(</span><span class="n">mincost</span><span class="o">:</span><span class="n">maxcost</span><span class="p">)</span>
|
||||
<span class="w"> </span><span class="k">end</span>
|
||||
<span class="w"> </span><span class="k">end</span>
|
||||
<span class="w"> </span><span class="n">C</span><span class="p">[</span><span class="n">j</span><span class="p">,</span><span class="n">j</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span>
|
||||
<span class="w"> </span><span class="k">end</span>
|
||||
<span class="w"> </span><span class="n">C</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=dd77ee3d">
|
||||
<div class="jp-Cell-inputWrapper" tabindex="0">
|
||||
<div class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser">
|
||||
@@ -8145,22 +8235,19 @@ a.anchor-link {
|
||||
<li>Use synchronous send MPI_SSEND (less efficient). Note that the blocking send MPI_SEND used above does not guarantee that the message was received.</li>
|
||||
<li>Barrier at the end of each iteration over $k$ (simple solution, but synchronization overhead)</li>
|
||||
<li>Order incoming messages (buffering and extra user code needed)</li>
|
||||
<li>Use a specific rank id instead of <code>MPI.ANY_SOURCE</code> (one needs to know which are the rows owned by the other ranks)</li>
|
||||
<li>Use a specific rank id instead of <code>MPI.ANY_SOURCE</code> or use <code>MPI.Bcast!</code> (one needs to know which are the rows owned by the other ranks)</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div><div class="jp-Cell jp-CodeCell jp-Notebook-cell jp-mod-noOutputs" id="cell-id=db2b586f">
|
||||
</div>
|
||||
<div class="jp-Cell jp-MarkdownCell jp-Notebook-cell" id="cell-id=c789dc7a">
|
||||
<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>
|
||||
</pre></div>
|
||||
</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">
|
||||
<h1 id="License">License<a class="anchor-link" href="#License">¶</a></h1><p>This notebook is part of the course <a href="https://www.francescverdugo.com/XM_40017">Programming Large Scale Parallel Systems</a> at Vrije Universiteit Amsterdam and may be used under a <a href="https://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a> license.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user