From cb2e410dac015a6c7ed3efc26996cb39dda9a7c0 Mon Sep 17 00:00:00 2001
From: tczrr1999 <2742392377@qq.com>
Date: Tue, 12 Jul 2022 12:02:55 +0800
Subject: [PATCH 1/6] add CINN squeeze rfc docs
---
.../APIs/20220711_api_design_for_squeeze.md | 83 +++++++++++++++++++
1 file changed, 83 insertions(+)
create mode 100644 rfcs/CINN/APIs/20220711_api_design_for_squeeze.md
diff --git a/rfcs/CINN/APIs/20220711_api_design_for_squeeze.md b/rfcs/CINN/APIs/20220711_api_design_for_squeeze.md
new file mode 100644
index 000000000..b906a323c
--- /dev/null
+++ b/rfcs/CINN/APIs/20220711_api_design_for_squeeze.md
@@ -0,0 +1,83 @@
+# CINN squeeze 设计文档
+
+|API名称 | 新增API名称 |
+|---|---|
+|提交作者 | 六个骨头 |
+|提交时间 | 2022-07-11 |
+|版本号 | V1.0 |
+|依赖CINN版本 | develop |
+|文件名 | 20220711_api_design_for_squeeze.md
|
+
+# 一、概述
+
+## 1、相关背景
+
+为了提升 CINN API 丰富度,需要扩充 API `squeeze`。
+
+## 2、名词解释
+
+无
+
+## 3、功能目标
+实现 squeeze 功能。
+
+## 4、意义
+
+为神经网络编译器 CINN 增加基础算子 squeeze 。
+
+# 二、CINN现状
+
+对CINN框架目前不支持此功能,可以使用 reshape API 替代,但使用 reshape API 需要明确的知道数据的尺寸,对开发者的精力消耗较大,因此有必要实现 squeeze API。
+
+# 三、业内方案调研
+
+- TVM:未实现该API,通常借用 numpy 等实现该功能。
+- XLA:通过调用reshape相关API实现。
+```cpp
+xla::XlaOp SqueezeAllTrivialDimensions(xla::XlaOp input) {
+ const xla::Shape& input_shape = XlaHelpers::ShapeOfXlaOp(input);
+ auto output_sizes =
+ BuildSqueezedDimensions(input_shape.dimensions(), /*squeeze_dim=*/-1);
+ return XlaHelpers::DynamicReshape(input, output_sizes);
+}
+```
+
+# 四、对比分析
+
+无
+
+# 五、设计思路与实现方案
+
+## 命名与参数设计
+- A:输入张量
+- name:输出名称
+
+## 底层OP设计
+1. 在 `cinn/hlir/pe/transform.cc` 里实现 `squeeze` 算子。
+2. 在 `cinn/hlir/op/transform.h` 里声明相应的 `strategy`。
+3. 在 `cinn/hlir/op/transform.cc` 里实现相应的 `strategy`。
+
+## API实现方案
+1. 在 `cinn/frontend/base_build.h` 里声明 `BaseBuilder::Squeeze`。
+2. 在 `cinn/frontend/base_build.cc` 里实现 `BaseBuilder::Squeeze`。
+3. 在 `cinn/pybind/frontend` 对 Python 类 `BaseBuilder` 添加 `squeeze` 接口,并绑定到 `BaseBuilder::Squeeze`。
+4. 上层 `net_builder` 调用提交到 `cinn/frontend/net_builder.h` 和 `.cc` 文件下。
+5. 上层 `load_paddle_model` 调用提交到 `cinn/frontend/paddle_model_to_program.h` 和 `.cc` 文件下。
+
+# 六、测试和验收的考量
+1. 提供基础的 demo 文件。
+2. 提交 API 使用方法到相应的文档中。
+
+# 七、可行性分析和排期规划
+
+- 可行性分析:非常可行
+- 排期规划:1-6已完成,7-9预计7月15日前完成
+
+# 八、影响面
+
+对其他模块无影响。
+
+# 附件及参考资料
+
+[CINN文档](https://paddlepaddle.github.io/CINN/)
+
From 2aec0e9edee4ccc4b2e6cd0f687282e32dd74404 Mon Sep 17 00:00:00 2001
From: tczrr1999 <2742392377@qq.com>
Date: Wed, 13 Jul 2022 19:46:04 +0800
Subject: [PATCH 2/6] update: modified part 7
---
.../APIs/20220711_api_design_for_squeeze.md | 34 +++++++++++--------
1 file changed, 19 insertions(+), 15 deletions(-)
diff --git a/rfcs/CINN/APIs/20220711_api_design_for_squeeze.md b/rfcs/CINN/APIs/20220711_api_design_for_squeeze.md
index b906a323c..149348a4d 100644
--- a/rfcs/CINN/APIs/20220711_api_design_for_squeeze.md
+++ b/rfcs/CINN/APIs/20220711_api_design_for_squeeze.md
@@ -1,12 +1,12 @@
# CINN squeeze 设计文档
-|API名称 | 新增API名称 |
-|---|---|
-|提交作者 | 六个骨头 |
-|提交时间 | 2022-07-11 |
-|版本号 | V1.0 |
-|依赖CINN版本 | develop |
-|文件名 | 20220711_api_design_for_squeeze.md
|
+| API名称 | 新增API名称 |
+| ---------------------------------------------------------- | -------------------------------------- |
+| 提交作者 | 六个骨头 |
+| 提交时间 | 2022-07-11 |
+| 版本号 | V1.0 |
+| 依赖CINN版本 | develop |
+| 文件名 | 20220711_api_design_for_squeeze.md
|
# 一、概述
@@ -19,6 +19,7 @@
无
## 3、功能目标
+
实现 squeeze 功能。
## 4、意义
@@ -33,14 +34,15 @@
- TVM:未实现该API,通常借用 numpy 等实现该功能。
- XLA:通过调用reshape相关API实现。
-```cpp
-xla::XlaOp SqueezeAllTrivialDimensions(xla::XlaOp input) {
+
+ ```cpp
+ xla::XlaOp SqueezeAllTrivialDimensions(xla::XlaOp input) {
const xla::Shape& input_shape = XlaHelpers::ShapeOfXlaOp(input);
auto output_sizes =
BuildSqueezedDimensions(input_shape.dimensions(), /*squeeze_dim=*/-1);
return XlaHelpers::DynamicReshape(input, output_sizes);
-}
-```
+ }
+ ```
# 四、对比分析
@@ -49,29 +51,32 @@ xla::XlaOp SqueezeAllTrivialDimensions(xla::XlaOp input) {
# 五、设计思路与实现方案
## 命名与参数设计
+
- A:输入张量
- name:输出名称
## 底层OP设计
+
1. 在 `cinn/hlir/pe/transform.cc` 里实现 `squeeze` 算子。
2. 在 `cinn/hlir/op/transform.h` 里声明相应的 `strategy`。
3. 在 `cinn/hlir/op/transform.cc` 里实现相应的 `strategy`。
## API实现方案
+
1. 在 `cinn/frontend/base_build.h` 里声明 `BaseBuilder::Squeeze`。
2. 在 `cinn/frontend/base_build.cc` 里实现 `BaseBuilder::Squeeze`。
3. 在 `cinn/pybind/frontend` 对 Python 类 `BaseBuilder` 添加 `squeeze` 接口,并绑定到 `BaseBuilder::Squeeze`。
-4. 上层 `net_builder` 调用提交到 `cinn/frontend/net_builder.h` 和 `.cc` 文件下。
-5. 上层 `load_paddle_model` 调用提交到 `cinn/frontend/paddle_model_to_program.h` 和 `.cc` 文件下。
+4. 上层 `load_paddle_model` 调用提交到 `cinn/frontend/paddle_model_to_program.h` 和 `.cc` 文件下。
# 六、测试和验收的考量
+
1. 提供基础的 demo 文件。
2. 提交 API 使用方法到相应的文档中。
# 七、可行性分析和排期规划
- 可行性分析:非常可行
-- 排期规划:1-6已完成,7-9预计7月15日前完成
+- 排期规划:底层OP设计已完成,API实现方案中1-3已完成,API实现方案中4预计7月15日前完成。
# 八、影响面
@@ -80,4 +85,3 @@ xla::XlaOp SqueezeAllTrivialDimensions(xla::XlaOp input) {
# 附件及参考资料
[CINN文档](https://paddlepaddle.github.io/CINN/)
-
From b57a82f7908ba42b1a0bc22b695c5b7cfe52d581 Mon Sep 17 00:00:00 2001
From: tczrr1999 <2742392377@qq.com>
Date: Thu, 14 Jul 2022 20:46:20 +0800
Subject: [PATCH 3/6] update: modified
---
.../APIs/20220711_api_design_for_squeeze.md | 90 +++++++++++++++++--
1 file changed, 81 insertions(+), 9 deletions(-)
diff --git a/rfcs/CINN/APIs/20220711_api_design_for_squeeze.md b/rfcs/CINN/APIs/20220711_api_design_for_squeeze.md
index 149348a4d..f233eeac7 100644
--- a/rfcs/CINN/APIs/20220711_api_design_for_squeeze.md
+++ b/rfcs/CINN/APIs/20220711_api_design_for_squeeze.md
@@ -12,19 +12,28 @@
## 1、相关背景
-为了提升 CINN API 丰富度,需要扩充 API `squeeze`。
+`squeeze` 是众多神经网络编译器中基础的算子,FQ,
+例如将卷积输出$(256, 1, 1)$输入线性层中时,可以直接使 `squeeze`将维度变为$(256)$,
+因此为了提升 CINN API 丰富度,需要扩充 API `squeeze`。
## 2、名词解释
-无
+张量/Tensor:指高维数组。
+squeeze:指删除尺寸为1的维度,可以是指定某个维度,也可以是所有维度。
+axis:指张量的维度。
## 3、功能目标
-实现 squeeze 功能。
+实现 squeeze 功能,删除张量指定尺寸为一的维度。
+
+例如,对于张量 $A = (N, 1, 1, M, 1, K)$,
+squeeze( $A$, axis = None) 结果尺寸为$(N, M, K)$,
+squeeze( $A$, axis = 1) 结果尺寸为$(N, 1, M, 1, K)$,
+squeeze( $A$, axis = [1, 2]) 结果尺寸为$(N, M, 1, K)$,且数据值不变。
## 4、意义
-为神经网络编译器 CINN 增加基础算子 squeeze 。
+为神经网络编译器 CINN 增加基础算子 `squeeze`。
# 二、CINN现状
@@ -32,8 +41,63 @@
# 三、业内方案调研
-- TVM:未实现该API,通常借用 numpy 等实现该功能。
-- XLA:通过调用reshape相关API实现。
+- TVM:通过遍历 shape,删除为1的维度并调用 reshape 相关 API 实现。
+ ```cpp
+ inline Tensor squeeze(const Tensor& x, Array axis, bool atleast1d = false,
+ std::string name = "T_squeeze", std::string tag = kInjective) {
+ auto ndim = x->shape.size();
+ std::vector axis_val;
+ if (!axis.defined() || axis.size() == 0) {
+ for (size_t i = 0; i < ndim; ++i) {
+ if (IsConstInt(x->shape[i]) && GetConstInt(x->shape[i]) == 1) {
+ axis_val.push_back(static_cast(i));
+ }
+ }
+ } else {
+ for (size_t i = 0; i < axis.size(); ++i) {
+ int64_t val = axis[i]->value;
+ if (val < 0) {
+ val += static_cast(x->shape.size());
+ }
+ if (IsConstInt(x->shape[val])) {
+ ICHECK_EQ(GetConstInt(x->shape[val]), 1) << "Dimension " << val << " must have size 1";
+ }
+ axis_val.push_back(val);
+ }
+ }
+
+ std::unordered_set axis_set(axis_val.begin(), axis_val.end());
+
+ Array out_shape;
+ for (size_t i = 0; i < ndim; ++i) {
+ if (axis_set.count(static_cast(i)) == 0) {
+ out_shape.push_back(x->shape[i]);
+ }
+ }
+ if (out_shape.size() == 0 && atleast1d) {
+ out_shape.push_back(1);
+ }
+
+ return compute(
+ out_shape,
+ [&](const Array& indices) {
+ Array real_indices;
+ int flag = 0;
+ for (size_t i = 0; i < ndim; ++i) {
+ if (axis_set.count(static_cast(i)) == 0) {
+ real_indices.push_back(indices[i - flag]);
+ } else {
+ real_indices.push_back(0);
+ flag += 1;
+ }
+ }
+ return x(real_indices);
+ },
+ name, tag);
+ }
+ ```
+
+- XLA:通过遍历 shape,删除为1的维度并调用 reshape 相关 API 实现。
```cpp
xla::XlaOp SqueezeAllTrivialDimensions(xla::XlaOp input) {
@@ -46,13 +110,14 @@
# 四、对比分析
-无
+TVM 与 XLA 实现方案类似。
# 五、设计思路与实现方案
## 命名与参数设计
- A:输入张量
+- axis:要删除的维度集合
- name:输出名称
## 底层OP设计
@@ -63,6 +128,11 @@
## API实现方案
+实现目标为对于张量 $A = (N, 1, 1, M, 1, K)$,
+squeeze( $A$, axis = 1) 结果尺寸为$(N, 1, M, 1, K)$,
+squeeze( $A$, axis = [1, 2]) 结果尺寸为$(N, M, 1, K)$,
+squeeze( $A$, axis = None) 结果尺寸为$(N, M, K)$,且数据值不变。
+
1. 在 `cinn/frontend/base_build.h` 里声明 `BaseBuilder::Squeeze`。
2. 在 `cinn/frontend/base_build.cc` 里实现 `BaseBuilder::Squeeze`。
3. 在 `cinn/pybind/frontend` 对 Python 类 `BaseBuilder` 添加 `squeeze` 接口,并绑定到 `BaseBuilder::Squeeze`。
@@ -71,12 +141,14 @@
# 六、测试和验收的考量
1. 提供基础的 demo 文件。
-2. 提交 API 使用方法到相应的文档中。
+2. 在`cinn/hlir/pe/pe_transform_test.cc`和`cinn/hlir/op/transform_test.cc`中添加对底层OP进行测试的代码。
+3. 在`python/tests`文件夹中添加对Python API进行测试的代码。
+4. 提交 API 使用方法到相应的文档中。
# 七、可行性分析和排期规划
- 可行性分析:非常可行
-- 排期规划:底层OP设计已完成,API实现方案中1-3已完成,API实现方案中4预计7月15日前完成。
+- 排期规划:底层OP设计已完成,API实现方案即将完成,测试和文档部分预计7月20日前完成。
# 八、影响面
From 91f5fd048359bbccbec8683d3119a1ef5236bd50 Mon Sep 17 00:00:00 2001
From: tczrr1999 <2742392377@qq.com>
Date: Thu, 14 Jul 2022 20:53:29 +0800
Subject: [PATCH 4/6] update: modified part 5
---
rfcs/CINN/APIs/20220711_api_design_for_squeeze.md | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/rfcs/CINN/APIs/20220711_api_design_for_squeeze.md b/rfcs/CINN/APIs/20220711_api_design_for_squeeze.md
index f233eeac7..8dc91a749 100644
--- a/rfcs/CINN/APIs/20220711_api_design_for_squeeze.md
+++ b/rfcs/CINN/APIs/20220711_api_design_for_squeeze.md
@@ -138,6 +138,16 @@ squeeze( $A$, axis = None) 结果尺寸为$(N, M, K)$,且数据值不变。
3. 在 `cinn/pybind/frontend` 对 Python 类 `BaseBuilder` 添加 `squeeze` 接口,并绑定到 `BaseBuilder::Squeeze`。
4. 上层 `load_paddle_model` 调用提交到 `cinn/frontend/paddle_model_to_program.h` 和 `.cc` 文件下。
+通过使用 Builder 类的方法调用 squeeze。
+```python
+builder = CinnBuilder("test_basic")
+a = builder.create_input(Float(32), (1, 24, 16, 1, 16, 16), "A") # shape=(1, 24, 16, 1, 16, 16)
+a = builder.squeeze(a) # 与 a = builder.squeeze(a,axis=None) 等价。shape=(24, 16, 16, 16)
+a = builder.squeeze(a,axis=0) # shape=(24, 16, 1, 16, 16)
+a = builder.squeeze(a,axis=3) # shape=(1, 24, 16, 16, 16)
+a = builder.squeeze(a,axis=4) # raise error
+```
+
# 六、测试和验收的考量
1. 提供基础的 demo 文件。
From 1145b99c43f26d63cc91f1e0ad6e86c1145db4fb Mon Sep 17 00:00:00 2001
From: tczrr1999 <2742392377@qq.com>
Date: Thu, 14 Jul 2022 21:28:02 +0800
Subject: [PATCH 5/6] update: modified part 7
---
rfcs/CINN/APIs/20220711_api_design_for_squeeze.md | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/rfcs/CINN/APIs/20220711_api_design_for_squeeze.md b/rfcs/CINN/APIs/20220711_api_design_for_squeeze.md
index 8dc91a749..f84e52c26 100644
--- a/rfcs/CINN/APIs/20220711_api_design_for_squeeze.md
+++ b/rfcs/CINN/APIs/20220711_api_design_for_squeeze.md
@@ -141,11 +141,14 @@ squeeze( $A$, axis = None) 结果尺寸为$(N, M, K)$,且数据值不变。
通过使用 Builder 类的方法调用 squeeze。
```python
builder = CinnBuilder("test_basic")
-a = builder.create_input(Float(32), (1, 24, 16, 1, 16, 16), "A") # shape=(1, 24, 16, 1, 16, 16)
-a = builder.squeeze(a) # 与 a = builder.squeeze(a,axis=None) 等价。shape=(24, 16, 16, 16)
-a = builder.squeeze(a,axis=0) # shape=(24, 16, 1, 16, 16)
-a = builder.squeeze(a,axis=3) # shape=(1, 24, 16, 16, 16)
-a = builder.squeeze(a,axis=4) # raise error
+a = builder.create_input(Float(32), (1, 24, 16, 1, 16, 16), "A1")
+b = builder.squeeze(a) # 与 a = builder.squeeze(a,axis=None) 等价。shape=(24, 16, 16, 16)
+a = builder.create_input(Float(32), (1, 24, 16, 1, 16, 16), "A2")
+b = builder.squeeze(a,axis=0) # shape=(24, 16, 1, 16, 16)
+a = builder.create_input(Float(32), (1, 24, 16, 1, 16, 16), "A3")
+b = builder.squeeze(a,axis=3) # shape=(1, 24, 16, 16, 16)
+a = builder.create_input(Float(32), (1, 24, 16, 1, 16, 16), "A4")
+b = builder.squeeze(a,axis=4) # raise error
```
# 六、测试和验收的考量
From dad8e4f01ed32adfdb629e4c5d472e449028105c Mon Sep 17 00:00:00 2001
From: tczrr1999 <2742392377@qq.com>
Date: Fri, 22 Jul 2022 11:46:13 +0800
Subject: [PATCH 6/6] update: modified
---
rfcs/CINN/APIs/20220711_api_design_for_squeeze.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/rfcs/CINN/APIs/20220711_api_design_for_squeeze.md b/rfcs/CINN/APIs/20220711_api_design_for_squeeze.md
index f84e52c26..da9c5e23c 100644
--- a/rfcs/CINN/APIs/20220711_api_design_for_squeeze.md
+++ b/rfcs/CINN/APIs/20220711_api_design_for_squeeze.md
@@ -12,7 +12,7 @@
## 1、相关背景
-`squeeze` 是众多神经网络编译器中基础的算子,FQ,
+`squeeze` 是众多神经网络编译器中基础的算子,
例如将卷积输出$(256, 1, 1)$输入线性层中时,可以直接使 `squeeze`将维度变为$(256)$,
因此为了提升 CINN API 丰富度,需要扩充 API `squeeze`。