Reputation: 1490
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
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
.
Best practice is to pass the sparse matrix to your mex code as-is.
In your mex function you should:
mxIsSparse
.mxGetIr
, mxGetJc
and mxGetPr
.ir
and jc
directly instead of row-column pairs that are less compact.Upvotes: 6