currybab's blog

pmpp lecture 16 sparse matrix computation (COO and CSR) 정리

Source: Lecture 16 - Sparse Matrix Computation (COO and CSR)

Today

Sparse Matrices

Sparse Matrix Storage Formats

SpMV (희소 행렬-벡터 곱)

spmv

Coordinate Format (COO)

coo

    // unsigned int numThreadsPerBlock = 1024;
    // unsigned int numBlocks = (cooMatrix_d.numNonzeros + numThreadsPerBlock - 1) / numThreadsPerBlock;
    // spmv_coo_kernel <<< numBlocks, numThreadsPerBlock >>> (cooMatrix_d, inVector_d, outVector_d);
    
    struct COOMatrix {
        unsigned int numRows;
        unsigned int numCols;
        unsigned int numNonzeros;
        unsigned int* rowIdxs;
        unsigned int* colIdxs;
        float* values;
    }

    __global__ void spmv_coo_kernel(COOMatrix cooMatrix, float* inVector, float* outVector) {
        unsigned int i = blockIdx.x * blockDim.x + threadIdx.x;
        if (i < cooMatrix.numNonzeros) {
            unsigned int row = cooMatrix.rowIdxs[i];
            unsigned int col = cooMatrix.colIdxs[i];
            float value = cooMatrix.values[i];
            atomicAdd(&outVector[row], value * inVector[col]);
        }
    }

COO Tradeoffs

Compressed Sparse Row (CSR)

csr

    struct CSRMatrix {
        unsigned int numRows;
        unsigned int numCols;
        unsigned int numNonzeros;
        unsigned int* rowPtrs;
        unsigned int* colIdxs;
        float* values;
    }

    __global__ void spmv_csr_kernel(CSRMatrix csrMatrix, float* inVector, float* outVector) {
        unsigned int row = blockIdx.x * blockDim.x + threadIdx.x;
        if (row < csrMatrix.numRows) {
            float acc = 0.0f;
            for (unsigned int i = csrMatrix.rowPtrs[row]; i < csrMatrix.rowPtrs[row + 1]; i++) {
                unsigned int col = csrMatrix.colIdxs[i];
                float value = csrMatrix.values[i];
                acc += value * inVector[col];
            }
            outVector[row] = acc;
        }
    }

CSR Tradeoffs (versus COO)

열버전인 CSC(Compressed Sparse Column)

#blog #cuda #gpu #pmpp