目前版本的cuda是很方便的,它的一个安装里面包括了Toolkit`SDK`document`Nsight等等,而不用你自己去挨个安装,这样也避免了版本的不同步问题。
1 cuda5.5的下载地址,官方网站即可:
https://developer.nvidia.com/cuda-downloads 在里面选择你所对应的电脑版本即可。
2 VS2010这个没什么说的了,网上各种的免费资源,下载一个不需要钱的就行。
3 Cuda的安装:(win7版32bit)
安装cuda
3.1 cuda的安装文件
直接双击exe文件,弹出后,首先会监测一下你的运行环境,如果找不到Nividia对应的显卡设备,他会提示你是否要继续安装。这里面nvidia的显卡,最起码也是8800以上的,要不是无法编写CUDA的。千万不要电脑上面是intel或者AMD的显卡,却要编写cuda,除非你有钱买一个cuda-x86这个编译器。
3.2 弹出的对话框直接OK就行,这个是CUDA的一些安装文件,无所谓的:
3.3 他会监测你的电脑是否支持cuda的搭建,等待就行
3.4 系统检查
3.5 选择同意并继续
3.6 推荐先选择自定义安装
3.7 最主要的是cuda document\cuda Toolkit \cuda samples(SDK),Nsight\图形驱动程序,3D如果需要的话安装,不安装也无所谓。这里主要就是能看见都有什么,免得漏掉了,博主当初就因为选了精简安装,没安装上SDK。
3.7 安装的位置,推荐自己建三个好找的文件夹,不用他默认的路径,免得稍后配置环境变量麻烦。
博主的安装路径为:
3.8 下一步安装就行了。
至此,cuda的安装就搞定了。
4 接下来配置cuda的环境变量,默认安装好后,他会自动帮你设置好2个环境变量,但是最好还自己添加下其他的几个,方便日后配置vs使用
上面的两个环境变量是cuda默认配置的,接下来添加
CUDA_BIN_PATH %CUDA_PATH%\bin
CUDA_LIB_PATH %CUDA_PATH%\lib\Win32
CUDA_SDK_BIN %CUDA_SDK_PATH%\bin\Win32
CUDA_SDK_LIB %CUDA_SDK_PATH%\common\lib\Win32
CUDA_SDK_PATH C:\cuda\cudasdk\common
添加完就行了
5 接下来是cuda的安装成功与否的监测了,这个步骤我们用到两个东西,这两个东西,都是cuda为我们准备好的。
deviceQuery.exe 和 bandwithTest.exe
首先启动cmd DOS命令窗口(博主的cuda安装到c:\cuda文件夹下)
默认进来的是c:\users\Admistrator\>路径,输入 cd .. 两次,来到c:目录下
输入dir 找到安装的cuda文件夹
进入Release文件夹后,直接执行bandwithTest.exe
再执行deviceQuery.exe
得到以上信息,因为我的显卡比较古老9300属于第一代的cuda显卡了。Rsult=PASS及说明,都通过了。如果Rsult=Fail 那不好意思,重新安装吧(或者是您的显卡真心不给力)。
关于VS项目测试(推荐)
打开VS,新建项目
利用安装好的cuda向导,直接建立工程,里面会自动有一段kernel累加的代码
在main函数return之前加入getchar(),停止自动退出,以便观测效果
进入后,点击运行按钮,可能发生LINK错误(如果没有错误,跳过此段)
这时进入-》项目-》属性-》通用配置-》输入和输出-》嵌入清单 ---- 修改成否,原来可能为“是”
再次编译,成功运行后,会显示下面的结果
恭喜,cuda已经在您的机器上安装成功了。
如果是新手,推荐这样新建工程后,在里面修改代码成为自己的工程,配置属性不会出错。
如果想要自己手动配置也可以参考下面的例子。
手动配置VS项目(不推荐)
最后就是VS的配置了(这个是自己手动配置的,有时候容易出现问题,不是很推荐,建议用上面的方法建立项目进行测试)
5.1 启动VS2010
5.2 新建一个win32的控制台工程,空的。
5.3 右键源文件文件夹->新建项->选择cuda c/c++->新建一个以.cu结尾的文件
5.4 右键工程-》生成自定义-》选择cuda生成
5.5 右键test.cu-》属性-》选择cuda c/c++编译器
5.6 右键工程-》属性-》链接器-》常规-》附加库目录-》添加目录 $(CUDA_PATH_V5_5)\lib\$(Platform);
5.7 在链接器-》输入中添加 cudart.lib
5.8 在工具-》选项-》文本编辑器-》文件扩展名-》添加cu \cuh两个文件扩展名
至此,编译环境的相关搭建就完成了。
下面提供了一段test.cu的代码,供测试使用:
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <cuda_runtime.h>
4
5 #define DATA_SIZE 1024
6 #define checkCudaErrors(err) __checkCudaErrors (err, __FILE__, __LINE__)
7 #define getLastCudaError(msg) __getLastCudaError (msg, __FILE__, __LINE__)
8
9 int data[DATA_SIZE];
10
11 ////
12 // These are CUDA Helper functions
13
14 // This will output the proper CUDA error strings in the event that a CUDA host call returns an error
15
16
17 inline void __checkCudaErrors(cudaError err, const char *file, const int line )
18 {
19 if(cudaSuccess != err)
20 {
21 fprintf(stderr, "%s(%i) : CUDA Runtime API error %d: %s.\n",file, line, (int)err, cudaGetErrorString( err ) );
22 return ;
23 }
24 }
25
26 // This will output the proper error string when calling cudaGetLastError
27
28
29 inline void __getLastCudaError(const char *errorMessage, const char *file, const int line )
30 {
31 cudaError_t err = cudaGetLastError();
32 if (cudaSuccess != err)
33 {
34 fprintf(stderr, "%s(%i) : getLastCudaError() CUDA error : %s : (%d) %s.\n",
35 file, line, errorMessage, (int)err, cudaGetErrorString( err ) );
36 return ;
37 }
38 }
39
40 // end of CUDA Helper Functions
41
42 __global__ static void sumOfSquares(int *num, int * result){
43 int sum=0;
44 int i;
45 for(i=0;i<DATA_SIZE;i++) {
46 sum += num[i]*num[i];
47 }
48 *result = sum;
49 }
50 void GenerateNumbers(int *number, int size){
51 for(int i = 0; i < size; i++) {
52 number[i] = rand() % 10;
53 printf("number[%d] is %d\n",i,number[i]);
54 }}
55
56 int main(){
57
58 cudaSetDevice(0);
59 cudaDeviceSynchronize();
60 cudaThreadSynchronize();
61
62 GenerateNumbers(data, DATA_SIZE);
63
64 int * gpudata, * result;
65 int sum;
66
67 checkCudaErrors( cudaMalloc((void**) &gpudata, sizeof(int)*DATA_SIZE));
68 checkCudaErrors(cudaMalloc((void**) &result, sizeof(int)));
69 checkCudaErrors(cudaMemcpy(gpudata, data, sizeof(int)*DATA_SIZE,cudaMemcpyHostToDevice));
70
71 sumOfSquares<<<1, 1, 0>>>(gpudata, result);
72
73 checkCudaErrors(cudaMemcpy(&sum, result, sizeof(int), cudaMemcpyDeviceToHost));
74
75 cudaFree(gpudata);
76 cudaFree(result);
77
78 printf("-----------sum: %d\n",sum);
79
80 sum = 0;
81 for(int i = 0; i < DATA_SIZE; i++) {
82 sum += data[i] * data[i];
83 }
84 printf("sum (CPU): %d\n", sum);
85
86 getchar();
87 return 0;
88 }
前言
本文讲解如何在VS 2010开发平台中搭建CUDA开发环境
当前配置:
系统:WIN7 64位
开发平台:VS 2010
显卡:英伟达G卡
CUDA版本:6.0
若配置不一样,请勿参阅本文。
第一步
点击这里下载 cuda最新版,目前最高版本是6.0。下载完毕后得到 cuda_6.0.37_winvista_win7_win8.1_general_64.exe 文件。
第二步
运行安装程序,弹出安装过程中转文件路径设定框:
这个路径随便填无所谓,安装完后就会自动删除的,我就直接设置为默认的。
第三步
等待系统帮你检测当前平台是否适合搭建CUDA:
第四步
检测完毕后,正式进入CUDA安装界面:
同意并继续
第五步
然后选择安装模式:
为了完全安装所有功能,选择自定义模式安装。
第六步
接下来勾选要安装的组件:
全部勾上
第七步
接下来要设置三个安装路径:
这三个路径安装的是什么在日后的文章中将会解释,目前先不理会,直接安装到默认路径。点击下一步之后开始正式安装。
第八步
安装完毕后,可以看到系统中多了CUDA_PATH和CUDA_PATH_V6_0两个环境变量,接下来,还要在系统中添加以下几个环境变量:
CUDA_SDK_PATH = C:\ProgramData\NVIDIA Corporation\CUDA Samples\v6.0
CUDA_LIB_PATH = %CUDA_PATH%\lib\x64
CUDA_BIN_PATH = %CUDA_PATH%\bin
CUDA_SDK_BIN_PATH = %CUDA_SDK_PATH%\bin\x64
CUDA_SDK_LIB_PATH = %CUDA_SDK_PATH%\common\lib\x64
然后,在系统变量 PATH 的末尾添加:
;%CUDA_LIB_PATH%;%CUDA_BIN_PATH%;%CUDA_SDK_LIB_PATH%;%CUDA_SDK_BIN_PATH%;
第九步
重新启动计算机以使环境变量生效
第十步
打开VS2010并建立一个空的win32控制台项目:
附加选项那里请把“空项目”打钩:
第十一步
右键源文件 -> 添加 -> 新建项 如下图所示:
在打开的对话框中选择新建一个CUDA格式的源文件 (如果你只是要调用 CUDA 库编写程序而不需要自行调用核函数分配块,线程的话也可以就建立 .cpp 的源文件):
第十二步
右键工程 -> 生成自定义 如下图所示:
在弹出的对话框中勾选“CUDA 6.0 *****"选项:
第十三步
右键项目 -> 属性 -> 配置属性 -> VC++目录,添加以下两个包含目录:
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v6.0\include
C:\ProgramData\NVIDIA Corporation\CUDA Samples\v6.0\common\inc
再添加以下两个库目录:
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v6.0\lib\x64
C:\ProgramData\NVIDIA Corporation\CUDA Samples\v6.0\common\lib\x64
第十四步
右键项目 -> 属性 -> 配置属性 ->连接器 -> 常规 -> 附加库目录,添加以下目录:
$(CUDA_PATH_V6_0)\lib\$(Platform)
如下图所示:
第十五步
右键项目 -> 属性 -> 配置属性 ->连接器 -> 输入 -> 附加依赖项,添加以下库:
cublas.lib cublas_device.lib cuda.lib cudadevrt.lib cudart.lib cudart_static.lib cufft.lib cufftw.lib curand.lib cusparse.lib nppc.lib nppi.lib npps.lib nvblas.lib (32位系统请勿附加此库!) nvcuvenc.lib nvcuvid.lib OpenCL.lib
如下图所示:
第十六步
右键项目 -> 属性,如下图所示:
将项类型设置为 CUDA C/C++:
第十七步
打开配置管理器,如下图所示:
点击 新建,如下图所示:
选择 X64 平台:
好了,至此平台已经完全搭建完毕,可用以下代码进行测试:
1 // CUDA runtime 库 + CUBLAS 库 2 #include "cuda_runtime.h" 3 #include "cublas_v2.h" 4 5 #include <time.h> 6 #include <iostream> 7 8 using namespace std; 9 10 // 定义测试矩阵的维度 11 int const M = 5; 12 int const N = 10; 13 14 int main() 15 { 16 // 定义状态变量 17 cublasStatus_t status; 18 19 // 在 内存 中为将要计算的矩阵开辟空间 20 float *h_A = (float*)malloc (N*M*sizeof(float)); 21 float *h_B = (float*)malloc (N*M*sizeof(float)); 22 23 // 在 内存 中为将要存放运算结果的矩阵开辟空间 24 float *h_C = (float*)malloc (M*M*sizeof(float)); 25 26 // 为待运算矩阵的元素赋予 0-10 范围内的随机数 27 for (int i=0; i<N*M; i++) { 28 h_A[i] = (float)(rand()%10+1); 29 h_B[i] = (float)(rand()%10+1); 30 31 } 32 33 // 打印待测试的矩阵 34 cout << "矩阵 A :" << endl; 35 for (int i=0; i<N*M; i++){ 36 cout << h_A[i] << " "; 37 if ((i+1)%N == 0) cout << endl; 38 } 39 cout << endl; 40 cout << "矩阵 B :" << endl; 41 for (int i=0; i<N*M; i++){ 42 cout << h_B[i] << " "; 43 if ((i+1)%M == 0) cout << endl; 44 } 45 cout << endl; 46 47 /* 48 ** GPU 计算矩阵相乘 49 */ 50 51 // 创建并初始化 CUBLAS 库对象 52 cublasHandle_t handle; 53 status = cublasCreate(&handle); 54 55 if (status != CUBLAS_STATUS_SUCCESS) 56 { 57 if (status == CUBLAS_STATUS_NOT_INITIALIZED) { 58 cout << "CUBLAS 对象实例化出错" << endl; 59 } 60 getchar (); 61 return EXIT_FAILURE; 62 } 63 64 float *d_A, *d_B, *d_C; 65 // 在 显存 中为将要计算的矩阵开辟空间 66 cudaMalloc ( 67 (void**)&d_A, // 指向开辟的空间的指针 68 N*M * sizeof(float) // 需要开辟空间的字节数 69 ); 70 cudaMalloc ( 71 (void**)&d_B, 72 N*M * sizeof(float) 73 ); 74 75 // 在 显存 中为将要存放运算结果的矩阵开辟空间 76 cudaMalloc ( 77 (void**)&d_C, 78 M*M * sizeof(float) 79 ); 80 81 // 将矩阵数据传递进 显存 中已经开辟好了的空间 82 cublasSetVector ( 83 N*M, // 要存入显存的元素个数 84 sizeof(float), // 每个元素大小 85 h_A, // 主机端起始地址 86 1, // 连续元素之间的存储间隔 87 d_A, // GPU 端起始地址 88 1 // 连续元素之间的存储间隔 89 ); 90 cublasSetVector ( 91 N*M, 92 sizeof(float), 93 h_B, 94 1, 95 d_B, 96 1 97 ); 98 99 // 同步函数 100 cudaThreadSynchronize(); 101 102 // 传递进矩阵相乘函数中的参数,具体含义请参考函数手册。 103 float a=1; float b=0; 104 // 矩阵相乘。该函数必然将数组解析成列优先数组 105 cublasSgemm ( 106 handle, // blas 库对象 107 CUBLAS_OP_T, // 矩阵 A 属性参数 108 CUBLAS_OP_T, // 矩阵 B 属性参数 109 M, // A, C 的行数 110 M, // B, C 的列数 111 N, // A 的列数和 B 的行数 112 &a, // 运算式的 α 值 113 d_A, // A 在显存中的地址 114 N, // lda 115 d_B, // B 在显存中的地址 116 M, // ldb 117 &b, // 运算式的 β 值 118 d_C, // C 在显存中的地址(结果矩阵) 119 M // ldc 120 ); 121 122 // 同步函数 123 cudaThreadSynchronize(); 124 125 // 从 显存 中取出运算结果至 内存中去 126 cublasGetVector ( 127 M*M, // 要取出元素的个数 128 sizeof(float), // 每个元素大小 129 d_C, // GPU 端起始地址 130 1, // 连续元素之间的存储间隔 131 h_C, // 主机端起始地址 132 1 // 连续元素之间的存储间隔 133 ); 134 135 // 打印运算结果 136 cout << "计算结果的转置 ( (A*B)的转置 ):" << endl; 137 138 for (int i=0;i<M*M; i++){ 139 cout << h_C[i] << " "; 140 if ((i+1)%M == 0) cout << endl; 141 } 142 143 // 清理掉使用过的内存 144 free (h_A); 145 free (h_B); 146 free (h_C); 147 cudaFree (d_A); 148 cudaFree (d_B); 149 cudaFree (d_C); 150 151 // 释放 CUBLAS 库对象 152 cublasDestroy (handle); 153 154 getchar(); 155 156 return 0; 157 }运行结果
PS: 矩阵元素是随机生成的