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 placeholder lifetime bug in memory planning #6971

Merged
merged 1 commit into from
Dec 2, 2024

Conversation

tarun292
Copy link
Contributor

Differential Revision: D66184849

Copy link

pytorch-bot bot commented Nov 19, 2024

🔗 Helpful Links

🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/executorch/6971

Note: Links to docs will display an error until the docs builds have been completed.

✅ No Failures

As of commit 7c8271e with merge base a347665 (image):
💚 Looks good so far! There are no failures yet. 💚

This comment was automatically generated by Dr. CI and updates every 15 minutes.

@facebook-github-bot facebook-github-bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Nov 19, 2024
@facebook-github-bot
Copy link
Contributor

This pull request was exported from Phabricator. Differential Revision: D66184849

@facebook-github-bot
Copy link
Contributor

This pull request was exported from Phabricator. Differential Revision: D66184849

tarun292 added a commit that referenced this pull request Nov 21, 2024
Summary:

If we have a node that is inserted between placeholders via a pass after to_edge then there is a bug in memory planning lifetime calculations which results in two placeholders being allocated the same memory segment.

Two placeholders should never be using the same memory segment and to prevent this we set the beginning lifetime of the placeholder to be always 0 in the memory planning pass.

In the test case added this is the graph:
```
graph():
    %a : [num_users=1] = placeholder[target=a]
    %aten_permute_copy_default : [num_users=1] = call_function[target=executorch.exir.dialects.edge._ops.aten.permute_copy.default](args = (%a, [1, 0, 2]), kwargs = {})
    %b : [num_users=2] = placeholder[target=b]
    %aten_add_tensor : [num_users=2] = call_function[target=executorch.exir.dialects.edge._ops.aten.add.Tensor](args = (%aten_permute_copy_default, %b), kwargs = {})
    %aten_add_tensor_1 : [num_users=1] = call_function[target=executorch.exir.dialects.edge._ops.aten.add.Tensor](args = (%aten_add_tensor, %b), kwargs = {})
    return (aten_add_tensor, aten_add_tensor_1)
```

Without this fix the lifetimes of placeholders a and b are:
`a => [0, 2]`
`b => [3, 7]`
Thus the same memory segment is allocated for both of them.

After this fix the lifetimes of the placeholders a and b are:
`a => [0, 2]`
`b => [0, 7]`

Differential Revision: D66184849
@facebook-github-bot
Copy link
Contributor

This pull request was exported from Phabricator. Differential Revision: D66184849

tarun292 added a commit that referenced this pull request Nov 27, 2024
Summary:

If we have a node that is inserted between placeholders via a pass after to_edge then there is a bug in memory planning lifetime calculations which results in two placeholders being allocated the same memory segment.

Two placeholders should never be using the same memory segment and to prevent this we set the beginning lifetime of the placeholder to be always 0 in the memory planning pass.

In the test case added this is the graph:
```
graph():
    %a : [num_users=1] = placeholder[target=a]
    %aten_permute_copy_default : [num_users=1] = call_function[target=executorch.exir.dialects.edge._ops.aten.permute_copy.default](args = (%a, [1, 0, 2]), kwargs = {})
    %b : [num_users=2] = placeholder[target=b]
    %aten_add_tensor : [num_users=2] = call_function[target=executorch.exir.dialects.edge._ops.aten.add.Tensor](args = (%aten_permute_copy_default, %b), kwargs = {})
    %aten_add_tensor_1 : [num_users=1] = call_function[target=executorch.exir.dialects.edge._ops.aten.add.Tensor](args = (%aten_add_tensor, %b), kwargs = {})
    return (aten_add_tensor, aten_add_tensor_1)
```

Without this fix the lifetimes of placeholders a and b are:
`a => [0, 2]`
`b => [3, 7]`
Thus the same memory segment is allocated for both of them.

After this fix the lifetimes of the placeholders a and b are:
`a => [0, 2]`
`b => [0, 7]`

Reviewed By: JacobSzwejbka

Differential Revision: D66184849
@facebook-github-bot
Copy link
Contributor

This pull request was exported from Phabricator. Differential Revision: D66184849

facebook-github-bot pushed a commit that referenced this pull request Nov 27, 2024
Summary:

If we have a node that is inserted between placeholders via a pass after to_edge then there is a bug in memory planning lifetime calculations which results in two placeholders being allocated the same memory segment.

Two placeholders should never be using the same memory segment and to prevent this we set the beginning lifetime of the placeholder to be always 0 in the memory planning pass.

In the test case added this is the graph:
```
graph():
    %a : [num_users=1] = placeholder[target=a]
    %aten_permute_copy_default : [num_users=1] = call_function[target=executorch.exir.dialects.edge._ops.aten.permute_copy.default](args = (%a, [1, 0, 2]), kwargs = {})
    %b : [num_users=2] = placeholder[target=b]
    %aten_add_tensor : [num_users=2] = call_function[target=executorch.exir.dialects.edge._ops.aten.add.Tensor](args = (%aten_permute_copy_default, %b), kwargs = {})
    %aten_add_tensor_1 : [num_users=1] = call_function[target=executorch.exir.dialects.edge._ops.aten.add.Tensor](args = (%aten_add_tensor, %b), kwargs = {})
    return (aten_add_tensor, aten_add_tensor_1)
```

Without this fix the lifetimes of placeholders a and b are:
`a => [0, 2]`
`b => [3, 7]`
Thus the same memory segment is allocated for both of them.

After this fix the lifetimes of the placeholders a and b are:
`a => [0, 2]`
`b => [0, 7]`

Reviewed By: JacobSzwejbka

Differential Revision: D66184849
@facebook-github-bot
Copy link
Contributor

This pull request was exported from Phabricator. Differential Revision: D66184849

facebook-github-bot pushed a commit that referenced this pull request Nov 27, 2024
Summary:

If we have a node that is inserted between placeholders via a pass after to_edge then there is a bug in memory planning lifetime calculations which results in two placeholders being allocated the same memory segment.

Two placeholders should never be using the same memory segment and to prevent this we set the beginning lifetime of the placeholder to be always 0 in the memory planning pass.

In the test case added this is the graph:
```
graph():
    %a : [num_users=1] = placeholder[target=a]
    %aten_permute_copy_default : [num_users=1] = call_function[target=executorch.exir.dialects.edge._ops.aten.permute_copy.default](args = (%a, [1, 0, 2]), kwargs = {})
    %b : [num_users=2] = placeholder[target=b]
    %aten_add_tensor : [num_users=2] = call_function[target=executorch.exir.dialects.edge._ops.aten.add.Tensor](args = (%aten_permute_copy_default, %b), kwargs = {})
    %aten_add_tensor_1 : [num_users=1] = call_function[target=executorch.exir.dialects.edge._ops.aten.add.Tensor](args = (%aten_add_tensor, %b), kwargs = {})
    return (aten_add_tensor, aten_add_tensor_1)
```

Without this fix the lifetimes of placeholders a and b are:
`a => [0, 2]`
`b => [3, 7]`
Thus the same memory segment is allocated for both of them.

After this fix the lifetimes of the placeholders a and b are:
`a => [0, 2]`
`b => [0, 7]`

Reviewed By: JacobSzwejbka

Differential Revision: D66184849
@facebook-github-bot
Copy link
Contributor

This pull request was exported from Phabricator. Differential Revision: D66184849

1 similar comment
@facebook-github-bot
Copy link
Contributor

This pull request was exported from Phabricator. Differential Revision: D66184849

Summary:

If we have a node that is inserted between placeholders via a pass after to_edge then there is a bug in memory planning lifetime calculations which results in two placeholders being allocated the same memory segment.

Two placeholders should never be using the same memory segment and to prevent this we set the beginning lifetime of the placeholder to be always 0 in the memory planning pass.

In the test case added this is the graph:
```
graph():
    %a : [num_users=1] = placeholder[target=a]
    %aten_permute_copy_default : [num_users=1] = call_function[target=executorch.exir.dialects.edge._ops.aten.permute_copy.default](args = (%a, [1, 0, 2]), kwargs = {})
    %b : [num_users=2] = placeholder[target=b]
    %aten_add_tensor : [num_users=2] = call_function[target=executorch.exir.dialects.edge._ops.aten.add.Tensor](args = (%aten_permute_copy_default, %b), kwargs = {})
    %aten_add_tensor_1 : [num_users=1] = call_function[target=executorch.exir.dialects.edge._ops.aten.add.Tensor](args = (%aten_add_tensor, %b), kwargs = {})
    return (aten_add_tensor, aten_add_tensor_1)
```

Without this fix the lifetimes of placeholders a and b are:
`a => [0, 2]`
`b => [3, 7]`
Thus the same memory segment is allocated for both of them.

After this fix the lifetimes of the placeholders a and b are:
`a => [0, 2]`
`b => [0, 7]`

Reviewed By: JacobSzwejbka

Differential Revision: D66184849
@facebook-github-bot
Copy link
Contributor

This pull request was exported from Phabricator. Differential Revision: D66184849

@facebook-github-bot facebook-github-bot merged commit c9d7b6e into main Dec 2, 2024
41 of 42 checks passed
@facebook-github-bot facebook-github-bot deleted the export-D66184849 branch December 2, 2024 19:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. fb-exported topic: not user facing
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants