Drexel dragonThe Math ForumDonate to the Math Forum



Search All of the Math Forum:

Views expressed in these public forums are not endorsed by Drexel University or The Math Forum.


Math Forum » Discussions » Software » comp.soft-sys.matlab

Topic: partial matrix operations without memory copying
Replies: 2   Last Post: Dec 2, 2012 6:30 AM

Advanced Search

Back to Topic List Back to Topic List Jump to Tree View Jump to Tree View   Messages: [ Previous | Next ]
James Tursa

Posts: 2,069
Registered: 8/5/09
Re: partial matrix operations without memory copying
Posted: Dec 2, 2012 6:30 AM
  Click to see the message monospaced in plain text Plain Text   Click to reply to this topic Reply

"Nick" wrote in message <k9e78r$m21$1@newscl01ah.mathworks.com>...
> I would like to do operations on vectors of a matrix efficiently, without memory copying.
> For example, say V is KxK, A is Nxp p>k
> I want to do X(:,1:K)*V efficiently. As it is currently written, matlab makes a temporary copy of the first K colomns of X and does the multiplication. The primitive BLAS routines can handle this without memory copying: just give it the same pointer to X with different number of columns as input. I would like to realize this speedup without having to go to mex. Is this possible?


It is *not* possible without a mex routine. For your particular example, however, the mex routine is very easy. Since you want the *first* k columns we can use a simple shared data copy with an altered number of columns:

/* Create shared data copy of 1st k columns of input */
/* B = subblock(A,k) */
/* A = m x n matrix (any class) */
/* B = m x k matrix using shared data of A */
/* */
/* If k < 0, then 0 is used. */
/* If k > n, then n is used. */
/* */
/* Programmer: James Tursa */

#include "mex.h"

#ifndef MWSIZE_MAX
#define mwSize int
#endif

mxArray *mxCreateSharedDataCopy(mxArray *); /* Undocumented API function */

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
mwSize k, n;

if( nrhs != 2 ) {
mexErrMsgTxt("Need exactly two inputs.");
}
if( nlhs > 1 ) {
mexErrMsgTxt("Too many outputs.");
}
if( !mxIsNumeric(prhs[1]) || mxGetNumberOfElements(prhs[1]) != 1 ) {
mexErrMsgTxt("2nd argument must be a numeric scalar.");
}
n = mxGetN(prhs[0]);
k = mxGetScalar(prhs[1]);
if( k < 0 ) k = 0;
if( k > n ) k = n;
plhs[0] = mxCreateSharedDataCopy(prhs[0]);
mxSetN(plhs[0],k); /* Manually set the number of columns */
}

Note that this routine is very robust and does not require any special care on your part to use. The returned variable can be deleted at any time, or even exist in memory if you clear the original. The only caveat is that if you have a large variable then all of the original memory is locked up in the truncated variable. So if you start with a 1,000,000 column variable and you use the routine to get only the first column then clear the original 1,000,000 column variable, the new variable with only 1 column will still have the original 1,000,000 columns locked in memory. It simply is fooling MATLAB into thinking that there is only one column. To clear all the memory you will need to clear the variable.

If you want the sub-matrix to be an arbitrary set of contiguous columns and not necessarily the first set of contiguous columns, then you will have to use something like Bruno's suggested code.

James Tursa



Point your RSS reader here for a feed of the latest messages in this topic.

[Privacy Policy] [Terms of Use]

© Drexel University 1994-2014. All Rights Reserved.
The Math Forum is a research and educational enterprise of the Drexel University School of Education.