我写了一个fortran函数来调用blas level 3函数sgemm。我传递的矩阵要乘以这个函数并返回结果。代码有效,结果也正确。但是里面有一个印刷声明,它不会打印任何东西。为什么会这样?
function matmul(A,B) result(C)
real,dimension(:,:),allocatable::A
real,dimension(:,:),allocatable::B
real,dimension(:,:),allocatable::C
integer::m,n,k
m = size(A,1)
n = size(A,2)
k = size(B,2)
print *,"INSIDE FN"
call sgemm ('N','N',m,k,n,1.0,A,n,B,k,0.0,C,k)
end function matmul
答案 0 :(得分:0)
您选择的函数名称 MATMUL
是一个强大的内在函数(请参阅fortran标准的13.7.105部分或here)。您实现的函数尝试使用相同的名称“重载/遮蔽”此内在函数。这在Fortran中是可行的,但您必须明确地通知编译器。编译以下代码时:
function matmul(A,B) result(C)
real,dimension(:,:),allocatable::A,B,C
print *,"matmul overloaded"
C=A
end function matmul
program test
real, dimension(:,:), allocatable :: A,B,C
allocate(A(1,1),B(1,1),C(1,1))
C = matmul(A,B)
end program test
程序test
不了解您自己的matmul
子例程的存在和/或接口。程序test
和子程序matmul
都存在于两个未连接的程序单元中,因此,编译器将假定要调用内部MATMUL
函数。
EXTERNAL
属性(请参阅STDF2003::5.3.9)
由于编译器没有从程序单元matmul
访问用户test
代码的机制,因此它的接口是隐式。如果要指定名称matmul
是外部或虚拟过程之一,我们可以使用external
语句:
program test
external :: matmul
real, dimension(:,:), allocatable :: A,B,C
allocate(A(1,1),B(1,1),C(1,1))
C = matmul(A,B)
end program test
INTERFACE
阻止(请参阅STDF2003::12.4)
使用external
属性,您只需指定matmul
是外部或虚拟过程。它没有指定接口,它仍然是隐含的。但是,接口可以通过接口块定义为
program test
real, dimension(:,:), allocatable :: A,B,C
allocate(A(1,1),B(1,1),C(1,1))
interface
function matmul(A,B) result(C)
real,dimension(:,:),allocatable::A,B,C
end function matmul
end interface
C = matmul(A,B)
end program test
将函数matmul
放入模块并使用该模块时,会自动实现后者。
注意:从 Modern Fortran Explained, M. Metcalf, J. Reid and M. Cohen, (Oxford, 2013)
中广泛采用的信息