使用mex将一个大矩阵从Matlab传递到C:Matlab崩溃
Passing a big matrix from Matlab to C using mex: Matlab crashes
我写了一个mex代码,它从matlab代码向C代码发送标量和矩阵。它适用于较小的矩阵。然而,当我试图通过大型稀疏矩阵(大小~8448x3264)时,matlab崩溃,并出现以下错误:
我得到以下错误:Matlab遇到内部问题,需要关闭
*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.
这是我的matlab代码:
% 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);
这是我的mex代码
#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
}
更新:谢谢谢指出我的错误。如果你能回答另一个问题,我将不胜感激通过稀疏矩阵的最佳方式是什么1) 通过将指针传递到矩阵,就像我在mex文件中所做的那样2) 通过将指针传递到像这样的非零元素:
[rows cols values] = find(smA_System);
[nrows ncols] = size(smA_System);
然后,将指针传递给行、列和值。
正如您在问题中指出的那样,您的代码只适合作为第二个参数读取full
矩阵。当prhs[1]
是稀疏矩阵时,您不能再使用*(y+count)
将其作为全矩阵访问:它是sparse,它不会占用内存中的n
整数,但要少得多
要访问mex中稀疏矩阵的元素,应该使用mxGetIr
和mxGetJc
。Matlab存储稀疏矩阵的方式在这里得到了最好的解释
此外,输入矩阵是稀疏的,而输出矩阵是满的——这可能会在尝试分配输出矩阵时导致内存不足错误。然而,您没有检查从mxCreateDoubleMatrix(mrows,ncols, mxREAL);
返回的plhs[0]
,它很可能是NULL
。
更新:
最佳实践是按原样将稀疏矩阵传递给mex代码
在您的mex函数中,您应该:
- 验证输入是否确实如预期的那样稀疏。参见
mxIsSparse
- 使用
mxGetIr
、mxGetJc
和mxGetPr
获得三个相关指针(四个用于复数矩阵) - 直接使用
ir
和jc
,而不是不太紧凑的行-列对
相关文章:
- 当回溯以零开始时,如何调试崩溃
- 在C++STL中是否有Polyval(Matlab函数)等价物?
- 内联映射初始化的动态atexit析构函数崩溃
- 执行函数时导致崩溃的变量
- 有可能在Armadillo中复制MATLAB circshift方法吗
- 程序崩溃并显示"std::out_of_range"错误
- CoInitialize()在单独的线程上崩溃而不返回
- 使用调试/崩溃报告将应用程序部署到客户端
- 使用 MATLAB 编码器生成C++代码:编译错误"undefined reference to `rgb2gray_tbb_real64'"
- 为什么所有C++编译器都会崩溃或挂起此代码
- 当我运行MEX文件时,MATLAB崩溃
- MATLAB由于调用库(C++.h文件和FORTRAN.dll)而崩溃
- 当未选择 /CLR时,编译的MATLAB代码崩溃
- 使用fopen for file时,matlab在没有转储文件的情况下崩溃
- 使用mex将一个大矩阵从Matlab传递到C:Matlab崩溃
- matlab调用Findclass JNI崩溃
- 在MEX文件中的断言导致Matlab崩溃
- c++ Mex文件在64位linux上崩溃matlab,但不是32位windows,但程序在matlab外运行良好
- 防止一个MEX文件在MATLAB中崩溃
- mex文件崩溃,如何在MATLAB中使用MATLAB_MEM_MGR