diff --git a/rfcs/APIs/20020329_api_design_for_sparse_subtract.md b/rfcs/APIs/20020329_api_design_for_sparse_subtract.md
index 1c4f8b03a..a7ba18810 100644
--- a/rfcs/APIs/20020329_api_design_for_sparse_subtract.md
+++ b/rfcs/APIs/20020329_api_design_for_sparse_subtract.md
@@ -1,12 +1,12 @@
# paddle.sparse.subtract 设计文档
-|API名称 | paddle.sparse.subtract |
- |----------------------------------------|-----------------------------------------------------------|
-|提交作者 | PeachML |
-|提交时间 | 2022-03-29 |
-|版本号 | V1.0 |
-|依赖飞桨版本 | develop |
-|文件名 | 20220329_api_design_for_sparse_subtract.md
|
+| API名称 | paddle.sparse.subtract |
+|----------------------------------------------------------|------------------------------------------------|
+| 提交作者 | PeachML |
+| 提交时间 | 2022-03-29 |
+| 版本号 | V1.0 |
+| 依赖飞桨版本 | develop |
+| 文件名 | 20220329_api_design_for_sparse_subtract.md
|
# 一、概述
@@ -141,7 +141,7 @@ Scipy中有csr类型的稀疏矩阵,可以支持相减操作,通过`binary_o
# 四、对比分析
-torch设计结构复杂,为了适配paddle phi库的设计模式,故采用scipy的实现方式
+torch设计结构复杂,为了适配paddle phi库的设计模式,故参考scipy的实现方式
# 五、方案设计
@@ -150,55 +150,85 @@ torch设计结构复杂,为了适配paddle phi库的设计模式,故采用sc
在paddle/phi/kernels/sparse/目录下, kernel设计为
```
-void SubtractCsrKernel(const Context& dev_ctx,
- const SparseCsrTensor& x,
- const SparseCsrTensor& y,
- SparseCsrTensor* out);
+void ElementWiseSubtractCsrCPUKernel(const Context& dev_ctx,
+ const SparseCsrTensor& x,
+ const SparseCsrTensor& y,
+ SparseCsrTensor* out)
+```
+
+
+```
+void ElementWiseSubtractCooKernel(const Context& dev_ctx,
+ const SparseCooTensor& x,
+ const SparseCooTensor& y,
+ SparseCooTensor* out)
```
```
-//暂定
-void SubtractCsrGradKernel(const Context& dev_ctx,
- const SparseCsrTensor& x,
- const SparseCsrTensor& y,
- const SparseCsrTensor& dout,
- SparseCsrTensor* dx,
- SparseCsrTensor* dy);
+void ElementWiseSubtractCsrGradKernel(const Context& dev_ctx,
+ const SparseCsrTensor& x,
+ const SparseCsrTensor& y,
+ const SparseCsrTensor& dout,
+ SparseCsrTensor* dx,
+ SparseCsrTensor* dy);
+
+```
+```
+void ElementWiseSubtractCooGradKernel(const Context& dev_ctx,
+ const SparseCooTensor& x,
+ const SparseCooTensor& y,
+ const SparseCooTensor& dout,
+ SparseCooTensor* dx,
+ SparseCooTensor* dy);
```
函数设计为
```
-SparseCooTensor Subtract(const Context& dev_ctx,
- const SparseCooTensor& x,
- const SparseCooTensor& y);
+SparseCsrTensor ElementWiseSubtractCsr(const Context& dev_ctx,
+ const SparseCsrTensor& x,
+ const SparseCsrTensor& y)
```
和
```
-SparseCsrTensor Subtract(const Context& dev_ctx,
- const SparseCsrTensor& x,
- const SparseCsrTensor& y);
+SparseCooTensor ElementWiseSubtractCoo(const Context& dev_ctx,
+ const SparseCooTensor& x,
+ const SparseCooTensor& y)
```
## 底层OP设计
-新增一个sparse elementwise 的功能模块(暂定),然后使用已有op组合实现, 主要涉及`SparseCooToCsrKernel`和`SparseCsrToCooKernel`。
+实现对应的 CPU Kernel,使用 Merge 两个有序数组的算法,然后使用已有op组合实现, 主要涉及`SparseCooToCsrKernel`和`SparseCsrToCooKernel`。
+
+对于dense tensor,值连续的存储在一块内存中,二元运算需要处理每一个元素,即`x[i][j] ∘ y[i][j]`,运算时间复杂度为 `O(numel(x))`,
+`numel(x)`为`x`中总素个数。
+
+而sparse tensor以索引和值的模式存储一个多数元素为零的tensor,二元运算只需要处理两个输入不全为0的位置,
+在sparse tensor构造时,索引按升序排序,可以采取merge有序数组的方式,若两输入索引相等,则计算`x[i][j] ∘ y[i][j]`,
+若不相等则说明该位置上的二元运算有一个元为0,
+`x`索引小时计算 `x[i][j] ∘ 0`,`y`索引小时计算 `0 ∘ y[i][j]`。
+计算过的位置存储在新的索引数组中,这样,索引没有覆盖到的位置依然为0,节省了计算开销,时间复杂度为`O(nnz(x) + nnz(y))`,
+`nnz(x)`为`x`中非零元素个数。
## API实现方案
-主要参考scipy实现,将coo转换成csr再进行减法,然后转换回coo
+对于SparseCsrTensor,将csr格式转换成coo格式再进行运算,然后转换回csr格式输出。
+
+对于SparseCooTensor,直接进行运算。
# 六、测试和验收的考量
测试考虑的case如下:
- 数值正确性
+- 反向
+- 不同 `sparse_dim`
# 七、可行性分析及规划排期
-方案主要依赖paddle现有op组合而成
+方案主要依赖paddle现有op组合而成,并自行实现核心算法
# 八、影响面
diff --git a/rfcs/APIs/20220329_api_design_for_sparse_add.md b/rfcs/APIs/20220329_api_design_for_sparse_add.md
index 2385af587..14615225b 100644
--- a/rfcs/APIs/20220329_api_design_for_sparse_add.md
+++ b/rfcs/APIs/20220329_api_design_for_sparse_add.md
@@ -1,12 +1,12 @@
# paddle.sparse.add 设计文档
-|API名称 | paddle.sparse.add |
-|---|-----------------------------------------------------------|
-|提交作者 | PeachML |
-|提交时间 | 2022-03-29 |
-|版本号 | V1.0 |
-|依赖飞桨版本 | develop |
-|文件名 | 20220329_api_design_for_sparse_add.md
|
+| API名称 | paddle.sparse.add |
+|----------------------------------------------------------|-------------------------------------------|
+| 提交作者 | PeachML |
+| 提交时间 | 2022-03-29 |
+| 版本号 | V1.0 |
+| 依赖飞桨版本 | develop |
+| 文件名 | 20220329_api_design_for_sparse_add.md
|
# 一、概述
@@ -141,7 +141,7 @@ void csr_binop_csr_general(const I n_row, const I n_col,
# 四、对比分析
-torch设计结构复杂,为了适配paddle phi库的设计模式,故采用scipy的实现方式
+torch设计结构复杂,为了适配paddle phi库的设计模式,故参考scipy的实现方式
# 五、方案设计
@@ -150,54 +150,83 @@ torch设计结构复杂,为了适配paddle phi库的设计模式,故采用sc
在paddle/phi/kernels/sparse/目录下, kernel设计为
```
-void AddCsrKernel(const Context& dev_ctx,
- const SparseCsrTensor& x,
- const SparseCsrTensor& y,
- SparseCsrTensor* out);
+void ElementWiseAddCsrKernel(const Context& dev_ctx,
+ const SparseCsrTensor& x,
+ const SparseCsrTensor& y,
+ SparseCsrTensor* out)
+```
+
+
+```
+void ElementWiseAddCooKernel(const Context& dev_ctx,
+ const SparseCooTensor& x,
+ const SparseCooTensor& y,
+ SparseCooTensor* out)
```
```
-//暂定
-void AddCsrGradKernel(const Context& dev_ctx,
- const SparseCsrTensor& x,
- const SparseCsrTensor& y,
- const SparseCsrTensor& dout,
- SparseCsrTensor* dx,
- SparseCsrTensor* dy);
+void ElementWiseAddCsrGradKernel(const Context& dev_ctx,
+ const SparseCsrTensor& x,
+ const SparseCsrTensor& y,
+ const SparseCsrTensor& dout,
+ SparseCsrTensor* dx,
+ SparseCsrTensor* dy);
+```
+```
+void ElementWiseAddCooGradKernel(const Context& dev_ctx,
+ const SparseCooTensor& x,
+ const SparseCooTensor& y,
+ const SparseCooTensor& dout,
+ SparseCooTensor* dx,
+ SparseCooTensor* dy);
```
函数设计为
```
-SparseCooTensor Add(const Context& dev_ctx,
- const SparseCooTensor& x,
- const SparseCooTensor& y);
+SparseCsrTensor ElementWiseAddCsr(const Context& dev_ctx,
+ const SparseCsrTensor& x,
+ const SparseCsrTensor& y)
```
和
```
-SparseCsrTensor Add(const Context& dev_ctx,
- const SparseCsrTensor& x,
- const SparseCsrTensor& y);
+SparseCooTensor ElementWiseAddCoo(const Context& dev_ctx,
+ const SparseCooTensor& x,
+ const SparseCooTensor& y)
```
## 底层OP设计
-新增一个sparse elementwise 的功能模块(暂定),然后使用已有op组合实现, 主要涉及`SparseCooToCsrKernel`和`SparseCsrToCooKernel`。
+实现对应的 CPU Kernel,使用 Merge 两个有序数组的算法,然后使用已有op组合实现, 主要涉及`SparseCooToCsrKernel`和`SparseCsrToCooKernel`。
+
+对于dense tensor,值连续的存储在一块内存中,二元运算需要处理每一个元素,即`x[i][j] ∘ y[i][j]`,运算时间复杂度为 `O(numel(x))`,
+`numel(x)`为`x`中总素个数。
+
+而sparse tensor以索引和值的模式存储一个多数元素为零的tensor,二元运算只需要处理两个输入不全为0的位置,
+在sparse tensor构造时,索引按升序排序,可以采取merge有序数组的方式,若两输入索引相等,则计算`x[i][j] ∘ y[i][j]`,
+若不相等则说明该位置上的二元运算有一个元为0,
+`x`索引小时计算 `x[i][j] ∘ 0`,`y`索引小时计算 `0 ∘ y[i][j]`。
+计算过的位置存储在新的索引数组中,这样,索引没有覆盖到的位置依然为0,节省了计算开销,时间复杂度为`O(nnz(x) + nnz(y))`,
+`nnz(x)`为`x`中非零元素个数。
## API实现方案
-主要参考scipy实现,将coo转换成csr再进行加法,然后转换回coo
+对于SparseCsrTensor,将csr格式转换成coo格式再进行运算,然后转换回csr格式输出。
+
+对于SparseCooTensor,直接进行运算。
# 六、测试和验收的考量
测试考虑的case如下:
- 数值正确性
+- 反向
+- 不同 `sparse_dim`
# 七、可行性分析及规划排期
-方案主要依赖paddle现有op组合而成
+方案主要依赖paddle现有op组合而成,并自行实现核心算法
# 八、影响面
diff --git a/rfcs/APIs/20220329_api_design_for_sparse_divide.md b/rfcs/APIs/20220329_api_design_for_sparse_divide.md
index f75de08a7..98b288824 100644
--- a/rfcs/APIs/20220329_api_design_for_sparse_divide.md
+++ b/rfcs/APIs/20220329_api_design_for_sparse_divide.md
@@ -1,12 +1,12 @@
# paddle.sparse.divide 设计文档
-|API名称 | paddle.sparse.divide |
- |----------------------------------------------|-----------------------------------------------------------|
-|提交作者 | PeachML |
-|提交时间 | 2022-03-29 |
-|版本号 | V1.0 |
-|依赖飞桨版本 | develop |
-|文件名 | 20220329_api_design_for_sparse_divide.md
|
+| API名称 | paddle.sparse.divide |
+|----------------------------------------------------------|----------------------------------------------|
+| 提交作者 | PeachML |
+| 提交时间 | 2022-03-29 |
+| 版本号 | V1.0 |
+| 依赖飞桨版本 | develop |
+| 文件名 | 20220329_api_design_for_sparse_divide.md
|
# 一、概述
@@ -141,65 +141,98 @@ Scipy中有csr类型的稀疏矩阵,可以支持相除操作,通过`binary_o
# 四、对比分析
-torch设计结构复杂,为了适配paddle phi库的设计模式,故采用scipy的实现方式
+torch设计结构复杂,为了适配paddle phi库的设计模式,故参考scipy的实现方式
# 五、方案设计
## 命名与参数设计
-在paddle/phi/kernels/sparse/目录下,在paddle/phi/kernels/sparse/目录下, kernel设计为
+在paddle/phi/kernels/sparse/目录下, kernel设计为
```
-void DivideCsrKernel(const Context& dev_ctx,
- const SparseCsrTensor& x,
- const SparseCsrTensor& y,
- SparseCsrTensor* out);
+void ElementWiseDivideCsrCPUKernel(const Context& dev_ctx,
+ const SparseCsrTensor& x,
+ const SparseCsrTensor& y,
+ SparseCsrTensor* out)
```
```
-//暂定
-void DivideGradKernel(const Context& dev_ctx,
- const SparseCsrTensor& x,
- const SparseCsrTensor& y,
- const SparseCsrTensor& out,
- const SparseCsrTensor& dout,
- SparseCsrTensor* dx,
- SparseCsrTensor* dy);
+void ElementWiseDivideCooKernel(const Context& dev_ctx,
+ const SparseCooTensor& x,
+ const SparseCooTensor& y,
+ SparseCooTensor* out)
+```
+
+```
+template
+void ElementWiseDivideCsrGradKernel(const Context& dev_ctx,
+ const SparseCsrTensor& x,
+ const SparseCsrTensor& y,
+ const SparseCsrTensor& out,
+ const SparseCsrTensor& dout,
+ SparseCsrTensor* dx,
+ SparseCsrTensor* dy);
+```
+
+```
+void ElementWiseDivideCooGradKernel(const Context& dev_ctx,
+ const SparseCooTensor& x,
+ const SparseCooTensor& y,
+ const SparseCooTensor& out,
+ const SparseCooTensor& dout,
+ SparseCooTensor* dx,
+ SparseCooTensor* dy);
```
函数设计为
```
-SparseCooTensor Divide(const Context& dev_ctx,
- const SparseCooTensor& x,
- const SparseCooTensor& y);
+SparseCsrTensor ElementWiseDivideCsr(const Context& dev_ctx,
+ const SparseCsrTensor& x,
+ const SparseCsrTensor& y)
```
和
```
-SparseCsrTensor Divide(const Context& dev_ctx,
- const SparseCsrTensor& x,
- const SparseCsrTensor& y);
+SparseCooTensor ElementWiseDivideCoo(const Context& dev_ctx,
+ const SparseCooTensor& x,
+ const SparseCooTensor& y)
```
## 底层OP设计
-新增一个sparse elementwise 的功能模块(暂定),然后使用已有op组合实现, 主要涉及`SparseCooToCsrKernel`和`SparseCsrToCooKernel`。
+实现对应的 CPU Kernel,使用 Merge 两个有序数组的算法,然后使用已有op组合实现, 主要涉及`SparseCooToCsrKernel`和`SparseCsrToCooKernel`。
+
+对于dense tensor,值连续的存储在一块内存中,二元运算需要处理每一个元素,即`x[i][j] ∘ y[i][j]`,运算时间复杂度为 `O(numel(x))`,
+`numel(x)`为`x`中总素个数。
+
+而sparse tensor以索引和值的模式存储一个多数元素为零的tensor,二元运算只需要处理两个输入不全为0的位置,
+在sparse tensor构造时,索引按升序排序,可以采取merge有序数组的方式,若两输入索引相等,则计算`x[i][j] ∘ y[i][j]`,
+若不相等则说明该位置上的二元运算有一个元为0,
+`x`索引小时计算 `x[i][j] ∘ 0`,`y`索引小时计算 `0 ∘ y[i][j]`。
+对于除法而言,两个输入都为0的位置运算结果不为0,所以需要将`y`中索引未覆盖到的位置(原tensor中为0),在运算中通过指向一个零常量的方式填充为0,
+以参与除法运算。
+此时,时间复杂度为`O(numel(x))`,鉴于实际场景中动辄50% ~ 99%的稀疏性 [[1]][1] ,
+虽然时间复杂度与dense tensor一样,但是可以节省大量的存储空间。
## API实现方案
-主要参考scipy实现,将coo转换成csr再进行除法,然后转换回coo
+对于SparseCsrTensor,将csr格式转换成coo格式再进行运算,然后转换回csr格式输出。
+
+对于SparseCooTensor,直接进行运算。
# 六、测试和验收的考量
测试考虑的case如下:
- 数值正确性
+- 反向
+- 不同 `sparse_dim`
# 七、可行性分析及规划排期
-方案主要依赖paddle现有op组合而成
+方案主要依赖paddle现有op组合而成,并自行实现核心算法
# 八、影响面
@@ -211,4 +244,6 @@ SparseCsrTensor Divide(const Context& dev_ctx,
# 附件及参考资料
-无
\ No newline at end of file
+[[1]: 深度学习中的稀疏性][1]
+
+[1]: https://sinews.siam.org/Details-Page/the-future-of-deep-learning-will-be-sparse
diff --git a/rfcs/APIs/20220329_api_design_for_sparse_multiply.md b/rfcs/APIs/20220329_api_design_for_sparse_multiply.md
index edb54cea8..df5fb226c 100644
--- a/rfcs/APIs/20220329_api_design_for_sparse_multiply.md
+++ b/rfcs/APIs/20220329_api_design_for_sparse_multiply.md
@@ -1,12 +1,12 @@
# paddle.sparse.multiply 设计文档
-|API名称 | paddle.sparse.multiply |
- |----------------------------------------|-----------------------------------------------------------|
-|提交作者 | PeachML |
-|提交时间 | 2022-03-29 |
-|版本号 | V1.0 |
-|依赖飞桨版本 | develop |
-|文件名 | 20220329_api_design_for_sparse_multiply.md
|
+| API名称 | paddle.sparse.multiply |
+|----------------------------------------------------------|------------------------------------------------|
+| 提交作者 | PeachML |
+| 提交时间 | 2022-03-29 |
+| 版本号 | V1.0 |
+| 依赖飞桨版本 | develop |
+| 文件名 | 20220329_api_design_for_sparse_multiply.md
|
# 一、概述
@@ -141,7 +141,7 @@ Scipy中有csr类型的稀疏矩阵,可以支持相乘操作,通过`binary_o
# 四、对比分析
-torch设计结构复杂,为了适配paddle phi库的设计模式,故采用scipy的实现方式
+torch设计结构复杂,为了适配paddle phi库的设计模式,故参考scipy的实现方式
# 五、方案设计
@@ -150,55 +150,86 @@ torch设计结构复杂,为了适配paddle phi库的设计模式,故采用sc
在paddle/phi/kernels/sparse/目录下, kernel设计为
```
-void MultiplyCsrKernel(const Context& dev_ctx,
- const SparseCsrTensor& x,
- const SparseCsrTensor& y,
- SparseCsrTensor* out);
+void ElementWiseMultiplyCsrCPUKernel(const Context& dev_ctx,
+ const SparseCsrTensor& x,
+ const SparseCsrTensor& y,
+ SparseCsrTensor* out)
```
+
+```
+void ElementWiseMultiplyCooKernel(const Context& dev_ctx,
+ const SparseCooTensor& x,
+ const SparseCooTensor& y,
+ SparseCooTensor* out)
+```
+
+```
+template
+void ElementWiseMultiplyCsrGradKernel(const Context& dev_ctx,
+ const SparseCsrTensor& x,
+ const SparseCsrTensor& y,
+ const SparseCsrTensor& dout,
+ SparseCsrTensor* dx,
+ SparseCsrTensor* dy);
```
-//暂定
-void MultiplyCsrGradKernel(const Context& dev_ctx,
- const SparseCsrTensor& x,
- const SparseCsrTensor& y,
- const SparseCsrTensor& dout,
- SparseCsrTensor* dx,
- SparseCsrTensor* dy)
+
+```
+void ElementWiseMultiplyCooGradKernel(const Context& dev_ctx,
+ const SparseCooTensor& x,
+ const SparseCooTensor& y,
+ const SparseCooTensor& dout,
+ SparseCooTensor* dx,
+ SparseCooTensor* dy);
```
函数设计为
```
-SparseCooTensor Multiply(const Context& dev_ctx,
- const SparseCooTensor& x,
- const SparseCooTensor& y);
+SparseCsrTensor ElementWiseMultiplyCsr(const Context& dev_ctx,
+ const SparseCsrTensor& x,
+ const SparseCsrTensor& y)
```
和
```
-SparseCsrTensor Multiply(const Context& dev_ctx,
- const SparseCsrTensor& x,
- const SparseCsrTensor& y);
+SparseCooTensor ElementWiseMultiplyCoo(const Context& dev_ctx,
+ const SparseCooTensor& x,
+ const SparseCooTensor& y)
```
## 底层OP设计
-新增一个sparse elementwise 的功能模块(暂定),然后使用已有op组合实现, 主要涉及`SparseCooToCsrKernel`和`SparseCsrToCooKernel`。
+实现对应的 CPU Kernel,使用 Merge 两个有序数组的算法,然后使用已有op组合实现, 主要涉及`SparseCooToCsrKernel`和`SparseCsrToCooKernel`。
+
+对于dense tensor,值连续的存储在一块内存中,二元运算需要处理每一个元素,即`x[i][j] ∘ y[i][j]`,运算时间复杂度为 `O(numel(x))`,
+`numel(x)`为`x`中总素个数。
+
+而sparse tensor以索引和值的模式存储一个多数元素为零的tensor,二元运算只需要处理两个输入不全为0的位置,
+在sparse tensor构造时,索引按升序排序,可以采取merge有序数组的方式,若两输入索引相等,则计算`x[i][j] ∘ y[i][j]`,
+若不相等则说明该位置上的二元运算有一个元为0,
+`x`索引小时计算 `x[i][j] ∘ 0`,`y`索引小时计算 `0 ∘ y[i][j]`。
+计算过的位置存储在新的索引数组中,这样,索引没有覆盖到的位置依然为0,节省了计算开销,时间复杂度为`O(nnz(x) + nnz(y))`,
+`nnz(x)`为`x`中非零元素个数。
## API实现方案
-主要参考scipy实现,将coo转换成csr再进行乘法,然后转换回coo
+对于SparseCsrTensor,将csr格式转换成coo格式再进行运算,然后转换回csr格式输出。
+
+对于SparseCooTensor,直接进行运算。
# 六、测试和验收的考量
测试考虑的case如下:
- 数值正确性
+- 反向
+- 不同 `sparse_dim`
# 七、可行性分析及规划排期
-方案主要依赖paddle现有op组合而成
+方案主要依赖paddle现有op组合而成,并自行实现核心算法
# 八、影响面