2013-04-29 62 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 

健壯的代碼會進一步適當地設置數組參數的種類。