<div dir="ltr">Any opinions? Paolo<br><div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">---------- Forwarded message ---------<br>From: <b class="gmail_sendername" dir="auto">Samuel Poncé</b> <span dir="auto"><<a href="mailto:gitlab@mg.gitlab.com">gitlab@mg.gitlab.com</a>></span><br>Date: Mon, Sep 23, 2019 at 5:22 PM<br>Subject: q-e | Syntax rules in QE (#143)<br>To: <<a href="mailto:p.giannozzi@gmail.com">p.giannozzi@gmail.com</a>><br></div><br><br><u></u>
<div>
<div class="m_3629046376005003669content">
<p class="m_3629046376005003669details" style="font-style:italic;color:#777">
<a href="https://gitlab.com/sponce24" target="_blank">Samuel Poncé</a> created an issue:
</p>
<div></div>
<p dir="auto">Dear QE developers,</p>
<p dir="auto">After carefully thinking about a general syntax rules for the code, trying to make them as consistent with each other as possible, I propose the following rules:</p>
<h3 dir="auto">
<a id="m_3629046376005003669user-content-pre-processing" class="m_3629046376005003669anchor" href="#m_3629046376005003669_pre-processing"></a>Pre-processing</h3>
<ul dir="auto">
<li>Preprocessing options should be capitalized and start with two underscores. Examples:<code>__MPI, __LINUX, ...</code>
</li>
<li>Use preprocessing syntax<code>#if defined (XXX)</code>, not <code>#if defined XXX</code> or <code>#ifdef XXX</code>
</li>
</ul>
<h3 dir="auto">
<a id="m_3629046376005003669user-content-common-style" class="m_3629046376005003669anchor" href="#m_3629046376005003669_common-style"></a>Common style</h3>
<ul dir="auto">
<li>Fortran commands should be capitalized: <code>CALL something(XXX)</code>
</li>
<li>Variable names should be lowercase: <code>foo = bar/2</code>
</li>
<li>Use <code>(KIND = DP)</code> (defined in module kinds) to define the type of real and complex variables</li>
</ul>
<h3 dir="auto">
<a id="m_3629046376005003669user-content-order-of-declaration" class="m_3629046376005003669anchor" href="#m_3629046376005003669_order-of-declaration"></a>Order of declaration</h3>
<ul dir="auto">
<li>The recommanded order is as follow:</li>
</ul>
<pre class="m_3629046376005003669code m_3629046376005003669highlight m_3629046376005003669js-syntax-highlight m_3629046376005003669plaintext" lang="plaintext"><code><span id="m_3629046376005003669LC1" class="m_3629046376005003669line" lang="plaintext">CHARACTER(LEN = 256) :: var</span>
<span id="m_3629046376005003669LC2" class="m_3629046376005003669line" lang="plaintext">LOGICAL :: var</span>
<span id="m_3629046376005003669LC3" class="m_3629046376005003669line" lang="plaintext">LOGICAL, ALLOCATED :: var(:)</span>
<span id="m_3629046376005003669LC4" class="m_3629046376005003669line" lang="plaintext">INTEGER :: var</span>
<span id="m_3629046376005003669LC5" class="m_3629046376005003669line" lang="plaintext">INTEGER, ALLOCATED :: var(:) </span>
<span id="m_3629046376005003669LC6" class="m_3629046376005003669line" lang="plaintext">REAL(KIND = DP) :: var</span>
<span id="m_3629046376005003669LC7" class="m_3629046376005003669line" lang="plaintext">REAL(KIND = DP), ALLOCATED :: var(:)</span>
<span id="m_3629046376005003669LC8" class="m_3629046376005003669line" lang="plaintext">COMPLEX(KIND = DP) :: var</span>
<span id="m_3629046376005003669LC9" class="m_3629046376005003669line" lang="plaintext">COMPLEX(KIND = DP), ALLOCATED :: var(:)</span></code></pre>
<ul dir="auto">
<li>First all <code>INTENT</code> variables are declared (in that order) and then all the local variables are declared (in that order).</li>
<li>Note: Do not use <code>DIMENSION(:)</code>
</li>
</ul>
<h3 dir="auto">
<a id="m_3629046376005003669user-content-typical-header-of-subroutines" class="m_3629046376005003669anchor" href="#m_3629046376005003669_typical-header-of-subroutines"></a>Typical header of subroutines</h3>
<pre class="m_3629046376005003669code m_3629046376005003669highlight m_3629046376005003669js-syntax-highlight m_3629046376005003669plaintext" lang="plaintext"><code><span id="m_3629046376005003669LC1" class="m_3629046376005003669line" lang="plaintext">!------------------------------------------------------------------------</span>
<span id="m_3629046376005003669LC2" class="m_3629046376005003669line" lang="plaintext">SUBROUTINE name(arg1, arg2)</span>
<span id="m_3629046376005003669LC3" class="m_3629046376005003669line" lang="plaintext">!------------------------------------------------------------------------</span>
<span id="m_3629046376005003669LC4" class="m_3629046376005003669line" lang="plaintext">!!</span>
<span id="m_3629046376005003669LC5" class="m_3629046376005003669line" lang="plaintext">!! Description of subroutine</span>
<span id="m_3629046376005003669LC6" class="m_3629046376005003669line" lang="plaintext">!!</span>
<span id="m_3629046376005003669LC7" class="m_3629046376005003669line" lang="plaintext">!------------------------------------------------------------------------</span>
<span id="m_3629046376005003669LC8" class="m_3629046376005003669line" lang="plaintext">USE kinds, ONLY : DP</span>
<span id="m_3629046376005003669LC9" class="m_3629046376005003669line" lang="plaintext">USE cell_base, ONLY : at, bg, alat</span>
<span id="m_3629046376005003669LC10" class="m_3629046376005003669line" lang="plaintext">!</span>
<span id="m_3629046376005003669LC11" class="m_3629046376005003669line" lang="plaintext">IMPLICIT NONE</span>
<span id="m_3629046376005003669LC12" class="m_3629046376005003669line" lang="plaintext">!</span>
<span id="m_3629046376005003669LC13" class="m_3629046376005003669line" lang="plaintext">! input variables</span>
<span id="m_3629046376005003669LC14" class="m_3629046376005003669line" lang="plaintext">!</span>
<span id="m_3629046376005003669LC15" class="m_3629046376005003669line" lang="plaintext">INTEGER, INTENT(in) :: arg1</span>
<span id="m_3629046376005003669LC16" class="m_3629046376005003669line" lang="plaintext">!! Description</span>
<span id="m_3629046376005003669LC17" class="m_3629046376005003669line" lang="plaintext">REAL(KIND = DP), INTENT(in) :: arg2(3, 5)</span>
<span id="m_3629046376005003669LC18" class="m_3629046376005003669line" lang="plaintext">!! Description</span>
<span id="m_3629046376005003669LC19" class="m_3629046376005003669line" lang="plaintext">!</span>
<span id="m_3629046376005003669LC20" class="m_3629046376005003669line" lang="plaintext">! Local variables</span>
<span id="m_3629046376005003669LC21" class="m_3629046376005003669line" lang="plaintext">!</span>
<span id="m_3629046376005003669LC22" class="m_3629046376005003669line" lang="plaintext">INTEGER :: ik</span>
<span id="m_3629046376005003669LC23" class="m_3629046376005003669line" lang="plaintext">!! Description</span>
<span id="m_3629046376005003669LC24" class="m_3629046376005003669line" lang="plaintext"></span>
<span id="m_3629046376005003669LC25" class="m_3629046376005003669line" lang="plaintext">!------------------------------------------------------------------------</span>
<span id="m_3629046376005003669LC26" class="m_3629046376005003669line" lang="plaintext">END SUBROUTINE name </span>
<span id="m_3629046376005003669LC27" class="m_3629046376005003669line" lang="plaintext">!------------------------------------------------------------------------</span></code></pre>
<h3 dir="auto">
<a id="m_3629046376005003669user-content-indentation" class="m_3629046376005003669anchor" href="#m_3629046376005003669_indentation"></a>Indentation</h3>
<ul dir="auto">
<li>Use <b>two</b> spaces for indentation</li>
</ul>
<pre class="m_3629046376005003669code m_3629046376005003669highlight m_3629046376005003669js-syntax-highlight m_3629046376005003669plaintext" lang="plaintext"><code><span id="m_3629046376005003669LC1" class="m_3629046376005003669line" lang="plaintext">DO ik = 1, nkf</span>
<span id="m_3629046376005003669LC2" class="m_3629046376005003669line" lang="plaintext"> DO imode = 1, nmodes</span>
<span id="m_3629046376005003669LC3" class="m_3629046376005003669line" lang="plaintext"> code</span>
<span id="m_3629046376005003669LC4" class="m_3629046376005003669line" lang="plaintext"> ENDDO</span>
<span id="m_3629046376005003669LC5" class="m_3629046376005003669line" lang="plaintext">ENDDO </span></code></pre>
<h3 dir="auto">
<a id="m_3629046376005003669user-content-spaces" class="m_3629046376005003669anchor" href="#m_3629046376005003669_spaces"></a>Spaces</h3>
<ul dir="auto">
<li>Leave <b>one</b> space after a comma "," and between "multiple conditions" in a IF statement</li>
</ul>
<pre class="m_3629046376005003669code m_3629046376005003669highlight m_3629046376005003669js-syntax-highlight m_3629046376005003669plaintext" lang="plaintext"><code><span id="m_3629046376005003669LC1" class="m_3629046376005003669line" lang="plaintext">IF (cond) THEN</span>
<span id="m_3629046376005003669LC2" class="m_3629046376005003669line" lang="plaintext"> CALL name(arg1, arg2, arg3)</span>
<span id="m_3629046376005003669LC3" class="m_3629046376005003669line" lang="plaintext">ENDIF</span>
<span id="m_3629046376005003669LC4" class="m_3629046376005003669line" lang="plaintext">ALLOCATE(var1(dim1, dim2), STAT = ierr)</span>
<span id="m_3629046376005003669LC5" class="m_3629046376005003669line" lang="plaintext">IF (ierr /= 0) CALL io_error('Error allocating var1 in subroutine_name')</span>
<span id="m_3629046376005003669LC6" class="m_3629046376005003669line" lang="plaintext"></span>
<span id="m_3629046376005003669LC7" class="m_3629046376005003669line" lang="plaintext">DO ik = 1, nkf</span>
<span id="m_3629046376005003669LC8" class="m_3629046376005003669line" lang="plaintext"> ikk = 2 * ik - 1</span>
<span id="m_3629046376005003669LC9" class="m_3629046376005003669line" lang="plaintext"> ikq = 2 * ik</span>
<span id="m_3629046376005003669LC10" class="m_3629046376005003669line" lang="plaintext"> IF ((MINVAL(ABS(var1(:, ikk) - ef)) < fsthick) .AND. (MINVAL(ABS(var1(:, ikq) - ef)) < fsthick)) THEN</span>
<span id="m_3629046376005003669LC11" class="m_3629046376005003669line" lang="plaintext">ENDDO</span>
<span id="m_3629046376005003669LC12" class="m_3629046376005003669line" lang="plaintext"></span>
<span id="m_3629046376005003669LC13" class="m_3629046376005003669line" lang="plaintext">DEALLOCATE(var1, STAT = ierr)</span>
<span id="m_3629046376005003669LC14" class="m_3629046376005003669line" lang="plaintext">IF (ierr /= 0) CALL io_error('Error deallocating var1 in subroutine_name')</span></code></pre>
<h3 dir="auto">
<a id="m_3629046376005003669user-content-allocating-and-deallocating-arrays" class="m_3629046376005003669anchor" href="#m_3629046376005003669_allocating-and-deallocating-arrays"></a>Allocating and deallocating arrays</h3>
<ul dir="auto">
<li>Check the status once an array is allocated or deallocated</li>
</ul>
<pre class="m_3629046376005003669code m_3629046376005003669highlight m_3629046376005003669js-syntax-highlight m_3629046376005003669plaintext" lang="plaintext"><code><span id="m_3629046376005003669LC1" class="m_3629046376005003669line" lang="plaintext">ALLOCATE(var1(dim1, dim2), STAT = ierr)</span>
<span id="m_3629046376005003669LC2" class="m_3629046376005003669line" lang="plaintext">IF (ierr /= 0) CALL errore('subroutine_name', 'Error allocating var1', 1)</span>
<span id="m_3629046376005003669LC3" class="m_3629046376005003669line" lang="plaintext"></span>
<span id="m_3629046376005003669LC4" class="m_3629046376005003669line" lang="plaintext">DEALLOCATE(var1, STAT = ierr)</span>
<span id="m_3629046376005003669LC5" class="m_3629046376005003669line" lang="plaintext">IF (ierr /= 0) CALL errore('subroutine_name', 'Error deallocating var1', 1)</span></code></pre>
<h3 dir="auto">
<a id="m_3629046376005003669user-content-reading-and-writing-files" class="m_3629046376005003669anchor" href="#m_3629046376005003669_reading-and-writing-files"></a>Reading and writing files</h3>
<ul dir="auto">
<li>Leave <b>one</b> space after a comma "," and after a statement</li>
</ul>
<pre class="m_3629046376005003669code m_3629046376005003669highlight m_3629046376005003669js-syntax-highlight m_3629046376005003669plaintext" lang="plaintext"><code><span id="m_3629046376005003669LC1" class="m_3629046376005003669line" lang="plaintext">OPEN(UNIT = file_unit, FILE = 'file_name', STATUS = 'old', FORMAT = 'formatted', IOSTAT = ios)</span>
<span id="m_3629046376005003669LC2" class="m_3629046376005003669line" lang="plaintext">IF (ios /= 0) CALL errore('subroutine', 'error opening file_name', iunit_name)</span>
<span id="m_3629046376005003669LC3" class="m_3629046376005003669line" lang="plaintext">READ(file_unit) index</span>
<span id="m_3629046376005003669LC4" class="m_3629046376005003669line" lang="plaintext">CLOSE(file_unit)</span>
<span id="m_3629046376005003669LC5" class="m_3629046376005003669line" lang="plaintext"></span>
<span id="m_3629046376005003669LC6" class="m_3629046376005003669line" lang="plaintext">OPEN(UNIT = file_unit, FILE = 'file_name', STATUS = 'old', FORMAT = 'formatted', IOSTAT = ios)</span>
<span id="m_3629046376005003669LC7" class="m_3629046376005003669line" lang="plaintext">IF (ios /= 0) CALL errore('subroutine', 'error opening file_name', iunit_name)</span>
<span id="m_3629046376005003669LC8" class="m_3629046376005003669line" lang="plaintext">WRITE(file_unit, '(i7)') index</span>
<span id="m_3629046376005003669LC9" class="m_3629046376005003669line" lang="plaintext">CLOSE(file_unit)</span></code></pre>
<h3 dir="auto">
<a id="m_3629046376005003669user-content-intrinsic-functions" class="m_3629046376005003669anchor" href="#m_3629046376005003669_intrinsic-functions"></a>Intrinsic functions</h3>
<ul dir="auto">
<li>Use <b>capital</b> letters when calling an intrinsic function or logical:</li>
</ul>
<pre class="m_3629046376005003669code m_3629046376005003669highlight m_3629046376005003669js-syntax-highlight m_3629046376005003669plaintext" lang="plaintext"><code><span id="m_3629046376005003669LC1" class="m_3629046376005003669line" lang="plaintext">a = MATMUL(c, d)</span>
<span id="m_3629046376005003669LC2" class="m_3629046376005003669line" lang="plaintext">c = TRANSPOSE(DBLE(e))</span>
<span id="m_3629046376005003669LC3" class="m_3629046376005003669line" lang="plaintext">f = .TRUE.</span></code></pre>
<h3 dir="auto">
<a id="m_3629046376005003669user-content-relational-operator" class="m_3629046376005003669anchor" href="#m_3629046376005003669_relational-operator"></a>Relational operator</h3>
<ul dir="auto">
<li>Use modern relational operators:</li>
</ul>
<pre class="m_3629046376005003669code m_3629046376005003669highlight m_3629046376005003669js-syntax-highlight m_3629046376005003669plaintext" lang="plaintext"><code><span id="m_3629046376005003669LC1" class="m_3629046376005003669line" lang="plaintext">> instead of .gt.</span>
<span id="m_3629046376005003669LC2" class="m_3629046376005003669line" lang="plaintext">< instead of .lt.</span>
<span id="m_3629046376005003669LC3" class="m_3629046376005003669line" lang="plaintext">== instead of .eq.</span>
<span id="m_3629046376005003669LC4" class="m_3629046376005003669line" lang="plaintext">/= instead of .neq.</span></code></pre>
<h3 dir="auto">
<a id="m_3629046376005003669user-content-mathematical-operator" class="m_3629046376005003669anchor" href="#m_3629046376005003669_mathematical-operator"></a>Mathematical operator</h3>
<ul dir="auto">
<li>Use <b>one</b> space between mathematical operators</li>
</ul>
<pre class="m_3629046376005003669code m_3629046376005003669highlight m_3629046376005003669js-syntax-highlight m_3629046376005003669plaintext" lang="plaintext"><code><span id="m_3629046376005003669LC1" class="m_3629046376005003669line" lang="plaintext">a = b + i</span>
<span id="m_3629046376005003669LC2" class="m_3629046376005003669line" lang="plaintext">c = c / SQRT(s)</span></code></pre>
<h3 dir="auto">
<a id="m_3629046376005003669user-content-spaces-in-the-code" class="m_3629046376005003669anchor" href="#m_3629046376005003669_spaces-in-the-code"></a>Spaces in the code</h3>
<ul dir="auto">
<li>Avoid white space in the code. When a space is need, add a comment (!) that follows the indentation:</li>
</ul>
<pre class="m_3629046376005003669code m_3629046376005003669highlight m_3629046376005003669js-syntax-highlight m_3629046376005003669plaintext" lang="plaintext"><code><span id="m_3629046376005003669LC1" class="m_3629046376005003669line" lang="plaintext">!</span>
<span id="m_3629046376005003669LC2" class="m_3629046376005003669line" lang="plaintext">a = b</span>
<span id="m_3629046376005003669LC3" class="m_3629046376005003669line" lang="plaintext">! </span>
<span id="m_3629046376005003669LC4" class="m_3629046376005003669line" lang="plaintext">DO i = 1, n</span>
<span id="m_3629046376005003669LC5" class="m_3629046376005003669line" lang="plaintext"> !</span>
<span id="m_3629046376005003669LC6" class="m_3629046376005003669line" lang="plaintext"> y = a + c</span>
<span id="m_3629046376005003669LC7" class="m_3629046376005003669line" lang="plaintext">ENDDO</span></code></pre>
<h3 dir="auto">
<a id="m_3629046376005003669user-content-conditional-allocation" class="m_3629046376005003669anchor" href="#m_3629046376005003669_conditional-allocation"></a>Conditional allocation</h3>
<ul dir="auto">
<li>Do <b>NOT</b> use:
<code>IF (.NOT. ALLOCATED(var)) ALLOCATE(var(dim1))</code>
</li>
<li>Do use:</li>
</ul>
<pre class="m_3629046376005003669code m_3629046376005003669highlight m_3629046376005003669js-syntax-highlight m_3629046376005003669plaintext" lang="plaintext"><code><span id="m_3629046376005003669LC1" class="m_3629046376005003669line" lang="plaintext">ALLOCATE(var1(dim1, dim2), STAT = ierr)</span>
<span id="m_3629046376005003669LC2" class="m_3629046376005003669line" lang="plaintext">IF (ierr /= 0) CALL errore('subroutine_name', 'Error allocating var1', 1)</span></code></pre>
<p dir="auto">Indeed conditional allocations create potential memory leaks and can always be avoided.</p>
<h3 dir="auto">
<a id="m_3629046376005003669user-content-good-practice" class="m_3629046376005003669anchor" href="#m_3629046376005003669_good-practice"></a>Good practice</h3>
<ul dir="auto">
<li>Conversions should be explicitly indicated. For conversions to real, use <code>DBLE</code>, or else <code>REAL(..., KIND = DP)</code>. For conversions to complex, use <code>CMPLX(...,...,KIND = DP)</code>. For complex conjugate, use <code>CONJG</code>. For imaginary part, use <code>AIMAG</code>.</li>
<li>Do not use <code>REAL</code> or <code>CMPLX</code> without <code>KIND = DP</code>, or else you will lose precision (except when you take the real part of a double precision complex number).</li>
<li>Do not use automatic arrays (e.g. <code>REAL(KIND = DP) :: A(N)</code> with N defined at run time) unless you are sure that the array is small in all cases: large arrays may easily exceed the stack size, or the memory size.</li>
<li>Do not use pointers unless you have a good reason to: pointers may hinder optimization. Allocatable arrays should be used instead.</li>
<li>If you use pointers, nullify them before performing tests on their status.</li>
<li>Be careful with F90 array syntax and in particular with array sections. Passing an array section to a routine may look elegant but it may turn out to be inefficient: a copy will be silently done if the section is not contiguous in memory (or if the compiler decides it is the right thing to do), increasing the memory footprint.</li>
<li>Do not pass unallocated arrays as arguments, even in those cases where they are not actually used inside the subroutine: some compilers don't like it.</li>
<li>Always use <code>IMPLICIT NONE</code> and declare all local variables. All variables passed as arguments to a routine should be declared as <code>INTENT(in)</code>, <code>(out)</code> , or <code>(inout)</code>. All variables from modules should be explicitly specified via <code>USE module, ONLY : variable</code>. Variables used in an array declaration must be declared first, as in the following example:</li>
</ul>
<pre class="m_3629046376005003669code m_3629046376005003669highlight m_3629046376005003669js-syntax-highlight m_3629046376005003669plaintext" lang="plaintext"><code><span id="m_3629046376005003669LC1" class="m_3629046376005003669line" lang="plaintext">INTEGER, INTENT(in) :: N</span>
<span id="m_3629046376005003669LC2" class="m_3629046376005003669line" lang="plaintext">REAL(KIND = DP), INTENT(out) :: A(N)</span></code></pre>
<p dir="auto">in this order (some compilers complain if you put the second line before the first).</p>
</div>
<div class="m_3629046376005003669footer" style="margin-top:10px">
<p style="font-size:small;color:#777">
—
<br>
Reply to this email directly or <a href="https://gitlab.com/QEF/q-e/issues/143" target="_blank">view it on GitLab</a>.
<br>
You're receiving this email because of your account on <a href="http://gitlab.com" target="_blank">gitlab.com</a>.
If you'd like to receive fewer emails, you can
<a href="https://gitlab.com/sent_notifications/9eae4242f545c27068c3b41bad3f7ef5/unsubscribe" target="_blank">unsubscribe</a>
from this thread or
adjust your notification settings.
</p>
</div>
</div>
</div><br clear="all"><br>-- <br><div dir="ltr" class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr"><div><div dir="ltr"><div>Paolo Giannozzi, Dip. Scienze Matematiche Informatiche e Fisiche,<br>Univ. Udine, via delle Scienze 208, 33100 Udine, Italy<br>Phone +39-0432-558216, fax +39-0432-558222<br><br></div></div></div></div></div></div></div>