Fortran
Fortran (short for Formula Translation) is a programming language geared towards numerical computation.
Miscelaneous Notes
Equivalence Statement
The equivalence
statement allows different variable names to reference the same "data" (read as memory allocation).
A common paradigm in PHASTA is the use of temporary arrays to store the result of calculations that maybe reused multiple times.
For example, the function fun_prod
below calculates sum over i of [ 2* (a * b)_i + sqrt(a * b)_i ], where a and b are vectors:
real function fun_prod1(a, b) implicit none real, intent(in), dimension(4) :: a, b real, dimension(4) :: temp, sqrtab integer :: i temp = a*b sqrtab = sqrt(temp) temp = temp * 2. fun_prod1 = sum(temp + sqrtab) return end function fun_prod1
While reusing the temp
array for both a*b and 2*a*b is memory efficient (as we only need to have 2 1x4 arrays) and computationally efficient (as we calculate a*b only once), it's not very easy to read as the definition of temp
changes throughout the code.
To improve the legibility, we could set a*b and 2*a*b to be different variables instead:
real function fun_prod2(a, b) implicit none real, intent(in), dimension(4) :: a, b real, dimension(4) :: ab, ab2, sqrtab integer :: i ab = a*b sqrtab = sqrt(ab) ab2 = ab * 2. fun_prod2 = sum(ab2 + sqrtab) return end function fun_prod2
This is easier to read, as the contents of ab
and ab2
are far less ambiguous. However, note that we are less memory efficient than before; we now require 3 1x4 arrays compared to the previous 2. This may not seem like much, but memory speed is often the bottle-neck when it comes to HPC performance, so a 50% increase in required memory is significant.
However, using the equivalence
statement, we can get the best of both worlds:
real function fun_prod3(a, b) implicit none real, intent(in), dimension(4) :: a, b real, dimension(4) :: equiv__ab, equiv_2ab, sqrtab equivalence (equiv_ab, equiv_2ab) integer :: i equiv_ab = a*b sqrtab = sqrt(equiv_ab) equiv_2ab = equiv_ab * 2. fun_prod3 = sum(equiv_2ab + sqrtab) return end function fun_prod3
Here, eqab</code and <code>eq2ab
use the same memory, thus we only require 2 1x4 arrays. fun_prod3
is compiled as completely identical to fun_prod1
, but it's more easily readable.
Note: equivalence
can unexpected results if the programmer is not aware that two variables are made equivalent. That is why the variables ab
and ab2
in fun2_prod
were changed to equiv_ab</code and <code>equiv_2ab
. This serves as a reminder that variables with the prefix equiv_
belong to the same memory space, and thus cannot be treated as different.