<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://xiyivan.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://xiyivan.github.io/" rel="alternate" type="text/html" /><updated>2026-06-21T14:32:40+00:00</updated><id>https://xiyivan.github.io/feed.xml</id><title type="html">Yifan’s blog</title><subtitle>Documenting thoughts, progress, stories and achievements.</subtitle><entry><title type="html">memo for fortran commands</title><link href="https://xiyivan.github.io/tech/2026/05/30/fortran-command-memo.html" rel="alternate" type="text/html" title="memo for fortran commands" /><published>2026-05-30T17:11:00+00:00</published><updated>2026-05-30T17:11:00+00:00</updated><id>https://xiyivan.github.io/tech/2026/05/30/fortran-command-memo</id><content type="html" xml:base="https://xiyivan.github.io/tech/2026/05/30/fortran-command-memo.html"><![CDATA[<p>After a few days of Fortran programming, I found a record of commonly used Fortran commands need to be kept, as there are subtle differences between Fortran and other languages I have used in the past.</p>

<h1 id="terminal-commands">Terminal Commands</h1>

<p>Simple compilation</p>
<div class="language-zsh highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gfortran my_program.f90 <span class="nt">-o</span> my_program
</code></pre></div></div>

<p>Compiling only</p>
<div class="language-zsh highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gfortran <span class="nt">-c</span> my_program.f90
</code></pre></div></div>

<p>Multi-thread compilation</p>
<div class="language-zsh highlighter-rouge"><div class="highlight"><pre class="highlight"><code>caf my_program.f90 <span class="nt">-o</span> my_program
</code></pre></div></div>

<p>Multi-thread execution</p>
<div class="language-zsh highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cafrun <span class="nt">-n</span> x ./my_program
</code></pre></div></div>
<p>where x is the number of images</p>

<p><strong>note</strong></p>
<ul>
  <li><code class="language-plaintext highlighter-rouge">$!</code> can be used to speed up command typing</li>
</ul>

<h1 id="fortran-commands">Fortran commands</h1>

<h2 id="variable-initialization">Variable initialization</h2>

<h3 id="initialization-statement">Initialization statement</h3>

<p>single variable initialization</p>
<div class="language-fortran highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">data_type</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">variable_name</span><span class="w">
</span></code></pre></div></div>

<p>Array initialization</p>
<div class="language-fortran highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">data_type</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">array_name</span><span class="p">(</span><span class="n">n</span><span class="p">)</span><span class="w">
</span><span class="n">data_type</span><span class="p">,</span><span class="w"> </span><span class="k">dimension</span><span class="p">(</span><span class="n">n</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">array_name</span><span class="w">
</span></code></pre></div></div>
<p>Finally don’t need to indexing with (y, x) lol</p>

<p>Coarray initialization</p>
<div class="language-fortran highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">data_type</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">array_name</span><span class="p">(</span><span class="n">n</span><span class="p">)[</span><span class="o">*</span><span class="p">]</span><span class="w">
</span></code></pre></div></div>

<p>Constant initialization</p>
<div class="language-fortran highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">data_type</span><span class="p">,</span><span class="w"> </span><span class="k">parameter</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">const_name</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">xxx</span><span class="w">
</span></code></pre></div></div>

<h3 id="variable-type">Variable type</h3>

<div class="language-fortran highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">integer</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">i</span><span class="p">,</span><span class="w"> </span><span class="n">n</span><span class="w">
</span><span class="kt">real</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">x</span><span class="w">
</span><span class="kt">complex</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="n">a</span><span class="p">,</span><span class="w"> </span><span class="n">b</span><span class="p">)</span><span class="w">
</span></code></pre></div></div>

<p><strong>note</strong></p>
<ul>
  <li>a constant can be used to initialize other variables</li>
  <li>constant’s value must be provided on initialization</li>
</ul>

<p>specific kind of variable</p>
<div class="language-fortran highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">use</span><span class="w"> </span><span class="n">iso_fortran_env</span><span class="w">
</span><span class="kt">integer</span><span class="p">(</span><span class="nb">kind</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">int32</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">n</span><span class="w">
</span></code></pre></div></div>

<h2 id="control-flow-statements">Control flow statements</h2>

<p>if statement</p>
<div class="language-fortran highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">condition</span><span class="p">)</span><span class="w"> </span><span class="c1">!...</span><span class="w">

</span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">condition</span><span class="p">)</span><span class="w"> </span><span class="k">then</span><span class="w">
    </span><span class="c1">!...</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">if</span><span class="w">

</span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">condition</span><span class="p">)</span><span class="w"> </span><span class="k">then</span><span class="w">
    </span><span class="c1">!...</span><span class="w">
</span><span class="k">else</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">other_condition</span><span class="p">)</span><span class="w"> </span><span class="k">then</span><span class="w">
    </span><span class="c1">!...</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">if</span><span class="w">
</span></code></pre></div></div>

<p>do loop</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>do n = start, end
    !...
end do

do n = start, end, increment
    !...
end do

!named loop
outer_loop: do j = 1, jm
    inner_loop: do i = 1, im
        !...
    end do inner_loop
end do outer_loop
</code></pre></div></div>

<h2 id="fortran-program-units">Fortran program units</h2>
<p><strong>program</strong>: the only unit can be invoked as an executable from the operating system</p>
<div class="language-fortran highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">program</span><span class="w"> </span><span class="n">xxx</span><span class="w">
    </span><span class="k">implicit</span><span class="w"> </span><span class="k">none</span><span class="w"> 
    </span><span class="kt">integer</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">a</span><span class="p">,</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="c1">!declaration of variables</span><span class="w">

    </span><span class="k">if</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="k">call</span><span class="w"> </span><span class="n">add</span><span class="p">(</span><span class="n">a</span><span class="p">,</span><span class="w"> </span><span class="n">b</span><span class="p">)</span><span class="w"> </span><span class="c1">!invoke a subroutine</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">program</span><span class="w">
</span></code></pre></div></div>

<p><strong>function</strong>: Invoked in expressions, return only one value.</p>
<div class="language-fortran highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">function</span><span class="w"> </span><span class="nb">sum</span><span class="p">(</span><span class="n">a</span><span class="p">,</span><span class="n">b</span><span class="p">)</span><span class="w">
    </span><span class="kt">integer</span><span class="p">,</span><span class="w"> </span><span class="k">intent</span><span class="p">(</span><span class="k">in</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">a</span><span class="p">,</span><span class="w"> </span><span class="n">b</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="nb">sum</span><span class="w">

    </span><span class="nb">sum</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">b</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">function</span><span class="w"> </span><span class="nb">sum</span><span class="w">
</span></code></pre></div></div>
<p>OR</p>
<div class="language-fortran highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">integer</span><span class="w"> </span><span class="k">function</span><span class="w"> </span><span class="nb">sum</span><span class="p">(</span><span class="n">a</span><span class="p">,</span><span class="n">b</span><span class="p">)</span><span class="w">
    </span><span class="kt">integer</span><span class="p">,</span><span class="w"> </span><span class="k">intent</span><span class="p">(</span><span class="k">in</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">a</span><span class="p">,</span><span class="w"> </span><span class="n">b</span><span class="w">
    </span><span class="c1">! no need to define sum</span><span class="w">

    </span><span class="nb">sum</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">b</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">function</span><span class="w"> </span><span class="nb">sum</span><span class="w">
</span></code></pre></div></div>
<p>OR</p>
<div class="language-fortran highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">integer</span><span class="w"> </span><span class="k">function</span><span class="w"> </span><span class="nb">sum</span><span class="p">(</span><span class="n">a</span><span class="p">,</span><span class="n">b</span><span class="p">)</span><span class="w"> </span><span class="n">results</span><span class="p">(</span><span class="n">res</span><span class="p">)</span><span class="w">
    </span><span class="kt">integer</span><span class="p">,</span><span class="w"> </span><span class="k">intent</span><span class="p">(</span><span class="k">in</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">a</span><span class="p">,</span><span class="n">b</span><span class="w">

    </span><span class="n">res</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">a</span><span class="o">+</span><span class="n">b</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">function</span><span class="w"> </span><span class="nb">sum</span><span class="w">
</span></code></pre></div></div>

<p><strong>subroutine</strong>: Invoked with a <code class="language-plaintext highlighter-rouge">call</code> statement.</p>
<div class="language-fortran highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">subroutine</span><span class="w"> </span><span class="n">add</span><span class="p">(</span><span class="n">a</span><span class="p">,</span><span class="n">b</span><span class="p">)</span><span class="w">
    </span><span class="kt">integer</span><span class="p">,</span><span class="w"> </span><span class="k">intent</span><span class="p">(</span><span class="k">inout</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">a</span><span class="w">
    </span><span class="kt">integer</span><span class="p">,</span><span class="w"> </span><span class="k">intent</span><span class="p">(</span><span class="k">in</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">b</span><span class="w">
    </span><span class="n">a</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">a</span><span class="o">+</span><span class="n">b</span><span class="w">
    </span><span class="k">print</span><span class="w"> </span><span class="o">*</span><span class="p">,</span><span class="w"> </span><span class="s1">'a='</span><span class="p">,</span><span class="w"> </span><span class="n">a</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">subroutine</span><span class="w"> </span><span class="n">add</span><span class="w">
</span></code></pre></div></div>
<h3 id="attributes">Attributes</h3>
<p><strong>pure</strong> : indicate the function has no side effects. This includes modifying the value of a variable declared outside the procedure.</p>

<p><strong>elemental</strong> : allows receiving array arguments in place of scalars</p>

<div class="language-fortran highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">pure</span><span class="w"> </span><span class="k">elemental</span><span class="w"> </span><span class="kt">integer</span><span class="w"> </span><span class="k">function</span><span class="w"> </span><span class="nb">sum</span><span class="p">(</span><span class="n">a</span><span class="p">,</span><span class="n">b</span><span class="p">)</span><span class="w">
    </span><span class="kt">integer</span><span class="p">,</span><span class="w"> </span><span class="k">intent</span><span class="p">(</span><span class="k">in</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">a</span><span class="p">,</span><span class="w"> </span><span class="n">b</span><span class="w">
    </span><span class="nb">sum</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">a</span><span class="o">+</span><span class="n">b</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">function</span><span class="w"> </span><span class="nb">sum</span><span class="w">

</span><span class="nb">sum</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">],</span><span class="w"> </span><span class="mi">3</span><span class="p">)</span><span class="w"> </span><span class="c1">! is valid</span><span class="w">
</span><span class="nb">sum</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">],</span><span class="w"> </span><span class="p">[</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">])</span><span class="w"> </span><span class="c1">! is valid</span><span class="w">
</span><span class="nb">sum</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">],</span><span class="w"> </span><span class="p">[</span><span class="mi">4</span><span class="p">,</span><span class="mi">5</span><span class="p">])</span><span class="w"> </span><span class="c1">! is not valid as arrays are not of the same shape.</span><span class="w">
</span></code></pre></div></div>

<p><strong>optional argument</strong></p>
<div class="language-fortran highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">subroutine</span><span class="w"> </span><span class="n">add</span><span class="p">(</span><span class="n">a</span><span class="p">,</span><span class="w"> </span><span class="n">b</span><span class="p">,</span><span class="w"> </span><span class="n">res</span><span class="p">,</span><span class="w"> </span><span class="n">debug</span><span class="p">)</span><span class="w">
    </span><span class="kt">integer</span><span class="p">,</span><span class="w"> </span><span class="k">intent</span><span class="p">(</span><span class="k">in</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">a</span><span class="p">,</span><span class="w"> </span><span class="n">b</span><span class="w">
    </span><span class="kt">integer</span><span class="p">,</span><span class="w"> </span><span class="k">intent</span><span class="p">(</span><span class="k">out</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">res</span><span class="w">
    </span><span class="kt">logical</span><span class="p">,</span><span class="w"> </span><span class="k">intent</span><span class="p">(</span><span class="k">in</span><span class="p">),</span><span class="w"> </span><span class="k">optional</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">debug</span><span class="w">

    </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nb">present</span><span class="p">(</span><span class="n">debug</span><span class="p">))</span><span class="w"> </span><span class="k">then</span><span class="w">
        </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">debug</span><span class="p">)</span><span class="w"> </span><span class="k">then</span><span class="w">
            </span><span class="c1">!...</span><span class="w">
        </span><span class="k">end</span><span class="w"> </span><span class="k">if</span><span class="w">
    </span><span class="k">end</span><span class="w"> </span><span class="k">if</span><span class="w">

    </span><span class="n">res</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">b</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">subroutine</span><span class="w"> </span><span class="n">add</span><span class="w">
</span></code></pre></div></div>

<h2 id="modules">modules</h2>

<p>import module</p>
<div class="language-fortran highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">use</span><span class="w"> </span><span class="n">iso_fortran_env</span><span class="p">,</span><span class="w"> </span><span class="k">only</span><span class="p">:</span><span class="w"> </span><span class="n">int32</span><span class="p">,</span><span class="w"> </span><span class="n">real32</span><span class="w">
</span></code></pre></div></div>

<p><strong>rename entity when import</strong></p>
<div class="language-fortran highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">use</span><span class="w"> </span><span class="n">mod_atmosphere</span><span class="p">,</span><span class="w"> </span><span class="k">only</span><span class="p">:</span><span class="w"> </span><span class="n">temperature</span><span class="w">
</span><span class="k">use</span><span class="w"> </span><span class="n">mod_ocean</span><span class="p">,</span><span class="w"> </span><span class="k">only</span><span class="p">:</span><span class="w"> </span><span class="n">temperature_ocean</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="n">temperature</span><span class="p">,</span><span class="w"> </span><span class="n">velocity_ocean</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="n">velocity</span><span class="w">

</span></code></pre></div></div>

<p>=&gt; means point to</p>

<p><strong>Module variable</strong></p>
<div class="language-fortran highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">module</span><span class="w"> </span><span class="n">mod_circle</span><span class="w">
    </span><span class="k">implicit</span><span class="w"> </span><span class="k">none</span><span class="w">
    </span><span class="k">private</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">pi</span><span class="w">
    </span><span class="kt">real</span><span class="p">,</span><span class="w"> </span><span class="k">parameter</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">pi</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">3.14159265</span><span class="w">
</span><span class="k">contains</span><span class="w">
    </span><span class="c1">!...</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">module</span><span class="w"> </span><span class="n">mod_circle</span><span class="w">
</span></code></pre></div></div>

<h1 id="parallel-programming-commands">Parallel programming commands</h1>

<h2 id="parallel-programming-image-indexing">Parallel programming image indexing</h2>

<p>get current image number</p>
<div class="language-fortran highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">this_image</span><span class="p">()</span><span class="w">
</span></code></pre></div></div>

<p>get total image number</p>
<div class="language-fortran highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">num_images</span><span class="p">()</span><span class="w">
</span></code></pre></div></div>

<p>wait and sync</p>
<div class="language-fortran highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">sync all</span><span class="w">
</span></code></pre></div></div>

<h2 id="parallel-programming-flow-statements">Parallel programming flow statements</h2>

<p>embarrassingly parallel iteration</p>
<div class="language-fortran highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">do</span><span class="w"> </span><span class="k">concurrent</span><span class="w"> </span><span class="p">(</span><span class="n">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">:</span><span class="n">grid_size</span><span class="p">)</span><span class="w">
    </span><span class="c1">!...</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
</span></code></pre></div></div>]]></content><author><name></name></author><category term="tech" /><summary type="html"><![CDATA[After a few days of Fortran programming, I found a record of commonly used Fortran commands need to be kept, as there are subtle differences between Fortran and other languages I have used in the past.]]></summary></entry><entry><title type="html">opencoarray吐槽向</title><link href="https://xiyivan.github.io/tech/2026/05/27/opencoarray-shit-mountain.html" rel="alternate" type="text/html" title="opencoarray吐槽向" /><published>2026-05-27T22:03:00+00:00</published><updated>2026-05-27T22:03:00+00:00</updated><id>https://xiyivan.github.io/tech/2026/05/27/opencoarray-shit-mountain</id><content type="html" xml:base="https://xiyivan.github.io/tech/2026/05/27/opencoarray-shit-mountain.html"><![CDATA[<p>今天在尝试并行计算，需要用到opencoarray。原本计划使用开源链gfortran + openmpi + opencoarray. 在安装aur中的opencoarray时发现 opencoarray 在 openmpi V15 后不再支持openmpi，因为openmpi 无法满足全局统一ID的需求 <a href="https://github.com/open-mpi/ompi/issues/13385">open-mpi issue</a>. 于是转向 mpich（不知为何还满足这个特性）。编译并安装mpich后发现 mpich的可执行文件都放在了/opt/mpich/bin/ 而不是/usr/bin/,导致<a href="https://aur.archlinux.org/packages/opencoarrays-mpich-git">opencoarrays-mpich-git|aur</a>无法自动化安装。于是转而从github源码开始编译并直接使用<code class="language-plaintext highlighter-rouge">FC=mpif90</code>制定mpich。同时这个位置导致cafrun无法找到mpiexec让我又重新编译了一下（～——～）。</p>

<p>令人吐槽的点</p>
<ul>
  <li>opencoarray一直架在一个并非mpi协议规定的特性上</li>
  <li>mpich 非标准目录结构</li>
  <li>opencoarray的古早CMakeList</li>
</ul>

<p>P.S. 而且为什么sublime的fortran plugin需要自己下载并编译而不在官方包管理器里啊。</p>]]></content><author><name></name></author><category term="tech" /><summary type="html"><![CDATA[今天在尝试并行计算，需要用到opencoarray。原本计划使用开源链gfortran + openmpi + opencoarray. 在安装aur中的opencoarray时发现 opencoarray 在 openmpi V15 后不再支持openmpi，因为openmpi 无法满足全局统一ID的需求 open-mpi issue. 于是转向 mpich（不知为何还满足这个特性）。编译并安装mpich后发现 mpich的可执行文件都放在了/opt/mpich/bin/ 而不是/usr/bin/,导致opencoarrays-mpich-git|aur无法自动化安装。于是转而从github源码开始编译并直接使用FC=mpif90制定mpich。同时这个位置导致cafrun无法找到mpiexec让我又重新编译了一下（～——～）。]]></summary></entry><entry><title type="html">Learning note for german rail signal</title><link href="https://xiyivan.github.io/game/2026/05/22/tsw-german-signal.html" rel="alternate" type="text/html" title="Learning note for german rail signal" /><published>2026-05-22T22:01:00+00:00</published><updated>2026-05-22T22:01:00+00:00</updated><id>https://xiyivan.github.io/game/2026/05/22/tsw-german-signal</id><content type="html" xml:base="https://xiyivan.github.io/game/2026/05/22/tsw-german-signal.html"><![CDATA[<h2 id="fundamental">Fundamental</h2>

<p>Two signal systems</p>
<ul>
  <li>PZB</li>
  <li>LZB</li>
</ul>

<h2 id="light-signal">Light signal</h2>

<p>Two types of signals</p>
<ul>
  <li>main signal</li>
  <li>distance signal</li>
</ul>

<h3 id="main-signal">Main signal</h3>

<p><strong>Green</strong>
Clear to proceed at current line speed</p>

<p><strong>Green over yellow</strong>
Proceed at 40 km/h</p>

<p><strong>Red</strong>
Stop at this signal</p>

<p><strong>White number on top of signal</strong>
Indicate speed of proceeding</p>

<p><strong>Blinking green</strong>
Proceed at line speed, expect to slow down at next signal.</p>

<h3 id="distance-signal">Distance signal</h3>
<p>Indicate the main signal ahead. Lights are at diagonal angle. White light indicate this distance signal is closer to main signal than usual.</p>

<p><strong>Double green</strong></p>

<p>Next main signal is clear</p>

<p><strong>Green over yellow</strong>
Proceed at 40 km/h</p>

<p><strong>Two yellow lights</strong>
Expect to stop at next main signal</p>

<h3 id="shunt-signal">Shunt signal</h3>

<p><strong>Two horizontal red light</strong>
Not clear to proceed</p>

<p><strong>Two diagonal white light</strong>
Clear to proceed at 40 km/h</p>

<h2 id="pzb">PZB</h2>

<p>There are three modes for PZB. The number for each mode indicate the speed to reduce to when passing cautionary signal (diagonal yellow).</p>

<ul>
  <li>O mode for passenger train, illuminate 85.</li>
</ul>

<h3 id="pzb-control">PZB control</h3>

<p><strong>PZB acknowledge</strong></p>

<p>Pgdown</p>

<p><strong>PZB release</strong></p>

<p>end</p>

<p><strong>PZB overide</strong></p>

<p>del</p>

<h3 id="sop">SOP</h3>

<h4 id="passing-cautionary-signal">Passing cautionary signal</h4>

<ol>
  <li>Press acknowledge when pass cautionary signal</li>
  <li>1000hz magnet light up</li>
  <li>reduce speed to below 85 km/h</li>
  <li>When 1000Hz magnet light off. If the path is clear ahead, press PZB release and accelerate. If not clear, decrease speed to 65 km/h.</li>
  <li>When 500Hz magnet light up, decelerate to 45 km/h.</li>
  <li>Stop before red signal</li>
  <li>If get permission from the signaler, press and hold the overide button and move forward.</li>
  <li>Keep speed below 40 km/h after passing this way untile travel 2km or pass a clear signal. After which press pzb release and accelerate.</li>
</ol>

<p><strong>note</strong></p>
<ul>
  <li>No need for acknowledge of 500Hz magnet</li>
  <li>Can’t go over 45 km/h after passing 500Hz even if signal is clear. The restriction last for 250m pass the signal.</li>
</ul>

<h2 id="lzb">LZB</h2>

<p>Indicate by the U light.</p>

<p>When AFB active, the speed automatically adjust.</p>

<p>B lamp indicate whether auto braking is active. 
G lamp indicate it is faster than the braking curve allows.</p>

<p>When reaching end of LZB section</p>

<ol>
  <li>ende light up</li>
  <li>press PZB acknowledge</li>
</ol>

<h2 id="signs">Signs</h2>

<p><strong>Speed Post</strong></p>

<p><img src="/assets/image/2026-05-22/speed-post.png" alt="Speed Post" /></p>

<p>Show speed limit divide by ten. Arrow above the post indicates the track this speed limit applies to.</p>

<p><strong>Speed Limit Warning Post</strong></p>

<p><img src="/assets/image/2026-05-22/speed-limit-warning-post.png" alt="Speed List Warning Post" /></p>

<p>Indicate the upcoming speed change. May contain pzb magnet.</p>

<p><strong>Distance Marker Post</strong></p>

<p><img src="/assets/image/2026-05-22/distance-marker-post.png" alt="Distance marker post" /></p>

<p>Represent distance to an upcoming signal. 3 stripes — 250m; 2 stripes — 175m; 1 stripe — 100m.</p>

<p><strong>Hectometer Post</strong></p>

<p><img src="/assets/image/2026-05-22/hectometer-post.png" alt="Hectometer post" /></p>

<p>Exist every 200m. Indicate location from a location.</p>

<p><strong>P Sign</strong></p>

<p><img src="/assets/image/2026-05-22/p-sign.png" alt="P sign" /></p>

<p>Sound horn when passing P sign.</p>

<p><strong>H Sign</strong></p>

<p><img src="/assets/image/2026-05-22/h-sign.png" alt="H sign" /></p>

<p>Indicate stopping location.</p>

<p>Credit to <a href="https://www.youtube.com/@PTGRail">PTGRail</a> for the amazing video he made about this topic.</p>]]></content><author><name></name></author><category term="game" /><summary type="html"><![CDATA[Fundamental]]></summary></entry><entry><title type="html">Abnormal dGPU Power Consumption</title><link href="https://xiyivan.github.io/tech/2026/02/19/Nvidia_sleep_issue.html" rel="alternate" type="text/html" title="Abnormal dGPU Power Consumption" /><published>2026-02-19T22:34:25+00:00</published><updated>2026-02-19T22:34:25+00:00</updated><id>https://xiyivan.github.io/tech/2026/02/19/Nvidia_sleep_issue</id><content type="html" xml:base="https://xiyivan.github.io/tech/2026/02/19/Nvidia_sleep_issue.html"><![CDATA[<p>I disabled my dGPU because of its incompatibility with Kwin compositor. However, I found the device still shows up in pci devices occasionally, and consuming a lot of power.</p>

<p>After a bit of investigation, I found although the dGPU is not waked during a reboot, bios power it up during waking up from suspension, and makes it stuck at D0.</p>

<p>The stuck was caused by the power control switched to on after the reboot. Therefore, this problem can be solved by writing a script than automatically set the power control back to auto after suspension. This can be down using a simple bash program.</p>]]></content><author><name></name></author><category term="tech" /><summary type="html"><![CDATA[I disabled my dGPU because of its incompatibility with Kwin compositor. However, I found the device still shows up in pci devices occasionally, and consuming a lot of power.]]></summary></entry><entry><title type="html">Fix: Surface Pen on ROG Flow 13 (KDE Plasma Wayland)</title><link href="https://xiyivan.github.io/tech/2026/01/21/Stylus_issue.html" rel="alternate" type="text/html" title="Fix: Surface Pen on ROG Flow 13 (KDE Plasma Wayland)" /><published>2026-01-21T20:48:00+00:00</published><updated>2026-01-21T20:48:00+00:00</updated><id>https://xiyivan.github.io/tech/2026/01/21/Stylus_issue</id><content type="html" xml:base="https://xiyivan.github.io/tech/2026/01/21/Stylus_issue.html"><![CDATA[<p>If you are using an ASUS ROG Flow 13 with an MPP (Microsoft Pen Protocol) stylus like the Surface Pen on KDE Plasma (Wayland), you might find that while the kernel sees the device, the cursor refuses to move.</p>

<p>Here is how I diagnosed and fixed the issue when my stylus was recognized as a device but wouldn’t move the pointer.</p>

<hr />

<h3 id="step-1-verification-the-before-state">Step 1: Verification (The “Before” State)</h3>

<p>Even without configuration, Linux often “sees” the hardware. I started by checking if the kernel was receiving signals.</p>
<ul>
  <li>Command: <code class="language-plaintext highlighter-rouge">sudo evtest</code></li>
  <li>Result: I selected the <code class="language-plaintext highlighter-rouge">ELAN9008</code> device. Moving the pen showed a stream of $ABS_X$ and $ABS_Y$ coordinates.</li>
  <li>What this told me: The hardware is fine. The screen digitizer is working, and the kernel driver (<code class="language-plaintext highlighter-rouge">hid-multitouch</code>) is active. The problem lies higher up.</li>
</ul>

<h3 id="step-2-bridging-the-gap-with-libwacom">Step 2: Bridging the Gap with libwacom</h3>

<p>KDE Plasma relies on a library called <code class="language-plaintext highlighter-rouge">libwacom</code> to identify tablets. If THE device isn’t in its database, the “Graphics Tablet” settings page in KDE will be empty or missing features.</p>

<ul>
  <li>The Problem: <code class="language-plaintext highlighter-rouge">libwacom-list-local-devices</code> showed the device was “not supported.”</li>
  <li>The Fix: I created a custom tablet definition file at <code class="language-plaintext highlighter-rouge">/etc/libwacom/elan-9008.tablet</code>.</li>
  <li>The Data:</li>
</ul>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[Device]
Name=ELAN9008:00 04F3:40FD Stylus
DeviceMatch=i2c|04f3|40fd
Class=ISDV4
IntegratedIn=Display;System
Styli=@generic-with-eraser;
</code></pre></div></div>

<ul>
  <li>Why this helped: This “introduced” the stylus to the system. After running <code class="language-plaintext highlighter-rouge">sudo libwacom-update-db</code>, the Graphics Tablet section finally appeared in my KDE System Settings.</li>
</ul>

<h3 id="step-3-debugging-the-flicker-wayland-input">Step 3: Debugging the “Flicker” (Wayland Input)</h3>
<p>Even with the settings page visible, the cursor would only “flicker” or appear/disappear without actually moving.</p>
<ul>
  <li>Command: <code class="language-plaintext highlighter-rouge">libinput debug-events</code></li>
  <li>Observation: This tool showed <code class="language-plaintext highlighter-rouge">TABLET_TOOL_AXIS</code> events with perfect coordinates.</li>
  <li>What this told me: <code class="language-plaintext highlighter-rouge">libinput</code> was correctly processing the movement, but KWin was dropping the data.</li>
</ul>

<h3 id="step-4-the-final-boss--the-calibration-matrix">Step 4: The Final Boss – The Calibration Matrix</h3>
<p>This was the “Aha!” moment. I checked the KDE input configuration file to see how it was mapping the pen to the pixels.</p>
<ul>
  <li>Command: <code class="language-plaintext highlighter-rouge">grep -A 20 "ELAN9008" ~/.config/kcminputrc</code></li>
  <li>The Discovery: The <code class="language-plaintext highlighter-rouge">CalibrationMatrix</code> was filled with scientific notation numbers like 1.19e-07 (effectively 0).</li>
  <li>The Fix: I manually edited <code class="language-plaintext highlighter-rouge">~/.config/kcminputrc</code> and reset the matrix to the Identity Matrix:
    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>CalibrationMatrix=1,0,0,0,1,0,0,0,1
</code></pre></div>    </div>
  </li>
</ul>

<hr />

<h3 id="summary">Summary</h3>
<ol>
  <li>
    <p>Check Hardware: Use evtest to ensure the kernel sees the pen.</p>
  </li>
  <li>
    <p>Identify for UI: Create a .tablet file so libwacom and KDE recognize the device.</p>
  </li>
  <li>
    <p>Check libinput: Ensure debug-events shows axis movement.</p>
  </li>
  <li>
    <p>Fix the Math: Reset the CalibrationMatrix in kcminputrc to identity matrix.</p>
  </li>
</ol>]]></content><author><name></name></author><category term="tech" /><summary type="html"><![CDATA[If you are using an ASUS ROG Flow 13 with an MPP (Microsoft Pen Protocol) stylus like the Surface Pen on KDE Plasma (Wayland), you might find that while the kernel sees the device, the cursor refuses to move.]]></summary></entry><entry><title type="html">Fixing bad microphone quility in linux</title><link href="https://xiyivan.github.io/tech/2026/01/17/linux_audio_gain_issue.html" rel="alternate" type="text/html" title="Fixing bad microphone quility in linux" /><published>2026-01-17T23:10:00+00:00</published><updated>2026-01-17T23:10:00+00:00</updated><id>https://xiyivan.github.io/tech/2026/01/17/linux_audio_gain_issue</id><content type="html" xml:base="https://xiyivan.github.io/tech/2026/01/17/linux_audio_gain_issue.html"><![CDATA[<p>I recently had a Discord call with my friends and we immediately found that the quality of my internal microphone sucks. This turned out to be an issue with microphone gain, which is surprisingly difficult to source with modern software despite being a simple problem.</p>

<p>The reason it’s confusing is that applications like Discord control the microphone gain from their end. This keeps the volume from being loud enough to immediately identify as a gain issue, though the constant popping and high sensitivity indicate otherwise.</p>

<p>For anyone using ALSA, the fix is as simple as getting into alsamixer and manually changing the gain of the internal microphone.</p>]]></content><author><name></name></author><category term="tech" /><summary type="html"><![CDATA[I recently had a Discord call with my friends and we immediately found that the quality of my internal microphone sucks. This turned out to be an issue with microphone gain, which is surprisingly difficult to source with modern software despite being a simple problem.]]></summary></entry><entry><title type="html">Extending lvm</title><link href="https://xiyivan.github.io/tech/2026/01/06/extend-lvm.html" rel="alternate" type="text/html" title="Extending lvm" /><published>2026-01-06T18:51:00+00:00</published><updated>2026-01-06T18:51:00+00:00</updated><id>https://xiyivan.github.io/tech/2026/01/06/extend-lvm</id><content type="html" xml:base="https://xiyivan.github.io/tech/2026/01/06/extend-lvm.html"><![CDATA[<p>Now that I have used Arch for a period of time and it has performed well, I want to allocate more space from the Windows partition to the Arch partition. The only problem is my Windows partition is located before the LVM that contains my Arch partitions.</p>

<p>My original plan was to create a new physical volume and add it to the LVM. However, since I had not yet stored any important documents on the system, I decided to directly increase the size of the existing volume. Here are the steps I took:</p>

<p>First, the most important step is to create backups. Keep recovery images for both systems on a separate drive in case anything goes wrong. Before starting any disk operations, I recommend creating a Ventoy USB drive with GParted Live, Arch Linux, and Windows installation ISOs. I also recommend saving a backup of the partition table to the same USB drive.</p>

<p>I used DiskGenius to decrease the Windows volume size and GParted to increase the LVM volume size. You could theoretically use GParted for both operations, but DiskGenius is known for having better support for Windows. The only issue I had in this process was that the LVM was mounted for some reason, which I didn’t notice initially. Therefore, be sure to unmount all volumes using umount -a before proceeding.</p>

<p>After moving the LVM, we need to fix GRUB. This <a href="https://gparted.org/display-doc.php?name=help-manual&amp;lang=C#gparted-fix-grub-boot-problem">guide</a> from GParted was very useful. For Arch users, this process can be further simplified by booting into an Arch Live environment.</p>

<p>For Arch users with an LVM on a UEFI system, the process I used was as follows:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># 1.activate LVM logic volume
vgchange -ay

# 2.mount root logic volume to /mnt
mount /dev/vg_arch/root /mnt

# 3.mount the efi partition
mkdir -p /mnt/boot/efi
mount /dev/nvme0n1p1 /mnt/boot/efi

# 4.chroot into the original system
arch-chroot /mnt

# 5.re-install GRUB to ESP partition
grub-install --target=x86_64-efi --efi-directory=/boot/efi /dev/nvme0n1

# 6.regen init ramdisk
mkinitcpio -P

# 7.regen GRUB config file
grub-mkconfig -o /boot/grub/grub.cfg

# 8.exit and reboot
exit
umount -R /mnt
reboot
</code></pre></div></div>]]></content><author><name></name></author><category term="tech" /><summary type="html"><![CDATA[Now that I have used Arch for a period of time and it has performed well, I want to allocate more space from the Windows partition to the Arch partition. The only problem is my Windows partition is located before the LVM that contains my Arch partitions.]]></summary></entry><entry><title type="html">Running Zenless Zone Zero on Arch Linux</title><link href="https://xiyivan.github.io/tech/game/2026/01/02/zzz-install.html" rel="alternate" type="text/html" title="Running Zenless Zone Zero on Arch Linux" /><published>2026-01-02T15:27:00+00:00</published><updated>2026-01-02T15:27:00+00:00</updated><id>https://xiyivan.github.io/tech/game/2026/01/02/zzz-install</id><content type="html" xml:base="https://xiyivan.github.io/tech/game/2026/01/02/zzz-install.html"><![CDATA[<p>Key points</p>
<ul>
  <li>Add executable to steam</li>
  <li>Place the game file in the virtual C</li>
  <li>Perform integrity check before launching</li>
  <li>Ignore the error 9041-0-0</li>
  <li>Enjoy the game</li>
</ul>

<p>Since I have switched my daily OS to arch, I naturally want to minimize the time I have to boot back to Windows. Obviously professional softwares like Catia or Ansys(which is buggy even on Windows) are hard to run on linux, but I could as least try and run all my games in linux. Thanks to the consant investment in compatibility from valve, all the steam titles can run smoothly without any pain. The only remaining game is ZenlessZoneZero.</p>

<p>Initially I tried to run it on standard wine, but a weird error of constant relaunching hit me, and I decided to instead using proton for this mihoyo game.</p>

<p>The launcher installed via steam flawlessly. After putting the game file into the virtual C under <code class="language-plaintext highlighter-rouge">~/.local/share/Steam/steamapps/compatdata/game_id/pfx/drive_c/Program Files/miHoYo Launcher/game/</code>, the launcher was capable of detecting it instantaneously. Success seemed imminent.</p>

<p>However, the game entered a black screen after the initial logo appeared. To fix this, I ran an integrity check to prevent any file corruption from the migration. That’s when I hit a wall: the post-check download failed with error 9041-0-0, a cryptic parity-check failure.</p>

<p>After a few more attempt of revalidation, I decided on a last-ditch effort: bypassing the launcher entirely. By running the game executable directly from steam, the game launched perfectly, bypassing the broken launcher logic entirely.</p>

<p>In order to make the launching process more convenient, we can also add the application to application menu. However, the steamgameid for non-steam game can only be obtained using the “add desktop shortcut” function of steam. After creating the shortcut, we can move the file to the application menu directory using command <code class="language-plaintext highlighter-rouge">mv ~/Desktop/zenlesszonezero.desktop ~/.local/share/applications/</code>. To improve the looking, we can change the icon by editing the desktop file <code class="language-plaintext highlighter-rouge">nano ~/.local/share/applications/ZenlessZoneZero.desktop</code> and replace (or add) the entry <code class="language-plaintext highlighter-rouge">Icon=~/.local/share/Steam/steamapps/compatdata/game_id/pfx/drive_c/Program Files/miHoYo Launcher/1.12.0.303/ico/nap_cn.ico</code>.</p>

<p>The process of getting steamgameid part was inspired by this <a href="https://blog.dimeta.top/archives/linuxxia-shi-yong-proton-wine-yun-xing-windowsruan-jian-bing-jin-xing-hou-xu-pei-zhi">blog</a> by “洛元”. I am confused why valve decided to use different id for the directory and the execution command.</p>]]></content><author><name></name></author><category term="tech" /><category term="game" /><summary type="html"><![CDATA[Key points Add executable to steam Place the game file in the virtual C Perform integrity check before launching Ignore the error 9041-0-0 Enjoy the game]]></summary></entry><entry><title type="html">And so, a new year began</title><link href="https://xiyivan.github.io/personal/2026/01/01/new-year-summary.html" rel="alternate" type="text/html" title="And so, a new year began" /><published>2026-01-01T13:58:43+00:00</published><updated>2026-01-01T13:58:43+00:00</updated><id>https://xiyivan.github.io/personal/2026/01/01/new-year-summary</id><content type="html" xml:base="https://xiyivan.github.io/personal/2026/01/01/new-year-summary.html"><![CDATA[<p>迟到了9个小时的总结：</p>

<p>2025年，稳定又变化。剑桥重复的流程，让人很难感受到年份的实感。周围太多人进入了下一个阶段，而我仍未知我的信息是否足够支持下一步的决定。今年太多的突发事件让我不断在信息不足时调整流程，完成了许多事，但也留下了许多遗憾。所幸，无论在哪，家人与朋友总会握紧我的手，给我信心来做出决定。接受，并感谢2025年的我所执行的一切，从中汲取必须的知识，并开始新的一年。</p>]]></content><author><name></name></author><category term="personal" /><summary type="html"><![CDATA[迟到了9个小时的总结：]]></summary></entry></feed>