何时在编写或编译Fortran代码时使用iso_Fortran_env、selected_int_kind、real(8)或-fdefault-real-8?

3
我有一段简单的代码,使用 DGEMM 例程进行矩阵乘法。
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

现在,当我用命令编译这段代码时

gfortran -o check check.f90   -lblas 

我得到了一些随机的垃圾值。但是当我在编译选项中添加

-fdefault-real-8

后,我得到了正确的值。

但由于这不是Fortran中变量声明的好方法。因此,我使用了iso_fortran_env内置模块,并在代码中添加了两行。

use iso_fortran_env
real(kind=real32),dimension(2,2)::A,B,C

编译时使用

 gfortran -o check check.f90 -lblas

我又得到了错误的输出。 请问这段代码哪里出错了? 我的系统是32位Linux,使用的编译器是GCC。

1个回答

2

DGEMM 期望使用 double precision 值作为 ALPHABETA 参数。

如果不加任何选项,你会向 LAPACK 传递单精度浮点数,因此会出现垃圾数据。通过使用 -fdefault-real-8 选项,可以强制所有指定的浮点数默认为双精度,从而正确地传递给 DGEMM

在你的情况下,应该调用如下:

call DGEMM('n','n',2,2,2,1.00_8,A,2,B,2,0.00_8,C,2)

该语句指定alpha的值为8号浮点数中的1,beta的值为8号浮点数中的0

如果您想在单精度下进行矩阵向量乘积,请使用SGEMM

请注意这与编译器有关,应考虑改用ISO_Fortran_env模块中的REAL32/REAL64(也适用于代码中的ABC的声明)。


2
很好,我错过了默认的实数常量。理论上,在调用BLAS时,双精度仍然比real64更可靠,但在绝大多数情况下它都能正常工作。 - Vladimir F Героям слава
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Alexander Vogt
这并不保证一切。如果某个处理器的默认实数为64位,则double为128位,而real64将等同于单精度而不是双精度。 - Vladimir F Героям слава
谢谢你帮助我。 - pauli
@VladimirF 如果在默认双精度为128位的处理器上将real64传递给DEMM,会导致错误吗? - user15964

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接