1

3 つのループ カーネルをベンチマークするための 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のダミー_でエラーが発生しています '

ダミー関数が呼び出されるたびに。なにか提案を?前もって感謝します。

4

3 に答える 3

3

iso_c_bindingこのサイトで何度も議論されているように、Fortran との最新のインターフェースは、C およびモジュールとの相互運用性です。

C からの FORTRAN サブルーチンの呼び出し

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

于 2013-04-29T21:12:59.287 に答える
3

Fortram プログラム内では、シンボルdummyは暗黙的なインターフェースを持つサブルーチンと見なされます。当然、Fortran コンパイラーはサブルーチンが Fortran サブルーチンになり、引数の受け渡し、リンカー名のマングリングなどを適切に調整します。

dummyプロシージャーは C 関数であり、Fortran サブルーチンではないため、問題が発生します。

ダミー シンボルが C 関数であることが Fortran コンパイラに明示的に通知されると、適切な変更が行われます。メインプログラムの仕様部分で:

INTERFACE
  SUBROUTINE dummy(array) BIND(C, NAME='dummy')
    IMPLICIT NONE
    DOUBLE PRECISION :: array(*)
  END SUBROUTINE 
END INTERFACE

堅牢なコードはさらに、配列引数の種類を適切に設定します。

于 2013-04-29T21:16:11.817 に答える
0

GNU コンパイラを使用する場合、C と Fortran では名前マングリングが少し異なることに注意してください。Fortran プログラムがサブルーチンを呼び出すxyz場合、対応する C サブルーチンの名前はxyz_.

したがって、あなたの場合、C ソースで名前を変更dummyするだけで十分です。dummy_私の記憶が正しければ、-lg2c とリンクする必要があるかもしれません。

于 2013-04-29T17:35:27.080 に答える