Decentralize and Improve key hash implementation for Dict variable tracker (#169204)
Summary:
Fixes https://github.com/pytorch/pytorch/issues/167956
## Summary
This PR decentralizes and improves the hash implementation for dictionary keys in Dynamo's ConstDictVariable tracker. Instead of maintaining a centralized list of hashable types and custom equality logic in
_HashableTracker, we now delegate hashability checks, hash computation, and equality comparison to individual VariableTracker subclasses.
## Motivation
The previous implementation had several issues:
1. Centralized logic: All hashability checks and hash computations were centralized in dicts.py, making it difficult to add support for new hashable types
2. Maintainability: Adding a new hashable type required modifying multiple locations in _HashableTracker (underlying_value, _eq_impl, and the is_hashable function)
3. Scattered knowledge: Type-specific hashing logic was separated from the type's own implementation
4. Limited extensibility: No clear protocol for VariableTracker subclasses to declare themselves as hashable
## Changes
New Protocol Methods
Added three new methods to the VariableTracker base class:
1. is_python_hashable(): Returns whether the underlying Python object is hashable
2. get_python_hash(): Computes the hash value for the underlying Python object
3. is_python_equal(other): Checks Python-level equality between two VariableTrackers
The base implementation raises unimplemented() with helpful error messages, and subclasses override these methods as appropriate.
## Simplified _HashableTracker
The _HashableTracker class in ConstDictVariable is now much simpler:
- Removed underlying_value property (centralized type handling)
- Removed _eq_impl static method (centralized equality logic)
- Simplified __hash__() to delegate to vt.get_python_hash()
- Simplified __eq__() to delegate to vt.is_python_equal()
## Decentralized Implementations
Implemented the new protocol methods across relevant VariableTracker subclasses:
- ConstantVariable, TensorVariable, TupleVariable, ListVariable
- FrozensetVariable, FrozenDataClassVariable
- BuiltinVariable, UserFunctionVariable, SkipFunctionVariable
- FunctoolsPartialVariable, WeakRefVariable
- NumpyVariable, NNModuleVariable, MethodWrapperVariable
- TorchInGraphFunctionVariable, TorchHigherOrderOperatorVariable
- TypingVariable, UserDefinedObjectVariable, UserDefinedClassVariable
- SymNodeVariable, EnumVariable
## Enhanced Test Coverage
Added 14 new test cases covering various hashable types as dictionary keys:
- range, tuples, enums, frozensets
- Typing constructs (e.g., typing.Union)
- NumPy dtypes, method wrappers
- Torch builtin functions, frozen dataclasses
- Custom objects with __hash__
- Negative test for unhashable types (lists)
## Improved Error Messages
Updated error messages to be more informative when encountering unhashable types, showing both the Python type and the VariableTracker type.
X-link: https://github.com/pytorch/pytorch/pull/169204
Approved by: https://github.com/jansel
Reviewed By: williamwen42, huydhn
Differential Revision: D88129557
fbshipit-source-id: 7404f4ba39f557300c894d664dd64b0c0a1632bb