1818
1919from aie .iron import Kernel , ObjectFifo , Worker
2020from aie .iron .controlflow import range_
21+ from aie .iron .dataflow .endpoint import ObjectFifoEndpoint
2122
2223from bottleneck ._common import i8 , load_wts
23- from lowlevel_dma import StaticWeightStream
2424from network_spec import block as nsblock
2525
2626
@@ -30,8 +30,8 @@ def post_l2(act_in, sf, *, placement, data_dir):
3030 Args:
3131 act_in: ObjectFifo — host-scratch fill of the avgpool output (uint16).
3232 sf: dict — full scale-factor mapping; uses sf["POST"]["FC1"], ["FC2"].
33- placement: dict — PLACEMENT["post_l2"] with keys "fc1_memtiles ",
34- "fc2_memtiles", " compute", "join_memtile".
33+ placement: dict — PLACEMENT["post_l2"] with keys "wts_memtiles ",
34+ "compute", "join_memtile".
3535 data_dir: str — directory holding FC{1,2}_{0..3}_chain.txt.
3636
3737 Returns:
@@ -66,9 +66,6 @@ def post_l2(act_in, sf, *, placement, data_dir):
6666 depth = 2 ,
6767 )
6868
69- # FC weights: ping-pong across two adjacent MemTiles per compute tile (FC1
70- # on the even-column MemTile, FC2 on the odd-column MemTile that hosts the
71- # MM2S DMA — keeps DMA off (4,1) which post_L1 owns).
7269 PostOutputSplitL2 = 40
7370 fc_full_per_tile = post_L2_InC * fc_out_per_tile # 409600 B per FC half
7471 fc_recv_per_tile = fc_full_per_tile // PostOutputSplitL2 # 10240 B on compute
@@ -83,8 +80,7 @@ def post_l2(act_in, sf, *, placement, data_dir):
8380 tile = placement ["join_memtile" ],
8481 )
8582
86- fc1_memtiles = placement ["fc1_memtiles" ]
87- fc2_memtiles = placement ["fc2_memtiles" ]
83+ wts_memtiles = placement ["wts_memtiles" ]
8884 fc_comptiles = placement ["compute" ]
8985
9086 def _u16 (shape ):
@@ -111,24 +107,22 @@ def _u16(shape):
111107 fc1_data = load_wts (data_dir , fc1_f , fc_full_per_tile )
112108 fc2_data = load_wts (data_dir , fc2_f , fc_full_per_tile )
113109
114- # FC weights: ping-pong across two adjacent memtiles. Primary = FC1
115- # (consumed first), ping-pong = FC2. DMA + primary share fc2_memtiles[i]
116- # (odd column) to avoid colliding with post_L1's MM2S on (4,1).
117- fc_pb = StaticWeightStream (
118- obj_type = i8 ((fc_full_per_tile ,)),
119- initial_value = fc1_data ,
120- name = f"fc1_wts_{ i } " ,
121- recv_type = i8 ((fc_recv_per_tile ,)),
122- repeat_count = PostOutputSplitL2 ,
123- memtile_placement = fc2_memtiles [i ],
124- compute_placement = fc_comptiles [i ],
125- s2mm_channel = 1 ,
126- ping_pong_buf = (i8 ((fc_full_per_tile ,)), fc2_data , f"fc2_wts_{ i } " ),
127- ping_pong_memtile = fc1_memtiles [i ],
128- mem_lock_id = 0 ,
129- comp_lock_id = 2 ,
130- pp_lock_id = 0 ,
110+ # FC weights: depth-2 ObjectFifo with both FC1 and FC2 weight sets
111+ # as init_values. The consumer loops through buffer 0 (FC1) then
112+ # buffer 1 (FC2), each split into PostOutputSplitL2 chunks.
113+ fc_wts_of = ObjectFifo (
114+ i8 ((fc_full_per_tile ,)),
115+ depth = 2 ,
116+ name = f"post_L2_wts_{ i + 1 } " ,
117+ consumer_obj_type = i8 ((fc_recv_per_tile ,)),
118+ init_values = [
119+ fc1_data .reshape (fc_full_per_tile ),
120+ fc2_data .reshape (fc_full_per_tile ),
121+ ],
131122 )
123+ # Pin the producer to a MemTile. Normally a Worker sets its fifo
124+ # endpoint implicitly, but this fifo has no producing Worker
125+ fc_wts_of .prod ().endpoint = ObjectFifoEndpoint (wts_memtiles [i ])
132126
133127 def post_l2_fn (
134128 act_in ,
@@ -161,7 +155,7 @@ def post_l2_fn(
161155 fn_args = [
162156 act_in .cons (),
163157 act_post_l2_tiles [i ].prod (),
164- fc_pb ,
158+ fc_wts_of . cons () ,
165159 k_post_l2 ,
166160 post_L1_OutC ,
167161 post_L2_InC ,
0 commit comments