When to use iso_Fortran_env, selected_int_kind, real (8), or -fdefault-real-8 to write or compile fortran code?
I have this simple code that uses a routine DGEMM
for matrix multiplication
program check
implicit none
real(8),dimension(2,2)::A,B,C
A(1,1)=4.5
A(1,2)=4.5
A(2,1)=4.5
A(2,2)=4.5
B(1,1)=2.5
B(1,2)=2.5
B(2,1)=2.5
B(2,2)=2.5
c=0.0
call DGEMM('n','n',2,2,2,1.00,A,2,B,2,0.00,C,2)
print *,C(1,1)
print *,C(1,2)
print *,C(2,1)
print *,C(2,2)
end program check
now when i compile this code using command
gfortran -o check check.f90 -lblas
I am getting some random garbage values. But when I add
-fdefault real 8
for the compilation options I am getting the correct values.
But since this is not a good way to declare variables in Fortran. So I used the inline module iso_fortran_env
and added two lines to the code
use iso_fortran_env
real(kind=real32),dimension(2,2)::A,B,C
and compiled with
gfortran -o check check.f90 -lblas
Again I got the wrong result. Where am I going wrong with this code? I am on 32 bit Linux and using GCC
source to share
DGEMM
expects double precision
values ββfor ALPHA
and BETA
.
Without options, you feed single precision floats into the LAPACK - hence the rubbish. By using -fdefault-real-8
, you are forcing each float listed as double by default and DGEMM
fed correctly.
In your case, the call should be:
call DGEMM('n','n',2,2,2,1.00_8,A,2,B,2,0.00_8,C,2)
which specifies the alpha value 1
as float of type 8 and zero of type 8 for beta.
If you want to perform single precision matrix-vector product use SGEMM
.
Note that this is very compiler specific, you must use REAL32
/ REAL64
from a module ISO_Fortran_env
(also for declaring A
, B
and C
).
source to share