在Matlab中调用GPU的CUDA API进行并行加速,主要有两种途径:
1)对现有Matlab代码的简单改写,调用Matlab中支持CUDA的函数进行加速。
2)将C语言的CUDA函数封装成库,在Matlab中进行调用。
前者简单方便,效率低;后者效率高,稍微麻烦。
一、matlab中直接的gpu加速计算
matlab中直接做GPU计算分为三个步骤。
(1)数据的初始化
使用gpuArray()则可生成gpu端数据,a=gpuArray(b),即为将cpu端数据b拷贝到gpu端的a中。
(2)对GPU数据进行操作
可以使用matlab中的库函数对gpuarray直接进行操作。
(3)把GPU上的数据回传给CPU
使用gather()则可将gpu端的数据传回cpu端。
二、 Matlab中调用CUDA C
- 配置环境
(1)Matlab环境配置:
1mex -setupC 配置编译器。注:若c语言编译器和matlab版本不匹配系统会报错:找不到编译器活SDK等。配置成功后显示下图所示信息。
2 mex -setup c++ 选择语言,在编译器配置成功后选择所需的语言。配置成功后显示如下图所示信息。
Matlab环境配置结束。
(2)系统环境变量配置
打开电脑中的高级系统设置。选择环境变量,在系统变量的Path变量中添加所安装matlab文件夹中的extern\lib\win64\microsoft,matlab\lib\win64和matlab\bin\win64。如下图所示
系统变量配置结束。
(3)VS2015环境配置:
1打开VS中得项目工程文件,对项目进行属性设置,在解决方案资源管理器中选中项目,右键选择属性进行项目属性配置。如下图所示。
2在项目得属性页中对所有配置进行一下操作。首先对VC++ 目录栏中得包含目录及库目录进行配置。在包含目录中添加所安装matlab文件夹中的extern\include和extern\include\win64,在库目录中添加extern\lib\win64\microsoft。如下图所示。(本机matlab安装于D:\matlab文件夹。)
接着配置链接器,选择常规选项栏中得附加库目录进行编辑。添加所安装的Matlab文件夹中的extern\lib\win64\microsoft.如下图所示。
最后配置链接器输入选项栏中的附加依赖项。在附加依赖项中添加:libmat.lib
、libmx.lib、libmex.lib、libeng.lib如图所示。
现VS环境配置结束。
在matlab,VS2015和系统变量成功配置后即可进行matlab与CUDA C的混合编程。
- matlab中调用.cu程序
在对matlab的配置中安装了mex文件,MEX文件是一种可在matlab环境中调用的C语言(或fortran)衍生程序。
以matlab安装目录下的mexGPUExample.cu文件为例,该文件在所安装的matlab文件夹中的toolbox\distcomp\gpu\extern\src\mex夹内,在matlab中更改路径到相应的位置。如下图所示。
首先使用mexcuda针对该mexGPUExample.cu文件,生成其mex文件。在命令行输入mexcuda mexGPUExample.cu。如下图所示。
Mex文件生成成功会有如下显示,并生成相应的mex64文件
MEX文件的调用极为方便,其调用方式与MATALAB的内建函数完全相同,只需要在命令窗口内输入对应的文件名称即可。如下图所示。
- C语言MEX程序代码文件
C语言MEX程序代码文件有计算子例程(Computational routine)和接口子程序(GatWay routine)两个相互独立的子程序组成。其中,计算子例程的功能是完成所需要的计算,它和具有相同功能的一般C源程序文件相同;接口子程序的功能则是计算子程序和MATALAB的接口,用户实现两个不同内存空间中的通信。
接口函数:mexFunction
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
nlhs:输出参数数目
plhs:指向输出参数的指针
nrhs:输入参数数目
prhs:指向输入参数的指针
- 获得输入、输出参数
输入,输出参数的获取可以用两种方式
1读取mat数据文件
将matlab中所需要的数据以mat文件形式保存。如save(‘路径’,’变量名称’)。
之后则可在程序中对该mat文件数据进行读写操作。(注:所读写的文件按每一列依次操作)。
2使用接口函数传递参数
如:[a,b]=test(c,d,e)
c,d,e为3个输入参数,a,b为两个输出参数这里的输入输出参数的指针都是指向mxArray类型。当调用test函数时会将prhs[0]=c ,prhs[1]=d ,prhs[2]=e。在c语言程序中需要使用的是mxArray指针指向的数据。因此在需要对mxArray数据进行转换。mxGetPr函数从指向mxArray类型数据的prhs[0]获得了指向double类型的指针。再通过mxGetM和mxGetN来获得输入参数的行数和列数后即可构造相应的输入矩阵。
a,b为两个输出参数。a=plhs[0], b=plhs[1],因为输出参数的指针为指向mxArray类型,需对该数据构造相应的mxArray。
mxCreateDoubleMatrix(int m, int n, mxComplexity ComplexFlag)函数得到m*n矩阵大小的mxArray的指针,现即可放入plhs[],中传回。对输出参数的赋值与输入参数相同。
在完成了以上步骤之后即成功完成了matlab与cuda(c语言)的混合编程。