GPU&VS2012&CUDA&matlab&Arrayfire杂记(五)——square的例子

时间:2021-10-30 16:12:42
这个地主要学习了《实战matlab并行程序设计》中的square这个例子

先建一个CUDA工程,然后.cu文件,把代码敲入
#include"mex.h"
#include"cuda.h"
#include "cuda_runtime.h"
#include "cuda.h"
#include "device_launch_parameters.h"
 #include <iostream>
 #include <cstdlib>
__global__ void square_elements(float* in,float * out ,int N)
{
        int idx =blockIdx.x*blockDim.x+threadIdx.x;
        if (idx<N)out[idx]=in[idx]*in[idx];
}
void mexFunction (int nlhs,mxArray *plhs[],int nrhs ,const mxArray *prhs[])
{
    int i,j,m,n;
    double *data1,*data2;
    float *data1f,*data2f;
    float *data1f_gpu,*data2f_gpu;
    mxClassID category;
    if(nrhs != nlhs)
    {
    mexErrMsgTxt("The number of input and output arguments must be the same.");
    
    }
    for(i=0;i<nrhs;i++)
    {
        m=mxGetM(prhs[i]);
        n=mxGetN(prhs[i]);
        plhs[i]=mxCreateDoubleMatrix(m,n,mxREAL);
        cudaMalloc((void **)&data1f_gpu,sizeof(float)*m*n);
        cudaMalloc((void **)&data2f_gpu,sizeof(float)*m*n);
        data1=mxGetPr(prhs[i]);
        category=mxGetClassID(prhs[i]);
        if( category==mxSINGLE_CLASS)
        {
            cudaMemcpy(data1f_gpu,data1,sizeof(float)*m*n,cudaMemcpyHostToDevice);
        }
        if (category==mxDOUBLE_CLASS)
        {
            data1f=(float *)mxMalloc(sizeof(float)*m*n);
            for(j=0;j<m*n;j++)
            {
                data1f[j]=(float)data1[j];
            
            }
            cudaMemcpy(data1f_gpu,data1f,sizeof(float)*n*m,cudaMemcpyHostToDevice);
        }
        data2f=(float *)mxMalloc(sizeof(float)*m*n);
        dim3 dimBlock(128);
        dim3 dimGrid((m*n)/dimBlock.x);
        if((n*m)%128!=0)
        {
            dimGrid.x+=1;
        }
        square_elements<<< dimGrid,dimBlock>>>(data1f_gpu,data2f_gpu,n*m);
        cudaMemcpy(data2f,data2f_gpu,sizeof(float)*n*m,cudaMemcpyDeviceToHost);
        data2=mxGetPr(plhs[i]);
        for(j=0;j<m*n;j++)
        {
            data2[j]=(double)data2f[j];
        }
        mxFree(data1f);
        mxFree(data2f);
        cudaFree(data1f_gpu);
        cudaFree(data2f_gpu);
        
}
    
}
接下来通过nvcc将其编译成.cpp文件,然后在matlab中 mex成动态链接库,像函数一样使用这个就okay了;
这个命令可以在cmd中敲,也可以通过matla调用系统命令进行。
nvcc square.cu - cuda -o square.cpp -l"wenjianweizhi"
mex('square.cpp','-LX:kuwenjian(cuda)','-lcudart')
-L选项的作用是设置库文件目录,-L选项的作用是连接cudart.lib

还有一种nvmex工具可以直接将.cu文件转化成.mexw64文件,不过没有去研究这个了。

然后另外一种方式就是 ptx文件了,也是使用nvcc进行编译,具体可参考《实战matlab并行程序设计》

最后就是输出了,命令行输入[out1,out2]=square(in1,in2)就okay了,对应上你写的函数样式。