Matlab使用CUDA--利用cudamex

一、编写可供Matlab编译的CUDA代码

1、 待编译的程序需要包含的头文件

在项目中添加新建项 mexFunction.h,头文件内容如下

#ifndef _mexFunction_H
#define _mexFunction_H
 
#include "MatlabPath\extern\include\mex.h"
#include "MatlabPath\toolbox\parallel\gpu\extern\include\gpu\mxGPUArray.h"
 
#endif

MatlabPath是本机Matlab的安装目录,mex和mxGPUArray的文件路径可能与上述不符,在Matlab安装目录中搜索mex.h和mxGPUArray.h,将搜索结果所在的路径复制过来即可。
这里如果单独写了.h头文件也可以跟其他的放在一起,具体看程序。

2、待编译程序的程序入口函数mexFunction

与c语言不同,使用Matlab编译代码时的程序入口函数为mexFunction函数,函数定义规范为:

void mexFunction(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
{
    /**** 程序内容 ****/		
}

调用语句包括后面的参数都是固定的,
nlhs:输出参数数目 (Left-hand side)
plhs:指向输出参数的指针
nrhs:输入参数数目
prhs:指向输入参数的指针

例如,[a,b]=test(c,d,e)
利用mex函数调用test时,传给test的这三个参数分别是 prhs[0]=c ,prhs[1]=d ,prhs[2]=e
当函数返回时,将会把你放在plhs[0],plhs[1]里的地址赋给a和b,达到返回数据的目的。

3、参数传递方法

1、获取矩阵大小

//输入矩阵的行数
row = mxGetM(prhs[0]);
 
//输入矩阵的列数
column = mxGetN(prhs[0]);

2、给matlab分配动态内存空间–mxCalloc

void *mxCalloc(size_t n,size_t size)

参数定义:
n:分配空间的大小。
size:每个元素所占的字节。
返回值:
成功的话会返回一个指向一块动态分配的内存空间:
空间不足的时候mxCalloc将执行不成功。

//程序实例
(char*)mxCalloc(A, sizeof(char))

3、数据类型
(1)mxArray:
在VC中,所有和Matlab的数据交互都是通过mxArray来实现的。
创建任何数组前都需要加上mxArray。例如:

 mxArray* A[]

(2)mwSize:
图像的维度数及每一维度的大小的数据类型

//三维
const mwSize dims[] = { x, y, z };
//二维
const mwSize dim[] = { x, y };

(3)uint8_t
存放图像信息的矩阵的数据类型
4、mxGet类型系列
该类型函数的作用都是将matlab传入的数据复制到c风格的字符串中
mxGetString:获得字符串阵列的内容
mxGetData:获取指向真实数据的内容
mxGetPr:获取double类型阵列的实数部分的阵列内容
mxGetPi:虚数部分
mxGetScalar:获取标量(一个数值)类型的内容
mxGetLogicals:Logicals是逻辑值的意思,就是0、1这种数据/数组

//使用方式
#include "matrix.h"
double *mxGetPr(const mxArray *pm);
double *mxGetPi(const mxArray *array_ptr);

具体选择哪个函数获取阵列内容要根据matlab传入的数据类型确定,可以用7中的函数先判断是哪种类型的数据再获取。
5、mxCreat类型函数
(1)mxCreateDoulbeMatrix
创建二维的双精度浮点数组

//语法:
#include "matrix.h"
mxArray *mxCreateDoubleMatrix(mwSize m, mwSize n,
  mxComplexity ComplexFlag);

相似的还有:
mxCreateDoubleScalar:创建指向一个double标量的指针,并初始化。
mxCreateLogicalArray :逻辑值数组
mxCreateLogicalMatrix :逻辑值矩阵
mxCreateLogicalScalar :逻辑值标量
mxCreateNumericArray :数值数组
mxCreateNumericMatrix :数值矩阵

以mxCreateNumericArray为例,详细说明使用方法:
生成特定维度的矩阵

mxArray *mxCreateNumericArray(mwSize ndim, const mwSize *dims,
    mxClassID classid, mxComplexity ComplexFlag);
//使用示例
plhs[0] = mxCreateNumericArray(3, dims, mxSINGLE_CLASS, mxREAL);

参数含义:
ndim:创建的矩阵维度
dims:包含尺寸的数组
classid:类标识符,指定数据为哪种类型。Classid决定数值数据在内存中的表示方式。例如,mxCreateNumericMatrix将mxINT16_CLASS值存储为16位有符号整数。
ComplexFlag:复杂数组指示符,指定为mxComplexity值。矩阵中的元素类型依 mxComplexity 的值而定。
1>如果 mxComplexity 的值是 mxREAL 则矩阵中的元素类型全是实数,matlab会分配足够的空间来存放这些实数,并将这些实数初始化为0;
2>如果 mxComplexity 的值是 mxCOMPLEX ,则matlab分配足够的空间来存放这个复数空间(实部地址为 pr ,虚部地址为 pi ),实部和虚部都初始化为0。
classid与数据类型对应表:
在这里插入图片描述

6、mexToString函数
将matlab传入的字符串变量转为C/C++可识别的字符串,matlab与C/C++接口功能函数之一。
7、判断matlab传入数据类型API函数
mexIsScalar:判断参数是否为标量(一个数值)
mxIsDouble:是否为双精度浮点型(double型)
mxIsLogical:是否是布尔值(逻辑值)
mxIsSingle:是否是单精度浮点型(single型)
mxIsSparse:是否为稀疏数组
稀疏数组:只记录矩阵中有意义的数据点,其他为0的点位置不记录,普通矩阵是全部记录的。
mxIsStruct:是否是结构体

类似函数比较全面的总结表格查看这篇文章
8、mexErrMsgTxt
mexrmsgtxt将错误消息写入MATLAB®窗口。错误信息打印出来后,MATLAB终止mex文件并将控制权返回给MATLAB提示符。
9、

二、使用Matlab编译CUDA工程并调用

1、mexcuda编译指令

想要在Matlab中调用.cu文件的程序,需要先把.cu文件编译成mex cuda工程,编译需要在matlab中完成,具体的编译指令为:
官方文档
(1)如果工程中有多个源文件option1,option2,……,optionN,则需要输出使用到的所有源文件的路径,此处建议输入文件的完整路径(绝对路径),而非相对路径,例如:

mexcuda E:\Work\cudaSource1.cu...
E:\Work\cudaSource2.cu...
E:\Work\cSource1.cpp...
E:\Work\cSource2.cpp

(2)如果文件中使用了动态并行,则需要在对应的文件前面加上-dynamic,例如:

mexcuda -dynamic E:\Work\cudaDynamicSource1.cu ...
E:\Work\cudaNoDynamicSource2.cu ...
-dynamic E:\Work\cudaDynamicSource3.cu ...
E:\Work\cSource1.cpp ...

(3) 如果文件中使用了CUDA库函数(cufft、cublas等),则需要加入库函数路径,格式是
‘库函数完整文件路径’ -l+库函数名称,例如:

mexcuda  'C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.3\lib\x64\cufft.lib' -lcufft ...
-dynamic E:\Work\cudaDynamicSource1.cu ...
E:\Work\cudaNoDynamicSource2.cu ...
-dynamic E:\Work\cudaDynamicSource3.cu ...
E:\Work\cSource1.cpp ...

(4)保存写好的编译文件并执行,出现MEX已成功完成证明编译成功,此时文件夹中应该出现.mexw64执行文件,该文件名称与mexcuda指令后的第一个文件名保持一致,例如,(3)中生成的文件名称为cudaDynamicSource1.mewx64。

一般没有特殊需求,普通的编译文件只需要一行:

mexcuda -v 文件名***.cu

注意:
1、mexw64/mexa64文件是matlab下使用的一种特殊的函数封装形式。这种函数一般是用C/C++语言编写的,在使用的时候也像一个普通m文件一样按照文件名调用,只是不可能看到源码。
2、按照matlab的调用顺序规则,mex比m有更高的优先级,即只会调用***.mexa64而不调用***.m。
3、mexa64是linux64位下编译和使用的版本,不能在windows下用。windows64位下编译的是mexw64。

2、

参考文章:

https://blog.csdn.net/hsc0709/article/details/124182076
https://zhidao.baidu.com/question/1430803365903554779.html

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值