Phase 2c-1: wire chunkifies into Flits + reassembly compat layer
Wire decomposes Transactions into Flits per `_flit_bytes` but emits all flits atomically at the same env.now — preserves single-msg timing as infrastructure for Phase 2c-2 (per-flit timing + flit-aware routers). Non-flit-aware components reassemble Flits in `_fan_in`; `_update_step` sets txn.step to current component's path position so legacy step-based routing continues working when upstream is flit-aware. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -53,11 +53,51 @@ class ComponentBase(ABC):
|
||||
env.process(self._fan_in(port))
|
||||
env.process(self._worker(env))
|
||||
|
||||
# ADR-0033 Phase 2c: flit-aware components consume Flits directly;
|
||||
# non-flit-aware components reassemble Flits into the parent
|
||||
# Transaction before delivery to _inbox. Default False preserves
|
||||
# legacy single-msg semantics during incremental rollout.
|
||||
_FLIT_AWARE: bool = False
|
||||
|
||||
def _fan_in(self, port: simpy.Store) -> Generator:
|
||||
"""Relay messages from one in_port into the shared inbox."""
|
||||
"""Relay messages from in_port to _inbox. For non-flit-aware
|
||||
components (default), Flits are accumulated by parent Transaction
|
||||
and only the reassembled Transaction is placed on _inbox once
|
||||
``is_last`` arrives. Step is updated to this component's path
|
||||
position for legacy step-based routing."""
|
||||
from kernbench.sim_engine.transaction import Flit
|
||||
|
||||
if self._FLIT_AWARE:
|
||||
while True:
|
||||
msg = yield port.get()
|
||||
yield self._inbox.put(msg)
|
||||
return
|
||||
|
||||
flit_buffers: dict[int, list[Any]] = {}
|
||||
while True:
|
||||
msg = yield port.get()
|
||||
yield self._inbox.put(msg)
|
||||
if isinstance(msg, Flit):
|
||||
tid = id(msg.txn)
|
||||
flit_buffers.setdefault(tid, []).append(msg)
|
||||
if msg.is_last:
|
||||
flit_buffers.pop(tid, None)
|
||||
self._update_step(msg.txn)
|
||||
yield self._inbox.put(msg.txn)
|
||||
else:
|
||||
yield self._inbox.put(msg)
|
||||
|
||||
def _update_step(self, txn: Any) -> None:
|
||||
"""Set txn.step to this component's index in txn.path (if found).
|
||||
Allows legacy step-based routing to work even when flit-aware
|
||||
upstream components don't call txn.advance()."""
|
||||
my_id = self.node.id
|
||||
path = getattr(txn, "path", None)
|
||||
if not path:
|
||||
return
|
||||
for i, n in enumerate(path):
|
||||
if n == my_id:
|
||||
txn.step = i
|
||||
return
|
||||
|
||||
def _worker(self, env: simpy.Environment) -> Generator:
|
||||
"""Generic forwarding worker: spawns _forward_txn per message (pipeline)."""
|
||||
|
||||
Reference in New Issue
Block a user