<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>