Category:Programming

From VASP Wiki

In VASP.4.X, the module prec must be included in all subroutines, and

      USE prec

at the beginning of all subroutines. All real and complex variables must be defined as REAL(q) and COMPLEX(q) (never: REAL or COMPLEX). The use of IMPLICIT NONE is strongly recommended, but currently not used in all subroutines. If you do not use IMPLICIT NONE, you must use

      IMPLICIT REAL(q) (A-H,O-Z)

to guarantee that all real variables have the correct type. The IMPLICIT statement must be the first statement after the USE statement (some compiler allow IMPLICIT statements somewhere else, but not all F90 compiler do so). For instance:

      SUBROUTINE RHOATO(LFOUR,LPAR,GRIDC,T_INFO,B,P,CSTRF,CHTOT,CHDER)
      USE prec
      USE mgrid
      USE pseudo
      USE constant

      IMPLICIT REAL(q) (A-B,D-H,O-Z)

      TYPE (type_info)   T_INFO
      TYPE (potcar)      P(T_INFO%NTYP)
      TYPE (grid_3d)     GRIDC
      COMPLEX(q)   CHTOT(GRIDC%RC%NP),CHDER(GRIDC%RC%NP)
      COMPLEX(q)   CSTRF(GRIDC%MPLWV,T_INFO%NTYP)
      REAL(q)      B(3,3)
      LOGICAL LFOUR,LPAR

Work arrays should be allocated on the fly with ALLOCATE and DEALLOCATE. Do not use dynamic F90 arrays (except for small performance insensitive arrays). The dynamic arrays are allocated from the stack and this can degrade performance by up to 20 % on some machines (i.e. IBM workstations). In addition, it might happen that one runs out of stack memory if large arrays are allocated from the stack, unpredictable crashes are possible (at least on IBM workstations). ALLOCATE and DEALLOCATE uses the heap and not the stack and is therefore often saver.

All file must conform to the F90 free format. A small utility called convert can be found in the package to convert F77 style programs to F90 free format.

All subroutines should be placed in a MODULE so that dummy-parameters can be checked during compilation.

Debugging

For debugging built in runtime checks, debugging and tracebacks should be allowed. That means the necessary flags have to be set at compilation time. We recommend the following flags for ifort:

-C -debug -g -traceback -check noarg_temp_created

Input and Output

Input/Output (IO) should be done with extreme care, to allow later parallelisation. The following rules must be obeyed:

  • Six classes of information can be distinguished:
    • Debugging messages.
    • General results.
    • Notifications (important results).
    • Warnings (strange behaviour, continuation possible).
    • Errors (user error, file can not be opened etc.).
    • Internal errors (absolute chaos, internal inconsistency).
  • Debugging code and messages might remain within the subroutines, and is simply bracketed by
#ifdef debug
...
code
...
#endif
  • Unit * should be used to write debugging results.
  • For less important output (general results) unit IO%IU6 must be used and before writing it must be checked whether IO%IU6 is (in the parallel version most nodes will have IO%IU6 set to -1).
  • Notifications and warnings should be written to unit I\%IU0, and before writing them it must be checked whether IO%IU0 is 0 or not. (in the parallel version most nodes will have IO%IU0 set to -1). Unit * must not be used for notifications and warnings.
  • If the program comes to a point where continuation is impossible (errors, or internal errors) the program should STOP and write why continuation is impossible. If program logic allows to determine that all nodes will come to the same STOP, then preferably only one node should report to unit IO%IU0. If this is not possible and whenever in doubt all nodes should write an error status to the unit *.
  • Defensive programming should be used whenever possible (i.e. input parameter checked against each other). If a subroutine finds an internal inconsistency errors might be reported to unit * (internal error).

This category currently contains no pages or media.