前言
最近接触了需要使用CUDA进行gpu并行计算的项目,在这里总结一下CUDA上手过程中遇到的问题以及相应的参考链接,最后是成功的搭建了环境,成功运行自己的c++结合cuda的项目。
1. 环境搭建
本人使用的是vs2019+cuda10.2;
安装的顺序最好是第一步安装好visual studio 2019,第二步安装(更新)自己的显卡对应的驱动,第三步安装与驱动版本号相匹配的cuda版本。
整个顺序的原因在于安装cuda时会检测driver是否兼容,并且安装cuda的最后会自动检测是否安装vs,以自动添加vs配置。
下附上对应下载链接:
Visual Studio dowload
NVIDIA driver
CUDA download
CUDA 官方文档
截至CUDA10.2的驱动版本对应关系:
正常来说此时CUDA环境已配置好。
新建一个工程,可以选择直接建立CUDA "ver"Runtime工程,或者建立一个控制台程序,
如果选择建立控制台项目,则需要在工程属性中设置一下CUDA依赖,使得vs可以找到CUDA,控制台的CUDA依赖设置参见下文的第二步:
https://blog.csdn.net/a12345676abc/article/details/86160226
设置成功后项目属性面板相比普通的控制台程序会多出两个cuda的属性页,如下图:
此时应该可以运行cuda示例代码了,但是如果编译时仍提醒无法找到cuda对应的源文件,请检查一下项目属性页->c/c++ ->附加包含目录,继承的值 是否包括$(CudaToolkitIncludeDir),如下图,如果没有,请手动编辑加上这一项。
2. 代码参考
我参考的是下面这篇文章中的代码,
CUDA编程入门(三)从矩阵加法例程上手CUDA编程
注意,该文中关于计时的函数是基于类Linux系统的,如果你是windows系统,可以注释掉那一部分代码。
3. 关于kernel函数中的threadId,block与grid概念
下文对此讲解比较详细,总结起来就是水平向右为cuda中线程矩阵排布的x方向,竖直向下为其y方向;在核函数(用globle或device修饰)中,经过grid-block-thread三层的id索引,可以确定执行当前这步计算的线程的id。
threadIdx,blockIdx, blockDim, gridDim之间的区别与联系
为了理解2中代码的线程与数据的对应关系,假设说数据矩阵是100*100维,同时也有100*100个线程被用来对这个数据进行计算,那么第id个线程正好来处理矩阵的第id位数据。
4. CUDA与Eigen
Eigen是一个开源C++线性代数库,现在在CUDA的核函数中可以调用部分Eigen中的函数功能
第一个问题
CUDA核函数只能调用一小部分简单的Eigen函数,很多Eigen函数尚不支持。
下面链接是说明文件,和调用Eigen成功或失败的案例。
Eigen支持CUDA的说明文档,内容很少
一个调用简单eigen函数成功的案例
一个调用Eigen函数失败的案例
目前我没能找到具体的Eigen中的哪些函数可以被CUDA核函数调用,如果有知道的小伙伴,欢迎补充。
第二个问题
编译CUDA文件的nvcc编译器对有些eigen无法编译,建议CPU上的Eigen计算单独写在一个.cpp文件中,而不要写在CUDA的.cu文件中,可以参考下篇文:
cuda与Eigen不兼容的解决方案
cuda内涵了很强大的cuBlas,cuSolver等线性计算库,有这一步需求的可以参考其官方文档。
其他
记录我遇到的其他问题,仅供参考
1.cuda编译出现lnk2019错误
2.目前的cuda好像不再支持x86系统