-
Notifications
You must be signed in to change notification settings - Fork 25.7k
[jit] fix side-effects and aliasing for custom ops #18711
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
Conversation
Previously we didn't track aliasing, mutation, or side effects for custom ops. This PR adds in guards with the most conservative assumptions possible: the op will 1) have side effects, 2) write to everything, and 3) produce a wildcard. We can reign in those restrictions later, but want to get something correct for now. It's a little weird because we have no way of knowing whether a given node represents a custom op--I added it to the schema but I'm open to suggestions for a better place. Follow-ups to this: - Users should be able to specify aliasing annotations/side effects to get better perf somehow. - Relax assumptions a bit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have a few comments but is just about ready I think
|
Okay, comments are addressed. This is only a short term fix to get things to be correct—I think in the long run, we should just use the options that #18589 introduces. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good!
aten/src/ATen/core/function_schema.h
Outdated
| const auto& aliasInfo = arg.alias_info(); | ||
| return aliasInfo && aliasInfo.value().isWrite(); | ||
| }); | ||
| return is_inferred_from_custom_op_ || |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So to be clear we are saying that it is mutable even if it doesn't have any inputs, add comment maybe ?
|
Can we just assume that |
That's an interesting idea…I don't think namespaces are restricted right now for custom ops, but it's easy to add. And we already have this distinction when emitting builtins. |
|
Yeah, we could expose a special subclass of |
This would require changing some of our tests which use the |
|
@eellison I think the idea is to designate "reserved" namespaces that users can't define custom ops in. I think this is good idea anyway (right now I think you could create an |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Different implementation, have to re-review
test/cpp/jit/test_custom_operators.h
Outdated
| } | ||
| { | ||
| RegisterOperators reg( | ||
| {createOperator("foo::no_input", []() -> double { return 4.0; })}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this test causes windows build to fail
|
I think the most recent commit will make it harder to move forward to a future api where users declare ops as functional, because we will have ops that are in user space which we do want to assume mutate the inputs. Operators in c10/caffe2/TVM will also no longer be able to create an operator with specified aliasing, because the namespace will override any information that has been given. |
|
Right now there is no way (short of writing alias annotations manually) for the user to specify the purity of their custom op, so we need to insert guards to make sure things are correct. I expect that when we give users the ability to specify purity, the guards will have to change. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code seems bug free, but see inline comments. I strongly suggest we switch this to whitelist aten and prim rather than special-case all primitive ops.
aten/src/ATen/core/function_schema.h
Outdated
| return aliasInfo && aliasInfo.value().isWrite(); | ||
| }); | ||
| } | ||
| bool is_custom_op() const { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For this PR, I think it would be safer to white-list prim and aten into the stronger alias behavior. I do not like the idea of making a publically-exposed distinction between custom ops and our ops, even for just a few commits.
| // Does this symbol live in one of the above built-in namespaces? | ||
| // If not, that means that this symbol came from the user, through the | ||
| // defintiion of a custom operator. | ||
| bool is_builtin_ns() const; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please do not commit this. I do not want to have people be able to easily special case stuff for built in ops. This will create huge long-term tech debt even if commit for a little while.
| std::tuple_size<ArgumentTuple>::value; | ||
|
|
||
| auto schema = torch::jit::detail::inferAndCheckSchema<Traits>(schemaOrName); | ||
| Symbol name = Symbol::fromQualString(schema.name()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't like this. I want to move our operator registration over to this API and this guard will prevent it. This will need to be removed in the future commit.
torch/csrc/jit/ir.cpp
Outdated
| case prim::TimePoint: | ||
| return true; | ||
| } | ||
| // Custom ops may have arbitrary side effects |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (kind.is_aten() || kind.is_print())
return false
[jit] fix side-effects and aliasing for custom ops Previously we didn't track aliasing, mutation, or side effects for custom ops. This PR adds in guards with the most conservative assumptions possible: the op will 1) have side effects, 2) write to everything, and 3) produce a wildcard. We can reign in those restrictions later, but want to get something correct for now. It's a little weird because we have no way of knowing whether a given node represents a custom op--I added it to the schema but I'm open to suggestions for a better place. Follow-ups to this: - Users should be able to specify aliasing annotations/side effects to get better perf somehow. - Relax assumptions a bit. gh-metadata: pytorch pytorch 18711 gh/suo/15/head
[jit] fix side-effects and aliasing for custom ops Previously we didn't track aliasing, mutation, or side effects for custom ops. This PR adds in guards with the most conservative assumptions possible: the op will 1) have side effects, 2) write to everything, and 3) produce a wildcard. We can reign in those restrictions later, but want to get something correct for now. It's a little weird because we have no way of knowing whether a given node represents a custom op--I added it to the schema but I'm open to suggestions for a better place. Follow-ups to this: - Users should be able to specify aliasing annotations/side effects to get better perf somehow. - Relax assumptions a bit. gh-metadata: pytorch pytorch 18711 gh/suo/15/head
Summary: Pull Request resolved: pytorch/pytorch#18711 ghimport-source-id: c9caedc0660b2b7ba3730cd0e1a2e0e9c3cf422b Stack from [ghstack](https://github.com/ezyang/ghstack): * **#18711 [jit] fix side-effects and aliasing for custom ops** Previously we didn't track aliasing, mutation, or side effects for custom ops. This PR adds in guards with the most conservative assumptions possible: the op will 1) have side effects, 2) write to everything 3) produce a wildcard. In order to tell whether a given operator is a custom op, this PR introduces the concept of a "reserved" namespace (basically all our builtin namespaces). Custom ops live in non-reserved namespaces, so a check on the namespace is sufficient to tell whether a schema/node is "custom" or not. This is just to get things correct for now. Follow-ups to this: - Users should be able to specify aliasing/mutability without having to learn the whole alias annotation schema. - Relax assumptions a bit. In particular outputs can only alias input tensors, they don't have to be wildcards. Fixes #18490 Differential Revision: D14730978 fbshipit-source-id: 540b47a24ccf24145051609bdcc99c97e46e0fe0
|
This pull request has been merged in fefa6d3. |
Summary: Pull Request resolved: #18712 ghimport-source-id: e435150 Stack from [ghstack](https://github.com/ezyang/ghstack): * **#18712 [jit][easy] remove unused func** * #18711 [jit] fix side-effects and aliasing for custom ops as title Differential Revision: D14730979 fbshipit-source-id: 381d16ea2a45779bf6d5fc6d90a4f8585461e902
Summary: Pull Request resolved: pytorch#18711 ghimport-source-id: c9caedc Stack from [ghstack](https://github.com/ezyang/ghstack): * **pytorch#18711 [jit] fix side-effects and aliasing for custom ops** Previously we didn't track aliasing, mutation, or side effects for custom ops. This PR adds in guards with the most conservative assumptions possible: the op will 1) have side effects, 2) write to everything 3) produce a wildcard. In order to tell whether a given operator is a custom op, this PR introduces the concept of a "reserved" namespace (basically all our builtin namespaces). Custom ops live in non-reserved namespaces, so a check on the namespace is sufficient to tell whether a schema/node is "custom" or not. This is just to get things correct for now. Follow-ups to this: - Users should be able to specify aliasing/mutability without having to learn the whole alias annotation schema. - Relax assumptions a bit. In particular outputs can only alias input tensors, they don't have to be wildcards. Fixes pytorch#18490 Differential Revision: D14730978 fbshipit-source-id: 540b47a24ccf24145051609bdcc99c97e46e0fe0
Summary: Pull Request resolved: pytorch#18712 ghimport-source-id: e435150 Stack from [ghstack](https://github.com/ezyang/ghstack): * **pytorch#18712 [jit][easy] remove unused func** * pytorch#18711 [jit] fix side-effects and aliasing for custom ops as title Differential Revision: D14730979 fbshipit-source-id: 381d16ea2a45779bf6d5fc6d90a4f8585461e902
Stack from ghstack:
Previously we didn't track aliasing, mutation, or side effects for
custom ops. This PR adds in guards with the most conservative
assumptions possible: the op will
In order to tell whether a given operator is a custom op, this PR introduces
the concept of a "reserved" namespace (basically all our builtin namespaces).
Custom ops live in non-reserved namespaces, so a check on the namespace
is sufficient to tell whether a schema/node is "custom" or not.
This is just to get things correct for now. Follow-ups to this:
the whole alias annotation schema.
they don't have to be wildcards.
Fixes #18490
Differential Revision: D14730978