Skip to content

Commit 1f2fd9a

Browse files
erwei-xilinxclaude
andcommitted
[AIEPlacer] Unify objectfifo + flow placement through Adjacency
Replaces the parallel `ConnectivityGroup` / DFS-grouping path with the same `Adjacency` representation already used by buffer / lock / cascade constraints (#3041, #3042, #3046, prior commit on this branch). ## Motivation Before this commit, the placer maintained two independent "tile-to-tile relation" representations: 1. `Adjacency` -- introduced for buffer/cascade/lock affinity. Pairwise edges + indexed lookup. Used for legality predicates. 2. `ConnectivityGroup` + bespoke `MapVector<LT, SetVector<LT>>` adjacency + manual DFS in `buildFlowGroups`. Used for centroid placement of mem/shim tiles near their core peers. These do the same job (encode "what tiles are related") in different shapes. With #3046 landed there's now exactly one canonical representation; the legacy fifo path is the only thing left using the parallel one. ## What changes - New `buildObjectFifoAdjacency(objectFifos, objectFifoLinks) -> Adjacency`: emits one edge per `(producer, consumer_i)` pair. Linked fifos share an intermediate tile (link tile == consumer of every source fifo and producer of every destination fifo), so the natural edge emission already connects all sibling endpoints transitively through that shared tile -- no separate group-id machinery needed. - New `buildFlowAdjacency(flows, pktFlows) -> Adjacency`: one edge per `aie.flow` `(src, dst)`; per `aie.packet_flow`, cross-product of its `aie.packet_source`s and `aie.packet_dest`s. - New `placeNonCoreTileByCentroid(lt, adjacencies, channelRequirements)`: BFS through every supplied adjacency starting at `lt`, accumulating columns of placed `CoreTile` peers along the way; place at the rounded centroid (or the LTO's pinned column if set), respecting channel-requirement capacity. Walking through `LogicalTileOp` peers preserves the legacy ConnectivityGroup behaviour of seeing cores reachable transitively through intermediate mem/shim tiles. - Phase 4 + Phase 5 in `place()` collapse into a single iteration over unplaced non-core LTOs, each calling the new placement function. ## Removals - `struct ConnectivityGroup` (header) - `buildObjectFifoGroups`, `buildFlowGroups`, `placeNonCoreTilesInGroup` (cpp + header) ## Behavior Identical placements on all existing lit tests (10/10 in `test/place-tiles/`, including the multi-fifo `edge_detect`, linked-fifo, and flow-grouping cases). Channel-requirements path is untouched -- it's a per-tile resource counter, fundamentally not a pairwise relation, and rightfully stays as `DenseMap<Op*, pair<in, out>>` outside Adjacency. Net diff: -25 lines. The unified path is shorter than the parallel one it replaces. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 0c390b0 commit 1f2fd9a

2 files changed

Lines changed: 163 additions & 188 deletions

File tree

include/aie/Dialect/AIE/Transforms/AIEPlacer.h

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,6 @@ enum class PlacerType { SequentialPlacer };
2222
// maps logical tile operations to physical coordinates
2323
using PlacementResult = llvm::DenseMap<mlir::Operation *, TileID>;
2424

25-
// A set of LogicalTileOps connected by some connectivity op (objectfifo,
26-
// flow, packet_flow, ...). `coreTiles` is used to compute the common column
27-
// for placing the group's `nonCoreTiles`. Both lists may contain duplicates
28-
// when a tile is referenced by multiple connectivity ops in the same group;
29-
// duplicates intentionally weight the common-column average.
30-
struct ConnectivityGroup {
31-
llvm::SmallVector<LogicalTileOp, 4> coreTiles;
32-
llvm::SmallVector<LogicalTileOp, 4> nonCoreTiles;
33-
};
34-
3525
// Track available tiles and resource usage
3626
struct TileAvailability {
3727
std::vector<TileID> compTiles;
@@ -96,19 +86,6 @@ class SequentialPlacer : public Placer {
9686

9787
void limitCoresPerColumn(int maxCoresPerCol, int numColumns);
9888

99-
void buildObjectFifoGroups(llvm::ArrayRef<ObjectFifoCreateOp> objectFifos,
100-
llvm::ArrayRef<ObjectFifoLinkOp> objectFifoLinks,
101-
llvm::SmallVectorImpl<ConnectivityGroup> &groups);
102-
103-
void buildFlowGroups(llvm::ArrayRef<FlowOp> flows,
104-
llvm::ArrayRef<PacketFlowOp> pktFlows,
105-
llvm::SmallVectorImpl<ConnectivityGroup> &groups);
106-
107-
mlir::LogicalResult placeNonCoreTilesInGroup(
108-
const ConnectivityGroup &group,
109-
const llvm::DenseMap<mlir::Operation *, std::pair<int, int>>
110-
&channelRequirements);
111-
11289
std::optional<TileID> findTileWithCapacity(int targetCol,
11390
std::vector<TileID> &tiles,
11491
int requiredInputChannels,
@@ -182,6 +159,35 @@ class SequentialPlacer : public Placer {
182159
// destination.
183160
Adjacency buildCascadeAdjacency(llvm::ArrayRef<CascadeFlowOp> cascadeFlows);
184161

162+
// Connectivity edges from `aie.objectfifo`s. Each fifo emits edges from its
163+
// producer tile to each consumer tile. Linked fifos share an intermediate
164+
// tile (the link tile is the consumer of source fifos and the producer of
165+
// destination fifos), so the natural edge emission already connects all
166+
// sibling endpoints transitively without needing a separate group-id pass.
167+
// Used for non-core (mem/shim) tile placement, not for legality checks --
168+
// an unplaced mem/shim LTO is placed near the centroid of its placed core
169+
// peers (transitively reachable through these edges).
170+
Adjacency
171+
buildObjectFifoAdjacency(llvm::ArrayRef<ObjectFifoCreateOp> objectFifos,
172+
llvm::ArrayRef<ObjectFifoLinkOp> objectFifoLinks);
173+
174+
// Connectivity edges from `aie.flow` and `aie.packet_flow`. For `aie.flow`,
175+
// each op emits one (src, dst) edge. For `aie.packet_flow`, each op emits
176+
// a cross-product of its `aie.packet_source`s and `aie.packet_dest`s.
177+
Adjacency buildFlowAdjacency(llvm::ArrayRef<FlowOp> flows,
178+
llvm::ArrayRef<PacketFlowOp> pktFlows);
179+
180+
// Place a single non-core (mem/shim) `LogicalTileOp` at the column closest
181+
// to the centroid of its placed core peers, where peers are reached by BFS
182+
// through every adjacency in `connectivityAdjacencies`. Falls back to
183+
// column 0 if the LTO has no placed core peers (e.g., a tile not mentioned
184+
// by any fifo or flow). Honours the LTO's own column pin if set.
185+
mlir::LogicalResult placeNonCoreTileByCentroid(
186+
LogicalTileOp logicalTile,
187+
llvm::ArrayRef<const Adjacency *> connectivityAdjacencies,
188+
const llvm::DenseMap<mlir::Operation *, std::pair<int, int>>
189+
&channelRequirements);
190+
185191
// Generic adjacency predicate. `pred` returns true iff `(firstPos,
186192
// secondPos)` satisfies the constraint, where `first` and `second` are
187193
// `adjacency.edges[i].first` and `.second`. Unplaced peers without pin

0 commit comments

Comments
 (0)