Skip to content

Commit 7770667

Browse files
AndraBiscaabiscagithub-actions[bot]jgmelber
authored
ObjectFIFO pass emits packet flows (#2420)
Co-authored-by: AndraBisca <[email protected]> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Joseph Melber <[email protected]>
1 parent d98dd25 commit 7770667

File tree

24 files changed

+953
-61
lines changed

24 files changed

+953
-61
lines changed

include/aie/Dialect/AIE/IR/AIEOps.td

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1596,18 +1596,29 @@ def AIE_ShimDMAAllocationOp : AIE_Op<"shim_dma_allocation", [HasParent<"DeviceOp
15961596
AIEI64Attr:$channel_index,
15971597
AIEI64Attr:$col,
15981598
// If this is set we are using the PLIO in this ShimTile
1599-
DefaultValuedAttr<BoolAttr, "false">:$plio
1599+
DefaultValuedAttr<BoolAttr, "false">:$plio,
1600+
OptionalAttr<PacketInfoAttr>:$packet
16001601
);
16011602

16021603
let results = (outs);
16031604

16041605
let assemblyFormat = [{
1605-
$sym_name `(` $channel_dir `,` $channel_index `,` $col `)` attr-dict
1606+
$sym_name `(` $channel_dir `,` $channel_index `,` $col (`,` $packet^)? `)` attr-dict
16061607
}];
16071608

16081609
let extraClassDeclaration = [{
16091610
static ::xilinx::AIE::ShimDMAAllocationOp getForSymbol(::xilinx::AIE::DeviceOp device, ::llvm::StringRef symbol);
16101611
}];
1612+
1613+
let builders = [
1614+
OpBuilder<(ins "mlir::StringRef":$sym_name, "DMAChannelDir":$dir, "int":$channel_index,
1615+
"int":$col, "bool":$plio), [{
1616+
build($_builder, $_state, ::mlir::SymbolRefAttr::get(odsBuilder.getContext(), sym_name),
1617+
DMAChannelDirAttr::get(odsBuilder.getContext(), dir),
1618+
$_builder.getI64IntegerAttr(channel_index),
1619+
$_builder.getI64IntegerAttr(col), $_builder.getBoolAttr(plio), nullptr);
1620+
}]>
1621+
];
16111622
}
16121623

16131624
def AIE_ObjectFifoCreateOp: AIE_Op<"objectfifo", [HasParent<"DeviceOp">, Symbol]> {

include/aie/Dialect/AIE/Transforms/AIEPasses.td

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,9 @@ def AIEObjectFifoStatefulTransform : Pass<"aie-objectFifo-stateful-transform", "
203203

204204
let options = [
205205
Option<"clDynamicObjectFifos", "dynamic-objFifos", "bool", /*default=*/"false",
206-
"Flag to enable dynamic object fifo lowering in cores instead of loop unrolling.">
206+
"Flag to enable dynamic object fifo lowering in cores instead of loop unrolling.">,
207+
Option<"clPacketSwObjectFifos", "packet-sw-objFifos", "bool", /*default=*/"false",
208+
"Flag to enable aie.packetflow lowering from objectfifos.">,
207209
];
208210
}
209211

include/aie/Dialect/AIEX/IR/AIEX.td

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -968,15 +968,16 @@ def AIE_DMAConfigureTaskOp : AIEX_Op<"dma_configure_task", [HasParent<"RuntimeSe
968968
DMAChannelDir:$direction,
969969
I32Attr:$channel,
970970
DefaultValuedOptionalAttr<BoolAttr, "false">:$issue_token,
971-
DefaultValuedOptionalAttr<I32Attr, "0">:$repeat_count
971+
DefaultValuedOptionalAttr<I32Attr, "0">:$repeat_count,
972+
OptionalAttr<PacketInfoAttr>:$packet
972973
);
973974

974975
let regions = (
975976
region AnyRegion:$body
976977
);
977978

978979
let assemblyFormat = [{
979-
`(` $tile `,` $direction `,` $channel `)` regions attr-dict
980+
`(` $tile `,` $direction `,` $channel (`,` $packet^)? `)` regions attr-dict
980981
}];
981982

982983
let extraClassDeclaration = [{
@@ -991,6 +992,16 @@ def AIE_DMAConfigureTaskOp : AIEX_Op<"dma_configure_task", [HasParent<"RuntimeSe
991992

992993
let hasVerifier = 1;
993994
let hasCanonicalizeMethod = 1;
995+
996+
let builders = [
997+
OpBuilder<(ins "::mlir::Type":$result, "mlir::Value":$tile, "xilinx::AIE::DMAChannelDir":$dir, "int":$channel_index,
998+
"bool":$token, "int":$repeat), [{
999+
build($_builder, $_state, result, tile,
1000+
xilinx::AIE::DMAChannelDirAttr::get(odsBuilder.getContext(), dir),
1001+
$_builder.getI32IntegerAttr(channel_index), $_builder.getBoolAttr(token),
1002+
$_builder.getI32IntegerAttr(repeat), nullptr);
1003+
}]>
1004+
];
9941005
}
9951006

9961007
def AIE_DMAConfigureTaskForOp : AIEX_Op<"dma_configure_task_for", [HasParent<"RuntimeSequenceOp">]>, Results<(outs Index:$result)> {

lib/Dialect/AIE/Transforms/AIEObjectFifoStatefulTransform.cpp

Lines changed: 109 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -747,11 +747,16 @@ struct AIEObjectFifoStatefulTransformPass
747747
void createBd(OpBuilder &builder, LockOp acqLock, int acqMode,
748748
LockAction acqLockAction, LockOp relLock, int relMode,
749749
MyOp buff, int offset, int len, Block *succ,
750-
BDDimLayoutArrayAttr dims, BDPadLayoutArrayAttr padDimensions) {
750+
BDDimLayoutArrayAttr dims, BDPadLayoutArrayAttr padDimensions,
751+
std::optional<PacketInfoAttr> bdPacket) {
751752
if (acqLock)
752753
builder.create<UseLockOp>(builder.getUnknownLoc(), acqLock, acqLockAction,
753754
acqMode);
754-
755+
if (bdPacket) {
756+
builder.create<DMABDPACKETOp>(builder.getUnknownLoc(),
757+
bdPacket->getPktType(),
758+
bdPacket->getPktId());
759+
}
755760
if (!dims.getValue().empty() && padDimensions) {
756761
builder.create<DMABDOp>(builder.getUnknownLoc(), buff, offset, len, dims,
757762
padDimensions);
@@ -775,6 +780,7 @@ struct AIEObjectFifoStatefulTransformPass
775780
DMAChannelDir channelDir, size_t lockIndex, Block *succ,
776781
BDDimLayoutArrayAttr dims,
777782
BDPadLayoutArrayAttr padDimensions,
783+
std::optional<PacketInfoAttr> bdPacket,
778784
bool distribOrJoin = false) {
779785
LockOp acqLock;
780786
LockOp relLock;
@@ -808,26 +814,27 @@ struct AIEObjectFifoStatefulTransformPass
808814
}
809815
}
810816
createBd(builder, acqLock, acqMode, acqLockAction, relLock, relMode, buff,
811-
offset, len, succ, dims, padDimensions);
817+
offset, len, succ, dims, padDimensions, bdPacket);
812818
}
813819

814820
/// Function that either calls createAIETileDMA(), createShimDMA() or
815821
/// createMemTileDMA() based on op tile row value.
816822
void createDMA(DeviceOp &device, OpBuilder &builder, ObjectFifoCreateOp op,
817823
DMAChannelDir channelDir, int channelIndex, int lockMode,
818-
BDDimLayoutArrayAttr dims, BDPadLayoutArrayAttr pad_dims) {
824+
BDDimLayoutArrayAttr dims, BDPadLayoutArrayAttr pad_dims,
825+
std::optional<PacketInfoAttr> bdPacket) {
819826
if (op.getProducerTileOp().isShimTile()) {
820827
createShimDMA(device, builder, op, channelDir, channelIndex, lockMode,
821-
dims);
828+
dims, bdPacket);
822829
} else if (op.getProducerTileOp().isMemTile()) {
823830
BDPadLayoutArrayAttr padDims = nullptr;
824831
if (channelDir == DMAChannelDir::MM2S && pad_dims)
825832
padDims = pad_dims;
826833
createMemTileDMA(device, builder, op, channelDir, channelIndex, lockMode,
827-
dims, padDims);
834+
dims, padDims, bdPacket);
828835
} else {
829836
createAIETileDMA(device, builder, op, channelDir, channelIndex, lockMode,
830-
dims);
837+
dims, bdPacket);
831838
}
832839
}
833840

@@ -836,7 +843,8 @@ struct AIEObjectFifoStatefulTransformPass
836843
void createAIETileDMA(DeviceOp &device, OpBuilder &builder,
837844
ObjectFifoCreateOp op, DMAChannelDir channelDir,
838845
int channelIndex, int lockMode,
839-
BDDimLayoutArrayAttr dims) {
846+
BDDimLayoutArrayAttr dims,
847+
std::optional<PacketInfoAttr> bdPacket) {
840848
size_t numBlocks = op.size();
841849
if (numBlocks == 0)
842850
return;
@@ -921,8 +929,8 @@ struct AIEObjectFifoStatefulTransformPass
921929
builder.setInsertionPointToStart(curr);
922930
createBdBlock<BufferOp>(builder, target, lockMode, acqNum, relNum,
923931
buffersPerFifo[target][elemIndex], /*offset*/ 0,
924-
len, channelDir, elemIndex, succ, dims,
925-
nullptr);
932+
len, channelDir, elemIndex, succ, dims, nullptr,
933+
bdPacket);
926934
curr = succ;
927935
totalBlocks++;
928936
}
@@ -934,8 +942,8 @@ struct AIEObjectFifoStatefulTransformPass
934942
/// It uses creatBdBlock(), see there for lockMode input.
935943
void createShimDMA(DeviceOp &device, OpBuilder &builder,
936944
ObjectFifoCreateOp op, DMAChannelDir channelDir,
937-
int channelIndex, int lockMode,
938-
BDDimLayoutArrayAttr dims) {
945+
int channelIndex, int lockMode, BDDimLayoutArrayAttr dims,
946+
std::optional<PacketInfoAttr> bdPacket) {
939947
size_t numBlocks = externalBuffersPerFifo[op].size();
940948
if (numBlocks == 0)
941949
return;
@@ -998,7 +1006,7 @@ struct AIEObjectFifoStatefulTransformPass
9981006
createBdBlock<ExternalBufferOp>(builder, op, lockMode, acqNum, relNum,
9991007
externalBuffersPerFifo[op][elemIndex],
10001008
/*offset*/ 0, len, channelDir, elemIndex,
1001-
succ, dims, nullptr);
1009+
succ, dims, nullptr, bdPacket);
10021010
curr = succ;
10031011
elemIndex++;
10041012
}
@@ -1010,7 +1018,8 @@ struct AIEObjectFifoStatefulTransformPass
10101018
ObjectFifoCreateOp op, DMAChannelDir channelDir,
10111019
int channelIndex, int lockMode,
10121020
BDDimLayoutArrayAttr dims,
1013-
BDPadLayoutArrayAttr padDimensions) {
1021+
BDPadLayoutArrayAttr padDimensions,
1022+
std::optional<PacketInfoAttr> bdPacket) {
10141023
size_t numBlocks = op.size();
10151024
if (numBlocks == 0)
10161025
return;
@@ -1174,7 +1183,7 @@ struct AIEObjectFifoStatefulTransformPass
11741183
createBdBlock<BufferOp>(builder, target, lockMode, acqNum, relNum,
11751184
buffersPerFifo[target][elemIndex], offset,
11761185
lenOut, channelDir, lockIndex, succ, dims,
1177-
padDimensions, distribOrJoin);
1186+
padDimensions, bdPacket, distribOrJoin);
11781187
curr = succ;
11791188
totalBlocks++;
11801189
}
@@ -1631,12 +1640,16 @@ struct AIEObjectFifoStatefulTransformPass
16311640
void createObjectFifoAllocationInfo(OpBuilder &builder, MLIRContext *ctx,
16321641
FlatSymbolRefAttr obj_fifo, int colIndex,
16331642
DMAChannelDir channelDir,
1634-
int channelIndex, bool plio) {
1643+
int channelIndex, bool plio,
1644+
std::optional<PacketInfoAttr> packet) {
1645+
PacketInfoAttr packetInfo = nullptr;
1646+
if (packet)
1647+
packetInfo = *packet;
16351648
builder.create<ShimDMAAllocationOp>(builder.getUnknownLoc(), obj_fifo,
16361649
DMAChannelDirAttr::get(ctx, channelDir),
16371650
builder.getI64IntegerAttr(channelIndex),
16381651
builder.getI64IntegerAttr(colIndex),
1639-
builder.getBoolAttr(plio));
1652+
builder.getBoolAttr(plio), packetInfo);
16401653
}
16411654

16421655
/// Function used to verify that an objectfifo is present in at most one
@@ -1659,6 +1672,18 @@ struct AIEObjectFifoStatefulTransformPass
16591672
}
16601673
}
16611674

1675+
/// Account for already used packet IDs and return next available ID.
1676+
int getStartPacketID(DeviceOp &device) {
1677+
int packetID = 0;
1678+
for (PacketFlowOp packetflow : device.getOps<PacketFlowOp>()) {
1679+
if (packetflow.getID() > packetID) {
1680+
// compute next available ID
1681+
packetID = packetflow.getID() + 1;
1682+
}
1683+
}
1684+
return packetID;
1685+
}
1686+
16621687
/// Helper function to assign DMA channel indices for FIFOs based on
16631688
/// cross-tile conditions
16641689
void assignDMAChannelIndices(
@@ -1831,7 +1856,6 @@ struct AIEObjectFifoStatefulTransformPass
18311856
createOp.setElemNumberAttr(
18321857
builder.getI32IntegerAttr(createOp.size()));
18331858
else {
1834-
18351859
if (!createOp.getInitValues().has_value()) {
18361860

18371861
int prodMaxAcquire = findObjectFifoSize(
@@ -1845,58 +1869,74 @@ struct AIEObjectFifoStatefulTransformPass
18451869
}
18461870
}
18471871

1848-
// Analyze cross-tile buffer allocations and print results
1872+
//===------------------------------------------------------------------===//
1873+
// Create flows and tile DMAs
1874+
//===------------------------------------------------------------------===//
1875+
// Only the objectFifos we split above require DMA communication; the others
1876+
// rely on shared memory and share the same buffers.
1877+
1878+
// analyze cross-tile buffer allocations and print results
18491879
auto crossTileInfos = analyzeCrossTileFIFOBuffers();
18501880

1851-
// assign DMA channels for FIFOs
1852-
// assign the channel index for fifos that has cross-tile issues first
1853-
// use dmaAnalysis.getDMAChannelIndex() to assign index (which internally
1854-
// loop over all of available channels and assign from 0 to maximum)
1881+
// maps ends of split FIFO to DMA channels
18551882
std::map<ObjectFifoCreateOp, int> fifo_dma_channel_index;
18561883

1857-
// Assign channel indices for FIFOs with cross-tile issues first
1884+
// assign channel indices for FIFOs with cross-tile issues first
18581885
assignDMAChannelIndices(dmaAnalysis, crossTileInfos, fifo_dma_channel_index,
18591886
true);
1860-
1861-
// Then assign channel indices for FIFOs without cross-tile issues
1887+
// then assign channel indices for FIFOs without cross-tile issues
18621888
assignDMAChannelIndices(dmaAnalysis, crossTileInfos, fifo_dma_channel_index,
18631889
false);
18641890

1865-
//===------------------------------------------------------------------===//
1866-
// Create flows and tile DMAs
1867-
//===------------------------------------------------------------------===//
1868-
// Only the objectFifos we split above require DMA communication; the others
1869-
// rely on shared memory and share the same buffers.
1891+
int packetID = getStartPacketID(device);
18701892
for (auto &[producer, consumers] : splitFifos) {
18711893
int producerChanIndex = fifo_dma_channel_index[producer];
18721894
if (producerChanIndex == -1)
18731895
producer.getProducerTileOp().emitOpError(
18741896
"number of output DMA channel exceeded!");
18751897
DMAChannel producerChan = {DMAChannelDir::MM2S, producerChanIndex};
1898+
std::optional<PacketInfoAttr> bdPacket = {};
1899+
if (clPacketSwObjectFifos) {
1900+
if (packetID > 31)
1901+
device.emitOpError("max number of packet IDs reached");
1902+
bdPacket = {
1903+
AIE::PacketInfoAttr::get(ctx, /*pkt_type*/ 0, /*pkt_id*/ packetID)};
1904+
packetID++;
1905+
}
18761906
createDMA(device, builder, producer, producerChan.direction,
18771907
producerChan.channel, 0, producer.getDimensionsToStreamAttr(),
1878-
producer.getPadDimensionsAttr());
1908+
producer.getPadDimensionsAttr(), bdPacket);
18791909
// generate objectFifo allocation info
18801910
builder.setInsertionPoint(device.getBody()->getTerminator());
18811911

18821912
if (producer.getProducerTileOp().isShimTile())
18831913
createObjectFifoAllocationInfo(
18841914
builder, ctx, SymbolRefAttr::get(ctx, producer.getName()),
18851915
producer.getProducerTileOp().colIndex(), producerChan.direction,
1886-
producerChan.channel, producer.getPlio());
1916+
producerChan.channel, producer.getPlio(), bdPacket);
1917+
1918+
PacketFlowOp packetflow;
1919+
if (clPacketSwObjectFifos) {
1920+
// create packet flow
1921+
builder.setInsertionPointAfter(producer);
1922+
packetflow = builder.create<PacketFlowOp>(
1923+
builder.getUnknownLoc(),
1924+
builder.getIntegerAttr(builder.getI8Type(), bdPacket->getPktId()),
1925+
nullptr, nullptr);
1926+
{
1927+
OpBuilder::InsertionGuard g(builder);
1928+
builder.setInsertionPointToStart(
1929+
&packetflow.getRegion().emplaceBlock());
1930+
builder.create<EndOp>(builder.getUnknownLoc());
1931+
}
1932+
}
18871933

18881934
for (auto consumer : consumers) {
18891935
int consumerChanIndex = fifo_dma_channel_index[consumer];
18901936
if (consumerChanIndex == -1)
18911937
consumer.getProducerTileOp().emitOpError(
18921938
"number of input DMA channel exceeded!");
18931939
DMAChannel consumerChan = {DMAChannelDir::S2MM, consumerChanIndex};
1894-
BDDimLayoutArrayAttr consumerDims =
1895-
consumer.getDimensionsFromStreamPerConsumer()[0];
1896-
createDMA(device, builder, consumer, consumerChan.direction,
1897-
consumerChan.channel, 1, consumerDims, nullptr);
1898-
// generate objectFifo allocation info
1899-
builder.setInsertionPoint(device.getBody()->getTerminator());
19001940

19011941
// If we have PLIO then figure out the direction and make that a PLIO
19021942
if (producer.getPlio()) {
@@ -1910,19 +1950,42 @@ struct AIEObjectFifoStatefulTransformPass
19101950
producerWireType = WireBundle::DMA;
19111951
consumerWireType = WireBundle::DMA;
19121952
}
1953+
if (clPacketSwObjectFifos) {
1954+
builder.setInsertionPointToStart(&packetflow.getPorts().front());
1955+
builder.create<PacketDestOp>(builder.getUnknownLoc(),
1956+
consumer.getProducerTile(),
1957+
WireBundle::DMA, consumerChan.channel);
1958+
}
1959+
1960+
BDDimLayoutArrayAttr consumerDims =
1961+
consumer.getDimensionsFromStreamPerConsumer()[0];
1962+
createDMA(device, builder, consumer, consumerChan.direction,
1963+
consumerChan.channel, 1, consumerDims, nullptr, {});
1964+
// generate objectFifo allocation info
1965+
builder.setInsertionPoint(device.getBody()->getTerminator());
19131966

19141967
if (consumer.getProducerTileOp().isShimTile())
19151968
createObjectFifoAllocationInfo(
19161969
builder, ctx, SymbolRefAttr::get(ctx, producer.getName()),
19171970
consumer.getProducerTileOp().colIndex(), consumerChan.direction,
1918-
consumerChan.channel, producer.getPlio());
1971+
consumerChan.channel, producer.getPlio(), {});
1972+
1973+
if (!clPacketSwObjectFifos) {
1974+
// create flow
1975+
builder.setInsertionPointAfter(producer);
1976+
builder.create<FlowOp>(builder.getUnknownLoc(),
1977+
producer.getProducerTile(), producerWireType,
1978+
producerChan.channel,
1979+
consumer.getProducerTile(), consumerWireType,
1980+
consumerChan.channel);
1981+
}
1982+
}
19191983

1920-
// create flow
1921-
builder.setInsertionPointAfter(producer);
1922-
builder.create<FlowOp>(builder.getUnknownLoc(),
1923-
producer.getProducerTile(), producerWireType,
1924-
producerChan.channel, consumer.getProducerTile(),
1925-
consumerWireType, consumerChan.channel);
1984+
if (clPacketSwObjectFifos) {
1985+
builder.setInsertionPointToStart(&packetflow.getPorts().front());
1986+
builder.create<PacketSourceOp>(builder.getUnknownLoc(),
1987+
producer.getProducerTile(),
1988+
WireBundle::DMA, producerChan.channel);
19261989
}
19271990
}
19281991

0 commit comments

Comments
 (0)