如果这已经在某个地方得到解决,我真的很抱歉,但我无法在任何地方找到任何解决方案。我正在尝试使用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代码可以很好地编译。
同样,如果解决方案已经存在,我道歉。我可能已经找到它但不理解它。提前谢谢!
编辑:我简化了整个计划,因此问题可以更清晰。答案 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