Skip to content

Support scripting classmethod called with object instances#49967

Closed
ppwwyyxx wants to merge 1 commit intopytorch:masterfrom
ppwwyyxx:classmethod
Closed

Support scripting classmethod called with object instances#49967
ppwwyyxx wants to merge 1 commit intopytorch:masterfrom
ppwwyyxx:classmethod

Conversation

@ppwwyyxx
Copy link
Copy Markdown
Collaborator

Currentlt classmethods are compiled the same way as methods - the first argument is self.
Adding a fake statement to assign the first argument to the class.
This is kind of hacky, but that's all it takes.

@facebook-github-bot facebook-github-bot added cla signed oncall: jit Add this issue/PR to JIT oncall triage queue labels Dec 30, 2020
@facebook-github-bot
Copy link
Copy Markdown
Contributor

facebook-github-bot commented Dec 30, 2020

💊 CI failures summary and remediations

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


  • 1/1 failures possibly* introduced in this PR
    • 1/1 non-CircleCI failure(s)

ci.pytorch.org: 1 failed


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.

This comment has been revised 3 times.

@codecov
Copy link
Copy Markdown

codecov Bot commented Dec 30, 2020

Codecov Report

Merging #49967 (31db055) into master (963f762) will increase coverage by 5.54%.
The diff coverage is 100.00%.

@@            Coverage Diff             @@
##           master   #49967      +/-   ##
==========================================
+ Coverage   75.14%   80.69%   +5.54%     
==========================================
  Files        1891     1895       +4     
  Lines      205325   205461     +136     
==========================================
+ Hits       154291   165794   +11503     
+ Misses      51034    39667   -11367     

@ppwwyyxx ppwwyyxx requested review from SplitInfinity and eellison and removed request for SplitInfinity December 30, 2020 21:59
Comment thread torch/jit/frontend.py


def get_jit_def(fn, def_name, self_name=None):
def get_jit_def(fn, def_name, self_name=None, is_classmethod=False):
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Is it possible to determine if fn is a classmethod without passing an extra parameter? I think it is:

>>> class A:
...   @classmethod
...   def a(cls):
...     pass
...   def b(self):
...     pass
...   @staticmethod
...   def c(s, t):
...     pass
... 
>>> A.a.__self__
<class '__main__.A'>
>>> A.b.__self__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'function' object has no attribute '__self__'
>>> A.c.__self__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'function' object has no attribute '__self__'

So it seems that __self__ is only present on classmethods? So I think we can do that check in get_jit_def directly without the extra parameter.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Regular methods that are bounded to instances, e.g. A().b in your example will have __self__. Could get_jit_def be called with such methods?

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

From my knowledge, no. Can you try it to see if it's possible (to get rid of the extra function argument)?

Copy link
Copy Markdown
Collaborator Author

@ppwwyyxx ppwwyyxx Jan 7, 2021

Choose a reason for hiding this comment

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

This fails many tests. I added print(fn) when __self__ is present, and saw cases it is called with bound regular methods:

$python3 test/test_jit.py                                                                                                                                                          
Fail to import hypothesis in common_utils, tests are not derandomized                                                                                                                 
.................................<bound method BasicModule.forward of BasicModule()>                                                                                                  
E<bound method BasicModule.forward of BasicModule()>                                                                                                                                  
E<bound method BasicModule.forward of BasicModule()>                                                                                                                                  
E./private/home/yuxinwu/DL/pytorch/test/jit/test_builtins.py:127: DeprecationWarning: Please use assertEqual instead.                                                                 
  self.assertEquals(py_out, jit_out)                                                                                                                                                  
.<bound method TestBuiltins.test_has_attr.<locals>.Mod.forward of Mod(                                                                                                                
  (mods): ModuleList(                                                                                                                                                                 
    (0): HasA()                                                                                                                                                                       
    (1): HasB()                                                                                                                                                                       
  )                                                                                                                                                                                   
)>                                                                                                                                                                                    
<bound method ModuleList.forward of ModuleList(                                                                                                                                       
  (0): HasA()                                                                                                                                                                         
  (1): HasB()                                                                                                                                                                         
)>                                                                                                                                                                                    
E<bound method TestBuiltins.test_has_attr_invalid_args.<locals>.Mod.forward of Mod(                                                                                                   
  (mod): Linear(in_features=1, out_features=1, bias=True)                                                                                                                             
)>                                                                    

It seems that's because scripted modules are always created from instance, not class - so regular methods are bound.

Copy link
Copy Markdown
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.

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

@facebook-github-bot
Copy link
Copy Markdown
Contributor

@ppwwyyxx merged this pull request in 49bb0a3.

facebook-github-bot pushed a commit to facebookresearch/detectron2 that referenced this pull request Jan 11, 2021
Summary: require pytorch/pytorch#49967

Reviewed By: theschnitz

Differential Revision: D25852122

fbshipit-source-id: eb2da41f28861fd8ac4f348283bb072abfe8fedd
@ppwwyyxx ppwwyyxx deleted the classmethod branch September 26, 2024 23:17
laurentdupin pushed a commit to laurentdupin/pytorch that referenced this pull request Apr 24, 2026
…9967)

Summary:
Currentlt classmethods are compiled the same way as methods - the first argument is self.
Adding a fake statement to assign the first argument to the class.
This is kind of hacky, but that's all it takes.

Pull Request resolved: pytorch#49967

Reviewed By: gchanan

Differential Revision: D25841378

Pulled By: ppwwyyxx

fbshipit-source-id: 0f3657b4c9d5d2181d658f9bade9bafc72de33d8
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cla signed 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.

3 participants