Summary of Matlab calling CUDA (Windows, Ubuntu)

For the purpose of speeding up the calculation, the project needs to use CUDA to implement some calculations in matlab and then use matlab to call

Since there are too many parameters required in the calculation part, it is too troublesome to transfer them one by one to CUDA, so first use Matlab to store these parameters in the mat file, and read the mat file in the CUDA c++ code.

The final effect is to call the mexw64 file (essentially a dll, the extension name of the linux platform is mexa64) in the Matlab code like a function call.

Since CUDA cannot be used to compile mex directly into mexw64, first use nvcc to compile the cu file into an obj file for mex linking.

Project overall structure

Ø matlabfunction.m - call CUDA's matlab main program

Ø mexmain.cpp - the C++ file that defines mexFunction, and reads the mat file internally, and passes the parameters to CUDA to calculate

Ø kernel.cu - CUDA file, with the definition of the kernel function and a C++ function to receive parameters and call the kernel function to calculate the calculation result

code structure
matlab.m
%matlab performs some data processing
%.........
% Call the compiled mexw64/mexa64 file, pass in the parameters, and get the calculation result
[result1,result2]=MexMain(arg1,arg2)
% Processing of calculation results
%............
mexmain.cpp
#include "mat.h"
#include "mex.h"
extern int CUDAFunction(double* arg1, double*arg2);//implemented in the kernel.cu file, the main function is to pass the parameters into the CUDA kernel function and use the GPU for calculation
void mexFunction (int nlhs, mxArray * plhs [], int nrhs, const mxArray * prhs [])
{//...
}

Write the required environment setup on vs

Create a new CUDA project and create a new mexmain.cpp file

Since mexFunction is defined in mexmain.cpp, the mat file is read, and cufft is also called in kernel.cu for fft operation, so add the corresponding include directory and linker input in the vs project properties

Right click project - properties

C/C++-General, additional include directories on the right are added

C:\ProgramFiles\MATLAB\R2017a\extern\include\win64
C:\ProgramFiles\MATLAB\R2017a\extern\include

Linker - General, the additional library directory on the right increases

C:\ProgramFiles\MATLAB\R2017a\extern\lib\win64\microsoft

linker-input, additional dependencies on the right add

libmat.lib
libmx.lib
libmex.lib
libeng.lib
cufft.lib

At this point, the project configuration is complete. If vs still prompts that functions or types such as mxArray , mexErrMsgTxt , and matOpen are undefined, you may need to configure environment variables.

add to PATH

C:\ProgramFiles\MATLAB\R2017a\bin\win64
C:\ProgramFiles\MATLAB\R2017a\lib\win64
C:\ProgramFiles\MATLAB\R2017a\extern\lib\win64\microsoft
C:\ProgramFiles\MATLAB\R2017a\bin
C:\ProgramFiles\MATLAB\R2017a\runtime\win64

(Some are added automatically after installing matlab)

compile

After the code is written, you can start compiling

First use nvcc to compile kernel.cu into an obj file

nvcc -c kernel.cu

This is a simplified command. In actual use, you need to specify the target GPU architecture (parameters such as -arch) and some other parameters. For details, please refer to the introduction of NVCC in the official CUDA document.

C:\Program Files\NVIDIA GPU ComputingToolkit\CUDA\v8.0\doc

If nvcc has the following error message

nvcc fatal   : Cannot find compiler 'cl.exe' in PATH

That's because cl can't be found in the PATH, just add it to it

In vs2015, cl.exe is in

C:\Program Files(x86)\Microsoft Visual Studio 14.0\VC\bin

Then use the mex command in matlab to compile the obj file with the cpp file

mex mexmain.cpp kernel.obj -lCUDArt-lcufft ...
-L"C:\Program Files\NVIDIA GPU ComputingToolkit\CUDA\v8.0\lib\x64" ...
-v -I"C:\Program Files\NVIDIA GPU ComputingToolkit\CUDA\v8.0\include"

Compilation for Linux platform

Since the software will eventually run on Linux, it is not enough to compile the mexw64 file, it needs to be recompiled on Linux

But the process didn't go as smoothly as it did on Windows

Operating system Ubuntu, C++ compiler G++

First, compile the .o file using the same

nvcc -c kernel.cu

then in matlab

mex mexmain.cpp kernel.o -lCUDArt-lcufft ...
-L"/usr/local/CUDA-8.0/lib64" ...
-v -I"/usr/local/CUDA-8.0/include"

But it prompted the following error

wrong use of mex
/usr/bin/ld:kernel.o: relocation R_X86_64_32 against `.bss' can not be used when making ashared object;
recompile with-fPIC
kernel.o: erroradding symbols: wrong values
collect2: error: ld returned 1

Simply put, the kernel.o file compiled by kernel.cu is not address-independent. To use the -fPIC option to recompile, the shared library (.so file) must be compiled with -fPIC under Linux.

The way to use the -fPIC option in nvcc is to use --compiler-options-fPIC

so use

nvcc -c--compiler-options -fPIC  kernel.cu

Compile the kernel.o and then use the mex command to successfully compile the mexa64 file

References for problems

CUDA8 + VS2015 corecrt.h error


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324683708&siteId=291194637