Skip to content

[NewIR] 动静Op定义的参数名映射修复 #55334

Closed
@kangguangli

Description

需求描述 Feature Description

注:关于飞桨各个 Yaml 文件作用,详见代码自动生成技术

需求背景

目前飞桨的算子已十分丰富,能够满足众多用户需求,但另一方面,繁多的算子给框架的维护和开发带来了困难。飞桨目前分别支持动态图和静态图执行,因为历史原因,动态图的算子和静态图算子的定义并不完全一致。

而在飞桨新一代IR的开发过程中,我们基于动态图的更规范的算子定义(ops.yaml、legacy_ops.yaml)生成了新IR体系下的算子。但是出于兼容旧IR体系的考虑,我们开发了ProgramTranslator(相关代码位于 paddle/fluid/ir_adaptor/translator/),用于将定义在旧IR下的计算图转化为新IR表示。在这种情况下,我们就遇到了动静算子定义不一致的问题。

举例来说,对于算子atan2而言,它的静态图定义是

class Atan2OpMaker : public framework::OpProtoAndCheckerMaker {
 public:
  void Make() override {
    AddInput("X1", "(Tensor), input 0 of atan2 op.");
    AddInput("X2", "(Tensor), input 1 of atan2 op.");
    AddOutput("Out", "(Tensor), output 0 of atan2 op.");
  }
};

可以看到,有两个名叫X1 X2的输入,一个名叫Out的输出。

但是其动态图定义如下:

- op : atan2
  args : (Tensor x, Tensor y)
  output : Tensor

输入输出分别是x y out。进而新IR在生成Op定义时,生成的定义如下:

class Atan2Op : public ir::Op<Atan2Op,OpYamlInfoInterface,InferMetaInterface> {
 public:
  using Op::Op;
  
  void Verify();
  ir::Value x() { return operand(0); }
  ir::Value y() { return operand(1); }
  ir::OpResult out() { return result(0); }

};

OpInfoTuple Atan2Op::GetOpInfo() {
  std::vector<paddle::dialect::OpInputInfo> inputs = { OpInputInfo("x", "paddle::dialect::DenseTensorType", false, false, false), OpInputInfo("y", "paddle::dialect::DenseTensorType", false, false, false) };
  std::vector<paddle::dialect::OpAttributeInfo> attributes = {  };
  std::vector<paddle::dialect::OpOutputInfo> outputs = { OpOutputInfo("out", "paddle::dialect::DenseTensorType", false, false) };
  paddle::dialect::OpRunTimeInfo run_time_info = OpRunTimeInfo("Atan2InferMeta", {"x", "y"}, {"atan2"}, {"x", "y"}, {""}, {}, {});

  return std::make_tuple(inputs, attributes, outputs, run_time_info);
}

这种差异在ProgramTranslator工作时会带来一些问题,因为ProgramTranslator需要确定,应该将旧IR的哪个参数对应到新IR的哪个参数?一般来说,这种映射定义在 paddle/phi/api/yaml/op_compat.yaml中,然而,该文件并未包含所有的映射,有少量的映射并未补充到里面。

ProgramTranslator中目前采用这样的参数转换逻辑,该逻辑会将下划线风格命名的参数默认转为驼峰风格(即静态图参数命名风格),进而导致新定义的算子(采用了下划线命名风格)找不到映射,进而在paddle/phi/api/yaml/op_compat.yaml,不得不添加下面这样冗余的映射。

- op : warprnnt
  inputs :
    {input : input, label : label,  input_lengths : input_lengths, label_lengths : label_lengths}
  outputs :
    {loss : loss, warprnntgrad : warprnntgrad}

本项目的最终目的就是添加必要的参数映射, 去除上面的冗余映射。

攻略方式 (整体进展:18/18)

按 merge 的时间顺序,排名不分先后: @GreatV (3) @RedContritio (4) @kangguangli (1) @heavyrain-lzy (1) @Asthestarsfalll (3) @ccsuzzh (1) @gouzil (2) @Liyulingyue (1) @zrr1999 (1)

补全以下Op参数在paddle/phi/api/yaml/op_compat.yaml的映射:

序号 算子 PR 贡献者
1 feed✅(2023/7/14) #55402 @kangguangli
2 increment✅(2023/7/15) #55404 @RedContritio
3 elementwise_add✅(2023/7/14) #55403 @RedContritio
4 transpose✅(2023/7/17) #55458 @RedContritio
5 cast✅(2023/7/18) #55467 @gouzil
6 repeat_interleave✅(2023/7/18) #55467 @gouzil
7 logsumexp✅(2023/7/14) #55406 @RedContritio
8 mish✅(2023/7/17) #55422 @Asthestarsfalll
9 norm✅(2023/6/28) #54943 @heavyrain-lzy
10 slice✅(2023/7/17) #55432 @ccsuzzh
11 split✅(2023/7/14) #55417 @GreatV
12 sync_batch_norm✅(2023/7/14) #55417 @GreatV
13 fetch✅(2023/7/17) #55422 @Asthestarsfalll
14 assert✅(2023/7/21) #55500 @zrr1999
15 print✅(2023/7/14) #55417 @GreatV
16 fill_constant✅(2023/7/19) #55517 @Liyulingyue

修复代码逻辑

注意,由于种种原因,即便补全了上述单测,可能依然有部分Op的映射没有加入,这时候只要确定失败的单测是哪个,对于OpTest相关单测,可以确认是否在paddle/phi/api/yaml/op_compat.yaml加入了对应Op的映射。

对于更复杂的问题,可以咨询 @kangguangli

去除现存冗余映射

  • 去除paddle/phi/api/yaml/op_compat.yaml中类似warprnnt的映射逻辑

一个可能的方案是 通过脚本检测所有的映射列表,如果某个映射的key和value完全一致,就应当去除。

奖励

一颗【夏玻利利葡萄】

替代实现 Alternatives

No response

Metadata

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions