对主要fortran程序的未定义引用

时间:2013-04-29 17:09:39

标签: c fortran fortran90 hpc intel-fortran

我正在编写一个用于对三个循环内核进行基准测试的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_'

每次调用虚函数。有什么建议吗?提前谢谢。

3 个答案:

答案 0 :(得分:3)

与Fortran接口的现代方式是与C和iso_c_binding模块的互操作性,正如本网站多次讨论的那样。

Calling a FORTRAN subroutine from C

https://stackoverflow.com/search?tab=votes&q=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。