【问题标题】:Cuda/c++ - Fortran - Undefined reference to Cuda functionsCuda/c++ - Fortran - 对 Cuda 函数的未定义引用
【发布时间】:2014-02-25 22:11:37
【问题描述】:

如果这已经在某个地方解决了,我真的很抱歉,但是我在任何地方都找不到任何解决方案。我正在尝试使用 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 包含目录的名称更改为任何名称,编译器不会真正注意到并发出相同的错误(例如“cuda-5.5/include”到“cuda-banana/include”)

我正在使用我刚刚安装的 gfortran 4.8.1 和 Cuda 5.5。 cuda 代码可以自行编译。

再次,如果解决方案已经在某处,我深表歉意。我可能已经找到它但不理解它。提前谢谢你!

编辑:我简化了整个程序,这样问题就更清楚了。

【问题讨论】:

    标签: c++ cuda fortran


    【解决方案1】:

    这个 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  
    

    【讨论】:

    • 谢谢,它有效!那么我的做法在任何情况下都能奏效吗?我不得不使用 nvcc 来完成整个事情,因为某处有 cuda 功能?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-06-14
    • 2021-07-14
    • 2021-02-12
    • 2018-05-07
    • 2014-11-16
    • 2016-07-21
    相关资源
    最近更新 更多