一、首先安装CUDA软件包, 需要下载的东西有3个,分别是:
1.开发驱动(cuda-toolkit_3.2.7_win_32.msi)
2.工具包(devdriver_3.2_winvista-win7_32_260.61_notebook.exe)
3.SDK样例代码(gpucomputingsdk_3.2_win_32.exe)
需要注意的问题是,这三个工具的版本号一定要匹配、还有就是要跟自己的操作系统和硬件匹配。比如笔记本电脑应选择带有notebook字样的下载,64位系统的要选择64位版本。
下载完成后进行安装,过程比较简单,一路下一步即可。安装完驱动后需要重启电脑。
二、安装CUDA VS Wizard
安装完这些软件后,我们可以开始创建一个CUDA的程序了。网上有很多手动配置工程的方法,非常繁琐。我们基本上都会使用更加自动化的工具:CUDA VS Wizard,这个安装后会在VS中显示CUDA的项目模板。免去了繁琐的手工配置。这个工具的项目主页是:http://sourceforge.net/projects/cudavswizard/
下载的时候一定要根据自己系统的版本来选择32位还是64位的版本。如果操作系统是32位的,却安装了64位版本的Wizard,在vs中创建cuda project时就会出错。
三、配置
1、设置 VS2008 环境
打开 VS2008 ,选择菜单【工具 (Tools) 】 - 【选项 (Options) 】 - 【项目和解决方案 (Projects and Solutions) 】 - 【 VC++ 目录 (VC++ Directories) 】。
①在【包含文件 (Include Files) 】中添加(以下需按照自己的安装目录更改路径):
G:\win7 software\NVIDIA GPU Computing Toolkit\CUDA\v3.2\include
G:\win7 software\NVIDIA Corporation\NVIDIA GPU Computing SDK 3.2\C\common\inc
②在【库文件 (Library Files) 】中添加:
G:\win7 software\NVIDIA GPU Computing Toolkit\CUDA\v3.2\lib\Win32
G:\win7 software\NVIDIA Corporation\NVIDIA GPU Computing SDK 3.2\C\common\lib
③在【源文件 (Source Files) 】中添加:
G:\win7 software\NVIDIA GPU Computing Toolkit\CUDA\v3.2\src
G:\win7 software\NVIDIA Corporation\NVIDIA GPU Computing SDK 3.2\C\common\src
④选择【VC++ 项目设置 (VC++ Project Settins) 】,在【C/C++ 文件扩展名 (C/C++ File Extensions) 】中添加 *.cu ,在【包括的扩展名 (Extensions to Include) 】添加 .cuh 。
⑤选择【文本编辑器 (Text Editor) 】 - 【文件扩展名 (File Extension) 】,在编辑框中填入 cu ,在【编辑器 (Editor) 】下拉菜单中选择 Microsoft Visual C++ ,点击添加。
2、规则添加
此时如果运行 SDK Browser 中 browser.exe 自带的程序能过通过,则配置完成,否则将 CUDA toolkit 安装目录(如 G:\win7 software\NVIDIA GPU Computing Toolkit\CUDA\v3.2\extras\visual_studio_integration\rules )下的四个 rules 文件复制到 G:\win7 software\Microsoft Visual Studio 9.0\VC\VCProjectDefaults 目录下。
3、添加环境变量 / “没有找到 cutil32D.dll ”
添加环境变量(【计算机】 - 【属性】 - 【高级系统设置】 - 【高级】 - 【环境变量】)。随意取一个变量名,在变量值中填入类似如下的目录:
G:\win7 software\NVIDIA Corporation\NVIDIA GPU Computing SDK 3.2\C\bin\win32\Debug;
G:\win7 software\NVIDIA Corporation\NVIDIA GPU Computing SDK 3.2\C\bin\win32\Release;
G:\win7 software\NVIDIA Corporation\NVIDIA GPU Computing SDK 3.2\C\bin\win32\EmuDebug;
G:\win7 software\NVIDIA Corporation\NVIDIA GPU Computing SDK 3.2\C\bin\win32\EmuRelease;
在 Path 中添加:
%CUDA_DLL%\Debug;%CUDA_DLL%\Release;%CUDA_DLL%\EmuDebug;%CUDA_DLL%\EmuRelease;
如果没有添加环境变量,将会在运行时报错“没有找到 cutil32D.dll ”或其他。
还是没有找到的话:把debug文件里的dll放到…toolkit/CUDA/bin这个文件夹里。
4、编译 /“没有找到 cutil32D.lib ” “没有找到 cutil32.lib ”
编译sdk中的例子,验证cuda是否能正常使用,注意cuda工程中有*.sln文件(支持2005,2008,2010的都有),sln中的路径设置都是相对路径(有两种方式release和debug)。
注意的是,后面在运行cuda程序的时候有可能出现找不到库的情况,那是因为你没有对相应的源码进行编译,所以也可以有针对性的分别编译。必须编译的有:C\common中的src (别忘了release模式编译),这个是用来产生cutil的相关库的:cutil32.lib,cutil32.dll,cutil32D.dll,cutil32D.lib(D就是用debug编译的)。Shared中的src也要编译,这个是用来生成shrUtils32.lib的。
5、第三方软件Visual Assist X完成语法高亮和智能感知(语法提示)。
1. 如果希望程序可以高亮显示,则需要将 CUDA SDK 安装目录(比如在我的电脑上是 G:\win7 software\NVIDIA Corporation\NVIDIA GPU Computing SDK 3.2\C\doc\syntax_highlighting\visual_studio_8 )下的 usertype.dat 文件复制到 VS2008 安装目录 Microsoft Visual Studio 9.0\Common7\IDE 下。
2. 关闭VS2008。.进注册表HKEY_LOCAL_MACHINE/SOFTWARE /Microsoft/VisualStudio/9.0/Languages/File Extensions/下面添加子键.cu ,然后复制.cpp的键值到.cu。
3. HKEY_CURRENT_USER\Software\Whole Tomato\Visual Assist X\VANet9。在右边找到ExtSource项目,鼠标右键选修改,添加:.cu;.cuh; 关闭注册表。
4. 打开VS,点击VAssistX->Visual Assist X Options ……,然后就是Projects->C/C++ Directories,左边Platform中选Custom,右边“show Directories for”中选:“Other include files”,然后开始依次添加头文件路径:Sdk中的\c\common\inc;sdk中的\shared\inc;Toolkit中的CUDA\v4.0\include。
5. 打开vs2008。注意看一下__global__这些CUDA特有的关键字有没有被着色。最后在代码中敲cuda,然后就应该显示出一个以cuda开头的函数列表。如果这里也成功了,恭喜你~你的CUDA之旅可以起航了!
四、创建一个新的项目
1、创建一个空项目
打开 VS2008 ,选择菜单栏中的【文件】 - 【新建】 - 【项目】,选择【其他语言】 - 【 Win32 】 - 【 Win32 控制台应用程序】,填写名称创建解决方案。
在 Win32 应用程序向导的【附加选项】中勾选【空项目】。
右击项目名称,选择【自定义生成规则】,勾选【 CUDA Build Rule v3.0.0 】。
右击项目,选择【属性】,选择【配置属性】 - 【链接器】 - 【输入】,在附加依赖项中添加 cudart.lib cutil32D.lib 。否则在编译时会出现类似“ error LNK2019 无法解析的外部符号 ”的错误。
右击【源文件】文件夹,选择【添加】 - 【新建项】,选择【 CUDA 】,填写名称,新建一个 .cu 文件,点击【添加】。
2、使用 CUDA VS Wizard 创建新项目
打开 VS2008 ,选择菜单栏中的【文件】 - 【新建】 - 【项目】,选择【其他语言】 - 【 CUDA 】 - 【 CUDAWinApp 】,填写名称创建解决方案。
生成解决方案后,可以看到如下结构的项目,其中 sample.cu 为示例代码。
将其放到【源文件】文件夹中, Ctrl+F5 运行。
/*
* Copyright 徐洪志(西北农林科技大学.信息工程学院). All rights reserved.
* Data: 2012-4-15
*/
//
// 此程序是演示了vector型数据如何拷贝入、出显存
#include <cutil_inline.h>
#include <iostream>
#include <vector>
using namespace std;
///
//
// MAIN
//
///
int main(int argc, char** argv)
{
CUT_DEVICE_INIT(argc, argv); // 启动CUDA
int row, col;
/// Vector-->Device-->Host 1D
cout << "Vector-->Device-->Host 1D" << endl;
vector<int> vec; // Host端vector
int *gpu_data; // Device端data
int *cpu_data; // Host端data
int dataWd = 20;
cpu_data = (int*)calloc(dataWd, sizeof(int)); // 申请内存空间
cutilSafeCall( cudaMalloc((void**) &gpu_data, sizeof(int) * dataWd)); // 申请显存空间
cutilSafeCall( cudaMemset(gpu_data, 0, sizeof(float) * dataWd));
if((cpu_data == NULL)||(gpu_data == NULL)) // 判断空间是否申请成功
{
cout << "Alloc Memery Error" << endl;
return -1;
}
for(row = 0; row < dataWd; ++row) // 给Host端的vector初始化
vec.push_back(row);
cutilSafeCall( cudaMemcpy(gpu_data, &vec[0] , sizeof(int) * dataWd, cudaMemcpyHostToDevice)); // 将Host端vector拷贝入Device端data
cutilSafeCall( cudaMemcpy(cpu_data, gpu_data, sizeof(int) * dataWd, cudaMemcpyDeviceToHost)); // 将Device端data拷贝入Host端data
for(row = 0; row < dataWd; ++row) // 打印Host端data
cout << cpu_data[row] << " ";
cout << endl;
cutilSafeCall( cudaFree(gpu_data)); // 释放显存空间
free(cpu_data); // 释放内存空间
/// vector-->Device-->Host 2D
cout << "Vector-->Device-->Host 2D" << endl;
vector< vector<int> > vec2D; // Host端vector
int *cpu_data2D; // Host端data
int *gpu_data2D; // Device端data
size_t pitch; // 字节对齐
int Wd = 10; // 宽度
int Ht = 5; // 高度
cutilSafeCall( cudaMallocPitch((void**) &gpu_data2D, &pitch, sizeof(int) * Wd, Ht)); // 申请显存空间
cutilSafeCall( cudaMemset2D(gpu_data2D, pitch, 0, sizeof(int)*Wd, Ht)); // 显存空间初始化
cpu_data2D = (int*)calloc(Wd * Ht, sizeof(int)); // 申请内存空间
if((cpu_data2D == NULL)||(gpu_data2D == NULL)) // 判断空间是否申请成功
{
cout << "Alloc Memery Error" << endl;
return -1;
}
for(row = 0; row < Ht; ++row) // 初始化Vector
{
vector<int> temp;
for(col = 0; col < Wd; ++col)
{
temp.push_back(row+col);
}
vec2D.push_back(temp);
temp.clear();
}
cout << "Vetor2D" << endl;
for(row = 0; row < Ht; ++row)
{
for(col = 0; col < Wd; ++col)
cout << vec2D[row][col] << " ";
cout << endl;
}
// 将vector中的数据拷贝到Device端data
for(row = 0; row < Ht; ++row)
{
cutilSafeCall( cudaMemcpy(&gpu_data2D[row*(pitch/sizeof(int))], &vec2D[row][0], sizeof(int)*Wd, cudaMemcpyHostToDevice));
}
// 将Device端data拷贝到Host端data
cutilSafeCall( cudaMemcpy2D( cpu_data2D, sizeof(int) * Wd, gpu_data2D, pitch, sizeof(int) * Wd, Ht, cudaMemcpyDeviceToHost));
cout << "cpu_data2D" << endl; // 打印Host端data
for(row = 0; row < Ht; ++row)
{
for(col = 0; col < Wd; ++col)
{
cout << cpu_data2D[row*Wd + col] << " ";
}
cout << endl;
}
cutilSafeCall( cudaFree(gpu_data2D)); // 释放显存空间
free(cpu_data2D); // 释放内存空间
CUT_EXIT(argc, argv); // 退出CUDA
};