@@ -30,18 +30,25 @@ class IdSpace(Enum):
3030 Temp = auto ()
3131
3232
33- @dataclass (frozen = True )
33+ @dataclass (eq = False , frozen = True )
3434class Slot :
35+ """Represents an allocated tensor or symbolic int slot.
36+
37+ Uses identity-based equality and hashing (not field-based) so that
38+ two Slots with the same (id_type, id_space, idx) — which can happen
39+ when the delete-as-you-go allocator recycles an idx — remain distinct
40+ in sets and dicts during build().
41+ """
42+
3543 id_type : IdType
3644 id_space : IdSpace
3745 idx : Optional [int ] = None
38- # Unique allocation ID — ensures Slots with the same (id_type, id_space, idx)
39- # remain distinct in sets/dicts after an idx is freed and reused.
40- # Without this, the delete-as-you-go allocator can free idx=5, then
41- # make_tmp_slot reuses idx=5, and the new Slot equals the old one.
42- # In build()'s _collect_used_slots (a set) and _create_slot_mappings (a dict),
43- # they merge into one entry and get the same global Tid — causing aliasing.
44- alloc_id : Optional [int ] = None
46+
47+ def __eq__ (self , other ):
48+ return self is other
49+
50+ def __hash__ (self ):
51+ return id (self )
4552
4653
4754class IdManager :
@@ -66,13 +73,6 @@ def __init__(self):
6673 self .tid_managers : Dict [IdSpace , IdManager ] = defaultdict (IdManager )
6774 self .vid_managers : Dict [IdSpace , IdManager ] = defaultdict (IdManager )
6875 self .name_to_slot : Dict [str , Slot ] = {}
69- self ._next_alloc_id : int = 0
70-
71- def _alloc_id (self ) -> int :
72- """Return a globally unique allocation ID."""
73- aid = self ._next_alloc_id
74- self ._next_alloc_id += 1
75- return aid
7676
7777 def set_slot (self , node_or_name : Union [Node , str ], slot : Slot ):
7878 if isinstance (node_or_name , Node ):
@@ -124,9 +124,7 @@ def make_constant_slot(self, name: str) -> Slot:
124124 id_space = IdSpace .Constant
125125 manager = self .tid_managers [id_space ]
126126 idx = manager .get_id ()
127- slot = Slot (
128- id_type = IdType .Tensor , id_space = id_space , idx = idx , alloc_id = self ._alloc_id ()
129- )
127+ slot = Slot (id_type = IdType .Tensor , id_space = id_space , idx = idx )
130128 self .name_to_slot [name ] = slot
131129 return slot
132130
@@ -135,9 +133,7 @@ def make_tmp_slot(self) -> Tuple[str, Slot]:
135133 id_space = IdSpace .Temp
136134 manager = self .tid_managers [id_space ]
137135 idx = manager .get_id ()
138- slot = Slot (
139- id_type = IdType .Tensor , id_space = id_space , idx = idx , alloc_id = self ._alloc_id ()
140- )
136+ slot = Slot (id_type = IdType .Tensor , id_space = id_space , idx = idx )
141137 self .name_to_slot [name ] = slot
142138 return name , slot
143139
@@ -147,9 +143,7 @@ def make_tmp_value_slot(self) -> Tuple[str, Slot]:
147143 id_space = IdSpace .Temp
148144 manager = self .vid_managers [id_space ]
149145 idx = manager .get_id ()
150- slot = Slot (
151- id_type = IdType .SymInt , id_space = id_space , idx = idx , alloc_id = self ._alloc_id ()
152- )
146+ slot = Slot (id_type = IdType .SymInt , id_space = id_space , idx = idx )
153147 self .name_to_slot [name ] = slot
154148 return name , slot
155149
@@ -182,14 +176,7 @@ def make_or_get_slots(
182176 else :
183177 manager = self .vid_managers [id_space ]
184178 idx = manager .get_id ()
185- slots .append (
186- Slot (
187- id_type = id_type ,
188- id_space = id_space ,
189- idx = idx ,
190- alloc_id = self ._alloc_id (),
191- )
192- )
179+ slots .append (Slot (id_type = id_type , id_space = id_space , idx = idx ))
193180 slots = tuple (slots )
194181
195182 # Store in the format that matches the node's output structure
0 commit comments