diff --git a/include/aie/Conversion/Passes.td b/include/aie/Conversion/Passes.td index 87d69f2698..1ef348b8d7 100644 --- a/include/aie/Conversion/Passes.td +++ b/include/aie/Conversion/Passes.td @@ -69,6 +69,10 @@ def ConvertAIEToTransaction : Pass<"convert-aie-to-transaction", let constructor = "xilinx::AIE::createConvertAIEToTransactionPass()"; let dependentDialects = ["xilinx::AIE::AIEDialect", "xilinx::AIEX::AIEXDialect"]; + let options = [ + Option<"clElfDir", "elf-dir", "std::string", /*default=*/"", + "Where to find ELF files">, + ]; } #endif // AIE_CONVERSION_PASSES diff --git a/include/aie/Targets/AIETargets.h b/include/aie/Targets/AIETargets.h index 4dd1581591..530026fde9 100644 --- a/include/aie/Targets/AIETargets.h +++ b/include/aie/Targets/AIETargets.h @@ -35,13 +35,16 @@ mlir::LogicalResult AIETranslateShimSolution(mlir::ModuleOp module, mlir::LogicalResult AIETranslateGraphXPE(mlir::ModuleOp module, llvm::raw_ostream &); mlir::LogicalResult AIETranslateToNPU(mlir::ModuleOp module, - llvm::raw_ostream &output); -mlir::LogicalResult AIETranslateToNPU(mlir::ModuleOp, std::vector &); + llvm::raw_ostream &output, + llvm::StringRef sequenceName = ""); +mlir::LogicalResult AIETranslateToNPU(mlir::ModuleOp, std::vector &, + llvm::StringRef sequenceName = ""); mlir::LogicalResult -AIETranslateControlPacketsToUI32Vec(mlir::ModuleOp module, - llvm::raw_ostream &output); +AIETranslateControlPacketsToUI32Vec(mlir::ModuleOp module, llvm::raw_ostream &output, + llvm::StringRef sequenceName = ""); mlir::LogicalResult -AIETranslateControlPacketsToUI32Vec(mlir::ModuleOp, std::vector &); +AIETranslateControlPacketsToUI32Vec(mlir::ModuleOp, std::vector &, + llvm::StringRef sequenceName = ""); mlir::LogicalResult AIETranslateToLdScript(mlir::ModuleOp module, llvm::raw_ostream &output, int tileCol, int tileRow); diff --git a/lib/Conversion/AIEToTransaction/AIEToTransaction.cpp b/lib/Conversion/AIEToTransaction/AIEToTransaction.cpp index 4002181498..67586c4a8f 100644 --- a/lib/Conversion/AIEToTransaction/AIEToTransaction.cpp +++ b/lib/Conversion/AIEToTransaction/AIEToTransaction.cpp @@ -223,9 +223,8 @@ struct ConvertAIEToTransactionPass // start collecting transations XAie_StartTransaction(&ctl.devInst, XAIE_TRANSACTION_DISABLE_AUTO_FLUSH); - std::string workDirPath = "workdir"; auto result = - generateTxn(ctl, workDirPath, device, aieSim, true, true, true); + generateTxn(ctl, clElfDir, device, aieSim, true, true, true); if (failed(result)) return signalPassFailure(); @@ -236,14 +235,12 @@ struct ConvertAIEToTransactionPass // parse the binary data std::vector operations; - auto c = parseTransactionBinary(txn_data, operations); - if (!c) { + if (!parseTransactionBinary(txn_data, operations)) { llvm::errs() << "Failed to parse binary\n"; return signalPassFailure(); } - // int columns = *c; - OpBuilder builder(device); + OpBuilder builder(device.getBodyRegion()); auto loc = device.getLoc(); // for each blockwrite in the binary, create a GlobalOp with the data @@ -271,7 +268,12 @@ struct ConvertAIEToTransactionPass global_data.push_back(global); } - auto seq = builder.create(loc, nullptr); + int id = 0; + std::string seq_name = "configure"; + while (device.lookupSymbol(seq_name)) + seq_name = "configure" + std::to_string(id++); + StringAttr seq_sym_name = builder.getStringAttr(seq_name); + auto seq = builder.create(loc, seq_sym_name); seq.getBody().push_back(new Block); // create the txn ops diff --git a/lib/Dialect/AIEX/IR/AIEXDialect.cpp b/lib/Dialect/AIEX/IR/AIEXDialect.cpp index 89c94f3bfe..e0e547a09d 100644 --- a/lib/Dialect/AIEX/IR/AIEXDialect.cpp +++ b/lib/Dialect/AIEX/IR/AIEXDialect.cpp @@ -532,16 +532,6 @@ LogicalResult AIEX::RuntimeSequenceOp::verify() { (*this)->emitOpError() << "must be inside AIE device operation."; return failure(); } - auto seq_ops = device.getOps(); - if (std::distance(seq_ops.begin(), seq_ops.end()) > 1) { - auto err = device.emitOpError() - << "Cannot have more than one runtime sequence per device."; - for (auto it = seq_ops.begin(); it != seq_ops.end(); ++it) { - AIEX::RuntimeSequenceOp seq_op = *it; - err.attachNote(seq_op.getLoc()) << "Sequence operation definition here."; - } - return failure(); - } return success(); } diff --git a/lib/Targets/AIETargetNPU.cpp b/lib/Targets/AIETargetNPU.cpp index 0439c427e5..823b7e8b19 100644 --- a/lib/Targets/AIETargetNPU.cpp +++ b/lib/Targets/AIETargetNPU.cpp @@ -187,7 +187,8 @@ void appendBlockWrite(std::vector &instructions, NpuBlockWriteOp op) { LogicalResult xilinx::AIE::AIETranslateToNPU(ModuleOp module, - std::vector &instructions) { + std::vector &instructions, + StringRef sequenceName) { auto words = reserveAndGetTail(instructions, 4); @@ -206,8 +207,10 @@ xilinx::AIE::AIETranslateToNPU(ModuleOp module, words[1] = (numMemTileRows << 8) | numCols; auto sequenceOps = deviceOp.getOps(); - for (auto f : sequenceOps) { - Block &entry = f.getBody().front(); + for (auto seq : sequenceOps) { + if (sequenceName.size() && sequenceName != seq.getSymName()) + continue; + Block &entry = seq.getBody().front(); for (auto &o : entry) { llvm::TypeSwitch(&o) .Case([&](auto op) { @@ -240,9 +243,10 @@ xilinx::AIE::AIETranslateToNPU(ModuleOp module, } LogicalResult xilinx::AIE::AIETranslateToNPU(ModuleOp module, - raw_ostream &output) { + raw_ostream &output, + StringRef sequenceName) { std::vector instructions; - auto r = AIETranslateToNPU(module, instructions); + auto r = AIETranslateToNPU(module, instructions, sequenceName); if (failed(r)) return r; for (auto w : instructions) @@ -250,13 +254,16 @@ LogicalResult xilinx::AIE::AIETranslateToNPU(ModuleOp module, return success(); } -LogicalResult xilinx::AIE::AIETranslateControlPacketsToUI32Vec( - ModuleOp module, std::vector &instructions) { - +LogicalResult +xilinx::AIE::AIETranslateControlPacketsToUI32Vec(ModuleOp module, + std::vector &instructions, + StringRef sequenceName) { DeviceOp deviceOp = *module.getOps().begin(); auto sequenceOps = deviceOp.getOps(); - for (auto f : sequenceOps) { - Block &entry = f.getBody().front(); + for (auto seq : sequenceOps) { + if (sequenceName.size() && sequenceName != seq.getSymName()) + continue; + Block &entry = seq.getBody().front(); for (auto &o : entry) { llvm::TypeSwitch(&o).Case([&](auto op) { uint32_t size = 0; @@ -291,10 +298,10 @@ LogicalResult xilinx::AIE::AIETranslateControlPacketsToUI32Vec( } LogicalResult -xilinx::AIE::AIETranslateControlPacketsToUI32Vec(ModuleOp module, - raw_ostream &output) { +xilinx::AIE::AIETranslateControlPacketsToUI32Vec(ModuleOp module, raw_ostream &output, + StringRef sequenceName) { std::vector instructions; - auto r = AIETranslateControlPacketsToUI32Vec(module, instructions); + auto r = AIETranslateControlPacketsToUI32Vec(module, instructions, sequenceName); if (failed(r)) return r; for (auto w : instructions) diff --git a/lib/Targets/AIETargets.cpp b/lib/Targets/AIETargets.cpp index 7638c45aaf..6180285905 100644 --- a/lib/Targets/AIETargets.cpp +++ b/lib/Targets/AIETargets.cpp @@ -159,6 +159,11 @@ void registerAIETranslations() { "Select binary (true) or text (false) output for supported " "translations. e.g. aie-npu-instgen, aie-ctrlpkt-to-bin")); + static llvm::cl::opt sequenceName( + "aie-sequence-name", llvm::cl::init(""), + llvm::cl::desc( + "Specify the name of the aiex.runtime_sequence to translate")); + TranslateFromMLIRRegistration registrationMMap( "aie-generate-mmap", "Generate AIE memory map", [](ModuleOp module, raw_ostream &output) { @@ -360,14 +365,14 @@ void registerAIETranslations() { [](ModuleOp module, raw_ostream &output) { if (outputBinary == true) { std::vector instructions; - auto r = AIETranslateToNPU(module, instructions); + auto r = AIETranslateToNPU(module, instructions, sequenceName); if (failed(r)) return r; output.write(reinterpret_cast(instructions.data()), instructions.size() * sizeof(uint32_t)); return success(); } - return AIETranslateToNPU(module, output); + return AIETranslateToNPU(module, output, sequenceName); }, registerDialects); TranslateFromMLIRRegistration registrationCtrlPkt( @@ -375,7 +380,7 @@ void registerAIETranslations() { [](ModuleOp module, raw_ostream &output) { if (outputBinary == true) { std::vector instructions; - auto r = AIETranslateControlPacketsToUI32Vec(module, instructions); + auto r = AIETranslateControlPacketsToUI32Vec(module, instructions, sequenceName); if (failed(r)) return r; output.write(reinterpret_cast(instructions.data()), @@ -398,9 +403,10 @@ void registerAIETranslations() { } else workDirPath_ = workDirPath.getValue(); LLVM_DEBUG(llvm::dbgs() << "work-dir-path: " << workDirPath_ << "\n"); - return AIETranslateToControlPackets(module, output, workDirPath_, - outputBinary, cdoAieSim, - cdoXaieDebug, cdoEnableCores); + // return AIETranslateToControlPackets(module, output, workDirPath_, + // outputBinary, cdoAieSim, + // cdoXaieDebug, cdoEnableCores); + return AIETranslateToControlPackets(module, output, sequenceName); }, registerDialects); } diff --git a/python/compiler/aiecc/main.py b/python/compiler/aiecc/main.py index dddb65a910..3cae7cf9dc 100644 --- a/python/compiler/aiecc/main.py +++ b/python/compiler/aiecc/main.py @@ -564,7 +564,6 @@ async def process_cdo(self): generate_cdo(input_physical.operation, self.tmpdirname) async def process_txn(self): - from aie.dialects.aie import generate_txn with Context(), Location.unknown(): for elf in glob.glob("*.elf"): @@ -577,11 +576,16 @@ async def process_txn(self): shutil.copy(elf_map, self.tmpdirname) except shutil.SameFileError: pass - input_physical = Module.parse( - await read_file_async(self.prepend_tmp("input_physical.mlir")) + await self.do_call( + None, + [ + "aie-opt", + "--convert-aie-to-transaction=elf-dir=" + self.tmpdirname + "", + self.prepend_tmp("input_physical.mlir"), + "-o", + self.prepend_tmp("input_physical_txn.mlir"), + ], ) - txn_file = os.path.join(self.tmpdirname, "txn.mlir") - generate_txn(input_physical.operation, txn_file, self.tmpdirname) async def process_ctrlpkt(self): from aie.dialects.aie import generate_ctrlpkt diff --git a/test/npu-xrt/add_one_two_txn/run.lit b/test/npu-xrt/add_one_two_txn/run.lit index 9410178e12..1d282d9861 100644 --- a/test/npu-xrt/add_one_two_txn/run.lit +++ b/test/npu-xrt/add_one_two_txn/run.lit @@ -6,6 +6,6 @@ // RUN: clang %S/test.cpp -o test.exe -std=c++11 -Wall %xrt_flags -lrt -lstdc++ -lboost_program_options -lboost_filesystem // RUN: %python aiecc.py --xclbin-kernel-name=ADDONE --xclbin-kernel-id=0x901 --xclbin-instance-name=ADDONEINST --no-aiesim --aie-generate-cdo --aie-generate-npu --no-compile-host --xclbin-name=add_one.xclbin --npu-insts-name=add_one_insts.txt %S/aie1.mlir // RUN: %python aiecc.py --no-aiesim --aie-generate-txn --aie-generate-npu --no-compile-host --npu-insts-name=add_two_insts.txt %S/aie2.mlir -// RUN: aie-translate -aie-npu-instgen -aie-output-binary=true aie2.mlir.prj/txn.mlir -o add_two_cfg.bin +// RUN: aie-translate -aie-npu-instgen -aie-output-binary=true -aie-sequence-name=configure aie2.mlir.prj/input_physical_txn.mlir -o add_two_cfg.bin // RUN: %run_on_npu ./test.exe -x add_one.xclbin -i add_one_insts.txt -c add_two_cfg.bin -j add_two_insts.txt | FileCheck %s // CHECK: PASS!