MATLAB和CUDA配置(参考《GPU和MATLAB混合编程》)
目录
1、配置Matlab进行c-Mex编程
(1)查看电脑中安装的编辑器的位置
点击选择任意一个编辑器即可。
(2)在菜单中选择File-》New-》Script创建新的脚本。然后将新的脚本保存为test.cpp。
(3)在编译窗口中输入的代码如下:
#include"mex.h"
void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray* prhs[])
{
mexPrintf("Hello,mex!\n");
}
注意:需要在安装的matlab软件的bin文件下创建。
(4)在命令窗口运行以下指令:
mex test.cpp
成功后会生成如下文件:
(5)在命令窗口输入相应指令,即会出现相应的回应
2、MATLAB中的CUDA配置
(1)安装合适的CUDA.
在命令窗口输入下列指令:
system('nvcc')
得到的错误信息如下:
说明出现错误的原因是没有指定要编译的输入文件。
(2)实例:使用CUDA实现简单的向量加法
<1>在工作目录中创建AddVectors.h,输入以下代码并保存:
#ifndef __ADDVECTORS_H__
#define __ADDVECTORS_H__
extern void addVectors(float* A,float* B,float* C,int size);
#endif
<2>创建AddVectors.cu文件
#include"AddVectors.h"
#include"mex.h"
__global__ void addVectorsMask(float* A,float* B,float* C,int size)
{
int i=blockIdx.x;
if(i>=size)
{
return ;
}
C[i]=A[i]+B[i];
}
void addVectors(float* A,float* B,float* C,int size)
{
float *devPtrA=0,*devPtrB=0,*devPtrC=0;
cudaMalloc(&devPtrA,sizeof(float)*size);
cudaMalloc(&devPtrB,sizeof(float)*size);
cudaMalloc(&devPtrC,sizeof(float)*size);
cudaMemcpy(devPtrA,A,sizeof(float)*size,cudaMemcpyHostToDevice);
cudaMemcpy(devPtrB,B,sizeof(float)*size,cudaMemcpyHostToDevice);
addVectorsMask<<<size,1>>>(devPtrA,devPtrB,devPtrC,size);
cudaMemcpy(C,devPtrC,sizeof(float)*size,cudaMemcpyDeviceToHost);
cudaFree(devPtrA);
cudaFree(devPtrB);
cudaFree(devPtrC);
}
<3>使用-c选项编译简单的CUDA代码,生成目标文件。
该文件稍后将用于链接mex代码。
在命令窗口中输入以下指令:
system('nvcc -c AddVectors.cu')
显示如下 ,即表示成功
文件夹下生成如下文件:
注意:报错
解决方法:
system('nvcc -c AddVectors.cu -ccbin "D:\vs2017\VS\VC\Tools\MSVC\14.16.27023\bin\Hostx64\x64"')
后面路径为cl.exe所在的路径(一般安装的编辑器下的bin文件中)。
<4>创建mex函数,AddVectorsCuda.cpp
#include"mex.h"
#include"AddVectors.h"
void mexFunction(int nlhs,mxArray* plhs[],int nrhs,mxArray* prhs[])
{
if(nrhs!=2)
{
mexErrMsgTxt("Invaid number of input arguments");
}
if(nlhs!=1)
{
mexErrMsgTxt("Invaid number of outputs");
}
if(!mxIsSingle(prhs[0])&&!mxIsSingle(prhs[1]))
{
mexErrMsgTxt("input vector data type must be single");
}
int numRowsA=(int)mxGetM(prhs[0]);
int numColsA=(int)mxGetN(prhs[0]);
int numRowsB=(int)mxGetM(prhs[1]);
int numColsB=(int)mxGetN(prhs[1]);
if(numRowsA!=numRowsB||numColsA!=numColsB)
{
mexErrMsgTxt("Invalid size.The sizes of two vectors must be same");
}
int minSize=(numRowsA<numColsA)?numRowsA:numColsA;
int maxSize=(numRowsA>numColsA)?numRowsA:numColsA;
if(minSize!=1)
{
mexErrMsgTxt("input vector data type must be one dimentional");
}
float* A=(float*)mxGetData(prhs[0]);
float* B=(float*)mxGetData(prhs[1]);
plhs[0]=mxCreateNumericMatrix(numRowsA,numColsB,mxSINGLE_CLASS,mxREAL);
float* C=(float*)mxGetData(plhs[0]);
addVectors(A,B,C,maxSize);
}
<5>编译mex
mex AddVectorsCuda.cpp AddVectors.obj -lcudart -L"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.2\lib\x64"
成功后多一个文件:
注意:路径为CUDA的安装路径
<6>在Matlab中运行新的mex函数。
在命令窗口中,运行·: