關於CUDA C 項目中“ error C2059: 語法錯誤:“<” ”問題的解決方法


  該問題的關鍵在於理解CUDA項目中C\C++文件需要由c++編譯器進行編譯,而CUDA C的源文件需要由CUDA的編譯器nvcc.exe進行編譯。

       發生該語法錯誤的原因是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),然后在外邊main.cpp文件中用調用普通函數的方法調用addKernel(int *a, int *b, int *c, int size)函數,此外需要在addKernel(int *a, int *b, int *c, int size)函數的定義之處和main.cpp文件頭部將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 的項目,新建一個main.cpp文件,添加代碼如下:

#include <stdio.h>  
#include <stdlib.h>  
//#include "kernel.cu"  
   
#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<N; i++)  
  {  
    a[i]=i;  
    b[i]=2*i;  
    c[i]=0;  
  } 
  addKernel(a, b, c, N);     
  for(int i=0; i<N; i++)  
  {  
    printf("%d is %d.\n", i, c[i]);  
  }  
   return 0;  
}

(2)將kernel.cu文件清空后寫入下述代碼:

#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)把main.cpp中的注釋行取消注釋,重新編譯執行。結果如下所示:

出現文中所述問題。

 

參考鏈接:

1、關於CUDA C 項目中“ error C2059: 語法錯誤:“<” ”問題的解決方法

2、調用cuda程序<<<>>>部分報錯error C2059: 語法錯誤:“<“

3、VS2012安裝CUDA

4、VS中CUDA與C++工程項目的配置


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM