我正在编写一个用于对三个循环内核进行基准测试的fortran代码:
program Kernel_benchmark
implicit none
double precision,dimension (:),save,allocatable:: a,b,c,d,x,y
double precision s
double precision,dimension (:,:),save,allocatable:: mat
double precision wcs,wce,ct,runtime, total
integer k,iter,r,i,j,N
do k = 3, 20
N = INT(2.5**k)
allocate (a(N),b(N),c(N),d(N))
do i=1,N
a(i) = 1.2
b(i) = 1.2
c(i) = 1.2
d(i) = 1.2
end do
iter = 1
runtime = 0.0
do while(runtime < 0.2)
call timing(wcs,ct)
do r =0, iter
do i=1,N
a(i) = b(i) + c(i) * d(i)
end do
if(a(ISHFT(N,-1)) < 0.0) then
call dummy(a)
end if
end do
call timing(wce,ct)
runtime = wce - wcs
iter = iter * 2
end do
iter = iter / 2
open(unit=1, file = 'vector_triad.dat',status = 'unknown')
write(1,*) N, (N * iter* 2) / (runtime * 1e-6)
close(1)
deallocate(a,b,c,d)
end do
do k = 3, 20
N = INT(2.5**k)
allocate(a(N))
do i = 1, N
a(i) = 1.2
end do
s = 2.2
iter = 1
runtime = 0.0
do while(runtime < 0.2)
call timing(wcs,ct)
do r = 0, iter
do i = 1, N
a(i) = s * a(i)
end do
if(a(ISHFT(N,-1)) < 0.0) then
call dummy(a)
end if
end do
call timing(wce,ct)
runtime = wce - wcs
iter = iter * 2
end do
iter = iter / 2
open (unit = 2, file = 'vector_update.txt', status = 'unknown' )
write(2,*) N, (N * iter) / (runtime * 1e-6)
close(2)
deallocate(a)
end do
do k = 10, 22
N = INT(1.5**k)
allocate (mat(N,N),x(N),y(N))
do i = 1, N
do j = 1, N
mat(i,j) = 1.2
end do
y(i) = 1.2
x(i) = 1.2
end do
iter = 1
runtime = 0.0
do while(runtime < 0.2)
call timing(wcs,ct)
do r = 0, iter
do i = 1, N
y(i) = 0.0
do j = 1, N
y(i) = y(i) + (mat(i,j) * x(i))
end do
end do
if(y(ISHFT(N,-1))< 0.0) then
call dummy(y)
end if
end do
call timing(wce,ct)
runtime = wce - wcs
iter = iter * 2
end do
iter = iter / 2
open (unit = 3, file = 'matrix_vector.txt', status ='unknown')
write(3,*) N, (2 * N * N * iter) / (runtime * 1e-6)
close(3)
deallocate(mat,x,y)
end do
end program Kernel_benchmark
我在C源文件中编写的虚函数如下
#include "dummy.h"
void dummy(double *array){
printf ("Well if its printing this then you're pretty much screwed.");
}
和dummy.h只包含函数原型。
我制作了一个dummy.o目标文件,我正在尝试使用intel ifort编译器将其与我的fortran源代码链接。不幸的是,我收到了一个错误
在函数MAIN__':bench.f90:(.text+0x8ca): undefined reference to
dummy_'
每次调用虚函数。有什么建议吗?提前谢谢。
答案 0 :(得分:3)
与Fortran接口的现代方式是与C和iso_c_binding
模块的互操作性,正如本网站多次讨论的那样。
答案 1 :(得分:3)
在Fortram程序中,符号dummy
被认为是具有隐式接口的子程序。自然地,Fortran编译器子程序将是一个Fortran子例程,并将适当地安排参数传递,链接器名称修改等。
因为dummy
过程是C函数而不是Fortran子例程,所以问题确实存在。
如果明确告知Fortran编译器虚拟符号是C函数,那么它将进行适当的更改。在主程序的规范部分:
INTERFACE
SUBROUTINE dummy(array) BIND(C, NAME='dummy')
IMPLICIT NONE
DOUBLE PRECISION :: array(*)
END SUBROUTINE
END INTERFACE
强大的代码会进一步适当地设置数组参数的类型。
答案 2 :(得分:0)
如果你使用GNU编译器,请注意C和Fortran的名称修改有点不同。如果您的fortran程序调用子例程xyz
,则相应的C子例程应命名为xyz_
。
因此,在您的情况下,在{C}来源中将dummy
重命名为dummy_
就足够了。如果我没记错的话,您可能还需要链接-lg2c。