CKM
CKM

Reputation: 1971

On memory allocation in armadillo sparse matrices

I want to know whether I need to free up the memory occupied by locations and values objects after sparse matrix has been created. Here is the code:

void load_data(umat &locations, vec& values){
  // fill up locations and values
}

int main(int argc, char**argv){
    umat loc;
    vec val;
    load_data(loc,val);
    sp_mat X(loc,val);
    return 0;
}

In the above code, load_data() fills up the locations and values objects and then sparse matrix is created in main(). My Q: Do I need to free up memory used by locations and values after construction of X? The reason is that X could be large and I am on low RAM. I know when main returns, OS will free up locations and values as well as X. But, the real question is whether the memory occupied by X is the same as by locationsand values OR X is allocated memory separately and I need to free locations and values in the case.

Upvotes: 0

Views: 650

Answers (1)

Darkdragon84
Darkdragon84

Reputation: 911

The constructor (SpMat_meat.hpp:231) you are using

template<typename T1, typename T2>
inline SpMat(const Base<uword,T1>& locations, const Base<eT,T2>&  values, const bool sort_locations = true);

fills the sparse matrix with copies of the values in values.

I understand you are worried that you will run out of memory and if you keep loc, val and X separately you basically have two copies of the same data, taking up twice as much memory as actually needed (this is indeed what happens in your code snippet), so I will try to focus on addressing this problem and give you a few options:

1) If you are fine with keeping two copies of the data for a short while, the easiest solution is to dynamically allocate loc and val and delete them right after initialization of X

int main(int argc, char**argv){
    umat* ploc;
    vec* pval;
    load_data(*ploc,*pval); 
    // at this point we have one copy of the data
    sp_mat X(*ploc,*pval); 
    // at this point we have two copies of the data
    delete ploc;
    delete pval;
    // at this point we have one copy of the data

    return 0;
}

Of course you can use safe pointers instead of C style ones, but you get the idea.

2) If you absolutely don't want to have two copies of the data at any time, I would suggest that you modify your load_data routine to sequentially load values one by one and directly insert them into X

void load_data(umat &locations, vec& values, sp_mat& X){
 // fill up locations and values one by one into X
}

Other options would be to i) use move semantics to directly move the values in val into X or ii) directly use the memory allocated for val as the memory for X, similar to the advanced constructor for matrices

Mat(eT* aux_mem, const uword aux_n_rows, const uword aux_n_cols, const bool copy_aux_mem = true, const bool strict = false)

Both options would however require modifications on the level of the armadillo library, as such a functionality is not supplied yet for sparse matrices (There is only a plain move constructor so far). It would be a good idea to request these features from the developers though!

Upvotes: 1

Related Questions