-
Notifications
You must be signed in to change notification settings - Fork 21.4k
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
Fix and update type hints for make_functional.py
#91579
Conversation
🔗 Helpful Links🧪 See artifacts and rendered test results at hud.pytorch.org/pr/91579
Note: Links to docs will display an error until the docs builds have been completed. ✅ No FailuresAs of commit bce866f: This comment was automatically generated by Dr. CI and updates every 15 minutes. |
|
2afefe2
to
2329d7a
Compare
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.
Thanks for the PR, @XuehaiPan. We should try to enable mypy checking for this file in PyTorch CI (to check the type hints and prevent regressions -- thanks for catching incorrect type annotations).
I don't buy using OrderedDict over dict here -- if you feel strongly about it, could we please leave it to a separate discussion?
torch/_functorch/make_functional.py
Outdated
named_params = OrderedDict(named_params) | ||
tied_named_params = OrderedDict(tied_named_params) |
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 buy the dict -> OrderedDict change:
- Performance. OrderedDict has a different implementation than dict and there isn't a need to construct a new OrderedDict around a dict here.
- As you mentioned, dict() is already ordered. As of Python 3.7, the language standard says that dict() is ordered. PyTorch does not support Python < 3.7, so there are no BC concerns.
- consistency: I'd like to see buy in for "prefer OrderedDict to dict" in other parts of the PyTorch codebase.
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 buy the dict -> OrderedDict change:
- Performance. OrderedDict has a different implementation than dict and there isn't a need to construct a new OrderedDict around a dict here.
- As you mentioned, dict() is already ordered. As of Python 3.7, the language standard says that dict() is ordered. PyTorch does not support Python < 3.7, so there are no BC concerns.
Let's pass on this since the language standard guarantees the insertion order for dict
since Python 3.7. The builtin dict
is faster for iteration.
In [1]: from collections import OrderedDict
In [2]: iterable = tuple((str(i), i) for i in range(100))
In [3]: %timeit dict(iterable)
2.37 µs ± 20.5 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)
In [4]: %timeit OrderedDict(iterable)
8.42 µs ± 86.5 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)
In [5]: d = dict(iterable)
In [6]: od = OrderedDict(iterable)
In [7]: %timeit list(d.items())
2.41 µs ± 83.5 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)
In [8]: %timeit list(od.items())
4.05 µs ± 87.4 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)
- consistency: I'd like to see buy in for "prefer OrderedDict to dict" in other parts of the PyTorch codebase.
pytorch/torch/nn/modules/module.py
Lines 448 to 463 in 3120054
super().__setattr__('training', True) | |
super().__setattr__('_parameters', OrderedDict()) | |
super().__setattr__('_buffers', OrderedDict()) | |
super().__setattr__('_non_persistent_buffers_set', set()) | |
super().__setattr__('_backward_pre_hooks', OrderedDict()) | |
super().__setattr__('_backward_hooks', OrderedDict()) | |
super().__setattr__('_is_full_backward_hook', None) | |
super().__setattr__('_forward_hooks', OrderedDict()) | |
super().__setattr__('_forward_hooks_with_kwargs', OrderedDict()) | |
super().__setattr__('_forward_pre_hooks', OrderedDict()) | |
super().__setattr__('_forward_pre_hooks_with_kwargs', OrderedDict()) | |
super().__setattr__('_state_dict_hooks', OrderedDict()) | |
super().__setattr__('_state_dict_pre_hooks', OrderedDict()) | |
super().__setattr__('_load_state_dict_pre_hooks', OrderedDict()) | |
super().__setattr__('_load_state_dict_post_hooks', OrderedDict()) | |
super().__setattr__('_modules', OrderedDict()) |
The attributes in nn.Module
, such as _paramters
, _buffers
, _modules
are stored as OrderedDict
.
Note that, del
and set
attribute in _swap_state
changes the order of items in _paramters
and _buffers
. (del + set
is equivalent to move_to_end()
)
pytorch/torch/_functorch/make_functional.py
Lines 134 to 142 in 3120054
def _swap_state(mod: nn.Module, names_map: List[str], elems): | |
result = [] | |
for (_, attr_names), elem in zip(names_map.items(), elems): | |
for i, attr_name in enumerate(attr_names): | |
if i == 0: | |
result.append(_get_nested_attr(mod, attr_name)) | |
_del_nested_attr(mod, attr_name) | |
_set_nested_attr(mod, attr_name, elem) | |
return result |
9ea0f0e
to
dd122d2
Compare
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.
thank you!
Once approved by a PyTorch maintainer, you can trigger the merge yourself by commenting More ref about the pytorchbot: https://github.com/pytorch/pytorch/wiki/Bot-commands |
@pytorchbot merge |
Merge startedYour 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 |
Merge failedReason: This PR is too stale; the last push date was more than 3 days ago. Please rebase and try again. You can rebase by leaving the following comment on this PR: Details for Dev Infra teamRaised by workflow job |
@pytorchbot rebase |
@pytorchbot merge |
@pytorchbot successfully started a rebase job. Check the current status here |
Successfully rebased |
dd122d2
to
bce866f
Compare
Merge startedYour 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 |
The merge job was canceled. If you believe this is a mistake,then you can re trigger it through pytorch-bot. |
@pytorchbot merge |
Merge startedYour 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 |
Changes in details:
Fix and update some out-of-date type hints in
_functorch/make_functional.py
.Explicitly useOrderedDict
for order-sensitive mappings.In
create_names_map()
,_swap_state()
, andFunctionalModuleWithBuffers.__init__()
, the unordereddict
was used. The key order should be preserved fordict.items()
while it is required tozip
with a tuple ofparams
/buffers
. Although since Python 3.6, the built-in dictionary is insertion ordered (PEP 468). Explicit is better than implicit.cc @zou3519