关于Visual Studio 2008:如何将内核文件CUDA与主.cpp文件分开

How to separate the kernel file CUDA with the main .cpp file

当我在同一文件mainFunc.cu中使用kernelAdd()函数和main()函数构建代码时,就可以了。

但是当我将kernelAdd.cu文件中的kernelAdd()函数与main.cpp文件中的主文件分开时,它是由以下2个错误构建的:

"错误C2065:'add':未声明的标识符"

和"错误C2059:语法错误:'<'"

我在Visual Studio 2008和Cuda v5.0中构建它们。

如何纠正其错误?

谢谢!

kernelAdd.cu

1
2
3
__global__ void add(int a, int b, int *c) {
*c = a + b;
}

mainFunc.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include"cuda_runtime.h"
#include"device_launch_parameters.h"
#include <stdio.h>
#include <conio.h>

int main(void) {

int c;
int *devC;

cudaMalloc((void**) &devC, sizeof(int));
add<<<1,1>>>(2,7,devC);
cudaMemcpy(&c, devC, sizeof(int), cudaMemcpyDeviceToHost);

printf("2+7=%d\
", c);

cudaFree(devC);

getch();
return 0;
}

error C2065: 'add' : undeclared identifier

此错误与CUDA无关。 add函数属于一个编译单元(kernelAdd.cu),而另一个编译单元(mainFunc.cpp)对此一无所知。为了提供此信息,您必须使用函数声明创建一个附加的头文件kernelAdd.h

1
__global__ void add(int a, int b, int *c);

并将其包含在mainFunc.cpp

1
#include"kernelAdd.h"

每个cucpp文件都是单独编译的,并且只知道它在包含的头文件中看到的功能。

error C2059: syntax error : '<'

现在我在这里猜测(没有VS,甚至没有Windows要检查),但是VS似乎根据其扩展名为项目中的每个文件选择了编译器。因此,mainFunc.cpp使用通用的C编译器进行编译,但是用于内核调用的<<<>>>语法不属于标准C,而是来自CUDA。所有特定于CUDA的语法必须仅在将要用nvcc编译的文件中使用。

因此,解决问题的一种方法是将mainFunc.cpp重命名为mainFunc.cu。当然,您仍然可以保留主文件.cpp,但是随后您将不得不将内核调用移至cu文件中的某些常规C函数,并将其公开在标准C头文件中,而您的.cpp文件将包含。


使C CUDA C唯一添加到C的是启动内核(<<<>>>)的三重尖括号语法。其他所有内容都使用现有的C功能。将函数指定为__global__将使nvcc为设备编译该函数并创建符号等,以便可以从主机调用该函数。

这意味着:

  • 设备代码(__global__功能等)必须位于.cu文件中。
  • 使用<<<>>>语法启动内核的主机代码必须位于.cu文件中。
  • 您仍然可以将所有其他主机代码保存在.cpp文件中,只需在.cu文件中放置一个Stubbing即可调用内核,例如void launch_add(...) { add<<<...>>>(...); }