diff --git a/include/aie-c/Translation.h b/include/aie-c/Translation.h index 37f075729a..e326dd7917 100644 --- a/include/aie-c/Translation.h +++ b/include/aie-c/Translation.h @@ -34,10 +34,6 @@ MLIR_CAPI_EXPORTED MlirLogicalResult aieTranslateToCDODirect(MlirOperation moduleOp, MlirStringRef workDirPath, bool bigEndian, bool emitUnified, bool cdoDebug, bool aieSim, bool xaieDebug, bool enableCores); - -MLIR_CAPI_EXPORTED MlirLogicalResult aieTranslateToTxn( - MlirOperation moduleOp, MlirStringRef outputFile, MlirStringRef workDirPath, - bool aieSim, bool xaieDebug, bool enableCores); MLIR_CAPI_EXPORTED MlirLogicalResult aieTranslateToCtrlpkt( MlirOperation moduleOp, MlirStringRef outputFile, MlirStringRef workDirPath, bool aieSim, bool xaieDebug, bool enableCores); diff --git a/include/aie/Conversion/AIEToConfiguration/AIEToConfiguration.h b/include/aie/Conversion/AIEToConfiguration/AIEToConfiguration.h index 50aa485fcf..7f937b933f 100644 --- a/include/aie/Conversion/AIEToConfiguration/AIEToConfiguration.h +++ b/include/aie/Conversion/AIEToConfiguration/AIEToConfiguration.h @@ -23,6 +23,10 @@ namespace xilinx::AIE { std::unique_ptr> createConvertAIEToTransactionPass(); +std::optional +convertTransactionBinaryToMLIR(mlir::MLIRContext *ctx, + std::vector &binary); + } // namespace xilinx::AIE #endif // AIE_CONVERSION_AIETOCONFIGURATION_AIETOCONFIGURATION_H diff --git a/include/aie/Targets/AIETargets.h b/include/aie/Targets/AIETargets.h index 761531a2a6..9a6473ddb2 100644 --- a/include/aie/Targets/AIETargets.h +++ b/include/aie/Targets/AIETargets.h @@ -64,11 +64,6 @@ AIETranslateToCDODirect(mlir::ModuleOp m, llvm::StringRef workDirPath, bool cdoDebug = false, bool aieSim = false, bool xaieDebug = false, bool enableCores = true); mlir::LogicalResult -AIETranslateToTxn(mlir::ModuleOp m, llvm::raw_ostream &output, - llvm::StringRef workDirPath, bool outputBinary = false, - bool aieSim = false, bool xaieDebug = false, - bool enableCores = true); -mlir::LogicalResult AIETranslateToControlPackets(mlir::ModuleOp m, llvm::raw_ostream &output, llvm::StringRef workDirPath, bool outputBinary = false, bool aieSim = false, @@ -84,9 +79,6 @@ mlir::LogicalResult AIETranslateToAirbin(mlir::ModuleOp module, mlir::LogicalResult AIETranslateToTargetArch(mlir::ModuleOp module, llvm::raw_ostream &output); -std::optional -AIETranslateBinaryToTxn(mlir::MLIRContext *ctx, std::vector &binary); - std::optional AIETranslateBinaryToCtrlpkt(mlir::MLIRContext *ctx, std::vector &binary); diff --git a/lib/CAPI/Translation.cpp b/lib/CAPI/Translation.cpp index 264bebf478..637eed4a2c 100644 --- a/lib/CAPI/Translation.cpp +++ b/lib/CAPI/Translation.cpp @@ -10,6 +10,7 @@ #include "aie-c/Translation.h" +#include "aie/Conversion/AIEToConfiguration/AIEToConfiguration.h" #include "aie/Dialect/AIE/IR/AIETargetModel.h" #include "aie/Targets/AIERT.h" #include "aie/Targets/AIETargets.h" @@ -83,39 +84,6 @@ MlirLogicalResult aieTranslateToCDODirect(MlirOperation moduleOp, return wrap(status); } -MlirLogicalResult aieTranslateToTxn(MlirOperation moduleOp, - MlirStringRef outputFile, - MlirStringRef workDirPath, bool aieSim, - bool xaieDebug, bool enableCores) { - ModuleOp mod = llvm::cast(unwrap(moduleOp)); - bool outputBinary = false; - - std::string errorMessage; - auto output = openOutputFile(StringRef(outputFile.data, outputFile.length), - &errorMessage); - if (!output) { - llvm::errs() << errorMessage << "\n"; - return wrap(failure()); - } - - auto status = AIETranslateToTxn( - mod, output->os(), llvm::StringRef(workDirPath.data, workDirPath.length), - outputBinary, aieSim, xaieDebug, enableCores); - - std::vector diagnostics; - ScopedDiagnosticHandler handler(mod.getContext(), [&](Diagnostic &d) { - llvm::raw_string_ostream(diagnostics.emplace_back()) - << d.getLocation() << ": " << d; - }); - - if (failed(status)) - for (const auto &diagnostic : diagnostics) - std::cerr << diagnostic << "\n"; - else - output->keep(); - return wrap(status); -} - MlirLogicalResult aieTranslateToCtrlpkt(MlirOperation moduleOp, MlirStringRef outputFile, MlirStringRef workDirPath, bool aieSim, @@ -151,7 +119,7 @@ MlirLogicalResult aieTranslateToCtrlpkt(MlirOperation moduleOp, MlirOperation aieTranslateBinaryToTxn(MlirContext ctx, MlirStringRef binary) { std::vector binaryData(binary.data, binary.data + binary.length); - auto mod = AIETranslateBinaryToTxn(unwrap(ctx), binaryData); + auto mod = convertTransactionBinaryToMLIR(unwrap(ctx), binaryData); if (!mod) return wrap(ModuleOp().getOperation()); return wrap(mod->getOperation()); diff --git a/lib/Conversion/AIEToConfiguration/AIEToConfiguration.cpp b/lib/Conversion/AIEToConfiguration/AIEToConfiguration.cpp index fbab272ff6..4b8f32419d 100644 --- a/lib/Conversion/AIEToConfiguration/AIEToConfiguration.cpp +++ b/lib/Conversion/AIEToConfiguration/AIEToConfiguration.cpp @@ -200,6 +200,108 @@ static LogicalResult generateTxn(AIERTControl &ctl, const StringRef workDirPath, return success(); } +static LogicalResult convertTransactionOpsToMLIR( + OpBuilder builder, AIE::DeviceOp device, + std::vector &operations) { + + auto loc = builder.getUnknownLoc(); + + // for each blockwrite in the binary, create a GlobalOp with the data + std::vector global_data; + for (auto &op : operations) { + if (op.cmd.Opcode != XAIE_IO_BLOCKWRITE) { + global_data.push_back(nullptr); + continue; + } + uint32_t size = op.cmd.Size / 4; + const uint32_t *d = reinterpret_cast(op.cmd.DataPtr); + std::vector data32(d, d + size); + + int id = 0; + std::string name = "blockwrite_data"; + while (device.lookupSymbol(name)) + name = "blockwrite_data_" + std::to_string(id++); + + MemRefType memrefType = MemRefType::get({size}, builder.getI32Type()); + TensorType tensorType = RankedTensorType::get({size}, builder.getI32Type()); + auto global = builder.create( + loc, name, builder.getStringAttr("private"), memrefType, + DenseElementsAttr::get(tensorType, data32), true, nullptr); + global_data.push_back(global); + } + + // create aiex.runtime_sequence + 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 + builder.setInsertionPointToStart(&seq.getBody().front()); + for (auto p : llvm::zip(operations, global_data)) { + auto op = std::get<0>(p); + memref::GlobalOp payload = std::get<1>(p); + + if (op.cmd.Opcode == XAie_TxnOpcode::XAIE_IO_WRITE) { + builder.create(loc, op.cmd.RegOff, op.cmd.Value, + nullptr, nullptr, nullptr); + } else if (op.cmd.Opcode == XAie_TxnOpcode::XAIE_IO_BLOCKWRITE) { + auto memref = builder.create(loc, payload.getType(), + payload.getName()); + builder.create( + loc, builder.getUI32IntegerAttr(op.cmd.RegOff), memref.getResult(), + nullptr, nullptr, nullptr); + } else if (op.cmd.Opcode == XAie_TxnOpcode::XAIE_IO_MASKWRITE) { + builder.create(loc, op.cmd.RegOff, op.cmd.Value, + op.cmd.Mask, nullptr, nullptr, + nullptr); + } else { + llvm::errs() << "Unhandled txn opcode: " << op.cmd.Opcode << "\n"; + return failure(); + } + } + + return success(); +} + +// Convert a transaction binary to MLIR. On success return a new ModuleOp +std::optional +xilinx::AIE::convertTransactionBinaryToMLIR(mlir::MLIRContext *ctx, + std::vector &binary) { + + // parse the binary + std::vector operations; + auto c = parseTransactionBinary(binary, operations); + if (!c) { + llvm::errs() << "Failed to parse binary\n"; + return std::nullopt; + } + int columns = *c; + + auto loc = mlir::UnknownLoc::get(ctx); + + // create a new ModuleOp and set the insertion point + auto module = ModuleOp::create(loc); + OpBuilder builder(module.getBodyRegion()); + builder.setInsertionPointToStart(module.getBody()); + + // create aie.device + std::vector devices{AIEDevice::npu1_1col, AIEDevice::npu1_2col, + AIEDevice::npu1_3col, AIEDevice::npu1_4col, + AIEDevice::npu1}; + auto device = builder.create(loc, devices[columns - 1]); + device.getRegion().emplaceBlock(); + builder.setInsertionPointToStart(device.getBody()); + + if (failed(convertTransactionOpsToMLIR(builder, device, operations))) + return std::nullopt; + + return module; +} + namespace { struct ConvertAIEToTransactionPass @@ -241,65 +343,9 @@ struct ConvertAIEToTransactionPass } OpBuilder builder(device.getBodyRegion()); - auto loc = device.getLoc(); - - // for each blockwrite in the binary, create a GlobalOp with the data - std::vector global_data; - for (auto &op : operations) { - if (op.cmd.Opcode != XAIE_IO_BLOCKWRITE) { - global_data.push_back(nullptr); - continue; - } - uint32_t size = op.cmd.Size / 4; - const uint32_t *d = reinterpret_cast(op.cmd.DataPtr); - std::vector data32(d, d + size); - - int id = 0; - std::string name = "blockwrite_data"; - while (device.lookupSymbol(name)) - name = "blockwrite_data_" + std::to_string(id++); - - MemRefType memrefType = MemRefType::get({size}, builder.getI32Type()); - TensorType tensorType = - RankedTensorType::get({size}, builder.getI32Type()); - auto global = builder.create( - loc, name, builder.getStringAttr("private"), memrefType, - DenseElementsAttr::get(tensorType, data32), true, nullptr); - global_data.push_back(global); - } - 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 - builder.setInsertionPointToStart(&seq.getBody().front()); - for (auto p : llvm::zip(operations, global_data)) { - auto op = std::get<0>(p); - memref::GlobalOp payload = std::get<1>(p); - - if (op.cmd.Opcode == XAie_TxnOpcode::XAIE_IO_WRITE) { - builder.create(loc, op.cmd.RegOff, op.cmd.Value, - nullptr, nullptr, nullptr); - } else if (op.cmd.Opcode == XAie_TxnOpcode::XAIE_IO_BLOCKWRITE) { - auto memref = builder.create( - loc, payload.getType(), payload.getName()); - builder.create( - loc, builder.getUI32IntegerAttr(op.cmd.RegOff), memref.getResult(), - nullptr, nullptr, nullptr); - } else if (op.cmd.Opcode == XAie_TxnOpcode::XAIE_IO_MASKWRITE) { - builder.create(loc, op.cmd.RegOff, op.cmd.Value, - op.cmd.Mask, nullptr, nullptr, - nullptr); - } else { - llvm::errs() << "Unhandled txn opcode: " << op.cmd.Opcode << "\n"; - return signalPassFailure(); - } - } + if (failed(convertTransactionOpsToMLIR(builder, device, operations))) + return signalPassFailure(); } }; diff --git a/lib/Targets/AIERT.cpp b/lib/Targets/AIERT.cpp index c0ec5290ad..2746b2e1c4 100644 --- a/lib/Targets/AIERT.cpp +++ b/lib/Targets/AIERT.cpp @@ -592,8 +592,7 @@ LogicalResult AIERTControl::addAieElf(uint8_t col, uint8_t row, } LogicalResult AIERTControl::addAieElfs(DeviceOp &targetOp, - const StringRef workDirPath, - bool aieSim) { + const StringRef elfPath, bool aieSim) { for (auto tileOp : targetOp.getOps()) if (tileOp.isShimNOCorPLTile()) { // Resets no needed with V2 kernel driver @@ -611,8 +610,7 @@ LogicalResult AIERTControl::addAieElfs(DeviceOp &targetOp, auto ps = std::filesystem::path::preferred_separator; if (failed(addAieElf( col, row, - (llvm::Twine(workDirPath) + std::string(1, ps) + fileName) - .str(), + (llvm::Twine(elfPath) + std::string(1, ps) + fileName).str(), aieSim))) return failure(); } diff --git a/lib/Targets/AIETargetCDODirect.cpp b/lib/Targets/AIETargetCDODirect.cpp index 17e3bacd36..b25760532a 100644 --- a/lib/Targets/AIETargetCDODirect.cpp +++ b/lib/Targets/AIETargetCDODirect.cpp @@ -379,90 +379,6 @@ LogicalResult xilinx::AIE::AIETranslateToCDODirect( aieSim, xaieDebug, enableCores); } -std::optional -xilinx::AIE::AIETranslateBinaryToTxn(mlir::MLIRContext *ctx, - std::vector &binary) { - - // parse the binary - std::vector operations; - auto c = parseTransactionBinary(binary, operations); - if (!c) { - llvm::errs() << "Failed to parse binary\n"; - return std::nullopt; - } - int columns = *c; - - auto loc = mlir::UnknownLoc::get(ctx); - - // create a new ModuleOp and set the insertion point - auto module = ModuleOp::create(loc); - OpBuilder builder(module.getBodyRegion()); - builder.setInsertionPointToStart(module.getBody()); - - // create aie.device - std::vector devices{AIEDevice::npu1_1col, AIEDevice::npu1_2col, - AIEDevice::npu1_3col, AIEDevice::npu1_4col, - AIEDevice::npu1}; - auto device = builder.create(loc, devices[columns - 1]); - device.getRegion().emplaceBlock(); - builder.setInsertionPointToStart(device.getBody()); - - // for each blockwrite in the binary, create a GlobalOp with the data - std::vector global_data; - for (auto &op : operations) { - if (op.cmd.Opcode != XAIE_IO_BLOCKWRITE) { - global_data.push_back(nullptr); - continue; - } - uint32_t size = op.cmd.Size / 4; - const uint32_t *d = reinterpret_cast(op.cmd.DataPtr); - std::vector data32(d, d + size); - - int id = 0; - std::string name = "blockwrite_data"; - while (device.lookupSymbol(name)) - name = "blockwrite_data_" + std::to_string(id++); - - MemRefType memrefType = MemRefType::get({size}, builder.getI32Type()); - TensorType tensorType = RankedTensorType::get({size}, builder.getI32Type()); - auto global = builder.create( - loc, name, builder.getStringAttr("private"), memrefType, - DenseElementsAttr::get(tensorType, data32), true, nullptr); - global_data.push_back(global); - } - - // create aiex.runtime_sequence - auto seq = builder.create(loc, nullptr); - seq.getBody().push_back(new Block); - - // create the txn ops - builder.setInsertionPointToStart(&seq.getBody().front()); - for (auto p : llvm::zip(operations, global_data)) { - auto op = std::get<0>(p); - memref::GlobalOp payload = std::get<1>(p); - - if (op.cmd.Opcode == XAie_TxnOpcode::XAIE_IO_WRITE) { - builder.create(loc, op.cmd.RegOff, op.cmd.Value, - nullptr, nullptr, nullptr); - } else if (op.cmd.Opcode == XAie_TxnOpcode::XAIE_IO_BLOCKWRITE) { - auto memref = builder.create(loc, payload.getType(), - payload.getName()); - builder.create( - loc, builder.getUI32IntegerAttr(op.cmd.RegOff), memref.getResult(), - nullptr, nullptr, nullptr); - } else if (op.cmd.Opcode == XAie_TxnOpcode::XAIE_IO_MASKWRITE) { - builder.create(loc, op.cmd.RegOff, op.cmd.Value, - op.cmd.Mask, nullptr, nullptr, - nullptr); - } else { - llvm::errs() << "Unhandled txn opcode: " << op.cmd.Opcode << "\n"; - return std::nullopt; - } - } - - return module; -} - std::optional xilinx::AIE::AIETranslateBinaryToCtrlpkt(mlir::MLIRContext *ctx, std::vector &binary) { @@ -572,29 +488,6 @@ xilinx::AIE::AIETranslateBinaryToCtrlpkt(mlir::MLIRContext *ctx, return module; } -LogicalResult xilinx::AIE::AIETranslateToTxn(ModuleOp m, - llvm::raw_ostream &output, - llvm::StringRef workDirPath, - bool outputBinary, bool enableSim, - bool xaieDebug, bool enableCores) { - std::vector bin; - auto result = - translateToTxn(m, bin, workDirPath, enableSim, xaieDebug, enableCores); - if (failed(result)) - return result; - - if (outputBinary) { - output.write(reinterpret_cast(bin.data()), bin.size()); - return success(); - } - - auto new_module = AIETranslateBinaryToTxn(m.getContext(), bin); - if (!new_module) - return failure(); - new_module->print(output); - return success(); -} - LogicalResult xilinx::AIE::AIETranslateToControlPackets( ModuleOp m, llvm::raw_ostream &output, llvm::StringRef workDirPath, bool outputBinary, bool enableSim, bool xaieDebug, bool enableCores) { diff --git a/lib/Targets/AIETargets.cpp b/lib/Targets/AIETargets.cpp index 79a2749d46..b13ce23845 100644 --- a/lib/Targets/AIETargets.cpp +++ b/lib/Targets/AIETargets.cpp @@ -343,23 +343,6 @@ void registerAIETranslations() { cdoXaieDebug, cdoEnableCores); }, registerDialects); - TranslateFromMLIRRegistration registrationCDOWithTxn( - "aie-generate-txn", - "Generate TXN configuration. Use --aie-output-binary to select between " - "mlir (default) and binary output", - [](ModuleOp module, raw_ostream &output) { - SmallString<128> workDirPath_; - if (workDirPath.getNumOccurrences() == 0) { - if (llvm::sys::fs::current_path(workDirPath_)) - llvm::report_fatal_error( - "couldn't get cwd to use as work-dir-path"); - } else - workDirPath_ = workDirPath.getValue(); - LLVM_DEBUG(llvm::dbgs() << "work-dir-path: " << workDirPath_ << "\n"); - return AIETranslateToTxn(module, output, workDirPath_, outputBinary, - cdoAieSim, cdoXaieDebug, cdoEnableCores); - }, - registerDialects); TranslateFromMLIRRegistration registrationNPU( "aie-npu-instgen", "Translate npu instructions to binary", [](ModuleOp module, raw_ostream &output) { diff --git a/python/AIEMLIRModule.cpp b/python/AIEMLIRModule.cpp index 2d71249e72..fa3d214dac 100644 --- a/python/AIEMLIRModule.cpp +++ b/python/AIEMLIRModule.cpp @@ -107,23 +107,6 @@ PYBIND11_MODULE(_aie, m) { "emit_unified"_a = false, "cdo_debug"_a = false, "aiesim"_a = false, "xaie_debug"_a = false, "enable_cores"_a = true); - m.def( - "generate_txn", - [](MlirOperation op, const std::string &outputFile, - const std::string &workDirPath, bool aieSim, bool xaieDebug, - bool enableCores) { - mlir::python::CollectDiagnosticsToStringScope scope( - mlirOperationGetContext(op)); - if (mlirLogicalResultIsFailure( - aieTranslateToTxn(op, {outputFile.data(), outputFile.size()}, - {workDirPath.data(), workDirPath.size()}, - aieSim, xaieDebug, enableCores))) - throw py::value_error("Failed to generate txn binary because: " + - scope.takeMessage()); - }, - "module"_a, "output_file"_a, "work_dir_path"_a, "aiesim"_a = false, - "xaie_debug"_a = false, "enable_cores"_a = true); - m.def( "generate_ctrlpkt", [](MlirOperation op, const std::string &outputFile, diff --git a/python/dialects/aie.py b/python/dialects/aie.py index 09f2451e30..c810aab0a6 100644 --- a/python/dialects/aie.py +++ b/python/dialects/aie.py @@ -22,7 +22,6 @@ aie_llvm_link, generate_bcf, generate_cdo, - generate_txn, generate_ctrlpkt, generate_xaie, generate_control_packets,