基于CUDA进行简单的矢量相加:
利用MATLAB2020b在UBANTU20.4系统上进行GPU矢量相加,遇到以下问题。
system('nvcc -c AddVectors.cu')
mex AddVectorsCuda.cpp AddVectors.o -lcudart -L"/usr/local/cuda/lib64"
成功生成AddVectors.o和AddVectorsCuda.mexa64文件,
但是,当输入
A = single([1 2 3 4 5 6 7 8 9 10]);
B = single([10 9 8 7 6 5 4 3 2 1]);
C = AddVectorsCuda(A,B);
进行测试时,报错:
MEX 文件
'/home/node/Desktop/ForwardModeling/GPU_in_MATLAB/AddVectorsCuda.mexa64' 无
效: 缺少入口函数
出错 Exs2_5ForTheBook (第 32 行)
C = AddVectorsCuda(A,B);
解决方法:
- 检查AddVectors.h 文件
#ifndef __ADDVECTORS_H__
#define __ADDVECTORS_H__
extern void addVectors(float*A, float*B, float*C, int size);
#endif // __ADDVECTORS_H__
- 检查AddVectors.cu 文件
#include "AddVectors.h"
#include "/usr/local/MATLAB/R2020b/extern/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);
}
- 检查 AddVectorsCuda.cpp 文件
#include "mex.h"
#include "AddVectors.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, mxArray *prhs[])
{
// line 7-14: 确保输入数据为 支持的数据类型 和 正确的矢量大小;
if(nrhs != 2)
mexErrMsgTxt("Invalid number of input arguments");
if(nlhs != 1)
mexErrMsgTxt("Invalid 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 size of two vectors must be same");
int minSize = (numRowsA < numColsA) ? numRowsA : numColsA;
int maxSize = (numRowsA > numColsA) ? numRowsA : numColsA;
if(minSize != 1)
mexErrMsgTxt("Invalid size. The vector must be dimensional");
float*A = (float*)mxGetData(prhs[0]);
float*B = (float*)mxGetData(prhs[1]);
// Herein,创建output矢量,承接加法运算的结果
plhs[0] = mxCreateNumericMatrix(numRowsA, numColsB, mxSINGLE_CLASS, mxREAL);
float*C = (float*)mxGetData(plhs[0]);
// call基于CUDA的函数,执行加法运算
addVectors(A, B, C, maxSize);
}
麻蛋,没找到原因,暂且搁置。
17: 26 找到原因: AddVectorsCuda.cpp 文件:
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, mxArray *prhs[])
change as:
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])