C++ Cuda/c++;-Fortran-对Cuda函数的未定义引用

C++ Cuda/c++;-Fortran-对Cuda函数的未定义引用,c++,cuda,fortran,C++,Cuda,Fortran,如果这已经在某个地方解决了,我真的很抱歉,但我在任何地方都找不到任何解决方案。我正在尝试使用cuda编译一个基于Fortran的代码。我偶然发现了一些奇怪的错误,我可以用这个简单的例子重现这些错误 这是一个简单的操作,我们有cuda代码: cudatest.cu #include <stdio.h> #include <stdlib.h> #include <string.h> #include <cuda.h> #include <cuda

如果这已经在某个地方解决了,我真的很抱歉,但我在任何地方都找不到任何解决方案。我正在尝试使用cuda编译一个基于Fortran的代码。我偶然发现了一些奇怪的错误,我可以用这个简单的例子重现这些错误

这是一个简单的操作,我们有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;
}
以及生成文件:

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 BANAR/include”)

我正在使用刚刚安装的gfortran 4.8.1和Cuda 5.5。cuda代码本身编译得很好

同样,如果解决方案已经存在,我道歉。我可能已经找到了,但还不明白。提前谢谢你


编辑:我简化了整个程序,使问题更加清晰。

这个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
这也行得通,解决的办法是正确的顺序。首先是包含对库函数的引用的文件,然后是包含函数的库(调整库的路径):

程序的输出:

./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  

谢谢你,这很有效!那么,我的工作方式在任何情况下都能起作用吗?我必须使用nvcc来完成整个过程,因为在某个地方有cuda功能?
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