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

fix relay.build to not change the module argument in place #5822

Merged
merged 1 commit into from
Jun 16, 2020

Conversation

t-vi
Copy link
Contributor

@t-vi t-vi commented Jun 16, 2020

@t-vi
Copy link
Contributor Author

t-vi commented Jun 16, 2020

@tqchen

Copy link
Member

@junrushao junrushao left a comment

Choose a reason for hiding this comment

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

Thank you for the fix!

@@ -244,6 +244,9 @@ class RelayBuildModule : public runtime::ModuleNode {
GlobalVar main_glb_var = relay_module->GetGlobalVar("main");
Function main_func = Downcast<Function>(relay_module->Lookup(main_glb_var));
auto new_main = BindParamsByName(main_func, params);
// copy module to avoid changing our input
relay_module = IRModule(relay_module->functions, relay_module->type_definitions,
Copy link
Member

Choose a reason for hiding this comment

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

If I understand the issue correctly, I think we need to call CopyOnWrite instead.

IRModule is actually defined with CopyOnWrite method here, the macro expands to this. What we need to do is just call its CopyOnWrite method to generate a unique copy of IRModule.

Copy link
Contributor Author

@t-vi t-vi Jun 16, 2020

Choose a reason for hiding this comment

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

Thank you for the feedback!

OK, so I changed it to call CopyOnWrite and it appears to work.

To understand this better, I got the re-instatiation from FunctionPassNode::operator() here:
https://github.com/apache/incubator-tvm/blob/99745a44407f2d1bd06b8c6a47e6c6c5239ec665/src/relay/ir/transform.cc#L123
is there a reason that isn't done via CopyOnWrite?
Superficially, it seems that the update is then
https://github.com/apache/incubator-tvm/blob/99745a44407f2d1bd06b8c6a47e6c6c5239ec665/src/relay/ir/transform.cc#L135
which would seem very similar to the Update done in the Optimize
https://github.com/apache/incubator-tvm/blob/99745a44407f2d1bd06b8c6a47e6c6c5239ec665/src/relay/backend/build_module.cc#L247
which itself just calls add
https://github.com/apache/incubator-tvm/blob/99745a44407f2d1bd06b8c6a47e6c6c5239ec665/src/ir/module.cc#L271-L273

Is something that could also use CopyOnWrite or is it not applicable there.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I must admit I'm not understanding this very well yet, in particular in for the use of the new relay_module_ptr I get from CopyOnWrite and the original module.
Which one would I use for what after CopyOnWrite?

@t-vi t-vi force-pushed the relay_build_preserve_inputs branch 3 times, most recently from 758002d to fa9f8ec Compare June 16, 2020 11:52
@t-vi
Copy link
Contributor Author

t-vi commented Jun 16, 2020

Now it's not working anymore. :( I think I need a hint.

@junrushao
Copy link
Member

Ooops let me take a closer look

@tqchen
Copy link
Member

tqchen commented Jun 16, 2020

What I would do instead is to simply move relay_module.CopyOnWrite() inside params.size() != 0, which triggers copy if there is additional copy of relay module outside the function.

Note that for mods pass from python, CopyOnWrite always triggers a copy, unless we do mod._move() (moves the python side of the ref)

@t-vi t-vi force-pushed the relay_build_preserve_inputs branch from fa9f8ec to 469b9ea Compare June 16, 2020 17:23
@t-vi
Copy link
Contributor Author

t-vi commented Jun 16, 2020

@tqchen Thank you for the hint. I applied it, but I must admit I'm not entirely certain what's going on.

Do I need to call Update on the ptr returned by CopyOnWrite or on original module? Previously I called it on the original module, but 1) I'm not sure, 2) then the compiler complains about the return of CopyOnWrite being unused.

Also, it seems that CopyOnWrite + Update is certain to do the copy, is it?

@t-vi t-vi force-pushed the relay_build_preserve_inputs branch from 469b9ea to 9f1d172 Compare June 16, 2020 17:27
@tqchen
Copy link
Member

tqchen commented Jun 16, 2020

We don't have to use the ptr of CopyOnWrite in this case, the module also get updated to points to the new copy .

@junrushao
Copy link
Member

@t-vi Here is what is going on: Internally, CopyOnWrite checks if the object (in our case, relay_module) is unique. If so, it does nothing; otherwise, it triggers a copy to make sure that the object is unique. Therefore, after calling CopyOnWrite, it makes sure that any change only happens locally, in our case, making relay.build don't change the input.

@t-vi
Copy link
Contributor Author

t-vi commented Jun 16, 2020

Thanks for the explanation, I'll have to read the source a bit more, but now I can do so with a high-level sense of what's going on. 🙂

Happily the CI likes it better now, too.

@tqchen tqchen merged commit 8931cfa into apache:master Jun 16, 2020
@tqchen
Copy link
Member

tqchen commented Jun 16, 2020

Thanks @t-vi for the contribution ! Thanks @junrushao1994 for reviewing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants