Inferensys

Glossary

CSR Format (Compressed Sparse Row)

CSR (Compressed Sparse Row) is a memory-efficient storage format for sparse matrices that encodes only non-zero values and their column indices with compressed row pointers.
Developer working on RAG retrieval system, document chunks visible on screen, technical workspace with code editor.
SPARSE MODEL INFERENCE

What is CSR Format (Compressed Sparse Row)?

The CSR (Compressed Sparse Row) format is a standard storage scheme for sparse matrices, designed to minimize memory usage and enable efficient linear algebra operations by encoding only non-zero values and their locations.

CSR (Compressed Sparse Row) is a memory-efficient data structure for representing sparse matrices, where most elements are zero. It encodes three arrays: values (non-zero entries), col_indices (their column positions), and row_ptr (compressed pointers to the start of each row). This format eliminates the storage of zeros, drastically reducing memory footprint for models with weight sparsity from pruning. Its row-major compression is optimal for operations like sparse matrix-vector multiplication (SpMV), a core kernel in neural network inference.

The efficiency of CSR in execution depends on the sparse data layout. The row_ptr array enables fast row traversal, but irregular column indices within a row can cause load imbalance in parallel hardware. For sparse matrix multiplication (SpMM) on GPUs, CSR kernels must optimize gather-scatter operations to mitigate overhead from irregular memory access. While excellent for general sparse storage, structured pruning patterns like N:M sparsity may use even more efficient, hardware-native formats. CSR remains foundational for representing unstructured sparsity in compressed models.

SPARSE MODEL INFERENCE

Key Characteristics of CSR Format

The Compressed Sparse Row (CSR) format is a foundational data structure for efficiently storing and operating on sparse matrices, where most elements are zero. Its design prioritizes fast row access and is a cornerstone for executing pruned neural networks.

01

Core Data Structure

CSR represents a sparse matrix using three one-dimensional arrays:

  • values (val or data): Stores all non-zero values in row-major order.
  • column_indices (col_idx): Stores the column index for each corresponding non-zero value.
  • row_pointers (row_ptr): Stores the cumulative number of non-zero elements up to each row. The non-zero values for row i are found in values[row_ptr[i]:row_ptr[i+1]].

This structure eliminates the storage of zeros, trading memory for the overhead of storing explicit indices.

02

Optimized for Row-Wise Operations

The row_pointers array enables constant-time lookup to find the start and end of any row's non-zero elements. This makes CSR exceptionally efficient for algorithms that iterate over rows, such as:

  • Sparse Matrix-Vector Multiplication (SpMV): The canonical operation where CSR excels.
  • Row slicing and access.
  • Forward passes in neural networks, which are often expressed as sequences of SpMV-like operations.

Its efficiency diminishes for operations requiring fast column access, for which the Compressed Sparse Column (CSC) format is better suited.

03

Memory Efficiency Profile

For an M x N matrix with NZ non-zeros, CSR storage cost is:

  • values: NZ elements.
  • column_indices: NZ integer elements.
  • row_pointers: M + 1 integer elements.

This is typically far smaller than the dense M * N storage. The break-even point depends on the sparsity level and the bit-width of the indices. For highly sparse weight matrices in pruned models, CSR can reduce memory footprint by 10x or more compared to dense storage.

04

Sparse Matrix Multiplication (SpMM) Kernel

Executing Sparse Matrix-Dense Matrix Multiplication (SpMM)—the workhorse of sparse inference—with CSR involves a nested loop:

  1. Outer loop iterates over rows (i).
  2. Inner loop iterates over non-zeros in row i (using row_ptr).
  3. For each non-zero, multiply it with the corresponding row of the dense input matrix (indexed by col_idx).

Performance is dominated by indirect memory access (gather) into the dense matrix and potential load imbalance if rows have highly variable non-zero counts. Optimized SpMM kernels use techniques like row grouping and warp-level parallelism to mitigate these issues.

05

Comparison with COO Format

CSR is often compared to the simpler Coordinate (COO) Format, which stores a list of (row, column, value) tuples.

AspectCSRCOO
StorageNZ + NZ + (M+1)NZ + NZ + NZ (3 arrays)
Row AccessFast (O(1) via row_ptr)Slow (requires search)
ConstructionRequires sortingSimple to build
DuplicatesNot allowedCan handle duplicates

CSR is generally preferred for efficient computation, while COO is useful for incremental matrix construction before conversion.

06

Hardware & Compiler Considerations

Efficient execution of CSR-based models depends on the underlying hardware and software stack:

  • GPUs with Sparse Tensor Cores (e.g., NVIDIA Ampere+): Can accelerate CSR/SpMM but often require a structured sparsity pattern (e.g., 2:4) for peak performance, necessitating a conversion from the unstructured CSR format.
  • Compiler Mapping: AI compilers (e.g., TVM, MLIR) must map the abstract CSR operations to optimized gather-compute-scatter kernels on the target architecture.
  • Overhead: The sparse efficiency gap is real; the theoretical FLOP reduction from sparsity is offset by kernel overhead for index processing and irregular memory access. Profiling is essential.
COMPARISON

CSR vs. Other Sparse Storage Formats

A technical comparison of the Compressed Sparse Row (CSR) format against other common sparse tensor representations, highlighting their memory efficiency, access patterns, and suitability for different computational kernels in sparse model inference.

Feature / MetricCSR (Compressed Sparse Row)COO (Coordinate Format)CSC (Compressed Sparse Column)Blocked CSR (BCSR)

Primary Storage Arrays

row_ptr, col_ind, val

row_ind, col_ind, val

col_ptr, row_ind, val

row_ptr, col_ind, val (blocked)

Optimal Access Pattern

Row-wise traversal

Random, unordered access

Column-wise traversal

Row-wise, block-aligned traversal

Memory Overhead (Indices)

O(nnz + n_rows)

O(2 * nnz)

O(nnz + n_cols)

O(nnz + n_rows) + block metadata

SpMM (Sparse-Dense) Kernel Suitability

✅ Excellent for SpMM (A * B)

❌ Poor (requires conversion)

✅ Excellent for SpMM (A^T * B)

✅ Excellent for vectorized/GPU SpMM

Ease of Construction/Modification

❌ Difficult (requires sorting, prefix sum)

✅ Trivial (append tuples)

❌ Difficult (requires sorting, prefix sum)

❌ Difficult (requires block detection & alignment)

Hardware Acceleration Support

Widely supported in BLAS libraries

Minimal native support

Widely supported in BLAS libraries

Targeted support for specific NPUs/GPUs

Typical Use Case in ML

Inference for unstructured sparse weights (SpMM)

Initial sparse representation; graph data

Operations requiring column access

Inference for structured/blocked sparse weights

SPARSE MODEL INFERENCE

CSR in ML Frameworks and Libraries

The Compressed Sparse Row (CSR) format is a foundational data structure for efficiently storing and computing with sparse matrices, where most elements are zero. It is critical for executing pruned neural networks on hardware accelerators.

01

Core Data Structure

The CSR format represents a sparse matrix using three one-dimensional arrays:

  • data: Stores all non-zero values in row-major order.
  • indices: Stores the column index for each corresponding non-zero value in the data array.
  • indptr (index pointer): Stores the start and end indices in the data and indices arrays for each row. For row i, non-zero values are found at data[indptr[i]:indptr[i+1]] with column indices indices[indptr[i]:indptr[i+1]]. This structure eliminates the storage of zeros, compressing memory footprint, but introduces indirect memory access via the indices array.
02

Sparse Matrix Multiplication (SpMM)

The primary operation enabled by CSR is Sparse Matrix-Dense Matrix Multiplication (SpMM), a key kernel in sparse neural network inference. For a sparse weight matrix W in CSR and a dense input activation matrix X, the output Y = W @ X is computed row-by-row:

  • Each row of W defines a sparse dot product.
  • The indptr array allows efficient iteration over rows.
  • For each non-zero weight W[i, j] at column j, the operation gathers the dense vector X[j, :], multiplies it by the weight, and scatters the result into Y[i, :]. Performance hinges on optimizing these gather-scatter operations and managing load imbalance from varying row lengths.
03

Integration in ML Frameworks

Major frameworks provide specialized APIs and backends for CSR:

  • PyTorch: Offers torch.sparse_csr tensor type with operators like torch.sparse.mm() for SpMM. Sparse tensors can be created from dense ones via to_sparse_csr(). The TorchInductor compiler can fuse sparse operations.
  • TensorFlow / JAX: Use scipy.sparse.csr_matrix as an interoperable standard. JAX's jax.experimental.sparse module provides JIT-compatible CSR operations. TensorFlow has historical support via tf.sparse.SparseTensor (in COO format, convertible to CSR).
  • Framework Kernels: These APIs dispatch to optimized backend libraries like cuSPARSE (NVIDIA GPU), MKL (Intel CPU), or Eigen for actual computation, abstracting the complex kernel implementation.
04

Hardware Acceleration & Limitations

While CSR is versatile, its irregular memory access pattern poses challenges for peak hardware utilization:

  • GPU Execution: NVIDIA's Sparse Tensor Cores (on Ampere+ GPUs) do not natively support arbitrary CSR. They require the 2:4 fine-grained structured sparsity pattern, where a custom compressed format is used. Generic CSR SpMM relies on cuSPARSE libraries which can suffer from load imbalance and metadata overhead.
  • CPU Execution: Optimized MKL/OpenBLAS kernels use vectorization, but performance is often memory-bandwidth bound due to indirect accesses.
  • Specialized NPUs: Many edge AI accelerators have dedicated units for structured sparsity (e.g., channel pruning). Irregular CSR from unstructured pruning may not achieve peak throughput, leading to the sparse efficiency gap. The choice between CSR and other formats (like Blocked CSR) is a hardware-aware decision.
05

The Sparse Efficiency Gap

A critical concept in sparse inference is that the theoretical FLOP reduction from pruning does not translate linearly to speedup. With CSR, this gap is caused by:

  • Kernel Overhead: Decoding indptr and indices arrays, conditional branching, and pointer chasing add fixed costs.
  • Inefficient Memory Access: The gather of dense inputs via indices results in non-contiguous, cache-unfriendly reads, often stalling the compute pipeline.
  • Load Imbalance: Rows with vastly different numbers of non-zeros cause thread divergence in parallel execution, leaving some cores idle. Thus, a model with 90% weight sparsity (a 10x FLOP reduction) may only achieve a 2-3x actual speedup using generic CSR kernels, emphasizing the need for hardware-aligned sparsity patterns.
06

Related Sparse Formats

CSR is one of several sparse storage formats, each with trade-offs:

  • CSC (Compressed Sparse Column): The column-major analogue of CSR. Optimal for operations that access columns of the sparse matrix.
  • COO (Coordinate Format): Stores explicit (row, column, value) tuples. Simpler to construct but often less efficient for SpMM due to lack of row compression.
  • Blocked CSR (BSR): Groups non-zeros into small dense blocks (e.g., 4x4). Improves memory access regularity and enables use of vector/SIMD units, trading some sparsity for better hardware utilization.
  • Structured Sparsity Formats (e.g., 2:4): Used by NVIDIA Sparse Tensor Cores. Stores a compressed matrix of non-zero values plus a bitmask, enabling predictable, aligned memory accesses and 2x theoretical speedup on supported GPUs.
CSR FORMAT

Frequently Asked Questions

The Compressed Sparse Row (CSR) format is a foundational data structure for efficiently storing and computing with sparse matrices, where most elements are zero. It is critical for executing pruned neural networks in on-device and high-performance computing environments.

The Compressed Sparse Row (CSR) format is a storage scheme for sparse matrices that compresses row index information to minimize memory overhead. It works by using three one-dimensional arrays:

  • values (or data): Stores all the non-zero values, in row-major order.
  • col_indices: Stores the column index for each corresponding non-zero value in the values array.
  • row_ptr (or row_offsets): Stores the cumulative count of non-zero elements up to each row. The value at index i gives the start position in the values and col_indices arrays for row i, and row_ptr[i+1] gives the end position.

For a matrix with M rows and N columns, and nnz non-zero elements, the memory footprint is O(nnz + M) instead of O(M * N). The row_ptr array enables fast row-wise traversal, making operations like Sparse Matrix-Vector Multiplication (SpMV) efficient, as all non-zeros for a given row are stored contiguously.

Prasad Kumkar

About the author

Prasad Kumkar

CEO & MD, Inference Systems

Prasad Kumkar is the CEO & MD of Inference Systems and writes about AI systems architecture, LLM infrastructure, model serving, evaluation, and production deployment. Over 5+ years, he has worked across computer vision models, L5 autonomous vehicle systems, and LLM research, with a focus on taking complex AI ideas into real-world engineering systems.

His work and writing cover AI systems, large language models, AI agents, multimodal systems, autonomous systems, inference optimization, RAG, evaluation, and production AI engineering.