Skip to content

Commit b4f0388

Browse files
author
James Yen
authored
Replace StaticWeightStream with ObjectFifos in MobileNet (#3129)
1 parent 740ed48 commit b4f0388

4 files changed

Lines changed: 33 additions & 275 deletions

File tree

programming_examples/ml/mobilenet/bottleneck/post_l1.py

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@
1919

2020
from aie.iron import Kernel, ObjectFifo, Worker
2121
from aie.iron.controlflow import range_
22+
from aie.iron.dataflow.endpoint import ObjectFifoEndpoint
2223

2324
from bottleneck._common import i8, load_wts
24-
from lowlevel_dma import StaticWeightStream
2525
from network_spec import block as nsblock
2626

2727

@@ -49,25 +49,26 @@ def post_l1(act_in, sf, *, placement, data_dir):
4949
# Input: (7,1,80) int8 Output: (1,1,960) int8
5050
# ------------------------------------------------------------------
5151
# 76800 B of L1 weights are too large for the compute tile. Stage them on
52-
# MemTile(4,1) and stream 9600 B chunks via StaticWeightStream.
52+
# MemTile(4,1) and stream 9600 B chunks via ObjectFifo.
5353
PostOutputSplit = 8
5454
PostRepeatChannels = post_L1_InH # = 7
5555
post_l1_wts_full_sz = post_L1_OutC * post_L1_InC # 76800 B on MemTile
5656
post_l1_wts_chunk = post_l1_wts_full_sz // PostOutputSplit # 9600 B per chunk
5757

5858
post_l1_wts_data = load_wts(data_dir, "post_conv_chain.txt", post_l1_wts_full_sz)
5959

60-
post_l1_pb = StaticWeightStream(
61-
obj_type=i8((post_l1_wts_full_sz,)),
62-
initial_value=post_l1_wts_data,
60+
post_l1_wts_of = ObjectFifo(
61+
i8((post_l1_wts_full_sz,)),
62+
depth=1,
6363
name="post_L1_wts",
64-
recv_type=i8((post_l1_wts_chunk,)),
64+
consumer_obj_type=i8((post_l1_wts_chunk,)),
65+
init_values=[post_l1_wts_data.reshape(post_l1_wts_full_sz)],
6566
repeat_count=PostRepeatChannels,
66-
memtile_placement=placement["memtile"],
67-
compute_placement=placement["compute"],
68-
mem_lock_id=2,
69-
comp_lock_id=0,
7067
)
68+
# Pin the producer (source of weight data) to a MemTile. Normally a
69+
# Worker sets its fifo endpoint implicitly, but this fifo has no
70+
# producing Worker.
71+
post_l1_wts_of.prod().endpoint = ObjectFifoEndpoint(placement["memtile"])
7172

7273
# Round-trip avgpool output through L3 (DDR) so it can be re-broadcast to
7374
# all 4 PostL2 FC tiles — a direct compute→4-compute fan-out exceeds
@@ -138,7 +139,7 @@ def post_l1_fn(
138139
fn_args=[
139140
act_in.cons(),
140141
act_out_post_avgpool_shim.prod(),
141-
post_l1_pb,
142+
post_l1_wts_of.cons(),
142143
k_post_l1,
143144
post_L1_InW,
144145
post_L1_InH,

programming_examples/ml/mobilenet/bottleneck/post_l2.py

Lines changed: 20 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@
1818

1919
from aie.iron import Kernel, ObjectFifo, Worker
2020
from aie.iron.controlflow import range_
21+
from aie.iron.dataflow.endpoint import ObjectFifoEndpoint
2122

2223
from bottleneck._common import i8, load_wts
23-
from lowlevel_dma import StaticWeightStream
2424
from 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,

programming_examples/ml/mobilenet/lowlevel_dma.py

Lines changed: 0 additions & 236 deletions
This file was deleted.

programming_examples/ml/mobilenet/placement.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,7 @@
2020
"init": Tile(0, 2),
2121
"post_l1": {"compute": Tile(6, 4), "memtile": Tile(4, 1)},
2222
"post_l2": {
23-
"fc1_memtiles": [Tile(0, 1), Tile(2, 1), Tile(4, 1), Tile(6, 1)],
24-
"fc2_memtiles": [Tile(1, 1), Tile(3, 1), Tile(5, 1), Tile(7, 1)],
23+
"wts_memtiles": [Tile(1, 1), Tile(3, 1), Tile(5, 1), Tile(7, 1)],
2524
"compute": [Tile(6, 3), Tile(7, 4), Tile(7, 3), Tile(7, 2)],
2625
"join_memtile": Tile(6, 1),
2726
},

0 commit comments

Comments
 (0)