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

[Relay] Partial Eval now Support Interprocedural optimization and has termination check. #3033

Merged
merged 1 commit into from
Jun 15, 2019

Conversation

MarisaKirisame
Copy link
Contributor

@MarisaKirisame MarisaKirisame commented Apr 16, 2019

@nhynes @wweic @icemelon9 @junrushao1994 @ZihengJiang @jroesch @tqchen can you guys review?

tqchen
tqchen previously requested changes Apr 16, 2019
include/tvm/relay/expr.h Outdated Show resolved Hide resolved
@MarisaKirisame
Copy link
Contributor Author

@tqchen can you give another round of review?

@tqchen
Copy link
Member

tqchen commented May 16, 2019

@MarisaKirisame please rebase. @wweic @jroesch please help review this PR

Copy link
Contributor

@wweic wweic left a comment

Choose a reason for hiding this comment

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

some general cents. will do more detailed review in the next few days.

@@ -220,8 +220,8 @@ TVM_REGISTER_API("relay._make.Call")

TVM_STATIC_IR_FUNCTOR_REGISTER(IRPrinter, vtable)
.set_dispatch<CallNode>([](const CallNode* node, tvm::IRPrinter* p) {
p->stream << "CallNode(" << node->op << ", " << node->args << ", "
<< node->attrs << ", " << node->type_args << ")";
p->stream << "CallNode(" << node->op << ", " << node->args << ", "
Copy link
Contributor

Choose a reason for hiding this comment

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

Better use the command in https://github.com/dmlc/tvm/blob/master/.clang-format to do the formatting so we maintain a consistent code style. The indentation style is 2 space I think.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It does not work - the result is completely different from all other files.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Probably due to we use different rules for macro.

src/relay/pass/partial_eval.cc Outdated Show resolved Hide resolved
src/relay/pass/partial_eval.cc Show resolved Hide resolved
tests/python/relay/test_pass_partial_eval.py Outdated Show resolved Hide resolved
private:
Environment env_;
Module mod_;
std::unordered_map<GlobalVar, PStatic, NodeHash, NodeEqual> gv_map_;
/*! Termination checking is done as follow:
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a test that verifies termination checking(no infinite loop)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

there is test_map and test_loop. However, none of the test is working right now as the vm merge break this. I will fix them.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

They are fixed.

@MarisaKirisame
Copy link
Contributor Author

note to self: dead code elimination dont do inline, so we need an inline pass to make test work again.

@MarisaKirisame
Copy link
Contributor Author

@nhynes @icemelon9 can you guys help review?

@MarisaKirisame
Copy link
Contributor Author

@tqchen @jroesch @slyubomirsky can you guys give it a round of review?

@@ -383,15 +388,78 @@ FInterpreter CPUInterpreter() {
return CreateInterpreter(Module(nullptr), CPUContext(), target);
}

bool IsAtomic(const Expr& e) {
return e.as<VarNode>() || e.as<OpNode>() || e.as<ConstructorNode>() || e.as<GlobalVarNode>();
Copy link
Contributor

Choose a reason for hiding this comment

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

Are constant nodes atomic?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

They arent: they are big.

@slyubomirsky
Copy link
Contributor

I think it would be good to include some explanation as to the use of the creation time mechanism and why it's important for termination checking, as that was all very difficult for me to understand. More varied test cases (given how complicated the feature is) would be good too.

@MarisaKirisame
Copy link
Contributor Author

@slyubomirsky it is not complicated at all! the high level idea is that the argument must be strictly decreasing in some order to be terminating. We choose the order to simply be the order it is created. This work for lots of the case, because for any adt, the outer node is newer then the inner node. So, as long as any of the argument is decreasing, it is good. To include the case where argument a decrease, argument b increase, then argument b increase, argument a decrease, we specify that decrease mean 'globally decrease' (etc: smaller then all seen time at that argument).
I will look at the comment and update it.

@MarisaKirisame
Copy link
Contributor Author

@slyubomirsky I revisited the comment and couldnt figure out how to change it. Anything that is particularly confusing?

@slyubomirsky
Copy link
Contributor

I didn't mean that anything is confusing in itself, just that there should somewhere be a note explaining what the creation times are for and what it does. It took me a fair bit of reading and rereading and thinking to figure out how it worked and that is probably not good for future maintainability.

@wweic
Copy link
Contributor

wweic commented Jun 6, 2019

@MarisaKirisame How do we prevent infinite loop of PE? One case I can think of is a function with 2 arguments, the series of created_time that can cause infinite loop is (1, 1), (0, 2),(2, 1), (1, 3), (3, 2), (2, 4), .... 1st argument grow its created time by 1 at odd position, 2nd argument grow its created time by 1 at even position, so it can trick the PE to recurse all the time.
1st argument: 1, 0, 2, 1, 3, 2, 4, 3, 5, 4
2nd argument: 1, 2, 1, 3, 2, 4, 3, 5, 4, 6

Do you think is this case possible and how do we prevent that?

@MarisaKirisame
Copy link
Contributor Author

MarisaKirisame commented Jun 7, 2019

@wweic

the series of created_time that can cause infinite loop is (1, 1), (0, 2),(2, 1), (1, 3), (3, 2), (2, 4), ...

the lowest_bound is (1, 1), (0, 1), then (2, 1) is checked and found that it does not decrease any argument. I specifically design it to avoid this. I had no idea how to fix the comment though. Can you make some suggestion?

@MarisaKirisame
Copy link
Contributor Author

@wweic I had add some test to make sure. They did pass.

@slyubomirsky
Copy link
Contributor

Thank you for expanding some of the comments

@wweic
Copy link
Contributor

wweic commented Jun 7, 2019

the lowest_bound is (1, 1), (0, 1), then (2, 1) is checked and found that it does not decrease any argument.

@MarisaKirisame Got it. I missed that you compare timestamp with historical minimum.

return recurse();
} else {
// We check to see that at least one argument decrease
// with respect to all previous invocation.
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe expand the comment here that the number of recursive inline calls is bounded by the first created time of all arguments(product of created times).

Copy link
Contributor

@wweic wweic left a comment

Choose a reason for hiding this comment

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

It would be good to comment how the number of recursive inline is bounded by created time.

/* We check to see that at least one argument decrease
* with respect to all previous invocation.
* The depth of the recursion is bounded by
* the sum of the time of all argument at the first call.
Copy link
Contributor

Choose a reason for hiding this comment

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

I think it's product in stead of sum?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

it is sum. everytime the sum must decrease by at least 1.

Copy link
Contributor

Choose a reason for hiding this comment

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

yes you are right. @MarisaKirisame

save

save

save

upstream

lint

remove bad changes

fix build

save

save

please the ci god

Update src/relay/pass/partial_eval.cc

Co-Authored-By: Wei Chen <[email protected]>

save

fix test

ci is ANGRY

fix rebase problem

fix rebase

add test

save

save

comment
@jroesch jroesch merged commit df88c41 into apache:master Jun 15, 2019
wweic pushed a commit to wweic/tvm that referenced this pull request Jun 26, 2019
save

save

save

upstream

lint

remove bad changes

fix build

save

save

please the ci god

Update src/relay/pass/partial_eval.cc

Co-Authored-By: Wei Chen <[email protected]>

save

fix test

ci is ANGRY

fix rebase problem

fix rebase

add test

save

save

comment
wweic pushed a commit to neo-ai/tvm that referenced this pull request Jun 27, 2019
save

save

save

upstream

lint

remove bad changes

fix build

save

save

please the ci god

Update src/relay/pass/partial_eval.cc

Co-Authored-By: Wei Chen <[email protected]>

save

fix test

ci is ANGRY

fix rebase problem

fix rebase

add test

save

save

comment
@MarisaKirisame MarisaKirisame deleted the pe branch July 19, 2019 07:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: need review status: need update need update based on feedbacks
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants