Developers
##########
The EPW team welcome any new development to the code.
How to become an EPW developer
==============================
Please follow the following steps:
* Contact one of us via email about whether your developement is already there or under development.
* Register on GitLab at `https://gitlab.com/ `_
* Fork the QE project at `https://gitlab.com/QEF/q-e `_
* Do your development following EPW coding style (see below)
* Run the test-farm. Go to q-e/test-suite and run ``make run-tests-epw-parallel``
* (optional but recommanded) Compile the code in sequential without MPI and run the test-farm in sequential with ``make run-tests-epw-serial``
* Make a pull request
It is also good to contact one of us via email.
.. _my-reference-label:
EPW good coding practice
========================
Here are some good coding practice that we would like to implement in EPW (some might not be fully respected in the code yet):
* Compile your code with ``-O0 -Wall`` flags. Make sure that you do not introduce unused variables etc...
* ``FFLAGS = -O2 -g -Wall -fbounds-check -frange-check -finit-integer=987654321 -finit-real=nan -finit-logical=true -finit-character=64``
* Make your code ready for automatic documentation (Ford). Document the subroutine purpose and variables (also local variables) using !! below the variable name.
* Do use ``INTENT (in/out)`` when you pass variables to a subroutine.
* Make sure that your developments will not break the test-farm. You can run the tests in ``QE/test-suites``.
* Always use the ``ONLY`` keyword when you call a module with ``USE``.
* Do NOT use ``#ifdef __PARA`` except if truly required (e.g. if you directly call an MPI routine and you do not use the QE wrapper).
* Do NOT use ``IF( ALLOCATED(var1) ) DEALLOCATE(var1)``. The variable should be correctly allocated and deallocated and should not be called more than necessary.
EPW coding style
================
* Preprocessing options should be capitalized and start with two underscores. Examples: ``__MPI, __LINUX``, ... Use preprocessing syntax ``#if defined (XXX)``, not ``#if defined XXX`` or ``#ifdef XXX``
* Fortran commands should be capitalized: ``CALL something( )``
* Variable names should be lowercase: ``foo = bar/2``
* use "DP" (defined in module ''kinds'') to define the type of real and complex variables
* conversions should be explicitly indicated. For conversions to real, use DBLE, or else REAL(...,KIND = DP). For conversions to complex, use CMPLX(...,...,KIND = DP). For complex conjugate, use CONJG. For imaginary part, use AIMAG. IMPORTANT: Do not use REAL or CMPLX without KIND = DP, or else you will lose precision (except when you take the real part of a double precision complex number).
* Do not use automatic arrays (e.g. REAL(KIND = DP) :: A(N) 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
* Do not use pointers unless you have a good reason to: pointers may hinder optimization. Allocatable arrays should be used instead.
* If you use pointers, nullify them before performing tests on their status.
* 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.
* 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.
* Always use IMPLICIT NONE and declare all local variables. All variables passed as arguments to a routine should be declared as INTENT(in), (out), or (inout). All variables from modules should be explicitly specified via USE module, ONLY : variable. Variables used in an array declaration must be declared first, as in the following example:
::
INTEGER, INTENT(in) :: N
REAL(KIND = DP), INTENT(out) :: A(N)
in this order (some compilers complain if you put the second line before the first).
**Typical header of subroutines**
::
!------------------------------------------------------------------------
SUBROUTINE name(arg1, arg2)
!------------------------------------------------------------------------
!!
!! Description of subroutine
!!
!------------------------------------------------------------------------
USE kinds, ONLY : DP
USE cell_base, ONLY : at, bg, alat
!
IMPLICIT NONE
!
! input variables
!
INTEGER, INTENT(in) :: arg1
!! Description
REAL(KIND = DP), INTENT(in) :: arg2(3, 5)
!! Description
!
! Local variables
!
INTEGER :: ik
!! Description
!------------------------------------------------------------------------
END SUBROUTINE name
!------------------------------------------------------------------------
**Indentation**
Use **two** spaces for indentation
::
DO ik = 1, nkf
DO imode = 1, nmodes
code
ENDDO
ENDDO
**Spaces**
Leave **one** space after a comma "," and between "multiple conditions" in a IF statement
::
IF (cond) THEN
CALL name(arg1, arg2, arg3)
ENDIF
ALLOCATE(var1(dim1, dim2), STAT = ierr)
IF (ierr /= 0) CALL io_error('Error allocating var1 in subroutine_name')
DO ik = 1, nkf
ikk = 2 * ik - 1
ikq = 2 * ik
IF ((MINVAL(ABS(var1(:, ikk) - ef)) < fsthick) .AND. (MINVAL(ABS(var1(:, ikq) - ef)) < fsthick)) THEN
ENDDO
DEALLOCATE(var1, STAT = ierr)
IF (ierr /= 0) CALL io_error('Error deallocating var1 in subroutine_name')
**Allocating and deallocating arrays**
Check the status once an array is allocated or deallocated
::
ALLOCATE(var1(dim1, dim2), STAT = ierr)
IF (ierr /= 0) CALL errore('subroutine_name', 'Error allocating var1', 1)
DEALLOCATE(var1, STAT = ierr)
IF (ierr /= 0) CALL errore('subroutine_name', 'Error deallocating var1', 1)
**Reading and writing files**
Leave **one** space after a comma "," and after a statement
::
OPEN(UNIT = file_unit, FILE = 'file_name', STATUS = 'old', FORMAT = 'formatted', IOSTAT = ios)
IF (ios /= 0) CALL errore('subroutine', 'error opening file_name', iunit_name)
READ(file_unit) index
CLOSE(file_unit)
OPEN(UNIT = file_unit, FILE = 'file_name', STATUS = 'old', FORMAT = 'formatted', IOSTAT = ios)
IF (ios /= 0) CALL errore('subroutine', 'error opening file_name', iunit_name)
WRITE(file_unit, '(i7)') index
CLOSE(file_unit)
**Intrinsic functions**
Use **capital** letters when calling an intrinsic function or logicals:
::
a = MATMUL(c, d)
c = TRANSPOSE(DBLE(e))
f = .TRUE.
**Relational operator**
Use modern relational operators:
::
> instead of .gt.
< instead of .lt.
== instead of .eq.
/= instead of .neq.
**Mathematical operator**
Use **one** space between mathematical operators
::
a = b + i
c = c / SQRT(s)
**Spaces in the code**
Avoid white space in the code. When a space is need, add a comment (!) that follows the indentation:
::
!
a = b
!
DO i = 1, n
!
y = a + c
ENDDO
**Conditional allocation**
Do NOT use:
::
IF (.NOT. ALLOCATED(var)) ALLOCATE(var(dim1))
but rather use
::
ALLOCATE(var1(dim1, dim2), STAT = ierr)
IF (ierr /= 0) CALL errore('subroutine_name', 'Error allocating var1', 1)
Indeed conditional allocations create memory leaks and can always be avoided.
**Order of declaration**
The recommanded order is as follow:
::
CHARACTER(LEN = 256) :: var
LOGICAL :: var
LOGICAL, ALLOCATED :: var(:)
INTEGER :: var
INTEGER, ALLOCATED :: var(:)
REAL(KIND = DP) :: var
REAL(KIND = DP), ALLOCATED :: var(:)
COMPLEX(KIND = DP) :: var
COMPLEX(KIND = DP), ALLOCATED :: var(:)
First all INTENT variables are declared (in that order) and then all the local variables are declared (in that order).
Note: Do not use "DIMENSION(:)"
**Use of capital letters**
Do not use capital letters in variables (even if only first letter).
Capital letters are reserved for function, subroutines, kinds, intrinsic etc..