73 DeviceOp device = getOperation();
74 const auto &targetModel = device.getTargetModel();
75 auto *ctx = device->getContext();
76 auto loc = device->getLoc();
78 if (targetModel.getTargetArch() == AIEArch::AIE1)
81 SmallVector<Operation *> erased;
82 auto sequenceOps = device.getOps<AIE::RuntimeSequenceOp>();
83 for (
auto f : sequenceOps) {
85 auto controlPacketOps = f.getOps<AIEX::NpuControlPacketOp>();
86 if (controlPacketOps.empty())
93 auto newSeq = AIE::RuntimeSequenceOp::create(
94 builder, loc, f.getSymNameAttr(), BoolAttr{}, f.getTraceBufferAttr(),
95 f.getTraceSlicesAttr(), f.getScratchpadParametersAttr());
96 newSeq.getBody().push_back(
new Block);
99 for (
auto arg : f.getBody().getArguments()) {
101 auto newArg = newSeq.getBody().addArgument(arg.getType(), arg.getLoc());
103 arg.replaceAllUsesWith(newArg);
105 mapping.map(arg, newArg);
109 auto ctrlPktMemrefType = MemRefType::get(
110 ShapedType::kDynamic, IntegerType::get(ctx, 32),
nullptr,
nullptr);
111 auto newBlockArg = newSeq.getBody().addArgument(ctrlPktMemrefType, loc);
113 builder.setInsertionPointToStart(&newSeq.getBody().front());
120 std::string shimDmaAllocName;
124 std::vector<BatchInfo> batches;
126 int64_t ddrOffset = 0;
127 Block &entry = f.getBody().front();
130 bool new_batch =
true;
131 for (Operation &o : entry) {
132 auto ctrlPktOp = dyn_cast<NpuControlPacketOp>(&o);
139 int col = ctrlPktOp.getColumnFromAddr();
140 int row = ctrlPktOp.getRowFromAddr();
143 int64_t ctrlPktSize = 2;
144 if (
auto data = ctrlPktOp.getData())
145 ctrlPktSize += data->size();
148 bool batchable = ctrlPktOp.getOpcode() == 0;
149 if (targetModel.getTargetArch() == AIEArch::AIE2p && batchable &&
150 !new_batch && batches.back().tileId ==
TileID{col, row}) {
152 batches.back().totalSize += ctrlPktSize;
155 ShimDMAAllocationOp alloc = getCtrlPktShimAlloc(device, col);
157 ctrlPktOp.emitOpError(
"column ")
159 <<
" has no control packet shim DMA allocation; run "
160 "-aie-generate-column-control-overlay with "
161 "configuration=true, then -aie-import-overlay first";
162 return signalPassFailure();
164 batches.push_back({
TileID{col, row}, ddrOffset, ctrlPktSize,
165 alloc.getSymName().str(),
166 static_cast<int>(alloc.getChannelIndex()), &o});
168 new_batch = !batchable;
169 ddrOffset += ctrlPktSize;
173 auto batchIt = batches.begin();
175 for (Operation &o : entry) {
176 auto ctrlPktOp = dyn_cast<NpuControlPacketOp>(&o);
178 builder.clone(o, mapping);
183 if (batchIt == batches.end())
187 if (batchIt->first != &o)
190 int col = ctrlPktOp.getColumnFromAddr();
193 const std::vector<int64_t> staticOffsets = {0, 0, 0,
194 batchIt->startOffset};
195 const std::vector<int64_t> staticSizes = {1, 1, 1, batchIt->totalSize};
196 const std::vector<int64_t> staticStrides = {0, 0, 0, 1};
198 SymbolRefAttr metadata =
199 SymbolRefAttr::get(builder.getContext(), batchIt->shimDmaAllocName);
200 NpuDmaMemcpyNdOp::create(builder, loc, newBlockArg, staticOffsets,
201 staticSizes, staticStrides, metadata,
210 AIEX::NpuSyncOp::create(builder, loc, shimCol, shimRow, dir, chan,
218 for (
auto *e : erased)