### MATLAB

MATLAB下使用CUDA。

#@author:       gr
#@date:         2014-04-08
#@email:        forgerui@gmail.com

一、 Matlab & C

1. 概念

MatlabC 混编可以提高程序运行效率。

2. C文件

C文件需要在引入头文件mex.h,我的mex.h位置在/opt/MATLAB/R2013a/extern/include/mex.h

#include <mex.h>

Matlab与C文件的接口函数是mexFunction

mexFunction(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]){
    // entry
}

mexFunciton就像main函数一样,是Matlab调用的入口。其中,nlhs是输出参数个数,plhs是输出参数;nrhs是输入参数个数,prhs是输入参数,它是一个只读的变量。

3. 常用函数

4. 编译

需要将C语言源文件编译成可执行文件才能被Matlab调用,并且编译出来的文件比同名的.m文件执行优先级更高,即如果两个同名先执行编译出来的文件。

编译分两个步骤,先编译生成.o中间文件(windows下是.obj),再链接生成.mexa64文件(linux32位是.mexglx,windows是.mexw64),这个.mexa64文件可以直接被Matlab使用。

具体操作是打开Matlab,进入要编译文件的文件夹,要先配置一下编译器。
# configure the compiler
mex -setup
# compile
mex -c hello.c -o hello.o
# link
mex -O hello.o

之后在Matlab中直接敲hello便可以调用hello程序。

Alt text

二、Matlab & CUDA

1. Cuda的kernel函数

代码分为两部分,一部分代码在主机(host)上执行,另一部分则在设备(device)上执行,kernel函数是在GPU上执行的函数。

进行Cuda编译的一般步骤:

  1. 在主机上申请device内存
  2. 将主机数据拷贝到设备上
  3. 在设备上进行运算
  4. 主机将设备上的运算结果拷贝回主机内存
  5. 释放设备内存

如下定义kernel函数:

__global__ static void kernel_function(int* a, int* b, int* c){
    // realted code
}    

2. Cuda的启动

在主机上通过调用kernel函数名进行启动。

# 启动
kernel_function<<<block, thread>>>(a, b, c);

其中thread是一个block中启动的线程数,而block是需要划分为多少个block.块内的thread可以时行数据同步和共享内存,不同的block之间无法进行同步。a, b, c是相关的参数。

具体CUDA相关知识请看博客

3. 编译

因为Cuda有自己的编译器nvcc,所以需要调用这个编译器去编译C文件。我们可以在Matlab中利用一个脚本进行编译。

    nvmex('hello.c');
    function [ path, filename, zaet, fd ] = nvmex( cuFileName )
    %NVMEX Summary of this function goes here
    %   Detailed explanation goes here
    
    file_split = regexp(cuFileName, '.', 'split');
    filename = file_split{1};
    
    if ispc % Windows
        CUDA_LIB_LOCATION = 'C:CUDAlib';
        Host_Compiler_Location = '-ccbin "D:Program FilesMicrosoft Visual Studio 9.0VCin"';
        PIC_Option = '';
    else % Mac and Linux
        CUDA_LIB_Location = '/usr/local/cuda/lib64';
        Host_Compiler_Location = '';
        PIC_Option = '--compiler-options -fPIC';
    end
    
    % compile .o file
    nvccCommandLine = [ ... 
        'nvcc --compile ' cuFileName ' ' Host_Compiler_Location ' ' ...
    ' -o ' filename '.o ' ... 
    PIC_Option ...
    ' -I' matlabroot '/extern/include ' ...
    ];
    disp(nvccCommandLine);
    status = system(nvccCommandLine);
    if status < 0
    error 'Error invoking nvcc';
    end
    
    % link .mexa64 file
    mexCommandLine = ['mex (''' filename '.o'', ''-L' CUDA_LIB_Location ''', ''-lcudart'')'];
    disp(mexCommandLine);
    eval(mexCommandLine);
    
    end
原文地址:https://www.cnblogs.com/gr-nick/p/4489449.html