Skip to content

Add CPU Fallback#78522

Closed
eellison wants to merge 23 commits intogh/eellison/300/basefrom
gh/eellison/300/head
Closed

Add CPU Fallback#78522
eellison wants to merge 23 commits intogh/eellison/300/basefrom
gh/eellison/300/head

Conversation

@eellison
Copy link
Contributor

@eellison eellison commented May 31, 2022

Stack from ghstack (oldest at bottom):

This adds the option to convert tensors to fallback to cpu if the operator is not supported on meta tensors. The output of the cpu fallback operator must be a new-unaliased TensorImpl because the conversion to cpu and back will lose shared metadata between inputs and outputs.

[ghstack-poisoned]
@facebook-github-bot
Copy link
Contributor

facebook-github-bot commented May 31, 2022

🔗 Helpful links

✅ No Failures (1 Pending)

As of commit 48e1e46 (more details on the Dr. CI page):

Expand to see more

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


This comment was automatically generated by Dr. CI (expand for details).

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

Click here to manually regenerate this comment.

[ghstack-poisoned]
@eellison eellison mentioned this pull request May 31, 2022
Elias Ellison added 2 commits May 31, 2022 09:16
[ghstack-poisoned]
[ghstack-poisoned]
This adds the option to convert tensors to fallback to cpu if the operator is not supported on `meta` tensors. The output of the cpu fallback operator must be a new-unaliased TensorImpl because the conversion to cpu and back will lose shared metadata between inputs and outputs.

[ghstack-poisoned]
try:
yield
finally:
cpu_fallback_enabled = orig
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not have this on the fake tensor mode itself?

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 guess... is this something that we view as temporary? If so, it might be nice not to commit it to the FakeTensorMode api. But I guess it's not that different either way.. I can move into the Mode

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Also there’s no clear way for that to interact with FakeTensors that are constructed from FakeTensor.from_tensor

Copy link
Contributor

Choose a reason for hiding this comment

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

It is simpler and organizationally better for it to live on the mode, so yes I'd prefer it!

Re how tensors can get to it, that would be done by storing the mode on the tensor!

Copy link
Contributor Author

@eellison eellison May 31, 2022

Choose a reason for hiding this comment

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

One thing I don't love about storing the Mode on the Tensor is that you're creating a circular reference from
FakeTensor(a) -> FakeTensorMode -> FakeTensorConverter -> input Tensor -> FakeTensor(a). (cc @samdow )

Copy link
Contributor

Choose a reason for hiding this comment

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

Converter should have a weak ref to the input tensor

r = run_function(func, types, args, kwargs)
except NotImplementedError as not_implemented_error:
if not cpu_fallback_enabled:
raise not_implemented_error
Copy link
Contributor

Choose a reason for hiding this comment

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

raise here is better as doing it this way will destroy the original backtrace info

Copy link
Contributor Author

Choose a reason for hiding this comment

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

sorry, how is this different from one i'm doing now ?

r = func(*args , **kwargs)
except Exception:
# original error more orinformative
raise orig_not_implemented_exception
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 this will impede debugging. I suggest raising a fresh exception here but from orig_exception

Copy link
Contributor Author

Choose a reason for hiding this comment

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

What does raising a fresh exception here but from orig_exception entail ?

Copy link
Contributor

Choose a reason for hiding this comment

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

hmm I didn't think it through. How about raise orig_not_implemented_exception from e where e is the exception you caught here

if e in tensor_impls:
raise orig_not_implemented_exception

tree_map(throw_on_reused_impls, r)
Copy link
Contributor

Choose a reason for hiding this comment

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

This seems very insufficient and also the case being tested for here feels like it can be handled.

It's insufficient in that this fallback will not work for view operations, and you won't capture errors here because view operators will return a fresh tensor with shared storage. Testing for shared storage is better.

It's handleable in that if an output of the cpu operation is exactly the same as the input, we know we can just return the original meta in that case and it will be OK.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

if one were to have an operator which both
a) is unsupported on meta
and
b) changes the input metadata

then just returning the input meta value would not be sufficient

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes. But you can also have an operator that doesn't return the input but does mutate the metadata and you have no way of detecting this. Well, tags would help.

eellison added 2 commits June 1, 2022 06:30
This adds the option to convert tensors to fallback to cpu if the operator is not supported on `meta` tensors. The output of the cpu fallback operator must be a new-unaliased TensorImpl because the conversion to cpu and back will lose shared metadata between inputs and outputs.

[ghstack-poisoned]
This adds the option to convert tensors to fallback to cpu if the operator is not supported on `meta` tensors. The output of the cpu fallback operator must be a new-unaliased TensorImpl because the conversion to cpu and back will lose shared metadata between inputs and outputs.

[ghstack-poisoned]
This adds the option to convert tensors to fallback to cpu if the operator is not supported on `meta` tensors. The output of the cpu fallback operator must be a new-unaliased TensorImpl because the conversion to cpu and back will lose shared metadata between inputs and outputs.

[ghstack-poisoned]
eellison added a commit that referenced this pull request Jun 1, 2022
ghstack-source-id: 4a1062d
Pull Request resolved: #78522
This adds the option to convert tensors to fallback to cpu if the operator is not supported on `meta` tensors. The output of the cpu fallback operator must be a new-unaliased TensorImpl because the conversion to cpu and back will lose shared metadata between inputs and outputs.

[ghstack-poisoned]
eellison added a commit that referenced this pull request Jun 2, 2022
ghstack-source-id: 06479c9
Pull Request resolved: #78522
This adds the option to convert tensors to fallback to cpu if the operator is not supported on `meta` tensors. The output of the cpu fallback operator must be a new-unaliased TensorImpl because the conversion to cpu and back will lose shared metadata between inputs and outputs.

[ghstack-poisoned]
This adds the option to convert tensors to fallback to cpu if the operator is not supported on `meta` tensors. The output of the cpu fallback operator must be a new-unaliased TensorImpl because the conversion to cpu and back will lose shared metadata between inputs and outputs.

[ghstack-poisoned]
This adds the option to convert tensors to fallback to cpu if the operator is not supported on `meta` tensors. The output of the cpu fallback operator must be a new-unaliased TensorImpl because the conversion to cpu and back will lose shared metadata between inputs and outputs.

[ghstack-poisoned]
eellison added a commit that referenced this pull request Jun 2, 2022
ghstack-source-id: 8cb6b3a
Pull Request resolved: #78522
This adds the option to convert tensors to fallback to cpu if the operator is not supported on `meta` tensors. The output of the cpu fallback operator must be a new-unaliased TensorImpl because the conversion to cpu and back will lose shared metadata between inputs and outputs.

[ghstack-poisoned]
eellison added 9 commits June 7, 2022 09:16
This adds the option to convert tensors to fallback to cpu if the operator is not supported on `meta` tensors. The output of the cpu fallback operator must be a new-unaliased TensorImpl because the conversion to cpu and back will lose shared metadata between inputs and outputs.

[ghstack-poisoned]
This adds the option to convert tensors to fallback to cpu if the operator is not supported on `meta` tensors. The output of the cpu fallback operator must be a new-unaliased TensorImpl because the conversion to cpu and back will lose shared metadata between inputs and outputs.

[ghstack-poisoned]
This adds the option to convert tensors to fallback to cpu if the operator is not supported on `meta` tensors. The output of the cpu fallback operator must be a new-unaliased TensorImpl because the conversion to cpu and back will lose shared metadata between inputs and outputs.

[ghstack-poisoned]
This adds the option to convert tensors to fallback to cpu if the operator is not supported on `meta` tensors. The output of the cpu fallback operator must be a new-unaliased TensorImpl because the conversion to cpu and back will lose shared metadata between inputs and outputs.

[ghstack-poisoned]
This adds the option to convert tensors to fallback to cpu if the operator is not supported on `meta` tensors. The output of the cpu fallback operator must be a new-unaliased TensorImpl because the conversion to cpu and back will lose shared metadata between inputs and outputs.

[ghstack-poisoned]
This adds the option to convert tensors to fallback to cpu if the operator is not supported on `meta` tensors. The output of the cpu fallback operator must be a new-unaliased TensorImpl because the conversion to cpu and back will lose shared metadata between inputs and outputs.

[ghstack-poisoned]
This adds the option to convert tensors to fallback to cpu if the operator is not supported on `meta` tensors. The output of the cpu fallback operator must be a new-unaliased TensorImpl because the conversion to cpu and back will lose shared metadata between inputs and outputs.

[ghstack-poisoned]
This adds the option to convert tensors to fallback to cpu if the operator is not supported on `meta` tensors. The output of the cpu fallback operator must be a new-unaliased TensorImpl because the conversion to cpu and back will lose shared metadata between inputs and outputs.

[ghstack-poisoned]
This adds the option to convert tensors to fallback to cpu if the operator is not supported on `meta` tensors. The output of the cpu fallback operator must be a new-unaliased TensorImpl because the conversion to cpu and back will lose shared metadata between inputs and outputs.

[ghstack-poisoned]
@eellison
Copy link
Contributor Author

eellison commented Jun 8, 2022

@pytorchbot merge

@pytorchmergebot
Copy link
Collaborator

@pytorchbot successfully started a merge job. Check the current status here

@github-actions
Copy link
Contributor

github-actions bot commented Jun 8, 2022

Hey @eellison.
You've committed this PR, but it does not have both a 'release notes: ...' and 'topics: ...' label. Please add one of each to the PR. The 'release notes: ...' label should represent the part of PyTorch that this PR changes (fx, autograd, distributed, etc) and the 'topics: ...' label should represent the kind of PR it is (not user facing, new feature, bug fix, perf improvement, etc). The list of valid labels can be found here for the 'release notes: ...' and here for the 'topics: ...'.
For changes that are 'topic: not user facing' there is no need for a release notes label.

ezyang pushed a commit to ezyang/pytorch that referenced this pull request Jun 9, 2022
ghstack-source-id: 85603cf
Pull Request resolved: pytorch#78522
facebook-github-bot pushed a commit that referenced this pull request Jun 10, 2022
Summary:
Pull Request resolved: #78522

Approved by: https://github.com/ezyang

Test Plan: contbuild & OSS CI, see https://hud.pytorch.org/commit/pytorch/pytorch/fe7a13496eb87c620ec404a0c37fb243bdbc7c01

Reviewed By: osalpekar

Differential Revision: D37025735

Pulled By: eellison

fbshipit-source-id: 806330725980fece8d43650d9fdeb8eb6003ffd7
@facebook-github-bot facebook-github-bot deleted the gh/eellison/300/head branch June 12, 2022 14:20
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.

4 participants