2023年11月29日发(作者:)

关于CUDAC项⽬中“errorC2059:语法错误:“””问题的解决⽅

该问题的关键在于理解CUDA项⽬中CC++⽂件需要由c++编译器进⾏编译,⽽CUDA C的源⽂件需要由CUDA的编译器进

⾏编译。

发⽣该语法错误的原因是cu⽂件被C++编译器所编译,C++编译器⽆法识别 “<<<”,导致报错。

为什么cu⽂件会被C++编译器所编译呢?原因在于我们使⽤#include将cu⽂件包含到了C++⽂件中。对于#include的⽤途,更简单的

理解就是把⼏个⽂件合并成⼀个⽂件,所以,当编译C++⽂件中,包含其中的cu⽂件也会被编译,从⽽导致 “<<<”运算符被C++编译器编

译,导致语法错误。

问题原因:不能直接把cuda程序放⼊cpp中去调⽤,即核函数的调⽤语句add<<<2, 128>>>(dev_a, dev_b, dev_c,size); 不能出现

在 .cpp ⽂件中。

解决办法:可以在 .cu ⽂件中封装⼀层,就是在 .cu ⽂件中写⼀个传同样参数的核函数调⽤函数addKernel(int *a, int *b, int *c, int

size),即在addKernel(int *a, int *b, int *c, int size)函数中调⽤核函数add<<<2, 128>>>(dev_a, dev_b, dev_c,size),然后在外边

⽂件中⽤调⽤普通函数的⽅法调⽤addKernel, int size)

(int *a, int *b, int *c函数,此外需要在addKernel(int *a, int *b, int *c, int size)函数的

定义之处和⽂件头部将addKernel(int *a, int *b, int *c, int size)声明为外部函数,即需要⽤extern "C" 声明。这也是为什么在调⽤cu⽂件中核函数的间

接调⽤函数addKernel(int *a, int *b, int *c, int size)时我们需要使⽤ extern “C”

⽰例如下:

(1)创建⼀个CUDA 6.5 的项⽬,新建⼀个⽂件,添加代码如下:

#include

#include

//#include ""

#define N 256

extern "C" void addKernel(int *a, int *b, int *c, int size);

int main(int argc, char **argv)

{

int a[N];

int b[N];

int c[N];

for (int i=0; i

{

a[i]=i;

b[i]=2*i;

c[i]=0;

}

addKernel(a, b, c, N);

for(int i=0; i

{

printf("%d is %d.n", i, c[i]);

}

return 0;

}

(2)将⽂件清空后写⼊下述代码:

#include "cuda_runtime.h"

#include "device_launch_parameters.h"

__global__ void add(const int *a, const int *b, int *c, int size)

{

int tid = threadIdx.x + blockIdx.x * blockDim.x;

c[tid] = b[tid] + a[tid];

}

extern "C" void addKernel(const int *a, const int *b, int *c, int size)

{

int *dev_a=0;

int *dev_b=0;

int *dev_c=0;

cudaSetDevice(0);

cudaMalloc((void**)&dev_a, sizeof(int)*size);

cudaMalloc((void**)&dev_b, sizeof(int)*size);

cudaMalloc((void**)&dev_c, sizeof(int)*size);

cudaMemcpy(dev_a, a, sizeof(int)*size, cudaMemcpyHostToDevice);

cudaMemcpy(dev_b, b, sizeof(int)*size, cudaMemcpyHostToDevice);

cudaMemcpy(dev_c, c, sizeof(int)*size, cudaMemcpyHostToDevice);

add<<<2, 128>>>(dev_a, dev_b, dev_c,size);

cudaMemcpy(c, dev_c, size * sizeof(int), cudaMemcpyDeviceToHost);

cudaFree(dev_a);

cudaFree(dev_b);

cudaFree(dev_c);

}

(3)编译执⾏。结果如下所⽰

这时显⽰是成功的。

(4)把中的注释⾏取消注释,重新编译执⾏。结果如下所⽰:

出现⽂中所述问题。