Skip to content

Commit

Permalink
remove aie to txn from aie-translate and python biding
Browse files Browse the repository at this point in the history
  • Loading branch information
fifield committed Sep 11, 2024
1 parent f3b5221 commit 2dc6884
Show file tree
Hide file tree
Showing 11 changed files with 113 additions and 253 deletions.
4 changes: 0 additions & 4 deletions include/aie-c/Translation.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ namespace xilinx::AIE {
std::unique_ptr<mlir::OperationPass<xilinx::AIE::DeviceOp>>
createConvertAIEToTransactionPass();

std::optional<mlir::ModuleOp>
convertTransactionBinaryToMLIR(mlir::MLIRContext *ctx, std::vector<uint8_t> &binary);

} // namespace xilinx::AIE

#endif // AIE_CONVERSION_AIETOCONFIGURATION_AIETOCONFIGURATION_H
8 changes: 0 additions & 8 deletions include/aie/Targets/AIETargets.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,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,
Expand All @@ -83,9 +78,6 @@ mlir::LogicalResult AIETranslateToAirbin(mlir::ModuleOp module,
mlir::LogicalResult AIETranslateToTargetArch(mlir::ModuleOp module,
llvm::raw_ostream &output);

std::optional<mlir::ModuleOp>
AIETranslateBinaryToTxn(mlir::MLIRContext *ctx, std::vector<uint8_t> &binary);

std::optional<mlir::ModuleOp>
AIETranslateBinaryToCtrlpkt(mlir::MLIRContext *ctx,
std::vector<uint8_t> &binary);
Expand Down
36 changes: 2 additions & 34 deletions lib/CAPI/Translation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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<ModuleOp>(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<std::string> 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,
Expand Down Expand Up @@ -151,7 +119,7 @@ MlirLogicalResult aieTranslateToCtrlpkt(MlirOperation moduleOp,

MlirOperation aieTranslateBinaryToTxn(MlirContext ctx, MlirStringRef binary) {
std::vector<uint8_t> 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());
Expand Down
165 changes: 105 additions & 60 deletions lib/Conversion/AIEToConfiguration/AIEToConfiguration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,108 @@ generateTxn(AIERTControl &ctl, const StringRef workDirPath, DeviceOp &targetOp,
return success();
}

static LogicalResult convertTransactionOpsToMLIR(
OpBuilder builder, AIE::DeviceOp device,
std::vector<TransactionBinaryOperation> &operations) {

auto loc = builder.getUnknownLoc();

// for each blockwrite in the binary, create a GlobalOp with the data
std::vector<memref::GlobalOp> 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<const uint32_t *>(op.cmd.DataPtr);
std::vector<uint32_t> 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<memref::GlobalOp>(
loc, name, builder.getStringAttr("private"), memrefType,
DenseElementsAttr::get<uint32_t>(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<AIEX::RuntimeSequenceOp>(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<AIEX::NpuWrite32Op>(loc, op.cmd.RegOff, op.cmd.Value,
nullptr, nullptr, nullptr);
} else if (op.cmd.Opcode == XAie_TxnOpcode::XAIE_IO_BLOCKWRITE) {
auto memref = builder.create<memref::GetGlobalOp>(loc, payload.getType(),
payload.getName());
builder.create<AIEX::NpuBlockWriteOp>(
loc, builder.getUI32IntegerAttr(op.cmd.RegOff), memref.getResult(),
nullptr, nullptr, nullptr);
} else if (op.cmd.Opcode == XAie_TxnOpcode::XAIE_IO_MASKWRITE) {
builder.create<AIEX::NpuMaskWrite32Op>(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<mlir::ModuleOp>
xilinx::AIE::convertTransactionBinaryToMLIR(mlir::MLIRContext *ctx,
std::vector<uint8_t> &binary) {

// parse the binary
std::vector<TransactionBinaryOperation> 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<AIEDevice> devices{AIEDevice::npu1_1col, AIEDevice::npu1_2col,
AIEDevice::npu1_3col, AIEDevice::npu1_4col,
AIEDevice::npu1};
auto device = builder.create<DeviceOp>(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
Expand All @@ -223,8 +325,7 @@ struct ConvertAIEToTransactionPass
// start collecting transations
XAie_StartTransaction(&ctl.devInst, XAIE_TRANSACTION_DISABLE_AUTO_FLUSH);

auto result =
generateTxn(ctl, clElfDir, device, aieSim, true, true, true);
auto result = generateTxn(ctl, clElfDir, device, aieSim, true, true, true);
if (failed(result))
return signalPassFailure();

Expand All @@ -241,65 +342,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<memref::GlobalOp> 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<const uint32_t *>(op.cmd.DataPtr);
std::vector<uint32_t> 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<memref::GlobalOp>(
loc, name, builder.getStringAttr("private"), memrefType,
DenseElementsAttr::get<uint32_t>(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<AIEX::RuntimeSequenceOp>(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<AIEX::NpuWrite32Op>(loc, op.cmd.RegOff, op.cmd.Value,
nullptr, nullptr, nullptr);
} else if (op.cmd.Opcode == XAie_TxnOpcode::XAIE_IO_BLOCKWRITE) {
auto memref = builder.create<memref::GetGlobalOp>(
loc, payload.getType(), payload.getName());
builder.create<AIEX::NpuBlockWriteOp>(
loc, builder.getUI32IntegerAttr(op.cmd.RegOff), memref.getResult(),
nullptr, nullptr, nullptr);
} else if (op.cmd.Opcode == XAie_TxnOpcode::XAIE_IO_MASKWRITE) {
builder.create<AIEX::NpuMaskWrite32Op>(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();
}
};

Expand Down
6 changes: 2 additions & 4 deletions lib/Targets/AIERT.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<TileOp>())
if (tileOp.isShimNOCorPLTile()) {
// Resets no needed with V2 kernel driver
Expand All @@ -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();
}
Expand Down
Loading

0 comments on commit 2dc6884

Please sign in to comment.