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 函数是高亮的,使用函数名符号就会自动提示函数全称,参数类型等信息。