Skip to content

[jit] Handled cases when input list to cat is mutated after cat using AliasDb#60774

Closed
navahgar wants to merge 7 commits intogh/navahgar/24/basefrom
gh/navahgar/24/head
Closed

[jit] Handled cases when input list to cat is mutated after cat using AliasDb#60774
navahgar wants to merge 7 commits intogh/navahgar/24/basefrom
gh/navahgar/24/head

Conversation

@facebook-github-bot facebook-github-bot added oncall: jit Add this issue/PR to JIT oncall triage queue cla signed labels Jun 25, 2021
@facebook-github-bot
Copy link
Copy Markdown
Contributor

facebook-github-bot commented Jun 25, 2021

💊 CI failures summary and remediations

As of commit d06305b (more details on the Dr. CI page and at hud.pytorch.org/pr/60774):


💚 💚 Looks good so far! There are no failures yet. 💚 💚


Preview docs built from this PR

This comment was automatically generated by Dr. CI (expand for details).Follow this link to opt-out of these comments for your Pull Requests.

Please report bugs/suggestions to the (internal) Dr. CI Users group.

Click here to manually regenerate this comment.

@navahgar
Copy link
Copy Markdown
Contributor Author

@navahgar has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@navahgar navahgar requested a review from eellison June 25, 2021 23:10
@navahgar
Copy link
Copy Markdown
Contributor Author

@navahgar has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

Comment thread test/cpp/jit/test_concat_opt.cpp
Comment thread torch/csrc/jit/passes/concat_opt.cpp Outdated
auto aliasDb = getOrCreateAliasDb();
for (auto use : list_uses) {
if (aliasDb->isMutable(use.user)) {
if (aliasDb->couldMoveBeforeTopologically(use.user, cat)) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I don't know if this is the right logic.
If you have

x = [a, a]
x.append([3])
torch.cat(x)
...
torch.cat(x)

You will not be able to move the append before the second cat, however nonetheless there is a mutation before cat.

You might see something similar if you have a loop as well.

Can I ask what the specific use case is here that we're trying to address?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I probably had the wrong assumption regarding couldMoveBeforeTopologically then. I thought that since the append is already "before" the second cat, couldMoveBeforeTopologically would return true here. IIUC, you are saying that it would try to move just before that destination point and fail here.

I just want to catch all cases where the list (that is input to this cat) is mutated before this cat. In your example, I want to know that both cat ops are with mutated list.

Another case is:

x = [a, a]
torch.cat(x) 
... 
x.append([3])
torch.cat(x)

In this example, I want to know that the first cat is not with mutated list, but the second cat uses a mutated list.

I need this so that, this pass only changes those cat ops without mutated list to prim::Concat. The subsequent calls to RemoveListMutation (added in another PR) will remove the mutation involved.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

How about changing that condition to the following?

if (use.user->isBefore(cat) || aliasDb->couldMoveBeforeTopologically(use.user, cat)) {
  ...

For your example, this should return true (list is modified) for both cat ops since the append is "before" both cat ops.

For my example above, this should return false for the first cat and true for the second one.

IIUC, for nodes in a block isBefore check should suffice. But if we have multiple blocks involved (say with some conditionals), then we might need couldMoveBeforeTopologically.

Am I right about this usage?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

IIUC, you are saying that it would try to move just before that destination point and fail here.

Yes, that is correct.

I don't know that isBefore is a sufficient condition.

li = [x]
for _ in range(4):
     print(torch.cat(li)
     li.append(x)

So, a couple things we could do here:

we could try to augment alias analysis to add a function to test for this case, basically couldMoveBeforeTopologicallyValid except we are ignoring topological dependencies and just look at write/side effectful ones.

However,

I think this problem we're looking here is better solved by iteratively trying to remove mutation on list and also replace cats with a variadic version. Isnt that we're doing #60776, and after that pass doesn't this problem we're trying to solve just become:

x = [a, a]
torch.cat(x,) 
... 
x.append([3])
torch.cat(x)

->

torch.cat(a, a) 
torch.cat(a, a, 3)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good point regarding isBefore.

I think this problem we're looking here is better solved by iteratively trying to remove mutation on list and also replace cats with a variadic version.

It will solve some cases but not all. For example:

x = [a, a]
x.append([a])
torch.cat(x) 
... 
x.append([a])
torch.cat(x)

After one round of RemoveListMutation, the first append will be eliminated but the second one will still be there.

x = [a, a, a]
torch.cat(x) 
... 
x.append([a])
torch.cat(x)

Now, we can replace the first cat with prim::Concat but we still can't do the same for the second one. We need a check to restrict such cases. These are the cases I am trying to catch with this check.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Can we just make the pass iteratively try to remove both appends and cats, so that the pass would remove all instances of x in one pass ?

Even in that case, the pass to remove cats should only remove those that have not been mutated. And that needs the same check again. I still don't see a way to get around that check.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It doesn't need the same check that those have not been mutated, it just needs the check that you can merge the instantiation of the list with its use

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Sure, that should work as well. How is that any better? Is there a different API to check that?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

let's VC tomorrow to takl about it

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Changed this to check if the input list could be moved before cat, as we discussed. PTAL.

@navahgar navahgar requested a review from eellison July 7, 2021 18:16
@navahgar
Copy link
Copy Markdown
Contributor Author

navahgar commented Jul 9, 2021

@navahgar has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@navahgar
Copy link
Copy Markdown
Contributor Author

@navahgar has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

Copy link
Copy Markdown
Contributor

@eellison eellison left a comment

Choose a reason for hiding this comment

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

LGTM

@navahgar
Copy link
Copy Markdown
Contributor Author

@navahgar has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@navahgar
Copy link
Copy Markdown
Contributor Author

@navahgar has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@navahgar
Copy link
Copy Markdown
Contributor Author

@navahgar has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@facebook-github-bot
Copy link
Copy Markdown
Contributor

@navahgar merged this pull request in 4dd04a8.

@facebook-github-bot facebook-github-bot deleted the gh/navahgar/24/head branch July 24, 2021 14:17
laurentdupin pushed a commit to laurentdupin/pytorch that referenced this pull request Apr 25, 2026
… AliasDb (pytorch#60774)

Summary: Pull Request resolved: pytorch#60774

Test Plan: Imported from OSS

Reviewed By: mrshenli

Differential Revision: D29406100

Pulled By: navahgar

fbshipit-source-id: af6afca65881c18c51b482eb63898a0f1c94d591
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cla signed Merged oncall: jit Add this issue/PR to JIT oncall triage queue

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants