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`。