Skip to content
This repository was archived by the owner on Jul 10, 2025. It is now read-only.

Commit 52e920c

Browse files
authored
Update the RFC based on comments.
1 parent 2f24acb commit 52e920c

File tree

1 file changed

+18
-10
lines changed

1 file changed

+18
-10
lines changed

rfcs/20200519-csr-sparse-matrix.md

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ Support the [compressed sparse row (CSR)](https://en.wikipedia.org/wiki/Sparse_m
2424

2525
## Motivation
2626

27-
Sparse tensor representation has a significant impact on performance. Modern architectures are most suited for non-random, bulk memory accesses. Sparse formats that optimize for data locality and reuse can achieve large performance gains. TensorFlow currently stores sparse tensors in [coordinate (COO)](https://www.tensorflow.org/api_docs/python/tf/sparse/SparseTensor) format, which works well for tensors with very few nonzeroes, and is inefficient otherwise. Deep learning and sparse linear algebra applications typically do not have sufficient sparsities to benefit from the COO format. The compressed sparse row (CSR) format is one of the most commonly used formats. It generally requires less storage and is faster than COO, sometimes by up to orders of magnitudes.
27+
Sparse tensor representation has a significant impact on performance. Modern architectures are most suited for non-random, bulk memory accesses. Sparse formats that optimize for data locality and reuse can achieve large performance gains. TensorFlow currently stores sparse tensors in [coordinate (COO)](https://www.tensorflow.org/api_docs/python/tf/sparse/SparseTensor) format, which works well for tensors with very few nonzeroes, and is inefficient otherwise. Deep learning and sparse linear algebra applications typically do not have sufficient sparsities to benefit from the COO format. The compressed sparse row (CSR) format is one of the most commonly used formats. It generally requires less storage and is faster than COO, sometimes by up to orders of magnitude.
2828

2929
We propose supporting the CSR format in TensorFlow to accelerate sparse linear algebra and applicable deep learning applications in TensorFlow.
3030

@@ -46,6 +46,14 @@ All kernel implementations are in C++, with a Python wrapper for Python APIs. Du
4646

4747
### Supported Operations
4848
See APIs in the Detailed Design section.
49+
* Construction ops:
50+
* From a dense tensor.
51+
* From a SparseTensor.
52+
* From given `batch_pointers`, `row_pointers`, `col_indices`, and `values` arrays.
53+
* Op that returns CSR components.
54+
* Conversions ops:
55+
* Convert to and from dense tensor
56+
* Convert to and from SparseTensor.
4957
* Sparse linear algebra ops:
5058
* Sparse matrix-vector multiplication (SpMV)
5159
* Sparse-dense matrix multiplication (SpMM)
@@ -55,12 +63,9 @@ See APIs in the Detailed Design section.
5563
* Sparse Cholesky factorization
5664
* Sparse LU factorization
5765
* Sparse QR factorization
58-
* Conversions ops:
59-
* Convert to and from dense tensor
60-
* Convert to and from SparseTensor.
6166

6267
General ops, borrowing APIs from numpy and scipy ([sparse](https://docs.scipy.org/doc/scipy/reference/sparse.html), [sparse.csr_matrix](https://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.csr_matrix.html)) packages.
63-
* Construction ops: [eye](https://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.eye.html) and [rand](https://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.rand.html)
68+
* Generation ops: [eye](https://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.eye.html) and [rand](https://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.rand.html)
6469
* Unary ops that preserve sparsity structure:
6570
* [sin](https://docs.scipy.org/doc/numpy/reference/generated/numpy.sin.html), [cos](https://docs.scipy.org/doc/numpy/reference/generated/numpy.cos.html), [tan](https://docs.scipy.org/doc/numpy/reference/generated/numpy.tan.html), [sinh](https://docs.scipy.org/doc/numpy/reference/generated/numpy.sinh.html), [cosh](https://docs.scipy.org/doc/numpy/reference/generated/numpy.cosh.html), [tanh](https://docs.scipy.org/doc/numpy/reference/generated/numpy.tanh.html)
6671
* [arcsin](https://docs.scipy.org/doc/numpy/reference/generated/numpy.arcsin.html), [arcsinh](https://docs.scipy.org/doc/numpy/reference/generated/numpy.arcsinh.html), [arccos](https://docs.scipy.org/doc/numpy/reference/generated/numpy.arccos.html), [arccosh](https://docs.scipy.org/doc/numpy/reference/generated/numpy.arccosh.html), [arctan](https://docs.scipy.org/doc/numpy/reference/generated/numpy.arctan.html), [arctanh](https://docs.scipy.org/doc/numpy/reference/generated/numpy.arctanh.html)
@@ -74,6 +79,8 @@ General ops, borrowing APIs from numpy and scipy ([sparse](https://docs.scipy.or
7479
* [eliminate_zeros](https://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.sparse.csr_matrix.eliminate_zeros.html)
7580
* [sum_duplicates](https://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.csr_matrix.sum_duplicates.html)
7681
* [transpose](https://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.csr_matrix.transpose.html)
82+
* Binary element-wise ops that preserve sparsity structure:
83+
* [with_values](https://www.tensorflow.org/api_docs/python/tf/RaggedTensor#with_values)
7784
* Binary element-wise ops (may change sparsity structure):
7885
* [maximum](https://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.csr_matrix.maximum.html), [minimum](https://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.csr_matrix.minimum.html)
7986
* add, sub, [multiply](https://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.csr_matrix.multiply.html), divide, [dot](https://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.csr_matrix.dot.html)
@@ -87,6 +94,7 @@ General ops, borrowing APIs from numpy and scipy ([sparse](https://docs.scipy.or
8794
* Ops that returns indices:
8895
* [argmax](https://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.csr_matrix.argmax.html), [argmin](https://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.csr_matrix.argmin.html), [diagonal](https://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.csr_matrix.diagonal.html), [nonzero](https://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.csr_matrix.nonzero.html)
8996

97+
The ops will support broadcasting when possible.
9098

9199
### Alternatives Considered
92100
We have considered several other sparse formats in addition to CSR.
@@ -194,7 +202,7 @@ D_csr = csr.concat([A_csr, B_csr, C_csr], axis=1)
194202
* How this proposal interacts with other parts of the TensorFlow Ecosystem:
195203
* TFLite: TFLite already supports the CSR format. TensorFlow should be able to pass the format to TFLite without problems.
196204
* Distribution strategies: Don’t plan on interacting with this in this initial phase.
197-
* tf.function: Should work just like any other ops.
205+
* tf.function: Can be made to work with tf.function. Will work straightforwardly if CSRSparseMatrix is a [CompositeTensor](https://cs.opensource.google/tensorflow/tensorflow/+/v2.2.0:tensorflow/python/framework/composite_tensor.py;l=31).
198206
* GPU: We plan to make all CSRSparseMatrix operations work on GPUs.
199207
* TPU: We don’t plan on supporting CSRSparseMatrix on TPUs yet.
200208
* SavedModel: Should work just like any other ops/tensors.
@@ -215,7 +223,7 @@ There are CSRSparseMatrix classes on both C++ and Python sides. The C++ CSRSpars
215223

216224

217225
### C++ Layer
218-
The C++ [CSRSparseMatrix](https://cs.opensource.google/tensorflow/tensorflow/+/master:tensorflow/core/kernels/sparse/sparse_matrix.h;l=35) class has the following properties:
226+
The C++ [CSRSparseMatrix](https://cs.opensource.google/tensorflow/tensorflow/+/v2.2.0:tensorflow/core/kernels/sparse/sparse_matrix.h;l=35) class has the following properties:
219227

220228
<table>
221229
<tr><th align="left">Property</th><th align="left">Description</th></tr>
@@ -275,7 +283,7 @@ The C++ [CSRSparseMatrix](https://cs.opensource.google/tensorflow/tensorflow/+/m
275283

276284

277285
### Python Layer
278-
The Python [CSRSparseMatrix](https://cs.opensource.google/tensorflow/tensorflow/+/v2.2.0-rc4:tensorflow/python/ops/linalg/sparse/sparse_csr_matrix_ops.py;l=315) class is a subclass of [SparseMatrix](https://cs.opensource.google/tensorflow/tensorflow/+/v2.2.0-rc4:tensorflow/python/ops/linalg/sparse/sparse_csr_matrix_ops.py;l=248), which stores common sparse matrix properties. Other new sparse formats can be added as subclasses of SparseMatrix. CSRSparseMatrix has the following properties:
286+
The Python [CSRSparseMatrix](https://cs.opensource.google/tensorflow/tensorflow/+/v2.2.0:tensorflow/python/ops/linalg/sparse/sparse_csr_matrix_ops.py;l=315) class is a subclass of [SparseMatrix](https://cs.opensource.google/tensorflow/tensorflow/+/v2.2.0:tensorflow/python/ops/linalg/sparse/sparse_csr_matrix_ops.py;l=248), which stores common sparse matrix properties. Other new sparse formats can be added as subclasses of SparseMatrix. CSRSparseMatrix has the following properties:
279287

280288
| Property | Description |
281289
| :-------- | :----------------------------------- |
@@ -285,7 +293,7 @@ The Python [CSRSparseMatrix](https://cs.opensource.google/tensorflow/tensorflow/
285293

286294

287295
### Shape Inference
288-
`Variant` tensors are perceived as scalars in TensorFlow. For proper shape inference, we store `CSRSparseMatrix`’s shape and data type in a shape inference primitive, [ShapeAndType](https://cs.opensource.google/tensorflow/tensorflow/+/v2.2.0-rc4:tensorflow/core/framework/shape_inference.h;l=133), and access them through [input_handle_shapes_and_types](https://cs.opensource.google/tensorflow/tensorflow/+/v2.2.0-rc4:tensorflow/core/framework/shape_inference.h;l=584) and [set_output_handle_shapes_and_types](https://cs.opensource.google/tensorflow/tensorflow/+/v2.2.0-rc4:tensorflow/core/framework/shape_inference.h;l=588) during shape inference.
296+
`Variant` tensors are perceived as scalars in TensorFlow. For proper shape inference, we store `CSRSparseMatrix`’s shape and data type in a shape inference primitive, [ShapeAndType](https://cs.opensource.google/tensorflow/tensorflow/+/v2.2.0:tensorflow/core/framework/shape_inference.h;l=133), and access them through [input_handle_shapes_and_types](https://cs.opensource.google/tensorflow/tensorflow/+/v2.2.0:tensorflow/core/framework/shape_inference.h;l=584) and [set_output_handle_shapes_and_types](https://cs.opensource.google/tensorflow/tensorflow/+/v2.2.0:tensorflow/core/framework/shape_inference.h;l=588) during shape inference.
289297

290298

291299
### APIs
@@ -321,7 +329,7 @@ Other sparse APIs follow NumPy and SciPy APIs. See links in [Supported Operation
321329
* Should we add `CSRSparseMatrix` support to existing standard ops as well, e.g., `tf.math.{add,asin,atan,ceil}`, etc?
322330
* Would love to hear about more use cases.
323331
* For neural networks, would CSR be useful for you (while Block CSR is still a future work)?
324-
* Should we make CSRSparseMatrix a [CompositeTensor](https://cs.opensource.google/tensorflow/tensorflow/+/v2.2.0-rc4:tensorflow/python/framework/composite_tensor.py;l=31)? Would the effort be worth it since we will transition to the new TFRT/MLIR backend soon? How should this be prioritized?
332+
* Should we make CSRSparseMatrix a [CompositeTensor](https://cs.opensource.google/tensorflow/tensorflow/+/v2.2.0:tensorflow/python/framework/composite_tensor.py;l=31)? Would the effort be worth it since we will transition to the new TFRT/MLIR backend soon? How should this be prioritized?
325333
* Should `SparseMatrix` replace `SparseTensor`?
326334

327335

0 commit comments

Comments
 (0)