<?xml version="1.0" encoding="UTF-8"?>
<rss  xmlns:atom="http://www.w3.org/2005/Atom" 
      xmlns:media="http://search.yahoo.com/mrss/" 
      xmlns:content="http://purl.org/rss/1.0/modules/content/" 
      xmlns:dc="http://purl.org/dc/elements/1.1/" 
      version="2.0">
<channel>
<title>siko1056</title>
<link>https://siko1056.github.io/</link>
<atom:link href="https://siko1056.github.io/index.xml" rel="self" type="application/rss+xml"/>
<description>Blog posts from siko1056</description>
<generator>quarto-1.10.18</generator>
<lastBuildDate>Tue, 11 Jan 2022 00:00:00 GMT</lastBuildDate>
<item>
  <title>Seminar notes mathematical optimization</title>
  <dc:creator>Kai T. Ohlhus</dc:creator>
  <link>https://siko1056.github.io/blog/2022/01/11/seminar-optimization.html</link>
  <description><![CDATA[ 





<p>Today I completed my seminar notes about selected topics in <a href="https://en.wikipedia.org/wiki/Mathematical_optimization">mathematical optimization</a>: optimality conditions for finite-dimensional (un-)constrained continuous problems, (un-)constrained optimization methods, convex analysis, and many <a href="https://octave.org/">GNU Octave</a> / <a href="https://www.mathworks.com/products/matlab.html">Matlab</a> examples. The material was created with <a href="https://jupyterbook.org/">Jupyter Book</a> and <a href="https://jupyter.org/">JupyterLab</a> running the <a href="https://github.com/Calysto/octave_kernel">octave_kernel</a> using the <a href="../../../../blog/2021/06/10/octave-docker.html">Octave Docker image</a>.</p>
<section id="seminar-selected-topics-in-mathematical-optimization" class="level2">
<h2 class="anchored" data-anchor-id="seminar-selected-topics-in-mathematical-optimization">Seminar “Selected Topics in Mathematical Optimization”</h2>
<ul>
<li><a href="https://siko1056.github.io/optim-2021">Web version</a></li>
<li><a href="https://github.com/siko1056/optim-2021/blob/main/optim-2021.pdf">PDF version</a></li>
<li>Repository: <a href="https://github.com/siko1056/optim-2021" class="uri">https://github.com/siko1056/optim-2021</a></li>
</ul>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="./gauss_hills.png"><img src="https://siko1056.github.io/blog/2022/01/11/gauss_hills.png" class="img-fluid figure-img"></a></p>
<figcaption>mswin_octave_blas</figcaption>
</figure>
</div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode matlab code-with-copy"><code class="sourceCode matlab"><span id="cb1-1"><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">N</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-2">[<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">X</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">Y</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">meshgrid</span> (<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">linspace</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">N</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">N</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">40</span>))<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-3"></span>
<span id="cb1-4"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">% Gaussian probability density function (PDF)</span></span>
<span id="cb1-5"><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">GAUSS</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">@</span>(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">sigma</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">mu</span>)  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> (<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">sigma</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">sqrt</span> (<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">pi</span>)) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span></span>
<span id="cb1-6">                      <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">exp</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> ((<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">X</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">mu</span>(<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>))<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.^</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> (<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">Y</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">mu</span> (<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>))<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.^</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">sigma</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">^</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-7"></span>
<span id="cb1-8"><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">Z</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">9</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">GAUSS</span> (<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.6</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> [ <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2.0</span>]) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">GAUSS</span> (<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> [ <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.0</span>]) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span></span>
<span id="cb1-9">  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">GAUSS</span> (<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.4</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> [<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.0</span>]) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">GAUSS</span> (<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.3</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> [<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.5</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span>]) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span></span>
<span id="cb1-10">  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">GAUSS</span> (<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> [ <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2.0</span>])<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-11"></span>
<span id="cb1-12"><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">surf</span> (<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">X</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">Y</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">Z</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-13"><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">colormap</span> (<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">'jet'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-14"><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">view</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">55</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">21</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-15"><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">axis</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">off</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span></code></pre></div></div>


</section>

 ]]></description>
  <category>math</category>
  <category>octave</category>
  <guid>https://siko1056.github.io/blog/2022/01/11/seminar-optimization.html</guid>
  <pubDate>Tue, 11 Jan 2022 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Using directed rounding in Octave/Matlab</title>
  <dc:creator>Kai T. Ohlhus</dc:creator>
  <link>https://siko1056.github.io/blog/2021/12/23/octave-matlab-directed-rounding.html</link>
  <description><![CDATA[ 





<p>The current <a href="https://en.wikipedia.org/wiki/IEEE_754">IEEE Standard for Floating-Point Arithmetic</a> specifies several rounding modes, which have become accessible to the C/C++ programming languages as part of the <a href="https://en.wikipedia.org/wiki/C99">C99</a>, <a href="https://en.wikipedia.org/wiki/C%2B%2B11">C++11</a>, and following standards. GNU Octave and Matlab use in general multi-threaded <a href="https://en.wikipedia.org/wiki/Basic_Linear_Algebra_Subprograms">BLAS</a>/ <a href="https://en.wikipedia.org/wiki/LAPACK">LAPACK</a> library functions for fast matrix-vector-computations. Depending on the used library, improper thread synchronization might lead to unreliable results when switching the rounding mode using C/C++ functions. This article investigates how to reliably switch the rounding mode in GNU Octave using the performant <a href="https://www.openblas.net/">OpenBLAS</a> library and last resort problem mitigations for Matlab.</p>
<section id="rounding-modes-standards-and-implementations" class="level2">
<h2 class="anchored" data-anchor-id="rounding-modes-standards-and-implementations">Rounding modes: standards and implementations</h2>
<p>Switching the rounding mode is an important tool used by many verification methods based on floating-point arithmetic. The latter being only of <strong>finite precision</strong>, input data or results of numerical computations with “too long” fractional part have to be <strong>rounded</strong> to a <a href="https://en.wikipedia.org/wiki/Floating-point_arithmetic">floating-point number</a>, i.e.&nbsp;a number that fits “nicely” into the computers memory.</p>
<p>The rules for rounding are defined by the IEEE Standard for Floating-Point Arithmetic (IEEE-754 2019, <a href="https://doi.org/10.1109/IEEESTD.2019.8766229">doi: 10.1109/IEEESTD.2019.8766229</a>), which the <a href="https://en.wikipedia.org/wiki/C99">C99</a>, <a href="https://en.wikipedia.org/wiki/C%2B%2B11">C++11</a>, and later C/C++ standards refer to in an older version. Those rounding modes with respective C/C++ macros are:</p>
<ul>
<li>Roundings to nearest
<ul>
<li><code>FE_TONEAREST</code> (“ties to even”)</li>
<li>(“ties away from zero” is not available in C/C++)</li>
</ul></li>
<li>Directed roundings
<ul>
<li><code>FE_TOWARDZERO</code> = towards zero</li>
<li><code>FE_UPWARD</code> = towards +infinity</li>
<li><code>FE_DOWNWARD</code> = towards -infinity</li>
</ul></li>
</ul>
<p>C/C++ functions using the macros above are:</p>
<ul>
<li>since C99 <a href="https://en.cppreference.com/w/c/numeric/fenv/feround"><code>fesetround</code> and <code>fegetround</code></a></li>
<li>since C++11 <a href="https://en.cppreference.com/w/cpp/numeric/fenv/feround"><code>std::fesetround</code> and <code>std::fegetround</code></a>.</li>
</ul>
<p>Under the hood, for example in the GNU C library (glibc 2.34) the functions <a href="https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/x86_64/fpu/fesetround.c;h=2d3f1ca3c6102d06cfec0b8e64b807b750289467;hb=refs/heads/release/2.34/master">fesetround.c</a> and <a href="https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/x86_64/fpu/fegetround.c;h=0039987696f335f289d163bc4412b5d97698ee70;hb=refs/heads/release/2.34/master">fegetround.c</a> modify or read the active rounding mode from the <strong>global</strong> <a href="https://en.wikipedia.org/wiki/X87">x87 FPU Control Status Register</a> and <a href="https://en.wikipedia.org/wiki/Streaming_SIMD_Extensions#Registers">SSE Control Status Register (MXCSR)</a>. The state of those registers is part of a running process. During a <a href="https://en.wikipedia.org/wiki/Context_switch">process context switch</a> the register state (and thus the active rounding mode) is usually saved and restored properly.</p>
<p>With gaining popularity of multi-core processors, using light-weight <strong>threads</strong> has become more popular in software design. Context switches for threads are designed to be fast. For the sake of performance and depending on the implementation, some register states are not properly synchronized or at worst (partially) reset or cleared.</p>
<p>To overcome implementation-dependency, software libraries like BLAS/LAPACK have to manually take care of synchronizing those register states when starting a new thread. The situation for OpenBLAS is described below.</p>
<p>Further details about the specification and implementation of floating-point arithmetic can be found in many excellent articles and books. To name an exceptional all-encompassing source of information, see section 2.2, sub-section 3.4.4, chapter 6, and sub-section 6.1.3 in Muller <em>et al.</em> “Handbook of Floating-Point Arithmetic” (2018, <a href="https://doi.org/10.1007/978-3-319-76526-6">doi: 10.1007/978-3-319-76526-6</a>) or the respective <a href="https://en.wikipedia.org/wiki/IEEE_754#Rounding_rules">Wikipedia article</a>.</p>
</section>
<section id="changing-the-rounding-mode-from-octavematlab" class="level2">
<h2 class="anchored" data-anchor-id="changing-the-rounding-mode-from-octavematlab">Changing the rounding mode from Octave/Matlab</h2>
<p>Finally, the C function <code>fesetround</code> can be called from Octave/Matlab through the <a href="https://octave.org/doc/v6.4.0/Getting-Started-with-Mex_002dFiles.html">mex-file interface</a> using the following code <code>setround.c</code>:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode c code-with-copy"><code class="sourceCode c"><span id="cb1-1"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;mex.h&gt;</span></span>
<span id="cb1-2"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;fenv.h&gt;</span></span>
<span id="cb1-3"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;float.h&gt;</span></span>
<span id="cb1-4"></span>
<span id="cb1-5"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#pragma STDC FENV_ACCESS ON</span></span>
<span id="cb1-6"></span>
<span id="cb1-7"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> mexFunction <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> nlhs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> mxArray <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span>plhs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[],</span></span>
<span id="cb1-8">                   <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> nrhs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">const</span> mxArray <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span>prhs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb1-9"></span>
<span id="cb1-10">  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> rnd <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> mxGetScalar <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>prhs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]);</span></span>
<span id="cb1-11">  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> mode <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> FE_TONEAREST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-12"></span>
<span id="cb1-13">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">switch</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>rnd<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb1-14">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb1-15">      <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">case</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span></span>
<span id="cb1-16">        mode <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> FE_DOWNWARD<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-17">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">break</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-18">      <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">case</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span></span>
<span id="cb1-19">        mode <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> FE_TONEAREST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-20">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">break</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-21">      <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">case</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span></span>
<span id="cb1-22">        mode <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> FE_UPWARD<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-23">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">break</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-24">      <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">case</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span></span>
<span id="cb1-25">        mode <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> FE_TOWARDZERO<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-26">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">break</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-27">      <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">default</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span></span>
<span id="cb1-28">        mode <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> FE_TONEAREST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-29">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">break</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-30">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb1-31"></span>
<span id="cb1-32">  fesetround <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>mode<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb1-33"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>which can be compiled with:</p>
<pre><code>mex --std=c11 setround.c                          % Octave
mex ('CFLAGS="$CFLAGS --std=c11"', 'setround.c')  % Matlab</code></pre>
<p>Switching the rounding mode to +infinity would be done with the call:</p>
<pre><code>setround (+1);</code></pre>
<p>See <code>setround.c</code> for analogous calls for other rounding modes.</p>
<p>This approach of switching the rounding mode is most notably used by <a href="https://www.tuhh.de/ti3/rump/intlab/">INTLAB</a> or the <a href="https://gnu-octave.github.io/packages/interval">Interval package</a>.</p>
</section>
<section id="the-issue-parallel-matrix-computation" class="level2">
<h2 class="anchored" data-anchor-id="the-issue-parallel-matrix-computation">The issue: parallel matrix computation</h2>
<p>For “small” (single-threaded) computations (thus mostly scalars) the function <code>setround</code> works fine.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode matlab code-with-copy"><code class="sourceCode matlab"><span id="cb4-1"><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">e</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">eps</span> () <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">eps</span> ()<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span>  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">% smaller than machine precision</span></span>
<span id="cb4-2"><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">setround</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span>        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">% round to +inf</span></span>
<span id="cb4-3"><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">num2hex</span> (<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">e</span>)</span>
<span id="cb4-4"><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">ans</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">ff0000000000001</span></span>
<span id="cb4-5"></span>
<span id="cb4-6"><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">setround</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span>        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">% round to -inf</span></span>
<span id="cb4-7"><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">num2hex</span> (<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">e</span>)</span>
<span id="cb4-8"><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">ans</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">ff0000000000000</span></span></code></pre></div></div>
<p>However, the strength of Octave and Matlab is the ease and speed of matrix and vector computations. Therefore, it is desirable to perform those calculations using directed rounding modes as well.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode matlab code-with-copy"><code class="sourceCode matlab"><span id="cb5-1"><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">e</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">eps</span> () <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">eps</span> ()<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span>  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">% smaller than machine precision</span></span>
<span id="cb5-2"><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">setround</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span>        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">% round to +inf</span></span>
<span id="cb5-3"><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">a</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">ones</span>(<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">100</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">e</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb5-4"><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">a_sup</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">a</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">a</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span>        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">% use BLAS (multi-threaded)</span></span>
<span id="cb5-5"></span>
<span id="cb5-6"><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">setround</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span>        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">% round to -inf</span></span>
<span id="cb5-7"><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">a_inf</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">a</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">a</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span>        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">% use BLAS (multi-threaded)</span></span>
<span id="cb5-8"></span>
<span id="cb5-9"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">% The following value must be "0" (all values differ),</span></span>
<span id="cb5-10"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">% if rounding mode switching works correctly.</span></span>
<span id="cb5-11"><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">sum</span> (<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">a_inf</span>(<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">a_sup</span>(<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span>))</span></code></pre></div></div>
<p>As outlined above, Octave and Matlab use in general multi-threaded BLAS/LAPACK implementations for matrix and vector computations. The thread synchronization of the rounding mode (in the global register state) is often neglected by those BLAS/LAPACK implementations for the sake of performance and the code listing above returns a value larger than 0 (which means computing with <code>setround (+1)</code> or <code>setround (-1)</code> makes no difference at all).</p>
<p>For example OpenBLAS offers an <strong>optional</strong> compile flag <a href="https://github.com/xianyi/OpenBLAS/blob/253670383f15cd4d25c6be6b210dfa48a6dcc883/Makefile.rule#L210-L211"><code>CONSISTENT_FPCSR = 1</code></a> for manual rounding mode synchronization. See <a href="https://github.com/xianyi/OpenBLAS/blob/253670383f15cd4d25c6be6b210dfa48a6dcc883/driver/others/blas_server_omp.c#L284-L287"><code>driver/others/blas_server_omp.c</code></a>:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode c code-with-copy"><code class="sourceCode c"><span id="cb6-1"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">static</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> exec_threads<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>blas_queue_t <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span>queue<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> buf_index<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb6-2"></span>
<span id="cb6-3"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// ...</span></span>
<span id="cb6-4"></span>
<span id="cb6-5"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#ifdef CONSISTENT_FPCSR</span></span>
<span id="cb6-6">  __asm__ __volatile__ <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ldmxcsr %0"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"m"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>queue <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> sse_mode<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">));</span></span>
<span id="cb6-7">  __asm__ __volatile__ <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"fldcw %0"</span>   <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"m"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>queue <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> x87_mode<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">));</span></span>
<span id="cb6-8"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#endif</span></span></code></pre></div></div>
<p>Using this compile flag has already been suggested by <a href="http://verifiedby.me/adiary/?q=CONSISTENT_FPCSR&amp;all=1">Masahide Kashiwagi</a> (and <a href="http://verifiedby.me/adiary/0158">information on Apple M1 chips</a>) and by <a href="https://www.tuhh.de/ti3/rump/intlab/Octave/INTLAB_for_GNU_Octave.shtml">INTLAB</a>.</p>
<p>However, most Linux distributions provide OpenBLAS libraries without this compile flag set. And the situation seems similar for other BLAS/LAPACK implementations like the <a href="https://en.wikipedia.org/wiki/Math_Kernel_Library">Intel MKL</a>.</p>
<p>Therefore the remainder of this article deals with how to replace the default OpenBLAS version with a custom one compiled with the <code>CONSISTENT_FPCSR=1</code> flag set and, alternatively, how to ensure that only a single computation thread is used in Octave and Matlab, a slow and impractical last resort solution.</p>
</section>
<section id="octave-on-microsoft-windows" class="level2">
<h2 class="anchored" data-anchor-id="octave-on-microsoft-windows">Octave on Microsoft Windows</h2>
<p>It is assumed, that <a href="https://ftpmirror.gnu.org/octave/windows/octave-6.4.0-w64-installer.exe">octave-6.4.0-w64-installer.exe</a> from <a href="https://www.octave.org/download" class="uri">https://www.octave.org/download</a> has been successfully installed.</p>
<section id="option-1---single-computation-thread-slow" class="level3">
<h3 class="anchored" data-anchor-id="option-1---single-computation-thread-slow">Option 1 - Single computation thread (slow)</h3>
<p>Go in the Windows Explorer to the GNU Octave installation folder, for example:</p>
<pre><code>C:\Octave\Octave-6.4.0\</code></pre>
<p>and right-click on the <code>octave.vbs</code> (“edit”):</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="./mswin_octave_omp_num_threads.png"><img src="https://siko1056.github.io/blog/2021/12/23/mswin_octave_omp_num_threads.png" class="img-fluid figure-img"></a></p>
<figcaption>mswin_octave_blas</figcaption>
</figure>
</div>
<p>and add in the text editor the line:</p>
<pre><code>wshSystemEnv("OMP_NUM_THREADS") = "1"</code></pre>
<p>as shown in the screenshot above and start Octave as usual.</p>
</section>
<section id="option-2---replace-libblas.dll" class="level3">
<h3 class="anchored" data-anchor-id="option-2---replace-libblas.dll">Option 2 - Replace <code>libblas.dll</code></h3>
<p>Download the file compiled <a href="https://en.wikipedia.org/wiki/Dynamic-link_library">dynamic-link library (DLL)</a> for OpenBLAS:</p>
<ul>
<li><a href="./libopenblasFPCSR-0.3.18.dll">libopenblasFPCSR-0.3.18.dll</a> Below the DLL-file creation is described.</li>
</ul>
<blockquote class="blockquote">
<p>For the next steps <strong>administrator privileges</strong> might be required. Click yes of you are prompted for confirmation.</p>
</blockquote>
<p>Put the DLL-file in the directory</p>
<pre><code>C:\Octave\Octave-6.4.0\mingw64\bin</code></pre>
<p>like in the screenshot below:</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="./mswin_octave_blas.png"><img src="https://siko1056.github.io/blog/2021/12/23/mswin_octave_blas.png" class="img-fluid figure-img"></a></p>
<figcaption>mswin_octave_blas</figcaption>
</figure>
</div>
<p>Delete the file <code>libblas.dll</code>.</p>
<p>Copy <code>libopenblasFPCSR-0.3.18.dll</code> and rename the copy to <code>libblas.dll</code>.</p>
<blockquote class="blockquote">
<p>If you want to <strong>undo this change</strong>: Delete the file <code>libblas.dll</code> again.</p>
<p>Copy <code>libopenblas.dll</code> and rename the copy to <code>libblas.dll</code>.</p>
</blockquote>
<blockquote class="blockquote">
<p><strong>How to create <code>libopenblasFPCSR-0.3.18.dll</code></strong></p>
<p>One can make use of the <a href="https://wiki.octave.org/Windows_Installer">MXE Octave</a> project to cross-compile Octave for MS Windows <strong>on Linux</strong>.</p>
<pre><code>hg clone https://hg.octave.org/mxe-octave
cd mxe-octave
./bootstrap
./configure                        \
  --enable-devel-tools             \
  --enable-binary-packages         \
  --with-ccache                    \
  --enable-octave=release</code></pre>
<p>Edit the file <a href="https://hg.octave.org/mxe-octave/file/6f8def83bcf7/src/openblas.mk#l27"><code>mxe-octave/src/openblas.mk</code></a> and add about line 28 to <code>$(PKG)_MAKE_OPTS</code> the compile flag <code>CONSISTENT_FPCSR=1</code>.</p>
<p>Then compile the project (this might take a few hours):</p>
<pre><code>make JOBS=8 all openblas</code></pre>
<p>Finally find the OpenBLAS DLL in:</p>
<pre><code>mxe-octave//usr/x86_64-w64-mingw32/bin/libopenblas.dll</code></pre>
<p>Rename and use it as described above.</p>
</blockquote>
</section>
</section>
<section id="octave-on-macos" class="level2">
<h2 class="anchored" data-anchor-id="octave-on-macos">Octave on macOS</h2>
<p>It is assumed, that GNU Octave is installed via Homebrew <a href="https://brew.sh/" class="uri">https://brew.sh/</a>:</p>
<pre><code>brew install octave</code></pre>
<section id="option-1---single-computation-thread-slow-1" class="level3">
<h3 class="anchored" data-anchor-id="option-1---single-computation-thread-slow-1">Option 1 - Single computation thread (slow)</h3>
<p>Start Octave from the Terminal with this command:</p>
<pre><code>OMP_NUM_THREADS=1 octave --gui</code></pre>
</section>
<section id="option-2---rebuild-openblas" class="level3">
<h3 class="anchored" data-anchor-id="option-2---rebuild-openblas">Option 2 - Rebuild OpenBLAS</h3>
<p>Edit the Homebrew Formula for OpenBLAS:</p>
<pre><code>export EDITOR="open -a TextEdit"  # optional
brew edit openblas</code></pre>
<p>and add the line in the “def install” section</p>
<pre><code>ENV["CONSISTENT_FPCSR"] = "1"</code></pre>
<p>like in the screenshot below:</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="./macos_openblas.png"><img src="https://siko1056.github.io/blog/2021/12/23/macos_openblas.png" class="img-fluid figure-img"></a></p>
<figcaption>macos_openblas</figcaption>
</figure>
</div>
<blockquote class="blockquote">
<p>EDIT: 20206-05-20</p>
<p>As part of this project, on 2022-09-22 the OpenBLAS project accepted a patch for Apple M1+ (aarch64 architecture) with the OpenBLAS release v0.3.22: <a href="https://github.com/OpenMathLib/OpenBLAS/commit/84453b924fe7695029cad974dfe0cf7bf6ffe0f6">84453b9</a>.</p>
<p>Full credit for the idea of this patch is to Masahide Kashiwagi in the previously mentioned <a href="http://verifiedby.me/adiary/0158">blog post on Apple M1 chips</a>.</p>
<p>A previously here described OpenBLAS source code patching is no longer required.</p>
</blockquote>
<p>Finally run from the Terminal:</p>
<pre><code>export HOMEBREW_NO_INSTALL_FROM_API=1  # Ensure to use local changes
brew uninstall --ignore-dependencies openblas
brew reinstall --build-from-source   openblas</code></pre>
<p>The compilation and installation might take about 15-20 minutes.</p>
<blockquote class="blockquote">
<p>If you want to <strong>undo this change</strong>:</p>
<pre><code>cd /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core
git restore Formula/openblas.rb
brew uninstall --ignore-dependencies openblas
brew install openblas</code></pre>
</blockquote>
</section>
</section>
<section id="octave-on-linux" class="level2">
<h2 class="anchored" data-anchor-id="octave-on-linux">Octave on Linux</h2>
<section id="option-1---single-computation-thread-slow-2" class="level3">
<h3 class="anchored" data-anchor-id="option-1---single-computation-thread-slow-2">Option 1 - Single computation thread (slow)</h3>
<p>Start Octave from the Terminal with this command:</p>
<pre><code>OMP_NUM_THREADS=1 octave --gui</code></pre>
</section>
<section id="option-2---rebuild-openblas-1" class="level3">
<h3 class="anchored" data-anchor-id="option-2---rebuild-openblas-1">Option 2 - Rebuild OpenBLAS</h3>
<blockquote class="blockquote">
<p><strong>Note:</strong> This approach does not work with Snap, Flatpak, or Docker installations of GNU Octave.</p>
</blockquote>
<p>Download and extract the OpenBLAS source code:</p>
<pre><code>cd /tmp
wget https://github.com/xianyi/OpenBLAS/archive/refs/tags/v0.3.19.tar.gz
tar -xf v0.3.19.tar.gz
cd OpenBLAS-0.3.19</code></pre>
<p>Build OpenBLAS (note: if you compiled Octave with <a href="https://en.wikipedia.org/wiki/64-bit_computing#64-bit_data_models">ilp64</a> add the flags <code>BINARY=64 INTERFACE64=1</code> to the <code>make</code> command) this should take about 5-10 minutes:</p>
<pre><code>make -j8             \
  CONSISTENT_FPCSR=1 \
  USE_THREAD=1       \
  USE_OPENMP=1       \
  NUM_THREADS=256</code></pre>
<p>Then locally install the library:</p>
<pre><code>make install PREFIX=$HOME</code></pre>
<p>Finally start Octave with this command (the part <code>_haswell</code> might differ depending on the used CPU):</p>
<pre><code>LD_PRELOAD=$HOME/lib/libopenblas_haswellp-r0.3.19.so octave --gui
&gt;&gt; version -blas
ans = OpenBLAS (config: OpenBLAS 0.3.19 NO_AFFINITY USE_OPENMP HASWELL MAX_THREADS=256)</code></pre>
</section>
</section>
<section id="matlab" class="level2">
<h2 class="anchored" data-anchor-id="matlab">Matlab</h2>
<p>In an <a href="https://undocumentedmatlab.com/articles/undocumented-feature-function">undocumented <code>feature</code>-function</a> Matlab offers an implementation, similar to <code>setround</code> above:</p>
<pre><code>feature ('setround', mode);  % mode = 0, 0.5, +Inf, or -Inf</code></pre>
<p>However, this function has the same limitations as <code>setround</code> and as it is no official function, it is not expected to work reliably. With every new Matlab release the thread synchronization of the underlying <a href="https://en.wikipedia.org/wiki/Math_Kernel_Library">Intel MKL</a> works more of less reliable. At the time of writing, Matlab R2020b is known to work, while Matlab R2021a is not.</p>
<p>A known reliable workaround is to force Matlab to only use a single computations thread with the startup option <code>-singleCompThread</code>. This works on <a href="https://www.mathworks.com/help/matlab/ref/matlabwindows.html">MS Windows</a>, <a href="https://www.mathworks.com/help/matlab/ref/matlabmacos.html">macOS</a>, and <a href="https://www.mathworks.com/help/matlab/ref/matlablinux.html">Linux</a>.</p>
</section>
<section id="summary" class="level2">
<h2 class="anchored" data-anchor-id="summary">Summary</h2>
<p>In this blog post the issue of reliably changing the rounding mode for basic linear algebra operations within multi-threaded BLAS/LAPACK libraries using C/C++ instructions from Octave and Matlab was investigated.</p>
<p>While Octave can address this problem by using a customized OpenBLAS or slower reference BLAS/LAPACK implementation, each Matlab release must be evaluated for limitations of the underlying Intel MKL. A solution of last resort for both Octave and Matlab is enforcing a single computation thread, sacrificing all benefits of having multiple CPU cores available.</p>
<p>The proposed solutions do not apply for <a href="https://en.wikipedia.org/wiki/Graphics_processing_unit">graphics processing units (GPUs)</a>, and associated numerical libraries, as the architecture and command set differs significantly from the CPU.</p>


</section>

 ]]></description>
  <category>matlab</category>
  <category>octave</category>
  <guid>https://siko1056.github.io/blog/2021/12/23/octave-matlab-directed-rounding.html</guid>
  <pubDate>Thu, 23 Dec 2021 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Talk (online) at the JST/CREST meeting</title>
  <dc:creator>Kai T. Ohlhus</dc:creator>
  <link>https://siko1056.github.io/blog/2021/11/27/talk-nvr.html</link>
  <description><![CDATA[ 





<p>The <a href="https://github.com/siko1056/slides_nvr2021/blob/main/slides.pdf">slides</a> about the <a href="https://github.com/gnu-octave/pkg-apa">arbitrary precision arithmetic (APA) toolbox</a> of my talk at the “JST/CREST”Development of Verified Numerical Computations for Mathematical Modeling” Result Briefing” <a href="http://verifiedby.me/nvr2021/" class="uri">http://verifiedby.me/nvr2021/</a> (online).</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://github.com/siko1056/slides_nvr2021/blob/main/slides.pdf"><img src="https://siko1056.github.io/blog/2021/11/27/title_slide.png" class="img-fluid figure-img"></a></p>
<figcaption>slides</figcaption>
</figure>
</div>
<p>The talk reviews existing GNU Octave/Matlab arbitrary precision arithmetic toolboxes, summarizes the current development status of the APA toolbox with usage examples, benchmarks, and an outlook for further extension.</p>



 ]]></description>
  <category>octave</category>
  <category>talk</category>
  <guid>https://siko1056.github.io/blog/2021/11/27/talk-nvr.html</guid>
  <pubDate>Sat, 27 Nov 2021 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Bring your own Octave</title>
  <dc:creator>Kai T. Ohlhus</dc:creator>
  <link>https://siko1056.github.io/blog/2021/06/10/octave-docker.html</link>
  <description><![CDATA[ 





<p>Thanks to the efforts of many developers, <a href="https://octave.org">GNU Octave</a> can be installed on all commonly used Linux distributions today. If the native distribution Octave package is out of date, <a href="https://wiki.octave.org/Octave_for_GNU/Linux#Distribution_independent">Flatpak, snap, and others</a> jump in the gab. Even though the latter systems keep on improving, in the end they are distributed versions, designed to be useful to many users and often difficult to customize. This article describes another distribution independent Octave version, based on <a href="https://wiki.octave.org/Octave_for_GNU/Linux#Distribution_independent">Docker/Podman/Singularity</a> images, which can be customized and shared with others. Moreover, it can use <a href="./octave_jupyterlab.png">JupyterLab</a> as alternative “GUI” for Octave.</p>
<section id="what-is-this-project-about" class="level2">
<h2 class="anchored" data-anchor-id="what-is-this-project-about">What is this project about?</h2>
<p>The <a href="https://github.com/gnu-octave/docker" class="uri">https://github.com/gnu-octave/docker</a> repository defines Docker images - to build Octave (e.g.&nbsp;<a href="https://github.com/gnu-octave/docker/blob/c4b868f47648e49dd882df8c40912e3781a16909/build-octave-6.docker"><code>build-octave-6.docker</code></a>), - to run a certain Octave release (e.g.&nbsp;<a href="https://github.com/gnu-octave/docker/blob/c4b868f47648e49dd882df8c40912e3781a16909/octave-6.docker"><code>octave-6.docker</code></a>), and - to run software on top of Octave (e.g.&nbsp;<a href="https://github.com/gnu-octave/docker/tree/c4b868f47648e49dd882df8c40912e3781a16909/jupyterlab">JupyterLab</a>).</p>
<p>Those Docker images are rebuilt monthly to incorporate maintenance and security updates and distributed via DockerHub: - <a href="https://hub.docker.com/r/gnuoctave/octave" class="uri">https://hub.docker.com/r/gnuoctave/octave</a> - <a href="https://hub.docker.com/r/gnuoctave/octave-build" class="uri">https://hub.docker.com/r/gnuoctave/octave-build</a></p>
<p>The images can be used by <a href="https://www.docker.com/">Docker</a> (= <a href="https://podman.io/">Podman</a>) and <a href="https://sylabs.io/singularity/">Singularity</a>. In the end of this article, some recommendations and experiences regarding the tools are given.</p>
<p>The following figure summarizes the available Octave Docker images and their dependencies.</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="./docker_image_hierachy.png"><img src="https://siko1056.github.io/blog/2021/06/10/docker_image_hierachy.png" class="img-fluid figure-img"></a></p>
<figcaption>octave_docker_overview</figcaption>
</figure>
</div>
</section>
<section id="what-makes-this-project-different" class="level2">
<h2 class="anchored" data-anchor-id="what-makes-this-project-different">What makes this project different?</h2>
<p>The Octave Docker images are created with several usage scenarios in mind.</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="./octave_docker_overview.png"><img src="https://siko1056.github.io/blog/2021/06/10/octave_docker_overview.png" class="img-fluid figure-img"></a></p>
<figcaption>octave_docker_overview</figcaption>
</figure>
</div>
<ul>
<li><p><strong>Simple usage by (non-root) users</strong></p>
<p>An installation script is provided, that can be called directly with this shell command:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb1-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">## Install</span></span>
<span id="cb1-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">/bin/bash</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-c</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$(</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">curl</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-fsSL</span> https://raw.githubusercontent.com/gnu-octave/docker/main/install.sh<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">)</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span> install <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-t</span> singularity</span>
<span id="cb1-3"></span>
<span id="cb1-4"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">## Uninstall</span></span>
<span id="cb1-5"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">/bin/bash</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-c</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$(</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">curl</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-fsSL</span> https://raw.githubusercontent.com/gnu-octave/docker/main/install.sh<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">)</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span> install <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-u</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-t</span> singularity</span></code></pre></div></div>
<p>It creates links in <code>$HOME/bin</code>, as well as Desktop entries, to start the Octave <strong>and JupyterLab</strong> as if it was installed by the Linux distribution.</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="./octave_launcher.png"><img src="https://siko1056.github.io/blog/2021/06/10/octave_launcher.png" class="img-fluid figure-img"></a></p>
<figcaption>octave_docker_overview</figcaption>
</figure>
</div>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="./octave_jupyterlab.png"><img src="https://siko1056.github.io/blog/2021/06/10/octave_jupyterlab.png" class="img-fluid figure-img"></a></p>
<figcaption>octave_docker_overview</figcaption>
</figure>
</div>
<p><strong>Note:</strong> The system must have either Docker (= Podman) or Singularity installed and the user account must be setup to use those tools properly. Please adapt the shell command after <code>-t</code> respectively.</p></li>
<li><p><strong>“Time travels”</strong> (Docker only)</p>
<p>Octave (package) developers, who want to test a specific Octave version X &gt;= 4.0.0 (CLI or GUI) can pull the desired Docker image and don’t have to worry about incompatible libraries or overlapping installations.</p>
<blockquote class="blockquote">
<p><strong>Hint:</strong> Using the installation script (described above), the desired version can be started very conveniently</p>
<ul>
<li><a href="./Octave_4.0.0.png"><code>OCTAVE_VERSION=4.0.0 octave --force-gui</code></a></li>
<li><a href="./Octave_4.2.0.png"><code>OCTAVE_VERSION=4.2.0 octave --force-gui</code></a></li>
<li><a href="./Octave_4.4.0.png"><code>OCTAVE_VERSION=4.4.0 octave --gui</code></a></li>
<li><a href="./Octave_5.1.0.png"><code>OCTAVE_VERSION=5.1.0 octave --gui</code></a></li>
<li><a href="./Octave_6.1.0.png"><code>OCTAVE_VERSION=6.1.0 octave --gui</code></a></li>
</ul>
</blockquote>
<p>Please note that storing all those Octave version images is expensive. Therefore it is recommend to use <strong>Docker</strong> (Podman) for this task. In contrast to Singularity, Docker does not bundle all image layers into a single file. Image layers shared between images (e.g.&nbsp;Octave 4.0.0 and 4.0.1) do not have to be stored twice.</p>
<p>After pulling all images:</p>
<pre><code>$ docker images
REPOSITORY         TAG          IMAGE ID      ...  SIZE
gnuoctave/octave   jupyterlab   c3f33109a9df  ...  3.81GB
gnuoctave/octave   6.2.0        dc589b215991  ...  3.48GB
gnuoctave/octave   6.1.0        635b3b411836  ...  3.47GB
gnuoctave/octave   4.2.1        889f5cf8bbb9  ...  2.34GB
gnuoctave/octave   5.1.0        56d1f94f3260  ...  2.83GB
gnuoctave/octave   4.2.0        21e4bc9e07c0  ...  2.34GB
gnuoctave/octave   5.2.0        8008f6c20bbe  ...  2.83GB
gnuoctave/octave   4.4.1        dddef7f82523  ...  2.82GB
gnuoctave/octave   4.2.2        c21b8daf6a96  ...  2.34GB
gnuoctave/octave   4.4.0        ecf795465a96  ...  2.82GB
gnuoctave/octave   4.0.1        aad035508ad4  ...  2.33GB
gnuoctave/octave   4.0.2        9752ba4f54a9  ...  2.32GB
gnuoctave/octave   4.0.3        df6af0aee010  ...  2.32GB
gnuoctave/octave   4.0.0        d89e88593166  ...  2.33GB</code></pre>
<p>Summing up their sizes gives <strong>38.38 GB</strong>. But thanks to shared layers</p>
<pre><code>$ docker system df
TYPE     TOTAL  ...  SIZE      RECLAIMABLE
Images   14     ...  15.06GB   15.06GB (100%)</code></pre>
<p>the real storage requirement is only <strong>15.06 GB (39 %)</strong>.</p></li>
<li><p><strong>CI projects</strong></p>
<p>Automated Continuous Integration (CI) for software testing is becoming popular these days. For example the <a href="https://github.com/gnu-octave/packages">Octave Packages</a> index uses the latest stable Octave image with <a href="https://github.com/gnu-octave/packages/blob/ef2ee4290d64c087183b454db5e8f003857741f7/.github/workflows/main.yml#L62-L79">GitHub Actions</a> to perform basic package checks.</p></li>
</ul>
</section>
<section id="customizing-the-images-or-your-own-octave" class="level2">
<h2 class="anchored" data-anchor-id="customizing-the-images-or-your-own-octave">Customizing the images or “your own Octave”</h2>
<blockquote class="blockquote">
<p><strong>Off-topic note</strong></p>
<p>When starting this blog post, <a href="https://www.docker.com/blog/changes-to-docker-hub-autobuilds/">unfortunate news</a> regarding the shutdown of the “free” DockerHub Autobuild service were published.</p>
<p>It took lots of time to get the Autobuild setup right and it was planned to advertise it in this blog post as “the way” to customize and publish Octave images. Many thanks to the DockerHub maintainers for their great service. It is a shame that free services are being misused.</p>
</blockquote>
<p>If the choice of bundled software or configurations is not satisfactory, there are options for customization:</p>
<section id="adding-a-missing-software-library" class="level3">
<h3 class="anchored" data-anchor-id="adding-a-missing-software-library">Adding a missing software (library)</h3>
<p>The easiest task is to add to the existing Octave Docker images. This can be done by a <code>Dockerfile</code>:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb4-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">FROM</span>  gnuoctave/octave:6.2.0</span>
<span id="cb4-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">LABEL</span> maintainer=<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Your Name &lt;e@mail.com&gt;"</span></span>
<span id="cb4-3"></span>
<span id="cb4-4"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># If a privileged installation is necessary</span></span>
<span id="cb4-5"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">USER</span> root</span>
<span id="cb4-6"></span>
<span id="cb4-7"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Install a missing Ubuntu package</span></span>
<span id="cb4-8"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">RUN</span> apt-get <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--yes</span> update  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">&amp;&amp;</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb4-9">    <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">DEBIAN_FRONTEND</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"noninteractive"</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb4-10">    <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">apt-get</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--no-install-recommends</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--yes</span> install <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb4-11">      missing-ubuntu-package</span>
<span id="cb4-12"></span>
<span id="cb4-13"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Install a custom library (Note: GLPK is already installed!)</span></span>
<span id="cb4-14"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">RUN</span> GLPK_VERSION=5.0     <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">&amp;&amp;</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb4-15">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mkdir</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-p</span> /tmp/build  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">&amp;&amp;</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb4-16">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">cd</span>       /tmp/build  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">&amp;&amp;</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb4-17">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">wget</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-q</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"https://ftp.gnu.org/gnu/glpk/glpk-</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">${GLPK_VERSION}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">.tar.gz"</span>  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">&amp;&amp;</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb4-18">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tar</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-xf</span> glpk-<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">${GLPK_VERSION}</span>.tar.gz  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">&amp;&amp;</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb4-19">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">cd</span>      glpk-<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">${GLPK_VERSION}</span>         <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">&amp;&amp;</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb4-20">    <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">./configure</span>             <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb4-21">      <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--with-gmp</span>            <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb4-22">      <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--prefix</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>/usr         <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb4-23">      <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--libdir</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>/usr/lib  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">&amp;&amp;</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb4-24">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">make</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-j8</span>             <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">&amp;&amp;</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb4-25">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">make</span> check           <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">&amp;&amp;</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb4-26">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">make</span> install         <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">&amp;&amp;</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb4-27">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rm</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-rf</span> /tmp/build</span>
<span id="cb4-28"></span>
<span id="cb4-29"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Ensure starting with an unprivileged default user.</span></span>
<span id="cb4-30"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">USER</span> jovyan</span></code></pre></div></div>
<p>Finally the customized Octave Docker image can be build locally with the <a href="https://docs.docker.com/engine/reference/commandline/build/"><code>docker build</code>-command</a> or by using an automated build service like <a href="https://github.com/gnu-octave/docker/blob/155443345ab77e93e186e0c251ac442870aaba70/.github/workflows/build_octave.yml">GitHub Actions</a>.</p>
<p>For example, building <strong>all</strong> provided Octave images using GitHub Actions takes about three hours. As one can see in the next figure, extending existing images is much faster (the JupyterLab extensions takes just 3 minutes to build), as most of the “hard” work is already done.</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="./github_actions.png"><img src="https://siko1056.github.io/blog/2021/06/10/github_actions.png" class="img-fluid figure-img"></a></p>
<figcaption>octave_docker_overview</figcaption>
</figure>
</div>
</section>
<section id="customizing-existing-images" class="level3">
<h3 class="anchored" data-anchor-id="customizing-existing-images">Customizing existing images</h3>
<p>To change the existing Octave Docker images, it is recommended to copy the <code>Dockerfile</code>(s) of interest, to modify and build them (locally or by an automated build service).</p>
<p>For Octave 6.2.0 + JupyterLab the <code>Dockerfile</code>(s) of interest are in the chain <a href="https://github.com/gnu-octave/docker/blob/c4b868f47648e49dd882df8c40912e3781a16909/build-octave-6.docker"><code>build-octave-6.docker</code></a> ➡ <a href="https://github.com/gnu-octave/docker/blob/c4b868f47648e49dd882df8c40912e3781a16909/octave-6.docker"><code>octave-6.docker</code></a> ➡ <a href="https://github.com/gnu-octave/docker/blob/c4b868f47648e49dd882df8c40912e3781a16909/jupyterlab/Dockerfile"><code>jupyterlab/Dockerfile</code></a>.</p>
<p>What is remarkable about this approach is that uploading those customized images makes the installation as easy as with the already provided Octave Docker base images of <a href="https://hub.docker.com/r/gnuoctave/octave" class="uri">https://hub.docker.com/r/gnuoctave/octave</a>. In particular, there is no need to beg or convince distribution maintainers to regard own desired customizations.</p>
</section>
</section>
<section id="bad-news-for-oldtimers-rhelcentos-7" class="level2">
<h2 class="anchored" data-anchor-id="bad-news-for-oldtimers-rhelcentos-7">Bad news for oldtimers (RHEL/CentOS 7)</h2>
<p>Even though containers are great to become independent of the host system, some elementary requirements remain, such as the Linux kernel. <a href="https://en.wikipedia.org/wiki/CentOS">RHEL/CentOS 7</a> uses Linux 3.10 and is a dominant distribution in many companies and universities until the end of life in June 2024.</p>
<p>All Docker images up to Octave 5 work on RHEL/CentOS 7 without problems. In contrast, Octave 6 images (and all newer Octave images in the future) use Ubuntu 20.04 as base image. The qt libraries of Ubuntu 20.04 are compiled using a Linux kernel feature, <a href="https://code.qt.io/cgit/qt/qtbase.git/tree/src/corelib/global/minimum-linux_p.h?id=4d9ac14bf8d1c1a33a2720c7f7dcaf8d912a592f#n77">which is not given in Linux 3.10</a>, and any attempts to start the GUI or print graphics will end with this error message:</p>
<pre><code>$ octave
/usr/libexec/octave/6.2.0/exec/x86_64-pc-linux-gnu/octave-gui: error while loading shared libraries: libQt5Core.so.5: cannot open shared object file: No such file or directory</code></pre>
<p>If you only use the CLI version for computations and avoid graphics (which is an unrealistic use case for a desktop installation of Octave), you can sneak around this limitation.</p>
<pre><code>$ octave-cli
GNU Octave, version 6.2.0
[...]
For information about changes from previous versions, type 'news'.

&gt;&gt;</code></pre>
<p>As described in the last section, you are free to customize and publish Docker images building Octave 6 based upon the <a href="https://hub.docker.com/r/gnuoctave/octave-build">docker.io/gnuoctave/octave-build:5</a> image.</p>
</section>
<section id="summary" class="level2">
<h2 class="anchored" data-anchor-id="summary">Summary</h2>
<p>Another Linux distribution independent way to install and run GNU Octave was introduced. The approach offers new ways of using and sharing customized Octave installations.</p>
<p>For the average user both, Docker and Singularity, perform equally well. <strong>Docker</strong> is to favor, when the intention is to install several Octave versions in parallel (see “Time travels” above). <strong>Singularity</strong> is clearly the choice for archiving or sharing images. This is in particular interesting for research projects, where all Octave setups should be at best equal and unaffected by updates or system changes. <strong>Podman</strong>, despite all praises by RedHat, had problems when running the Octave Docker images as non-root user. For example dealing with the default internal container user “jovyan” or the GPU and graphics support has still some flaws.</p>
<p>Finally, thanks to GitHub Actions and DockerHub, maintaining the introduced infrastructure comes almost for free.</p>


</section>

 ]]></description>
  <category>octave</category>
  <guid>https://siko1056.github.io/blog/2021/06/10/octave-docker.html</guid>
  <pubDate>Thu, 10 Jun 2021 00:00:00 GMT</pubDate>
</item>
<item>
  <title>SavannahAPI - A more systematic overview about bugs and patches</title>
  <dc:creator>Kai T. Ohlhus</dc:creator>
  <link>https://siko1056.github.io/blog/2021/03/17/savannah-api.html</link>
  <description><![CDATA[ 





<p>The <a href="https://octave.org">GNU Octave</a> project is registered on the code hosting platform <a href="https://savannah.gnu.org/">GNU Savannah</a> since April 2002. With about 10,000 of 60,000 bugs, Octave is one of its biggest and most active users. However, the issue tracker interface has some limitations and valuable information is not as accessible as it can be. A <a href="https://en.wikipedia.org/wiki/Web_scraping">data scraping</a> approach <a href="https://github.com/gnu-octave/SavannahAPI">SavannahAPI</a> overcomes some of these limitations and offers interesting new insights and overviews.</p>
<blockquote class="blockquote">
<p>EDIT: 2024-04-10 Project moved <a href="https://octave.space/savannah" class="uri">https://octave.space/savannah</a> → <a href="https://savannah.octave.org" class="uri">https://savannah.octave.org</a>.</p>
</blockquote>
<section id="the-savannahapi-interface" class="level2">
<h2 class="anchored" data-anchor-id="the-savannahapi-interface">The SavannahAPI interface</h2>
<p>First and most important: SavannahAPI is <strong>not</strong> a new GNU Savannah. SavannahAPI only provides improved <strong>read access</strong> to the issues (bugs and patches) for a particular GNU Savannah project. There is no possibility to edit or modify issues, neither it has a user or account management.</p>
<p>For an interface description, see the <a href="https://github.com/gnu-octave/SavannahAPI">project README.md on GitHub</a>.</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://savannah.octave.org/"><img src="https://siko1056.github.io/blog/2021/03/17/SavannahAPI_client.png" class="img-fluid figure-img"></a></p>
<figcaption>JavaScript client</figcaption>
</figure>
</div>
<p>While working on the Octave project with GNU Savannah for a few years, I often felt a <strong>lack of overview</strong> about the ever growing number of bugs. Now (March 2021) there are more than 10,000 issues (bugs and patches) accumulated in a time span of more than 10 years.</p>
<p>Some specific points that I missed with GNU Savannah are:</p>
<section id="search-over-all-issues-bugs-and-patches" class="level3">
<h3 class="anchored" data-anchor-id="search-over-all-issues-bugs-and-patches">1. Search over all issues (bugs and patches)</h3>
<p>The Savannah issue trackers are divided into bugs, patches, and tasks. The latter tracker is not really used by the Octave project. Thus searching for a keyword (e.g.&nbsp;“fminsearch”) involves at least two separate searches <a href="https://savannah.gnu.org/search/?Search=Search&amp;words=fminsearch&amp;type_of_search=bugs&amp;only_group_id=1925&amp;exact=1&amp;max_rows=25#options">on the bugs</a> and <a href="https://savannah.gnu.org/search/?Search=Search&amp;words=fminsearch&amp;type_of_search=patch&amp;only_group_id=1925&amp;exact=1&amp;max_rows=25#options">on the patch</a> tracker.</p>
<blockquote class="blockquote">
<p><strong>SavannahAPI</strong> does not distinguish between bugs or patches. <a href="https://savannah.octave.org/?Action=get&amp;Format=HTMLCSS&amp;OrderBy=TrackerID,!ItemID&amp;Keywords=fminsearch">A single search is enough.</a></p>
</blockquote>
</section>
<section id="search---is-it-already-fixed" class="level3">
<h3 class="anchored" data-anchor-id="search---is-it-already-fixed">2. Search - Is it already fixed?</h3>
<p>The first point almost leads to this one. Even if your search for a keyword succeeded, for example <a href="https://savannah.gnu.org/search/?Search=Search&amp;words=fminsearch&amp;type_of_search=bugs&amp;only_group_id=1925&amp;exact=1&amp;max_rows=25#options">“fminsearch” on the bugs tracker</a>, how should one know (except for clicking on each and every search hit) that this issue is open or closed?</p>
<p>This seemingly unnecessary information (open or closed) is often interesting when touching an Octave function for changes, because: - one gets to know something else is wrong with “fminsearch”, for example, and some unexpected results are not necessarily my fault. - one can simultaneously incorporate smaller changes or patches into own changes.</p>
<blockquote class="blockquote">
<p><strong>SavannahAPI</strong> <a href="https://savannah.octave.org/?Action=get&amp;Format=HTMLCSS&amp;OrderBy=TrackerID,!ItemID&amp;Keywords=fminsearch">shows (almost) all bug information by default</a>, especially green and red color indicators. Unnecessary information can be filtered out and search results further narrowed down.</p>
</blockquote>
</section>
<section id="browse---getting-issues-by-categories-predicates" class="level3">
<h3 class="anchored" data-anchor-id="browse---getting-issues-by-categories-predicates">3. Browse - Getting issues by categories (predicates)</h3>
<p>Despite keyword searches Savannah offers “browsing” issues. That is selecting a single or multiple predicates from some predicate groups</p>
<ul>
<li>status (none, fixed, patch submitted, …)</li>
<li>item group (none, regression, build failure, …)</li>
<li>…</li>
</ul>
<p>to narrow down the set of displayed issues.</p>
<p>Getting a useful combination of those predicates is an art. For example, to find <a href="https://savannah.gnu.org/bugs/index.php?go_report=Apply&amp;group=octave&amp;func=browse&amp;set=custom&amp;msort=0&amp;report_id=221&amp;advsrch=1&amp;resolution_id%5B%5D=0&amp;bug_group_id%5B%5D=0&amp;status_id%5B%5D=1&amp;priority%5B%5D=0&amp;severity%5B%5D=0&amp;category_id%5B%5D=100&amp;category_id%5B%5D=110&amp;category_id%5B%5D=101&amp;category_id%5B%5D=102&amp;category_id%5B%5D=104&amp;category_id%5B%5D=105&amp;category_id%5B%5D=106&amp;category_id%5B%5D=107&amp;category_id%5B%5D=103&amp;category_id%5B%5D=114&amp;category_id%5B%5D=112&amp;category_id%5B%5D=109&amp;category_id%5B%5D=113&amp;release_id%5B%5D=173&amp;release_id%5B%5D=174&amp;platform_version_id%5B%5D=0&amp;history_search=0&amp;history_field=0&amp;history_event=modified&amp;history_date_dayfd=25&amp;history_date_monthfd=2&amp;history_date_yearfd=2021&amp;chunksz=100&amp;spamscore=5&amp;boxoptionwanted=1#options">all Octave bugs related to the release 6 (6.1.0, 6.2.0)</a>.</p>
<p>After several trials and errors clicking through the combo boxes, excluding Octave Forge and Website related bugs, you get presented some naked bug IDs. There should be a <a href="https://savannah.nongnu.org/support/?110340">workaround</a>, but this type of by admin customized searches do likely not satisfy the needs of another user.</p>
<blockquote class="blockquote">
<p><strong>SavannahAPI</strong> uses a <a href="https://github.com/gnu-octave/SavannahAPI#api-parameter-syntax-and-grammar">query language</a> that is editable and readable from the URL query string, e.g.&nbsp;“all Octave bugs related to the release 6.x”: <a href="https://savannah.octave.org/?Action=get&amp;Format=HTMLCSS&amp;OpenClosed=open&amp;TrackerID=bugs&amp;Category!=Forge,website&amp;Release=6"><code>Action=get&amp;Format=HTMLCSS&amp;OpenClosed=open&amp;TrackerID=bugs</code> <code>&amp;Category!=Forge,website&amp;Release=6</code></a></p>
</blockquote>
</section>
<section id="sharing-information---a-longer-short-history" class="level3">
<h3 class="anchored" data-anchor-id="sharing-information---a-longer-short-history">4. Sharing information - a longer short history</h3>
<p>The biggest motivation of creating SavannahAPI was probably the lack of sharing information.</p>
<p>In the advent of an <strong>Octave release</strong>, the most vital information is if there are important bugs to fix, i.e.&nbsp;<strong>“Severity &gt;= 4”</strong>.</p>
<p>Not long ago for Octave 5, the release manager used to create for this purpose a wiki “Bug Fix List” <a href="https://wiki.octave.org/Bug_Fix_List_-_5.0_Release" class="uri">https://wiki.octave.org/Bug_Fix_List_-_5.0_Release</a>. Needless to say, that maintaining highly dynamic bug information without any automatic synchronization is very tedious duplicated work. It almost leads the use of Savannah itself to absurdity. (Why not posting the bugs directly to the wiki?) But this information given on this wiki page was <strong>easy to find, understand,</strong> <strong>and share</strong> with other Octave developers. Three lessons that can be learned from this old habit:</p>
<blockquote class="blockquote">
<ol type="1">
<li>Do things <strong>automatically</strong>.</li>
<li>Getting an <strong>overview on a single page</strong>.</li>
<li>Make information (permanently) <strong>shareable</strong> with other developers.</li>
</ol>
</blockquote>
<p>For the following painful long Octave 6 release (starting in December 2019), I first thought about getting rid of this double listing habit (lesson [1]) by creating URLs pointing to the desired information using the Savannah “browsing” feature: <a href="https://wiki.octave.org/6.1_Release_Checklist#Current_state_at_Savannah" class="uri">https://wiki.octave.org/6.1_Release_Checklist#Current_state_at_Savannah</a> The result was a list of about nine links to Savannah with horrible long and unreadable “magic” URLs, e.g.&nbsp;for <a href="https://savannah.gnu.org/bugs/index.php?go_report=Apply&amp;group=octave&amp;func=browse&amp;set=custom&amp;msort=0&amp;report_id=101&amp;advsrch=1&amp;status_id%5B%5D=1&amp;resolution_id%5B%5D=100&amp;resolution_id%5B%5D=1&amp;resolution_id%5B%5D=102&amp;resolution_id%5B%5D=103&amp;resolution_id%5B%5D=10&amp;resolution_id%5B%5D=9&amp;resolution_id%5B%5D=4&amp;resolution_id%5B%5D=11&amp;resolution_id%5B%5D=8&amp;resolution_id%5B%5D=6&amp;resolution_id%5B%5D=7&amp;resolution_id%5B%5D=2&amp;submitted_by%5B%5D=0&amp;assigned_to%5B%5D=0&amp;category_id%5B%5D=100&amp;category_id%5B%5D=110&amp;category_id%5B%5D=101&amp;category_id%5B%5D=102&amp;category_id%5B%5D=104&amp;category_id%5B%5D=105&amp;category_id%5B%5D=106&amp;category_id%5B%5D=107&amp;category_id%5B%5D=103&amp;category_id%5B%5D=114&amp;category_id%5B%5D=112&amp;category_id%5B%5D=109&amp;bug_group_id%5B%5D=0&amp;severity%5B%5D=7&amp;severity%5B%5D=8&amp;severity%5B%5D=9&amp;priority%5B%5D=0&amp;summary=&amp;details=&amp;sumORdet=0&amp;history_search=0&amp;history_field=0&amp;history_event=modified&amp;history_date_dayfd=10&amp;history_date_monthfd=12&amp;history_date_yearfd=2019&amp;chunksz=100&amp;spamscore=5&amp;boxoptionwanted=1#options">“Severity &gt;= 4”</a></p>
<pre><code>https://savannah.gnu.org/bugs/index.php?go_report=Apply&amp;group=octave
  &amp;func=browse&amp;set=custom&amp;msort=0&amp;report_id=221&amp;advsrch=1
  &amp;resolution_id%5B%5D=0&amp;bug_group_id%5B%5D=0&amp;status_id%5B%5D=1
  &amp;priority%5B%5D=0&amp;severity%5B%5D=0&amp;category_id%5B%5D=100
  &amp;category_id%5B%5D=110&amp;category_id%5B%5D=101&amp;category_id%5B%5D=102
  &amp;category_id%5B%5D=104&amp;category_id%5B%5D=105&amp;category_id%5B%5D=106
  &amp;category_id%5B%5D=107&amp;category_id%5B%5D=103&amp;category_id%5B%5D=114
  &amp;category_id%5B%5D=112&amp;category_id%5B%5D=109&amp;category_id%5B%5D=113
  &amp;release_id%5B%5D=173&amp;release_id%5B%5D=174
  &amp;platform_version_id%5B%5D=0&amp;history_search=0&amp;history_field=0
  &amp;history_event=modified&amp;history_date_dayfd=25
  &amp;history_date_monthfd=2&amp;history_date_yearfd=2021&amp;chunksz=100
  &amp;spamscore=5&amp;boxoptionwanted=1#options</code></pre>
<blockquote class="blockquote">
<p>For comparison, the same query URL for <strong>SavannahAPI</strong> is shorter, more readable, and more handy to share (<a href="https://savannah.octave.org/?Action=get&amp;Format=HTMLCSS&amp;OpenClosed=open&amp;TrackerID=bugs&amp;Category!=Forge,website&amp;Severity=4,5,6&amp;Status!=Wont">“Severity &gt;= 4”</a>):</p>
<pre><code>https://savannah.octave.org/?Action=get&amp;Format=HTMLCSS
  &amp;OpenClosed=open&amp;TrackerID=bugs&amp;Category!=Forge,website
  &amp;Severity=4,5,6&amp;Status!=Wont</code></pre>
</blockquote>
<p>But hidden behind a readable label, nobody has to worry about long URLs. Still yet the “overview on a single page” problem (lesson [2]) was still present. Nine clicks were still needed to obtain the desired overview and I sometimes manually updated the bug count in the wiki to avoid those clicks.</p>
<p>In October 2020, while the painful long Octave 6 release was still pending, I created a quick &amp; dirty php tool called <a href="https://octave.discourse.group/t/remaining-items-for-the-6-1-release/350">“Release Burn Down Chart”</a> which completed lesson [2] by querying and combining those Savannah browsing link results. A big leap forward.</p>
<p>Finally, I polished up this tool by changing the way it synchronizes with GNU Savannah (see next section) and introduced a <a href="https://github.com/gnu-octave/SavannahAPI#api-parameter-syntax-and-grammar">query language</a> (see also the example in this and the previous section) to fulfill lesson [3].</p>
<p>In addition to this, a JavaScript web application allows to flexibly save, edit, and sort an arbitrary number of “saved queries” individually for the needs of a user.</p>
</section>
</section>
<section id="the-project-in-detail" class="level2">
<h2 class="anchored" data-anchor-id="the-project-in-detail">The project in detail</h2>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="./project_overview_thumb.jpg"><img src="https://siko1056.github.io/blog/2021/03/17/project_overview_thumb.jpg" class="img-fluid figure-img"></a></p>
<figcaption>project overview</figcaption>
</figure>
</div>
<section id="client-server-model" class="level3">
<h3 class="anchored" data-anchor-id="client-server-model">Client-server model</h3>
<p>A key idea to make this project flexible in its usage is to introduce a server, which is able to process queries using a web API</p>
<ul>
<li><a href="https://savannah.octave.org/api.php" class="uri">https://savannah.octave.org/api.php</a></li>
</ul>
<p>and a JavaScript client which uses the API to present the query results to the user</p>
<ul>
<li><a href="https://savannah.octave.org/" class="uri">https://savannah.octave.org/</a>(index.html)</li>
</ul>
<p>GNU Savannah does not have this server API layer. It can only <a href="https://savannah.gnu.org/bugs/export.php?group=octave">export all data</a> (70 MB) to a custom HTML-like format or present a subset of the data as php generated HTML website as described above.</p>
</section>
<section id="synchronization-with-gnu-savannah" class="level3">
<h3 class="anchored" data-anchor-id="synchronization-with-gnu-savannah">Synchronization with GNU Savannah</h3>
<p>To stay in sync with GNU Savannah, the server periodically <a href="https://en.wikipedia.org/wiki/Web_scraping">scrapes</a> the data from GNU Savannah and stores it in a <strong>SQLite database</strong>. New items are scraped from the <a href="https://savannah.gnu.org/bugs/?group=octave">“browse all items” view</a>, while updated items are found with the help of the <a href="https://lists.gnu.org/archive/html/octave-bug-tracker/">mailing-list archive</a>.</p>
</section>
</section>
<section id="summary---many-new-possibilities" class="level2">
<h2 class="anchored" data-anchor-id="summary---many-new-possibilities">Summary - Many new possibilities</h2>
<p>Having a copy of all issue tracker data, it is very straight forward to create custom queries to obtain a desired subset (or all) of this data in <strong>various data formats</strong> (HTML, <a href="https://en.wikipedia.org/wiki/JSON">JSON</a>, <a href="https://en.wikipedia.org/wiki/Comma-separated_values">CSV</a>).</p>
<p>Thus SavannahAPI is also a <strong>backup</strong> of GNU Savannah and enables a possible <strong>exit strategy</strong>, once the GNU Octave project decides for another code hosting service.</p>
<p>Despite existing JavaScript web application, the web API can be used by any <strong>arbitrary client</strong>, e.g.&nbsp;from a GUI programmed in Octave language itself.</p>
<p><strong>Octave Forge</strong> developers do not have to monitor the whole bug tracker, they can query a subset of interest in the JavaScript web application, or embed the table in their own website, e.g.</p>
<ul>
<li>io-package (all bugs):
<ul>
<li><a href="https://savannah.octave.org/?%5Boctave%20forge%5D%20(io)" class="uri">https://savannah.octave.org/?[octave%20forge]%20(io)</a></li>
<li><a href="https://savannah.octave.org/api.php?Action=get&amp;Format=HTMLCSS&amp;Title=%5Boctave%20forge%5D%20(io)" class="uri">https://savannah.octave.org/api.php?Action=get&amp;Format=HTMLCSS&amp;Title=[octave%20forge]%20(io)</a></li>
</ul></li>
<li>io-package (all open bugs):
<ul>
<li><a href="https://savannah.octave.org/?Action=get&amp;Format=HTMLCSS&amp;Title=%5Boctave%20forge%5D%20(io)&amp;OpenClosed=open" class="uri">https://savannah.octave.org/?Action=get&amp;Format=HTMLCSS&amp;Title=[octave%20forge]%20(io)&amp;OpenClosed=open</a></li>
<li><a href="https://savannah.octave.org/api.php?Action=get&amp;Format=HTMLCSS&amp;Title=%5Boctave%20forge%5D%20(io)&amp;OpenClosed=open" class="uri">https://savannah.octave.org/api.php?Action=get&amp;Format=HTMLCSS&amp;Title=[octave%20forge]%20(io)&amp;OpenClosed=open</a></li>
</ul></li>
</ul>
<p>Similarly, all other kind of <strong>permalinks</strong> to dynamic content can be created and shared. For example do you want to join a code-sprint on three particular bugs? - <a href="https://savannah.octave.org/?Action=get&amp;Format=HTMLCSS&amp;ItemID=60245,60237,60236" class="uri">https://savannah.octave.org/?Action=get&amp;Format=HTMLCSS&amp;ItemID=60245,60237,60236</a></p>
<p>Any feedback on <a href="https://github.com/gnu-octave/SavannahAPI">GitHub</a> or <a href="https://octave.discourse.group/">Octave Discourse</a> is very welcome.</p>
<p>Enjoy using SavannahAPI.</p>


</section>

 ]]></description>
  <category>octave</category>
  <category>web</category>
  <guid>https://siko1056.github.io/blog/2021/03/17/savannah-api.html</guid>
  <pubDate>Wed, 17 Mar 2021 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Tell me about the world</title>
  <dc:creator>Kai T. Ohlhus</dc:creator>
  <link>https://siko1056.github.io/blog/2021/01/27/octave-world-plot.html</link>
  <description><![CDATA[ 





<p>A short demonstration using <a href="https://gnu-octave.github.io/pkg-index/package/pkg-json">pkg-json</a> with GNU Octave to plot a simplified two dimensional political <a href="https://data.nasa.gov/dataset/World-Map/7zbq-j77a">“World Map”</a> from public available JSON data provided by the <a href="https://en.wikipedia.org/wiki/NASA">NASA</a>. The following code can be used, to easily visualize data divided by countries (e.g.&nbsp;population densities, health data, economic figures, tax, export, etc.).</p>
<section id="the-code-at-a-glance" class="level2">
<h2 class="anchored" data-anchor-id="the-code-at-a-glance">The code at a glance</h2>
<div id="cell-2" class="cell" data-execution_count="1">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode octave code-with-copy"><code class="sourceCode octave"><span id="cb1-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%% Step 1: Install and load pkg-json.</span></span>
<span id="cb1-2"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">isempty</span> (<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pkg</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"list"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"pkg-json"</span>)))</span>
<span id="cb1-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pkg</span> install <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"https://github.com/gnu-octave/pkg-json/archive/v1.0.0.tar.gz"</span></span>
<span id="cb1-4"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb1-5"></span>
<span id="cb1-6"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pkg</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">load</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pkg</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>json</span>
<span id="cb1-7"></span>
<span id="cb1-8"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%% Step 2: Define a helper function to plot an individual country.</span></span>
<span id="cb1-9"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span> plot_country (name<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> countries<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> obj)</span>
<span id="cb1-10">  idx <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">find</span> (<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">strcmp</span> (name<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> countries))<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-11">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">isempty</span> (idx))</span>
<span id="cb1-12">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">error</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Country ''%s' not found."</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> name)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-13">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb1-14">  data_str <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> obj.data(idx){<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>}(<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>){<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>}<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-15">  data_str <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> data_str((<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">length</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"MULTIPOLYGON ((("</span>))<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span>(<span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>))<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-16">  data_str <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">strsplit</span> (data_str<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">")), (("</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-17">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">i</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">length</span> (data_str)</span>
<span id="cb1-18">    data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">textscan</span> (data_str{<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">i</span>}<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"%f %f,"</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-19">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">fill</span> (data{<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:,</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>}<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> data{<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:,</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>}<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> color)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-20">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">hold</span> on<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-21">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb1-22"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb1-23"></span>
<span id="cb1-24"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%% Step 3: Download the public data set.</span></span>
<span id="cb1-25">json_str <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">urlread</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"https://data.nasa.gov/api/views/yqhp-cuk8/rows.json?accessType=DOWNLOAD"</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-26"></span>
<span id="cb1-27"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%% Step 4: Import JSON data to GNU Octave.</span></span>
<span id="cb1-28">obj <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> jsondecode (json_str)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-29"></span>
<span id="cb1-30"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%% Step 5: Extract the country names.</span></span>
<span id="cb1-31">countries <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">cell</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">length</span> (obj.data)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-32"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">i</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">length</span> (obj.data)</span>
<span id="cb1-33">  countries{<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">i</span>} <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> obj.data(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">i</span>){<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>}(<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">9</span>){<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>}<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-34"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb1-35"></span>
<span id="cb1-36"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%% Step 6: Plot all available countries with random color.</span></span>
<span id="cb1-37"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">i</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">length</span> (countries)</span>
<span id="cb1-38">    plot_country (countries{<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">i</span>}<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rand</span> (<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> countries<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> obj)</span>
<span id="cb1-39"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span></code></pre></div></div>
<div class="cell-output cell-output-display">
<div>
<figure class="figure">
<p><img src="https://siko1056.github.io/blog/2021/01/27/octave-world-plot_files/figure-html/cell-2-output-1.png" class="img-fluid figure-img"></p>
</figure>
</div>
</div>
</div>
</section>
<section id="the-code-explained" class="level2">
<h2 class="anchored" data-anchor-id="the-code-explained">The code explained</h2>
<p><strong>Step 3:</strong> Using <code>urlread</code> it is really straight forward to import the data provided by the NASA into a string.</p>
<div id="cell-4" class="cell" data-execution_count="2">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode octave code-with-copy"><code class="sourceCode octave"><span id="cb2-1">json_str <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">urlread</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"https://data.nasa.gov/api/views/yqhp-cuk8/rows.json?accessType=DOWNLOAD"</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span></code></pre></div></div>
</div>
<div id="cell-5" class="cell" data-execution_count="3">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode octave code-with-copy"><code class="sourceCode octave"><span id="cb3-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">printf</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"The string contains %.2f KB of data."</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">length</span> (json_str) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1024</span>)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>The string contains 253.02 KB of data.</code></pre>
</div>
</div>
<p><strong>Step 4:</strong> Thanks to <a href="https://abdallahshamy.wordpress.com/2020/08/28/google-summer-of-code-2020-with-gnu-octave-final-report/">Abdalla’s Google Summer of Code project</a> the JSON data is available for further Octave processing with a single function call.</p>
<div id="cell-7" class="cell" data-execution_count="4">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode octave code-with-copy"><code class="sourceCode octave"><span id="cb5-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tic</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb5-2">obj <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> jsondecode (json_str)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb5-3"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">toc</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>Elapsed time is 0.0160789 seconds.</code></pre>
</div>
</div>
<p>The <code>jsondecode</code> function can of course not know about the structure of the NASA map data itself, thus it is necessary to explore the imported data using Octave.</p>
<p>The first step is to simply output the content of <code>obj</code>, which is quite verbose and thus omitted here.</p>
<p>As JSON is a structured data format, most of the content is converted to Octave structures. A handy function to get an overview of Octave structures is <code>fieldnames</code>.</p>
<div id="cell-9" class="cell" data-execution_count="5">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode octave code-with-copy"><code class="sourceCode octave"><span id="cb7-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">fieldnames</span> (obj)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>ans =
{
  [1,1] = meta
  [2,1] = data
}
</code></pre>
</div>
</div>
<p>A splitting into a <code>meta</code> and <code>data</code> section can be observed. Some further investigation of the <code>meta</code> section revealed, that it is not very useful for the purpose of plotting the world map, thus it is not further explained here.</p>
<p>On the other hand the <code>data</code> section contains the desired polygon edge data of the several country borders.</p>
<p><strong>Step 5:</strong> For the sake of convenience, the names of the individual countries are exported into an cell array of strings.</p>
<div id="cell-11" class="cell" data-execution_count="6">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode octave code-with-copy"><code class="sourceCode octave"><span id="cb9-1">countries <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">cell</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">length</span> (obj.data)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb9-2"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">i</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">length</span> (obj.data)</span>
<span id="cb9-3">  countries{<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">i</span>} <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> obj.data(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">i</span>){<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>}(<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">9</span>){<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>}<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb9-4"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span></code></pre></div></div>
</div>
<p>With this approach, it is easy to map a country name to an index in <code>obj.data</code>, which is examined in the following for “Japan”.</p>
<div id="cell-13" class="cell" data-execution_count="7">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb10" style="background: #f1f3f5;"><pre class="sourceCode octave code-with-copy"><code class="sourceCode octave"><span id="cb10-1">japan <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">find</span> (<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">strcmp</span> (countries<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Japan"</span>))</span>
<span id="cb10-2">usa   <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">find</span> (<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">strcmp</span> (countries<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"United States of America"</span>))</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>japan =  88
usa =  173</code></pre>
</div>
</div>
<div id="cell-14" class="cell" data-execution_count="8">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb12" style="background: #f1f3f5;"><pre class="sourceCode octave code-with-copy"><code class="sourceCode octave"><span id="cb12-1">obj.data(japan)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>ans =
{
  [1,1] =
  {
    [1,1] = row-bxsn-brky.azms
    [2,1] = 00000000-0000-0000-1E4A-C7232D9BDD99
    [3,1] = 0
    [4,1] =  1495517988
    [5,1] = [](0x0)
    [6,1] =  1495517988
    [7,1] = [](0x0)
    [8,1] = { }
    [9,1] = Japan
    [10,1] = MULTIPOLYGON (((134.638428 34.149234, 134.766379 33.806335, 134.203416 33.201178, 133.79295 33.521985, 133.280268 33.28957, 133.014858 32.704567, 132.363115 32.989382, 132.371176 33.463642, 132.924373 34.060299, 133.492968 33.944621, 133.904106 34.364931, 134.638428 34.149234)), ((140.976388 37.142074, 140.59977 36.343983, 140.774074 35.842877, 140.253279 35.138114, 138.975528 34.6676, 137.217599 34.606286, 135.792983 33.464805, 135.120983 33.849071, 135.079435 34.596545, 133.340316 34.375938, 132.156771 33.904933, 130.986145 33.885761, 132.000036 33.149992, 131.33279 31.450355, 130.686318 31.029579, 130.20242 31.418238, 130.447676 32.319475, 129.814692 32.61031, 129.408463 33.296056, 130.353935 33.604151, 130.878451 34.232743, 131.884229 34.749714, 132.617673 35.433393, 134.608301 35.731618, 135.677538 35.527134, 136.723831 37.304984, 137.390612 36.827391, 138.857602 37.827485, 139.426405 38.215962, 140.05479 39.438807, 139.883379 40.563312, 140.305783 41.195005, 141.368973 41.37856, 141.914263 39.991616, 141.884601 39.180865, 140.959489 38.174001, 140.976388 37.142074)), ((143.910162 44.1741, 144.613427 43.960883, 145.320825 44.384733, 145.543137 43.262088, 144.059662 42.988358, 143.18385 41.995215, 141.611491 42.678791, 141.067286 41.584594, 139.955106 41.569556, 139.817544 42.563759, 140.312087 43.333273, 141.380549 43.388825, 141.671952 44.772125, 141.967645 45.551483, 143.14287 44.510358, 143.910162 44.1741)))
  }

}
</code></pre>
</div>
</div>
<p>From this data about Japan, we are only interested in the 10th entry, defining the “MULTIPOLYGON” data about three larger Japanese islands (areas). The format is as follows:</p>
<pre><code>MULTIPOLYGON (
  ((x1 y1, x2 y2, ...))    // Area 1
  ((x1 y1, x2 y2, ...))    // Area 2
  ...
)</code></pre>
<p>Using some straight forward Octave instructions, this sub format of the JSON data can be further processed by Octave.</p>
<div id="cell-16" class="cell" data-execution_count="9">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb15" style="background: #f1f3f5;"><pre class="sourceCode octave code-with-copy"><code class="sourceCode octave"><span id="cb15-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%% Extract the 10th data entry.</span></span>
<span id="cb15-2">data_str <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> obj.data(japan){<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>}(<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>){<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>}<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb15-3"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%% Strip start and end of the numerical data.</span></span>
<span id="cb15-4">data_str <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> data_str((<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">length</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"MULTIPOLYGON ((("</span>))<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span>(<span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>))<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb15-5"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%% Split area data into individual cells of an array.</span></span>
<span id="cb15-6">data_str <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">strsplit</span> (data_str<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">")), (("</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span></code></pre></div></div>
</div>
<p>The data in the three cells is still of type “string” and can finally be converted using <code>textscan</code> for example.</p>
<p>Now the x,y-data for the edges of each area is available in numerical form and can be simply plotted by Octave’s <code>fill</code> function in the same loop.</p>
<div id="cell-18" class="cell" data-execution_count="10">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb16" style="background: #f1f3f5;"><pre class="sourceCode octave code-with-copy"><code class="sourceCode octave"><span id="cb16-1"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">i</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">length</span> (data_str)</span>
<span id="cb16-2">  data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">textscan</span> (data_str{<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">i</span>}<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"%f %f,"</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb16-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">fill</span> (data{<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:,</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>}<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> data{<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:,</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>}<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"r"</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb16-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">hold</span> on<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb16-5"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span></code></pre></div></div>
<div class="cell-output cell-output-display">
<div>
<figure class="figure">
<p><img src="https://siko1056.github.io/blog/2021/01/27/octave-world-plot_files/figure-html/cell-11-output-1.png" class="img-fluid figure-img"></p>
</figure>
</div>
</div>
</div>
<p><strong>Step 2:</strong> All steps above can conveniently be abstracted into a single function <code>plot_country</code>, defined in the first code section of this notebook.</p>
<p>A second more simplified function call will look like this, where <code>countries</code> is obtained by <strong>Step 5</strong> and <code>obj</code> by <strong>Step 4</strong>. <code>"g"</code> (= “green”) is the color that should used.</p>
<div id="cell-20" class="cell" data-execution_count="11">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb17" style="background: #f1f3f5;"><pre class="sourceCode octave code-with-copy"><code class="sourceCode octave"><span id="cb17-1">plot_country (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"United States of America"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"g"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> countries<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> obj)</span></code></pre></div></div>
<div class="cell-output cell-output-display">
<div>
<figure class="figure">
<p><img src="https://siko1056.github.io/blog/2021/01/27/octave-world-plot_files/figure-html/cell-12-output-1.png" class="img-fluid figure-img"></p>
</figure>
</div>
</div>
</div>
<p>In <strong>Step 6</strong> an example was given how all available countries can be plotted.</p>


</section>

 ]]></description>
  <category>octave</category>
  <guid>https://siko1056.github.io/blog/2021/01/27/octave-world-plot.html</guid>
  <pubDate>Wed, 27 Jan 2021 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Support for the JSON data format after GSoC 2020</title>
  <dc:creator>Kai T. Ohlhus</dc:creator>
  <link>https://siko1056.github.io/blog/2020/11/23/gsoc2020-json-benchmark.html</link>
  <description><![CDATA[ 





<p>The <a href="https://summerofcode.withgoogle.com/">Google Summer of Code (GSoC) 2020</a> is over and I had the pleasure to mentor <a href="https://abdallahshamy.wordpress.com/">Abdallah Elshamy</a>, who enriched Octave with the <code>jsondecode()</code> and <code>jsonencode()</code> functions. A remaining issue was the translation of the Octave function <a href="https://www.octave.org/doc/v5.2.0/XREFmatlab_005flang_005fmakeValidName.html"><code>matlab.lang.makeValidName</code></a> to the C++ language. This is now accomplished and the overall results are great.</p>
<blockquote class="blockquote">
<p>See <a href="../../../../blog/2020/08/19/gsoc2020-json-benchmark.html">the previous benchmark of this Jupyter Notebook</a> (August 19, 2020) with <code>matlab.lang.makeValidName</code> as Octave code.</p>
</blockquote>
<p>Again a larger JSON data set was used, with test cases collected from the excellent <a href="https://github.com/miloyip/nativejson-benchmark">nativejson-benchmark</a>, but with focus on Octave.</p>
<p>Only the running times for reading and writing JSON data are regarded in this benchmark. Another <a href="https://lists.gnu.org/archive/html/octave-maintainers/2020-06/msg00112.html">test by Abdallah</a> has been carried out in June to test the compatibility for Matlab.</p>
<p>The test environment is a laptop with - <a href="https://ark.intel.com/content/www/us/en/ark/products/193563/intel-core-i7-8665u-processor-8m-cache-up-to-4-80-ghz.html">Intel(R) Core(TM) i7-8665U CPU @ 1.90GHz</a> - 16 GB of main memory - OpenSUSE 15.2 Linux - <a href="https://github.com/siko1056/jupyterlab-runner">JupyterLab</a> - Octave version as given below</p>
<div id="cell-1" class="cell" data-execution_count="1">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode octave code-with-copy"><code class="sourceCode octave"><span id="cb1-1">octave_version <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">version</span> ()</span>
<span id="cb1-2">octave_hg_id   <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">version</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'-hgid'</span>)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>octave_version = 7.0.0
octave_hg_id = 38e22065d9ec</code></pre>
</div>
</div>
<p>The following JSON extensions for Octave are under test.</p>
<table class="caption-top table">
<thead>
<tr class="header">
<th>name</th>
<th>description</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><a href="https://abdallahshamy.wordpress.com/">Octave (builtin)</a></td>
<td>Based on <a href="https://rapidjson.org/">RapidJSON</a>, reading DOM API.</td>
</tr>
<tr class="even">
<td><a href="https://github.com/Andy1978/octave-rapidjson">octave-rapidjson</a></td>
<td>Based on <a href="https://rapidjson.org/">RapidJSON</a>, reading SAX API.</td>
</tr>
<tr class="odd">
<td><a href="https://github.com/apjanke/octave-jsonstuff">octave-jsonstuff</a></td>
<td>Based on <a href="https://rapidjson.org/">RapidJSON</a>, reading DOM API, writing m-file.</td>
</tr>
<tr class="even">
<td><a href="https://github.com/gllmflndn/JSONio">JSONio</a></td>
<td>Based on <a href="https://zserge.com/jsmn/">JSMN</a>, writing m-file.</td>
</tr>
<tr class="odd">
<td><a href="https://github.com/fangq/jsonlab">jsonlab</a></td>
<td>m-file only</td>
</tr>
</tbody>
</table>
<p>The JSON test files are described in the following table.</p>
<table class="caption-top table">
<thead>
<tr class="header">
<th>name</th>
<th style="text-align: right;">size (byte)</th>
<th>description</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><a href="https://github.com/RichardHightower/json-parsers-benchmark/blob/master/data/citm_catalog.json">citm_catalog.json</a></td>
<td style="text-align: right;">1,727,204</td>
<td>Structured data with mixed text and numeric.</td>
</tr>
<tr class="even">
<td><a href="https://github.com/mloskot/json_benchmark/blob/master/data/canada.json">canada.json</a></td>
<td style="text-align: right;">2,251,060</td>
<td>Numeric data set in <a href="https://en.wikipedia.org/wiki/GeoJSONhttps://en.wikipedia.org/wiki/GeoJSON">GeoJSON</a> format.</td>
</tr>
<tr class="odd">
<td><a href="https://github.com/json-iterator/test-data/blob/master/large-file.json">large-file.json</a></td>
<td style="text-align: right;">26,141,343</td>
<td>Structured data with mixed text and numeric.</td>
</tr>
</tbody>
</table>
<section id="benchmark-setup" class="level2">
<h2 class="anchored" data-anchor-id="benchmark-setup">Benchmark setup</h2>
<p>Create a directory to keep track of the mess.</p>
<div id="cell-5" class="cell" data-execution_count="2">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode octave code-with-copy"><code class="sourceCode octave"><span id="cb3-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mkdir</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'benchmark'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-2"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">cd</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'benchmark'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span></code></pre></div></div>
</div>
<p>Load the benchmark JSON files.</p>
<div id="cell-7" class="cell" data-execution_count="3">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode octave code-with-copy"><code class="sourceCode octave"><span id="cb4-1"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">exist</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'citm_catalog.json'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'file'</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>)</span>
<span id="cb4-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">urlwrite</span> ( <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span></span>
<span id="cb4-3">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'https://github.com/RichardHightower/json-parsers-benchmark/raw/master/data/citm_catalog.json'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span></span>
<span id="cb4-4">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'citm_catalog.json'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb4-5"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb4-6"></span>
<span id="cb4-7"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">exist</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'canada.json'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'file'</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>)</span>
<span id="cb4-8">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">urlwrite</span> ( <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span></span>
<span id="cb4-9">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'https://github.com/mloskot/json_benchmark/raw/master/data/canada.json'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span></span>
<span id="cb4-10">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'canada.json'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb4-11"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb4-12"></span>
<span id="cb4-13"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">exist</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'large-file.json'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'file'</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>)</span>
<span id="cb4-14">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">urlwrite</span> ( <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span></span>
<span id="cb4-15">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'https://github.com/json-iterator/test-data/raw/master/large-file.json'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span></span>
<span id="cb4-16">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'large-file.json'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb4-17"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span></code></pre></div></div>
</div>
<p>Setup <strong>octave-rapidjson</strong>.</p>
<div id="cell-9" class="cell" data-execution_count="4">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode octave code-with-copy"><code class="sourceCode octave"><span id="cb5-1"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">exist</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'octave-rapidjson'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'dir'</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span>
<span id="cb5-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">urlwrite</span> ( <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span></span>
<span id="cb5-3">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'https://github.com/Andy1978/octave-rapidjson/archive/2d88511712032b14dea4c2272d82249e7547772a.zip'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span></span>
<span id="cb5-4">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'octave-rapidjson.zip'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb5-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">unzip</span>  (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'octave-rapidjson.zip'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb5-6">  <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">rename</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'octave-rapidjson-2d88511712032b14dea4c2272d82249e7547772a'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span></span>
<span id="cb5-7">          <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'octave-rapidjson'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb5-8">  <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">cd</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'octave-rapidjson'</span>)</span>
<span id="cb5-9">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">urlwrite</span> ( <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span></span>
<span id="cb5-10">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'https://github.com/Tencent/rapidjson/archive/35e480fc4ddf4ec4f7ad34d96353eef0aabf002d.zip'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span></span>
<span id="cb5-11">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'rapidjson.zip'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb5-12">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">unzip</span>  (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'rapidjson.zip'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb5-13">  <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">rename</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'rapidjson-35e480fc4ddf4ec4f7ad34d96353eef0aabf002d'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'rapidjson'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb5-14">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mkoctfile</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>Wall <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>Wextra <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>I<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">./</span>rapidjson<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span>include load_json.cc</span>
<span id="cb5-15">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mkoctfile</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>Wall <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>Wextra <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>I<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">./</span>rapidjson<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span>include save_json.cc</span>
<span id="cb5-16">  <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">cd</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'..'</span>)</span>
<span id="cb5-17"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span></code></pre></div></div>
</div>
<p>Setup <strong>octave-jsonstuff</strong>.</p>
<div id="cell-11" class="cell" data-execution_count="5">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode octave code-with-copy"><code class="sourceCode octave"><span id="cb6-1"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">isempty</span> (<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pkg</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'list'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'jsonstuff'</span>)))</span>
<span id="cb6-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pkg</span> install https<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">://</span>github.com<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span>apjanke<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span>octave<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>jsonstuff<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span>releases<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span>download<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span>v0<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">.3.3</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span>jsonstuff<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.3.3</span>.tar.gz</span>
<span id="cb6-3"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span></code></pre></div></div>
</div>
<p>Setup <strong>JSONio</strong>.</p>
<div id="cell-13" class="cell" data-execution_count="6">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode octave code-with-copy"><code class="sourceCode octave"><span id="cb7-1"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">exist</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'JSONio'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'dir'</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span>
<span id="cb7-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">urlwrite</span> ( <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span></span>
<span id="cb7-3">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'https://github.com/gllmflndn/JSONio/archive/6c699a315ac2c578864d8b740a061bff47b718bf.zip'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span></span>
<span id="cb7-4">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'JSONio.zip'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb7-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">unzip</span>  (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'JSONio.zip'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb7-6">  <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">rename</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'JSONio-6c699a315ac2c578864d8b740a061bff47b718bf'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'JSONio'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb7-7">  <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">cd</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'JSONio'</span>)</span>
<span id="cb7-8">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mkoctfile</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">--</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mex</span> jsonread.c jsmn.c <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>DJSMN_PARENT_LINKS</span>
<span id="cb7-9">  <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">cd</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'..'</span>)</span>
<span id="cb7-10"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span></code></pre></div></div>
</div>
<p>Setup <strong>jsonlab</strong>.</p>
<div id="cell-15" class="cell" data-execution_count="7">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode octave code-with-copy"><code class="sourceCode octave"><span id="cb8-1"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">exist</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'jsonlab'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'dir'</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span>
<span id="cb8-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">urlwrite</span> ( <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span></span>
<span id="cb8-3">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'https://github.com/fangq/jsonlab/archive/d0fb684bd43165d312063345bdb795b628b2c679.zip'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span></span>
<span id="cb8-4">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'jsonlab.zip'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb8-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">unzip</span>  (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'jsonlab.zip'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb8-6">  <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">rename</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'jsonlab-d0fb684bd43165d312063345bdb795b628b2c679'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'jsonlab'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb8-7"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span></code></pre></div></div>
</div>
</section>
<section id="benchmark-run" class="level2">
<h2 class="anchored" data-anchor-id="benchmark-run">Benchmark run</h2>
<p>The benchmark function reads the respective JSON file into a string and calls the libraries reading and writing function.</p>
<div id="cell-17" class="cell" data-execution_count="8">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode octave code-with-copy"><code class="sourceCode octave"><span id="cb9-1"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span> t <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> benchmark (json_read_fcn<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> json_write_fcn)</span>
<span id="cb9-2">  test_files <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> {<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'citm_catalog.json'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'canada.json'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'large-file.json'</span>}<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb9-3">  N <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">length</span> (test_files)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb9-4">  t <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">nan</span> (N<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb9-5">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">i</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span>N</span>
<span id="cb9-6">    json_str <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">fileread</span> (test_files{<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">i</span>})<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb9-7">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tic</span> ()<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb9-8">    octave_obj <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> json_read_fcn (json_str)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb9-9">    t(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">i</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">toc</span> ()<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb9-10">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tic</span> ()<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb9-11">    json_str2 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> json_write_fcn (octave_obj)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb9-12">    t(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">i</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">toc</span> ()<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb9-13">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb9-14"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span></code></pre></div></div>
</div>
<p>The results for the <strong>Matlab (R2020b, prerelease)</strong> have been measured on the same system without JupyterLab.</p>
<div id="cell-19" class="cell" data-execution_count="9">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb10" style="background: #f1f3f5;"><pre class="sourceCode octave code-with-copy"><code class="sourceCode octave"><span id="cb10-1">t.matlab <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [</span>
<span id="cb10-2">  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.0768</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.0853</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb10-3">  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.1510</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5405</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb10-4">  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.2222</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.6521</span>]<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span></code></pre></div></div>
</div>
<p><strong>Octave (7.0.0, development version)</strong></p>
<div id="cell-21" class="cell" data-execution_count="10">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb11" style="background: #f1f3f5;"><pre class="sourceCode octave code-with-copy"><code class="sourceCode octave"><span id="cb11-1">t.octave <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> benchmark (@jsondecode<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> @jsonencode)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span></code></pre></div></div>
</div>
<p><strong>octave-rapidjson</strong></p>
<div id="cell-23" class="cell" data-execution_count="11">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb12" style="background: #f1f3f5;"><pre class="sourceCode octave code-with-copy"><code class="sourceCode octave"><span id="cb12-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">addpath</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'octave-rapidjson'</span>)</span>
<span id="cb12-2">t.rapid_json <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> benchmark (@load_json<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> @save_json)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb12-3"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rmpath</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'octave-rapidjson'</span>)</span></code></pre></div></div>
</div>
<p><strong>octave-jsonstuff</strong>: No results due to an error.</p>
<div id="cell-25" class="cell" data-execution_count="12">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb13" style="background: #f1f3f5;"><pre class="sourceCode octave code-with-copy"><code class="sourceCode octave"><span id="cb13-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%pkg load jsonstuff</span></span>
<span id="cb13-2"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%t.jsonstuff = benchmark (@jsondecode, @jsonencode);</span></span>
<span id="cb13-3"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%error: cat: field names mismatch in concatenating structs</span></span>
<span id="cb13-4"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%error: called from</span></span>
<span id="cb13-5"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%    jsondecode&gt;condense_decoded_json_recursive at line 116 column 9</span></span>
<span id="cb13-6"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%    jsondecode&gt;condense_decoded_json at line 67 column 7</span></span>
<span id="cb13-7"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%    jsondecode at line 63 column 7</span></span>
<span id="cb13-8"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%    benchmark at line 8 column 16</span></span>
<span id="cb13-9"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%pkg unload jsonstuff</span></span></code></pre></div></div>
</div>
<p><strong>JSONio</strong>: Because of the long running time, the results of the first run are saved here.</p>
<div id="cell-27" class="cell" data-execution_count="13">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb14" style="background: #f1f3f5;"><pre class="sourceCode octave code-with-copy"><code class="sourceCode octave"><span id="cb14-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">addpath</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'JSONio'</span>)</span>
<span id="cb14-2"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%t.jsonio = benchmark (@jsonread, @jsonwrite);</span></span>
<span id="cb14-3">t.jsonio <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [ <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span></span>
<span id="cb14-4">  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.9583</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">30.5410</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb14-5">  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">6.1333</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">17.4022</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb14-6">  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">4.3382</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">552.8929</span>]<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb14-7"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rmpath</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'JSONio'</span>)</span></code></pre></div></div>
</div>
<p><strong>Jsonlab</strong>: Because of the long running time, the results of the first run are saved here.</p>
<div id="cell-29" class="cell" data-execution_count="14">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb15" style="background: #f1f3f5;"><pre class="sourceCode octave code-with-copy"><code class="sourceCode octave"><span id="cb15-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">addpath</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'jsonlab'</span>)</span>
<span id="cb15-2"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%t.jsonlab = benchmark (@loadjson, @savejson);</span></span>
<span id="cb15-3">t.jsonlab <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [ <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span></span>
<span id="cb15-4">   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">35.6242</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">26.0625</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb15-5">    <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">6.1303</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.7365</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb15-6">  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">372.2456</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">601.5318</span>]<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb15-7"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rmpath</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'jsonlab'</span>)</span></code></pre></div></div>
</div>
</section>
<section id="benchmark-results" class="level2">
<h2 class="anchored" data-anchor-id="benchmark-results">Benchmark results</h2>
<div id="cell-31" class="cell" data-execution_count="15">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb16" style="background: #f1f3f5;"><pre class="sourceCode octave code-with-copy"><code class="sourceCode octave"><span id="cb16-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">graphics_toolkit</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'qt'</span>)</span>
<span id="cb16-2">titles <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> {<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'citm\_catalog.json (2 MB, mixed)'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span></span>
<span id="cb16-3">          <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'canada.json (2 MB, numeric)'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span></span>
<span id="cb16-4">          <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'large-file.json (26 MB, mixed)'</span>}<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span></code></pre></div></div>
</div>
<div id="cell-32" class="cell" data-execution_count="16">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb17" style="background: #f1f3f5;"><pre class="sourceCode octave code-with-copy"><code class="sourceCode octave"><span id="cb17-1"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">i</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span></span>
<span id="cb17-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">subplot</span> (<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">i</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb17-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">bar</span> ([t.matlab(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">i</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,:</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> t.octave(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">i</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,:</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> t.rapid_json(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">i</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,:</span>)]<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb17-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">legend</span> ({<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Matlab (R2020b, pre)'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Octave (7.0.0, dev)'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span></span>
<span id="cb17-5">           <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'octave-rapidjson'</span>}<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Location'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'bestoutside'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb17-6">  xticklabels({<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'read'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'write'</span>})<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb17-7">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ylabel</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'time in seconds'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb17-8">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">title</span> (titles{<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">i</span>})<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb17-9"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span></code></pre></div></div>
<div class="cell-output cell-output-display">
<div>
<figure class="figure">
<p><img src="https://siko1056.github.io/blog/2020/11/23/gsoc2020-json-benchmark_files/figure-html/cell-17-output-1.png" class="img-fluid figure-img"></p>
</figure>
</div>
</div>
</div>
<div id="cell-33" class="cell" data-execution_count="17">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb18" style="background: #f1f3f5;"><pre class="sourceCode octave code-with-copy"><code class="sourceCode octave"><span id="cb18-1"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">i</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span></span>
<span id="cb18-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">subplot</span> (<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">i</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb18-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">bar</span> ([t.jsonio(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">i</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,:</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> t.jsonlab(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">i</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,:</span>)]<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb18-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">legend</span> ({<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'JSONio'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'jsonlab'</span>}<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Location'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'bestoutside'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb18-5">  xticklabels({<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'read'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'write'</span>})<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb18-6">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ylabel</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'time in seconds'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb18-7">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">title</span> (titles{<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">i</span>})<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb18-8"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span></code></pre></div></div>
<div class="cell-output cell-output-display">
<div>
<figure class="figure">
<p><img src="https://siko1056.github.io/blog/2020/11/23/gsoc2020-json-benchmark_files/figure-html/cell-18-output-1.png" class="img-fluid figure-img"></p>
</figure>
</div>
</div>
</div>
<p>The first figure compares the running times of <strong>Matlab</strong>, <strong>Octave</strong>, and <strong>octave-rapidjson</strong>. Both <strong>Octave</strong> and <strong>octave-rapidjson</strong> are based on RapidJSON and perform in many cases better than the Matlab implementation.</p>
<p><strong>octave-rapidjson</strong> is using the <strong>SAX API</strong> of RapidJSON, while the <strong>new Octave implementation</strong> uses the <strong>DOM API</strong>. This decision was made to achieve best compatibility to Matlab, which was in some cases difficult with the SAX API and is no pririty for the octave-rapidjson project. The results show, that both APIs perform similarly in the tested data sets, even though there is a claim, that <a href="https://rapidjson.org/md_doc_faq.html#autotoc_md70">the SAX API is faster</a> in some cases.</p>
<p>The results of <strong>JSONio</strong> and <strong>jsonlab</strong> are split into a second figure, as the running times are significantly larger than those of the first figure. For <strong>octave-jsonstuff</strong> we could due to an error not obtain any results and the <a href="https://github.com/apjanke/octave-jsonstuff/issues/21">maintainer is informed</a> about it.</p>


</section>

 ]]></description>
  <category>octave</category>
  <guid>https://siko1056.github.io/blog/2020/11/23/gsoc2020-json-benchmark.html</guid>
  <pubDate>Mon, 23 Nov 2020 00:00:00 GMT</pubDate>
</item>
<item>
  <title>rsync boosted Buildbots</title>
  <dc:creator>Kai T. Ohlhus</dc:creator>
  <link>https://siko1056.github.io/blog/2020/11/08/octave-buildbot-boosted.html</link>
  <description><![CDATA[ 





<p>Using <a href="https://rsync.samba.org/">rsync</a> instead of Buildbot’s own <a href="https://docs.buildbot.net/latest/manual/configuration/steps/file_transfer.html">file transfers</a>, which <a href="https://github.com/buildbot/buildbot/issues/3709">are known to be slow</a>, significantly reduced the file transfer time between the Buildbot Workers and the Buildbot Master from 25.5 hours to about 18 minutes <strong>(-98%)</strong>. This improvement, and a few others, enables a single “strong” Worker to build and publish Octave and all MS Windows installers within 24 hours or with four parallel Workers within 6 hours.</p>
<blockquote class="blockquote">
<p>EDIT: 2024-04-10 Project moved <a href="https://octave.space" class="uri">https://octave.space</a> → <a href="https://nightly.octave.org" class="uri">https://nightly.octave.org</a>.</p>
</blockquote>
<section id="octave-buildbot-the-final-picture" class="level2">
<h2 class="anchored" data-anchor-id="octave-buildbot-the-final-picture">octave-buildbot: the final picture?</h2>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="./octave_buildbot.png"><img src="https://siko1056.github.io/blog/2020/11/08/octave_buildbot.png" class="img-fluid figure-img"></a></p>
<figcaption>png</figcaption>
</figure>
</div>
<p>The <a href="../../../../blog/2020/08/17/octave-buildbot.html">initial project design from August</a> has “matured” in the following aspects: 1. The Buildbot Master container can now be accessed from the Workers by SSH. This enables rsync file transfers with significant speed improvements. On the other hand, additional authentication is necessary. SSH key-based authentication was favored over plain username/password authentication via <a href="https://docs.buildbot.net/latest/manual/secretsmanagement.html"><code>Secret</code></a>. This gives the Buildbot Master more control about the Workers which can access the Docker container. The SSH port is publicly visible and not only Buildbot Workers might try to get access. 2. The storage location of the build artifacts on the Buildbot Master was moved inside a Docker Volume and is shared with a <a href="https://hub.docker.com/_/nginx">Nginx web server container</a>. Testing on a local machine is now no different from the production system on <a href="https://octave.space" class="uri">https://octave.space</a> and one does not need to worry about the Buildbot Master to mess up the server’s file system directly. The system’s native Apache web server now only serves as proxy and delegates requests from the world wide web to the respective container to serve the requested content.</p>
</section>
<section id="the-bill-revisited" class="level2">
<h2 class="anchored" data-anchor-id="the-bill-revisited">The bill revisited</h2>
<p><a href="../../../2020/10/16/octave-buildbot-app">In a previous post</a> the computational costs for the Buildbot Workers are listed in Table 1 there. This table has been revisited below. For the Buildbot Master there were no big changes.</p>
<p>Like in the previous table, a Buildbot Worker is expected to provide 4 CPU cores and 75 GB of disk storage.</p>
<p>The heterogeneity among the Workers is the reason for significantly different build times for the MS Windows installers (Octave-MXE). “Stronger” Workers, equipped with a modern server CPU, outperform those with a consumer CPU by hours of build time.</p>
<table class="caption-top table">
<thead>
<tr class="header">
<th>Builder name</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><a href="https://buildbot.octave.space/#/builders/8">octave</a></td>
</tr>
<tr class="even">
<td><a href="https://buildbot.octave.space/#/builders/7">octave-mxe-w32</a></td>
</tr>
<tr class="odd">
<td><a href="https://buildbot.octave.space/#/builders/9">octave-mxe-w64</a></td>
</tr>
<tr class="even">
<td><a href="https://buildbot.octave.space/#/builders/10">octave-mxe-w64-64</a></td>
</tr>
<tr class="odd">
<td>sum (worst case)</td>
</tr>
</tbody>
</table>
<p>Table footnotes: 1. All builds are performed in a clean empty build folder. 2. Additional disk space is needed for ccache, which currently uses 13 GB of 20 GB, and 1.5 GB for the mxe-octave installer files, which are cached to avoid unnecessary downloads.</p>
<p>Despite the file transfer time reduction, there were two further minor improvements: 1. The <a href="https://docs.buildbot.net/latest/manual/concepts.html">“Builders”</a> for Octave and the Doxygen documentation have been merged. This reduces the build time of both tasks by about 20%, as no additional build of Octave for the Doxygen documentation is necessary. Compared to the Octave-MXE build times, this reduction is not significant. 2. The usage of <code>ccache</code> for the Octave-MXE had some measurable improvement, which is shown by three examples for different types of Workers: - <a href="https://buildbot.octave.space/#/builders/7/builds/1">5.3 hours</a> down to <a href="https://buildbot.octave.space/#/builders/7/builds/7">4.5 hours</a> (-15%) for “strong” <em>worker-03</em> after 2 repetitions. - <a href="https://buildbot.octave.space/#/builders/9/builds/1">5.25 hours</a> down to <a href="https://buildbot.octave.space/#/builders/9/builds/8">4.75 hours</a> (-10%) for “strong” <em>worker-04</em> after 4 repetitions. - <a href="https://buildbot.octave.space/#/builders/10/builds/1">8.3 hours</a> down to <a href="https://buildbot.octave.space/#/builders/10/builds/8">7.5 hours</a> (-10%) for “weak” <em>worker-01</em> after 3 repetitions.</p>
</section>
<section id="summary" class="level2">
<h2 class="anchored" data-anchor-id="summary">Summary</h2>
<p>The usage of <code>rsync</code> to copy the files from the Buildbot Workers to the Master is without doubt a huge step forward for the project and it’s very heterogeneous and (over continents) distributed infrastructure. Valuable machine hours are no longer wasted for unnecessarily slow file transfers.</p>
<p>Furthermore, the thorough usage of <code>ccache</code> for the Octave-MXE builds has a measurable impact for all types of Buildbot Workers and saves build time for repetitive compilation tasks without sacrificing “clean” release builds.</p>
<p>Currently the last outstanding issue of octave-buildbot is probably a library issue with modern CPUs. The progress on this issue is tracked on <a href="https://github.com/gnu-octave/octave-buildbot/issues/6">GitHub</a> and hopefully it will be solved soon.</p>
<p>Happy brewing.</p>


</section>

 ]]></description>
  <category>octave</category>
  <guid>https://siko1056.github.io/blog/2020/11/08/octave-buildbot-boosted.html</guid>
  <pubDate>Sun, 08 Nov 2020 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Fresh brewed Octave - every day!</title>
  <dc:creator>Kai T. Ohlhus</dc:creator>
  <link>https://siko1056.github.io/blog/2020/10/16/octave-buildbot-app.html</link>
  <description><![CDATA[ 





<p>The <a href="https://github.com/gnu-octave/octave-buildbot/">octave-buildbot</a> Server and Worker matured a lot in the past two months since <a href="../../../../blog/2020/08/17/octave-buildbot.html">I wrote about them in August</a>. Finally, the system is capable of delivering <strong>once per day</strong> a “fresh brewed” stable Octave release (tarballs, all flavors of MS Windows installers, and the Doxygen documentation). See it yourself on <a href="https://octave.space" class="uri">https://octave.space</a>.</p>
<p>Automated <a href="https://en.wikipedia.org/wiki/Continuous_delivery">Continuous delivery (CD)</a> is my hope to ease the tedious task of creating and publishing Octave releases and release candidates. As said before, now <strong>every day</strong> a stable release happens (if there were changes to the Octave stable branch) with no manpower needed at all.</p>
<blockquote class="blockquote">
<p>EDIT: 2024-04-10 Project moved <a href="https://octave.space" class="uri">https://octave.space</a> → <a href="https://nightly.octave.org" class="uri">https://nightly.octave.org</a>.</p>
</blockquote>
<section id="everything-in-view" class="level2">
<h2 class="anchored" data-anchor-id="everything-in-view">Everything in view</h2>
<p>When releases happen that frequently, users and developers must be able to judge themselves, if an automatically built set of release files is “good” and complete.</p>
<p>After a Buildbot Worker finishes his duty, the relevant build artifacts are copied to the Buildbot Master, stored with the Octave Mercurial (hg) ID, as shown in the screenshot below.</p>
<p><a href="./buildbot_octave_space_folder.png"> <img src="https://siko1056.github.io/blog/2020/10/16/buildbot_octave_space_folder.png" alt="png" width="200"> </a></p>
<p>This looks unattractive and this folder view lacks any information about the corresponding build processes done by the Buildbot Workers.</p>
<p>Fortunately, <a href="https://docs.buildbot.net/latest/manual/customization.html#writing-dashboards-with-flask-or-bottle">Buildbot allows to create custom dashboards</a>. The result can now be seen on the landing page of <a href="https://octave.space" class="uri">https://octave.space</a> or on the screenshot below.</p>
<p><a href="./buildbot_octave_space.png"> <img src="https://siko1056.github.io/blog/2020/10/16/buildbot_octave_space.png" alt="png" width="200"> </a></p>
<p>In this dashboard the build artifacts are connected to the respective build processes including their status. The arrangement of those many MS Windows installers is based on the well-known Octave website <a href="https://octave.org/download#ms-windows" class="uri">https://octave.org/download#ms-windows</a>. Furthermore, each Octave build entry clearly states the version label, hg id, and build date. Another feature is, that the GNU Octave user manual and Doxygen documentation can directly be viewed online to find potential flaws in them.</p>
</section>
<section id="trust-me-im-a-buildbot-worker" class="level2">
<h2 class="anchored" data-anchor-id="trust-me-im-a-buildbot-worker">Trust me, I’m a Buildbot Worker</h2>
<p>Especially, when automation and many systems are in the game, there should be a way to make sure, that the final installer downloaded from octave-buildbot is indeed that one “brewed” on the Worker.</p>
<p>To achieve this, before copying the files to the Buildbot Master, the <a href="https://en.wikipedia.org/wiki/SHA-2">SHA-256</a> hash sum of each file is displayed in the Buildbot Workers build log.</p>
<p><a href="./buildbot_octave_space_sha256.png"> <img src="https://siko1056.github.io/blog/2020/10/16/buildbot_octave_space_sha256.png" alt="png" width="200"> </a></p>
<p>Admittedly, it is a little clumsy to find those hashes. Their main purpose can be seen as check for damaged or incompletely copied installer files to exclude sources of errors.</p>
<p>Speaking of errors, for the heavy weighting mxe-octave builds, even in the event of a build error the valuable log files are compressed and copied to the Buildbot Master. Because of this, there might sometimes be more than only one build log for a particular mxe-octave build available. They can be distinguished by the build number suffix. The installer files themselves have a timestamp in their file name.</p>
</section>
<section id="the-bill-please" class="level2">
<h2 class="anchored" data-anchor-id="the-bill-please">The bill please</h2>
<p>Running octave-buildbot binds a certain amount of computational resources. The numbers given in the following table can slightly change in the future, but didn’t change significantly in the last weeks.</p>
<section id="table-1-buildbot-worker-resources" class="level3">
<h3 class="anchored" data-anchor-id="table-1-buildbot-worker-resources">Table 1: Buildbot Worker resources</h3>
<p>In the current setup <a href="https://github.com/gnu-octave/octave-buildbot/blob/41f6c1dfbec1d2511c99ca7a889f647b60d4391a/master/defaults/master.cfg#L190">[note 1]</a> <a href="https://github.com/gnu-octave/octave-buildbot/blob/41f6c1dfbec1d2511c99ca7a889f647b60d4391a/master/defaults/master.cfg#L351">[note 2]</a>, each Worker is expected to provide 4 CPUs. This value can of course be adjusted.</p>
<blockquote class="blockquote">
<p><strong>Note:</strong> See <a href="../../../../blog/2020/11/08/octave-buildbot-boosted.html">a newer blog post</a> for significant improvements.</p>
</blockquote>
<table class="caption-top table">
<thead>
<tr class="header">
<th>Builder name</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><a href="https://buildbot.octave.space/#/builders/5">octave-stable</a></td>
</tr>
<tr class="even">
<td><a href="https://buildbot.octave.space/#/builders/3">octave-doxygen</a></td>
</tr>
<tr class="odd">
<td><a href="https://buildbot.octave.space/#/builders/1">octave-mxe-stable-w32</a></td>
</tr>
<tr class="even">
<td><a href="https://buildbot.octave.space/#/builders/2">octave-mxe-stable-w64</a></td>
</tr>
<tr class="odd">
<td><a href="https://buildbot.octave.space/#/builders/4">octave-mxe-stable-w64-64</a></td>
</tr>
<tr class="even">
<td>sum (worst case)</td>
</tr>
</tbody>
</table>
<p>Table 1 footnotes: 1. Additional disk space is needed for ccache, which currently uses 13 GB of 20 GB, and 1.5 GB for the mxe-octave installer files, which are cached to avoid unnecessary downloads. 2. All builds are performed in an empty build folder. 3. <code>make check</code> takes most time. 4. Includes a minimal Octave build. 5. Might improve, ccache enabled for the mxe-octave builds since this week (thanks to Markus).</p>
<p>The GNU Octave stable release tasks are dived into five <a href="https://docs.buildbot.net/latest/manual/concepts.html">“Builders”</a> (Buildbot slang). The Builder “octave-stable” has to run first and the remaining four Builders can run in parallel after “octave-stable” finished successfully.</p>
<blockquote class="blockquote">
<p>This way the <strong>worst case time</strong> can be reduced to <strong>about 14 hours</strong>, if four Workers work on them in parallel.</p>
</blockquote>
<p>A single Worker would need 50 hours for all Octave release tasks and the goal of one release per day would be out of reach.</p>
<p>According to Table 1 and footnote [1], each Buildbot Worker must provide in worst case <strong>about 75 GB</strong> of disk space.</p>
</section>
<section id="buildbot-master-resources" class="level3">
<h3 class="anchored" data-anchor-id="buildbot-master-resources">Buildbot Master resources</h3>
<p>In contrast to the Workers, the Master only has to serve the build artifacts and coordinate the tasks run by the Workers. This does not require much “computational power”.</p>
<p>Nevertheless, storing all build artifacts requires <strong>9 GB</strong> per GNU Octave stable release. Note that the Doxygen documentation is unpacked for online inspection, for example.</p>
<p>The current setup of <a href="https://octave.space" class="uri">https://octave.space</a> assigns 65 GB in total to store Octave releases. This means roughly the last seven Octave releases are available and get automatically deleted once a new Octave release build starts.</p>
</section>
</section>
<section id="open-issues-if-you-want-to-jump-in" class="level2">
<h2 class="anchored" data-anchor-id="open-issues-if-you-want-to-jump-in">Open issues, if you want to jump in</h2>
<p>As of today (2020-10-16) there are four open issues about <a href="https://github.com/gnu-octave/octave-buildbot/">octave-buildbot</a> on GitHub. It would be nice if they are fixed, but those do not disturb the release process significantly (workarounds exist).</p>
<ul>
<li><a href="https://github.com/gnu-octave/octave-buildbot/issues/2">More efficient use of ccache.</a></li>
<li><a href="https://github.com/gnu-octave/octave-buildbot/issues/5">Speed up the file transfers.</a>
<ul>
<li>Fun fact: Because of my limited resources (money) the server is located in Germany, while the great Workers are in Japan.</li>
</ul></li>
<li><a href="https://github.com/gnu-octave/octave-buildbot/issues/6">Library issue with two of four Workers.</a></li>
<li><a href="https://github.com/gnu-octave/octave-buildbot/issues/7">Podman related deletion problem.</a></li>
</ul>
</section>
<section id="summary" class="level2">
<h2 class="anchored" data-anchor-id="summary">Summary</h2>
<p>All in all I am very happy to enjoy a “fresh brewed Octave” every day and hope to be able to run the system for a long time on little own expenses.</p>
<p>Thanks to the use of (Docker) containers, this system can reliably release Octave on <a href="https://github.com/gnu-octave/octave-buildbot/issues/6">almost</a> arbitrary machines with little setup and maintenance effort. On the other hand, the computational resources and storage requirements (4 CPUs and 75 GB per Worker and 70 GB for the Master) are not negligible and can hopefully be tuned a little in the future by binding a certain Worker to a particular task (<a href="https://github.com/gnu-octave/octave-buildbot/issues/2#issuecomment-708592746">see the small discussion with Markus</a>).</p>
<p>Please contact me on <a href="https://github.com/gnu-octave/octave-buildbot/">GitHub</a> if you have suggestions for improvements or you find any issues with this system.</p>
<p>Happy brewing.</p>


</section>

 ]]></description>
  <category>octave</category>
  <guid>https://siko1056.github.io/blog/2020/10/16/octave-buildbot-app.html</guid>
  <pubDate>Fri, 16 Oct 2020 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Support for the JSON data format after GSoC 2020</title>
  <dc:creator>Kai T. Ohlhus</dc:creator>
  <link>https://siko1056.github.io/blog/2020/08/19/gsoc2020-json-benchmark.html</link>
  <description><![CDATA[ 





<p>The <a href="https://summerofcode.withgoogle.com/">Google Summer of Code (GSoC) 2020</a> will end with this August. I had the pleasure to mentor <a href="https://abdallahshamy.wordpress.com/">Abdallah Elshamy</a> working on the implementation of the <code>jsondecode()</code> and <code>jsonencode()</code> functions for Octave. These function allow to convert <a href="https://en.wikipedia.org/wiki/JSON">JSON data</a> strings to Octave Objects and vice versa.</p>
<p>Last week <a href="https://hg.savannah.gnu.org/hgweb/octave/rev/5da49e37a6c9">we pushed most of Abdallah’s work</a> to the main Octave repository, but he is still working on the functions and hopefully still after GSoC 2020 is over. Now as it is very convenient to use the JSON functions, I gave them a try with larger JSON data. Some of the test cases I collected from the excellent <a href="https://github.com/miloyip/nativejson-benchmark">nativejson-benchmark</a>, but with focus on Octave. Another <a href="https://lists.gnu.org/archive/html/octave-maintainers/2020-06/msg00112.html">test by Abdallah</a> has been carried out in June to test the compatibility for Matlab.</p>
<p>Only the running times for reading and writing JSON data are regarded in this benchmark.</p>
<p>The test environment is a laptop with - <a href="https://ark.intel.com/content/www/us/en/ark/products/193563/intel-core-i7-8665u-processor-8m-cache-up-to-4-80-ghz.html">Intel(R) Core(TM) i7-8665U CPU @ 1.90GHz</a> - 16 GB of main memory - OpenSUSE 15.2 Linux - <a href="https://github.com/siko1056/jupyterlab-runner">JupyterLab</a> - Octave version as given below</p>
<div id="cell-1" class="cell" data-execution_count="1">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode octave code-with-copy"><code class="sourceCode octave"><span id="cb1-1">octave_version <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">version</span> ()</span>
<span id="cb1-2">octave_hg_id   <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">version</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'-hgid'</span>)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>octave_version = 7.0.0
octave_hg_id = 173807014259</code></pre>
</div>
</div>
<p>The following JSON extensions for Octave are under test.</p>
<table class="caption-top table">
<thead>
<tr class="header">
<th>name</th>
<th>description</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><a href="https://abdallahshamy.wordpress.com/">Octave (builtin)</a></td>
<td>Based on <a href="https://rapidjson.org/">RapidJSON</a>, reading DOM API.</td>
</tr>
<tr class="even">
<td><a href="https://github.com/Andy1978/octave-rapidjson">octave-rapidjson</a></td>
<td>Based on <a href="https://rapidjson.org/">RapidJSON</a>, reading SAX API.</td>
</tr>
<tr class="odd">
<td><a href="https://github.com/apjanke/octave-jsonstuff">octave-jsonstuff</a></td>
<td>Based on <a href="https://rapidjson.org/">RapidJSON</a>, reading DOM API, writing m-file.</td>
</tr>
<tr class="even">
<td><a href="https://github.com/gllmflndn/JSONio">JSONio</a></td>
<td>Based on <a href="https://zserge.com/jsmn/">JSMN</a>, writing m-file.</td>
</tr>
<tr class="odd">
<td><a href="https://github.com/fangq/jsonlab">jsonlab</a></td>
<td>m-file only</td>
</tr>
</tbody>
</table>
<p>The JSON test files are described in the following table.</p>
<table class="caption-top table">
<thead>
<tr class="header">
<th>name</th>
<th style="text-align: right;">size (byte)</th>
<th>description</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><a href="https://github.com/RichardHightower/json-parsers-benchmark/blob/master/data/citm_catalog.json">citm_catalog.json</a></td>
<td style="text-align: right;">1,727,204</td>
<td>Structured data with mixed text and numeric.</td>
</tr>
<tr class="even">
<td><a href="https://github.com/mloskot/json_benchmark/blob/master/data/canada.json">canada.json</a></td>
<td style="text-align: right;">2,251,060</td>
<td>Numeric data set in <a href="https://en.wikipedia.org/wiki/GeoJSONhttps://en.wikipedia.org/wiki/GeoJSON">GeoJSON</a> format.</td>
</tr>
<tr class="odd">
<td><a href="https://github.com/json-iterator/test-data/blob/master/large-file.json">large-file.json</a></td>
<td style="text-align: right;">26,141,343</td>
<td>Structured data with mixed text and numeric.</td>
</tr>
</tbody>
</table>
<section id="benchmark-setup" class="level2">
<h2 class="anchored" data-anchor-id="benchmark-setup">Benchmark setup</h2>
<p>Create a directory to keep track of the mess.</p>
<div id="cell-5" class="cell" data-execution_count="2">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode octave code-with-copy"><code class="sourceCode octave"><span id="cb3-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mkdir</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'benchmark'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-2"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">cd</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'benchmark'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span></code></pre></div></div>
</div>
<p>Load the benchmark JSON files.</p>
<div id="cell-7" class="cell" data-execution_count="3">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode octave code-with-copy"><code class="sourceCode octave"><span id="cb4-1"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">exist</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'citm_catalog.json'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'file'</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>)</span>
<span id="cb4-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">urlwrite</span> ( <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span></span>
<span id="cb4-3">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'https://github.com/RichardHightower/json-parsers-benchmark/raw/master/data/citm_catalog.json'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span></span>
<span id="cb4-4">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'citm_catalog.json'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb4-5"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb4-6"></span>
<span id="cb4-7"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">exist</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'canada.json'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'file'</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>)</span>
<span id="cb4-8">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">urlwrite</span> ( <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span></span>
<span id="cb4-9">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'https://github.com/mloskot/json_benchmark/raw/master/data/canada.json'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span></span>
<span id="cb4-10">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'canada.json'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb4-11"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb4-12"></span>
<span id="cb4-13"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">exist</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'large-file.json'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'file'</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>)</span>
<span id="cb4-14">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">urlwrite</span> ( <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span></span>
<span id="cb4-15">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'https://github.com/json-iterator/test-data/raw/master/large-file.json'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span></span>
<span id="cb4-16">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'large-file.json'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb4-17"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span></code></pre></div></div>
</div>
<p>Setup <strong>octave-rapidjson</strong>.</p>
<div id="cell-9" class="cell" data-execution_count="4">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode octave code-with-copy"><code class="sourceCode octave"><span id="cb5-1"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">exist</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'octave-rapidjson'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'dir'</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span>
<span id="cb5-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">urlwrite</span> ( <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span></span>
<span id="cb5-3">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'https://github.com/Andy1978/octave-rapidjson/archive/2d88511712032b14dea4c2272d82249e7547772a.zip'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span></span>
<span id="cb5-4">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'octave-rapidjson.zip'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb5-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">unzip</span>  (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'octave-rapidjson.zip'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb5-6">  <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">rename</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'octave-rapidjson-2d88511712032b14dea4c2272d82249e7547772a'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span></span>
<span id="cb5-7">          <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'octave-rapidjson'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb5-8">  <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">cd</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'octave-rapidjson'</span>)</span>
<span id="cb5-9">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">urlwrite</span> ( <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span></span>
<span id="cb5-10">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'https://github.com/Tencent/rapidjson/archive/35e480fc4ddf4ec4f7ad34d96353eef0aabf002d.zip'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span></span>
<span id="cb5-11">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'rapidjson.zip'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb5-12">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">unzip</span>  (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'rapidjson.zip'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb5-13">  <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">rename</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'rapidjson-35e480fc4ddf4ec4f7ad34d96353eef0aabf002d'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'rapidjson'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb5-14">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mkoctfile</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>Wall <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>Wextra <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>I<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">./</span>rapidjson<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span>include load_json.cc</span>
<span id="cb5-15">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mkoctfile</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>Wall <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>Wextra <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>I<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">./</span>rapidjson<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span>include save_json.cc</span>
<span id="cb5-16">  <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">cd</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'..'</span>)</span>
<span id="cb5-17"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span></code></pre></div></div>
</div>
<p>Setup <strong>octave-jsonstuff</strong>.</p>
<div id="cell-11" class="cell" data-execution_count="5">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode octave code-with-copy"><code class="sourceCode octave"><span id="cb6-1"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">isempty</span> (<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pkg</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'list'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'jsonstuff'</span>)))</span>
<span id="cb6-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pkg</span> install https<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">://</span>github.com<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span>apjanke<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span>octave<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>jsonstuff<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span>releases<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span>download<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span>v0<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">.3.3</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span>jsonstuff<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.3.3</span>.tar.gz</span>
<span id="cb6-3"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span></code></pre></div></div>
</div>
<p>Setup <strong>JSONio</strong>.</p>
<div id="cell-13" class="cell" data-execution_count="6">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode octave code-with-copy"><code class="sourceCode octave"><span id="cb7-1"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">exist</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'JSONio'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'dir'</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span>
<span id="cb7-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">urlwrite</span> ( <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span></span>
<span id="cb7-3">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'https://github.com/gllmflndn/JSONio/archive/6c699a315ac2c578864d8b740a061bff47b718bf.zip'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span></span>
<span id="cb7-4">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'JSONio.zip'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb7-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">unzip</span>  (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'JSONio.zip'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb7-6">  <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">rename</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'JSONio-6c699a315ac2c578864d8b740a061bff47b718bf'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'JSONio'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb7-7">  <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">cd</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'JSONio'</span>)</span>
<span id="cb7-8">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mkoctfile</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">--</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mex</span> jsonread.c jsmn.c <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>DJSMN_PARENT_LINKS</span>
<span id="cb7-9">  <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">cd</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'..'</span>)</span>
<span id="cb7-10"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span></code></pre></div></div>
</div>
<p>Setup <strong>jsonlab</strong>.</p>
<div id="cell-15" class="cell" data-execution_count="7">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode octave code-with-copy"><code class="sourceCode octave"><span id="cb8-1"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">exist</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'jsonlab'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'dir'</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span>
<span id="cb8-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">urlwrite</span> ( <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span></span>
<span id="cb8-3">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'https://github.com/fangq/jsonlab/archive/d0fb684bd43165d312063345bdb795b628b2c679.zip'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span></span>
<span id="cb8-4">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'jsonlab.zip'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb8-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">unzip</span>  (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'jsonlab.zip'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb8-6">  <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">rename</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'jsonlab-d0fb684bd43165d312063345bdb795b628b2c679'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'jsonlab'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb8-7"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span></code></pre></div></div>
</div>
</section>
<section id="benchmark-run" class="level2">
<h2 class="anchored" data-anchor-id="benchmark-run">Benchmark run</h2>
<p>The benchmark function reads the respective JSON file into a string and calls the libraries reading and writing function.</p>
<div id="cell-17" class="cell" data-execution_count="8">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode octave code-with-copy"><code class="sourceCode octave"><span id="cb9-1"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span> t <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> benchmark (json_read_fcn<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> json_write_fcn)</span>
<span id="cb9-2">  test_files <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> {<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'citm_catalog.json'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'canada.json'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'large-file.json'</span>}<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb9-3">  N <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">length</span> (test_files)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb9-4">  t <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">nan</span> (N<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb9-5">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">i</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span>N</span>
<span id="cb9-6">    json_str <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">fileread</span> (test_files{<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">i</span>})<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb9-7">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tic</span> ()<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb9-8">    octave_obj <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> json_read_fcn (json_str)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb9-9">    t(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">i</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">toc</span> ()<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb9-10">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tic</span> ()<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb9-11">    json_str2 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> json_write_fcn (octave_obj)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb9-12">    t(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">i</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">toc</span> ()<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb9-13">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb9-14"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span></code></pre></div></div>
</div>
<p>The results for the <strong>Matlab (R2020b, prerelease)</strong> have been measured on the same system without JupyterLab.</p>
<div id="cell-19" class="cell" data-execution_count="9">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb10" style="background: #f1f3f5;"><pre class="sourceCode octave code-with-copy"><code class="sourceCode octave"><span id="cb10-1">t.matlab <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [</span>
<span id="cb10-2">  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.0768</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.0853</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb10-3">  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.1510</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5405</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb10-4">  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.2222</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.6521</span>]<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span></code></pre></div></div>
</div>
<p><strong>Octave (7.0.0, development version)</strong></p>
<div id="cell-21" class="cell" data-execution_count="10">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb11" style="background: #f1f3f5;"><pre class="sourceCode octave code-with-copy"><code class="sourceCode octave"><span id="cb11-1">t.octave <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> benchmark (@jsondecode<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> @jsonencode)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span></code></pre></div></div>
</div>
<p><strong>octave-rapidjson</strong></p>
<div id="cell-23" class="cell" data-execution_count="11">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb12" style="background: #f1f3f5;"><pre class="sourceCode octave code-with-copy"><code class="sourceCode octave"><span id="cb12-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">addpath</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'octave-rapidjson'</span>)</span>
<span id="cb12-2">t.rapid_json <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> benchmark (@load_json<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> @save_json)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb12-3"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rmpath</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'octave-rapidjson'</span>)</span></code></pre></div></div>
</div>
<p><strong>octave-jsonstuff</strong>: No results due to an error.</p>
<div id="cell-25" class="cell" data-execution_count="12">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb13" style="background: #f1f3f5;"><pre class="sourceCode octave code-with-copy"><code class="sourceCode octave"><span id="cb13-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%pkg load jsonstuff</span></span>
<span id="cb13-2"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%t.jsonstuff = benchmark (@jsondecode, @jsonencode);</span></span>
<span id="cb13-3"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%error: cat: field names mismatch in concatenating structs</span></span>
<span id="cb13-4"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%error: called from</span></span>
<span id="cb13-5"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%    jsondecode&gt;condense_decoded_json_recursive at line 116 column 9</span></span>
<span id="cb13-6"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%    jsondecode&gt;condense_decoded_json at line 67 column 7</span></span>
<span id="cb13-7"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%    jsondecode at line 63 column 7</span></span>
<span id="cb13-8"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%    benchmark at line 8 column 16</span></span>
<span id="cb13-9"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%pkg unload jsonstuff</span></span></code></pre></div></div>
</div>
<p><strong>JSONio</strong>: Because of the long running time, the results of the first run are saved here.</p>
<div id="cell-27" class="cell" data-execution_count="13">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb14" style="background: #f1f3f5;"><pre class="sourceCode octave code-with-copy"><code class="sourceCode octave"><span id="cb14-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">addpath</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'JSONio'</span>)</span>
<span id="cb14-2"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%t.jsonio = benchmark (@jsonread, @jsonwrite);</span></span>
<span id="cb14-3">t.jsonio <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [ <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span></span>
<span id="cb14-4">  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.9583</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">30.5410</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb14-5">  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">6.1333</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">17.4022</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb14-6">  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">4.3382</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">552.8929</span>]<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb14-7"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rmpath</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'JSONio'</span>)</span></code></pre></div></div>
</div>
<p><strong>Jsonlab</strong>: Because of the long running time, the results of the first run are saved here.</p>
<div id="cell-29" class="cell" data-execution_count="14">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb15" style="background: #f1f3f5;"><pre class="sourceCode octave code-with-copy"><code class="sourceCode octave"><span id="cb15-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">addpath</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'jsonlab'</span>)</span>
<span id="cb15-2"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%t.jsonlab = benchmark (@loadjson, @savejson);</span></span>
<span id="cb15-3">t.jsonlab <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [ <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span></span>
<span id="cb15-4">   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">35.6242</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span>  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">26.0625</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb15-5">    <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">6.1303</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span>   <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.7365</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb15-6">  <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">372.2456</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">601.5318</span>]<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb15-7"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rmpath</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'jsonlab'</span>)</span></code></pre></div></div>
</div>
</section>
<section id="benchmark-results" class="level2">
<h2 class="anchored" data-anchor-id="benchmark-results">Benchmark results</h2>
<blockquote class="blockquote">
<p><strong>Update 2020-08-29</strong>: <a href="https://github.com/Abdallah-Elshamy/octave/issues/12#issuecomment-680052363">Abdallah found out</a> that the speed problem (described blow) was the call to <a href="https://www.octave.org/doc/v5.2.0/XREFmatlab_005flang_005fmakeValidName.html"><code>matlab.lang.makeValidName</code></a> not the chosen DOM API.</p>
</blockquote>
<div id="cell-31" class="cell" data-execution_count="15">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb16" style="background: #f1f3f5;"><pre class="sourceCode octave code-with-copy"><code class="sourceCode octave"><span id="cb16-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">graphics_toolkit</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'qt'</span>)</span>
<span id="cb16-2">titles <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> {<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'citm\_catalog.json (2 MB, mixed)'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span></span>
<span id="cb16-3">          <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'canada.json (2 MB, numeric)'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span></span>
<span id="cb16-4">          <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'large-file.json (26 MB, mixed)'</span>}<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span></code></pre></div></div>
</div>
<div id="cell-32" class="cell" data-execution_count="16">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb17" style="background: #f1f3f5;"><pre class="sourceCode octave code-with-copy"><code class="sourceCode octave"><span id="cb17-1"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">i</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span></span>
<span id="cb17-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">subplot</span> (<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">i</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb17-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">bar</span> ([t.matlab(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">i</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,:</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> t.octave(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">i</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,:</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> t.rapid_json(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">i</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,:</span>)]<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb17-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">legend</span> ({<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Matlab (R2020b, pre)'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Octave (7.0.0, dev)'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span></span>
<span id="cb17-5">           <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'octave-rapidjson'</span>}<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Location'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'bestoutside'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb17-6">  xticklabels({<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'read'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'write'</span>})<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb17-7">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ylabel</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'time in seconds'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb17-8">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">title</span> (titles{<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">i</span>})<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb17-9"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span></code></pre></div></div>
<div class="cell-output cell-output-display">
<div>
<figure class="figure">
<p><img src="https://siko1056.github.io/blog/2020/08/19/gsoc2020-json-benchmark_files/figure-html/cell-17-output-1.png" class="img-fluid figure-img"></p>
</figure>
</div>
</div>
</div>
<div id="cell-33" class="cell" data-execution_count="17">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb18" style="background: #f1f3f5;"><pre class="sourceCode octave code-with-copy"><code class="sourceCode octave"><span id="cb18-1"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">i</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span></span>
<span id="cb18-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">subplot</span> (<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">i</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb18-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">bar</span> ([t.jsonio(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">i</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,:</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> t.jsonlab(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">i</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,:</span>)]<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb18-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">legend</span> ({<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'JSONio'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'jsonlab'</span>}<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Location'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'bestoutside'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb18-5">  xticklabels({<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'read'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'write'</span>})<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb18-6">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ylabel</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'time in seconds'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb18-7">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">title</span> (titles{<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">i</span>})<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb18-8"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span></code></pre></div></div>
<div class="cell-output cell-output-display">
<div>
<figure class="figure">
<p><img src="https://siko1056.github.io/blog/2020/08/19/gsoc2020-json-benchmark_files/figure-html/cell-18-output-1.png" class="img-fluid figure-img"></p>
</figure>
</div>
</div>
</div>
<p><strike>The results are not as overwhelming as I initially hoped for</strike> (they are, see comment above.)</p>
<p>The first figure compares the running times of <strong>Matlab</strong>, <strong>Octave</strong>, and <strong>octave-rapidjson</strong>. Both <strong>Octave</strong> and <strong>octave-rapidjson</strong> are based on RapidJSON.</p>
<p><strike>It must be the choice of the API (DOM vs.&nbsp;SAX) that slows down the current Octave implementation (DOM) by a factor of 10 to 100</strike> (wrong, see comment above).</p>
<p><strong>octave-rapidjson</strong>, using the SAX API, is for the mixed data case not slower than Matlab. But the implementation itself is less Matlab compatible than the current Octave implementation. The choice of DOM for the current Octave implementation was made to achieve best compatibility to Matlab.</p>
<p>On the positive side, in the case of more numeric data (canada.json) the DOM API outperforms the SAX API. Nevertheless, my humble assumption is that mixed data is more common for JSON data files.</p>
<p>The results of <strong>JSONio</strong> and <strong>jsonlab</strong> are split into a second figure, as the running times are significantly larger than those of the first figure. For <strong>octave-jsonstuff</strong> we could due to an error not obtain any results. I’ll inform the maintainer to hopefully in the future repeat this benchmark.</p>
<p><strike> Regarding this benchmark Octave should seriously consider switching to the SAX API and additionally preserve the current Matlab compatibility </strike> (see comment above).</p>
<p>GSoC 2020 is over, and Abdallah enriched Octave with a great new feature. When he (or someone else) ports the Octave function <a href="https://www.octave.org/doc/v5.2.0/XREFmatlab_005flang_005fmakeValidName.html"><code>matlab.lang.makeValidName</code></a> to the C++ language, the performance of JSON decoding and encoding is great and compatible to Matlab.</p>


</section>

 ]]></description>
  <category>octave</category>
  <guid>https://siko1056.github.io/blog/2020/08/19/gsoc2020-json-benchmark.html</guid>
  <pubDate>Wed, 19 Aug 2020 00:00:00 GMT</pubDate>
</item>
<item>
  <title>octave-buildbot: Less painful Octave releases?</title>
  <dc:creator>Kai T. Ohlhus</dc:creator>
  <link>https://siko1056.github.io/blog/2020/08/17/octave-buildbot.html</link>
  <description><![CDATA[ 





<p>Since the minor <a href="https://wiki.octave.org/Release_History">Octave 5.2 release this January</a>, I experienced that building and especially releasing Octave is still a difficult task. Even worse, due to <a href="https://wiki.octave.org/Online_Developer_Meeting_(2020-07-28)">some nasty bugs</a> and the lack of a voluntary, skilled, and motivated release manager, the next major <a href="https://wiki.octave.org/6.1_Release_Checklist">Octave 6.1 release</a> got stuck for eight months now.</p>
<section id="how-was-octave-released-in-the-past" class="level2">
<h2 class="anchored" data-anchor-id="how-was-octave-released-in-the-past">1 How was Octave released in the past?</h2>
<p>The basic workflow for the last major Octave 5.1 release was as follows:</p>
<ol type="1">
<li>Some Octave maintainer thinks it is time for a release and starts a topic on the <a href="https://lists.gnu.org/archive/html/octave-maintainers/2018-12/msg00000.html">maintainers mailing-list</a> about it. This happened usually about once per year.</li>
<li>Another Octave maintainer (very often Rik, <em>many thanks!</em>) coordinated the release process by creating a <a href="https://wiki.octave.org/5.0.0_Release_Checklist">wiki checklist</a> and sometimes a <a href="https://wiki.octave.org/Bug_Fix_List_-_5.0_Release">wiki bug fix list</a> to coordinate important open bug reports.</li>
<li>Finally, mostly jwe created <a href="https://alpha.gnu.org/gnu/octave/">release candidates</a>, the final <a href="https://ftp.gnu.org/gnu/octave">release tarballs</a>, and MS Windows <a href="https://wiki.octave.org/MXE">mxe builds</a> on his machines.</li>
</ol>
</section>
<section id="why-not-just-continue-like-this" class="level2">
<h2 class="anchored" data-anchor-id="why-not-just-continue-like-this">2 Why not just continue like this?</h2>
<p>As mentioned before, the <a href="https://wiki.octave.org/6.1_Release_Checklist">Octave 6.1 release</a> got stuck and I tried to summarize some problems of the current release process. The description is from the perspective of a totally uninvolved volunteer trying to release Octave on his own for the first time.</p>
<section id="lack-of-knowledge" class="level3">
<h3 class="anchored" data-anchor-id="lack-of-knowledge">2.1 Lack of knowledge</h3>
<p>A volunteer who wants to release Octave must be able to <a href="https://wiki.octave.org/Building">build Octave</a>, release tarballs, and the MS Windows <a href="https://wiki.octave.org/MXE">mxe builds</a> on the machine. This requires the build machine to be setup correctly.</p>
<p>On the first glance, this sounds like an easy task. All steps are documented. Unfortunately, there are implicit unnecessary build dependencies, which only apply for releases. For example for the Octave 5.2 release all of my work was useless, because I did not know that the <a href="https://lists.gnu.org/archive/html/octave-maintainers/2020-01/msg00310.html">documentation has to be build using an X environment</a>…</p>
<p>Even though there exists lots of documentation, there is no complete documentation of how jwe creates the releases.</p>
</section>
<section id="lack-of-permission" class="level3">
<h3 class="anchored" data-anchor-id="lack-of-permission">2.2 Lack of permission</h3>
<p>Following the current release process, not any volunteer can just step in to become release manager. Despite the knowledge of what to do, the volunteer must possess or negotiate for the following permissions:</p>
<ul>
<li>Push rights on the <a href="https://hg.savannah.gnu.org/hgweb/octave/">Octave main repository</a> (apply bug fixes, updating dates, library version numbers, etc.).</li>
<li>Push rights on the <a href="https://hg.octave.org/mxe-octave">mxe-octave repository</a> (updating <a href="https://hg.octave.org/mxe-octave/file/7b15672f8679/src/release-octave.mk"><code>src/release-octave.mk</code></a>).</li>
<li>Push rights to the <a href="https://hg.octave.org/web-octave">Octave website repository</a> to announce the release.</li>
<li>Must be able to upload files to <a href="https://alpha.gnu.org/gnu/octave/" class="uri">https://alpha.gnu.org/gnu/octave/</a> and <a href="https://ftp.gnu.org/gnu/octave" class="uri">https://ftp.gnu.org/gnu/octave</a>.</li>
<li>Needs to add new versions to the <a href="https://savannah.gnu.org/bugs/?group=octave">Octave bug tracker at Savannah</a>.</li>
</ul>
</section>
<section id="lack-of-transparency" class="level3">
<h3 class="anchored" data-anchor-id="lack-of-transparency">2.3 Lack of transparency</h3>
<p>If the volunteer (or even jwe) succeeds to create the release tarballs, etc., and might be able to upload his work to the respective locations, <strong>how can we know everything was done correctly?</strong></p>
<p>Mistakes happen. To find out that something went wrong, some kind of reliable build logs should be publicly accessible alongside with the releases.</p>
</section>
</section>
<section id="octave-buildbot" class="level2">
<h2 class="anchored" data-anchor-id="octave-buildbot">3 Octave-buildbot</h2>
<p>In the past months, I thought about a system to address some of the weaknesses identified above. The key ideas are far from new:</p>
<ol type="1">
<li><strong>Save the output</strong> (tarballs, logs, …) from the existing <a href="https://wiki.octave.org/Continuous_Build">Octave Buildbots</a>.</li>
<li><strong>Use a reproducible build environment</strong>.</li>
</ol>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="./octave_buildbot.png"><img src="https://siko1056.github.io/blog/2020/08/17/octave_buildbot.png" class="img-fluid figure-img"></a></p>
<figcaption>png</figcaption>
</figure>
</div>
<section id="what-is-the-difference-to-the-existing-octave-buildbots" class="level3">
<h3 class="anchored" data-anchor-id="what-is-the-difference-to-the-existing-octave-buildbots">3.1 What is the difference to the existing Octave Buildbots?</h3>
<ul>
<li>The configuration of the Buildbot Master is <a href="https://hg.octave.org/octave-buildbot/">public available</a>, but is intended to run on a single server machine only and to build any commit to the Octave repository to find errors.</li>
<li>Most of the current Buildbot Workers are configured and managed by jwe. Copying those “real” machines is difficult, not everybody runs Debian, for example.</li>
</ul>
</section>
<section id="what-is-the-difference-to-the-current-octave-release-process" class="level3">
<h3 class="anchored" data-anchor-id="what-is-the-difference-to-the-current-octave-release-process">3.2 What is the difference to the current Octave release process?</h3>
<p>The key idea here is to get rid of the <strong>permission problem</strong> to increase the frequency of building release candidates (RC) before a release. The Buildbot Master defines the release infrastructure:</p>
<ul>
<li>The Octave repository (to release from) can be altered by the Buildbot Master and is documented in the build logs.</li>
<li>No need to store the release tarballs on <a href="https://alpha.gnu.org/gnu/octave/" class="uri">https://alpha.gnu.org/gnu/octave/</a>.</li>
<li>The <strong>Mercurial ID becomes the major Octave release identifier</strong>, not some artificial manual applied version (e.g.&nbsp;Octave 6.0.1).</li>
</ul>
<blockquote class="blockquote">
<p><strong>The idea is not to get rid of Octave versions entirely.</strong> The observation is that updating those numbers manually is tedious (updating the Octave and mxe-octave repository is involved) and leads to more confusion compared to an unique Mercurial ID.</p>
</blockquote>
<p>In the current Buildbot example setup a tarball will be published like this <a href="https://www.octave.space/data/stable/bdc53d9affb2/octave-6.0.1.tar.gz" class="uri">https://www.octave.space/data/stable/bdc53d9affb2/octave-6.0.1.tar.gz</a>. There it is clear from the URL that <a href="https://hg.savannah.gnu.org/hgweb/octave/rev/bdc53d9affb2"><code>bdc53d9affb2</code></a> was build, even though the release is labeled <code>6.0.1</code> for eight months.</p>
</section>
<section id="why-buildbot" class="level3">
<h3 class="anchored" data-anchor-id="why-buildbot">3.3 Why Buildbot?</h3>
<p>For the Octave 5.2.0 release, I used <a href="https://github.com/gnu-octave/OctaveCD">some bash scripts</a> to create the desired Octave builds and to preserve the logs for my <a href="https://octave.space">octave.space</a> website. That was too troublesome at some point (the complexity grew fast) and did not look “good” compared to Buildbot. Thus, why painfully reinventing the wheel, if Buildbot offers all demanded features in a good looking environment?</p>
</section>
<section id="why-docker" class="level3">
<h3 class="anchored" data-anchor-id="why-docker">3.4 Why Docker?</h3>
<blockquote class="blockquote">
<p>Having Docker installed, <strong>EVERYBODY can help testing/releasing Octave</strong> by running a <a href="https://github.com/gnu-octave/octave-buildbot/tree/master/worker">Buildbot worker</a> on his (unused) machine!</p>
</blockquote>
<p>Ever tried to compile Octave on CentOS 7? It is possible, but compared to a recent Ubuntu or Debian, you have to manually provide many tools and libraries yourself. Especially, if the machine is not run by you, or a compute server shared with other users, you are happy if nobody ever touches your self-compiled Octave once it succeeds.</p>
<p>This is of course far from reproducible or reliable. Using Docker, your virtual system (for building Octave) is defined by a <a href="https://github.com/gnu-octave/octave-buildbot/blob/70266b8c46a87c80c46aad0676f8e60675d0a60e/worker/Dockerfile">single Dockerfile</a> and started with a few commands.</p>
</section>
</section>
<section id="summary-and-outlook" class="level2">
<h2 class="anchored" data-anchor-id="summary-and-outlook">4 Summary and outlook</h2>
<p>The project goal of <a href="https://github.com/gnu-octave/octave-buildbot/"><em>octave-buildbot</em></a> is that everybody should be able to build/release Octave using a fully documented, reproducible Docker environment running Buildbot.</p>
<p>The current state of the project is:</p>
<ul>
<li>Buildbot Master and Server can be run on <a href="https://github.com/gnu-octave/octave-buildbot/tree/master/test">a single local machine</a> or distributed to a webserver and several PCs (see <a href="https://buildbot.octave.space" class="uri">https://buildbot.octave.space</a>, as of 2024-04-10, see <a href="https://nightly.octave.org" class="uri">https://nightly.octave.org</a>).</li>
<li>The Octave release tarballs and documentation are built and sent to the Master.</li>
</ul>
<p>What is missing?</p>
<ul>
<li><strike>Building Doxygen</strike></li>
<li>Better ideas how to faster send the 2 GB Doxygen zip-file to the Buildbot Master and where to store the builds for longer time.</li>
<li><strike>Implementing the MXE builds, lack of time so far.</strike></li>
<li>Interested developers supporting my efforts.</li>
</ul>
<p>The final suggestion from section 3.2 is to make the Mercurial ID the only necessary release candidate identifier. For mxe-octave this means that only <a href="https://hg.octave.org/mxe-octave/file/9b74815e8337/src/stable-octave.mk"><code>stable-octave.mk</code></a> will be used, not <a href="https://hg.octave.org/mxe-octave/file/9b74815e8337/src/release-octave.mk"><code>release-octave.mk</code></a>.</p>


</section>

 ]]></description>
  <category>octave</category>
  <guid>https://siko1056.github.io/blog/2020/08/17/octave-buildbot.html</guid>
  <pubDate>Mon, 17 Aug 2020 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Boosting the Octave hilb function</title>
  <dc:creator>Kai T. Ohlhus</dc:creator>
  <link>https://siko1056.github.io/blog/2020/07/01/octave-hilb-function.html</link>
  <description><![CDATA[ 





<p>Today, I read an interesting <a href="https://nhigham.com/2020/06/30/what-is-the-hilbert-matrix">article about Hilbert Matrices in N. Higham’s blog</a> and stumbled over these simple elegant two lines:</p>
<div id="cell-1" class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode octave code-with-copy"><code class="sourceCode octave"><span id="cb1-1"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span> H <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> hilb_higham (n)</span>
<span id="cb1-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">j</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span>n<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-3">  H <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">./</span> (j<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">'</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">j</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-4"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">endfunction</span></span></code></pre></div></div>
</div>
<p>I checked with the implementation of Octave. The currently implemented approach is not as elegant as it can be and includes a for-loop:</p>
<div id="cell-3" class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode octave code-with-copy"><code class="sourceCode octave"><span id="cb2-1"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span> H <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> hilb_octave (n)</span>
<span id="cb2-2">  H <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">zeros</span> (n)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb2-3">  tmp <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span>n<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb2-4">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">i</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span>n</span>
<span id="cb2-5">    H(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">i</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.0</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">./</span> tmp<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb2-6">    tmp <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb2-7">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">endfor</span></span>
<span id="cb2-8"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">endfunction</span></span></code></pre></div></div>
</div>
<blockquote class="blockquote">
<p><strong>Fun fact:</strong> The “MATLAB implicit expansion feature” mentioned in Higham’s article was introduced in <a href="https://nhigham.com/2016/09/20/implicit-expansion-matlab-r2016b/">Matlab R2016b</a>. This feature is called <a href="https://octave.org/doc/v5.2.0/Broadcasting.html">broadcasting</a> and was <a href="https://wiki.octave.org/Release_History#3.x_series">introduced in Octave 3.6.0 back in 2012</a>.</p>
</blockquote>
<p>Comparing the implementations clearly shows, that Higham’s solution should be taken.</p>
<p>In the figure generated by the test code below, <strong>smaller</strong> values are better.</p>
<div id="cell-5" class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode octave code-with-copy"><code class="sourceCode octave"><span id="cb3-1">N <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1000</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-2">time_octave_hilb <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">zeros</span> (<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> N)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-3">time_higham_hilb <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">zeros</span> (<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> N)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-4"></span>
<span id="cb3-5"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">i</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span>N</span>
<span id="cb3-6">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tic</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-7">  hilb_octave (<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">i</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-8">  time_octave_hilb(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">i</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">toc</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-9"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">endfor</span></span>
<span id="cb3-10"></span>
<span id="cb3-11"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">i</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span>N</span>
<span id="cb3-12">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tic</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-13">  hilb_higham (<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">i</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-14">  time_higham_hilb(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">i</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">toc</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-15"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">endfor</span></span>
<span id="cb3-16"></span>
<span id="cb3-17"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">semilogy</span> (<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span>N<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> time_octave_hilb<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'b'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-18"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">hold</span> on<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-19"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">semilogy</span> (<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span>N<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> time_higham_hilb<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'r'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-20"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">legend</span> ({<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Octave 5.2.0"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Higham"</span>})<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-21"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">xlabel</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Hilbert Matrix Dimension"</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-22"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ylabel</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Time in seconds"</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span></code></pre></div></div>
<div class="cell-output cell-output-display">
<div>
<figure class="figure">
<p><img src="https://siko1056.github.io/blog/2020/07/01/octave-hilb-function_files/figure-html/cell-4-output-1.png" class="img-fluid figure-img"></p>
</figure>
</div>
</div>
</div>
<p>Octave uses Higham’s approach since <a href="https://hg.savannah.gnu.org/hgweb/octave/rev/627da618dcc4">cset 627da618dcc4</a>.</p>



 ]]></description>
  <category>math</category>
  <category>octave</category>
  <guid>https://siko1056.github.io/blog/2020/07/01/octave-hilb-function.html</guid>
  <pubDate>Wed, 01 Jul 2020 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Testing the OctaveCoder</title>
  <dc:creator>Kai T. Ohlhus</dc:creator>
  <link>https://siko1056.github.io/blog/2020/06/18/OctaveCoder.html</link>
  <description><![CDATA[ 





<p>On June 4th there arrived an <a href="https://lists.gnu.org/archive/html/octave-maintainers/2020-06/msg00027.html">extraordinary mail by <em>Hossein</em></a> on the Octave maintainers mailing-list. To my knowledge he has not been involved into Octave development so far. He introduced shortly and convincingly <a href="https://github.com/shsajjadi/OctaveCoder">OctaveCoder</a>:</p>
<blockquote class="blockquote">
<ul>
<li>Octave instructions, are translated to the intermediate Coder C++ API.</li>
<li>The Coder C++ API uses the Octave C++ API and links against Octave core libraries.</li>
<li>Names and symbols are resolved at translation time
<ul>
<li>no symbol table lookup at runtime</li>
<li>no AST traversal at runtime</li>
</ul></li>
<li>Speed-up is usually 3X - 4X relative to the interpreter.</li>
</ul>
</blockquote>
<p>OctaveCoder can be installed as usual Octave package:</p>
<pre><code>pkg install https://github.com/shsajjadi/OctaveCoder/archive/coder-1.0.0-octave-5.2.0.tar.gz</code></pre>
<section id="the-test-setup" class="level2">
<h2 class="anchored" data-anchor-id="the-test-setup">The test setup</h2>
<p>To test the speed-up there is severe crime in the Octave language: <strong>“ijk Matrix multiplication”</strong> using triply nested loops</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode octave code-with-copy"><code class="sourceCode octave"><span id="cb2-1"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span> C <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> matrix_mult (A<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> B)</span>
<span id="cb2-2">  [m<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> r] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">size</span> (A)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb2-3">  [R<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> n] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">size</span> (B)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb2-4">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (r <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> R)</span>
<span id="cb2-5">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">error</span> (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"matrix_mult: Bad arguments"</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb2-6">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">endif</span></span>
<span id="cb2-7"></span>
<span id="cb2-8">  C <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">zeros</span> (m<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> n)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb2-9">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">i</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span>m</span>
<span id="cb2-10">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">j</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span>n</span>
<span id="cb2-11">      <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> k <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span>r</span>
<span id="cb2-12">        C(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">i</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">j</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+=</span> A(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">i</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span>k) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> B(k<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">j</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb2-13">      <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">endfor</span></span>
<span id="cb2-14">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">endfor</span></span>
<span id="cb2-15">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">endfor</span></span>
<span id="cb2-16"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">endfunction</span></span></code></pre></div></div>
<p>As can be seen from a short test run, even for rather small dimensions <code>matrix_mult.m</code> is by a factor of about 10,000 slower than Octave’s builtin matrix multiplication.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode octave code-with-copy"><code class="sourceCode octave"><span id="cb3-1">n <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">30</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-2">A <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rand</span> (<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span>n<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> n)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-3">B <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rand</span> (n<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span>n)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-4"></span>
<span id="cb3-5"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tic</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> C1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> A <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> B<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">toc</span></span>
<span id="cb3-6">Elapsed <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">time</span> is <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.000144958</span> seconds.</span>
<span id="cb3-7"></span>
<span id="cb3-8"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tic</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> C2 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> matrix_mult (A<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> B)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">toc</span></span>
<span id="cb3-9">Elapsed <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">time</span> is <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.72018</span> seconds.</span></code></pre></div></div>
<p>The interpretation of Octave code as in <code>matrix_mult.m</code> is rather slow, as many checks for index bounds, existing symbols, correct syntax, etc. and lots of memory operations have to be performed.</p>
<p>If there is no builtin routine available in Octave, as in the example above, one can study the <a href="https://octave.org/doc/v5.2.0/Vectorization-and-Faster-Code-Execution.html">vectorization chapter</a> in the Octave manual.</p>
</section>
<section id="the-test-result" class="level2">
<h2 class="anchored" data-anchor-id="the-test-result">The test result</h2>
<p>OctaveCoder claims to speed-up things by factor three to four and indeed succeeds:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode octave code-with-copy"><code class="sourceCode octave"><span id="cb4-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pkg</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">load</span> coder</span>
<span id="cb4-2">octave2oct (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"matrix_mult"</span>)</span>
<span id="cb4-3"></span>
<span id="cb4-4"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">which</span> matrix_mult</span>
<span id="cb4-5"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'matrix_mult'</span> is a <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span> from the file matrix_mult.oct</span>
<span id="cb4-6"></span>
<span id="cb4-7"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tic</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> C3 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> matrix_mult (A<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> B)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">toc</span></span>
<span id="cb4-8">Elapsed <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">time</span> is <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.54394</span> seconds.</span></code></pre></div></div>
<p>What happens under the hood? There is an option to keep intermediate files during the compilation to an oct-file.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode octave code-with-copy"><code class="sourceCode octave"><span id="cb5-1">octave2oct (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"matrix_mult"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"KeepSource"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">true</span>)</span></code></pre></div></div>
<p>The output is an about 5000 lines C++-file containing many class definitions and strongly reminds of Octave’s interpreter implementation. According to the description by Hossein, he implemented a “lightweight interpreter”, that does all symbol look-ups at compile time, but still there is interpretation work left to be done. The compiled file reacts dynamically on bad input, for example.</p>
</section>
<section id="summary" class="level2">
<h2 class="anchored" data-anchor-id="summary">Summary</h2>
<ul>
<li>OctaveCoder keeps it’s promise and speeds up ordinary Octave m-code by factor three to four.</li>
<li>It seems like a viable solution, if vectorization is not applicable or translation to C/C++ too tedious.</li>
<li>Until Octave finally gets a proper working <a href="https://wiki.octave.org/JIT">JIT compiler</a> this solution can be really recommended.</li>
</ul>


</section>

 ]]></description>
  <category>octave</category>
  <guid>https://siko1056.github.io/blog/2020/06/18/OctaveCoder.html</guid>
  <pubDate>Thu, 18 Jun 2020 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Can git and Mercurial work together?</title>
  <dc:creator>Kai T. Ohlhus</dc:creator>
  <link>https://siko1056.github.io/blog/2020/06/17/git-to-mercurial.html</link>
  <description><![CDATA[ 





<p>Many popular source code hosting services do not support <a href="https://www.mercurial-scm.org/">Mercurial</a> (in short “hg”). After <a href="https://bitbucket.org/blog/sunsetting-mercurial-support-in-bitbucket">Bitbucket</a> announced the “sunsetting” of Mercurial repositories in April 2020, only good old <a href="https://sourceforge.net/">SourceForge</a> and <a href="https://savannah.gnu.org/">GNU Savannah</a> still support hg.</p>
<p>Anyways, <a href="https://wiki.octave.org/Mercurial">GNU Octave</a> still uses Mercurial and due to <a href="https://summerofcode.withgoogle.com/projects/#6263027378159616">my GSoC mentoring</a> for Octave this year, I was curious how well git and Mercurial work together. The <strong>big idea</strong> I have in mind is: - to find a nice addition (replacement?) for the rusty <a href="https://savannah.gnu.org/patch/?group=octave">Octave patch tracker</a> on GNU Savannah. - Contributors can make usual “merge requests” in a nice and modern web interface or via git commands. Then Octave maintainers can easily pick them up to convert them to hg patches for application to the main repository.</p>
<p>I’ll show how to archive this.</p>
<section id="converting-hg-to-git-repositories" class="level2">
<h2 class="anchored" data-anchor-id="converting-hg-to-git-repositories">Converting hg to git repositories</h2>
<blockquote class="blockquote">
<p>No worries, this step can be omitted.</p>
</blockquote>
<p><em>mtmiller</em>, the maintainer of two unofficial Octave forks on <a href="https://gitlab.com/mtmiller/octave">GitLab</a> end <a href="https://github.com/mtmiller/octave">GitHub</a>, <a href="https://lists.gnu.org/archive/html/octave-maintainers/2020-05/msg00050.html">explained to me</a> that he uses <a href="https://github.com/glandium/git-cinnabar">git-cinnabar</a> to create and update these forks from the <a href="https://www.octave.org/hg/octave">official GNU Octave Mercurial repository</a>.</p>
<p>In the <a href="https://github.com/glandium/git-cinnabar/blob/master/README.md"><code>README.md</code> of git-cinnabar</a> and by own research on the web, I found that there are many tools for this purpose.</p>
<p>I gave it a short try myself after installing <em>git-cinnabar</em>:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb1-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">hg</span>  clone https://www.octave.org/hg/octave octave-hg</span>
<span id="cb1-2"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># The following is a git-cinnabar extension</span></span>
<span id="cb1-3"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">git</span> clone hg::octave-hg octave-git</span></code></pre></div></div>
<p>But I continue to use the solution from <em>mtmiller</em> as upstream to not duplicate efforts.</p>
</section>
<section id="applying-gitlab-merge-requests-to-mercurial" class="level2">
<h2 class="anchored" data-anchor-id="applying-gitlab-merge-requests-to-mercurial">Applying GitLab “merge requests”<sup>(*)</sup> to Mercurial</h2>
<blockquote class="blockquote">
<p><sup>(*)</sup>For those who are more familiar with GitHub, GitLab <a href="https://stackoverflow.com/a/29951658/3778706">“merge requests” are “pull requests”</a> in GitHub slang.</p>
</blockquote>
<p>First, I created a fork <code>https://gitlab.com/siko1056/octave</code> of <a href="https://gitlab.com/mtmiller/octave"><em>mtmiller</em>’s upstream repository</a> on GitLab.</p>
<p>In my fork, I used the online editor from GitLab, to make a meaningless change on the “master” branch and created a <a href="https://gitlab.com/mtmiller/octave/-/merge_requests/2">merge request</a> to <em>mtmiller</em>’s upstream repository at GitLab.</p>
<p>This “merge requests” or <a href="https://docs.gitlab.com/ee/user/project/merge_requests/cherry_pick_changes.html">individual commits</a> can be conveniently exported to patches from GitLab, without cloning the whole Octave fork, adding other remotes, etc. See the picture below showing the “merge request” view and how to download the associated patch.</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://siko1056.github.io/blog/2020/06/17/gitlab_export_patch.png" class="img-fluid figure-img"></p>
<figcaption>gitlab export patch</figcaption>
</figure>
</div>
<p>Unfortunately, this export button does not exist in GitHub. A nice trick that works for GitLab and GitHub is to append <code>.patch</code> the commit ID in the URL, e.g.</p>
<pre><code>https://gitlab.com/siko1056/octave/-/commit/4d43501fc2a442b179b2327ad8379a19d224323c.patch</code></pre>
<p>This automatically generates a git patch and this feature can nicely be exploited by tools like <code>wget</code> or <code>curl</code> or be <strong>posted on Octave’s patch tracker</strong>.</p>
<p>Finally, I saved the exported git patch as <code>bug-42424-git.patch</code> on my machine.</p>
<blockquote class="blockquote">
<p><strong>Applying git patches to Mercurial works almost perfect!</strong></p>
</blockquote>
<p>Only the second blank line in the commit message gets stripped, which is part of <a href="https://wiki.octave.org/Commit_message_guidelines">Octave’s guidelines</a>. Thus for importing git patches it is recommended to add <code>--edit</code> option</p>
<pre><code>hg import --edit bug-42424-git.patch</code></pre>
<p>to directly fix the commit message, or to call <code>hg commit --amend</code> after the import succeeded.</p>
<p>Basically, that is it.</p>
</section>
<section id="can-the-conversion-be-bettereasier" class="level1">
<h1>Can the conversion be better/easier?</h1>
<blockquote class="blockquote">
<p><em>The short answer is: Not really.</em></p>
</blockquote>
<p>In case a genuine Mercurial patch is needed, I did not find a great tool to convert git to hg patches. I succeeded using <a href="https://github.com/mozilla/moz-git-tools/">moz-git-tools</a> and shortly explain what I did. But for me this is not the “easy way” to go.</p>
<p>One can either obtain the git patch as described above, or by cloning the GitLab fork:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb4-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">git</span> clone https://gitlab.com/siko1056/octave.git octave-git</span>
<span id="cb4-2"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">cd</span> octave-git</span>
<span id="cb4-3"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">git</span> format-patch <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-1</span> HEAD <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--stdout</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> ../bug-42424-git.patch</span>
<span id="cb4-4"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">cd</span> ..</span>
<span id="cb4-5"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">cp</span> bug-42424-git.patch bug-42424-hg.patch</span>
<span id="cb4-6"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">git-patch-to-hg-patch</span>  bug-42424-hg.patch  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># moz-git-tools</span></span></code></pre></div></div>
<p>Going to the Octave Mercurial clone to apply the converted patch preserves the newline in the commit message.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb5-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">hg</span> clone https://www.octave.org/hg/octave octave-hg</span>
<span id="cb5-2"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">cd</span> octave-hg</span>
<span id="cb5-3"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">hg</span> patch ../bug-42424-hg.patch</span></code></pre></div></div>
<p>Finally, I exported the imported patch again to get an impression about the “quality” of the conversion.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb6-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">hg</span> export <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> ../bug-42424-real-hg.patch</span></code></pre></div></div>
<p>The differences between all patches can be seen in <a href="./git_hg_patch.png">this large picture</a>.</p>
<section id="summary" class="level2">
<h2 class="anchored" data-anchor-id="summary">Summary</h2>
<ul>
<li>Octave development using GitLab/GitHub is possible.</li>
<li>Sending Octave developers git patches is perfectly fine. Their application is as easy as genuine hg patches (except for the blank second line).</li>
<li>Using an intermediate conversion from git to hg patches is not worth the pain.</li>
</ul>


</section>
</section>

 ]]></description>
  <category>linux</category>
  <category>octave</category>
  <guid>https://siko1056.github.io/blog/2020/06/17/git-to-mercurial.html</guid>
  <pubDate>Wed, 17 Jun 2020 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Talk at LSPANC 2020 in Kobe, Japan</title>
  <dc:creator>Kai T. Ohlhus</dc:creator>
  <link>https://siko1056.github.io/blog/2020/01/30/lspanc-riken-talk.html</link>
  <description><![CDATA[ 





<p>My <a href="https://github.com/siko1056/slides_LSPANC_2020/">slides</a> and <a href="https://arxiv.org/abs/2004.04628">the white-paper</a> of the “Workshop on Large-scale Parallel Numerical Computing Technology” (<a href="https://www.r-ccs.riken.jp/labs/lpnctrt/lspanc2020jan/">LSPANC 2020</a>) at RIKEN.</p>
<p>The talk deals with the question, how to setup <strong>my software</strong> (with many dependencies) on <strong>other peoples</strong> systems. Two promising, with limitations combinable, tools are motivated: - <a href="https://spack.io/">spack</a> — the <em>Supercomputing Package manager</em> - <a href="https://sylabs.io/">singularity</a> — lightweight HPC container virtualization</p>



 ]]></description>
  <category>container</category>
  <category>linux</category>
  <category>octave</category>
  <category>talk</category>
  <guid>https://siko1056.github.io/blog/2020/01/30/lspanc-riken-talk.html</guid>
  <pubDate>Thu, 30 Jan 2020 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Talk about Octave at the University of Tokyo</title>
  <dc:creator>Kai T. Ohlhus</dc:creator>
  <link>https://siko1056.github.io/blog/2019/12/24/talk-about-octave.html</link>
  <description><![CDATA[ 





<p>This Christmas I had the honor to give a <a href="https://na.cs.tsukuba.ac.jp/mepa/?page_id=1689">seminar talk at the University of Tokyo</a>, which was organized by <a href="https://www2.jsiam.org/en/">JSIAM</a>.</p>
<p>The talk is an extension of a <a href="../../../../blob/2019/11/22/talk-about-octave.html">previous talk</a> given in Tokyo.</p>
<p>The topics covered are: - A brief introduction to GNU Octave (history, community) - Octave demonstrations (data I/O, plotting, m-code optimization) - Object-oriented programming with Octave - Package creation - oct-files (call Fortran/C/C++ code from Octave) - Using GNU Octave from C/C++ applications - Introduction to Octave development - Reporting bugs and getting help</p>
<p>All material, including the slides, are <a href="https://github.com/octave-de/octave_slides/releases/tag/2019-12-24">available on GitHub</a>.</p>



 ]]></description>
  <category>octave</category>
  <category>talk</category>
  <guid>https://siko1056.github.io/blog/2019/12/24/talk-about-octave.html</guid>
  <pubDate>Tue, 24 Dec 2019 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Talk: Scientific programming with GNU Octave</title>
  <dc:creator>Kai T. Ohlhus</dc:creator>
  <link>https://siko1056.github.io/blog/2019/11/22/talk-about-octave.html</link>
  <description><![CDATA[ 





<p>At the <a href="http://www.web.se.shibaura-it.ac.jp/mathsci/04-01.html">Shibaura Institute of Technology</a> I was given the opportunity to talk about GNU Octave.</p>
<p>The topics covered are: - A brief introduction to GNU Octave (history, community) - Installation on MS Windows 10 - Octave demonstrations (data I/O, plotting, m-code optimization, Fortran interface) - Brief overview of Octave development - Reporting bugs and getting help</p>
<p>All material, including the slides, are <a href="https://github.com/octave-de/octave_slides/releases/tag/2019-11-22">available on GitHub</a>.</p>



 ]]></description>
  <category>octave</category>
  <category>talk</category>
  <guid>https://siko1056.github.io/blog/2019/11/22/talk-about-octave.html</guid>
  <pubDate>Fri, 22 Nov 2019 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Protect your server using fail2ban</title>
  <dc:creator>Kai T. Ohlhus</dc:creator>
  <link>https://siko1056.github.io/blog/2019/02/07/jail2ban-setup.html</link>
  <description><![CDATA[ 





<p>While reading the <a href="https://doc.opensuse.org/documentation/leap/reference/html/book.opensuse.reference/cha.journalctl.html">system journal</a> of my server, I noticed a bunch of evil looking entries and finally found in the Python tool <a href="https://www.fail2ban.org/">fail2ban</a> a satisfying but not an overall answer to the problem.</p>
<p>The system journal can be inspected by:</p>
<pre><code>$ sudo journalctl -r

Feb 07 14:29:45 dummy sshd[763]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=XXX.XX.X.XXX  user=root
Feb 07 14:29:45 dummy sshd[764]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=YY.YYY.YY.YY  user=root
Feb 07 14:29:47 dummy sshd[760]: error: PAM: Authentication failure for root from XXX.XX.X.XXX
Feb 07 14:29:47 dummy sshd[758]: error: PAM: Authentication failure for root from YY.YYY.YY.YY
Feb 07 14:29:48 dummy sshd[765]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=YY.YYY.YY.YY  user=root
Feb 07 14:29:48 dummy sshd[766]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=XXX.XX.X.XXX  user=root
Feb 07 14:29:50 dummy sshd[758]: error: PAM: Authentication failure for root from YY.YYY.YY.YY
Feb 07 14:29:50 dummy sshd[760]: error: PAM: Authentication failure for root from XXX.XX.X.XXX
Feb 07 14:29:50 dummy sshd[767]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=YY.YYY.YY.YY  user=root
Feb 07 14:29:51 dummy sshd[768]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=XXX.XX.X.XXX  user=root
Feb 07 14:29:52 dummy sshd[758]: error: PAM: Authentication failure for root from YY.YYY.YY.YY
Feb 07 14:29:52 dummy sshd[758]: Received disconnect from YY.YYY.YY.YY port 58773:11:  [preauth]
Feb 07 14:29:52 dummy sshd[758]: Disconnected from authenticating user root YY.YYY.YY.YY port 58773 [preauth]
Feb 07 14:29:52 dummy sshd[760]: error: PAM: Authentication failure for root from XXX.XX.X.XXX
Feb 07 14:29:53 dummy sshd[760]: Postponed keyboard-interactive for root from XXX.XX.X.XXX port 19193 ssh2 [preauth]
Feb 07 14:29:53 dummy sshd[769]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=XXX.XX.X.XXX  user=root
Feb 07 14:29:56 dummy sshd[760]: error: PAM: Authentication failure for root from XXX.XX.X.XXX
Feb 07 14:29:56 dummy sshd[760]: Failed keyboard-interactive/pam for root from XXX.XX.X.XXX port 19193 ssh2
Feb 07 14:29:56 dummy sshd[760]: Postponed keyboard-interactive for root from XXX.XX.X.XXX port 19193 ssh2 [preauth]</code></pre>
<p>Two hosts (later I noticed a few more), lets call them <code>XXX.XX.X.XXX</code> and <code>YY.YYY.YY.YY</code> for now, are permanently trying to log in to my server as root.</p>
<p>Using an arbitrary <a href="https://www.whatismyip.com/ip-address-lookup/">IP-Address lookup service</a>, I was told be attacked from hosts in Asia. The country was reported as well, but it does not matter for this blog post. In my opinion the worth of this information is doubtful anyways.</p>
<p>But for now, I write about what I did and what prevented greater damage so far:</p>
<p>A good decision at server setup was to only permit logins via <a href="https://en.wikipedia.org/wiki/Public-key_cryptography">public-key cryptography</a> and not passwords. Especially <code>root</code> should <strong>never</strong> be able to login by a plain <code>ssh</code> command! To achieve this, the following entries are set in <code>/etc/ssh/sshd_config</code>:</p>
<pre><code>PermitRootLogin no
PubkeyAuthentication yes
PasswordAuthentication no</code></pre>
<p>This is in my opinion the most important layer of defense against brute force attacks. But as my system journal reveals, this is by far not enough. I don’t want my server to waste time with brute force attacks. It should simply ignore any communication with them.</p>
<p>A promising approach without writing black- or whitelists on my own is the Python software <a href="https://www.fail2ban.org/">fail2ban</a>. Like the name suggests, too many failed login attempts (= brute force attacks) automatically result in a permanent ban from my server. In general I consulted three sources for the <em>fail2ban</em> setup:</p>
<ul>
<li><a href="https://www.2daygeek.com/how-to-install-setup-configure-fail2ban-on-linux/" class="uri">https://www.2daygeek.com/how-to-install-setup-configure-fail2ban-on-linux/</a></li>
<li><a href="https://www.fail2ban.org/wiki/index.php/HOWTOs" class="uri">https://www.fail2ban.org/wiki/index.php/HOWTOs</a></li>
<li><a href="https://www.fail2ban.org/wiki/index.php/MANUAL_0_8" class="uri">https://www.fail2ban.org/wiki/index.php/MANUAL_0_8</a></li>
</ul>
<p>First one has to install the software. <em>openSUSE</em> makes this task pretty comfortable by typing</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb3-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sudo</span> zypper in fail2ban</span></code></pre></div></div>
<p>Then I edited as <code>root</code> the configuration file <code>/etc/fail2ban/jail.local</code>:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode conf code-with-copy"><code class="sourceCode toml"><span id="cb4-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Do all your modifications to the jail's configuration in jail.local!</span></span>
<span id="cb4-2"></span>
<span id="cb4-3"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">[DEFAULT]</span></span>
<span id="cb4-4"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">bantime</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">d</span></span>
<span id="cb4-5"></span>
<span id="cb4-6"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># SSH servers</span></span>
<span id="cb4-7"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">[sshd]</span></span>
<span id="cb4-8"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">enabled</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">true</span></span>
<span id="cb4-9"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">port</span>    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">ssh</span></span>
<span id="cb4-10"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">logpath</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">%(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">sshd_log</span><span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">)</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">s</span></span>
<span id="cb4-11"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">backend</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">%(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">sshd_backend</span><span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">)</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">s</span></span></code></pre></div></div>
<p>and finally started the already available service:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb5-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sudo</span> systemctl start fail2ban.service</span></code></pre></div></div>
<p>Now each suspicious login behavior will result in a one day <code>1d</code> ban. To verify this theory, there are several ways to check. The first method is to read the <em>fail2ban</em> log:</p>
<pre><code>$ sudo cat /var/log/fail2ban.log

2019-02-04 16:39:40,379 fail2ban.server         [2885]: INFO    --------------------------------------------------
2019-02-04 16:39:40,379 fail2ban.server         [2885]: INFO    Starting Fail2ban v0.10.3.fix1
2019-02-04 16:39:40,385 fail2ban.database       [2885]: INFO    Connected to fail2ban persistent database '/var/lib/fail2ban/fail2ban.sqlite3'
2019-02-04 16:39:40,386 fail2ban.database       [2885]: WARNING New database created. Version '2'
2019-02-07 14:31:02,652 fail2ban.server         [2885]: INFO    Shutdown in progress...
2019-02-07 14:31:02,652 fail2ban.server         [2885]: INFO    Stopping all jails
2019-02-07 14:31:02,652 fail2ban.database       [2885]: INFO    Connection to database closed.
2019-02-07 14:31:02,652 fail2ban.server         [2885]: INFO    Exiting Fail2ban
2019-02-07 14:31:02,737 fail2ban.server         [907]: INFO    --------------------------------------------------
2019-02-07 14:31:02,737 fail2ban.server         [907]: INFO    Starting Fail2ban v0.10.3.fix1
2019-02-07 14:31:02,739 fail2ban.database       [907]: INFO    Connected to fail2ban persistent database '/var/lib/fail2ban/fail2ban.sqlite3'
2019-02-07 14:31:02,740 fail2ban.jail           [907]: INFO    Creating new jail 'sshd'
2019-02-07 14:31:02,747 fail2ban.jail           [907]: INFO    Jail 'sshd' uses systemd {}
2019-02-07 14:31:02,748 fail2ban.jail           [907]: INFO    Initiated 'systemd' backend
2019-02-07 14:31:02,748 fail2ban.filter         [907]: INFO      maxLines: 1
2019-02-07 14:31:02,773 fail2ban.filtersystemd  [907]: INFO    [sshd] Added journal match for: '_SYSTEMD_UNIT=sshd.service + _COMM=sshd'
2019-02-07 14:31:02,773 fail2ban.filter         [907]: INFO      maxRetry: 5
2019-02-07 14:31:02,774 fail2ban.filter         [907]: INFO      encoding: UTF-8
2019-02-07 14:31:02,774 fail2ban.actions        [907]: INFO      banTime: 86400
2019-02-07 14:31:02,774 fail2ban.filter         [907]: INFO      findtime: 600
2019-02-07 14:31:02,776 fail2ban.jail           [907]: INFO    Jail 'sshd' started
2019-02-07 14:31:02,796 fail2ban.filter         [907]: INFO    [sshd] Found YY.YYY.YY.YY - 2019-02-07 14:21:03
2019-02-07 14:31:02,797 fail2ban.filter         [907]: INFO    [sshd] Found XXX.XX.X.XXX - 2019-02-07 14:21:04
... many many lines like this ...
2019-02-07 14:31:02,976 fail2ban.actions        [907]: NOTICE  [sshd] Ban YY.YYY.YY.YY
2019-02-07 14:31:03,016 fail2ban.actions        [907]: NOTICE  [sshd] Ban XXX.XX.X.XXX
2019-02-07 14:31:03,022 fail2ban.actions        [907]: WARNING [sshd] YY.YYY.YY.YY already banned
2019-02-07 14:31:03,022 fail2ban.actions        [907]: WARNING [sshd] XXX.XX.X.XXX already banned
...</code></pre>
<p>Et voilà, <code>XXX.XX.X.XXX</code> and <code>YY.YYY.YY.YY</code> misbehaved and were banned! :smile: To get even more trust and understanding in the <em>fail2ban</em> mechanism, one can take a look at <a href="https://doc.opensuse.org/documentation/leap/security/html/book.security/cha.security.firewall.html#sec.security.firewall.iptables">iptables</a>, the system tool, where <em>fail2ban</em> adds appropriate entries:</p>
<pre><code>$ sudo iptables -L

...
Chain f2b-sshd (1 references)
target  prot  opt  source        destination
REJECT  all   --   YY.YYY.YY.YY  anywhere    reject-with icmp-port-unreachable
REJECT  all   --   XXX.XX.X.XXX  anywhere    reject-with icmp-port-unreachable
...</code></pre>
<p>My system is of no such importance, that I dare write about this attack to learn from it. Maybe (and in case of critical systems hopefully) other system administrators know better and can teach me how to cope with such a delicate and mean situation.</p>
<p>All in all I hope not to be part of a botnet or similar right now and that attackers no longer find my sever to be a patient listener :wink:</p>



 ]]></description>
  <category>linux</category>
  <category>web</category>
  <guid>https://siko1056.github.io/blog/2019/02/07/jail2ban-setup.html</guid>
  <pubDate>Thu, 07 Feb 2019 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Setting up JupyterHub on openSUSE Leap 15.0</title>
  <dc:creator>Kai T. Ohlhus</dc:creator>
  <link>https://siko1056.github.io/blog/2019/01/11/jupyterhub-installation.html</link>
  <description><![CDATA[ 





<p>In a <a href="../../../../blog/2018/06/25/apache2-leap-15-0.html">previous blog post</a> the setup of the Apache2 webserver including <a href="https://en.wikipedia.org/wiki/Transport_Layer_Security">TLS</a> was explained. Based upon that effort, this blog post deals with the setup of <a href="https://jupyter.org/hub">JupyterHub</a>. The goal is to create an online development environment for fancy looking interactive <a href="https://www.octave.org">GNU Octave</a> notebooks. Those are a great tool for explaining mathematical code and software as they have builtin support for syntax-highlighting and, thanks to <a href="https://www.mathjax.org/">MathJax</a>, mathematics.</p>
<p>Before we start, lets shortly review three <a href="https://jupyter.org/documentation">“Jupyter-terms”</a> often mentioned in this blog post:</p>
<ul>
<li><strong>Jupyter</strong>:
<ul>
<li>A single-user <a href="https://jupyter.org/">Jupyter server</a> that can also be <a href="https://jupyter.readthedocs.io/en/latest/install.html">installed</a> and run locally on your own machine.</li>
<li>The <a href="https://jupyter-notebook.readthedocs.io/en/stable/notebook.html">classical</a> user (notebook) interface (a.k.a. <code>/tree</code>, see later why).</li>
</ul></li>
<li>Jupyter<strong>Lab</strong>:
<ul>
<li>The <a href="https://jupyterlab.readthedocs.io/">modern</a> user (notebook) interface (a.k.a. <code>/lab</code>).</li>
</ul></li>
<li>Jupyter<strong>Hub</strong>:
<ul>
<li>A multi-user <a href="https://jupyterhub.readthedocs.io/">Jupyter server</a>.</li>
</ul></li>
</ul>
<p>In one sentence, the goal is to setup a public JupyterHub-Server to run for certain predefined small group of users a Jupyter instance with the modern JupyterLab interface.</p>
<section id="install-required-python-software" class="level2">
<h2 class="anchored" data-anchor-id="install-required-python-software">Install required Python-software</h2>
<p>The installation might require admin (<code>sudo</code>) privileges:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb1-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">pip3</span> install <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--upgrade</span> pip jupyterlab <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb1-2">                           jupyterhub <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb1-3">                           oauthenticator <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb1-4">                           octave_kernel</span></code></pre></div></div>
<p>Finally, one can check the installation by starting a local single-user Jupyter server with the JupyterLab interface:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb2-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">jupyter</span> lab</span></code></pre></div></div>
</section>
<section id="configuring-the-public-jupyterhub-server" class="level2">
<h2 class="anchored" data-anchor-id="configuring-the-public-jupyterhub-server">Configuring the public JupyterHub server</h2>
<p>In the desired setup all configuration files for the server are located at <code>/srv/www/jupyterhub</code> and the server should be accessible by the public via <code>https://www.domain.org:8888</code> as explained in a <a href="../../../../blog/2018/06/25/apache2-leap-15-0.html">previous blog post</a>.</p>
<p>A good starting point is to create a default configuration file that can be modified:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb3-1"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">cd</span> /srv/www/jupyterhub</span>
<span id="cb3-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">jupyterhub</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--generate-config</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-f</span> jupyterhub_config.py</span></code></pre></div></div>
<p>The following options must be changed in <code>jupyterhub_config.py</code> to achieve the desired JupyterHub-server setup: - the port <code>c.JupyterHub.port = 8888</code>, - the location of the TLS-keys which are already established for the Apache2 webserver <code>python   c.JupyterHub.ssl_cert = '/etc/certbot/live/domain.org/fullchain.pem'   c.JupyterHub.ssl_key = '/etc/certbot/live/domain.org/privkey.pem'</code> - and the usage of the modern JupyterLab interface <code>python   c.Spawner.cmd = ['jupyter-labhub']   c.Spawner.default_url = '/lab'</code></p>
<p>Now one can test the public installation by starting JupyterHub with the custom configuration:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb4-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">jupyterhub</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--config</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>/srv/www/jupyterhub/jupyterhub_config.py</span></code></pre></div></div>
<p>If you want to give the classical notebook interface a try, just replace <code>/lab</code> by <code>/tree</code>:</p>
<pre><code>https://domain.org:8888/user/localUser/lab?
                                      /tree?</code></pre>
</section>
<section id="authenticate-users" class="level2">
<h2 class="anchored" data-anchor-id="authenticate-users">Authenticate users</h2>
<p>In general JupyterHub delegates the user authentication to some <code>authenticator_class</code>. By default this is the <a href="https://jupyterhub.readthedocs.io/en/stable/api/auth.html">PAMAuthenticator</a>, that just makes use of the authentication mechanism of the underlying server operating system:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb6-1">c.JupyterHub.authenticator_class <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'jupyterhub.auth.PAMAuthenticator'</span></span></code></pre></div></div>
<p>This has a serious impact: One does not only login to some sandboxed PHP-application (like a MediaWiki), one literally logs into the server! From Jupyter you can start a terminal window and can do any damage you could do from a ssh-login with your given user permissions. Keep this in mind.</p>
<p>If the desired setup demands more security, one should run Jupyter within some virtualization environment. But for my purpose using Docker, Kubernetes, or alike seems too bloated for a couple of predefined users.</p>
<p>To further control and restrict the user authentication, JupyterHub offers features such as a whitelist and a list of admin users:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb7-1">c.Authenticator.admin_users <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> {<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'localUser'</span>}</span>
<span id="cb7-2">c.Authenticator.whitelist <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> {<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'localUser'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'localUser2'</span>}</span></code></pre></div></div>
<p>For more options, see <a href="https://jupyterhub.readthedocs.io/en/stable/api/auth.html" class="uri">https://jupyterhub.readthedocs.io/en/stable/api/auth.html</a>. Unfortunately, those lists <a href="https://github.com/jupyterhub/jupyterhub/issues/1920">cannot be altered at runtime</a>. Of course one can create custom Python-classes, if needed.</p>
<p>Another problem is that I don’t want users to login on my server via password at all. Fortunately, <a href="https://github.com/jupyterhub/oauthenticator">OAuthenticator</a> provides several OAuth 2.0 based <code>authenticator_class</code>es. Among them:</p>
<ul>
<li><p>GitHub</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb8-1"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> oauthenticator.github <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> GitHubOAuthenticator</span>
<span id="cb8-2">c.JupyterHub.authenticator_class <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> GitHubOAuthenticator</span>
<span id="cb8-3">c.GitHubOAuthenticator.oauth_callback_url <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'https://domain.org:8888/hub/oauth_callback'</span></span>
<span id="cb8-4">c.GitHubOAuthenticator.client_id <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'xxxxxxxxxxxxxxxxxxxxxx'</span></span>
<span id="cb8-5">c.GitHubOAuthenticator.client_secret <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'xxxxxxxxxxxxxxxxxx'</span></span></code></pre></div></div></li>
<li><p>Google</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb9-1"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> oauthenticator.google <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> GoogleOAuthenticator</span>
<span id="cb9-2">c.JupyterHub.authenticator_class <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> GoogleOAuthenticator</span>
<span id="cb9-3">c.GoogleOAuthenticator.oauth_callback_url <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'https://domain.org:8888/hub/oauth_callback'</span></span>
<span id="cb9-4">c.GoogleOAuthenticator.client_id <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'xxxxxxxxxxxxxxxxxxxxxx'</span></span>
<span id="cb9-5">c.GoogleOAuthenticator.client_secret <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'xxxxxxxxxxxxxxxxxx'</span></span></code></pre></div></div></li>
</ul>
<p>Especially for Google it makes sense to map the authenticated user to a local server account:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb10" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb10-1">c.Authenticator.username_map <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> {<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'local.user@gmail.com'</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'localUser'</span>}</span></code></pre></div></div>
<p>But again, this map cannot be altered without restarting the JupyterHub server.</p>
<p>To sum up: New users (for example new colleagues) cannot be created on the fly by using the here described setup. This requires:</p>
<ol type="1">
<li><p>Creating a new local user account on the server</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb11" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb11-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">useradd</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--create-home</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--gid</span> jupyterhub <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>new colleague<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span></code></pre></div></div></li>
<li><p>whitelist that local user account <code>c.Authenticator.whitelist</code>.</p></li>
<li><p>Map that local user account to the OAuth 2.0 authenticated user name <code>c.Authenticator.username_map</code>.</p></li>
<li><p>Restart JupytherHub.</p></li>
</ol>
<p>On the other hand, not every user with a valid GitHub or Google account can log in the server.</p>
</section>
<section id="making-jupyterhub-a-system-service" class="level2">
<h2 class="anchored" data-anchor-id="making-jupyterhub-a-system-service">Making JupyterHub a system service</h2>
<p>The final target is to make the JupyterHub server run, even if you are logged out from your remote server.</p>
<p>There are other options such as running JupyterHub inside a <a href="https://www.gnu.org/software/screen/">screen</a>-session that does not shutdown when the connection to the server is terminated. But personally I prefer the solution of creating a system service:</p>
<ol type="1">
<li>A service starts after each reboot when enabled.</li>
<li>A service can be logged by <code>syslog</code>.</li>
<li>A service runs in the background and cannot accidentally be shutdown while maintaining the system.</li>
</ol>
<p>To create a service, just create a file <code>/srv/www/jupyterhub/jupyterhub.service</code> with the following content:</p>
<pre><code>[Unit]
Description=JupyterHub
After=apache2.target

[Service]
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=jupyterhub
ExecStart=/usr/bin/jupyterhub --config=/srv/www/jupyterhub/jupyterhub_config.py
WorkingDirectory=/srv/www/jupyterhub

[Install]
WantedBy=multi-user.target</code></pre>
<p>The service file has to be copied to the standard location and the file should be owned by <code>root</code>:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb13" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb13-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sudo</span> chown root:root /srv/www/jupyterhub/jupyterhub.service</span>
<span id="cb13-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sudo</span> cp /srv/www/jupyterhub/jupyterhub.service /etc/systemd/system/jupyterhub.service</span></code></pre></div></div>
<p>Now one can use the standard mechanisms to start and stop JupyterHub as system service:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb14" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb14-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sudo</span> systemctl enable jupyterhub  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Start service at system boot.</span></span>
<span id="cb14-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sudo</span> systemctl start  jupyterhub</span>
<span id="cb14-3"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sudo</span> systemctl stop   jupyterhub</span></code></pre></div></div>
<p>and the server log can be inspected by</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb15" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb15-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sudo</span> journalctl <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-u</span> jupyterhub</span></code></pre></div></div>
</section>
<section id="further-reading" class="level2">
<h2 class="anchored" data-anchor-id="further-reading">Further reading</h2>
<p>This blog post was greatly inspired by <a href="https://pythonforundergradengineers.com/add-google-oauth-and-system-service-to-jupyterhub.html" class="uri">https://pythonforundergradengineers.com/add-google-oauth-and-system-service-to-jupyterhub.html</a></p>
</section>
<section id="update-2019-01-13" class="level2">
<h2 class="anchored" data-anchor-id="update-2019-01-13">Update 2019-01-13</h2>
<ul>
<li><p>In the file <code>/srv/www/jupyterhub/jupyterhub.service</code></p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb16" style="background: #f1f3f5;"><pre class="sourceCode diff code-with-copy"><code class="sourceCode diff"><span id="cb16-1">[Unit]</span>
<span id="cb16-2"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">-After=network.target nss-lookup.target</span></span>
<span id="cb16-3"><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">+After=apache2.target</span></span></code></pre></div></div>
<p>and rather copy that file to <code>/etc/systemd/system/</code> instead of just linking it. Occasionally I noticed that JupyterHub did not start automatically, as the location <code>/srv/www/jupyterhub/</code> was not available to systemd on time.</p></li>
</ul>


</section>

 ]]></description>
  <category>linux</category>
  <category>web</category>
  <guid>https://siko1056.github.io/blog/2019/01/11/jupyterhub-installation.html</guid>
  <pubDate>Fri, 11 Jan 2019 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Setting up an apache2 webserver on openSUSE Leap 15.0</title>
  <dc:creator>Kai T. Ohlhus</dc:creator>
  <link>https://siko1056.github.io/blog/2018/06/25/apache2-leap-15-0.html</link>
  <description><![CDATA[ 





<p>The goal of this blog post is to properly remember what I did to create my root-server setup using <a href="https://software.opensuse.org/distributions/leap">openSUSE Leap 15.0</a>:</p>
<ul>
<li><a href="https://httpd.apache.org/">Apache web server</a> with HTTPS support, running
<ul>
<li>Static websites
<ul>
<li><a href="https://www.mkdocs.org/">MkDocs</a></li>
</ul></li>
<li>Dynamic websites (PHP, mySQL)
<ul>
<li><a href="https://www.mediawiki.org/">MediaWiki</a></li>
</ul></li>
</ul></li>
<li><a href="https://jupyterlab.readthedocs.io/en/stable/">Jupyterlab</a></li>
</ul>
<p>Two detailed and very useful references for a start are:</p>
<ul>
<li><a href="https://en.opensuse.org/SDB:LAMP_setup" class="uri">https://en.opensuse.org/SDB:LAMP_setup</a></li>
<li><a href="https://en.opensuse.org/Let%E2%80%99s_Encrypt" class="uri">https://en.opensuse.org/Let%E2%80%99s_Encrypt</a></li>
<li><a href="https://doc.opensuse.org/documentation/leap/reference/html/book.opensuse.reference/cha.apache2.html" class="uri">https://doc.opensuse.org/documentation/leap/reference/html/book.opensuse.reference/cha.apache2.html</a></li>
</ul>
<p>Here there are just the bare commands without verbose explanation given. All of them should be run with root privileges.</p>
<section id="basic-webserver-setup" class="level2">
<h2 class="anchored" data-anchor-id="basic-webserver-setup">Basic webserver setup</h2>
<ul>
<li><p>Install the required packages:</p>
<pre><code>zypper install apache2 \
               php7 php7-mysql apache2-mod_php7 \
               mariadb mariadb-tools \
               phpMyAdmin</code></pre></li>
<li><p>Enable Apache modules:</p>
<pre><code>a2enmod php7 rewrite</code></pre></li>
<li><p>Open the necessary ports in the Firewall (<code>firewalld</code>):</p>
<pre><code>firewall-cmd --permanent --zone=public --add-service=http --add-service=https
firewall-cmd --permanent --zone=public --add-port=8888/tcp  # For Jupyter only!
firewall-cmd --reload</code></pre></li>
<li><p>Start and enable (on each restart) all services:</p>
<pre><code>systemctl start  apache2 mysql
systemctl enable apache2 mysql</code></pre></li>
<li><p>Configure the mySQL database and follow the instructions given:</p>
<pre><code>mysql_secure_installation</code></pre></li>
</ul>
</section>
<section id="setting-up-the-directories" class="level2">
<h2 class="anchored" data-anchor-id="setting-up-the-directories">Setting up the directories</h2>
<p>The used directory structure for the websites and services is as follows:</p>
<pre><code>/srv/www/myMkDocsSite  (https://www.domain.org/)
        /myMediaWiki   (https://wiki.domain.org/)
        /jupyter       (https://www.domain.org:8888)</code></pre>
<p>As Jupyter comes with it’s own web server, one only has to add Apache2 configurations for <code>myMkDocsSite</code> and <code>myMediaWiki</code>. Those configuration files are located in the</p>
<pre><code>/etc/apache2/vhosts.d</code></pre>
<p>directory and have the <code>*.conf</code> extension. The <code>myMkDocsSite.conf</code> may look like this:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode html code-with-copy"><code class="sourceCode html"><span id="cb8-1"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">VirtualHost</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;"> *:80</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb8-2">    DocumentRoot "/srv/www/myMkDocsSite"</span>
<span id="cb8-3">    ServerName www.domain.org</span>
<span id="cb8-4">    ServerAlias domain.org</span>
<span id="cb8-5">    ServerAdmin joe@mail.com</span>
<span id="cb8-6">    ErrorLog /var/log/apache2/error_log</span>
<span id="cb8-7">    TransferLog /var/log/apache2/access_log</span>
<span id="cb8-8">    HostnameLookups Off</span>
<span id="cb8-9">    UseCanonicalName Off</span>
<span id="cb8-10">    ServerSignature Off</span>
<span id="cb8-11">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Directory</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;"> </span><span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">"/</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">srv</span><span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">/</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">www</span><span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">/</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">octave.space</span><span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">"</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb8-12">        Options Indexes FollowSymLinks</span>
<span id="cb8-13">        AllowOverride None</span>
<span id="cb8-14">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">IfModule</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;"> </span><span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">!</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">mod_access_compat.c</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb8-15">            Require all granted</span>
<span id="cb8-16">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">&lt;/</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">IfModule</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb8-17">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">IfModule</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;"> mod_access_compat.c</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb8-18">            Order allow,deny</span>
<span id="cb8-19">            Allow from all</span>
<span id="cb8-20">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">&lt;/</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">IfModule</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb8-21">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">&lt;/</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Directory</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb8-22"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">&lt;/</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">VirtualHost</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">&gt;</span></span></code></pre></div></div>
<p>Remember, that for dynamic websites the Apache2 server process might need write privileges. Therefore the owner of the respective directories should be <code>wwwrun</code> and can be set with:</p>
<pre><code>chown -R wwwrun:www &lt;directory&gt;</code></pre>
<p>Now the content of a file <code>index.html</code> should be displayed when typing “http://www.domain.org/” (note: HTTPS comes later!).</p>
</section>
<section id="webserver-https-setup" class="level2">
<h2 class="anchored" data-anchor-id="webserver-https-setup">Webserver HTTPS setup</h2>
<p>Fortunately, these days one has not to pay to be able to use the HTTPS protocol, one can easily make use of services like the <a href="https://letsencrypt.org/">Let’s encrypt</a> project.</p>
<ul>
<li><p>Install the required packages:</p>
<pre><code>zypper install certbot python-certbot python-certbot-apache</code></pre></li>
<li><p>Enable the SSL module and ensure the correct server flags:</p>
<pre><code>a2enmod ssl
a2enflag SSL</code></pre></li>
<li><p>Get the certificate by following the output of:</p>
<pre><code>certbot --apache</code></pre>
<p>This command usually updates the Apache2 configuration file, e.g.&nbsp;<code>myMkDocsSite.conf</code> above. If there are more websites, just call the <code>certbot</code> command above again to extend the certificate.</p></li>
<li><p>Update the certificate regulary by establishing a cronjob:</p>
<pre><code>crontab -e</code></pre>
<p>and add the lines:</p>
<pre><code># renew all certificates methode: renew
10 5 1 * *  root    /usr/bin/certbot renew</code></pre></li>
</ul>
</section>
<section id="mediawiki-setup" class="level2">
<h2 class="anchored" data-anchor-id="mediawiki-setup">Mediawiki setup</h2>
<p>To setup a <a href="https://www.mediawiki.org/">Mediawiki</a> one can basically follow the <a href="https://www.mediawiki.org/wiki/Installation">installation guide</a>. Additionally, the following extensions should be installed:</p>
<ul>
<li><a href="https://www.mediawiki.org/wiki/Extension:MobileFrontend" class="uri">https://www.mediawiki.org/wiki/Extension:MobileFrontend</a></li>
<li><a href="https://www.mediawiki.org/wiki/Extension:Math" class="uri">https://www.mediawiki.org/wiki/Extension:Math</a></li>
</ul>
<p>With openSUSE Leap, the following extra packages are useful to be installed for all the above:</p>
<pre><code>zypper install git ImageMagick make \
               php7-APCu php7-fileinfo php7-imagick php7-intl php7-mbstring</code></pre>
<p>After that run</p>
<pre><code>php myMediaWiki/maintenance/update.php</code></pre>
<p>to update the MediaWiki database for that extension.</p>


</section>

 ]]></description>
  <category>linux</category>
  <category>web</category>
  <guid>https://siko1056.github.io/blog/2018/06/25/apache2-leap-15-0.html</guid>
  <pubDate>Mon, 25 Jun 2018 00:00:00 GMT</pubDate>
</item>
</channel>
</rss>
