26 for (
auto program : device.getOps<DmaBody>()) {
27 for (Block &block : program.getDmaBody()) {
28 for (
auto start : block.getOps<DMAStartOp>()) {
30 if (start.getEndpoint())
32 usedChannels.try_emplace(std::make_tuple(getTileKey(program.getTile()),
33 start.getChannelDir(),
34 start.getChannelIndex()),
35 start.getOperation());
45 auto streamDMA = [&](Value tile, DMAChannelDir dir,
int channel,
47 streamedChannels.try_emplace(
48 std::make_tuple(getTileKey(tile), dir, channel), owner);
50 for (
auto flowOp : device.getOps<FlowOp>()) {
51 if (flowOp.getSourceBundle() == WireBundle::Core) {
52 usedStreams.try_emplace({getTileKey(flowOp.getSource()),
53 DMAChannelDir::MM2S, flowOp.getSourceChannel()},
54 StreamClaim{flowOp,
false});
56 if (flowOp.getDestBundle() == WireBundle::Core) {
57 usedStreams.try_emplace({getTileKey(flowOp.getDest()),
58 DMAChannelDir::S2MM, flowOp.getDestChannel()},
59 StreamClaim{flowOp,
false});
61 if (flowOp.getSourceBundle() == WireBundle::DMA)
62 streamDMA(flowOp.getSource(), DMAChannelDir::MM2S,
63 flowOp.getSourceChannel(), flowOp);
64 if (flowOp.getDestBundle() == WireBundle::DMA)
65 streamDMA(flowOp.getDest(), DMAChannelDir::S2MM, flowOp.getDestChannel(),
68 for (
auto packetFlow : device.getOps<PacketFlowOp>()) {
69 for (
auto source : packetFlow.getOps<PacketSourceOp>())
70 if (source.getBundle() == WireBundle::DMA)
71 streamDMA(source.getTile(), DMAChannelDir::MM2S, source.getChannel(),
73 for (
auto dest : packetFlow.getOps<PacketDestOp>())
74 if (dest.getBundle() == WireBundle::DMA)
75 streamDMA(dest.getTile(), DMAChannelDir::S2MM, dest.getChannel(),
81 device.walk([&](AIEX::DMAConfigureTaskOp task) {
82 usedChannels.try_emplace(std::make_tuple(getTileKey(task.getTile()),
84 (
int)task.getChannel()),
88 for (
auto flow : device.getOps<PacketFlowOp>()) {
89 Block &ports = flow.getPorts().front();
90 for (
auto source : ports.getOps<PacketSourceOp>())
91 if (source.getBundle() == WireBundle::Core)
92 usedStreams.try_emplace({getTileKey(source.getTile()),
93 DMAChannelDir::MM2S, source.channelIndex()},
94 StreamClaim{source,
true});
95 for (
auto dest : ports.getOps<PacketDestOp>())
96 if (dest.getBundle() == WireBundle::Core)
97 usedStreams.try_emplace({getTileKey(dest.getTile()),
98 DMAChannelDir::S2MM, dest.channelIndex()},
99 StreamClaim{dest,
true});
103 for (
auto allocOp : device.getOps<ShimDMAAllocationOp>()) {
104 (AIEDialect::ShareableWithAttrHelper(allocOp->getContext())
105 .isAttrPresent(allocOp)
108 .try_emplace(std::make_tuple(getTileKey(allocOp.getTile()),
109 allocOp.getChannelDir(),
110 (
int)allocOp.getChannelIndex()),
111 allocOp.getOperation());
116 TileLike tile, DMAChannelDir dir,
bool requiresAdjacentTileAccessChannels) {
117 std::optional<int> col = tile.tryGetCol();
118 std::optional<int> row = tile.tryGetRow();
124 : cast<LogicalTileOp>(tile.getOperation()).getCanonicalTileID();
125 int maxChannelNum = targetModel.getNumDMAChannels(
id.col,
id.row, dir);
127 if (!requiresAdjacentTileAccessChannels)
128 return maxChannelNum;
131 return std::min<int>(
133 targetModel.getMaxChannelNumForAdjacentMemTile(*col, *row));
137 bool foundPosition =
false;
138 for (
int c = 0; c < targetModel.columns(); ++c) {
139 if (col && c != *col)
141 for (
int r = 0; r < targetModel.rows(); ++r) {
142 if ((row && r != *row) ||
143 targetModel.getTileType(c, r) != tile.getTileType())
145 foundPosition =
true;
146 maxChannelNum = std::min<int>(
147 maxChannelNum, targetModel.getMaxChannelNumForAdjacentMemTile(c, r));
151 return foundPosition ? maxChannelNum : 0;
175 int channel, Operation *owner,
178 if (channel < 0 || channel >= maxChannelNum) {
181 auto key = std::make_tuple(getTileKey(tile->getResult(0)), dir, channel);
182 if (
auto *reservation = shareableChannels.lookup(key)) {
186 AIEDialect::ShareableWithAttrHelper(reservation->getContext())
187 .getAttr(reservation);
189 owner ? owner->getAttrOfType<StringAttr>(
"sym_name") : StringAttr();
190 if (!allowed || !name || llvm::none_of(allowed, [&](Attribute attr) {
191 auto symbol = dyn_cast<FlatSymbolRefAttr>(attr);
192 return symbol && symbol.getAttr() == name;
196 if (usedChannels.try_emplace(key, owner).second) {
198 sharedChannels.insert(key);
203 if (shareable && sharedChannels.contains(key))
struct TileID { friend std::ostream &operator<<(std::ostream &os, const TileID &s) { os<< "TileID("<< s.col<< ", "<< s.row<< ")"; return os; } friend std::string to_string(const TileID &s) { std::ostringstream ss; ss<< s; return ss.str(); } friend llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const TileID &s) { os<< to_string(s); return os; } inline bool operator<(const TileID &rhs) const { return std::tie(col, row)< std::tie(rhs.col, rhs.row); } bool operator==(const TileID &rhs) const { return std::tie(col, row)==std::tie(rhs.col, rhs.row); } bool operator!=(const TileID &rhs) const { return !(*this==rhs);} int col, row;} TileID