Garima Singh
Garima Singh

Reputation: 1490

Passing a big matrix from Matlab to C using mex: Matlab crashes

I have written a mex code which sends a scalar and a matrix to C-code from matlab code. It works fine with smaller matrix. However, when I try to pass big sparse matrix (size ~ 8448 x 3264), matlab crashes with following error:

I get the following error: Matlab has encountered an internal problem and needs to close.

                  *Detailed error report*


------------------------------------------------------------------------
         Segmentation violation detected at Mon Feb  9 13:21:48 2015
  ------------------------------------------------------------------------

  Configuration:
    Crash Decoding     : Disabled
    Current Visual     : None
    Default Encoding   : UTF-8
    GNU C Library      : 2.19 stable
    MATLAB Architecture: glnxa64
    MATLAB Root        : /usr/local/MATLAB/R2014b
    MATLAB Version     : 8.4.0.150421 (R2014b)
    Operating System   : Linux 3.13.0-37-generic #64-Ubuntu SMP Mon Sep 22 21:28:38 UTC 2014 x86_64
    Processor ID       : x86 Family 6 Model 44 Stepping 2, GenuineIntel
    Software OpenGL    : 1
    Virtual Machine    : Java 1.7.0_11-b21 with Oracle Corporation Java HotSpot(TM) 64-Bit Server VM mixed mode
    Window System      : No active display

  Fault Count: 1


  Abnormal termination:
  Segmentation violation

  Register State (from fault):
    RAX = 00007f011f000000  RBX = 0000000000000001
    RCX = 0000000000260fe0  RDX = 00007f0162197000
    RSP = 00007f024fffb4f0  RBP = 00007f024fffb4f0
    RSI = 00007f011ed9f020  RDI = 00007f0161f36020

     R8 = 00007f011ed9f010   R9 = 0000000000000000
    R10 = 0000000000000022  R11 = 0000000048000001
    R12 = 00007f024fffbaf0  R13 = 00007f01c63b57f0
    R14 = 00007f024fffbb00  R15 = 00007f024fffbb00

    RIP = 00007f01618d491e  EFL = 0000000000010206

     CS = 0033   FS = 0000   GS = 0000

  Stack Trace (from fault):
  [  0] 0x00007f01618d491e /home/dkumar/Mex_Codes_DKU/Matlab_Calling_C/Test_2/mexcallingmatlab.mexa64+00002334
  [  1] 0x00007f01618d4a8e /home/dkumar/Mex_Codes_DKU/Matlab_Calling_C/Test_2/mexcallingmatlab.mexa64+00002702 mexFunction+00000325
  [  2] 0x00007f025ef7ac0a     /usr/local/MATLAB/R2014b/bin/glnxa64/libmex.so+00150538 mexRunMexFile+00000090
  [  3] 0x00007f025ef775c4     /usr/local/MATLAB/R2014b/bin/glnxa64/libmex.so+00136644
  [  4] 0x00007f025ef78414     /usr/local/MATLAB/R2014b/bin/glnxa64/libmex.so+00140308
  [  5] 0x00007f025e2af329 /usr/local/MATLAB/R2014b/bin/glnxa64/libmwm_dispatcher.so+00791337 _ZN8Mfh_file11dispatch_fhEiPP11mxArray_tagiS2_+00000697
  [  6] 0x00007f025d189b70 /usr/local/MATLAB/R2014b/bin/glnxa64/libmwm_interpreter.so+04053872
  [  7] 0x00007f025d139e02 /usr/local/MATLAB/R2014b/bin/glnxa64/libmwm_interpreter.so+03726850
  [  8] 0x00007f025d13c022 /usr/local/MATLAB/R2014b/bin/glnxa64/libmwm_interpreter.so+03735586
  [  9] 0x00007f025d141f87 /usr/local/MATLAB/R2014b/bin/glnxa64/libmwm_interpreter.so+03760007
  [ 10] 0x00007f025d13d6ff /usr/local/MATLAB/R2014b/bin/glnxa64/libmwm_interpreter.so+03741439
  [ 11] 0x00007f025d13e334 /usr/local/MATLAB/R2014b/bin/glnxa64/libmwm_interpreter.so+03744564
  [ 12] 0x00007f025d1b352e /usr/local/MATLAB/R2014b/bin/glnxa64/libmwm_interpreter.so+04224302
  [ 13] 0x00007f025e2af329 /usr/local/MATLAB/R2014b/bin/glnxa64/libmwm_dispatcher.so+00791337 _ZN8Mfh_file11dispatch_fhEiPP11mxArray_tagiS2_+00000697
  [ 14] 0x00007f025d189b70 /usr/local/MATLAB/R2014b/bin/glnxa64/libmwm_interpreter.so+04053872
  [ 15] 0x00007f025d10a293 /usr/local/MATLAB/R2014b/bin/glnxa64/libmwm_interpreter.so+03531411
  [ 16] 0x00007f025d13b0de /usr/local/MATLAB/R2014b/bin/glnxa64/libmwm_interpreter.so+03731678
  [ 17] 0x00007f025d141f87 /usr/local/MATLAB/R2014b/bin/glnxa64/libmwm_interpreter.so+03760007
  [ 18] 0x00007f025d13d6ff /usr/local/MATLAB/R2014b/bin/glnxa64/libmwm_interpreter.so+03741439
  [ 19] 0x00007f025d13e334 /usr/local/MATLAB/R2014b/bin/glnxa64/libmwm_interpreter.so+03744564
  [ 20] 0x00007f025d1b352e /usr/local/MATLAB/R2014b/bin/glnxa64/libmwm_interpreter.so+04224302
  [ 21] 0x00007f025e2af4af /usr/local/MATLAB/R2014b/bin/glnxa64/libmwm_dispatcher.so+00791727 _ZN8Mfh_file11dispatch_fhEiPP11mxArray_tagiS2_+00001087
  [ 22] 0x00007f025d171ff5 /usr/local/MATLAB/R2014b/bin/glnxa64/libmwm_interpreter.so+03956725
  [ 23] 0x00007f025d133699 /usr/local/MATLAB/R2014b/bin/glnxa64/libmwm_interpreter.so+03700377
  [ 24] 0x00007f025d12fa87 /usr/local/MATLAB/R2014b/bin/glnxa64/libmwm_interpreter.so+03684999
  [ 25] 0x00007f025d130143 /usr/local/MATLAB/R2014b/bin/glnxa64/libmwm_interpreter.so+03686723
  [ 26] 0x00007f025f1bb9dc /usr/local/MATLAB/R2014b/bin/glnxa64/libmwbridge.so+00223708
  [ 27] 0x00007f025f1bc649 /usr/local/MATLAB/R2014b/bin/glnxa64/libmwbridge.so+00226889 _Z8mnParserv+00000729
  [ 28] 0x00007f02698c6b7f   /usr/local/MATLAB/R2014b/bin/glnxa64/libmwmcr.so+00772991 _ZN11mcrInstance30mnParser_on_interpreter_threadEv+00000031
  [ 29] 0x00007f02698a7083   /usr/local/MATLAB/R2014b/bin/glnxa64/libmwmcr.so+00643203
  [ 30] 0x00007f02698a8d69   /usr/local/MATLAB/R2014b/bin/glnxa64/libmwmcr.so+00650601 _ZN5boost6detail11task_objectIvNS_3_bi6bind_tIvPFvRKNS_8functionIFvvEEEENS2_5list1INS2_5valueIS6_EEEEEEE6do_runEv+00000025
  [ 31] 0x00007f02698a9737   /usr/local/MATLAB/R2014b/bin/glnxa64/libmwmcr.so+00653111 _ZN5boost6detail9task_baseIvE3runEv+00000071
  [ 32] 0x00007f02698a9797   /usr/local/MATLAB/R2014b/bin/glnxa64/libmwmcr.so+00653207
  [ 33] 0x00007f02698a4bca   /usr/local/MATLAB/R2014b/bin/glnxa64/libmwmcr.so+00633802
  [ 34] 0x00007f025c4eaa46   /usr/local/MATLAB/R2014b/bin/glnxa64/libmwuix.so+00330310
  [ 35] 0x00007f025c4d2ad2   /usr/local/MATLAB/R2014b/bin/glnxa64/libmwuix.so+00232146
  [ 36] 0x00007f026a06700f /usr/local/MATLAB/R2014b/bin/glnxa64/libmwservices.so+02523151
  [ 37] 0x00007f026a06717c /usr/local/MATLAB/R2014b/bin/glnxa64/libmwservices.so+02523516
  [ 38] 0x00007f026a06307f /usr/local/MATLAB/R2014b/bin/glnxa64/libmwservices.so+02506879
  [ 39] 0x00007f026a0684b5 /usr/local/MATLAB/R2014b/bin/glnxa64/libmwservices.so+02528437
  [ 40] 0x00007f026a0688e7 /usr/local/MATLAB/R2014b/bin/glnxa64/libmwservices.so+02529511
  [ 41] 0x00007f026a068fc0 /usr/local/MATLAB/R2014b/bin/glnxa64/libmwservices.so+02531264 _Z25svWS_ProcessPendingEventsiib+00000080
  [ 42] 0x00007f02698a5248   /usr/local/MATLAB/R2014b/bin/glnxa64/libmwmcr.so+00635464
  [ 43] 0x00007f02698a5564   /usr/local/MATLAB/R2014b/bin/glnxa64/libmwmcr.so+00636260
  [ 44] 0x00007f0269891cdd   /usr/local/MATLAB/R2014b/bin/glnxa64/libmwmcr.so+00556253
  [ 45] 0x00007f026877b182              /lib/x86_64-linux-gnu/libpthread.so.0+00033154
  [ 46] 0x00007f02684a7fbd                    /lib/x86_64-linux-gnu/libc.so.6+01028029 clone+00000109


  This error was detected while a MEX-file was running. If the MEX-file
  is not an official MathWorks function, please examine its source code
  for errors. Please consult the External Interfaces Guide for information
  on debugging MEX-files.

Here is my matlab code:

% Create system matrix (size 8448 x 3264)
smA_System = ConstructSystemMatrix();

    x = 9;
    y = ones(3);

    % This works fine
    z = mexcallingmatlab(x, y);

    % This gives error
    z = mexcallingmatlab(x, smA_System);

Here is my mex code

  #include "mex.h"

  void xtimesy(double x, double *y, double *z, int m, int n)
  {
    int i,j,count = 0;

    for (i = 0; i < n; i++) {
        for (j = 0; j < m; j++) {
            *(z+count) = x * *(y+count);
            count++;
        }
    }
  }


  void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
  {
    double *y, *z;
    double x;
    int status,mrows,ncols;


    if (nrhs != 2) 
        mexErrMsgTxt("Two inputs required.");
    if (nlhs != 1) 
        mexErrMsgTxt("One output required.");

    /* Check to make sure the first input argument is a scalar. */
    if (!mxIsDouble(prhs[0]) || mxIsComplex(prhs[0]) ||
        mxGetN(prhs[0])*mxGetM(prhs[0]) != 1) {
        mexErrMsgTxt("Input x must be a scalar.");
    }

    /* Get the scalar input x. */
    x = mxGetScalar(prhs[0]);

    /* Create a pointer to the input matrix y. */
    y = mxGetPr(prhs[1]);

    /* Get the dimensions of the matrix input y. */
    mrows = mxGetM(prhs[1]);
    ncols = mxGetN(prhs[1]);

    /* Set the output pointer to the output matrix. */
    plhs[0] = mxCreateDoubleMatrix(mrows,ncols, mxREAL);

    /* Create a C pointer to a copy of the output matrix. */
    z = mxGetPr(plhs[0]); 

    /* Call the C subroutine. */
    xtimesy(x, y, z, mrows, ncols);    // Passing x as a scalar and y,z as pointer; possibly implicit converion of y,z to their pointers

  }

Update: Thanks, Shai for pointing out my mistake. I would appreciate if you could answer another question. What would be the best way to pass the sparse matrix? 1) By passing pointer to matrix as I am doing in my mex file 2) By passing pointer to non zero elements like this:

[rows cols values] = find(smA_System);
[nrows ncols] = size(smA_System);

and then, pass pointer to rows, cols, values.

Upvotes: 0

Views: 547

Answers (1)

Shai
Shai

Reputation: 114966

As you pointed yourself in your question, your code is only suited to read full matrices as a second argument. When prhs[1] is a sparse matrix you can no longer access it as a full matrix using *(y+count): it is SPARSE, it does not occupy n entires in memory, but far less.
To access elements of a sparse matrix in mex you should use mxGetIr and mxGetJc. The way Matlab stores a sparse matrix is best explained here.
Moreover, your input matrix is sparse while your output matrix is full - this is likely to cause out-of-memory error when trying to allocate the output matrix. Yet, you are not checking plhs[0] returned from mxCreateDoubleMatrix(mrows,ncols, mxREAL); it is likely to be NULL.

Update:

Best practice is to pass the sparse matrix to your mex code as-is.
In your mex function you should:

  1. Verify that the input is indeed sparse, as expected. See mxIsSparse.
  2. Obtain the three relevant pointers (four for complex matrices) using mxGetIr, mxGetJc and mxGetPr.
  3. Work with ir and jc directly instead of row-column pairs that are less compact.

Upvotes: 6

Related Questions