Using Intel® Data Analytics Acceleration Library on Matlab*

Intel® Data Analytics Acceleration Library (Intel® DAAL) is high performance library, which provides a rich set of algorithms, ranging from the most basic descriptive statistics for datasets to more advanced data mining and machine learning algorithms. It can help developer develop highly optimized big data algorithm with relatively little effort. It’s designed for use with popular data platforms including Hadoop*, Spark*, R, and Matlab*.

Matlab* is a multi-paradigm numerical computing;interactive software;and has been widely used for solving engineering and scientific problem.

This article tries to show Matlab* and Intel DAAL developers one way to use Intel DAAL from Matlab*.  

Prerequisites:

  • Install Intel® DAAL on your system;
  • Install a C++ compiler such as Microsoft Visual Studio* 2015 (MSVS 2015);
  • Install Matlab* on your system;

Note: this article was tested with MATLAB R2015b and Intel DAAL 2017 for Windows

Principle: Linking Matlab and Intel DAAL function by MexFunction

Matlab provide some mechanism, which allow developer interface with programs written in other languages such as C++, Fortran etc. A basic interfacing with C++ language is through a C++ function called mexFunction provided by Matlab MEX library (http://www.mathworks.com/help/matlab/apiref/mexfunction.html). By creating the mexFunction in a *.c or *.cpp file, the function can be complied and called in the Matlab* platform as they were build-in functions. The *.c files are called MEX files and the function name is the Mex filename. Intel DAAL has C++, Java and Python Interface.  We will use the mechanism to call Intel DAAL C++ function from Matlab*.

Part 1. C++ side

The cpp file can be written either in a C++ editor like MSVS2015,  any C language editor like notepad, or in Matlab* IDE

Step 1. Writing a basic mexFunction in cpp

to create a mexFunction, as  below

#include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){...;}

Here mxArray *prhs[]  are able to accept the input from workspace of Matlab.

mxArray *plhs[]  are able to pass the function compute result to workspace of Matlab.

In the function, we will add Intel DAAL algorithm, for example get absolute value of data set .

   /* retrieve the input data from data source */
    DataSource<xxx> dataSource(...);
    dataSource.loadDataBlock();
   /* Create an algorithm */
    abs::Batch<float> algorithm;
    /* Set an input object for the algorithm */
    algorithm.input.set(abs::data, dataSource.getNumericTable());
    /* Compute Abs function */
    algorithm.compute();
    /* Print the results of the algorithm */
    services::SharedPtr<abs::Result> res = algorithm.getResult();

Please see the whole c++ example in Intel DAAL Developer Guide.

Here is a basic structure of the mexFunction in C language.

Step 2. Inputting and converting of matrix (optional)

As the above definition shows, the functions mexFunction facilitate the transfer of data between MEX files and the workspace of Matlab by mxArray. In some of cases, one can read external input data source directly and feed to Intel DAAL algorithm in the function. But in some of cases, one may want to pass the Matlab matrix to Intel DAAL function. Then we may consider the converting of matrix between mxArray and normal array in C.  

The function mxGetpr() (http://www.mathworks.com/help/matlab/access-data_buu4p6_-5.html) is able to read the matrix from Matlab* input.  But there is notable issue that the matrix from mxGetpr() is stored in column-major order, while C array take row-major order by default.  For example, In the function mexFunction where prhs[] refers to the input matrix structure  mxArray, the input matrix is stored in column-major order which means: a common matrix

1 2 3
4 5 6
7 8 9

was stored as [1 4 7 2 5 8 3 6 9] in prhs[]

However, the default read order in C language is row-major order which means when converting an array to matrix,

[1 4 7 2 5 8 3 6 9] with dimension of 3*3 will be read as:

1 4 7
2 5 8
3 6 9

So you need consider to transpose the input matrix data in Matlab* or convert it in the mexFunction in *.cpp file, or other read way to fill into Intel DAAL algorithm.

A piece of codes sample in Matlab is shown below:

input1=input1';
[output1,...]=yourfunctionname(input1,...)
output1=output1';

Note: Remember that every time a new matrix is inputted it has to be converted. (mexArray to C Array)

And the input matrix have to be converted back to column-major if they still need to be processed in Matlab*.(C Array to mexArray)

Remember that every time a matrix is going to be outputted it has to be converted. (C Array to mexArray)

Step 3. Defining Intel® DAAL function input and output

In Intel® DAAL computing, a NumericTable class is required to be the input of algorithms.  So before setting the input of algorithm, input matrix should be converted into NumericTable to be recognized by the Intel® DAAL algorithms.

The conversion from inputMatrix (C++ matrix processed in Step 2) to inputData (NumericTable of DAAL) is shown below:

SharedPtr<NumericTable>inputData = SharedPtr<NumericTable>(new Matrix<double>(number_of_colome, number_of_row, inputMatrixPtr))

Here is an code example of setting up inputs for Abs algorithm. The inputMatrix is from Matlab workspace. 

#include "daal.h"
#include "mex.h"
#include "matrix.h"

using namespace std;
using namespace daal;
using namespace daal::services;
using namespace daal::data_management;
using namespace daal::algorithms;
using namespace daal::algorithms::math;
#define inputA prhs[0]
#define outputA plhs[0]
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
	/*Input Arguments Check if needed*/
	if (!mxIsDouble(inputA) || mxIsComplex(inputA))
	{	mexErrMsgIdAndTxt("Sample:prhs", "Input matrix must be double");}
    */
	/*Defination*/
	mwSize nrow, ncol;
	double *pxtrain;
	double *poutA;
	/*Define the Size and Pointer of Input Matrix*/
	nrow = mxGetM(inputA);
	ncol = mxGetN(inputA);
	pxtrain = mxGetPr(inputA);

	/*Convert MexArray to C Array (Matlab to C++) if needed*/
	//matrix_cr_conv(pxtrain, ncol, nrow);

	/*Create an Intel DAAL NumericTable*/
	SharedPtr<NumericTable>inputdataA = SharedPtr<NumericTable>(new Matrix<double>(ncol, nrow, pxtrain));
	
	/* Create an algorithm */
	abs::Batch<double> abs;

	/* Set an input object for the algorithm */
	abs.input.set(abs::data, inputdataA);

	/* Compute Abs function */
	abs.compute();	
	
	/*Define Output Pointer*/
	SharedPtr<Matrix<double>>result = staticPointerCast<Matrix<double>, NumericTable>(abs.getResult()->get(abs::value));
	
	/*Create Output Matlab Matrix*/
	outputA = mxCreateDoubleMatrix(nrow,ncol, mxREAL);

	/*Define Output Pointer*/
	poutA = mxGetPr(outputA);
	int i;
	for (i = 0; i < nrow*ncol; i++) {
		poutA[i] = (*result)[0][i];
	}
	/*Convert C Array to MexArray (C++ to Matlab)* if needed/
	//matrix_cr_conv(poutA, nrow, ncol);
}

For more information about Intel® DAAL programming, please refer to Intel® DAAL Developer Guide.

To get and output the result you need first get the result from the algorithm (refer to the guide), then create an output matrix, finally define the output pointers to the algorithm results.

Also, don't forget to transpose the output matrix as mentioned above.

Regarding Debug

If you want to debug the *.cpp file in C++ compiler IDE, not only Intel® DAAL environment variables has to be set, but also the Matlab* environment variables need to be set.

Include path: %MATLAB ROOT%\extern\include;

library path: %MATLAB ROOT%\lib\win64;%MATLAB ROOT%\extern\lib\win64\microsoft;

Path: %MATLAB ROOT%\bin\win64; and the libmx.lib; libmex.lib; libmat.lib; should be added to the Additional Dependence (Configuration Properties>>Linker>>Input>> Additional Dependence)

Part 2. Matlab* Side

After the *.cpp file is created, the function is ready to be build and called from Matlab platform.

Step 1: Setting up the environment for Intel® DAAL in Matlab*

The easiest way of setting up the environment for Intel® DAAL in Matlab* is to launch the Matlab* from the Intel® Parallel Studio compiler command prompt:

  • Open command prompt from Start>>All apps>>Intel Parallel Studio XE 201X>>Command Prompt with Intel Compiler xx >>Intel 64 Visual Studio 201X environment (or  IA-32 Visual Studio 201X environment).
  • C:\Program Files (x86)\IntelSWTools>>"%MATLAB ROOT%\bin\matlab.exe"

Then in Matlab command windows, by using getenv() function and setenv() function you can add include and library path to the Matlab* recent environment.

(or If you meet compile or link error with starting the compiler command prompt, you can also check and set environment under Matlab* command window manually as below)

The Intel DAAL is installed in the default path (C:\Program Files (x86)\IntelSWTools\).

To be added to 'INCLUDE' list:

C:\Program Files (x86)\IntelSWTools\compilers_and_libraries_xxxx.x.xxx\windows\compiler\include;

C:\Program Files (x86)\IntelSWTools\compilers_and_libraries_xxxx.x.xxx\windows\compiler\include\intel64;

C:\Program Files (x86)\IntelSWTools\compilers_and_libraries_xxxx.x.xxx\windows\daal\include;

To be added to 'lib' list:

C:\Program Files (x86)\IntelSWTools\compilers_and_libraries_xxxx.x.xxx\windows\compiler\lib;

C:\Program Files (x86)\IntelSWTools\compilers_and_libraries_xxxx.x.xxx\windows\compiler\lib\intel64;

C:\Program Files (x86)\IntelSWTools\compilers_and_libraries_xxxx.x.xxx\windows\compiler\lib\intel64_win;

C:\Program Files (x86)\IntelSWTools\compilers_and_libraries_xxxx.x.xxx\windows\daal\lib\intel64_win;

Here is an example of adding a path to 'INCLUDE' list

>>setenv('INCLUDE',[getenv('INCLUDE') ';C:\Program Files (x86)\IntelSWTools\compilers_and_libraries_xxxx.x.xxx\windows\daal\include']);

setenv('LIBPATH',[getenv('LIBPATH') ';C:\Program Files (x86)\IntelSWTools\compilers_and_libraries_xxx\windows\lib\intel64'])

Then set up  compiler in Matlab* command line, use

>>mex -setup

to identify the C/C++ language compilation such as Microsoft Visual Studio*.

Step 2: Creating mexfile from cpp file

First allocate (cd) the current folder to the location of the cpp file, then use the following command to statically link the mexfile to the Intel® DAAL libraries.

>>C:\Users\xxx\Desktop\Matlab\daal_abs_sample

>>mex -v -largeArrayDims yourfunctionname.cpp daal_core.lib daal_thread.lib

daal_core.lib can be used if you want a static library within Matlab* (which will result in a larger mexfile);

daal_sequential.lib can be used if you don’t need multi-thread computing.

Paths may not be included if they are on the list of getenv('PATH').

A success build of mexfile should result in the word: MEX completed successfully and one yourfunctionname.mexw64 file was produced.

Step 3  Run the mexfunction as matlab build-in function

Now you can make full use of the function "yourfunctionname"(must be same name as the name of cpp file), it can be called under the path where the mexfile is.

[output1, output2...]=yourfunctionname (input1, input2, input3...);

Here is an example of calling function ‘m_daal_abs’ by mexing m_daal_abs.cpp.

Attach file: daal_abs_sample.rar

For more information about mex and mexFunction please visit:
http://www.mathworks.com/help/matlab/ref/mex.html
http://www.mathworks.com/help/matlab/apiref/mexfunction.html

For more information about Intel® DAAL please visit Intel® DAAL Developer Guide.

AttachmentSize
Package icon daal_abs_sample.zip2.83 KB
For more complete information about compiler optimizations, see our Optimization Notice.