0
$\begingroup$

I have a matrix in Coordinate format and I will convert it to CSC. As a reference, the format I am using looks like this, but I am not using the pointerE matrix, which I think is superfluous.

My conversion algorithm seems quite slow and I am losing some time sorting the row data by row number. I can't figure out why I am doing this though, since I will be simply applying a Conjugate Gradient or GMRES method, I only need the result of $A\hat{v}=...$ which I think I can do without sorting row data.

Any reason why I should sort them anyway?

$\endgroup$
3
$\begingroup$

I am assuming you are using the format here http://netlib.org/linalg/html_templates/node92.html

Efficient memory access! When you do an SpMV operation, if the row data is not sorted, there may be a lot of random back and forth jumps in the memory when reading and writing the vector $y$. See the pseudocode below;

for j=0 to n-1                      //loop over columns
  for i=col_ptr[j] to col_ptr[j+1]  //loop over rows
    y[row_ind[i]] += val[i]*x[j]    //y(row) += A(row,col) * x(col)
                                    //A(row,col) is stored at val[i] where i is s.t.
                                    //row_ind[i]=row and col_ptr[j]<=i<col_ptr[j+1]

Reading from RAM is especially important when the matrix is somehow structured and large, consider finite element matrices for example.

Also just to be sure, you are sorting the row data per column, right? Because sorting 20 or so elements shouldn't take much time, even if you are doing it 100,000 times.

| cite | improve this answer | |
$\endgroup$
  • $\begingroup$ hi yes, sorting per column. OK so you're saying if the resulting vector is large, you will have to bring different parts of your data into and out of the cache? and this would slow you down? $\endgroup$ – Not a chance Feb 15 at 9:51
  • $\begingroup$ Finite Element is my interest here by the way $\endgroup$ – Not a chance Feb 15 at 9:51
  • $\begingroup$ Yes, but not only a cache issue. Reading consecutively from RAM is faster than reading randomly. For example, think of dense matrix-vector multiplication operation in C. Since C is a row-major programming language, loops should first go over columns. Otherwise, it will be few orders slower. I heard that newer compilers are able to notice that and either fix the issue or throw a warning. But I do not know how true that is. For your case, better idea might be to create your matrix in CSC format directly. $\endgroup$ – Abdullah Ali Sivas Feb 15 at 18:34
  • $\begingroup$ indeed... good point. $\endgroup$ – Not a chance Feb 16 at 8:54
2
$\begingroup$

In addition to @AbdullahAliSivas answer, there is also the issue that one often doesn't just write into a matrix entry once. Rather, one adds up multiple contributions (e.g., in the finite element method, each cell adjacent to a degree of freedom will have contributions) and frequently also needs to read specific matrix entries.

If you don't sort the entries, then finding where to add another contribution or read from becomes quite an expensive step.

| cite | improve this answer | |
$\endgroup$
  • $\begingroup$ yes also a good point. Thanks $\endgroup$ – Not a chance Mar 1 at 9:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.