Best way to use CuSparseMatrixBSR

So after reading through the CUSPARSE docs, specifically the level-2 function bsrmv, I can gleam that the dir attribute refers to the matrix descriptor cusparseDirection_t here.

Further, conversion from CuSparseMatrixCSR to CuSparseMatrixBSR seems to set dir as 'R', consistent with the fact that CSR formatted matrices are parsed row major.

Since julia stores matrices in column major format, it would seem that the appropriate thing to do is to set dir = 'C', assuming that this is the alias for CUSPARSE_DIRECTION_COLUMN.

From this I believe the appropriate construction of the blockdiagonal matrix BLs should be pretty simple

nzval = CUDA.rand(3*3*100)
# == reshape(Ls, 3*3*100)

rowptr = CuArray{Int32,1}(1:101)
colval = CuArray{Int32,1}(1:100)
dims = (3*100, 3*100)
blockdim = 3
dir = 'C'
nnz = 100

BLs = CuSparseMatrixBSR{Float32,Int32}(
    rowptr, colval, nzval, dims, blockdim, dir, nnz
)

This would make indexing into the individual Ls slightly uglier, the first kernel becomes

function matrix_kernel(f, BLsnzVal, BLsblockDim)
    ind = (blockIdx().x - 1) * blockDim().x + threadIdx().x
    stride = gridDim().x * blockDim().x
    len = length(BLsnzVal) ÷ BLsblockDim
    for i in ind-1 : stride : len-1
        j = 3 * i + 1 : 3 * i + BLsblockDim
        BLsnzval[j] = f(BLsnzVal[j])
    end
end

@cuda threads=3*100 matrix_kernel(f, BLs.nzVal, BLs.blockDim)

I believe this makes sense, but I’d still love to verify that dir = 'C' is appropriate here. I’m sorry I have to ask, I won’t be at my CUDA-capable work laptop until Monday.

1 Like