Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add lod tensor interface design #3454

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 88 additions & 0 deletions paddle/framework/tensor_as_interface_design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# LODTensor 及周边设计
本设计尝试综合之前的讨论和目前实现的现状,提供一个简单但相对有扩展性的版本,其中有以下一些需要注意的点:

- 基本设计完全按照8-11(上周五)讨论的方案,只有如下变化
- 由于目前只有2种tensor,难以确保将来是否有其他类似 `LOD` 角色的Tensor,因此本设计不会将 `LODTensor` 直接作为 Interface,而是将最基础的Tensor概念作为Interface
- 目前实现的Tensor会更名为 `DenseTensor`
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

目前不需要把Tensor改成DenseTensor吧。我理解只需要约定所有需要用到Tensor的地方都用LODTensor即可?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

了解,那我把 Tensor 全局替换成 LODTensor 应该就可以了

- 目前的 LODTensor 会更名为 `LODDenseTensor`
- 为了实现简单,LODDenseTensor 会继承自DenseTensor,将来可以改成组合
- 更复杂的类型问题,将推迟到有了2个以上Tensor 类型的时候考虑

## Tensor 作为Interface
`Tensor interface` 直接对应其他平台的相同概念,但LODTensor无法; 稠密的为 DenseTensor,稀疏的为 SparseTensor。
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个提取interface的工作也是几个月之后才会需要做的吧?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

但暂时,LODTensor 只有在变长RNN的时候才开始用到,暂时只是定长RNN,这个阶段所有的Op都只需要Tensor。

这个替换是临时解决方案,是否hold到变长RNN的时候再全局替换(应该也在小demo,RNN定长demo两个阶段之后了)。

理解的是,如果是通用解决方案,可以现在合入,如果临时解决方案,就等到需要的时候合入?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

好。那就等需要边长RNN的时候再替换吧!



**为什么不用 LODTensor 作为 Interface?**

- 目前只有两个 Tensor,LODTensor
- 如果将LODTensor作为interface,难确保将来不会出现和`LOD`类似的语义
- 但 `Tensor` 作为基础概念作为 interface会更合理一些
- **两者带来的实现代价类似**

## LODDenseTensor

LODDenseTensor 会直接沿用目前的实现,即直接继承 `DenseTensor`,这里主要是为了更简单地实现 Tensor Interface规定的接口。

完整跑通之后,如果有必要可以增加代码改写为组合的实现。

## 现有代码迁移
### Tensor替换为 DenseTensor
现有所有类似以 `Tensor` 作为模板参数的操作,比如 `GetMutable<Tensor>` 全部替换为 `GetMutable<DenseTensor>`
### LODTensor 替换为 LODDenseTensor
### 在Variable中添加Clone接口

```c++
class Variable {
public:

// ...
template <typename T>
void Clone(const Variable& other) {
holder_.reset(new PlaceholderImpl<T>(other.Clone()));
}
// ...
};
```

### 所有的InferShape里在最开始添加var 的Clone,以实现类型传递

```c++
T* VarClone(const Variable& var){
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

如果现在只有LODTensor在实际使用,是不是也就不需要clone了?

return var.Get<Tensor>()->Clone();
}

void InferShape() {
// ...
// transfer LOD if input_var is a LODDenseTensor
// user should be aware that each output' tensor type is the same as input
output_var.Clone(input_var);
// ...
}
```

### 添加VarGetMutable函数支持Variable的继承关系

目前只有两种 tensor,因此直接裸写 if-else 实现

为了把 Tensor的实现与 Variable 解耦,另外增加一个函数

```c++
template <typename T>
bool IsInherienceOf(const Variable& child_type_var) {
// several if-else
if (xxxx) return true;
return false;
}

template <typename T>
T* VarGetMutable(Variable* var, bool enable_inherience = true) {
if (enable_inherience && IsInherienceOf<T>(var)) {
return var.Get<T>();
}
return var.GetMutable<T>();
}
```
## 未来扩展
两个维度,如果有新的tensor 类型,只需要如下两步支持
- 继承 `Tensor interface` 实现新类型tensor
- 在 `VarGetMutable` 中增加 if-else 支持新类型的继承关系