【问题标题】:Undefined reference to main fortran program对主 fortran 程序的未定义引用
【发布时间】:2013-04-29 17:09:38
【问题描述】:

我正在编写一个用于对三个循环内核进行基准测试的 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 目标文件,并尝试使用英特尔 ifort 编译器将它与我的 fortran 源代码链接。不幸的是,我遇到了一个错误 在函数MAIN__':bench.f90:(.text+0x8ca): undefined reference todummy_'

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

【问题讨论】:

    标签: c fortran fortran90 hpc intel-fortran


    【解决方案1】:

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

    Calling a FORTRAN subroutine from C

    https://stackoverflow.com/search?tab=votes&q=iso_c_binding

    【讨论】:

      【解决方案2】:

      在 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
      

      健壮的代码将进一步适当地设置数组参数的种类。

      【讨论】:

        【解决方案3】:

        如果您使用 GNU 编译器,请注意名称 mangling 对于 C 和 Fortran 有点不同。如果你的 fortran 程序调用子程序xyz,那么对应的 C 子程序应该命名为xyz_

        因此,在您的情况下,将 C 源代码中的 dummy 重命名为 dummy_ 就足够了。如果我没记错的话,您可能还需要链接 -lg2c。

        【讨论】:

        • 我正在使用英特尔 Ifort 编译器,但让我试试您建议的编译器开关,可能链接有问题。
        • 您确定这是一个正确的开关,因为我的编译器似乎无法识别它吗?我像 icc -O3 -xHost -fno-alias dummy.c -lg2c 一样使用它,对吗?
        • 好吧,我回答的是 gcc 编译器,而不是英特尔编译器。但是,对于英特尔编译器,您仍然需要在 C 源代码中添加下划线。使用 -lg2c 可能不是必需的(但我不确定)。您也可以尝试使用 fortran 编译器而不是 C 编译器进行所有链接,那么您肯定不需要 -lg2c。
        • 我也尝试过更改函数的名称,但它似乎仍然不起作用。我检查了一些此类示例问题,此错误可能是由于拼写错误而发生的,我检查了我的代码,但到目前为止一切似乎都是一致的。
        • 也许我的链接有问题。到目前为止,这就是我要做的事情:1)我制作了一个目标文件dummy.o:icc -O3 -xHost -fno-alias dummy.c -c 2)然后我试图将它们与fortran链接起来代码如下: ifort -O3 -xHost -fno-alias bench.f90 dummy.o timing.o -o bench 也许我不完全明白你想说什么,但不是 -o 你的意思是我使用 - lg2c 还是上面的行正确?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-01-15
        • 2016-06-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多