YdrMaster
c077a61681
Signed-off-by: YdrMaster <ydrml@hotmail.com> |
||
---|---|---|
.. | ||
include/optimization | ||
src | ||
src0 | ||
test | ||
CMakeLists.txt | ||
Makefile | ||
README.md |
README.md
设计概述
- 宗旨:简化 尽量简化定义。凡是当前用不到的就去掉,以保证开发同时保持敏捷和可靠。
- 目标:中层接口 因为不是面向用户开发,不需要考虑接口易用性,也不需要过度考虑防御式编程。调用这些 api 的将会是第一方编写的上层代码。
- 文档 覆盖率应逼近 100%。
代码解析
重要的文件是 tensor.h、graph.h 和 mutation.h。
tensor.h 提供了这个图表示中张量的定义。张量的结构由形状、数据类型和数据组成,并储存了在每个图上和算子的连接关系。张量的所有权由所有连接到张量的算子共享,因此其存在的唯一形式就是 std::shared_ptr
,脱离共享所有权智能指针是没有意义的。通过向工厂函数直接传递形状、数据类型和数据,直接构造智能指针的张量,一旦所有连接到张量的算子释放,算子也被释放。
算子定义和其他重要类型定义在 graph.h。算子中存储且仅存储一个算子类型,其他所有信息都由其持有所有权的输入张量表示。算子类型指示了算子如何解释自己的每个输入输出张量。这样做为算子提供了充分的灵活性,同时也不损失表达能力——那些决定算子如何工作的重要信息必定已经保存在张量的数据中了,而算子类型会解释它们是谁。
算子的所有权属于一张图,确切地说,一张未分的或不可再分的单体图,Unigraph
。每个算子由唯一的图控制,多个图之间不共享算子的任何部分。由于算子的定义非常轻(1 枚举 + 2 智能指针的数组),这样做不会带来大的开销,但减轻了所有权的管理难度——有且只有张量一种对象,会在算子这一种对象之间共享,其他所有东西的所有权都是独占的。
同时,Unigraph
具有只增性。只能向其中增加算子,必须以拓扑序,不能移除,也不能修改算子的顺序。因此,算子在图中的序号是唯一的,每个图则持有一个唯一的 ID。因此,可以用 ID 来指示图,用序号指示算子(OpRef
);用序号指示算子,再用序号指示张量(TensorPos
)。图必须整体销毁,销毁时,其中所有算子控制的所有张量连接也会同时销毁。因此,不必维持不可独立存在的所有权关系。
mutation.h 的 Partition
、Mutation
和 Rating
三个类用于支持图的规则优化。这三个类本质是一样的,这种定义是为了对优化的不同阶段实现编译时的约束——一轮优化必须按划分→突变→评价的顺序依次执行每个操作一次。
这些类中保存的是一个 Mutant
的二维数组。每个 Mutant
是子图的一种突变体,存储了子图结构和评分。内层数组表示每个子图的多个变体,外层数组表示每张图的多个子图。显然,Partition
输入完整的图,并构建外层数组的结构,Mutation
将填充内层数组。Rating
填充每个突变体的得分,然后从高到低排序。接下来可以用序号向量指导图的重建。