Incorrect result from cusparseSpMM() with COO sparse matrices

Hey there! I’m trying to use cusparse’s cusparseSpMM() operation, but it seems to be giving incorrect results, unless I’m calling it incorrectly.

For some reason, I’m getting correct results for some sparse matrices but incorrect result for others. The order of elements seems to make a difference. I’ve created a small git repo with my bug reproduction code: https://github.com/kurtamohler/cusparseSpMM-COO-bug

If you look in the main() of test.cpp, all my comments there describe the problem. The readme shows how to build and run the application.

Thanks in advance for any input!

By the way, I’m using Cuda compilation tools, release 10.1, V10.1.243

For the fifth example in my reproduction code, I’m setting the sparse matrix to be an identity:

1 0 0
0 1 0
0 0 1

The dense matrix is:

1 2 3
4 5 6
7 8 9

cusparseSpMM() is giving me this result:

3 6 9
0 0 0
0 0 0

But I should be getting a result equal to the input dense matrix.

I’ve updated my comments and printouts to hopefully show the problem more clearly. Someone from NVIDIA pointed out that the sparse matrix elements must be in ascending row order. However, I’m still getting incorrect results if I do that. Below is the full output of my current reproduction code.

Notice that the first case works fine, with only one element. The second one, in ascending order, fails. The third one is descending order, but it gives the correct result for some unknown reason. And the fourth and fifth both fail, whether or not I’m using ascending or descending order.

sparse matrix a:
(1, 1): 1
values: 1
row_indices: 1
col_indices: 1
shape: 3, 3
dense matrix b:
1 2 3
4 5 6
7 8 9
values: 1 4 7 2 5 8 3 6 9
shape: 3, 3
result dense matrix c = a * b =
0 0 0
4 5 6
0 0 0
values: 0 4 0 0 5 0 0 6 0
shape: 3, 3

sparse matrix a:
(1, 1): 1
(0, 0): 1
values: 1 1
row_indices: 1 0
col_indices: 1 0
shape: 3, 3
dense matrix b:
1 2 3
4 5 6
7 8 9
values: 1 4 7 2 5 8 3 6 9
shape: 3, 3
result dense matrix c = a * b =
1 2 3
4 5 6
0 0 0
values: 1 4 0 2 5 0 3 6 0
shape: 3, 3

sparse matrix a:
(0, 0): 1
(1, 1): 1
values: 1 1
row_indices: 0 1
col_indices: 0 1
shape: 3, 3
dense matrix b:
1 2 3
4 5 6
7 8 9
values: 1 4 7 2 5 8 3 6 9
shape: 3, 3
result dense matrix c = a * b =
2 4 6
0 0 0
0 0 0
values: 2 0 0 4 0 0 6 0 0
shape: 3, 3

sparse matrix a:
(2, 2): 1
(1, 1): 1
(0, 0): 1
values: 1 1 1
row_indices: 2 1 0
col_indices: 2 1 0
shape: 3, 3
dense matrix b:
1 2 3
4 5 6
7 8 9
values: 1 4 7 2 5 8 3 6 9
shape: 3, 3
result dense matrix c = a * b =
2 4 6
0 0 0
7 8 9
values: 2 0 7 4 0 8 6 0 9
shape: 3, 3

sparse matrix a:
(0, 0): 1
(1, 1): 1
(2, 2): 1
values: 1 1 1
row_indices: 0 1 2
col_indices: 0 1 2
shape: 3, 3
dense matrix b:
1 2 3
4 5 6
7 8 9
values: 1 4 7 2 5 8 3 6 9
shape: 3, 3
result dense matrix c = a * b =
3 6 9
0 0 0
0 0 0
values: 3 0 0 6 0 0 9 0 0
shape: 3, 3

sparse matrix a:
(0, 0): 1
(0, 1): 1
(0, 2): 1
(1, 0): 1
(1, 1): 1
(1, 2): 1
(2, 0): 1
(2, 1): 1
(2, 2): 1
values: 1 1 1 1 1 1 1 1 1
row_indices: 0 0 0 1 1 1 2 2 2
col_indices: 0 1 2 0 1 2 0 1 2
shape: 3, 3
dense matrix b:
1 2 3
4 5 6
7 8 9
values: 1 4 7 2 5 8 3 6 9
shape: 3, 3
result dense matrix c = a * b =
18 27 36
0 0 0
0 0 0
values: 18 0 0 27 0 0 36 0 0
shape: 3, 3

Liam from NVIDIA pointed out that I was using uint64_t indices in my sparse matrices, but cusparseSpMM only supports 32-bit indices. Liam showed me that the docs do mention this, I just didn’t read carefully enough. I switched to uint32_t, and now I’m getting correct results.

While I was going through this issue, I couldn’t find any existing examples of how to call cusparseSpMM. So now I’ve updated my repo to call it correctly, in case anyone else has the same issue and starts googling and searching github like I did.