CUDA與VS2013使用
目錄
2.2 CUDA 函數高亮,及CUDA 函數輸入代碼提示 12
1. 在Visual Studio的CUDA開發方法
1.1 自動配置 (推薦)
可以通過VS2013提供的CUDA模板進行自動配置。打開VS,新建項目,選擇CUDA 7.0 Runtime,從而生成一個類似"hello world"的程序,這是VS自動生成一個累贅的代碼,如下圖所示。
若存在編譯錯誤,則在:項目屬性à配置屬性à清單工具à輸入和輸出à嵌入清單中的下拉框中,選擇"否";
1.2 手動配置(不推薦)
如果是新手,推薦使用自動配置方式來新建工程后,在里面修改代碼成為自己的工程,配置屬性不會出錯。若是進行手動配置也是可以的,只是進行的配置非常繁瑣。手動配置需要進行的操作如下:
1.2.1 新建Win32控制台應用程序
為了演示手動配置的方法,首先新建一個Win32的控制台項目,然后添加一些CUDA代碼,完成一些必備的工作。
1.2.2 添加CUDA依賴庫
為了使用Visual Studio工具進行CUDA編程,需要添加CUDA的依賴庫,使其可以調用CUAD的API.
1.2.3 添加.cu文件
在Visual Studio進行CUDA編程,是以.cu文件進行編程,類似於C++常以.cpp文件一樣。所以為了使用CUDA,需在VS中添加.cu文件,其操作方式是:右鍵源文件文件夾->新建項->選擇cuda c/c++->新建一個以.cu結尾的文件。
在main.cu文件中添加自動配置生成的代碼,若手動配置后的代碼能執行與自動配置執行一樣的程序,那么說明手動配置成功,代碼如下:
2
3 #include " device_launch_parameters.h "
4
5 #include <stdio.h>
6
7 cudaError_t addWithCuda( int *c, const int *a, const int *b, unsigned int size);
8
9 __global__ void addKernel( int *c, const int *a, const int *b){
10
11 int i = threadIdx.x;
12
13 c[i] = a[i] + b[i];
14
15 }
16
17 int main(){
18
19 const int arraySize = 5;
20
21 const int a[arraySize] = { 1, 2, 3, 4, 5 };
22
23 const int b[arraySize] = { 10, 20, 30, 40, 50 };
24
25 int c[arraySize] = { 0 };
26
27
28
29 // Add vectors in parallel.
30
31 cudaError_t cudaStatus = addWithCuda(c, a, b, arraySize);
32
33 if (cudaStatus != cudaSuccess) {
34
35 fprintf(stderr, " addWithCuda failed! ");
36
37 return 1;
38
39 }
40
41
42
43 printf( " {1,2,3,4,5} + {10,20,30,40,50} = {%d,%d,%d,%d,%d}\n ",
44
45 c[ 0], c[ 1], c[ 2], c[ 3], c[ 4]);
46
47
48
49 // cudaDeviceReset must be called before exiting in order for profiling and
50
51 // tracing tools such as Nsight and Visual Profiler to show complete traces.
52
53 cudaStatus = cudaDeviceReset();
54
55 if (cudaStatus != cudaSuccess) {
56
57 fprintf(stderr, " cudaDeviceReset failed! ");
58
59 return 1;
60
61 }
62
63
64
65 return 0;
66
67 }
68
69 cudaError_t addWithCuda( int *c, const int *a, const int *b, unsigned int size){
70
71 int *dev_a = 0;
72
73 int *dev_b = 0;
74
75 int *dev_c = 0;
76
77 cudaError_t cudaStatus;
78
79
80
81 cudaStatus = cudaSetDevice( 0);
82
83 if (cudaStatus != cudaSuccess) {
84
85 fprintf(stderr, " cudaSetDevice failed! Do you have a CUDA-capable GPU installed? ");
86
87 goto Error;
88
89 }
90
91 cudaStatus = cudaMalloc(( void**)&dev_c, size * sizeof( int));
92
93 if (cudaStatus != cudaSuccess) {
94
95 fprintf(stderr, " cudaMalloc failed! ");
96
97 goto Error;
98
99 }
100
101 cudaStatus = cudaMalloc(( void**)&dev_a, size * sizeof( int));
102
103 if (cudaStatus != cudaSuccess) {
104
105 fprintf(stderr, " cudaMalloc failed! ");
106
107 goto Error;
108
109 }
110
111 cudaStatus = cudaMalloc(( void**)&dev_b, size * sizeof( int));
112
113 if (cudaStatus != cudaSuccess) {
114
115 fprintf(stderr, " cudaMalloc failed! ");
116
117 goto Error;
118
119 }
120
121 // Copy input vectors from host memory to GPU buffers.
122
123 cudaStatus = cudaMemcpy(dev_a, a, size * sizeof( int), cudaMemcpyHostToDevice);
124
125 if (cudaStatus != cudaSuccess) {
126
127 fprintf(stderr, " cudaMemcpy failed! ");
128
129 goto Error;
130
131 }
132
133 cudaStatus = cudaMemcpy(dev_b, b, size * sizeof( int), cudaMemcpyHostToDevice);
134
135 if (cudaStatus != cudaSuccess) {
136
137 fprintf(stderr, " cudaMemcpy failed! ");
138
139 goto Error;
140
141 }
142
143 // Launch a kernel on the GPU with one thread for each element.
144
145 addKernel << < 1, size >> >(dev_c, dev_a, dev_b);
146
147
148
149 // Check for any errors launching the kernel
150
151 cudaStatus = cudaGetLastError();
152
153 if (cudaStatus != cudaSuccess) {
154
155 fprintf(stderr, " addKernel launch failed: %s\n ", cudaGetErrorString(cudaStatus));
156
157 goto Error;
158
159 }
160
161
162
163 // cudaDeviceSynchronize waits for the kernel to finish, and returns
164
165 // any errors encountered during the launch.
166
167 cudaStatus = cudaDeviceSynchronize();
168
169 if (cudaStatus != cudaSuccess) {
170
171 fprintf(stderr, " cudaDeviceSynchronize returned error code %d after launching addKernel!\n ", cudaStatus);
172
173 goto Error;
174
175 }
176
177 // Copy output vector from GPU buffer to host memory.
178
179 cudaStatus = cudaMemcpy(c, dev_c, size * sizeof( int), cudaMemcpyDeviceToHost);
180
181 if (cudaStatus != cudaSuccess) {
182
183 fprintf(stderr, " cudaMemcpy failed! ");
184
185 goto Error;
186
187 }
188
189 Error:
190
191 cudaFree(dev_c);
192
193 cudaFree(dev_a);
194
195 cudaFree(dev_b);
196
197 return cudaStatus;
198 }
1.2.4 配置環境編譯器
由於CUDA編程中,host和device使用不同的編譯器進行編譯,而具體到開發平台上時,VS是根據文件的后綴來識別不同的文件並進行編譯,即CUDA和C/C++文件使用不同的編譯器,所以需要為CUDA指定編譯器。其操作過程為:
右鍵test.cu->屬性->選擇cuda c/c++編譯器
1.2.5 配置連接器:常規
配置連接器是指為CUDA編程指定需要的庫文件,其操作過程為:
右鍵工程->屬性->鏈接器->常規->附加庫目錄->添加目錄 $(CUDA_PATH_V5_5)\lib\$(Platform);
1.2.6 配置連接器:輸入
在鏈接器->輸入中添加 cudart.lib
1.2.7 編譯完成
至此,編譯環境的相關搭建就完成了,運行程序的結果與自動配置一樣,如下圖所示,從而表明手動配置成功。
2. CU文件關鍵詞及函數高亮顯示
本節參考網絡地址為:博客地址;
2.1 cu 文件中C/C++關鍵字高亮
這個設置是讓Visual Studio2013 在編輯.cu 文件時,把.cu 文件里的 C/C++語法高亮。
設置方法: 在Visual Studio 2013 的菜單依次選 " Tools|Options|Text Editor|File Extension(工具|選項|文本編 輯器|文件擴展名)",在該窗口中將"Editor(編輯器)"下拉框選擇"Microsoft Visual C++",在"Extension(擴展名)"文本框中輸入cu 點擊"Add(添 加)"按鈕,重復工作把cuh 添加為Visual C++類型,添加完成后點擊"OK (確定)"按鈕,如下圖所示。
2.2 CUDA 函數高亮,及CUDA 函數輸入代碼提示
實現這個功能需要使用Visual Assist X,如果沒有安裝支持Visual Studio 2010 的Visual Assist X,這部分功能無法實現。這里只是為使編寫代碼更加方便,對 與CUDA 程序的開發無實質性障礙。
如果已經安裝Visual Assist X,可以通過以下兩步實現需要的功能。
1) 使Visual Assist X 支持CUDA 函數高亮和代碼完成
在Visual Studio 2013的菜單里依次選擇:"VAssistX|Visual assist X Options|Projects|C/C++Directories",在該界面的"Platform"下拉框中選 擇Custom,在"Show Directories for"下拉框中選擇Other include files, 然后在下面的輸入框里,新建、添加如下路徑,如下圖:
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v7.0\include
C:\ProgramData\NVIDIA Corporation\CUDA Samples\v7.0\common\inc
2) 使Visual Assist X 支持CUDA 函數高亮和代碼完成
使Visual Assist X 實現.cu 文件高亮和代碼完成功能,需要編輯注冊表。 在修改注冊表時,為避免帶來不必要的錯誤請先關閉Visual Studio 2013。 使用Win+R組合鍵打開"運行"窗口,鍵入入regedit 命令(register edit 的縮寫)
打開注冊表,找到如下位置: HKEY_CURRENT_USER\Software\Whole Tomato\Visual Assist X\VANet10。在右邊找到ExtSource 項目,鼠標右鍵選修改,在原有文字后 添加如下文字:.cu;.cuh; 確定后關閉注冊表。
重新打開Visual Studio 2010,Visual Assist X 便開始支持.cu 及.cuh 文件的語法高亮及代碼完成。此時.cu 文件的CUDA 函數是高亮的,使用函數名符號就會自動提示函數全稱,參數類型等信息。