Maatlab crash with .mex function

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include "mat.h"
#include "mex.h"
#include "ComplexCal.h"
#include "IntrinsicUtils.h"
void mexFunction(int nlhs, mxArray * plhs[], int nrhs, const mxArray * prhs[])
{
uint16_t dim0, dim1, dim2;
uint32_t NumOfEle = 1;
int len_A, len_B, len_C, jj; /*can be changed to mwSize? */
int k = 1;
float *pA, *pB, *pC; /*can be changed to doube? */
mm_ps_Matrix2D_Info_t A;
mm_ps_Matrix2D_Info_t B;
mm_ps_Matrix2D_Info_t C;
pA = NULL;
pB = NULL;
pC = NULL;
pA = (float *) mxGetPr(prhs[0]);
pB = (float *) mxGetPr(prhs[1]);
dim0 = (uint16_t)(* (mxGetPr(prhs[2])));
dim1 = (uint16_t)(* (mxGetPr(prhs[3])));
dim2 = (uint16_t)(* (mxGetPr(prhs[4])));
len_A = mxGetNumberOfElements(prhs[0]);
len_B = mxGetNumberOfElements(prhs[1]);
len_C = dim0 * dim2 * 2 * NumOfEle;
if ((len_A != 2*dim0*dim1*NumOfEle) || (len_B != 2*dim1*dim2*NumOfEle))
{
mexErrMsgTxt("Input and output matrix dimension should be aligned!");
}
plhs[0] = mxCreateNumericMatrix(1, len_C , mxSINGLE_CLASS, mxREAL);
pC = mxGetPr(plhs[0]);
A.ppMatrix = (float ** )mxCalloc( dim0*dim1, sizeof(float *));
B.ppMatrix = (float ** )mxCalloc( dim1*dim2, sizeof(float *));
C.ppMatrix = (float ** )mxCalloc( dim0*dim2, sizeof(float *));
A.DimSize0 = dim0;
A.DimSize1 = dim1;
for (jj = 0; jj < dim0*dim1; jj++)
{
A.ppMatrix[jj] = &pA[jj*2*NumOfEle];
}
B.DimSize0 = dim1;
B.DimSize1 = dim2;
for (jj = 0; jj < dim1*dim2; jj++)
{
B.ppMatrix[jj] = &pB[jj*2*NumOfEle];
}
C.DimSize0 = dim0;
C.DimSize1 = dim2;
for (jj = 0; jj < dim0*dim2; jj++)
{
C.ppMatrix[jj] = &pC[jj*2*NumOfEle];
}
astri_mm_ps_matrix_cmul_2d(&A, &B, &C, NumOfEle);
} */
mxFree( (void ** ) A.ppMatrix);
mxFree( (void ** ) B.ppMatrix);
mxFree( (void ** ) C.ppMatrix);
}

5 comentarios

James Tursa
James Tursa el 19 de Abr. de 2021
What is this code supposed to do?
Tanuja Shanmukhappa
Tanuja Shanmukhappa el 20 de Abr. de 2021
Thanks James, the code is doing the 2-D matrix multiplication.
James Tursa
James Tursa el 21 de Abr. de 2021
Editada: James Tursa el 21 de Abr. de 2021
Can you post the code for astri_mm_ps_matrix_cmul_2d( )? Or if the source code is unavailable, can you post the prototype interface for it? And post the definition of the mm_ps_Matrix2D_Info_t type? And also post some sample MATLAB code for how you are calling this mex function?
Tanuja Shanmukhappa
Tanuja Shanmukhappa el 22 de Abr. de 2021
Hi James,
The source code is quite big to paste here, however the source code is basically using some of the intel instrinsic functions to carry out the matrix multiplication. The interface for "astri_mm_ps_matrix_cmul_2d" function would be: inline void astri_mm_ps_matrix_cmul_2d(mm_ps_Matrix2D_Info_t* A, mm_ps_Matrix2D_Info_t* B, mm_ps_Matrix2D_Info_t* C, uint32_t NumOfEle), where "mm_ps_Matrix2D_Info_t" is defined as:
typedef struct
{
uint16_t DimSize0;
uint16_t DimSize1;
float** ppMatrix;
} mm_ps_Matrix2D_Info_t;
This mex function is called in the main matlab function as:
cout = matrixCmul_float_x86(ain,bin,d0,d1,d2);
where: ain,bin are input matrix, d0,d1 & d2 are the dimensions for the 2 matrix. Lets say,d0=1, d1=4,d2=1. So, above function is used to multiply [1x4] matrix with a [4x1] matrix (the elements inside the matrix are complex values, so before entering the mex function, the real & imag parts are seperated).
Below is a sample code for testing the above mex function:
d0 = 4;
d1 = 3;
d2 = 5;
a = randn(d0,d1)+randn(d0,d1)*1j;
a = single(a);
b = randn(d1,d2)+randn(d1,d2)*1j;
b = single(b);
cref = a*b;
ain = transComplexFloat_x86(a, 1, d0, d1);
bin = transComplexFloat_x86(b, 1, d1, d2);
cout = matrixCmul_float_x86(ain,bin,d0,d1,d2);
c = transComplexFloat_x86(cout, 0, d0, d2);
where:
function dataout = transComplexFloat_x86(datain, direction, dim0, dim1)
% for a 2x3 (dim0xdim1) matrix, e.g.
% d00 d01 d02
% d10 d11 d12
% real(d00) imag(d00) real(d01) imag(d01) real(d02) imag(d02) real(d10) imag(d10) real(d11) imag(d11) real(d12) imag(d12)
if direction
tmp = reshape(datain.', 1,[]);
dataout = reshape([real(tmp);imag(tmp)], 1,[]);
else
tmp = datain(1:2:end) + 1j*datain(2:2:end);
dataout = reshape(tmp, dim1,dim0).';
end
Finally, i recently figured out that, the crash does not happen when i try to do a matrix multiplication such as [1x4] * [4x1]. However, the matlab crashes intermittently when i try to multiply [2x4]*[4*2] matrix. This i figured out through a simple approach, i looped the [1x4]*[4x1] multiplication 4 times to get the [2x2] multiplication output instead of directly doing the [2x4]*[4*2] multiplication. surprisingly, the matlab doesnot crash!
Thanks in advance
James Tursa
James Tursa el 22 de Abr. de 2021
Editada: James Tursa el 22 de Abr. de 2021
Which version of MATLAB are you using? If it is R2018a or later note that MATLAB already stores interleaved complex data so you wouldn't need to make that adjustment.
Also, I can't find any online documentation for these routines, so we may have to do a bit of trial and error to figure this out.

Iniciar sesión para comentar.

Respuestas (1)

James Tursa
James Tursa el 22 de Abr. de 2021
Editada: James Tursa el 23 de Abr. de 2021
I had to make some assumptions about how the matrix data areas are supposed to be loaded. We can try this first to see if these assumptions are correct. This is untested, so you may have to fix some typos.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include "mat.h"
#include "mex.h"
#include "ComplexCal.h"
#include "IntrinsicUtils.h"
void mexFunction(int nlhs, mxArray * plhs[], int nrhs, const mxArray * prhs[])
{
uint16_t dim0, dim1, dim2;
uint32_t NumOfEle = 1;
int len_A, len_B, len_C, jj; /*can be changed to mwSize? */
int k = 1;
float *pA, *pB, *pC; /*can be changed to doube? */
mm_ps_Matrix2D_Info_t A;
mm_ps_Matrix2D_Info_t B;
mm_ps_Matrix2D_Info_t C;
mwSize i;
/* Argument checks*/
if (nrhs != 5) mexErrMsgTxt("Need five inputs");
if (nlhs > 1) mexErrMsgTxt("Too many outputs");
if (!mxIsSingle(prhs[0]) || mxGetNumberOfDimensions(prhs[0]) != 2 ||
!mxIsSingle(prhs[1]) || mxGetNumberOfDimensions(prhs[1]) != 2)
mexErrMsgTxt("Inputs must be single 2D matrix");
if (!mxIsComplex(prhs[0]) || !mxIsComplex(prhs[1]))
mexErrMsgTxt("Inputs must be complex");
if (!mxIsNumeric(prhs[2]) || !mxIsNumeric(prhs[3]) || !mxIsNumeric(prhs[4]) ||
mxIsComplex(prhs[2]) || mxIsComplex(prhs[3]) || mxIsComplex(prhs[4]) ||
mxGetNumberOfElements(prhs[2]) != 1 || mxGetNumberOfElements(prhs[3]) != 1) ||
mxGetNumberOfElements(prhs[4]) != 1 )
mexErrMsgTxt("Dimensions must be real numeric scalars");
len_A = mxGetNumberOfElements(prhs[0]);
len_B = mxGetNumberOfElements(prhs[1]);
dim0 = mxGetScalar(prhs[2]);
dim1 = mxGetScalar(prhs[3]);
dim2 = mxGetScalar(prhs[4]);
len_C = dim0 * dim2 * 2 * NumOfEle;
if ((len_A != 2 * dim0*dim1*NumOfEle) || (len_B != 2 * dim1*dim2*NumOfEle))
{
mexErrMsgTxt("Input and output matrix dimension should be aligned!");
}
/* Load matrix headers */
/* ASSUMTION: matrix is stored in row order and ppMatrix are the row pointers */
A.DimSize0 = mxGetScalar(prhs[2]);
A.DimSize1 = mxGetScalar(prhs[3]);
A.ppMatrix = (float **)mxCalloc(A.DimSize0, sizeof(float *));
A.ppMatrix[0] = (float *)mxGetData(prhs[0]);
for (i = 1; i < A.DimSize0; i++){
A.ppMatrix[i] = A.ppMatrix[i - 1] + 2*A.DimSize1;
}
B.DimSize0 = mxGetScalar(prhs[3]);
B.DimSize1 = mxGetScalar(prhs[4]);
B.ppMatrix = (float **)mxCalloc(B.DimSize0, sizeof(float *));
B.ppMatrix[0] = (float *)mxGetData(prhs[1]);
for (i = 1; i < B.DimSize0; i++){
B.ppMatrix[i] = B.ppMatrix[i - 1] + 2*B.DimSize1;
}
plhs[0] = mxCreateNumericMatrix(1, mxGetScalar(prhs[2]) * mxGetScalar(prhs[4]) * 2 * NumOfEle, mxSINGLE_CLASS, mxREAL);
C.DimSize0 = mxGetScalar(prhs[2]);
C.DimSize1 = mxGetScalar(prhs[4]);
C.ppMatrix = (float **)mxCalloc(C.DimSize0, sizeof(float *));
C.ppMatrix[0] = (float *)mxGetData(plhs[0]);
for (i = 1; i < C.DimSize0; i++){
C.ppMatrix[i] = C.ppMatrix[i - 1] + 2*C.DimSize1;
}
/* Do the 2D complex matrix multiply */
astri_mm_ps_matrix_cmul_2d(&A, &B, &C, NumOfEle);
/* Free dynamic memory */
mxFree(A.ppMatrix);
mxFree(B.ppMatrix);
mxFree(C.ppMatrix);
}

3 comentarios

Tanuja Shanmukhappa
Tanuja Shanmukhappa el 23 de Abr. de 2021
Thanks for the reply James. I tried with ur code (ur assumptions are valid), and there are no typos in ur code. But the matlab still crashes. I added some print statement in-between to check where the crash happens in ur code, and seems it happens before memory freeing (the print statement before memory freeing is not executed, and matlab crashes).
James Tursa
James Tursa el 23 de Abr. de 2021
Are you sure the struct definition has float** ppMatrix; and not float* ppMatrix; ?
Tanuja Shanmukhappa
Tanuja Shanmukhappa el 26 de Abr. de 2021
Hi James,
the structure definition has float** ppMatrix.
Thank you
Tanuja

Iniciar sesión para comentar.

Categorías

Más información sobre Write C Functions Callable from MATLAB (MEX Files) en Centro de ayuda y File Exchange.

Etiquetas

Preguntada:

el 16 de Abr. de 2021

Comentada:

el 26 de Abr. de 2021

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by