Skip to content

Conversation

@gmagogsfm
Copy link
Contributor

@gmagogsfm gmagogsfm commented Jul 26, 2020

[3/N] Implement Enum JIT support

  • Add enum value as constant support
  • Add sugared value for EnumClass

Supported:
Enum-typed function arguments
using Enum type and comparing them
Support getting name/value attrs of enums
Using Enum value as constant

TODO:
Add PyThon sugared value for Enum
Support Enum-typed return values
Support serialization and deserialization

@facebook-github-bot facebook-github-bot added the oncall: jit Add this issue/PR to JIT oncall triage queue label Jul 26, 2020
@dr-ci
Copy link

dr-ci bot commented Jul 26, 2020

💊 CI failures summary and remediations

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


None of the CI failures appear to be your fault 💚



❄️ 1 failure tentatively classified as flaky

but reruns have not yet been triggered to confirm:

See CircleCI build pytorch_bazel_test (1/1)

Step: "Test" (full log | diagnosis details | 🔁 rerun) ❄️

Jul 31 21:22:39 TIMEOUT: //:integration_test (Summary)
Jul 31 21:21:47 [       OK ] CustomAutogradTest.Hooks (20 ms) 
Jul 31 21:21:47 [ RUN      ] CustomAutogradTest.HookNone 
Jul 31 21:21:47 [       OK ] CustomAutogradTest.HookNone (2 ms) 
Jul 31 21:21:47 [----------] 21 tests from CustomAutogradTest (11850 ms total) 
Jul 31 21:21:47  
Jul 31 21:21:47 [----------] Global test environment tear-down 
Jul 31 21:21:47 [==========] 28 tests from 2 test suites ran. (11941 ms total) 
Jul 31 21:21:47 [  PASSED  ] 28 tests. 
Jul 31 21:21:47 ================================================================================ 
Jul 31 21:22:39  
Jul 31 21:22:39 TIMEOUT: //:integration_test (Summary) 
Jul 31 21:22:39       /var/lib/jenkins/.cache/bazel/_bazel_jenkins/fdf6d09bf4b4f04a71e2a7dfceb40620/execroot/pytorch/bazel-out/k8-fastbuild/testlogs/integration_test/test.log 
Jul 31 21:22:39 INFO: From Testing //:integration_test: 
Jul 31 21:22:39 ==================== Test output for //:integration_test: 
Jul 31 21:22:39 Running main() from gmock_main.cc 
Jul 31 21:22:39 Note: Google Test filter = -*CUDA 
Jul 31 21:22:39 [==========] Running 1 test from 1 test suite. 
Jul 31 21:22:39 [----------] Global test environment set-up. 
Jul 31 21:22:39 [----------] 1 test from IntegrationTest 
Jul 31 21:22:39 [ RUN      ] IntegrationTest.CartPole 
Jul 31 21:22:39 -- Test timed out at 2020-07-31 21:22:24 UTC -- 

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 on the GitHub issue tracker or post in the (internal) Dr. CI Users group.

See how this bot performed.

This comment has been revised 69 times.

Copy link
Contributor

@facebook-github-bot facebook-github-bot left a comment

Choose a reason for hiding this comment

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

@gmagogsfm has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@gmagogsfm gmagogsfm linked an issue Jul 27, 2020 that may be closed by this pull request
@gmagogsfm gmagogsfm marked this pull request as ready for review July 27, 2020 07:23
@gmagogsfm gmagogsfm requested a review from apaszke as a code owner July 27, 2020 07:23
Copy link
Contributor

@facebook-github-bot facebook-github-bot left a comment

Choose a reason for hiding this comment

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

@gmagogsfm has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

Copy link
Contributor

@eellison eellison left a comment

Choose a reason for hiding this comment

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

Looks great!! This is almost landable i think there's a few fixes we need to make first

Copy link
Contributor

Choose a reason for hiding this comment

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

we don't technically need to compare both the value if we know they're the same type and the same name... although maybe this is more clear

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point, removed comparison of value

Copy link
Contributor

Choose a reason for hiding this comment

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

Could you add a test for this ? you can test this with isinstance

def foo(x: Any)
    if isinstance(x, Color):
        return x.value
    ...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done. To support this test case, I also had to implement a bit of code in pybind_utils.h tryToInferType. Please also take a look there.

Copy link
Contributor

Choose a reason for hiding this comment

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

this is being used for exporting enum constants (thus the annotated printing of the dict), so i'm not about the final ( v.value() ).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point, removed.

Copy link
Contributor

Choose a reason for hiding this comment

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

nit, i would maybe do type->cast<EnumType>(), as it would be weird if we found a AnyEnumType here. All of the runtime types should EnumType, and the AnyEnumType should just used for schema matching.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point. Done.

Copy link
Contributor

Choose a reason for hiding this comment

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

don't need to ignore loc, it's used below. in general. from searching around, looks like std::ignore is only ever used in this code as part of std::tie (the clang tidy errors you maybe seeing dont get run on master)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done. Removed std::ignore

Copy link
Contributor

Choose a reason for hiding this comment

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

it might be easier to change these 4 lines to: py::module::import("enum").attr("Enum"), I don't think there error messages we're giving here are any better than what python would throw.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

Copy link
Contributor

Choose a reason for hiding this comment

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

nit: is there a reason to not return PyObject_IsSubclass(obj.ptr(), enum_type_obj) ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It may return -1, which indicates failure to compare, and -1 becomes True in boolean.

Copy link
Contributor

@eellison eellison Jul 29, 2020

Choose a reason for hiding this comment

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

Is it possible here instead of getting Color.Red, we're getting Color.Red.value

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Discussed with eellison offline and addressed misunderstanding. This is WAI.

Copy link
Contributor

Choose a reason for hiding this comment

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

this code path gets executed when a python value gets closed over in a script function.

def foo():
     a = Color.Red
    return 

At this point, we may not necessarily have compiled Color as an Enum Class yet. I think you need to pass in the type of the object into the try_ann_to_type so that we ensure the class is regsitered

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done. Using try_ann_to_type here instead of building up the type directly here.

Copy link
Contributor

Choose a reason for hiding this comment

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

don't need to do it as part of this PR, but if you return a list of all of the Enum values this will work

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ack, it is already in next PR.

Choose a reason for hiding this comment

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

I would comment out the function parameter if it's not used.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

Choose a reason for hiding this comment

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

Suggested change
Function& m,
Function& /*m*/,

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

Copy link
Contributor

@facebook-github-bot facebook-github-bot left a comment

Choose a reason for hiding this comment

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

@gmagogsfm has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

Copy link
Contributor

Choose a reason for hiding this comment

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

Can you add some test cases for the case we discussed offline, where an Enum class isnt used as a type annotation and closed over?

a = Color
def foo():
    a

b = Color.Red
def foo():
    b...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

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 we can just compile the type, bc the type stores the name->value mapping, and use that

Copy link
Contributor

@eellison eellison left a comment

Choose a reason for hiding this comment

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

LGTM, Great job!! One small correctness thing to fix before we land this but it should be an easy one

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 has the same problems as we did previously, where we're individually introspecting the object's value so the EnumType doesn't get registered and we won't hit a compile error if someone tries to use an Enum with heterogenous types.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

Copy link
Contributor

Choose a reason for hiding this comment

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

A test to add this time or next time (I think this should work right now) is putting an Enum as a attribute of a module and check that it is retained durign scripting
`
class Mod(nn.Module):
self.a = Color.RED

def forward(self):
return self.a

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

Copy link
Contributor

@facebook-github-bot facebook-github-bot left a comment

Choose a reason for hiding this comment

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

@gmagogsfm has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@facebook-github-bot
Copy link
Contributor

@gmagogsfm merged this pull request in 655f376.

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

Labels

Merged oncall: jit Add this issue/PR to JIT oncall triage queue

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support Enum in TorchScript

5 participants