From 1864807a6906ddfc5e9a7ff678f00f44469add44 Mon Sep 17 00:00:00 2001 From: erwei-xilinx Date: Fri, 6 Sep 2024 12:56:57 -0700 Subject: [PATCH] [Ctrl Pkt Reconfig E2E] Enforcing determinism in control network routing and packet arbitration (#1752) --- include/aie/Dialect/AIE/IR/AIEOps.td | 12 +- .../AIEGenerateColumnControlOverlay.h | 12 ++ .../Dialect/AIE/Transforms/AIEPathFinder.h | 8 +- .../AIE/Transforms/AIECreatePathFindFlows.cpp | 134 +++++++++++++++--- lib/Dialect/AIE/Transforms/AIEFindFlows.cpp | 4 +- .../AIEGenerateColumnControlOverlay.cpp | 23 +-- lib/Dialect/AIE/Transforms/AIEPathFinder.cpp | 73 ++++++++-- .../Transforms/AIECreateBroadcastPacket.cpp | 2 +- python/compiler/txn2mlir.py | 11 +- .../AIE/generate_column_control_overlay.mlir | 38 ++--- test/npu-xrt/ctrl_packet_reconfig/run.lit | 1 + 11 files changed, 249 insertions(+), 69 deletions(-) diff --git a/include/aie/Dialect/AIE/IR/AIEOps.td b/include/aie/Dialect/AIE/IR/AIEOps.td index dfd757a420..20bc6e5638 100644 --- a/include/aie/Dialect/AIE/IR/AIEOps.td +++ b/include/aie/Dialect/AIE/IR/AIEOps.td @@ -639,7 +639,14 @@ def AIE_PacketFlowOp: AIE_Op<"packet_flow", [SingleBlockImplicitTerminator<"EndO let description = [{ A logical packet-switched flow between tiles. During place and route, this is replaced by MasterSets and PacketRules inside - switchboxes. + switchboxes. + + The optional attribute keep_pkt_header indicates whether each + data packet's packet header gets preserved at the flow's + destination. The optional attribute priority_route indicates + whether the packet flow is routed in priority over other flows, + so that they always get allocated with the same master, slave + ports, arbiters and master selects (msel). Example: ``` @@ -653,7 +660,8 @@ def AIE_PacketFlowOp: AIE_Op<"packet_flow", [SingleBlockImplicitTerminator<"EndO let arguments = ( ins AIEI8Attr:$ID, - OptionalAttr:$keep_pkt_header + OptionalAttr:$keep_pkt_header, + OptionalAttr:$priority_route ); let regions = (region AnyRegion:$ports); diff --git a/include/aie/Dialect/AIE/Transforms/AIEGenerateColumnControlOverlay.h b/include/aie/Dialect/AIE/Transforms/AIEGenerateColumnControlOverlay.h index 150104ed1b..47c3f5620f 100644 --- a/include/aie/Dialect/AIE/Transforms/AIEGenerateColumnControlOverlay.h +++ b/include/aie/Dialect/AIE/Transforms/AIEGenerateColumnControlOverlay.h @@ -36,4 +36,16 @@ using namespace xilinx::AIE; // Populate column control streaming interconnect overlay void populateAIEColumnControlOverlay(DeviceOp &device); +// AIE arch-specific row id to shim dma mm2s channel mapping. All shim mm2s +// channels were assumed to be available for control packet flow routing (i.e. +// not reserved by any aie.flow circuit-switched routing). +DenseMap getRowToShimChanMap(const AIETargetModel &targetModel, + WireBundle bundle); + +// AIE arch-specific tile id to controller id mapping. Users can use those +// packet ids for design but run into risk of deadlocking control packet flows. +DenseMap +getTileToControllerIdMap(bool clColumnWiseUniqueIDs, + const AIETargetModel &targetModel); + #endif \ No newline at end of file diff --git a/include/aie/Dialect/AIE/Transforms/AIEPathFinder.h b/include/aie/Dialect/AIE/Transforms/AIEPathFinder.h index d76a992cef..6546584b63 100644 --- a/include/aie/Dialect/AIE/Transforms/AIEPathFinder.h +++ b/include/aie/Dialect/AIE/Transforms/AIEPathFinder.h @@ -118,6 +118,7 @@ using PathEndPoint = struct PathEndPoint { using Flow = struct Flow { int packetGroupId; + bool isPriorityFlow; PathEndPoint src; std::vector dsts; }; @@ -181,7 +182,9 @@ class Router { virtual void initialize(int maxCol, int maxRow, const AIETargetModel &targetModel) = 0; virtual void addFlow(TileID srcCoords, Port srcPort, TileID dstCoords, - Port dstPort, bool isPacketFlow) = 0; + Port dstPort, bool isPacketFlow, + bool isPriorityFlow) = 0; + virtual void sortFlows(const int maxCol, const int maxRow) = 0; virtual bool addFixedConnection(SwitchboxOp switchboxOp) = 0; virtual std::optional> findPaths(int maxIterations) = 0; @@ -193,7 +196,8 @@ class Pathfinder : public Router { void initialize(int maxCol, int maxRow, const AIETargetModel &targetModel) override; void addFlow(TileID srcCoords, Port srcPort, TileID dstCoords, Port dstPort, - bool isPacketFlow) override; + bool isPacketFlow, bool isPriorityFlow) override; + void sortFlows(const int maxCol, const int maxRow) override; bool addFixedConnection(SwitchboxOp switchboxOp) override; std::optional> findPaths(int maxIterations) override; diff --git a/lib/Dialect/AIE/Transforms/AIECreatePathFindFlows.cpp b/lib/Dialect/AIE/Transforms/AIECreatePathFindFlows.cpp index e369cb56b1..183c255631 100644 --- a/lib/Dialect/AIE/Transforms/AIECreatePathFindFlows.cpp +++ b/lib/Dialect/AIE/Transforms/AIECreatePathFindFlows.cpp @@ -285,10 +285,13 @@ void AIEPathfinderPass::runOnPacketFlow(DeviceOp device, OpBuilder &builder) { // Map from a port and flowID to DenseMap, SmallVector> packetFlows; + DenseMap, SmallVector> ctrlPacketFlows; SmallVector, 4> slavePorts; DenseMap, int> slaveAMSels; - // Map from a port to + // Flag to keep packet header at packet flow destination DenseMap keepPktHeaderAttr; + // Map from tileID and master ports to flags labelling control packet flows + DenseMap, bool> ctrlPktFlows; for (auto tileOp : device.getOps()) { int col = tileOp.colIndex(); @@ -343,6 +346,12 @@ void AIEPathfinderPass::runOnPacketFlow(DeviceOp device, OpBuilder &builder) { std::pair{connect, flowID}) == switchboxes[currTile].end()) switchboxes[currTile].push_back({connect, flowID}); + // Assign "control packet flows" flag per switchbox, based on + // packet flow op attribute + auto ctrlPkt = pktFlowOp.getPriorityRoute(); + ctrlPktFlows[{ + {analyzer.getTile(builder, curr.col, curr.row), dest}, + flowID}] = ctrlPkt ? *ctrlPkt : false; } } } @@ -363,7 +372,10 @@ void AIEPathfinderPass::runOnPacketFlow(DeviceOp device, OpBuilder &builder) { Port destPort = conn.dst; auto sourceFlow = std::make_pair(std::make_pair(tileOp, sourcePort), flowID); - packetFlows[sourceFlow].push_back({tileOp, destPort}); + if (ctrlPktFlows[{{tileOp, destPort}, flowID}]) + ctrlPacketFlows[sourceFlow].push_back({tileOp, destPort}); + else + packetFlows[sourceFlow].push_back({tileOp, destPort}); slavePorts.push_back(sourceFlow); LLVM_DEBUG(llvm::dbgs() << "flowID " << flowID << ':' << stringifyWireBundle(sourcePort.bundle) << " " @@ -404,11 +416,18 @@ void AIEPathfinderPass::runOnPacketFlow(DeviceOp device, OpBuilder &builder) { auto getNewUniqueAmsel = [&](DenseMap, SmallVector> masterAMSels, - Operation *tileOp) { - for (int i = 0; i < numMsels; i++) - for (int a = 0; a < numArbiters; a++) - if (!masterAMSels.count({tileOp, getAmselFromArbiterIDAndMsel(a, i)})) - return getAmselFromArbiterIDAndMsel(a, i); + Operation *tileOp, bool isCtrlPkt) { + if (isCtrlPkt) { // Higher AMsel first + for (int i = numMsels - 1; i >= 0; i--) + for (int a = numArbiters - 1; a >= 0; a--) + if (!masterAMSels.count({tileOp, getAmselFromArbiterIDAndMsel(a, i)})) + return getAmselFromArbiterIDAndMsel(a, i); + } else { // Lower AMsel first + for (int i = 0; i < numMsels; i++) + for (int a = 0; a < numArbiters; a++) + if (!masterAMSels.count({tileOp, getAmselFromArbiterIDAndMsel(a, i)})) + return getAmselFromArbiterIDAndMsel(a, i); + } tileOp->emitOpError("tile op has used up all arbiter-msel combinations"); return -1; }; @@ -426,16 +445,87 @@ void AIEPathfinderPass::runOnPacketFlow(DeviceOp device, OpBuilder &builder) { return -1; }; - std::vector, SmallVector>> - sortedPacketFlows(packetFlows.begin(), packetFlows.end()); - - // To get determinsitic behaviour - std::sort(sortedPacketFlows.begin(), sortedPacketFlows.end(), - [](const auto &lhs, const auto &rhs) { - auto lhsFlowID = lhs.first.second; - auto rhsFlowID = rhs.first.second; - return lhsFlowID < rhsFlowID; + // To get determinsitic behaviour; allocate amsels for control packet flows + // before others + auto getWireBundleAsInt = [](WireBundle bundle) { + switch (bundle) { + case WireBundle::Core: + return 0; + case WireBundle::DMA: + return 1; + case WireBundle::FIFO: + return 2; + case WireBundle::South: + return 3; + case WireBundle::West: + return 4; + case WireBundle::North: + return 5; + case WireBundle::East: + return 6; + case WireBundle::PLIO: + return 7; + case WireBundle::NOC: + return 8; + case WireBundle::Trace: + return 9; + case WireBundle::Ctrl: + return 10; + } + return -1; + }; + auto getUniqueIdPerFlowPerSB = + [getWireBundleAsInt](int flowID, WireBundle srcBundle, + SmallVector dests) { + int totalNumOfWireBundles = AIE::getMaxEnumValForWireBundle(); + int currMultiplier = totalNumOfWireBundles; + int uniqueId = flowID; + uniqueId += currMultiplier + getWireBundleAsInt(srcBundle); + currMultiplier += totalNumOfWireBundles; + for (auto dst : dests) { + uniqueId += currMultiplier; + uniqueId += getWireBundleAsInt(dst.second.bundle); + currMultiplier += totalNumOfWireBundles; + } + return uniqueId; + }; + auto getSortedPacketFlows = + [&](DenseMap, SmallVector> pktFlows, + DenseMap, SmallVector> + ctrlPktFlows) { + std::vector< + std::pair, SmallVector>> + sortedpktFlows(pktFlows.begin(), pktFlows.end()); + std::sort( + sortedpktFlows.begin(), sortedpktFlows.end(), + [getUniqueIdPerFlowPerSB](const auto &lhs, const auto &rhs) { + int lhsUniqueID = getUniqueIdPerFlowPerSB( + lhs.first.second, lhs.first.first.second.bundle, lhs.second); + int rhsUniqueID = getUniqueIdPerFlowPerSB( + rhs.first.second, rhs.first.first.second.bundle, rhs.second); + return lhsUniqueID < rhsUniqueID; }); + std::vector< + std::pair, SmallVector>> + sortedctrlpktFlows(ctrlPktFlows.begin(), ctrlPktFlows.end()); + std::sort( + sortedctrlpktFlows.begin(), sortedctrlpktFlows.end(), + [getUniqueIdPerFlowPerSB](const auto &lhs, const auto &rhs) { + int lhsUniqueID = getUniqueIdPerFlowPerSB( + lhs.first.second, lhs.first.first.second.bundle, lhs.second); + int rhsUniqueID = getUniqueIdPerFlowPerSB( + rhs.first.second, rhs.first.first.second.bundle, rhs.second); + return lhsUniqueID < rhsUniqueID; + }); + sortedctrlpktFlows.insert(sortedctrlpktFlows.end(), + sortedpktFlows.begin(), sortedpktFlows.end()); + return sortedctrlpktFlows; + }; + + std::vector, SmallVector>> + sortedPacketFlows = getSortedPacketFlows(packetFlows, ctrlPacketFlows); + + packetFlows.insert(ctrlPacketFlows.begin(), ctrlPacketFlows.end()); // Check all multi-cast flows (same source, same ID). They should be // assigned the same arbiter and msel so that the flow can reach all the @@ -503,7 +593,17 @@ void AIEPathfinderPass::runOnPacketFlow(DeviceOp device, OpBuilder &builder) { if (!foundMatchedDest) { // This packet flow switchbox's output ports completely mismatches with // any existing amsel. Creating a new amsel. - amselValue = getNewUniqueAmsel(masterAMSels, tileOp); + + // Check if any of the master ports have ever been used for ctrl pkts. + // Ctrl pkt (i.e. prioritized packet flow) amsel assignment follows a + // different strategy (see method below). + bool ctrlPktAMsel = + llvm::any_of(packetFlow.second, [&](PhysPort destPhysPort) { + Port port = destPhysPort.second; + return ctrlPktFlows[{{tileOp, port}, packetFlow.first.second}]; + }); + + amselValue = getNewUniqueAmsel(masterAMSels, tileOp, ctrlPktAMsel); // Update masterAMSels with new amsel for (auto dest : packetFlow.second) { Port port = dest.second; diff --git a/lib/Dialect/AIE/Transforms/AIEFindFlows.cpp b/lib/Dialect/AIE/Transforms/AIEFindFlows.cpp index 93077cc791..1514d353a9 100644 --- a/lib/Dialect/AIE/Transforms/AIEFindFlows.cpp +++ b/lib/Dialect/AIE/Transforms/AIEFindFlows.cpp @@ -248,8 +248,8 @@ static void findFlowsFrom(TileOp op, ConnectivityAnalysis &analysis, destOp->getResult(0), destPort.bundle, destPort.channel); } else { - auto flowOp = rewriter.create(Op->getLoc(), - maskValue.value, nullptr); + auto flowOp = rewriter.create( + Op->getLoc(), maskValue.value, nullptr, nullptr); PacketFlowOp::ensureTerminator(flowOp.getPorts(), rewriter, Op->getLoc()); OpBuilder::InsertPoint ip = rewriter.saveInsertionPoint(); diff --git a/lib/Dialect/AIE/Transforms/AIEGenerateColumnControlOverlay.cpp b/lib/Dialect/AIE/Transforms/AIEGenerateColumnControlOverlay.cpp index e7ed2b4de0..2d85fc6f22 100644 --- a/lib/Dialect/AIE/Transforms/AIEGenerateColumnControlOverlay.cpp +++ b/lib/Dialect/AIE/Transforms/AIEGenerateColumnControlOverlay.cpp @@ -239,14 +239,16 @@ struct AIEGenerateColumnControlOverlayPass } } - AIE::PacketFlowOp - createPacketFlowOp(OpBuilder &builder, int &flowID, Value source, - xilinx::AIE::WireBundle sourceBundle, - uint32_t sourceChannel, Value dest, - xilinx::AIE::WireBundle destBundle, uint32_t destChannel, - mlir::BoolAttr keep_pkt_header = nullptr) { + AIE::PacketFlowOp createPacketFlowOp(OpBuilder &builder, int &flowID, + Value source, + xilinx::AIE::WireBundle sourceBundle, + uint32_t sourceChannel, Value dest, + xilinx::AIE::WireBundle destBundle, + uint32_t destChannel, + mlir::BoolAttr keep_pkt_header = nullptr, + mlir::BoolAttr ctrl_pkt_flow = nullptr) { AIE::PacketFlowOp pktFlow = builder.create( - builder.getUnknownLoc(), flowID++, keep_pkt_header); + builder.getUnknownLoc(), flowID++, keep_pkt_header, ctrl_pkt_flow); Region &r_pktFlow = pktFlow.getPorts(); Block *b_pktFlow = builder.createBlock(&r_pktFlow); builder.setInsertionPointToStart(b_pktFlow); @@ -307,6 +309,8 @@ struct AIEGenerateColumnControlOverlayPass auto availableShimChans = getAvailableShimChans(device, shimTile, shimWireBundle, isShimMM2S); SmallVector shimAllocs; + device.walk( + [&](AIE::ShimDMAAllocationOp salloc) { shimAllocs.push_back(salloc); }); for (auto tOp : ctrlTiles) { if (tOp->hasAttr("controller_id")) ctrlPktFlowID = @@ -323,16 +327,17 @@ struct AIEGenerateColumnControlOverlayPass "from routing control packets."); builder.setInsertionPointToEnd(device.getBody()); auto keep_pkt_header = builder.getBoolAttr(true); + auto ctrl_pkt_flow = builder.getBoolAttr(true); if (isShimMM2S) (void)createPacketFlowOp( builder, ctrlPktFlowID, shimTile, shimWireBundle, rowToShimChanMap[tOp.rowIndex()], tOp, ctrlWireBundle, - coreOrMemChanId, keep_pkt_header); + coreOrMemChanId, keep_pkt_header, ctrl_pkt_flow); else (void)createPacketFlowOp(builder, ctrlPktFlowID, tOp, ctrlWireBundle, coreOrMemChanId, shimTile, shimWireBundle, rowToShimChanMap[tOp.rowIndex()], - keep_pkt_header); + keep_pkt_header, ctrl_pkt_flow); // Generate shim dma alloc ops as handle for runtime sequence to pickup, // when issuing control packets diff --git a/lib/Dialect/AIE/Transforms/AIEPathFinder.cpp b/lib/Dialect/AIE/Transforms/AIEPathFinder.cpp index bb4d6a8e9c..80390a60e2 100644 --- a/lib/Dialect/AIE/Transforms/AIEPathFinder.cpp +++ b/lib/Dialect/AIE/Transforms/AIEPathFinder.cpp @@ -14,6 +14,8 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/raw_os_ostream.h" +#include "llvm/ADT/MapVector.h" + using namespace mlir; using namespace xilinx; using namespace xilinx::AIE; @@ -47,9 +49,11 @@ LogicalResult DynamicTileAnalysis::runAnalysis(DeviceOp &device) { << " -> (" << dstCoords.col << ", " << dstCoords.row << ")" << stringifyWireBundle(dstPort.bundle) << dstPort.channel << "\n"); - pathfinder->addFlow(srcCoords, srcPort, dstCoords, dstPort, false); + pathfinder->addFlow(srcCoords, srcPort, dstCoords, dstPort, + /*isPktFlow*/ false, /*isPriorityFlow*/ false); } + // Control packet flows to be routed (as prioritized routings) for (PacketFlowOp pktFlowOp : device.getOps()) { Region &r = pktFlowOp.getPorts(); Block &b = r.front(); @@ -73,11 +77,21 @@ LogicalResult DynamicTileAnalysis::runAnalysis(DeviceOp &device) { << stringifyWireBundle(dstPort.bundle) << dstPort.channel << "\n"); // todo: support many-to-one & many-to-many? - pathfinder->addFlow(srcCoords, srcPort, dstCoords, dstPort, true); + bool priorityFlow = + pktFlowOp.getPriorityRoute() + ? *pktFlowOp.getPriorityRoute() + : false; // Flows such as control packet flows are routed in + // priority, to ensure routing consistency. + pathfinder->addFlow(srcCoords, srcPort, dstCoords, dstPort, + /*isPktFlow*/ true, priorityFlow); } } } + // Sort ctrlPktFlows into a deterministic order; concat ctrlPktFlows to flows + pathfinder->sortFlows(device.getTargetModel().columns(), + device.getTargetModel().rows()); + // add existing connections so Pathfinder knows which resources are // available search all existing SwitchBoxOps for exising connections for (SwitchboxOp switchboxOp : device.getOps()) { @@ -283,11 +297,15 @@ void Pathfinder::initialize(int maxCol, int maxRow, // Add a flow from src to dst can have an arbitrary number of dst locations // due to fanout. void Pathfinder::addFlow(TileID srcCoords, Port srcPort, TileID dstCoords, - Port dstPort, bool isPacketFlow) { + Port dstPort, bool isPacketFlow, bool isPriorityFlow) { // check if a flow with this source already exists - for (auto &[_, src, dsts] : flows) { + for (auto &[_, prioritized, src, dsts] : flows) { if (src.coords == srcCoords && src.port == srcPort) { - dsts.emplace_back(PathEndPoint{dstCoords, dstPort}); + if (isPriorityFlow) { + prioritized = true; + dsts.emplace(dsts.begin(), PathEndPoint{dstCoords, dstPort}); + } else + dsts.emplace_back(PathEndPoint{dstCoords, dstPort}); return; } } @@ -299,7 +317,7 @@ void Pathfinder::addFlow(TileID srcCoords, Port srcPort, TileID dstCoords, int packetGroupId = -1; if (isPacketFlow) { bool found = false; - for (auto &[existingId, src, dsts] : flows) { + for (auto &[existingId, _, src, dsts] : flows) { if (src.coords == srcCoords && src.port == srcPort) { packetGroupId = existingId; found = true; @@ -320,10 +338,47 @@ void Pathfinder::addFlow(TileID srcCoords, Port srcPort, TileID dstCoords, } // If no existing flow was found with this source, create a new flow. flows.push_back( - Flow{packetGroupId, PathEndPoint{srcCoords, srcPort}, + Flow{packetGroupId, isPriorityFlow, PathEndPoint{srcCoords, srcPort}, std::vector{PathEndPoint{dstCoords, dstPort}}}); } +// Sort flows to (1) get deterministic routing, and (2) perform routings on +// prioritized flows before others, for routing consistency on those flows. +void Pathfinder::sortFlows(const int maxCol, const int maxRow) { + std::vector priorityFlows; + std::vector normalFlows; + for (auto f : flows) { + if (f.isPriorityFlow) + priorityFlows.push_back(f); + else + normalFlows.push_back(f); + } + std::sort(priorityFlows.begin(), priorityFlows.end(), + [maxCol, maxRow](const auto &lhs, const auto &rhs) { + int lhsUniqueID = lhs.src.coords.col; + lhsUniqueID += lhs.src.coords.row * maxCol; + int currMultiplier = maxCol * maxRow; + for (auto dest : lhs.dsts) { + lhsUniqueID += currMultiplier; + lhsUniqueID += dest.coords.col; + lhsUniqueID += dest.coords.row * maxCol; + currMultiplier += maxCol * maxRow; + } + int rhsUniqueID = rhs.src.coords.col; + rhsUniqueID += rhs.src.coords.row * maxCol; + currMultiplier = maxCol * maxRow; + for (auto dest : rhs.dsts) { + rhsUniqueID += currMultiplier; + rhsUniqueID += dest.coords.col; + rhsUniqueID += dest.coords.row * maxCol; + currMultiplier += maxCol * maxRow; + } + return lhsUniqueID < rhsUniqueID; + }); + flows = priorityFlows; + flows.insert(flows.end(), normalFlows.begin(), normalFlows.end()); +} + // Keep track of connections already used in the AIE; Pathfinder algorithm // will avoid using these. bool Pathfinder::addFixedConnection(SwitchboxOp switchboxOp) { @@ -464,7 +519,7 @@ Pathfinder::findPaths(const int maxIterations) { } // group flows based on packetGroupId - std::map> groupedFlows; + llvm::MapVector> groupedFlows; for (auto &f : flows) { if (groupedFlows.count(f.packetGroupId) == 0) { groupedFlows[f.packetGroupId] = std::vector(); @@ -514,7 +569,7 @@ Pathfinder::findPaths(const int maxIterations) { // update used_capacity for the path between them for (const auto &[_, flows] : groupedFlows) { - for (const auto &[packetGroupId, src, dsts] : flows) { + for (const auto &[packetGroupId, _, src, dsts] : flows) { // Use dijkstra to find path given current demand from the start // switchbox; find the shortest paths to each other switchbox. Output is // in the predecessor map, which must then be processed to get diff --git a/lib/Dialect/AIEX/Transforms/AIECreateBroadcastPacket.cpp b/lib/Dialect/AIEX/Transforms/AIECreateBroadcastPacket.cpp index da12c1d56f..8233efaa6c 100644 --- a/lib/Dialect/AIEX/Transforms/AIECreateBroadcastPacket.cpp +++ b/lib/Dialect/AIEX/Transforms/AIECreateBroadcastPacket.cpp @@ -66,7 +66,7 @@ struct AIEBroadcastPacketPass int flowID = bpid.IDInt(); builder.setInsertionPointAfter(broadcastpacket); PacketFlowOp pkFlow = builder.create( - builder.getUnknownLoc(), flowID, nullptr); + builder.getUnknownLoc(), flowID, nullptr, nullptr); Region &r_pkFlow = pkFlow.getPorts(); Block *b_pkFlow = builder.createBlock(&r_pkFlow); builder.setInsertionPointToStart(b_pkFlow); diff --git a/python/compiler/txn2mlir.py b/python/compiler/txn2mlir.py index c5fb49a395..88d5ded836 100755 --- a/python/compiler/txn2mlir.py +++ b/python/compiler/txn2mlir.py @@ -159,17 +159,12 @@ def sequence(arg0): data = np.array(payload.initial_value, dtype=np.int32) # Individual access cannot cross a 128-bit boundary. num_split_4s = (data.size + 3) // 4 - data_split_4 = data + data_split_4 = [data] if num_split_4s > 1: data_split_4 = np.array_split( - data[: (num_split_4s - 1) * 4], num_split_4s + data[: (num_split_4s - 1) * 4], num_split_4s - 1 ) - data_split_4 = data_split_4.append( - data[(num_split_4s - 1) * 4 :] - ) - if num_split_4s == 2: - # Individual access cannot cross a 128-bit boundary. - data_split_4 = [data[:4], data[4:]] + data_split_4.append(data[(num_split_4s - 1) * 4 :]) for d_split in data_split_4: control_packet( address=addr, diff --git a/test/dialect/AIE/generate_column_control_overlay.mlir b/test/dialect/AIE/generate_column_control_overlay.mlir index e10eaf1640..a7fe8764a3 100644 --- a/test/dialect/AIE/generate_column_control_overlay.mlir +++ b/test/dialect/AIE/generate_column_control_overlay.mlir @@ -20,18 +20,18 @@ // CHECK: aie.packet_flow(15) { // CHECK: aie.packet_source<%[[tile_0_0]], Ctrl : 0> // CHECK: aie.packet_dest<%[[tile_0_0]], South : 0> -// CHECK: } {keep_pkt_header = true} +// CHECK: }{{.*}}keep_pkt_header = true{{.*}}priority_route = true // TCTALLTILES-LABEL: module { // TCTALLTILES: %[[tile_0_0:.*]] = aie.tile(0, 0) // TCTALLTILES: %[[tile_0_1:.*]] = aie.tile(0, 1) // TCTALLTILES: aie.packet_flow(15) { // TCTALLTILES: aie.packet_source<%[[tile_0_0]], Ctrl : 0> // TCTALLTILES: aie.packet_dest<%[[tile_0_0]], South : 0> -// TCTALLTILES: } {keep_pkt_header = true} +// TCTALLTILES: }{{.*}}keep_pkt_header = true{{.*}}priority_route = true // TCTALLTILES: aie.packet_flow(26) { // TCTALLTILES: aie.packet_source<%[[tile_0_1]], Ctrl : 0> // TCTALLTILES: aie.packet_dest<%[[tile_0_0]], South : 0> -// TCTALLTILES: } {keep_pkt_header = true} +// TCTALLTILES: }{{.*}}keep_pkt_header = true{{.*}}priority_route = true // CTRLPKT-LABEL: module { // CTRLPKT: %[[tile_0_0:.*]] = aie.tile(0, 0) // CTRLPKT: %[[tile_0_1:.*]] = aie.tile(0, 1) @@ -63,11 +63,11 @@ aie.device(npu1_1col) { // CHECK: aie.packet_flow(15) { // CHECK: aie.packet_source<%[[tile_0_0]], Ctrl : 0> // CHECK: aie.packet_dest<%[[tile_0_0]], South : 0> -// CHECK: } {keep_pkt_header = true} +// CHECK: }{{.*}}keep_pkt_header = true{{.*}}priority_route = true // CHECK: aie.packet_flow(15) { // CHECK: aie.packet_source<%[[tile_1_0]], Ctrl : 0> // CHECK: aie.packet_dest<%[[tile_1_0]], South : 0> -// CHECK: } {keep_pkt_header = true} +// CHECK: }{{.*}}keep_pkt_header = true{{.*}}priority_route = true // TCTALLTILES-LABEL: module { // TCTALLTILES: %[[tile_0_0:.*]] = aie.tile(0, 0) // TCTALLTILES: %[[tile_0_1:.*]] = aie.tile(0, 1) @@ -76,19 +76,19 @@ aie.device(npu1_1col) { // TCTALLTILES: aie.packet_flow(15) { // TCTALLTILES: aie.packet_source<%[[tile_0_0]], Ctrl : 0> // TCTALLTILES: aie.packet_dest<%[[tile_0_0]], South : 0> -// TCTALLTILES: } {keep_pkt_header = true} +// TCTALLTILES: }{{.*}}keep_pkt_header = true{{.*}}priority_route = true // TCTALLTILES: aie.packet_flow(26) { // TCTALLTILES: aie.packet_source<%[[tile_0_1]], Ctrl : 0> // TCTALLTILES: aie.packet_dest<%[[tile_0_0]], South : 0> -// TCTALLTILES: } {keep_pkt_header = true} +// TCTALLTILES: }{{.*}}keep_pkt_header = true{{.*}}priority_route = true // TCTALLTILES: aie.packet_flow(15) { // TCTALLTILES: aie.packet_source<%[[tile_1_0]], Ctrl : 0> // TCTALLTILES: aie.packet_dest<%[[tile_1_0]], South : 0> -// TCTALLTILES: } {keep_pkt_header = true} +// TCTALLTILES: }{{.*}}keep_pkt_header = true{{.*}}priority_route = true // TCTALLTILES: aie.packet_flow(26) { // TCTALLTILES: aie.packet_source<%[[tile_1_1]], Ctrl : 0> // TCTALLTILES: aie.packet_dest<%[[tile_1_0]], South : 0> -// TCTALLTILES: } {keep_pkt_header = true} +// TCTALLTILES: }{{.*}}keep_pkt_header = true{{.*}}priority_route = true // CTRLPKT-LABEL: module { // CTRLPKT: %[[tile_0_0:.*]] = aie.tile(0, 0) // CTRLPKT: %[[tile_0_1:.*]] = aie.tile(0, 1) @@ -139,11 +139,11 @@ aie.device(npu1_2col) { // CHECK: aie.packet_flow(4) { // CHECK: aie.packet_source<%[[tile_0_0]], Ctrl : 0> // CHECK: aie.packet_dest<%[[tile_0_0]], South : 0> -// CHECK: } {keep_pkt_header = true} +// CHECK: }{{.*}}keep_pkt_header = true{{.*}}priority_route = true // CHECK: aie.packet_flow(5) { // CHECK: aie.packet_source<%[[tile_1_0]], Ctrl : 0> // CHECK: aie.packet_dest<%[[tile_1_0]], South : 0> -// CHECK: } {keep_pkt_header = true} +// CHECK: }{{.*}}keep_pkt_header = true{{.*}}priority_route = true // TCTALLTILES-LABEL: module { // TCTALLTILES: %[[tile_0_0:.*]] = aie.tile(0, 0) {controller_id = #aie.packet_info} // TCTALLTILES: %[[tile_0_1:.*]] = aie.tile(0, 1) {controller_id = #aie.packet_info} @@ -156,35 +156,35 @@ aie.device(npu1_2col) { // TCTALLTILES: aie.packet_flow(4) { // TCTALLTILES: aie.packet_source<%[[tile_0_0]], Ctrl : 0> // TCTALLTILES: aie.packet_dest<%[[tile_0_0]], South : 0> -// TCTALLTILES: } {keep_pkt_header = true} +// TCTALLTILES: }{{.*}}keep_pkt_header = true{{.*}}priority_route = true // TCTALLTILES: aie.packet_flow(3) { // TCTALLTILES: aie.packet_source<%[[tile_0_1]], Ctrl : 0> // TCTALLTILES: aie.packet_dest<%[[tile_0_0]], South : 0> -// TCTALLTILES: } {keep_pkt_header = true} +// TCTALLTILES: }{{.*}}keep_pkt_header = true{{.*}}priority_route = true // TCTALLTILES: aie.packet_flow(5) { // TCTALLTILES: aie.packet_source<%[[tile_0_2]], Ctrl : 0> // TCTALLTILES: aie.packet_dest<%[[tile_0_0]], South : 0> -// TCTALLTILES: } {keep_pkt_header = true} +// TCTALLTILES: }{{.*}}keep_pkt_header = true{{.*}}priority_route = true // TCTALLTILES: aie.packet_flow(1) { // TCTALLTILES: aie.packet_source<%[[tile_0_3]], Ctrl : 0> // TCTALLTILES: aie.packet_dest<%[[tile_0_0]], South : 0> -// TCTALLTILES: } {keep_pkt_header = true} +// TCTALLTILES: }{{.*}}keep_pkt_header = true{{.*}}priority_route = true // TCTALLTILES: aie.packet_flow(6) { // TCTALLTILES: aie.packet_source<%[[tile_0_4]], Ctrl : 0> // TCTALLTILES: aie.packet_dest<%[[tile_0_0]], South : 0> -// TCTALLTILES: } {keep_pkt_header = true} +// TCTALLTILES: }{{.*}}keep_pkt_header = true{{.*}}priority_route = true // TCTALLTILES: aie.packet_flow(2) { // TCTALLTILES: aie.packet_source<%[[tile_0_5]], Ctrl : 0> // TCTALLTILES: aie.packet_dest<%[[tile_0_0]], South : 0> -// TCTALLTILES: } {keep_pkt_header = true} +// TCTALLTILES: }{{.*}}keep_pkt_header = true{{.*}}priority_route = true // TCTALLTILES: aie.packet_flow(5) { // TCTALLTILES: aie.packet_source<%[[tile_1_0]], Ctrl : 0> // TCTALLTILES: aie.packet_dest<%[[tile_1_0]], South : 0> -// TCTALLTILES: } {keep_pkt_header = true} +// TCTALLTILES: }{{.*}}keep_pkt_header = true{{.*}}priority_route = true // TCTALLTILES: aie.packet_flow(7) { // TCTALLTILES: aie.packet_source<%[[tile_1_1]], Ctrl : 0> // TCTALLTILES: aie.packet_dest<%[[tile_1_0]], South : 0> -// TCTALLTILES: } {keep_pkt_header = true} +// TCTALLTILES: }{{.*}}keep_pkt_header = true{{.*}}priority_route = true // CTRLPKT-LABEL: module { // CTRLPKT: %[[tile_0_0:.*]] = aie.tile(0, 0) {controller_id = #aie.packet_info} // CTRLPKT: %[[tile_0_1:.*]] = aie.tile(0, 1) {controller_id = #aie.packet_info} diff --git a/test/npu-xrt/ctrl_packet_reconfig/run.lit b/test/npu-xrt/ctrl_packet_reconfig/run.lit index f9ab487b9c..c215cea20c 100644 --- a/test/npu-xrt/ctrl_packet_reconfig/run.lit +++ b/test/npu-xrt/ctrl_packet_reconfig/run.lit @@ -8,3 +8,4 @@ // RUN: clang %S/test.cpp -o test.exe -std=c++11 -Wall %xrt_flags -lrt -lstdc++ -lboost_program_options -lboost_filesystem // RUN: %run_on_npu ./test.exe -x aie.xclbin -k MLIR_AIE -i insts.txt | FileCheck %s // CHECK: PASS! +// XFAIL: *