optimize attr default value#33357
optimize attr default value#33357wanghuancoder merged 18 commits intoPaddlePaddle:developfrom wanghuancoder:attr2
Conversation
|
Thanks for your contribution! |
| } | ||
|
|
||
| OpBase::Run(*op, new_ins, outs, attrs, place); | ||
| OpBase::Run(*op, new_ins, outs, attrs, attr_checker->GetAttrDefaultMap(), |
There was a problem hiding this comment.
attr_checker 需要判断是不是存在null的情况
|
Sorry to inform you that d44aeb6's CIs have passed for more than 7 days. To prevent PR conflicts, you need to re-run all CIs manually. |
| if (it == attrs_.end()) { | ||
| if (attrs_default_ != nullptr) { | ||
| it = attrs_default_->find(name); | ||
| if (it == attrs_default_->end()) { |
There was a problem hiding this comment.
bool found = false;
if ( it == attrs_ends() )
{
if (attrs_default_ != nullptr) {
it = attrs_default_->find(name);
if (it == attrs_default_->end())
{
found = false;
}
}
PADDLE_ENFORE( found == true, "")
| platform::errors::InvalidArgument( | ||
| "Attribute (%s) is not set correctly.", attr_name_)); | ||
| // default_value_setter_ has no more than one element | ||
| attr_map->emplace(attr_name_, default_value_setter_[0]()); |
There was a problem hiding this comment.
auto res = attr_map->emplace(attr_name_, default_value_setter_0);
it = res.first;
emplace 之后会返回一个pair, 这个pair的第一个元素是新的iterator
| // default_value_setter_ has no more than one element | ||
| attr_map->emplace(attr_name_, default_value_setter_[0]()); | ||
| } | ||
| it = attr_map->find(attr_name_); |
| .SetDefault(""); | ||
| Validate(); | ||
|
|
||
| op_checker_->InitDefaultMap(); |
There was a problem hiding this comment.
这个Init可以放在68行后面,后面这些信息动态图都是不需要的
| void ClearGradVarBase() { grad_var_ = nullptr; } | ||
|
|
||
| void SetGradVarBase(VarBase& grad_var) { | ||
| void SetGradVarBase(VarBase& grad_var) { // NOLINT |
chenwhql
left a comment
There was a problem hiding this comment.
个人觉得,DefaultAttr相比AttrDefault更符合英语的修饰习惯
| explicit AttrReader(const AttributeMap& attrs) | ||
| : attrs_(attrs), attrs_default_(nullptr) {} | ||
|
|
||
| AttrReader(const AttributeMap& attrs, const AttributeMap& attrs_default) |
There was a problem hiding this comment.
命名有些奇怪,建议attrs_default -> default_attrs
| explicit_checker_num_ = attr_checkers_.size(); | ||
| } | ||
|
|
||
| void InitDefaultMap() { |
There was a problem hiding this comment.
InitDefaultMap意义不明,InitDefaultMap -> InitDefaultAttributeMap
|
|
||
| void InitDefaultMap() { | ||
| for (const auto& checker : attr_checkers_) { | ||
| checker(&attrs_default_, true, false); |
There was a problem hiding this comment.
attrs_default_ -> default_attrs_
| } | ||
| } | ||
|
|
||
| const AttributeMap& GetAttrDefaultMap() const { return attrs_default_; } |
There was a problem hiding this comment.
GetAttrDefaultMap -> GetDefaultAttrMap
| } | ||
|
|
||
| // Only for dygraph | ||
| void SetDygraphAttrsDefaultMap(const framework::AttributeMap& attrs_default) { |
There was a problem hiding this comment.
SetDygraphAttrsDefaultMap -> SetDygraphDefaultAttrsMap
| it = attrs_default_.find(name); | ||
| if (it == attrs_default_.end()) { | ||
| PADDLE_THROW( | ||
| platform::errors::NotFound("Can not find [%s] in attrs", name)); |
| void ClearGradVarBase() { grad_var_ = nullptr; } | ||
|
|
||
| void SetGradVarBase(VarBase& grad_var) { | ||
| void SetGradVarBase(VarBase& grad_var) { // NOLINT |
|
|
||
| private: | ||
| const AttributeMap& attrs_; | ||
| const AttributeMap* attrs_default_; |
There was a problem hiding this comment.
为什么不同样使用const &类型,这里有什么考虑吗
There was a problem hiding this comment.
引用必须在构造函数的时候初始化。考虑到动态图静态图都使用AttrReader他的构造函数有2种:
AttrReader(const AttributeMap& attrs)
: attrs_(attrs), default_attrs_(nullptr) {}
AttrReader(const AttributeMap& attrs, const AttributeMap& default_attrs)
: attrs_(attrs), default_attrs_(&default_attrs) {}
| auto* attr_checker = op_info.Checker(); | ||
| if (attr_checker) { | ||
| attr_checker->Check(&attrs, true); | ||
| attr_checker->Check(&attrs, true, true); |
There was a problem hiding this comment.
建议这里加上参数名注释,方便找到是这里调用的,attr_checker->Check(&attrs, true, /*without_default_value=*/true);
| void operator()(AttributeMap* attr_map, | ||
| bool get_default_value_only = false) const { | ||
| void operator()(AttributeMap* attr_map, bool get_default_value_only = false, | ||
| bool without_default_value = false) const { |
There was a problem hiding this comment.
without_default_value这个参数的命名理解起来比较困难,是不是改成only_check_exist_value之类的比较容易理解
There was a problem hiding this comment.
without_default_value 让人有点儿容易和get_default_value_only 的作用混淆....
| explicit AttrReader(const AttributeMap& attrs) | ||
| : attrs_(attrs), attrs_default_(nullptr) {} | ||
|
|
||
| AttrReader(const AttributeMap& attrs, const AttributeMap& attrs_default) |
| PADDLE_ENFORCE_NE(attrs_.count(name), 0, | ||
| auto it = attrs_.find(name); | ||
| bool found = it != attrs_.end(); | ||
| if (it == attrs_.end()) { |
There was a problem hiding this comment.
why not use found instead?
|
|
||
| private: | ||
| const AttributeMap& attrs_; | ||
| const AttributeMap* attrs_default_; |
| void operator()(AttributeMap* attr_map, | ||
| bool get_default_value_only = false) const { | ||
| void operator()(AttributeMap* attr_map, bool get_default_value_only = false, | ||
| bool without_default_value = false) const { |
There was a problem hiding this comment.
without_default_value 让人有点儿容易和get_default_value_only 的作用混淆....
| } | ||
| } | ||
|
|
||
| AttributeMap GetAttrsDefaultValuesMap() const { |
There was a problem hiding this comment.
GetDefaultAttrsValuesMap()?
| { | ||
| imperative::TracedGradOp traced_grad_op(node); | ||
| try { | ||
| traced_grad_op.SetAttrDefaultMap(this->DefaultAttrsMap()); |
| return op_->SetAttrMap(attrs); | ||
| } | ||
|
|
||
| void SetAttrDefaultMap(const framework::AttributeMap& attrs) { |
| DygraphInferShapeContext(const NameVarMap<VarType>* in, | ||
| const NameVarMap<VarType>* out, | ||
| const framework::AttributeMap* attr, | ||
| const framework::AttributeMap* attr_default, |
806564c
PR types
Performance optimization
PR changes
Others
Describe
1. 背景
每个OP有很多的Attribute,这些Attribute在OP Maker中设置默认值和Checker。在上层使用时,通常只传递少部分Attribute,而更多的,需要靠Checker补填默认值。这部分逻辑在
TypedAttrChecker中。而Attribute的存储方式是
using AttributeMap = std::unordered_map<std::string, Attribute>;,经测试发现,这种数据结构的补填、拷贝都非常慢。在动态图中,直接增加了框架的调度成本。2. 内容
本PR优化Attribute补填默认值带来的性能开销。
主要方法是: 不再向上层传入的AttrsMap中补填默认值。而是在注册前向OP时生成DefaultAttrMap,DefaultAttrMap用于存储OP的默认值。在传递AttrsMap时,伴随传递DefaultAttrMap,在查询Attr时,先从AttrsMap中查找,再从DefaultAttrMap中查找。对于GradOP和DoubleGradOP,其Attr为前向OP的Attr,因此在执行dygraph_grad_op_maker_时,不仅传入AttrsMap,也传入DefaultAttrMap,最终存储在OPBase中。
3. 性能测试
使用core.ops.elementwise_add测试,本PR对core.ops.elementwise_add有18.93%的性能提升。