2013-04-29 3 views
1

Я пишу Фортран код для тестирования три ядра цикла:Неопределенная ссылка на главный Фортран

 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 

Фиктивной функция я написал внутри исходного файла Си следующего

#include "dummy.h" 

void dummy(double *array){ 
    printf ("Well if its printing this then you're pretty much screwed."); 
} 

и манекен .h просто содержит прототип функции.

Я создал объектный файл dummy.o, и я пытаюсь связать его с моим исходным кодом fortran, используя компилятор intel ifort. К сожалению, я получаю ошибку В функции MAIN__':bench.f90:(.text+0x8ca): undefined reference to dummy_ '

каждый раз, когда вызывается функция-пустышка. Любое предложение? Заранее спасибо.

ответ

0

Если вы используете компиляторы GNU, обратите внимание, что изменение имени немного отличается для C и Fortran. Если ваша подпрограмма программирования fortran xyz, то соответствующая подпрограмма C должна быть названа xyz_.

Так что в вашем случае достаточно переименовать dummy в dummy_ в источниках C. Вам также может потребоваться ссылка на -lg2c, если я правильно помню.

+0

Я использую компилятор intel Ifort, но позвольте мне попробовать переключатель компилятора, который вы предложили, возможно, есть проблема с привязкой. – gmajal

+0

Вы уверены, что это правильный переключатель, потому что мой компилятор, похоже, не узнает его? Я использую его как icc -O3 -xHost -fno-alias dummy.c -lg2c, это правильно? – gmajal

+0

Ну, я ответил на gcc-компилятор, а не на intel. Hower, для компилятора Intel вам все равно нужно добавить символ подчеркивания в источнике C. Использование -lg2c может быть необязательным (но здесь я не уверен). Вы также можете попытаться сделать все ссылки на компилятор fortran, а не на компилятор C, тогда вам не нужно -lg2c точно. – begemotv2718

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 

Надежный код также задает тип аргумента массива соответствующим образом.

Смежные вопросы