- Created by Paul Sharp, last modified on Jul 19, 2022
You are viewing an old version of this page. View the current version.
Compare with Current View Page History
« Previous Version 4 Next »
Introduction
The aim of this document is to give OpenRadioss development guidelines. These guidelines cover the style and the efficiency of the code. OpenRadioss is mostly written in Fortran (Fortran77 and Fortran90 and above) https://fortran-lang.org/. A few functions are written in C and C++. The following rules apply for new code.
OpenRadioss Coding Standards
Fortran Language
Fortran90 is the programming language used for OpenRadioss development. Fortran95, Fortran2003, Fortran2008 and future extensions may be used only if necessary, and explicitly approved by OpenRadioss maintainers. In such case, these programming guidelines will have to be amended accordingly. It is allowed to use Intrinsic functions coming from Fortran95 up to Fortran2008
For Fortran code, the files should be named “<subroutine_name>.F”, “<module_name>_mod.F>” and “<include_file_name>.inc”. Only fixed format is allowed, extended to 132 columns
C/C++ Language
C routines deal with low level I/O, system calls. C++11 may be used
Preprocessor
C Preprocessor directives can be used to include files, define constants and macros
IMPLICIT NONE
Every OpenRadioss Fortran routine needs to include implicit_f.inc that contains IMPLICIT NONE
Fortran90 Restrictions
Fortran90 features that penalize performance should be avoided:
Object oriented features like operator overloading
Array manipulation, and especially non-contiguous section as subroutine argument is forbidden (assumed-shape-array)
Fortran77 extensions which are not Fortran90 standard are refused
Obsolete Fortran77 Coding
The following statements are not allowed in new code:
EQUIVALENCE
COMMON
SAVE
GOTO
It is also forbidden to use label for DO
loops, multiple RETURN
statements in a subroutine
WIP: Below being edited/modified
Precompiler Directives
Fortran files are of type foo.F. Fortran precompiler is automatically called
Therefore, it is forbidden to name a file .f or .f90
In particular the below directives are in use:
Examples:
#include
to include specific files or commons
#include "implicit_f.inc"
#define
#define my_real DOUBLE PRECISION
#ifdef
mainly used to define platform specific code
IMPLICIT NONE
For historical reasons, (in the past it was not supported everywhere) IMPLICIT NONE is automatically added to the source via a specific include implicit_f.inc. Its usage forces the programmer to declare every variable
Every Radioss Fortran routine needs to include implicit_f.inc
Fixed Format
To keep coherency between original code and new code, only fixed format is allowed, extended to 132 columns
Comments need to begin with "!"
They can be placed anywhere
("C"
and "*"
are still supported in first position)
Several instructions per line are allowed using ";"
Fortran95, Fortran2003, Fortran2008 Extensions
Intrinsic functions are allowed, especially NULL()
and CPU_TIME()
are allowed
Other Fortran95 extensions are refused
Fortran2003 and Fortran2008 extensions are refused
Fortran 90 Restrictions
Object oriented features like operator overloading are forbidden as they can highly penalize performance
Array manipulation, and especially non-contiguous section as subroutine argument is forbidden (assumed-shape-array)
Array reduction and special functions like MAXLOC/MINLOC/MAXVAL/MINVAL/SHAPE
, ... need to be used with care as their performance is compiler dependent
Fortran 77 Extensions
Fortran77 extensions which are not Fortran90 standard are refused
Obsolete Fortran 77 coding
EQUIVALENCE
EQUIVALENCE
is source of error. The use of EQUIVALENCE
is forbidden
Use MODULE
variables instead.
There is an ongoing effort to clean out the remaining instances in the code
COMMON
COMMON
is a source of error, use MODULE
variables instead
For new development, MODULE
should be used instead of COMMON
Current/existing COMMON
are maintained but one should avoid adding any new variables to existing COMMON
SAVE
SAVE
statement is forbidden. It needs to be replaced by variables in MODULE
Multiple RETURN
Multiple RETURN
statements inside a SUBROUTINE
are forbidden
GOTO
The use of GOTO
is forbidden. Existing GOTO
statements are progressively being removed from the code
DO loop with label
DO
loop with label is prohibited
Data Types
Integer
All integers are by default 32-bit integers (INTEGER
)
Where it is required 64-bit integer (INTEGER8
) can be used explicitly
Use of INTEGER8
in the code is limited to such specific usage
Real
Reals can be either 32-bit simple precision or 64-bit double precision reals
Real variables need to be declared as MY_REAL
or my_real
my_real.inc is automatically included together with implicit_f.inc to define MY_REAL
macro
The pre-compiler automatically replaces MY_REAL
by DOUBLE PRECISION
or REAL
depending on the R4R8
flag defined in the makefile:
R4R8=r8
: my_real
is transcribed to Fortran DOUBLE PRECISION
for double precision version of Radioss
R4R8=r4
: my_real
is transcribed to Fortran REAL
for extended single precision version of Radioss
Example:
my_real, INTENT(OUT) :: RES
For some exceptions, it is sometimes needed to explicitly use REAL
or DOUBLE PRECISION
for variables that need to stay in single or double precision independently of the Radioss precision version
Such exceptions are limited in the source code
Logical
LOGICAL
operators are restricted to .NOT.
, .AND.
, .OR.
, .EQV.
, .NEQV.
In particular, it is forbidden to use “==
" with LOGICAL
, .EQV.
needs to be used instead
Derived data type
Derived data type is one of the main improvements of Fortran90 standard
The use of derived data types is strongly encouraged (see OpenRadioss Coding Recommendations ).
Derived data type allows to define new structured types
The name of a new type should use suffix _STRUCT_
Example:
! Example of data structure definition TYPE DUMMY_STRUCT_ INTEGER :: L_ITAB ! size of ITAB INTEGER :: L_RTAB ! size of RTAB INTEGER, DIMENSION(:) , POINTER :: ITAB ! integer pointer my_real, DIMENSION(:) , POINTER :: RTAB ! real pointer END TYPE DUMMY_STRUCT_ ! Definition of a variable of type DUMMY_STRUCT_ TYPE(DUMMY_STRUCT_), INTENT(INOUT) :: MY_DUM ! Use of the variable MY_DUM MY_DUM%L_ITAB = NITEMS1 MY_DUM%L_RTAB = NITEMS2 ALLOCATE(MY_DUM%ITAB(MY_DUM%L_ITAB),MY_DUM%RTAB(MY_DUM%L_RTAB), & STAT=ierror)
Intrinsic functions
Programmers are only allowed to use generic functions compatible with both single and double precision: SQRT
, SIN
, COS
, MAX
, MIN
, LOG
, EXP
, ...
Explicitly typed functions are prohibited: DSQRT
, DSIN
, DCOS
, AMAX1
, AMAX0
, AMIN1
, DMAX1
, DLOG
, DEXP
, ...
Numerical constants
All real constant variables are declared inside constant.inc common and initialized using INICONSTANT
routine (iniconstant.F)
Examples:
Forbidden:
A = MAX(B,1.E-20) CALL SUB(0.,2.*A)
Allowed:
A = MAX(B,EM20) CALL SUB(ZERO,DEUX*A)
EM20
, ZERO
and DEUX
declared in constant.inc
and initialized by INICONSTANT
Zero & infinite values
To avoid division by zero, it is advised to test against EM20
To avoid infinite value test against EP20
These values are generally a good compromise for both double and single precision
It is always possible to check version precision using flag IRESP
IRESP=1
: Double Precision version
IRESP=0
: Extended Single Precision version
Bitwise logical operations
Semantic of bitwise logical operators like AND
, XOR
, may vary from one compiler to another. It is advised to use C emulation functions
Note: my_and
, my_or
, my_shift
already exist
Interfacing Fortran and C
Calling convention
There is no standard calling convention between Fortran and C
Here is described the way it is handled in Radioss by defining every potential calling convention
Notice that the importance of this specific point is decreasing with the number of architectures and compilers supported
Fortran 90 calling routine:
... INTEGER :: L my_real :: A(*) ... CALL DUMMY(A,L) ...
C callee routine:
void dummy(a,l) double *a; int *l; { /* dummy function definition */ ... } void dummy_(a,l) double *a; int *l; { dummy(a,l); } void _FCALL DUMMY(a,l) double *a; int *l; { dummy(a,l); }
Note:
dummy
, dummy_
and DUMMY
share the 3 possible formats encountered
Argument variable correspondence
Fortran | C |
---|---|
|
|
|
|
|
|
Notes:
A variable of type my_real
is never transferred from Fortran to C directly, It is copied into a REAL
or DOUBLE PRECISION
variable first
Variable of type CHARACTER
should not be transferred from Fortran to C directly, It is mandatory to use INTEGER
conversion through conversion function ICHAR
at Fortran level and type (char)
at the C level
Every variable is passed by address at Fortran level, therefore a pointer variable must match at the C level
Examples of type definition under Linux and Windows
Type | Linux, Windows Size in Bytes |
---|---|
| 4 |
| 8 |
| 4 |
| 8 |
| 4 |
| 8 |
| 1 |
| 2 |
| 4 |
| 4 |
| 8 |
| 4 |
| 8 |
Specific code management
For some reason, some code may depend on a specific architecture or compiler. In this case, such code is gathered into a unique directory (one for Starter and one for Engine) called spe and spe_inc for include files
The rest of the code needs to be machine independent. This facilitates porting to new machine or compiler
The specific part of the code is managed by the precompiler using #ifdef
directives depending on the compiling architecture
The different supported architectures are defined under hardware.inc
A clean up of the supported architecture must be scheduled
- No labels