-
Notifications
You must be signed in to change notification settings - Fork 3.7k
[SCHEDULE] add 'void AutoFuseEwise(Schedule sch)' #36
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
Changes from 3 commits
d15bbf6
83f5c4f
f66b3c9
d137400
8d6166c
fbf9ff0
d547e52
ae4de6f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -33,6 +33,13 @@ Map<IterVar, Range> InferBound(Schedule sch); | |
| */ | ||
| Stmt ScheduleOps(Schedule s, Map<IterVar, Range> dom_map); | ||
|
|
||
| /*! | ||
| * \brief To automatically fuse the element-wise operations. | ||
| * | ||
| * \param s The schedule to be fused. | ||
| */ | ||
| void AutoFuseElemWise(Schedule sch); | ||
|
||
|
|
||
| } // namespace schedule | ||
| } // namespace tvm | ||
| #endif // TVM_SCHEDULE_PASS_H_ | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| /*! | ||
| * Copyright (c) 2016 by Contributors | ||
| * \file elem_wise_detector.cc | ||
| */ | ||
| #include <tvm/ir.h> | ||
| #include <tvm/ir_visitor.h> | ||
| #include <tvm/operation.h> | ||
|
|
||
| namespace tvm { | ||
| namespace ir { | ||
|
|
||
| class ElemWiseDetector : public IRVisitor { | ||
| public: | ||
| explicit ElemWiseDetector(Array<IterVar> axis) : axis_(axis) {} | ||
|
|
||
| void Visit(const NodeRef& e) final { | ||
| if (!is_elem_wise_) | ||
| return; | ||
| IRVisitor::Visit(e); | ||
| } | ||
|
|
||
| void Visit_(const Call* op) final { | ||
| Array<Expr> axis = op->args; | ||
| if (axis_.size() != axis.size()) { | ||
| is_elem_wise_ = false; | ||
| return; | ||
| } | ||
|
|
||
| for (size_t i = 0; i < axis_.size(); ++i) { | ||
| const Variable *v1 = axis_[i]->var.as<Variable>(); | ||
| const Variable *v2 = axis[i].as<Variable>(); | ||
| if (!(v1 && v2) || (v1 != v2)) { | ||
| is_elem_wise_ = false; | ||
| return; | ||
| } | ||
| } | ||
| IRVisitor::Visit_(op); | ||
| } | ||
|
|
||
| bool is_elem_wise_{true}; | ||
|
|
||
| private: | ||
| Array<IterVar> axis_; | ||
| }; | ||
|
|
||
|
|
||
| bool IsElemWise(const NodeRef& node) { | ||
| if (const ComputeOpNode* compute = node.as<ComputeOpNode>()) { | ||
| ElemWiseDetector v = ElemWiseDetector(compute->axis); | ||
| v.Visit(compute->body); | ||
| return v.is_elem_wise_; | ||
| } | ||
| return false; | ||
| } | ||
|
|
||
| } // namespace ir | ||
| } // namespace tvm |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| /*! | ||
| * Copyright (c) 2016 by Contributors | ||
| * \file schedule.cc | ||
| */ | ||
| #include <tvm/schedule_pass.h> | ||
| #include <tvm/ir_pass.h> | ||
|
||
|
|
||
| namespace tvm { | ||
| namespace schedule { | ||
|
|
||
| namespace { | ||
| inline bool is_stage_scheduled(const Stage& s) { | ||
|
||
| return !(s->relations.empty() && s->attach_type == kNone); | ||
| } | ||
| } | ||
|
|
||
| void AutoFuseElemWise(Schedule sch) { | ||
| for (Stage s : sch->stages) { | ||
| if (!is_stage_scheduled(s) && ir::IsElemWise(s->op)) { | ||
| bool is_root = false; | ||
| for (auto r : sch->roots) { | ||
| if (r == s->op) { | ||
| is_root = true; | ||
| break; | ||
| } | ||
| } | ||
| if (!is_root) | ||
| s.compute_inline(); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| } // namespace schedule | ||
| } // namespace tvm | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do not pass in NodeRef, which can be anything. Consider pass in Stmt and Array.