2013-04-29 61 views
1

我写一个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."); 
} 

和虚置.h只是包含函数原型。

我做了一个dummy.o对象文件,我试图用英特尔ifort编译器将它与我的fortran源代码链接起来。不幸的是,我得到一个错误 在函数MAIN__':bench.f90:(.text+0x8ca): undefined reference to dummy_'

每次调用虚拟函数。任何建议?提前致谢。

回答

0

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

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

+0

我正在使用一个英特尔Ifort编译器,但让我试试你已经建议的编译器开关也许有链接问题。 – gmajal 2013-04-29 17:44:55

+0

你确定这是一个正确的开关,因为我的编译器似乎没有认出它?我使用它像icc -O3 -xHost -fno别名dummy.c -lg2c是否正确? – gmajal 2013-04-29 17:53:14

+0

那么,我回答了关于gcc编译器,而不是英特尔。 Hower,对于intel编译器,您仍然需要在C源代码中添加下划线。使用-lg2c可能没有必要(但在这里我不确定)。你也可以尝试使用Fortran编译器进行所有连接,而不是C编译器,那么你肯定不需要-lg2c。 – begemotv2718 2013-04-29 18:05:51

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 

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