2

I am using mex bridge to perform some operations on Sparse matrices from Matlab. For that I need to convert input matrix into CSR (compressed row storage) format, since Matlab stores the sparse matrices in CSC (compressed column storage).

I was able to get value array and column_indices array. However, I am struggling to get row_pointer array for CSR format.Is there any C library that can help in conversion from CSC to CSR ?

Further, while writing a CUDA kernel, will it be efficient to use CSR format for sparse operations or should I just use following arrays :- row indices, column indices and values?

Which on would give me more control over the data, minimizing the number for-loops in the custom kernel?

4
  • This seems like two completely unrelated questions - one to do with sparse matrix format conversion and the other a CUDA programming question. Which is it? Commented Jul 7, 2012 at 9:58
  • Second one.Cause I might end up in using triplet format or three arrays for row_indices,col_indices and values.Since I am not able to find a way to get row_ptrs for 'CSR' format.... Commented Jul 7, 2012 at 15:39
  • What about CUSPARSE? It has conversion routines including the one you are asking about, as well as comprehensive sparse BLAS operations, all without requiring you to write a line of code. And it ships with CUDA, so you already have it.... Commented Jul 7, 2012 at 16:42
  • @talonmies....Yes I am aware of CUSPARSE and CUSP and I am also aware of the fact that using libraries is always a better option, however, I was wondering whether it will be efficient to write my own kernel for sparse matrix addition/multiplication in CUDA...Thanks for the info about conversion routines in cuSPARSE...there is no direction conversion from CSC to CSR though...I'll have to create a intermediate dense matrix for that part... Commented Jul 7, 2012 at 21:28

3 Answers 3

4

Compressed row storage is similar to compressed column storage, just transposed. So the simplest thing is to use MATLAB to transpose the matrix before you pass it to your MEX file. Then, use the functions

Ap = mxGetJc(spA);
Ai = mxGetIr(spA);
Ax = mxGetPr(spA);

to get the internal pointers and treat them as row storage. Ap is row pointer, Ai is column indices of the non-zero entries, Ax are the non-zero values. Note that for symmetric matrices you do not have to do anything at all! CSC and CSR are the same.

Which format to use heavily depends on what you want to do with the matrix later. For example, have a look at matrix formats for Sparse matrix vector multiplication. That is one of the classic papers, research has moved since then so you can look around further.

Sign up to request clarification or add additional context in comments.

2 Comments

@angainor....Thanks for your suggestion....I was able to convert from CSC to CSR using CUDA CUSP library...
Perhaps post that as an answer then, @abhinole.
1

I ended up converting CSC format from Matlab to CSR using CUSP library as follows.

After getting the matrix A from matlab and I got its row,col and values vectors and I copied them in respective thrust::host_vector created for each of them.

After that I created two cusp::array1d of type Indices and Values as follows.

    typedef typename cusp::array1d<int,cusp::host_memory>Indices;   
    typedef typename cusp::array1d<float,cusp::host_memory>Values;
    Indices row_indices(rows.begin(),rows.end());
    Indices col_indices(cols.begin(),cols.end());
    Values  Vals(Val.begin(),Val.end());

where rows, cols and Val are thrust::host_vector that I got from Matlab.

After that I created a cusp::coo_matrix_view as given below.

typedef cusp::coo_matrix_view<Indices,Indices,Values>HostView;
HostView Ah(m,n,NNZa,row_indices,col_indices,Vals);

where m,n and NNZa are the parameters that I get from mex functions of sparse matrices.

I copied this view matrix to cusp::csr_matrixin device memory with proper dimensions set as given below.

    cusp::csr_matrix<int,float,cusp::device_memory>CSR(m,n,NNZa);
    CSR = Ah;   

After that I just copied the three individual content arrays of this CSR matrix back to the host using thrust::raw_pointer_cast where arrays with proper dimension are already mxCalloced as given below.

 cudaMemcpy(Acol,thrust::raw_pointer_cast(&CSR.column_indices[0]),sizeof(int)*(NNZa),cudaMemcpyDeviceToHost);
 cudaMemcpy(Aptr,thrust::raw_pointer_cast(&CSR.row_offsets[0]),sizeof(int)*(n+1),cudaMemcpyDeviceToHost);
 cudaMemcpy(Aval,thrust::raw_pointer_cast(&CSR.values[0]),sizeof(float)*(NNZa),cudaMemcpyDeviceToHost);

Hope this is useful to anyone who is using CUSP with Matlab

Comments

0

you can do something like this:

n = size(M,1);
nz_num = nnz(M);
[col,rowi,vals] = find(M');
row = zeros(n+1,1);
ll = 1; row(1) = 1;
for l = 2:n
    if rowi(l)~=rowi(l-1)
        ll = ll + 1;
        row(ll) = l;
    end
end
row(n+1) = nz_num+1;`

It works for me, hope it can help somebody else!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.