Skip to content

[JIT] Allow module interface subtyping to skip argument name matching #47950

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

Closed

Conversation

SplitInfinity
Copy link

@SplitInfinity SplitInfinity commented Nov 14, 2020

Stack from ghstack:

Summary
This commit allows users to define a class attribute in a module
interface definition that specifies which arguments of which methods
should be ignored when determining if modules subtype the interface in
question. Methods of interfaces that allow name mismatches cannot be
called with named arguments.

Test Plan
This commit adds a unit test that tests that implementations with
mismatched arguments subtype properly if the interface allows it.

Differential Revision: D24966648

cc @pietern @mrshenli @pritamdamania87 @zhaojuanmao @satgera @rohan-varma @gqchen @aazzolini @osalpekar @jiayisuse @SciPioneer @H-Huang @cbalioglu @gcramer23

…ching

**Summary**
This commit allows `@torch.jit.interface` to accept a boolean argument
that specify whether implementations must have the same argument names
for matching methods. Methods of interfaces that allow name mismatches cannot
be called with named arguments.

**Test Plan**
This commit adds a unit test that tests that implementations with
mismatched arguments subtype properly if the interface allows it.

[ghstack-poisoned]
@facebook-github-bot facebook-github-bot added oncall: jit Add this issue/PR to JIT oncall triage queue oncall: distributed Add this issue/PR to distributed oncall triage queue labels Nov 14, 2020
@dr-ci
Copy link

dr-ci bot commented Nov 14, 2020

🔗 Helpful links

💊 CI failures summary and remediations

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


Commit ec8bc05 was recently pushed. Waiting for builds...


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.

@SplitInfinity
Copy link
Author

SplitInfinity commented Nov 14, 2020

Pros
👍 simple, restricted to interfaces only
👍 no need to introduce positional args which only exist in 3.7+

Cons
👎 BC-breaking (but the fix is a simple find and replace!)

Rather than adding positional args (because they are not supported in python3.6), I would prefer some way to express the unimportance of argument names on the interface itself (but preferably not in a way that breaks BC like this). Maybe a class attribute?

…nt name matching"

**Summary**
This commit allows `@torch.jit.interface` to accept a boolean argument
that specify whether implementations must have the same argument names
for matching methods. Methods of interfaces that allow name mismatches cannot
be called with named arguments.

**Test Plan**
This commit adds a unit test that tests that implementations with
mismatched arguments subtype properly if the interface allows it.

Differential Revision: [D24966648](https://our.internmc.facebook.com/intern/diff/D24966648)

[ghstack-poisoned]
SplitInfinity pushed a commit that referenced this pull request Nov 14, 2020
…ching

**Summary**
This commit allows `@torch.jit.interface` to accept a boolean argument
that specify whether implementations must have the same argument names
for matching methods. Methods of interfaces that allow name mismatches cannot
be called with named arguments.

**Test Plan**
This commit adds a unit test that tests that implementations with
mismatched arguments subtype properly if the interface allows it.

ghstack-source-id: 15858ff
Pull Request resolved: #47950
@eellison
Copy link
Contributor

I haven't looked into the details of this, but my preference would be for the implementation to set "ignore argument name" to be an argument-level property, instead of a property of the whole schema. The former sets us up to easily support the 3.7 positional-only arg syntax, and is arguably a better API for users of 3.7. It's also "a thing" in python, whereas whole function schema no args isn't.

Other comment is that it's not backwards-incompatible if we add a default -

def interface(*, ignore_argument_names=False) (keyword only is debatable but IMO it's a little more explicit and readable)

@SplitInfinity
Copy link
Author

What do you think of using a class attribute to indicate which arguments should be ignored?

@eellison
Copy link
Contributor

Yea, I could see something like:

@torch.jit.interface
def module():
    ___ignored_argument_names = {"forward": ['x', 'y'], "other_method": ...}

@eellison
Copy link
Contributor

The API though, we can do whatever. More just that I htink it would be nice from an implementation perspective to make it easy to switch to the 3.7 syntax when that comes.

…nt name matching"

**Summary**
This commit allows `@torch.jit.interface` to accept a boolean argument
that specify whether implementations must have the same argument names
for matching methods. Methods of interfaces that allow name mismatches cannot
be called with named arguments.

**Test Plan**
This commit adds a unit test that tests that implementations with
mismatched arguments subtype properly if the interface allows it.

Differential Revision: [D24966648](https://our.internmc.facebook.com/intern/diff/D24966648)

[ghstack-poisoned]
…me matching"

**Summary**
This commit allows users to define a class attribute in a module
interface definition that specify which arguments of which methods
should be ignored when determining if modules subtype the interface in
question. Methods of interfaces that allow name mismatches cannot be
called with named arguments.

**Test Plan**
This commit adds a unit test that tests that implementations with
mismatched arguments subtype properly if the interface allows it.

Differential Revision: [D24966648](https://our.internmc.facebook.com/intern/diff/D24966648)

[ghstack-poisoned]
@SplitInfinity SplitInfinity changed the title [WIP][JIT] Allow module interface subtyping to skip argument name matching [JIT] Allow module interface subtyping to skip argument name matching Nov 18, 2020
…me matching"


**Summary**
This commit allows users to define a class attribute in a module
interface definition that specifies which arguments of which methods
should be ignored when determining if modules subtype the interface in
question. Methods of interfaces that allow name mismatches cannot be
called with named arguments.

**Test Plan**
This commit adds a unit test that tests that implementations with
mismatched arguments subtype properly if the interface allows it.

Differential Revision: [D24966648](https://our.internmc.facebook.com/intern/diff/D24966648)

[ghstack-poisoned]
SplitInfinity pushed a commit that referenced this pull request Nov 19, 2020
**Summary**
This commit allows users to define a class attribute in a module
interface definition that specify which arguments of which methods
should be ignored when determining if modules subtype the interface in
question. Methods of interfaces that allow name mismatches cannot be
called with named arguments.

**Test Plan**
This commit adds a unit test that tests that implementations with
mismatched arguments subtype properly if the interface allows it.

ghstack-source-id: a747954
Pull Request resolved: #47950
Copy link
Author

@SplitInfinity SplitInfinity left a comment

Choose a reason for hiding this comment

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

I left some comments to highlight items I'd like to discuss.

std::ostream* why_not) {
if (child.size() != parent.size()) {
return false;
}
for (size_t i = 0; i < child.size(); ++i) {
const Argument& c = child[i];
const Argument& p = parent[i];
if (c.name() != p.name()) {
if ((ignored_arg_names.count(c.name()) == 0) && (c.name() != p.name())) {
Copy link
Author

@SplitInfinity SplitInfinity Nov 19, 2020

Choose a reason for hiding this comment

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

Perhaps there should be another argument specifying whether ignored_arg_names refers to child or parent?

Also, I agree that this implementation facilitates the transition to positional args, but also allows users to write an interface method with the schema (a: Any, b: Any, c: Any) -> Any and ignore the names of a and c during subtyping, something that is not possible with the positional argument syntax unless the arguments are reordered.

Copy link
Contributor

Choose a reason for hiding this comment

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

If I take a step back, we are working on this solution mainly to unblock tracing issue that could generate arbitrary argument names. From a user's perspective, it is difficult to know which argument names would be changed, even harder to know what they are changed to. Allowing specifying either child/parent argument name would help in this case.

Copy link
Author

Choose a reason for hiding this comment

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

What's the best way to express this? Boolean argument? Enum argument? It feels very awkward.

Comment on lines +331 to +333
// Strip the Assign for the ignored argument names from the ClassDef for
// the interface because define_interface doesn't handle those.
ClassDef stripped_class_def = stripNonDefFromClass(class_def);
Copy link
Author

Choose a reason for hiding this comment

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

This is not elegant but is a necessary consequence of the fact that ClassDef is used to store the AST for interface types and that the parsing machinery for class types is reused for interfaces.

std::ostream* why_not) {
if (child.size() != parent.size()) {
return false;
}
for (size_t i = 0; i < child.size(); ++i) {
const Argument& c = child[i];
const Argument& p = parent[i];
if (c.name() != p.name()) {
if ((ignored_arg_names.count(c.name()) == 0) && (c.name() != p.name())) {
Copy link
Contributor

Choose a reason for hiding this comment

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

If I take a step back, we are working on this solution mainly to unblock tracing issue that could generate arbitrary argument names. From a user's perspective, it is difficult to know which argument names would be changed, even harder to know what they are changed to. Allowing specifying either child/parent argument name would help in this case.

@eellison eellison removed their request for review December 2, 2020 23:19
…me matching"


**Summary**
This commit allows users to define a class attribute in a module
interface definition that specifies which arguments of which methods
should be ignored when determining if modules subtype the interface in
question. Methods of interfaces that allow name mismatches cannot be
called with named arguments.

**Test Plan**
This commit adds a unit test that tests that implementations with
mismatched arguments subtype properly if the interface allows it.

Differential Revision: [D24966648](https://our.internmc.facebook.com/intern/diff/D24966648)

[ghstack-poisoned]
…me matching"


**Summary**
This commit allows users to define a class attribute in a module
interface definition that specifies which arguments of which methods
should be ignored when determining if modules subtype the interface in
question. Methods of interfaces that allow name mismatches cannot be
called with named arguments.

**Test Plan**
This commit adds a unit test that tests that implementations with
mismatched arguments subtype properly if the interface allows it.

Differential Revision: [D24966648](https://our.internmc.facebook.com/intern/diff/D24966648)

[ghstack-poisoned]
SplitInfinity pushed a commit that referenced this pull request Dec 3, 2020
**Summary**
This commit allows users to define a class attribute in a module
interface definition that specify which arguments of which methods
should be ignored when determining if modules subtype the interface in
question. Methods of interfaces that allow name mismatches cannot be
called with named arguments.

**Test Plan**
This commit adds a unit test that tests that implementations with
mismatched arguments subtype properly if the interface allows it.

ghstack-source-id: c9e2ac7
Pull Request resolved: #47950
…me matching"


**Summary**
This commit allows users to define a class attribute in a module
interface definition that specifies which arguments of which methods
should be ignored when determining if modules subtype the interface in
question. Methods of interfaces that allow name mismatches cannot be
called with named arguments.

**Test Plan**
This commit adds a unit test that tests that implementations with
mismatched arguments subtype properly if the interface allows it.

Differential Revision: [D24966648](https://our.internmc.facebook.com/intern/diff/D24966648)

[ghstack-poisoned]
…me matching"


**Summary**
This commit allows users to define a class attribute in a module
interface definition that specifies which arguments of which methods
should be ignored when determining if modules subtype the interface in
question. Methods of interfaces that allow name mismatches cannot be
called with named arguments.

**Test Plan**
This commit adds a unit test that tests that implementations with
mismatched arguments subtype properly if the interface allows it.

Differential Revision: [D24966648](https://our.internmc.facebook.com/intern/diff/D24966648)

[ghstack-poisoned]
SplitInfinity pushed a commit that referenced this pull request Dec 8, 2020
**Summary**
This commit allows users to define a class attribute in a module
interface definition that specify which arguments of which methods
should be ignored when determining if modules subtype the interface in
question. Methods of interfaces that allow name mismatches cannot be
called with named arguments.

**Test Plan**
This commit adds a unit test that tests that implementations with
mismatched arguments subtype properly if the interface allows it.

ghstack-source-id: d56a5df
Pull Request resolved: #47950
@codecov
Copy link

codecov bot commented Dec 9, 2020

Codecov Report

Merging #47950 (ec8bc05) into gh/splitinfinity/67/base (2b70bcd) will increase coverage by 0.00%.
The diff coverage is 96.77%.

@@                    Coverage Diff                    @@
##           gh/splitinfinity/67/base   #47950   +/-   ##
=========================================================
  Coverage                     80.74%   80.74%           
=========================================================
  Files                          1870     1870           
  Lines                        201724   201779   +55     
=========================================================
+ Hits                         162877   162925   +48     
- Misses                        38847    38854    +7     

@suo suo removed their request for review February 19, 2021 19:17
@facebook-github-bot
Copy link
Contributor

Hi @SplitInfinity!

Thank you for your pull request.

We require contributors to sign our Contributor License Agreement, and yours needs attention.

You currently have a record in our system, but the CLA is no longer valid, and will need to be resubmitted.

Process

In order for us to review and merge your suggested changes, please sign at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need to sign the corporate CLA.

Once the CLA is signed, our tooling will perform checks and validations. Afterwards, the pull request will be tagged with CLA signed. The tagging process may take up to 1 hour after signing. Please give it that time before contacting us about it.

If you have received this in error or have any questions, please contact us at cla@fb.com. Thanks!

@pytorchbot
Copy link
Collaborator

Looks like this PR hasn't been updated in a while so we're going to go ahead and mark this as Stale.
Feel free to remove the Stale label if you feel this was a mistake.
If you are unable to remove the Stale label please contact a maintainer in order to do so.
Stale pull requests will automatically be closed 30 days after being marked Stale

@github-actions github-actions bot closed this May 12, 2022
@facebook-github-bot facebook-github-bot deleted the gh/splitinfinity/67/head branch June 11, 2022 14:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla signed oncall: distributed Add this issue/PR to distributed oncall triage queue oncall: jit Add this issue/PR to JIT oncall triage queue open source Stale
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants