5

当我在同一个文件 mainFunc.cu 中使用 kernelAdd() 函数和 main() 函数构建代码时,没关系。

但是,当我将 kernelAdd.cu 文件中的 kernelAdd() 函数和 main.cpp 文件中的主文件分开时,它会产生 2 个错误:

“错误 C2065:‘添加’:未声明的标识符”

和“错误 C2059:语法错误:'<'”

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

我该如何纠正它的错误?

谢谢!

kernelAdd.cu

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

主函数.cpp

#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\n", c);

cudaFree(devC);

getch();
return 0;
}
4

2 回答 2

6

错误 C2065:“添加”:未声明的标识符

此错误与 CUDA 无关。该add函数属于一个编译单元 ( kernelAdd.cu),而另一个编译单元 ( mainFunc.cpp) 对此一无所知。为了给它这个信息,你必须创建一个kernelAdd.h带有函数声明的附加头文件:

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

并将其包含在mainFunc.cpp

#include "kernelAdd.h"

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

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

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

因此,解决问题的一种方法是重命名mainFunc.cppmainFunc.cu. 当然,您仍然可以保留主文件.cpp,但是您必须将内核调用移动到cu文件中的某些普通 C++ 函数,并将其公开在标准 C++ 头文件中,您的.cpp文件将包含该头文件。

于 2013-08-13T05:27:34.690 回答
3

对 C 进行 CUDA C 的唯一补充是用于启动内核 ( <<<>>>) 的三尖括号语法。其他一切都使用现有的 C 功能。指定函数 as__global__将导致 nvcc 为设备编译它并创建符号等,以便可以从主机调用它。

这意味着:

  1. 设备代码(__global__功能等)必须在 .cu 文件中。
  2. 使用该<<<>>>语法启动内核的主机代码必须位于 .cu 文件中。

您仍然可以将所有其他主机代码放在 .cpp 文件中,您只需在 .cu 文件中放置一个存根即可调用内核,例如void launch_add(...) { add<<<...>>>(...); }.

于 2013-08-13T10:46:58.220 回答