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

[PASS]LoopPartition #56

Merged
merged 13 commits into from
Mar 4, 2017
Merged

[PASS]LoopPartition #56

merged 13 commits into from
Mar 4, 2017

Conversation

ZihengJiang
Copy link
Contributor

@ZihengJiang ZihengJiang commented Feb 27, 2017

No description provided.

bounds = tvm.schedule.InferBound(s)
stmt = tvm.schedule.ScheduleOps(s, bounds)
stmt = tvm.ir_pass.LoopPartition(stmt)
print(stmt)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

any suggestion to add assert statement and construction strong test case?

Copy link
Member

Choose a reason for hiding this comment

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

we can assert the result AST
something like

str(stmt.condition) == xyz

Copy link
Member

Choose a reason for hiding this comment

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

Let us also add end to end test cases, to test elementwise add and gemm, to make sure the result program looks correct

@@ -137,6 +137,8 @@ Stmt InjectVirtualThread(Stmt stmt);
*/
Stmt LiftAllocate(Stmt stmt);

Stmt LoopPartition(Stmt stmt);
Copy link
Member

Choose a reason for hiding this comment

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

always document functions in header

bounds = tvm.schedule.InferBound(s)
stmt = tvm.schedule.ScheduleOps(s, bounds)
stmt = tvm.ir_pass.LoopPartition(stmt)
print(stmt)
Copy link
Member

Choose a reason for hiding this comment

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

we can assert the result AST
something like

str(stmt.condition) == xyz

bounds = tvm.schedule.InferBound(s)
stmt = tvm.schedule.ScheduleOps(s, bounds)
stmt = tvm.ir_pass.LoopPartition(stmt)
print(stmt)
Copy link
Member

Choose a reason for hiding this comment

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

Let us also add end to end test cases, to test elementwise add and gemm, to make sure the result program looks correct

public:
explicit LoopPartitioner() {}
Expr Mutate(Expr e) override {
return IRMutator::Mutate(e);
Copy link
Member

Choose a reason for hiding this comment

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

no need to override if there is no change


void Visit_(const For* op) {
for (auto kv : out_vars_) {
if (ExprUseVar(op->min, kv.first) ||
Copy link
Member

Choose a reason for hiding this comment

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

consider make ExprUseVar take the map, so it is one pass cost

using IRMutator::Mutate;

private:
const std::vector<Partition>& ps_;
Copy link
Member

Choose a reason for hiding this comment

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

map of Node*->Partition

Copy link
Member

Choose a reason for hiding this comment

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

avoids the linear search per expression

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Do you want to remove struct Partition, use std::unordered_map<const Node*, Interval> directly?

Copy link
Member

Choose a reason for hiding this comment

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

I think Partition is good, if things might change in future

return res;
}

PartitionFinder finder(op->loop_var, vars_);
Copy link
Member

Choose a reason for hiding this comment

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

move the subsequent logic to a separate function DoPartition

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Or std::vector<Partition> FindPartitions(Expr target, std::unorder_map<const Variable*, IntSet>)? here do the real partition in fact

Copy link
Member

Choose a reason for hiding this comment

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

I think this is fine. The only thing is there is a check on whether you want to do partition or not, and we skipped the constant loops. So Have a function name can indicate here we really start to do partition

Stmt s = simplified_stmt;

if (!can_prove(true_itrv.min() == universe.min())) {
Expr pre_doubt_cond = (true_itrv.min() != universe.min());
Copy link
Member

Choose a reason for hiding this comment

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

we don;t need to check this cond, since they are implicit in for loop and will be checked

* \return the set after intersected
*/
IntSet Intersect(const Array<IntSet>& sets);
IntSet Intersect(const std::vector<IntSet>& sets);
Copy link
Member

Choose a reason for hiding this comment

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

I think we can simply construct Array in outside and pass it in. Should be same as vector

@@ -16,17 +16,17 @@ def test_deduce():
d_s = tvm.arith.intset_interval(-3, -1)

e0 = (-b)*a+c-d
res0 = tvm.arith.DeduceBound(a, e0>=0, {b: b_s, c: c_s, d: d_s})
res0 = tvm.arith.DeduceBound(a, e0>=0, {b: b_s, c: c_s, d: d_s}, {})
Copy link
Member

Choose a reason for hiding this comment

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

Add a testcase where relax set is presented?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

added

tvm.make.IfThenElse(
(i*m+j+k < n), tvm.make.Evaluate(m), tvm.make.Evaluate(n)))))
stmt = tvm.ir_pass.LoopPartition(stmt)
# assert(stmt.body.first.body.body.condition.value == 1)
Copy link
Member

Choose a reason for hiding this comment

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

add assert is good

bool success = false;
PostOrderVisit(expr, [&vars, &success](const NodeRef& node) {
for (const Variable* v : vars) {
if (node.get() == v) {
Copy link
Member

Choose a reason for hiding this comment

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

use unordered_set<Variable*>

Copy link
Member

Choose a reason for hiding this comment

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

always think about time complexity, try use O(1) data structure when we can if it does not have to be O(n) cost

Copy link
Contributor Author

Choose a reason for hiding this comment

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

quite correct, I always not notice this

return success;
}

inline bool IsConstDomain(Expr min, Expr extent) {
Copy link
Member

Choose a reason for hiding this comment

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

I think we can simply fold it in, since the expression is so simple and fit into oneline

};

std::unordered_map<const Node*, Partition>
FindPartitions(VarExpr target, Stmt body, std::unordered_map<const Variable*, IntSet> vars) {
Copy link
Member

Choose a reason for hiding this comment

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

Sorry I am being not clear here. I do not mean FindPartition should be a function, instead the insertPartition logic should be a single function

Copy link
Member

Choose a reason for hiding this comment

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

So the logic is check if there can be partition, call insertPartition

return res;
}

Stmt s = DoPartition(op, stmt);
Copy link
Member

Choose a reason for hiding this comment

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

merge the logic

if (!is_const(op->min) || is_const(op->extent)) {
s = DoPartition()
if (s.defined()) return s;
}
the default logic

private:
Stmt DoPartition(const For* op, const Stmt& stmt);

std::unordered_map<const Variable*, IntSet> vars_;
Copy link
Member

Choose a reason for hiding this comment

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

dom_map_

public:
explicit PartitionFinder(VarExpr loop_var,
const std::unordered_map<const Variable*, IntSet>& vars)
: target_var_(loop_var), out_vars_(vars.size()), hint_map_(vars), relax_map_() {
Copy link
Member

Choose a reason for hiding this comment

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

no need to put relax map in the initializer

explicit PartitionFinder(VarExpr loop_var,
const std::unordered_map<const Variable*, IntSet>& vars)
: target_var_(loop_var), out_vars_(vars.size()), hint_map_(vars), relax_map_() {
for (auto kv : vars) out_vars_.insert(kv.first);
Copy link
Member

Choose a reason for hiding this comment

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

const auto& kv :

@@ -0,0 +1,203 @@
/*!
* Copyright (c) 2016 by Contributors
Copy link
Member

Choose a reason for hiding this comment

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

2017

@tqchen tqchen merged commit c8ebfbe into apache:master Mar 4, 2017
@tqchen tqchen mentioned this pull request Mar 7, 2017
2 tasks
@ZihengJiang ZihengJiang deleted the dev-clean branch April 19, 2017 20:43
tqchen pushed a commit to tqchen/tvm that referenced this pull request May 26, 2018
tqchen pushed a commit that referenced this pull request May 29, 2018
tqchen pushed a commit to tqchen/tvm that referenced this pull request Jul 6, 2018
tqchen added a commit to tqchen/tvm that referenced this pull request Jul 12, 2018
tqchen added a commit that referenced this pull request Jul 12, 2018
tqchen added a commit to tqchen/tvm that referenced this pull request Aug 4, 2018
sergei-mironov pushed a commit to sergei-mironov/tvm that referenced this pull request Aug 8, 2018
sergei-mironov pushed a commit to sergei-mironov/tvm that referenced this pull request Aug 8, 2018
tqchen added a commit to tqchen/tvm that referenced this pull request Mar 29, 2020
cyx-6 pushed a commit to cyx-6/tvm that referenced this pull request Jun 28, 2022
junrushao added a commit to cyx-6/tvm that referenced this pull request Jul 4, 2022
cyx-6 pushed a commit to cyx-6/tvm that referenced this pull request Jul 13, 2022
Hzfengsy pushed a commit to Hzfengsy/tvm that referenced this pull request Jul 30, 2022
yzh119 added a commit to yzh119/tvm that referenced this pull request Nov 22, 2022
vinx13 pushed a commit to vinx13/tvm that referenced this pull request Mar 27, 2023
A few new fixes have gone into tvm/unity that would be useful for us to
grab.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants