2014-02-25 113 views
1

如果這已經解決了某個地方,但我無法在任何地方找到任何解決方案,我真的很抱歉。我正在嘗試使用cuda編譯基於Fortran的代碼。我偶然發現了我能用this page這個簡單例子重現的奇怪錯誤。Cuda/C++ - Fortran - 未定義的Cuda函數引用

這是一個簡單的操作,我們有CUDA代碼:

cudatest.cu

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <cuda.h> 
#include <cuda_runtime.h> 

// function called from main fortran program 
extern "C" void kernel_wrapper_(float *a, int *Np) 
{ 
    float *a_d; // declare GPU vector copy 
    int N = *Np;  // N threads on GPU 

    // Allocate memory on GPU 
    cudaMalloc((void **)&a_d, sizeof(float) * N); 

    // free GPU memory 
    cudaFree(a_d); 
    return; 
} 

的Fortran代碼:

fortest.f95

PROGRAM fortest 

    IMPLICIT NONE 

    integer*4 :: i 
    integer*4, parameter :: N=8 
    real*4, Dimension(N) :: a 

    DO i=1,N 
    a(i)=i*1.0 
    END DO 

    print *, 'a = ', (a(i), i=1,N) 
    CALL kernel_wrapper(a, N) 
    print *, 'a = ', (a(i), i=1,N) 

END PROGRAM fortest 

而生成文件:

Test: fortest.f95 cudatest.o 
    gfortran -L/usr/local/cuda-5.5/lib64 -I/usr/local/cuda-5.5/include -lcudart -lcuda fortest.f95 cudatest.o 
cudatest.o: cudatest.cu 
    nvcc -c -O3 cudatest.cu 
clean: 
    rm a.out cudatest.o cudatest.linkinfo 

雖然試圖通過make編譯,我得到以下錯誤:

nvcc -c cudatest.cu 
gfortran -L /usr/local/cuda-5.5/lib64 -lcudart fortest.f95 cudatest.o 
cudatest.o: In function `kernel_wrapper_': 
tmpxft_00004a32_00000000-3_cudatest.cudafe1.cpp:(.text+0x31): undefined reference to `cudaMalloc' 
tmpxft_00004a32_00000000-3_cudatest.cudafe1.cpp:(.text+0x3d): undefined reference to `cudaFree' 
cudatest.o: In function `__cudaUnregisterBinaryUtil()': 
tmpxft_00004a32_00000000-3_cudatest.cudafe1.cpp:(.text+0x71): undefined reference to `__cudaUnregisterFatBinary' 
cudatest.o: In function `__sti____cudaRegisterAll_43_tmpxft_00004a32_00000000_6_cudatest_cpp1_ii_3bf9bcb9()': 
tmpxft_00004a32_00000000-3_cudatest.cudafe1.cpp:(.text+0x9a): undefined reference to `__cudaRegisterFatBinary' 
collect2: error: ld returned 1 exit status 
make: *** [Test] Erreur 1 

所以基本上,gfortran不知道,現在知道CUDA。我發現一些人遇到了同樣的問題,但似乎增加了cuda運行時庫(-lcudart)是所有人的解決方案。我注意到,如果我將cuda include目錄的名稱更改爲任何內容,編譯器並沒有真正注意到並噴出相同的錯誤(例如「cuda-5.5/include」爲「cuda-banana/include」)

我正在使用我剛剛安裝的gfortran 4.8.1和Cuda 5.5。 cuda代碼自行編譯。

再一次,如果解決方案已經在某處,我表示歉意。我可能已經找到它,但沒有理解它。先謝謝你 !

編輯:我簡化了整個程序,所以問題可以更清楚。

回答

0

這個Makefile適用於我的gcc 4.6和CUDA 4.2。主要觀點是與nvcc連接。

Test: fortest.o cudatest.o 
     nvcc -lgfortran -lgfortranbegin -L/usr/local/cuda-5.5/lib64 -I/usr/local/cuda-5.5/include -lcudart -lcuda fortest.o cudatest.o 
fortest.o: fortest.f95 
     gfortran -c -O5 fortest.f95 -o fortest.o 
cudatest.o: cudatest.cu 
     nvcc -c -O3 cudatest.cu 
clean: 
     rm a.out cudatest.o fortest.o cudatest.linkinfo 

這也適用,治療是有秩序的。首先包含到庫函數的引用,然後用該功能的庫文件(調整路徑庫):

Test: fortest.f95 cudatest.o 
    gfortran fortest.f95 cudatest.o -L/usr/local/cuda/lib64 -lcuda -lcudart 
cudatest.o: cudatest.cu 
    nvcc -c -O3 cudatest.cu 
clean: 
    rm a.out cudatest.o cudatest.linkinfo 

你的程序的輸出:

./a.out 
a = 1.0000000  2.0000000  3.0000000  4.0000000  5.0000000  6.0000000  7.0000000  8.0000000  
a = 1.0000000  2.0000000  3.0000000  4.0000000  5.0000000  6.0000000  7.0000000  8.0000000 
+0

謝謝你,它的工作原理!那麼我在任何情況下都可以這樣做嗎?我不得不使用nvcc來完成整個事情,因爲在某處有cuda功能? – user3350851

+0

請參閱編輯。 –