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

时间:2014-02-25 12:11:03

标签: c++ cuda fortran

如果这已经在某个地方得到解决,我真的很抱歉,但我无法在任何地方找到任何解决方案。我正在尝试使用cuda编译基于Fortran的代码。我偶然发现了我能够使用this page中的简单示例重现的奇怪错误。

这是一个简单的操作,我们有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

和makefile:

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代码可以很好地编译。

同样,如果解决方案已经存在,我道歉。我可能已经找到它但不理解它。提前谢谢!

编辑:我简化了整个计划,因此问题可以更清晰。

1 个答案:

答案 0 :(得分: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  
相关问题