linello
linello

Reputation: 8714

Mapping existing memory to Matlab mxArray without waste of memory

I'm mex-ing a file for Matlab where I handle huge matrices (more than 20.000x20.000 double precision). I would like, after my computations are done, to map the resulting matrix treated as Eigen matrix to an mxArray without memory copying and allocating other space on memory.

Eigen::MatrixXd myfunction(const Eigen::MatrixXd &W)
{
    return W*2;
}

void mexFunction( int nOutputArgs, mxArray *outputArgs[], int nInputArgs, const mxArray * inputArgs[])
{   
    int M = mxGetM(inputArgs[0]);
    int N = mxGetN(inputArgs[0]);

    // Create the input matrix W as Eigen Matrix mapping the input matrix
    Eigen::Map<Eigen::MatrixXd> W( mxGetPr(inputArgs[0]) ,M,N);

    // Allocate space for the output matrix G
    Eigen::MatrixXd G = myfunction(W);

    double *Gdata = G.data();
    outputArgs[0] = mxCreateDoubleMatrix(M,N,mxREAL);
    memcpy(mxGetPr(outputArgs[0]), Gdata, sizeof(double)*M*N);

    return;
}

I'm asking if it is not possible to just align the pointer to plhs[0] to the pointer of matrix G ( which is obtained in Eigen as G.data() ) or do I need to do memcpy.

Upvotes: 2

Views: 864

Answers (1)

sebastian
sebastian

Reputation: 9696

This might work (untested, no matlab ready):

outputArgs[0] = mxCreateDoubleMatrix(0,0,mxREAL);
mxSetM(outputArgs[0], M);
mxSetN(outputArgs[0], N);
mxSetPr(outputArgs[0], Gdata);

Creating an empty matrix to start with prevents matlab from allocating a bunch of memory you don't actually need.

Though this might work, beware:

You will have to make sure that the Eigen::MatrixXd does not delete this memory block upon its own deletion once the mexFunction returns, which might well be whats going to happen. Which would bring you back to memcpy again.

Upvotes: 1

Related Questions