KEMBAR78
Python 3.10 Union operator | support for JIT by randolf-scholz · Pull Request #109293 · pytorch/pytorch · GitHub
Skip to content

Conversation

@randolf-scholz
Copy link
Contributor

@randolf-scholz randolf-scholz commented Sep 14, 2023

Fixes #101777

  • Duplicated the tests from test/jit/test_union.py into test/jit/test_union_pep604.py, using PEP604 style Unions
  • Exchanged custom get_args and get_origin with typing.get_args and typing.get_origin which have the same functionality and became part of the standard library in 3.8
  • Added utility function pep604union_to_union in tree_views.h which converts a BinOP("|") node into the corresponding Union. This function intercepts ScriptTypeParser::parseTypeFromExpr and ScriptTypeParser::parseTypeFromExprImpl and patches the expression.
  • There is a single failing test, I commented it out for the moment to see if CI complains about anything else. I tried several hours to figure out how to patch it, but I am not experienced with C++ development and debugging.

From what I could gather, the following fails:

    def test_union_optional_of_union_return(self):
        @torch.jit.script
        def fn() -> None | str | int:
            y: Optional[int | str] = "foo"
            return y

In the section:

TypePtr ScriptTypeParser::parseTypeFromExpr(const Expr& expr) const {
// the resolver needs to recursively resolve the expression, so to avoid
// resolving all type expr subtrees we only use it for the top level
// expression and base type names.
if (resolver_) {
if (auto typePtr =
resolver_->resolveType(expr.range().text().str(), expr.range())) {
return typePtr;
}
}
return parseTypeFromExprImpl(expr);
}

When using regular Union, the resolver path is taken, whereas with the patch pep604 union, resolveType doesn't work.

cc @ezyang @malfet @rgommers @xuzhao9 @gramster

@pytorch-bot
Copy link

pytorch-bot bot commented Sep 14, 2023

🔗 Helpful Links

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

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

✅ You can merge normally! (1 Unrelated Failure)

As of commit 5a8c408 with merge base 5ad1baf (image):

FLAKY - The following job failed but was likely due to flakiness present on trunk:

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

@pytorch-bot pytorch-bot bot added the release notes: jit release notes category label Sep 14, 2023
@randolf-scholz randolf-scholz marked this pull request as ready for review September 17, 2023 19:02
@randolf-scholz randolf-scholz changed the title wip JIT PEP604 Python 3.10 Union operator | support for JIT Sep 17, 2023
@randolf-scholz
Copy link
Contributor Author

@pytorchbot label "module: typing"

@pytorch-bot pytorch-bot bot added the module: typing Related to mypy type annotations label Sep 20, 2023
@soulitzer soulitzer added the triaged This issue has been looked at a team member, and triaged and prioritized into an appropriate module label Sep 20, 2023
Copy link
Contributor

@ezyang ezyang left a comment

Choose a reason for hiding this comment

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

okey dokey

@ezyang
Copy link
Contributor

ezyang commented Sep 21, 2023

@pytorchbot merge

@pytorch-bot pytorch-bot bot added the ciflow/trunk Trigger trunk jobs on your pull request label Sep 21, 2023
@pytorchmergebot
Copy link
Collaborator

Merge started

Your change will be merged once all checks pass (ETA 0-4 Hours).

Learn more about merging in the wiki.

Questions? Feedback? Please reach out to the PyTorch DevX Team

Advanced Debugging
Check the merge workflow status
here

@randolf-scholz
Copy link
Contributor Author

randolf-scholz commented Sep 21, 2023

@ezyang This shouldn't be merged yet, first the failure of the Optional simplification should be clarified (as per review request). (whether to resolve it or to simply don't care about it)

EDIT: I forget to make the review visible...

@randolf-scholz
Copy link
Contributor Author

@ezyang I couldn't quite figure out how to solve it. Either we find a solution or one can decide to not care about this error. Also if you haven't it would be good to check the C++ code as I am a novice with respect to C++ development.

randolf-scholz

This comment was marked as spam.

expr.range(),
Var::create(expr.range(), Ident::create(expr.range(), "Union")),
List<Expr>::create(expr.range(), members));
return std::move(synthesised_union);
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: just return Subscript::create directly. There's a long thing about return on std::move impeding copy elision but iirc Exprs are cheap to move so it doesn't really matter.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@ezyang ezyang requested a review from eellison September 24, 2023 02:56
@ezyang
Copy link
Contributor

ezyang commented Sep 24, 2023

I'm willing to accept this with bugs. It will just mean some valid programs fail to typecheck, right? You can always figure it out later and send us a patch.

We don't have dedicated TS cycles so I am mostly estimating that this feature is relatively low risk to add. I also am not sure how to solve your particular problem, but if this would be useful to you it's better to just get this in.

@randolf-scholz
Copy link
Contributor Author

randolf-scholz commented Sep 24, 2023

I'm willing to accept this with bugs. It will just mean some valid programs fail to typecheck, right? You can always figure it out later and send us a patch.

We don't have dedicated TS cycles so I am mostly estimating that this feature is relatively low risk to add. I also am not sure how to solve your particular problem, but if this would be useful to you it's better to just get this in.

It means some valid programs fail JIT-compilation, specifically, this test fails (in the duplicated tests from test/jit/test_union.py):

    def test_union_optional_of_union_is_flattened(self):
        @torch.jit.script
        def fn(flag: int) -> str | int | None:
            y: int | str | None = "foo"
            if flag == 0:
                x: Optional[int | str] = y
            elif flag == 1:
                x: Optional[int | str] = 1
            else:
                x: Optional[int | str] = None
            return x

with the following error message upon attempting to jit.script the function:

Return value was annotated as having type Union[int, NoneType, str]
but is actually of type Optional[Union[int, str]]:

It succeeds if |-unions are replaced by typing.Union, or if the Optional is replaced by None | ....

@ezyang
Copy link
Contributor

ezyang commented Sep 25, 2023

Yeah, this is OK by me. Essentially, you are only strictly expanding the set of programs we accept, there are some programs we don't manage to get but they are easy to work around.

@ezyang
Copy link
Contributor

ezyang commented Sep 25, 2023

@pytorchbot merge

@pytorchmergebot
Copy link
Collaborator

Merge started

Your change will be merged once all checks pass (ETA 0-4 Hours).

Learn more about merging in the wiki.

Questions? Feedback? Please reach out to the PyTorch DevX Team

Advanced Debugging
Check the merge workflow status
here

@pytorchmergebot
Copy link
Collaborator

Merge failed

Reason: 1 mandatory check(s) failed. The first few are:

Dig deeper by viewing the failures on hud

Details for Dev Infra team Raised by workflow job

Failing merge rule: Core Maintainers

@ezyang ezyang added the topic: new features topic category label Sep 25, 2023
@ezyang
Copy link
Contributor

ezyang commented Sep 25, 2023

@pytorchbot merge -f "spurious failure"

@pytorchmergebot
Copy link
Collaborator

Merge started

Your change will be merged immediately since you used the force (-f) flag, bypassing any CI checks (ETA: 1-5 minutes). Please use -f as last resort and instead consider -i/--ignore-current to continue the merge ignoring current failures. This will allow currently pending tests to finish and report signal before the merge.

Learn more about merging in the wiki.

Questions? Feedback? Please reach out to the PyTorch DevX Team

Advanced Debugging
Check the merge workflow status
here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ciflow/trunk Trigger trunk jobs on your pull request Merged module: typing Related to mypy type annotations open source release notes: jit release notes category topic: new features topic category triaged This issue has been looked at a team member, and triaged and prioritized into an appropriate module

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Python 3.10 Union operator | is not supported in jit script

5 participants