From d5f0c3c79fbd3c18d2a423462b21021fed4309ad Mon Sep 17 00:00:00 2001 From: max Date: Wed, 6 Mar 2024 21:54:48 -0600 Subject: [PATCH 1/9] squashed and cherry-picked from #1104 [wip] use transaction API rename add transaction bindings --- include/aie-c/Translation.h | 15 + include/aie/Targets/AIERTX.h | 189 ++++++++ lib/CAPI/Translation.cpp | 35 +- lib/Targets/AIERTX.cpp | 457 ++++++++++++++++++ lib/Targets/AIETargetCDODirect.cpp | 738 +---------------------------- lib/Targets/CMakeLists.txt | 26 +- python/AIERTXModule.cpp | 50 ++ python/CMakeLists.txt | 20 + python/aiertx.py | 5 + test/python/aiertx_bindings.py | 20 + 10 files changed, 815 insertions(+), 740 deletions(-) create mode 100644 include/aie/Targets/AIERTX.h create mode 100644 lib/Targets/AIERTX.cpp create mode 100644 python/AIERTXModule.cpp create mode 100644 python/aiertx.py create mode 100644 test/python/aiertx_bindings.py diff --git a/include/aie-c/Translation.h b/include/aie-c/Translation.h index d51cd21499..c8ed3eeba7 100644 --- a/include/aie-c/Translation.h +++ b/include/aie-c/Translation.h @@ -10,6 +10,7 @@ #include "mlir-c/IR.h" #include "mlir-c/Support.h" +#include "mlir/CAPI/Wrap.h" #ifdef __cplusplus extern "C" { @@ -41,6 +42,20 @@ MLIR_CAPI_EXPORTED MlirLogicalResult aieTranslateToCtrlpkt( MLIR_CAPI_EXPORTED MlirOperation aieTranslateBinaryToTxn(MlirContext ctx, MlirStringRef binary); +struct AieRtxControl { + void *ptr; +}; +using AieRtxControl = struct AieRtxControl; + +MLIR_CAPI_EXPORTED AieRtxControl getAieRtxControl(size_t partitionStartCol, + size_t partitionNumCols); +MLIR_CAPI_EXPORTED void freeAieRtxControl(AieRtxControl aieCtl); +MLIR_CAPI_EXPORTED void aieRtxStartTransaction(AieRtxControl aieCtl); +MLIR_CAPI_EXPORTED void aieRtxDmaUpdateBdAddr(AieRtxControl aieCtl, int col, + int row, size_t addr, + size_t bdId); +MLIR_CAPI_EXPORTED void aieRtxExportSerializedTransaction(AieRtxControl aieCtl); + #ifdef __cplusplus } #endif diff --git a/include/aie/Targets/AIERTX.h b/include/aie/Targets/AIERTX.h new file mode 100644 index 0000000000..ba04460447 --- /dev/null +++ b/include/aie/Targets/AIERTX.h @@ -0,0 +1,189 @@ +// +// Created by maksim on 3/6/24. +// + +#ifndef AIE_AIERTX_H +#define AIE_AIERTX_H + +#include "aie/Dialect/AIE/IR/AIEDialect.h" +#include "aie/Dialect/AIE/IR/AIEEnums.h" +#include "aie/Dialect/AIE/IR/AIETargetModel.h" + +extern "C" { +#include "xaiengine/xaiegbl_defs.h" +// above needs to go first for u32, u64 typedefs +#include "xaiengine/xaie_txn.h" +#include "xaiengine/xaiegbl.h" +} +#include "llvm/Support/raw_ostream.h" + +#include +#include +#include + +#define AIERC_STR(x) x, #x +static const std::map AIERCTOSTR = { + {AIERC_STR(XAIE_OK)}, + {AIERC_STR(XAIE_ERR)}, + {AIERC_STR(XAIE_INVALID_DEVICE)}, + {AIERC_STR(XAIE_INVALID_RANGE)}, + {AIERC_STR(XAIE_INVALID_ARGS)}, + {AIERC_STR(XAIE_INVALID_TILE)}, + {AIERC_STR(XAIE_ERR_STREAM_PORT)}, + {AIERC_STR(XAIE_INVALID_DMA_TILE)}, + {AIERC_STR(XAIE_INVALID_BD_NUM)}, + {AIERC_STR(XAIE_ERR_OUTOFBOUND)}, + {AIERC_STR(XAIE_INVALID_DATA_MEM_ADDR)}, + {AIERC_STR(XAIE_INVALID_ELF)}, + {AIERC_STR(XAIE_CORE_STATUS_TIMEOUT)}, + {AIERC_STR(XAIE_INVALID_CHANNEL_NUM)}, + {AIERC_STR(XAIE_INVALID_LOCK)}, + {AIERC_STR(XAIE_INVALID_DMA_DIRECTION)}, + {AIERC_STR(XAIE_INVALID_PLIF_WIDTH)}, + {AIERC_STR(XAIE_INVALID_LOCK_ID)}, + {AIERC_STR(XAIE_INVALID_LOCK_VALUE)}, + {AIERC_STR(XAIE_LOCK_RESULT_FAILED)}, + {AIERC_STR(XAIE_INVALID_DMA_DESC)}, + {AIERC_STR(XAIE_INVALID_ADDRESS)}, + {AIERC_STR(XAIE_FEATURE_NOT_SUPPORTED)}, + {AIERC_STR(XAIE_INVALID_BURST_LENGTH)}, + {AIERC_STR(XAIE_INVALID_BACKEND)}, + {AIERC_STR(XAIE_INSUFFICIENT_BUFFER_SIZE)}, + {AIERC_STR(XAIE_ERR_MAX)}}; + +static const std::map AIETXNOPCODETOSTR = { + {AIERC_STR(XAIE_IO_WRITE)}, + {AIERC_STR(XAIE_IO_BLOCKWRITE)}, + {AIERC_STR(XAIE_IO_BLOCKSET)}, + {AIERC_STR(XAIE_IO_MASKWRITE)}, + {AIERC_STR(XAIE_IO_MASKPOLL)}, + {AIERC_STR(XAIE_CONFIG_SHIMDMA_BD)}, + {AIERC_STR(XAIE_CONFIG_SHIMDMA_DMABUF_BD)}, + {AIERC_STR(XAIE_IO_CUSTOM_OP_BEGIN)}, + {AIERC_STR(XAIE_IO_CUSTOM_OP_TCT)}, + {AIERC_STR(XAIE_IO_CUSTOM_OP_DDR_PATCH)}, + {AIERC_STR(XAIE_IO_CUSTOM_OP_NEXT)}, + {AIERC_STR(XAIE_IO_CUSTOM_OP_MAX)}}; +#undef AIERC_STR + +static const std::map + WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE = { + {xilinx::AIE::WireBundle::Core, StrmSwPortType::CORE}, + {xilinx::AIE::WireBundle::DMA, StrmSwPortType::DMA}, + // missing control from StrmSwPortType + {xilinx::AIE::WireBundle::FIFO, StrmSwPortType::FIFO}, + {xilinx::AIE::WireBundle::South, StrmSwPortType::SOUTH}, + {xilinx::AIE::WireBundle::West, StrmSwPortType::WEST}, + {xilinx::AIE::WireBundle::North, StrmSwPortType::NORTH}, + {xilinx::AIE::WireBundle::East, StrmSwPortType::EAST}, + // missing PLIO from WireBundle + // missing NOC from WireBundle + {xilinx::AIE::WireBundle::Trace, StrmSwPortType::TRACE}, +}; + +// https://stackoverflow.com/a/32230306 +template +llvm::raw_ostream &showAIEXRTArgs(llvm::raw_ostream &out, const char *label, + H1 &&value) { + return out << label << "=" << std::forward

(value); +} + +template +llvm::raw_ostream &showAIEXRTArgs(llvm::raw_ostream &out, const char *label, + H1 &&value, T &&...rest) { + const char *pcomma = strchr(label, ','); + return showAIEXRTArgs(out.write(label, pcomma - label) + << "=" << std::forward

(value) << ',', + pcomma + 1, std::forward(rest)...); +} + +llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const XAie_LocType &loc); + +llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const XAie_Lock &lock); + +llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const XAie_Packet &packet); + +#define SHOW_AIERTX_ARGS(os, ...) showAIEXRTArgs(os, #__VA_ARGS__, __VA_ARGS__) + +// So that we can use the pattern if(auto r = TRY_XAIE_API...) { // r is nonzero +// } +static_assert(XAIE_OK == 0); + +#define TRY_XAIE_API_FATAL_ERROR(API, ...) \ + do { \ + LLVM_DEBUG(llvm::dbgs() << "trying XAIE API: " << #API << " with args: "); \ + LLVM_DEBUG(SHOW_AIERTX_ARGS(llvm::dbgs(), __VA_ARGS__)); \ + LLVM_DEBUG(llvm::dbgs() << "\n"); \ + if (auto r = API(__VA_ARGS__)) \ + llvm::report_fatal_error(llvm::Twine(#API " failed with ") + \ + AIERCTOSTR.at(r)); \ + } while (0) + +#define TRY_XAIE_API_EMIT_ERROR(OP, API, ...) \ + do { \ + LLVM_DEBUG(llvm::dbgs() << "trying XAIE API: " << #API << " with args: "); \ + LLVM_DEBUG(SHOW_AIERTX_ARGS(llvm::dbgs(), __VA_ARGS__)); \ + LLVM_DEBUG(llvm::dbgs() << "\n"); \ + if (auto r = API(__VA_ARGS__)) \ + return OP.emitOpError() << #API " failed with " << AIERCTOSTR.at(r); \ + } while (0) + +#define TRY_XAIE_API_LOGICAL_RESULT(API, ...) \ + do { \ + LLVM_DEBUG(llvm::dbgs() << "trying XAIE API: " << #API << " with args: "); \ + LLVM_DEBUG(SHOW_AIERTX_ARGS(llvm::dbgs(), __VA_ARGS__)); \ + LLVM_DEBUG(llvm::dbgs() << "\n"); \ + if (auto r = API(__VA_ARGS__)) { \ + llvm::errs() << #API " failed with " << AIERCTOSTR.at(r); \ + return failure(); \ + } \ + } while (0) + +#define XAIE_BASE_ADDR 0x40000000 +#define XAIE_COL_SHIFT 25 +#define XAIE_ROW_SHIFT 20 +#define XAIE_SHIM_ROW 0 +#define XAIE_MEM_TILE_ROW_START 1 +#define XAIE_PARTITION_BASE_ADDR 0x0 + +#define NPI_ADDR 0x0 +#define NUM_LOCKS 16 +#define EVEN_BD_NUM_START 0 +#define ODD_BD_NUM_START 24 +#define MEM_TILE_LOCK_ID_INCR 64 +#define BASE_ADDR_A_INCR 0x80000 + +namespace xilinx::AIE { +struct AIERTXControl { + XAie_Config configPtr; + XAie_DevInst devInst; + const AIETargetModel &targetModel; + + AIERTXControl(size_t partitionStartCol, size_t partitionNumCols, + const xilinx::AIE::AIETargetModel &tm); + + mlir::LogicalResult setIOBackend(bool aieSim, bool xaieDebug); + mlir::LogicalResult configureBdInBlock(XAie_DmaDesc &dmaTileBd, + mlir::Block &block, + XAie_LocType &tileLoc, int bdId, + std::optional nextBdId); + mlir::LogicalResult pushToBdQueueAndEnable(mlir::Operation &op, + XAie_LocType &tileLoc, int chNum, + const DMAChannelDir &channelDir, + int bdId, int repeatCount); + mlir::LogicalResult configureLocksAndBd(mlir::Block &block, + XAie_LocType tileLoc); + mlir::LogicalResult initLocks(DeviceOp &targetOp); + mlir::LogicalResult configureSwitches(DeviceOp &targetOp); + mlir::LogicalResult enableCoresInDevice(DeviceOp &targetOp); + mlir::LogicalResult configureLocksInBdBlock(XAie_DmaDesc &dmaTileBd, + mlir::Block &block, + XAie_LocType &tileLoc); + void startTransaction(); + void dmaUpdateBdAddr(int col, int row, size_t addr, size_t bdId); + void exportSerializedTransaction(); +}; + +} // namespace xilinx::AIE + +#endif // AIE_AIERTX_H diff --git a/lib/CAPI/Translation.cpp b/lib/CAPI/Translation.cpp index f101e7e221..561bc903f4 100644 --- a/lib/CAPI/Translation.cpp +++ b/lib/CAPI/Translation.cpp @@ -9,6 +9,9 @@ //===----------------------------------------------------------------------===// #include "aie-c/Translation.h" + +#include "aie/Dialect/AIE/IR/AIETargetModel.h" +#include "aie/Targets/AIERTX.h" #include "aie/Targets/AIETargets.h" #include "mlir-c/IR.h" @@ -21,7 +24,6 @@ #include "mlir/Target/LLVMIR/Export.h" #include "llvm/IR/LLVMContext.h" -#include "llvm/IR/Module.h" #include "llvm/Support/Casting.h" #include "llvm/Support/ToolOutputFile.h" #include "llvm/Support/raw_ostream.h" @@ -223,3 +225,34 @@ MlirStringRef aieLLVMLink(MlirStringRef *modules, int nModules) { ll.copy(cStr, ll.size()); return mlirStringRefCreate(cStr, ll.size()); } + +DEFINE_C_API_PTR_METHODS(AieRtxControl, xilinx::AIE::AIERTXControl) + +AieRtxControl getAieRtxControl(size_t partitionStartCol, + size_t partitionNumCols) { + IPUTargetModel targetModel; + AIERTXControl *ctl = + new AIERTXControl(partitionStartCol, partitionNumCols, targetModel); + return wrap(ctl); +} + +void freeAieRtxControl(AieRtxControl aieCtl) { + AIERTXControl *ctl = unwrap(aieCtl); + delete ctl; +} + +void aieRtxDmaUpdateBdAddr(AieRtxControl aieCtl, int col, int row, size_t addr, + size_t bdId) { + AIERTXControl *ctl = unwrap(aieCtl); + ctl->dmaUpdateBdAddr(col, row, addr, bdId); +} + +void aieRtxStartTransaction(AieRtxControl aieCtl) { + AIERTXControl *ctl = unwrap(aieCtl); + ctl->startTransaction(); +} + +void aieRtxExportSerializedTransaction(AieRtxControl aieCtl) { + AIERTXControl *ctl = unwrap(aieCtl); + ctl->exportSerializedTransaction(); +} \ No newline at end of file diff --git a/lib/Targets/AIERTX.cpp b/lib/Targets/AIERTX.cpp new file mode 100644 index 0000000000..028f329ada --- /dev/null +++ b/lib/Targets/AIERTX.cpp @@ -0,0 +1,457 @@ +//===- AIERTX.cpp -----------------------------------------------*- C++ -*-===// +// +// Copyright (C) 2023, Advanced Micro Devices, Inc. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "aie/Targets/AIERTX.h" + +#include "mlir/Support/LogicalResult.h" + +extern "C" { +#include "xaiengine/xaie_core.h" +#include "xaiengine/xaie_dma.h" +#include "xaiengine/xaie_interrupt.h" +#include "xaiengine/xaie_locks.h" +#include "xaiengine/xaie_plif.h" +#include "xaiengine/xaie_ss.h" +#include "xaiengine/xaiegbl.h" +#include "xaiengine/xaiegbl_defs.h" +} + +using namespace mlir; + +#define DEBUG_TYPE "aie-aiertx" + +llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const XAie_LocType &loc) { + os << "XAie_LocType(col: " << std::to_string(loc.Col) + << ", row: " << std::to_string(loc.Row) << ")"; + return os; +} + +llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const XAie_Lock &lock) { + os << "XAie_Lock(id: " << std::to_string(lock.LockId) + << ", val: " << std::to_string(lock.LockVal) << ")"; + return os; +} + +llvm::raw_ostream &operator<<(llvm::raw_ostream &os, + const XAie_Packet &packet) { + os << "XAie_Packet(id: " << std::to_string(packet.PktId) + << ", type: " << std::to_string(packet.PktType) << ")"; + return os; +} + +namespace xilinx::AIE { +AIERTXControl::AIERTXControl(size_t partitionStartCol, size_t partitionNumCols, + const AIETargetModel &tm) + : targetModel(tm) { + configPtr = XAie_Config{ + /*AieGen*/ XAIE_DEV_GEN_AIEML, + /*BaseAddr*/ XAIE_BASE_ADDR, + /*ColShift*/ XAIE_COL_SHIFT, + /*RowShift*/ XAIE_ROW_SHIFT, + /*NumRows*/ static_cast(tm.rows()), + /*NumCols*/ static_cast(tm.columns()), + /*ShimRowNum*/ XAIE_SHIM_ROW, + /*MemTileRowStart*/ XAIE_MEM_TILE_ROW_START, + /*MemTileNumRows*/ static_cast(tm.getNumMemTileRows()), + /*AieTileRowStart*/ + static_cast(XAIE_MEM_TILE_ROW_START + tm.getNumMemTileRows()), + /*AieTileNumRows*/ + static_cast(tm.rows() - tm.getNumMemTileRows() - 1), + /*PartProp*/ {}, + /*Backend*/ XAIE_IO_BACKEND_CDO}; + XAie_InstDeclare(_devInst, &configPtr); + devInst = _devInst; + TRY_XAIE_API_FATAL_ERROR(XAie_SetupPartitionConfig, &devInst, + XAIE_PARTITION_BASE_ADDR, partitionStartCol, + partitionNumCols); + TRY_XAIE_API_FATAL_ERROR(XAie_CfgInitialize, &devInst, &configPtr); + TRY_XAIE_API_FATAL_ERROR(XAie_UpdateNpiAddr, &devInst, NPI_ADDR); +} + +LogicalResult AIERTXControl::setIOBackend(bool aieSim, bool xaieDebug) { + // Quoting: The instance of a device must be always declared using this + // macro. In the future, the same macro will be expanded to + // allocate more memory from the user application for resource + // management. + if (aieSim) { + TRY_XAIE_API_FATAL_ERROR(XAie_SetIOBackend, &devInst, XAIE_IO_BACKEND_SIM); + } else if (xaieDebug) + TRY_XAIE_API_FATAL_ERROR(XAie_SetIOBackend, &devInst, + XAIE_IO_BACKEND_DEBUG); + else + TRY_XAIE_API_FATAL_ERROR(XAie_SetIOBackend, &devInst, XAIE_IO_BACKEND_CDO); + return success(); +} + +LogicalResult AIERTXControl::configureLocksInBdBlock(XAie_DmaDesc &dmaTileBd, + Block &block, + XAie_LocType &tileLoc) { + LLVM_DEBUG(llvm::dbgs() << "\nstart configuring bds\n"); + std::optional acqValue, relValue, acqLockId, relLockId; + bool acqEn; + // switch (lock->getAc) + for (auto op : block.getOps()) { + // Only dyn_cast if you are going to check if it was of the type + // expected; if you aren't checking use cast instead as it will at + // least assert in debug mode with an easier to understand error than + // dereferencing. + LockOp lock = cast(op.getLock().getDefiningOp()); + switch (op.getAction()) { + case LockAction::Acquire: + case LockAction::AcquireGreaterEqual: + acqEn = op.getAcqEn(); + acqLockId = lock.getLockIDValue(); + acqValue = op.getLockValue(); + if (op.acquireGE()) + acqValue.value() = -acqValue.value(); + break; + case LockAction::Release: + relLockId = lock.getLockIDValue(); + relValue = op.getLockValue(); + break; + } + } + + assert(acqValue && relValue && acqLockId && relLockId && + "expected both use_lock(acquire) and use_lock(release) with bd"); + + if (targetModel.isMemTile(tileLoc.Col, tileLoc.Row)) { + if (acqLockId) + acqLockId.value() += MEM_TILE_LOCK_ID_INCR; + if (relLockId) + relLockId.value() += MEM_TILE_LOCK_ID_INCR; + } + + // no RelEn in the arch spec even though the API requires you to set it? + bool relEn = false; + XAie_Lock acqLock = XAie_LockInit(acqLockId.value(), acqValue.value()); + XAie_Lock relLock = XAie_LockInit(relLockId.value(), relValue.value()); + TRY_XAIE_API_EMIT_ERROR((*block.getOps().begin()), + dmaTileBd.DmaMod->SetLock, &dmaTileBd, acqLock, + relLock, acqEn, relEn); + return success(); +} + +LogicalResult AIERTXControl::configureBdInBlock(XAie_DmaDesc &dmaTileBd, + Block &block, + XAie_LocType &tileLoc, int bdId, + std::optional nextBdId) { + std::optional packetType; + std::optional packetID; + auto maybePacketOps = block.getOps(); + if (!maybePacketOps.empty()) { + assert(llvm::range_size(maybePacketOps) == 1 && + "expected only one dma_bd_packet"); + auto packetOp = *maybePacketOps.begin(); + packetType = packetOp.getPacketType(); + packetID = packetOp.getPacketID(); + } + + auto bdOp = *block.getOps().begin(); + + if (targetModel.isShimNOCTile(tileLoc.Col, tileLoc.Row)) { + // write them out like this so they show up with names in debug prints + size_t smid = 0; + size_t burstLen = 16; // (10):BLEN=16 (256Byte) (corresponds to + // 0x800000000 from targetipu) + size_t qOs = 0; + size_t cache = 0; + size_t secure = 0; + TRY_XAIE_API_EMIT_ERROR(bdOp, XAie_DmaSetAxi, &dmaTileBd, smid, burstLen, + qOs, cache, secure); + } + + // deref here because this is a const iter and the various getters below + // aren't const (even though they probably should be...) + // StringRef FifoMode = disable; // FIXME: when to enable FIFO mode? + ShapedType bufferType = bdOp.getBuffer().getType().cast<::mlir::MemRefType>(); + int bytes = bufferType.getElementTypeBitWidth() / 8; + int baseAddr = 0; + if (!targetModel.isShimNOCTile(tileLoc.Col, tileLoc.Row)) { + auto bufferOp = cast(bdOp.getBuffer().getDefiningOp()); + assert(bufferOp.getAddress().has_value() && "buffer must have address"); + baseAddr = bufferOp.getAddress().value(); + if (targetModel.isMemTile(tileLoc.Col, tileLoc.Row)) + baseAddr += BASE_ADDR_A_INCR; + } + + std::optional> dims = bdOp.getDimensions(); + int lenInBytes = bdOp.getLenValue() * bytes; + int basePlusOffset = baseAddr + bdOp.getOffsetValue(); + if (!dims) { + TRY_XAIE_API_EMIT_ERROR(bdOp, XAie_DmaSetAddrLen, &dmaTileBd, + basePlusOffset, lenInBytes); + } else { + XAie_DmaTensor dmaTileBdTensor = {}; + dmaTileBdTensor.NumDim = dims->size(); + dmaTileBdTensor.Dim = static_cast( + calloc(dims->size(), sizeof(XAie_DmaDimDesc))); + if (!dmaTileBdTensor.Dim) + return bdOp.emitError("couldn't allocate array of XAie_DmaDimDesc"); + // TODO(max): rethink this? + for (size_t i = 0; i < dims->size(); i++) { + // Pass down dimensions in reverse order; in the MLIR, this allows + // us to specify step sizes/wraps in the same order as we would + // access a multi-dim C array, with the highest dimension first. + int j = dims->size() - i - 1; + // Assume AIE-ML architecture; we assert this above + // TODO(max): no we don't + dmaTileBdTensor.Dim[j].AieMlDimDesc = {dims.value()[i].getStride(), + dims.value()[i].getSize()}; + } + // TODO: Probably need special handling for NOC + // TODO: Might need to adjust step sizes / wraps by -1 + TRY_XAIE_API_EMIT_ERROR(bdOp, XAie_DmaSetMultiDimAddr, &dmaTileBd, + &dmaTileBdTensor, basePlusOffset, lenInBytes); + } + + if (nextBdId) { + auto enableNextBd = 1; + TRY_XAIE_API_EMIT_ERROR(bdOp, XAie_DmaSetNextBd, &dmaTileBd, + nextBdId.value(), enableNextBd); + } + + if (packetID) { + assert(packetType && "must have packetType with packetID"); + if (bdOp.getLenValue() == 0) + return bdOp.emitOpError( + "For MM2S channels, if Buffer_Length=0 then Enable_Packet must be " + "set to 0, otherwise behavior is undefined (3.7.8 arch spec)"); + TRY_XAIE_API_EMIT_ERROR( + bdOp, XAie_DmaSetPkt, &dmaTileBd, + XAie_PacketInit(packetID.value(), packetType.value())); + } + TRY_XAIE_API_EMIT_ERROR(bdOp, XAie_DmaEnableBd, &dmaTileBd); + TRY_XAIE_API_EMIT_ERROR(bdOp, XAie_DmaWriteBd, &devInst, &dmaTileBd, tileLoc, + bdId); + LLVM_DEBUG(llvm::dbgs() << "\nend configuring bds\n"); + return success(); +}; + +LogicalResult AIERTXControl::pushToBdQueueAndEnable( + Operation &op, XAie_LocType &tileLoc, int chNum, + const DMAChannelDir &channelDir, int bdId, int repeatCount) { + XAie_DmaDirection direction = + channelDir == DMAChannelDir::S2MM ? DMA_S2MM : DMA_MM2S; + auto enTokenIssue = tileLoc.Row == 0 && direction == DMA_S2MM; + // in english repeat_count==0 means "do it once" and don't repeat but + // libxaie treats repeat_count=1 as do it once. + repeatCount += 1; + TRY_XAIE_API_EMIT_ERROR(op, XAie_DmaChannelSetStartQueue, &devInst, tileLoc, + chNum, direction, bdId, repeatCount, enTokenIssue); + TRY_XAIE_API_EMIT_ERROR(op, XAie_DmaChannelEnable, &devInst, tileLoc, chNum, + direction); + return success(); +}; + +LogicalResult AIERTXControl::configureLocksAndBd(Block &block, + XAie_LocType tileLoc) { + DMABDOp bd = *block.getOps().begin(); + assert(bd.getBdId().has_value() && + "DMABDOp must have assigned bd_id; did you forget to run " + "aie-assign-bd-ids?"); + XAie_DmaDesc dmaTileBd; + TRY_XAIE_API_EMIT_ERROR(bd, XAie_DmaDescInit, &devInst, &dmaTileBd, tileLoc); + if (!block.getOps().empty() && + failed(configureLocksInBdBlock(dmaTileBd, block, tileLoc))) + return failure(); + if (!block.getOps().empty() && + failed(configureBdInBlock(dmaTileBd, block, tileLoc, bd.getBdId().value(), + bd.getNextBdId()))) + return failure(); + return success(); +} + +LogicalResult AIERTXControl::initLocks(DeviceOp &targetOp) { + for (auto tileOp : targetOp.getOps()) { + auto tileLoc = XAie_TileLoc(tileOp.colIndex(), tileOp.rowIndex()); + if (!tileOp.isShimTile() && tileOp.getCoreOp()) { + TRY_XAIE_API_EMIT_ERROR(tileOp, XAie_CoreReset, &devInst, tileLoc); + TRY_XAIE_API_EMIT_ERROR(tileOp, XAie_CoreUnreset, &devInst, tileLoc); + // Set locks to zero + for (uint8_t l = 0; l < NUM_LOCKS; l++) { + auto locInit = XAie_LockInit(l, 0); + TRY_XAIE_API_EMIT_ERROR(tileOp, XAie_LockSetValue, &devInst, tileLoc, + locInit); + } + } + } + + // Set locks with explicit initializers + targetOp.walk([&](LockOp lockOp) { + if (lockOp.getLockID() && lockOp.getInit()) { + auto tileLoc = XAie_TileLoc(lockOp.getTileOp().colIndex(), + lockOp.getTileOp().rowIndex()); + auto locInit = XAie_LockInit(*lockOp.getLockID(), *lockOp.getInit()); + TRY_XAIE_API_FATAL_ERROR(XAie_LockSetValue, &devInst, tileLoc, locInit); + } else + LLVM_DEBUG(llvm::dbgs() + << "lock op missing either id or init" << lockOp << "\n"); + }); + return success(); +} + +LogicalResult AIERTXControl::configureSwitches(DeviceOp &targetOp) { + + // StreamSwitch (switchbox) configuration + for (auto switchboxOp : targetOp.getOps()) { + int32_t col = switchboxOp.colIndex(); + int32_t row = switchboxOp.rowIndex(); + XAie_LocType tileLoc = XAie_TileLoc(col, row); + assert(targetOp.getDevice() == AIEDevice::ipu && + "Only IPU currently supported"); + if (row == 0) { + // FIXME hack for TCT routing + // TODO Support both channels + auto slvPortNum = 0; + auto mstrPortNum = 0; + TRY_XAIE_API_EMIT_ERROR(switchboxOp, XAie_StrmConnCctEnable, &devInst, + tileLoc, CTRL, slvPortNum, SOUTH, mstrPortNum); + } + + Block &b = switchboxOp.getConnections().front(); + for (auto connectOp : b.getOps()) + TRY_XAIE_API_EMIT_ERROR( + switchboxOp, XAie_StrmConnCctEnable, &devInst, tileLoc, + WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at(connectOp.getSourceBundle()), + connectOp.sourceIndex(), + WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at(connectOp.getDestBundle()), + connectOp.destIndex()); + + for (auto connectOp : b.getOps()) { + int mask = 0; + int arbiter = -1; + + for (auto val : connectOp.getAmsels()) { + AMSelOp amsel = cast(val.getDefiningOp()); + arbiter = amsel.arbiterIndex(); + int msel = amsel.getMselValue(); + mask |= (1 << msel); + } + + bool isdma = connectOp.getDestBundle() == WireBundle::DMA; + // assume a connection going south from row zero gets wired to shimdma + // by a shimmux. TODO: fix the assumption + if (!isdma && (switchboxOp.rowIndex() == 0)) + isdma = connectOp.getDestBundle() == WireBundle::South; + // Flag for overriding DROP_HEADER. TODO: Formalize this in tablegen + isdma &= !connectOp->hasAttr("keep_pkt_header"); + auto dropHeader = + isdma ? XAIE_SS_PKT_DROP_HEADER : XAIE_SS_PKT_DONOT_DROP_HEADER; + TRY_XAIE_API_EMIT_ERROR( + connectOp, XAie_StrmPktSwMstrPortEnable, &devInst, tileLoc, + WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at(connectOp.getDestBundle()), + connectOp.destIndex(), dropHeader, arbiter, mask); + } + + for (auto connectOp : b.getOps()) { + int slot = 0; + Block &block = connectOp.getRules().front(); + for (auto slotOp : block.getOps()) { + AMSelOp amselOp = cast(slotOp.getAmsel().getDefiningOp()); + int arbiter = amselOp.arbiterIndex(); + int msel = amselOp.getMselValue(); + TRY_XAIE_API_EMIT_ERROR( + connectOp, XAie_StrmPktSwSlavePortEnable, &devInst, tileLoc, + WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at(connectOp.getSourceBundle()), + connectOp.sourceIndex()); + auto packetInit = XAie_PacketInit(slotOp.valueInt(), /*PktType*/ 0); + // TODO Need to better define packet id,type used here + TRY_XAIE_API_EMIT_ERROR( + connectOp, XAie_StrmPktSwSlaveSlotEnable, &devInst, tileLoc, + WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at(connectOp.getSourceBundle()), + connectOp.sourceIndex(), slot, packetInit, slotOp.maskInt(), msel, + arbiter); + slot++; + } + } + } + + for (auto muxOp : targetOp.getOps()) { + // NOTE ShimMux always connects from the south as directions are + // defined relative to the tile stream switch. + auto tileLoc = + XAie_TileLoc(muxOp.getTileOp().getCol(), muxOp.getTileOp().getRow()); + Block &b = muxOp.getConnections().front(); + for (auto connectOp : b.getOps()) { + // demux! + if (connectOp.getSourceBundle() == WireBundle::North) + TRY_XAIE_API_EMIT_ERROR(muxOp, XAie_EnableAieToShimDmaStrmPort, + &devInst, tileLoc, connectOp.sourceIndex()); + // mux + if (connectOp.getDestBundle() == WireBundle::North) + TRY_XAIE_API_EMIT_ERROR(muxOp, XAie_EnableShimDmaToAieStrmPort, + &devInst, tileLoc, connectOp.destIndex()); + } + } + + for (auto switchboxOp : targetOp.getOps()) { + Block &b = switchboxOp.getConnections().front(); + auto tileLoc = XAie_TileLoc(switchboxOp.getCol(), 0); + for (auto connectOp : b.getOps()) + TRY_XAIE_API_EMIT_ERROR( + switchboxOp, XAie_StrmConnCctEnable, &devInst, tileLoc, + WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at(connectOp.getSourceBundle()), + connectOp.sourceIndex(), + WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at(connectOp.getDestBundle()), + connectOp.destIndex()); + } + + // Cascade configuration + if (targetModel.getTargetArch() == AIEArch::AIE2) { + for (auto configOp : targetOp.getOps()) { + TileOp tile = cast(configOp.getTile().getDefiningOp()); + auto tileLoc = XAie_TileLoc(tile.getCol(), tile.getRow()); + TRY_XAIE_API_EMIT_ERROR( + targetOp, XAie_CoreConfigAccumulatorControl, &devInst, tileLoc, + WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at( + static_cast(configOp.getInputDir())), + WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at( + static_cast(configOp.getOutputDir()))); + } + } + return success(); +} + +LogicalResult AIERTXControl::enableCoresInDevice(DeviceOp &targetOp) { + // Start execution of all the cores. + for (auto tileOp : targetOp.getOps()) { + auto tileLoc = XAie_TileLoc(tileOp.colIndex(), tileOp.rowIndex()); + if (!tileOp.isShimTile() && tileOp.getCoreOp()) + TRY_XAIE_API_EMIT_ERROR(targetOp, XAie_CoreEnable, &devInst, tileLoc); + } + return success(); +} + +void AIERTXControl::dmaUpdateBdAddr(int col, int row, size_t addr, + size_t bdId) { + auto tileLoc = XAie_TileLoc(col, row); + TRY_XAIE_API_FATAL_ERROR(XAie_DmaUpdateBdAddr, &devInst, tileLoc, addr, bdId); +} + +void AIERTXControl::startTransaction() { + TRY_XAIE_API_FATAL_ERROR(XAie_StartTransaction, &devInst, + XAIE_TRANSACTION_DISABLE_AUTO_FLUSH); +} + +void AIERTXControl::exportSerializedTransaction() { + XAie_TxnInst *txnInst = XAie_ExportTransactionInstance(&devInst); + std::ios_base::fmtflags f(std::cout.flags()); + for (size_t i = 0; i < txnInst->NumCmds; ++i) { + std::cout.flags(f); + std::cout << "Txn OpCode: " << std::hex + << AIETXNOPCODETOSTR.at(txnInst->CmdBuf[i].Opcode) << "\n"; + std::cout.flags(f); + std::cout << "RegOff: 0x" << std::hex << txnInst->CmdBuf[i].RegOff << "\n"; + std::cout.flags(f); + std::cout << "Value: 0x" << std::hex << txnInst->CmdBuf[i].Value << "\n"; + std::cout.flags(f); + std::cout << "Mask: 0x" << std::hex << txnInst->CmdBuf[i].Mask << "\n"; + } +} + +} // namespace xilinx::AIE diff --git a/lib/Targets/AIETargetCDODirect.cpp b/lib/Targets/AIETargetCDODirect.cpp index 0e7a501dcb..09824e1abe 100644 --- a/lib/Targets/AIETargetCDODirect.cpp +++ b/lib/Targets/AIETargetCDODirect.cpp @@ -5,7 +5,7 @@ // //===----------------------------------------------------------------------===// -#include "aie/Dialect/AIE/IR/AIETargetModel.h" +#include "aie/Targets/AIERTX.h" #include "aie/Targets/AIETargets.h" extern "C" { #include "cdo-driver/cdo_driver.h" @@ -17,9 +17,7 @@ extern "C" { #include "mlir/IR/Block.h" #include "mlir/IR/BuiltinOps.h" -#include "mlir/IR/BuiltinTypeInterfaces.h" #include "mlir/IR/Operation.h" -#include "mlir/IR/Region.h" #include "mlir/Support/LLVM.h" #include "mlir/Support/LogicalResult.h" @@ -27,17 +25,11 @@ extern "C" { #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/Debug.h" -#include "llvm/Support/ErrorHandling.h" #include #include -#include // size_t -#include // uint -#include // calloc #include #include -#include -#include #include #include @@ -46,741 +38,17 @@ extern "C" { #endif extern "C" { -#include "xaiengine/xaie_core.h" -#include "xaiengine/xaie_dma.h" #include "xaiengine/xaie_elfloader.h" #include "xaiengine/xaie_interrupt.h" -#include "xaiengine/xaie_locks.h" -#include "xaiengine/xaie_plif.h" -#include "xaiengine/xaie_ss.h" -#include "xaiengine/xaie_txn.h" #include "xaiengine/xaiegbl.h" -#include "xaiengine/xaiegbl_defs.h" } #define DEBUG_TYPE "aie-generate-cdo" using namespace mlir; -using namespace xilinx; -using namespace xilinx::AIE; - -#define AIERC_STR(x) x, #x -static const std::map AIERCTOSTR = { - {AIERC_STR(XAIE_OK)}, - {AIERC_STR(XAIE_ERR)}, - {AIERC_STR(XAIE_INVALID_DEVICE)}, - {AIERC_STR(XAIE_INVALID_RANGE)}, - {AIERC_STR(XAIE_INVALID_ARGS)}, - {AIERC_STR(XAIE_INVALID_TILE)}, - {AIERC_STR(XAIE_ERR_STREAM_PORT)}, - {AIERC_STR(XAIE_INVALID_DMA_TILE)}, - {AIERC_STR(XAIE_INVALID_BD_NUM)}, - {AIERC_STR(XAIE_ERR_OUTOFBOUND)}, - {AIERC_STR(XAIE_INVALID_DATA_MEM_ADDR)}, - {AIERC_STR(XAIE_INVALID_ELF)}, - {AIERC_STR(XAIE_CORE_STATUS_TIMEOUT)}, - {AIERC_STR(XAIE_INVALID_CHANNEL_NUM)}, - {AIERC_STR(XAIE_INVALID_LOCK)}, - {AIERC_STR(XAIE_INVALID_DMA_DIRECTION)}, - {AIERC_STR(XAIE_INVALID_PLIF_WIDTH)}, - {AIERC_STR(XAIE_INVALID_LOCK_ID)}, - {AIERC_STR(XAIE_INVALID_LOCK_VALUE)}, - {AIERC_STR(XAIE_LOCK_RESULT_FAILED)}, - {AIERC_STR(XAIE_INVALID_DMA_DESC)}, - {AIERC_STR(XAIE_INVALID_ADDRESS)}, - {AIERC_STR(XAIE_FEATURE_NOT_SUPPORTED)}, - {AIERC_STR(XAIE_INVALID_BURST_LENGTH)}, - {AIERC_STR(XAIE_INVALID_BACKEND)}, - {AIERC_STR(XAIE_INSUFFICIENT_BUFFER_SIZE)}, - {AIERC_STR(XAIE_ERR_MAX)}}; -#undef AIERC_STR - -static const std::map - WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE = { - {WireBundle::Core, StrmSwPortType::CORE}, - {WireBundle::DMA, StrmSwPortType::DMA}, - {WireBundle::Ctrl, StrmSwPortType::CTRL}, - {WireBundle::FIFO, StrmSwPortType::FIFO}, - {WireBundle::South, StrmSwPortType::SOUTH}, - {WireBundle::West, StrmSwPortType::WEST}, - {WireBundle::North, StrmSwPortType::NORTH}, - {WireBundle::East, StrmSwPortType::EAST}, - // missing PLIO from WireBundle - // missing NOC from WireBundle - {WireBundle::Trace, StrmSwPortType::TRACE}, -}; - -#ifndef NDEBUG - -// https://stackoverflow.com/a/32230306 -template -static raw_ostream &showArgs(raw_ostream &out, const char *label, H1 &&value) { - return out << label << "=" << std::forward

(value); -} - -template -static raw_ostream &showArgs(raw_ostream &out, const char *label, H1 &&value, - T &&...rest) { - const char *pcomma = strchr(label, ','); - return showArgs(out.write(label, pcomma - label) - << "=" << std::forward

(value) << ',', - pcomma + 1, std::forward(rest)...); -} - -#define SHOW_ARGS(os, ...) showArgs(os, #__VA_ARGS__, __VA_ARGS__) - -static raw_ostream &operator<<(raw_ostream &os, const XAie_LocType &loc) { - os << "XAie_LocType(col: " << std::to_string(loc.Col) - << ", row: " << std::to_string(loc.Row) << ")"; - return os; -} - -static raw_ostream &operator<<(raw_ostream &os, const XAie_Lock &lock) { - os << "XAie_Lock(id: " << std::to_string(lock.LockId) - << ", val: " << std::to_string(lock.LockVal) << ")"; - return os; -} - -static raw_ostream &operator<<(raw_ostream &os, const XAie_Packet &packet) { - os << "XAie_Packet(id: " << std::to_string(packet.PktId) - << ", type: " << std::to_string(packet.PktType) << ")"; - return os; -} - -// So that we can use the pattern if(auto r = TRY_XAIE_API...) { // r is nonzero -// } -static_assert(XAIE_OK == 0); - -#define TRY_XAIE_API_FATAL_ERROR(API, ...) \ - do { \ - LLVM_DEBUG(llvm::dbgs() << "trying XAIE API: " << #API << " with args: "); \ - LLVM_DEBUG(SHOW_ARGS(llvm::dbgs(), __VA_ARGS__)); \ - LLVM_DEBUG(llvm::dbgs() << "\n"); \ - if (auto r = API(__VA_ARGS__)) \ - llvm::report_fatal_error(llvm::Twine(#API " failed with ") + \ - AIERCTOSTR.at(r)); \ - } while (0) - -#define TRY_XAIE_API_EMIT_ERROR(OP, API, ...) \ - do { \ - LLVM_DEBUG(llvm::dbgs() << "trying XAIE API: " << #API << " with args: "); \ - LLVM_DEBUG(SHOW_ARGS(llvm::dbgs(), __VA_ARGS__)); \ - LLVM_DEBUG(llvm::dbgs() << "\n"); \ - if (auto r = API(__VA_ARGS__)) \ - return OP.emitOpError() << #API " failed with " << AIERCTOSTR.at(r); \ - } while (0) - -#define TRY_XAIE_API_LOGICAL_RESULT(API, ...) \ - do { \ - LLVM_DEBUG(llvm::dbgs() << "trying XAIE API: " << #API << " with args: "); \ - LLVM_DEBUG(SHOW_ARGS(llvm::dbgs(), __VA_ARGS__)); \ - LLVM_DEBUG(llvm::dbgs() << "\n"); \ - if (auto r = API(__VA_ARGS__)) { \ - llvm::errs() << #API " failed with " << AIERCTOSTR.at(r); \ - return failure(); \ - } \ - } while (0) - -#else - -#define TRY_XAIE_API_FATAL_ERROR(API, ...) \ - do { \ - if (auto r = API(__VA_ARGS__)) \ - llvm::report_fatal_error(llvm::Twine(#API " failed with ") + \ - AIERCTOSTR.at(r)); \ - } while (0) - -#define TRY_XAIE_API_EMIT_ERROR(OP, API, ...) \ - do { \ - if (auto r = API(__VA_ARGS__)) \ - return OP.emitOpError() << #API " failed with " << AIERCTOSTR.at(r); \ - } while (0) - -#define TRY_XAIE_API_LOGICAL_RESULT(API, ...) \ - do { \ - if (auto r = API(__VA_ARGS__)) { \ - llvm::errs() << #API " failed with " << AIERCTOSTR.at(r); \ - return failure(); \ - } \ - } while (0) - -#endif - -auto ps = std::filesystem::path::preferred_separator; - -#define XAIE_BASE_ADDR 0x40000000 -#define XAIE_SHIM_ROW 0 -#define XAIE_MEM_TILE_ROW_START 1 -#define XAIE_PARTITION_BASE_ADDR 0x0 - -#define NPI_ADDR 0x0 -#define NUM_LOCKS 16 -#define EVEN_BD_NUM_START 0 -#define ODD_BD_NUM_START 24 -#define MEM_TILE_LOCK_ID_INCR 64 -#define BASE_ADDR_A_INCR 0x80000 - -static LogicalResult configureLocksInBdBlock(XAie_DmaDesc &dmaTileBd, - Block &block, - const AIETargetModel &targetModel, - XAie_LocType &tileLoc) { - LLVM_DEBUG(llvm::dbgs() << "\nstart configuring bds\n"); - std::optional acqValue, relValue, acqLockId, relLockId; - bool acqEn = false; - - // switch (lock->getAc) - for (auto op : block.getOps()) { - // Only dyn_cast if you are going to check if it was of the type - // expected; if you aren't checking use cast instead as it will at - // least assert in debug mode with an easier to understand error than - // dereferencing. - LockOp lock = cast(op.getLock().getDefiningOp()); - switch (op.getAction()) { - case LockAction::Acquire: - case LockAction::AcquireGreaterEqual: - acqEn = op.getAcqEn(); - acqLockId = lock.getLockIDValue(); - acqValue = op.getLockValue(); - if (op.acquireGE()) - acqValue.value() = -acqValue.value(); - break; - case LockAction::Release: - relLockId = lock.getLockIDValue(); - relValue = op.getLockValue(); - break; - } - } - - assert(acqValue && relValue && acqLockId && relLockId && - "expected both use_lock(acquire) and use_lock(release) with bd"); - - if (targetModel.isMemTile(tileLoc.Col, tileLoc.Row)) { - if (acqLockId) - acqLockId.value() += MEM_TILE_LOCK_ID_INCR; - if (relLockId) - relLockId.value() += MEM_TILE_LOCK_ID_INCR; - } - - // no RelEn in the arch spec even though the API requires you to set it? - bool relEn = false; - XAie_Lock acqLock = XAie_LockInit(acqLockId.value(), acqValue.value()); - XAie_Lock relLock = XAie_LockInit(relLockId.value(), relValue.value()); - TRY_XAIE_API_EMIT_ERROR((*block.getOps().begin()), - dmaTileBd.DmaMod->SetLock, &dmaTileBd, acqLock, - relLock, acqEn, relEn); - return success(); -} - -static LogicalResult configureBdInBlock(XAie_DevInst &devInst, - XAie_DmaDesc &dmaTileBd, Block &block, - const AIETargetModel &targetModel, - XAie_LocType &tileLoc, int bdId, - std::optional nextBdId) { - std::optional packetType; - std::optional packetID; - - // Below should go - auto maybePacketOps = block.getOps(); - if (!maybePacketOps.empty()) { - assert(llvm::range_size(maybePacketOps) == 1 && - "expected only one dma_bd_packet"); - auto packetOp = *maybePacketOps.begin(); - packetType = packetOp.getPacketType(); - packetID = packetOp.getPacketID(); - } - - auto bdOp = *block.getOps().begin(); - - if (targetModel.isShimNOCTile(tileLoc.Col, tileLoc.Row)) { - // write them out like this so they show up with names in debug prints - size_t smid = 0; - size_t burstLen = 16; // (10):BLEN=16 (256Byte) (corresponds to - // 0x800000000 from target) - size_t qOs = 0; - size_t cache = 0; - size_t secure = 0; - TRY_XAIE_API_EMIT_ERROR(bdOp, XAie_DmaSetAxi, &dmaTileBd, smid, burstLen, - qOs, cache, secure); - } - - // StringRef FifoMode = disable; // FIXME: when to enable FIFO mode? - int baseAddr = 0; - if (!targetModel.isShimNOCTile(tileLoc.Col, tileLoc.Row)) { - auto bufferOp = cast(bdOp.getBuffer().getDefiningOp()); - if (!bufferOp.getAddress()) - return bufferOp.emitError("buffer must have address assigned"); - baseAddr = bufferOp.getAddress().value(); - if (targetModel.isMemTile(tileLoc.Col, tileLoc.Row)) - baseAddr += BASE_ADDR_A_INCR; - } - - std::optional> dims = bdOp.getDimensions(); - int lenInBytes = bdOp.getLenInBytes(); - int basePlusOffsetInBytes = baseAddr + bdOp.getOffsetInBytes(); - if (!dims) { - TRY_XAIE_API_EMIT_ERROR(bdOp, XAie_DmaSetAddrLen, &dmaTileBd, - basePlusOffsetInBytes, lenInBytes); - } else { - XAie_DmaTensor dmaTileBdTensor = {}; - dmaTileBdTensor.NumDim = dims->size(); - dmaTileBdTensor.Dim = static_cast( - calloc(dmaTileBdTensor.NumDim, sizeof(XAie_DmaDimDesc))); - if (!dmaTileBdTensor.Dim) - return bdOp.emitError("couldn't allocate array of XAie_DmaDimDesc"); - // libxaie requires stride in multiples of 32b - double elementWidthIn32bWords = - static_cast(bdOp.getBufferElementTypeWidthInBytes()) / 4.0; - for (size_t i = 0; i < dims->size(); i++) { - // Pass down dimensions in reverse order; in the MLIR, this allows - // us to specify step sizes/wraps in the same order as we would - // access a multi-dim C array, with the highest dimension first. - int j = dims->size() - i - 1; - uint16_t size; - uint32_t stride; - if (j > 0) { - stride = static_cast(dims.value()[i].getStride() * - elementWidthIn32bWords); - size = dims.value()[i].getSize(); - } else { - stride = dims.value()[i].getStride(); - size = static_cast(dims.value()[i].getSize() * - elementWidthIn32bWords); - } - stride = stride > 0 ? stride : 1; - // Assume AIE-ML architecture (ie use AieMlDimDesc instead of AieDimDesc); - // asserted in AIETranslateToCDODirect). - dmaTileBdTensor.Dim[j].AieMlDimDesc = {stride, size}; - } - TRY_XAIE_API_EMIT_ERROR(bdOp, XAie_DmaSetMultiDimAddr, &dmaTileBd, - &dmaTileBdTensor, basePlusOffsetInBytes, - lenInBytes); - } - - // ND zero padding. - std::optional> padDims = - bdOp.getPadDimensions(); - - if (padDims) { - XAie_DmaPadTensor dmaPadTensor = {}; - dmaPadTensor.NumDim = padDims->size(); - dmaPadTensor.PadDesc = static_cast( - calloc(dmaPadTensor.NumDim, sizeof(XAie_PadDesc))); - if (!dmaPadTensor.PadDesc) - return bdOp.emitError("couldn't allocate array of XAie_PadDesc"); - // libxaie requires stride in multiples of 32b - double elementWidthIn32bWords = - static_cast(bdOp.getBufferElementTypeWidthInBytes()) / 4.0; - for (size_t i = 0; i < padDims->size(); i++) { - // Pass down dimensions in reverse order. - int j = padDims->size() - i - 1; - uint8_t before; - uint8_t after; - if (j > 0) { - before = static_cast(padDims.value()[i].getConstPadBefore()); - after = static_cast(padDims.value()[i].getConstPadAfter()); - } else { - before = static_cast(padDims.value()[i].getConstPadBefore() * - elementWidthIn32bWords); - after = static_cast(padDims.value()[i].getConstPadAfter() * - elementWidthIn32bWords); - } - dmaPadTensor.PadDesc[j] = {before, after}; - } - TRY_XAIE_API_EMIT_ERROR(bdOp, XAie_DmaSetPadding, &dmaTileBd, - &dmaPadTensor); - } - if (nextBdId) { - auto enableNextBd = 1; - TRY_XAIE_API_EMIT_ERROR(bdOp, XAie_DmaSetNextBd, &dmaTileBd, - nextBdId.value(), enableNextBd); - } - - if (auto packetInfo = bdOp.getPacket()) { - packetType = packetInfo->getPktType(); - packetID = packetInfo->getPktId(); - } - - if (packetID) { - if (!packetType) - bdOp.emitError("must have packetType with packetID"); - if (bdOp.getLen() == 0) - return bdOp.emitOpError( - "For MM2S channels, if Buffer_Length=0 then Enable_Packet must be " - "set to 0, otherwise behavior is undefined (3.7.8 arch spec)"); - TRY_XAIE_API_EMIT_ERROR( - bdOp, XAie_DmaSetPkt, &dmaTileBd, - XAie_PacketInit(packetID.value(), packetType.value())); - } - TRY_XAIE_API_EMIT_ERROR(bdOp, XAie_DmaEnableBd, &dmaTileBd); - TRY_XAIE_API_EMIT_ERROR(bdOp, XAie_DmaWriteBd, &devInst, &dmaTileBd, tileLoc, - bdId); - LLVM_DEBUG(llvm::dbgs() << "\nend configuring bds\n"); - return success(); -}; - -static LogicalResult pushToBdQueueAndEnable(XAie_DevInst &devInst, - Operation &op, - XAie_LocType &tileLoc, int chNum, - const DMAChannelDir &channelDir, - int bdId, int repeatCount) { - XAie_DmaDirection direction = - channelDir == DMAChannelDir::S2MM ? DMA_S2MM : DMA_MM2S; - auto enTokenIssue = tileLoc.Row == 0 && direction == DMA_S2MM; - // in english repeat_count==0 means "do it once" and don't repeat but - // libxaie treats repeat_count=1 as do it once. - repeatCount += 1; - TRY_XAIE_API_EMIT_ERROR(op, XAie_DmaChannelSetStartQueue, &devInst, tileLoc, - chNum, direction, bdId, repeatCount, enTokenIssue); - TRY_XAIE_API_EMIT_ERROR(op, XAie_DmaChannelEnable, &devInst, tileLoc, chNum, - direction); - return success(); -}; - -static LogicalResult configureLocksAndBd(XAie_DevInst &devInst, Block &block, - XAie_LocType tileLoc, - const AIETargetModel &targetModel) { - DMABDOp bd = *block.getOps().begin(); - assert(bd.getBdId().has_value() && - "DMABDOp must have assigned bd_id; did you forget to run " - "aie-assign-bd-ids?"); - XAie_DmaDesc dmaTileBd; - TRY_XAIE_API_EMIT_ERROR(bd, XAie_DmaDescInit, &devInst, &dmaTileBd, tileLoc); - if (!block.getOps().empty() && - failed(configureLocksInBdBlock(dmaTileBd, block, targetModel, tileLoc))) - return failure(); - if (!block.getOps().empty() && - failed(configureBdInBlock(devInst, dmaTileBd, block, targetModel, tileLoc, - bd.getBdId().value(), bd.getNextBdId()))) - return failure(); - return success(); -}; - -namespace { -struct AIEControl { - XAie_Config configPtr; - XAie_DevInst devInst; - - AIEControl(bool aieSim, bool xaieDebug, const BaseNPUTargetModel &tm) { - // The first column in the NPU lacks a shim tile. AIE-RT exposes some of - // the internals about how this is modeled in a somewhat awkward way. - size_t partitionStartCol = tm.isVirtualized() ? 1 : 0; - size_t partitionNumCols = tm.columns(); - size_t deviceRows = tm.rows(); - size_t deviceCols = tm.columns() + partitionStartCol; - - // Don't put this in the target model, because it's XAIE specific. - unsigned char devGen; - switch (tm.getTargetArch()) { - case AIEArch::AIE1: // probably unreachable. - devGen = XAIE_DEV_GEN_AIE; - break; - case AIEArch::AIE2: - devGen = XAIE_DEV_GEN_AIEML; - break; - default: - assert(false); - } - configPtr = XAie_Config{ - /*AieGen*/ devGen, - /*BaseAddr*/ XAIE_BASE_ADDR, - /*ColShift*/ (uint8_t)tm.getColumnShift(), - /*RowShift*/ (uint8_t)tm.getRowShift(), - /*NumRows*/ static_cast(deviceRows), - /*NumCols*/ static_cast(deviceCols), - /*ShimRowNum*/ XAIE_SHIM_ROW, - /*MemTileRowStart*/ XAIE_MEM_TILE_ROW_START, - /*MemTileNumRows*/ static_cast(tm.getNumMemTileRows()), - /*AieTileRowStart*/ - static_cast(XAIE_MEM_TILE_ROW_START + tm.getNumMemTileRows()), - /*AieTileNumRows*/ - static_cast(tm.rows() - tm.getNumMemTileRows() - 1), - /*PartProp*/ {}, - /*Backend*/ XAIE_IO_BACKEND_CDO}; - - // Quoting: The instance of a device must be always declared using this - // macro. In future, the same macro will be expanded to allocate - // more memory from the user application for resource management. - XAie_InstDeclare(_devInst, &configPtr); - devInst = _devInst; - TRY_XAIE_API_FATAL_ERROR(XAie_SetupPartitionConfig, &devInst, - XAIE_PARTITION_BASE_ADDR, partitionStartCol, - partitionNumCols); - TRY_XAIE_API_FATAL_ERROR(XAie_CfgInitialize, &devInst, &configPtr); - if (aieSim) { - TRY_XAIE_API_FATAL_ERROR(XAie_SetIOBackend, &devInst, - XAIE_IO_BACKEND_SIM); - } else if (xaieDebug) - TRY_XAIE_API_FATAL_ERROR(XAie_SetIOBackend, &devInst, - XAIE_IO_BACKEND_DEBUG); - else - TRY_XAIE_API_FATAL_ERROR(XAie_SetIOBackend, &devInst, - XAIE_IO_BACKEND_CDO); - - TRY_XAIE_API_FATAL_ERROR(XAie_UpdateNpiAddr, &devInst, NPI_ADDR); - } - - LogicalResult addAieElf(uint8_t col, uint8_t row, const StringRef elfPath, - bool aieSim) { - TRY_XAIE_API_LOGICAL_RESULT(XAie_CoreDisable, &devInst, - XAie_TileLoc(col, row)); - TRY_XAIE_API_LOGICAL_RESULT(XAie_DmaChannelResetAll, &devInst, - XAie_TileLoc(col, row), - XAie_DmaChReset::DMA_CHANNEL_RESET); - - // loadSym: Load symbols from .map file. This argument is not used when - // __AIESIM__ is not defined. - TRY_XAIE_API_LOGICAL_RESULT(XAie_LoadElf, &devInst, XAie_TileLoc(col, row), - elfPath.str().c_str(), /*loadSym*/ aieSim); - - TRY_XAIE_API_LOGICAL_RESULT(XAie_DmaChannelResetAll, &devInst, - XAie_TileLoc(col, row), - XAie_DmaChReset::DMA_CHANNEL_UNRESET); - - return success(); - } - - LogicalResult addAieElfs(DeviceOp &targetOp, const StringRef workDirPath, - bool aieSim) { - for (auto tileOp : targetOp.getOps()) - if (tileOp.isShimNOCorPLTile()) { - // Resets no needed with V2 kernel driver - } else { - int col = tileOp.colIndex(); - int row = tileOp.rowIndex(); - if (auto coreOp = tileOp.getCoreOp()) { - std::string fileName; - if (auto fileAttr = coreOp.getElfFile()) - fileName = fileAttr->str(); - else - fileName = (llvm::Twine("core_") + std::to_string(col) + "_" + - std::to_string(row) + ".elf") - .str(); - if (failed(addAieElf( - col, row, - (llvm::Twine(workDirPath) + std::string(1, ps) + fileName) - .str(), - aieSim))) - return failure(); - } - } - return success(); - } - - LogicalResult addInitConfig(DeviceOp &targetOp) { - for (auto tileOp : targetOp.getOps()) { - auto tileLoc = XAie_TileLoc(tileOp.colIndex(), tileOp.rowIndex()); - if (!tileOp.isShimTile() && tileOp.getCoreOp()) { - TRY_XAIE_API_EMIT_ERROR(tileOp, XAie_CoreReset, &devInst, tileLoc); - TRY_XAIE_API_EMIT_ERROR(tileOp, XAie_CoreUnreset, &devInst, tileLoc); - // Set locks to zero - for (uint8_t l = 0; l < NUM_LOCKS; l++) { - auto locInit = XAie_LockInit(l, 0); - TRY_XAIE_API_EMIT_ERROR(tileOp, XAie_LockSetValue, &devInst, tileLoc, - locInit); - } - } - } - - // Set locks with explicit initializers - targetOp.walk([&](LockOp lockOp) { - if (lockOp.getLockID() && lockOp.getInit()) { - auto tileLoc = XAie_TileLoc(lockOp.getTileOp().colIndex(), - lockOp.getTileOp().rowIndex()); - auto locInit = XAie_LockInit(*lockOp.getLockID(), *lockOp.getInit()); - TRY_XAIE_API_FATAL_ERROR(XAie_LockSetValue, &devInst, tileLoc, locInit); - } else - LLVM_DEBUG(llvm::dbgs() - << "lock op missing either id or init" << lockOp << "\n"); - }); - - const AIETargetModel &targetModel = targetOp.getTargetModel(); - - auto memOps = llvm::to_vector_of(targetOp.getOps()); - llvm::append_range(memOps, targetOp.getOps()); - llvm::append_range(memOps, targetOp.getOps()); - for (TileElement memOp : memOps) { - int col = memOp.getTileID().col; - int row = memOp.getTileID().row; - XAie_LocType tileLoc = XAie_TileLoc(col, row); - - // handle DMA ops separately - auto dmaOps = llvm::to_vector_of( - memOp.getOperation()->getRegion(0).getOps()); - if (!dmaOps.empty()) { - for (auto dmaOp : dmaOps) - for (auto &bdRegion : dmaOp.getBds()) { - Block &block = bdRegion.getBlocks().front(); - if (failed( - configureLocksAndBd(devInst, block, tileLoc, targetModel))) - return failure(); - } - } else { - for (Block &block : memOp.getOperation()->getRegion(0)) { - if (block.getOps().empty()) - continue; - if (failed(configureLocksAndBd(devInst, block, tileLoc, targetModel))) - return failure(); - } - } - - if (!dmaOps.empty()) - for (auto dmaOp : dmaOps) { - auto &block = dmaOp.getBds().front().getBlocks().front(); - DMABDOp bd = *block.getOps().begin(); - if (failed(pushToBdQueueAndEnable( - devInst, *dmaOp.getOperation(), tileLoc, - dmaOp.getChannelIndex(), dmaOp.getChannelDir(), - bd.getBdId().value(), dmaOp.getRepeatCount()))) - return failure(); - } - else - for (Block &block : memOp.getOperation()->getRegion(0)) { - for (auto op : block.getOps()) { - DMABDOp bd = *op.getDest()->getOps().begin(); - int chNum = op.getChannelIndex(); - auto channelDir = op.getChannelDir(); - if (failed(pushToBdQueueAndEnable( - devInst, *bd.getOperation(), tileLoc, chNum, channelDir, - bd.getBdId().value(), op.getRepeatCount()))) - return failure(); - } - } - } - - // StreamSwitch (switchbox) configuration - for (auto switchboxOp : targetOp.getOps()) { - int32_t col = switchboxOp.colIndex(); - int32_t row = switchboxOp.rowIndex(); - XAie_LocType tileLoc = XAie_TileLoc(col, row); - assert(targetModel.isNPU() && "Only NPU currently supported"); - - Block &b = switchboxOp.getConnections().front(); - for (auto connectOp : b.getOps()) - TRY_XAIE_API_EMIT_ERROR( - switchboxOp, XAie_StrmConnCctEnable, &devInst, tileLoc, - WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at(connectOp.getSourceBundle()), - connectOp.sourceIndex(), - WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at(connectOp.getDestBundle()), - connectOp.destIndex()); - - for (auto masterSetOp : b.getOps()) { - int mask = 0; - int arbiter = -1; - - for (auto val : masterSetOp.getAmsels()) { - AMSelOp amsel = cast(val.getDefiningOp()); - arbiter = amsel.arbiterIndex(); - int msel = amsel.getMselValue(); - mask |= (1 << msel); - } - - // the default is to keep header - bool keepHeader = true; - // the default for dma destinations is to drop the header - if (masterSetOp.getDestBundle() == WireBundle::DMA) - keepHeader = false; - // assume a connection going south from row zero gets wired to shimdma - // by a shimmux. - if (switchboxOp.rowIndex() == 0 && - masterSetOp.getDestBundle() == WireBundle::South) - keepHeader = false; - - // "keep_pkt_header" attribute overrides the above defaults, if set - if (auto keep = masterSetOp.getKeepPktHeader()) - keepHeader = *keep; - - auto dropHeader = keepHeader ? XAIE_SS_PKT_DONOT_DROP_HEADER - : XAIE_SS_PKT_DROP_HEADER; - TRY_XAIE_API_EMIT_ERROR( - masterSetOp, XAie_StrmPktSwMstrPortEnable, &devInst, tileLoc, - WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at(masterSetOp.getDestBundle()), - masterSetOp.destIndex(), dropHeader, arbiter, mask); - } - - for (auto packetRulesOp : b.getOps()) { - int slot = 0; - Block &block = packetRulesOp.getRules().front(); - for (auto slotOp : block.getOps()) { - AMSelOp amselOp = cast(slotOp.getAmsel().getDefiningOp()); - int arbiter = amselOp.arbiterIndex(); - int msel = amselOp.getMselValue(); - TRY_XAIE_API_EMIT_ERROR(packetRulesOp, XAie_StrmPktSwSlavePortEnable, - &devInst, tileLoc, - WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at( - packetRulesOp.getSourceBundle()), - packetRulesOp.sourceIndex()); - auto packetInit = XAie_PacketInit(slotOp.valueInt(), /*PktType*/ 0); - // TODO Need to better define packet id,type used here - TRY_XAIE_API_EMIT_ERROR(packetRulesOp, XAie_StrmPktSwSlaveSlotEnable, - &devInst, tileLoc, - WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at( - packetRulesOp.getSourceBundle()), - packetRulesOp.sourceIndex(), slot, packetInit, - slotOp.maskInt(), msel, arbiter); - slot++; - } - } - } - - for (auto muxOp : targetOp.getOps()) { - // NOTE ShimMux always connects from the south as directions are - // defined relative to the tile stream switch. - auto tileLoc = - XAie_TileLoc(muxOp.getTileOp().getCol(), muxOp.getTileOp().getRow()); - Block &b = muxOp.getConnections().front(); - for (auto connectOp : b.getOps()) { - // demux! - if (connectOp.getSourceBundle() == WireBundle::North) - TRY_XAIE_API_EMIT_ERROR(muxOp, XAie_EnableAieToShimDmaStrmPort, - &devInst, tileLoc, connectOp.sourceIndex()); - // mux - if (connectOp.getDestBundle() == WireBundle::North) - TRY_XAIE_API_EMIT_ERROR(muxOp, XAie_EnableShimDmaToAieStrmPort, - &devInst, tileLoc, connectOp.destIndex()); - } - } - - for (auto switchboxOp : targetOp.getOps()) { - Block &b = switchboxOp.getConnections().front(); - auto tileLoc = XAie_TileLoc(switchboxOp.getCol(), 0); - for (auto connectOp : b.getOps()) - TRY_XAIE_API_EMIT_ERROR( - switchboxOp, XAie_StrmConnCctEnable, &devInst, tileLoc, - WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at(connectOp.getSourceBundle()), - connectOp.sourceIndex(), - WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at(connectOp.getDestBundle()), - connectOp.destIndex()); - } - // Cascade configuration - if (targetModel.getTargetArch() == AIEArch::AIE2) { - for (auto configOp : targetOp.getOps()) { - TileOp tile = cast(configOp.getTile().getDefiningOp()); - auto tileLoc = XAie_TileLoc(tile.getCol(), tile.getRow()); - TRY_XAIE_API_EMIT_ERROR( - targetOp, XAie_CoreConfigAccumulatorControl, &devInst, tileLoc, - WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at( - static_cast(configOp.getInputDir())), - WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at( - static_cast(configOp.getOutputDir()))); - } - } - return success(); - } - LogicalResult addCoreEnable(DeviceOp &targetOp) { - // Start execution of all the cores. - for (auto tileOp : targetOp.getOps()) { - auto tileLoc = XAie_TileLoc(tileOp.colIndex(), tileOp.rowIndex()); - if (!tileOp.isShimTile() && tileOp.getCoreOp()) - TRY_XAIE_API_EMIT_ERROR(targetOp, XAie_CoreEnable, &devInst, tileLoc); - } - return success(); - } -}; - -} // namespace static void initializeCDOGenerator(byte_ordering endianness, bool cdoDebug) { // Enables AXI-MM prints for configs being added in CDO @@ -871,7 +139,9 @@ translateToCDODirect(ModuleOp m, llvm::StringRef workDirPath, // shim dma on tile (0,0) are hard-coded assumptions about NPU... assert(targetModel.isNPU() && "Only NPU currently supported"); - AIEControl ctl(aieSim, xaieDebug, targetModel); + AIERTXControl ctl(targetOp.getTargetModel()); + if (failed(ctl.setIOBackend(aieSim, xaieDebug))) + return failure(); initializeCDOGenerator(endianness, cdoDebug); auto result = [&]() { diff --git a/lib/Targets/CMakeLists.txt b/lib/Targets/CMakeLists.txt index e6e4307c2c..110e6b90a8 100644 --- a/lib/Targets/CMakeLists.txt +++ b/lib/Targets/CMakeLists.txt @@ -7,7 +7,25 @@ add_subdirectory(AIEVecToCpp) -add_mlir_library(AIETargets +# for #include +set(BOOTGEN_SOURCE_DIR ${PROJECT_SOURCE_DIR}/third_party/bootgen) + +add_mlir_library(AIERTX + AIERTX.cpp + + PARTIAL_SOURCES_INTENDED + ENABLE_AGGREGATION + + ADDITIONAL_HEADER_DIRS + ${CMAKE_CURRENT_SRC_DIR}/../../../include/aie/Targets +) + +target_link_libraries(AIERTX PRIVATE xaienginecdo_static) +target_include_directories(AIERTX SYSTEM PRIVATE ${BOOTGEN_SOURCE_DIR}) +target_include_directories(obj.AIERTX SYSTEM PRIVATE ${BOOTGEN_SOURCE_DIR}) +add_dependencies(obj.AIERTX xaienginecdo_static xaienginecdo_static-headers) + +set(_sources AIETargets.cpp AIETargetBCF.cpp AIETargetCDODirect.cpp @@ -26,7 +44,7 @@ add_mlir_library(AIETargets ADDITIONAL_HEADER_DIRS ${AIE_BINARY_DIR}/include - $(CMAKE_CURRENT_SRC_DIR)/../../../include/aie/Targets + ${CMAKE_CURRENT_SRC_DIR}/../../../include/aie/Targets LINK_COMPONENTS BinaryFormat @@ -41,6 +59,7 @@ add_mlir_library(AIETargets IPO LINK_LIBS PUBLIC + AIERTX AIE AIEX AIEXUtils @@ -68,9 +87,6 @@ if(AIE_ENABLE_AIRBIN) endif() target_link_libraries(AIETargets PRIVATE xaienginecdo_static) -add_dependencies(obj.AIETargets xaienginecdo_static xaienginecdo_static-headers) -# for #include -set(BOOTGEN_SOURCE_DIR ${PROJECT_SOURCE_DIR}/third_party/bootgen) target_include_directories(AIETargets SYSTEM PRIVATE ${BOOTGEN_SOURCE_DIR}) target_include_directories(obj.AIETargets SYSTEM PRIVATE ${BOOTGEN_SOURCE_DIR}) diff --git a/python/AIERTXModule.cpp b/python/AIERTXModule.cpp new file mode 100644 index 0000000000..75c93f1404 --- /dev/null +++ b/python/AIERTXModule.cpp @@ -0,0 +1,50 @@ +//===- XRTModule.cpp -------------------------------------------000---*- C++ +//-*-===// +// +// This file is licensed under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// Copyright (C) 2023, Advanced Micro Devices, Inc. +// +//===----------------------------------------------------------------------===// + +#include "aie-c/Translation.h" + +#include +#include + +#include + +namespace py = pybind11; +using namespace py::literals; + +class PyAIERTXControl { +public: + PyAIERTXControl(size_t partitionStartCol, size_t partitionNumCols) + : ctl(getAieRtxControl(partitionStartCol, partitionNumCols)) {} + + ~PyAIERTXControl() { freeAieRtxControl(ctl); } + + AieRtxControl ctl; +}; + +PYBIND11_MODULE(_aiertx, m) { + + py::class_(m, "AIERTXControl", py::module_local()) + .def(py::init(), "partition_start_col"_a, + "partition_num_cols"_a) + .def("start_transaction", + [](PyAIERTXControl &self) { aieRtxStartTransaction(self.ctl); }) + .def("export_serialized_transaction", + [](PyAIERTXControl &self) { + aieRtxExportSerializedTransaction(self.ctl); + }) + .def( + "dma_update_bd_addr", + [](PyAIERTXControl &self, int col, int row, size_t addr, + size_t bdId) { + aieRtxDmaUpdateBdAddr(self.ctl, col, row, addr, bdId); + }, + "col"_a, "row"_a, "addr"_a, "bd_id"_a); +} diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index 31d32f6102..6d7280071d 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -103,6 +103,12 @@ if (AIE_ENABLE_XRT_PYTHON_BINDINGS) ) endif() +declare_mlir_python_sources(AIEPythonSources.AIERTX + ADD_TO_PARENT AIEPythonSources + SOURCES + aiertx.py +) + ################################################################################ # Extensions ################################################################################ @@ -167,6 +173,7 @@ if (AIE_ENABLE_PYTHON_PASSES) list(APPEND _py_srcs ${CMAKE_CURRENT_SOURCE_DIR}/XRTModule.cpp) list(APPEND _py_libs xrt_coreutil uuid) endif() + list(APPEND _py_srcs ${CMAKE_CURRENT_SOURCE_DIR}/AIERTXModule.cpp) declare_mlir_python_extension(AIEPythonExtensions.MLIR MODULE_NAME _aie @@ -290,6 +297,19 @@ else () target_link_directories(AIEPythonExtensions.XRT INTERFACE ${XRT_LIB_DIR}) endif() + declare_mlir_python_extension(AIEPythonExtensions.AIERTX + MODULE_NAME _aiertx + ADD_TO_PARENT AIEPythonExtensions + ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR} + + PARTIAL_SOURCES_INTENDED + SOURCES + AIERTXModule.cpp + + PRIVATE_LINK_LIBS + LLVMSupport + ) + add_mlir_python_common_capi_library(AIEAggregateCAPI INSTALL_COMPONENT AIEPythonModules INSTALL_DESTINATION ${AIE_PYTHON_INSTALL_DIR}/aie/_mlir_libs diff --git a/python/aiertx.py b/python/aiertx.py new file mode 100644 index 0000000000..7dc325af9b --- /dev/null +++ b/python/aiertx.py @@ -0,0 +1,5 @@ +# Copyright (C) 2022, Advanced Micro Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +# noinspection PyUnresolvedReferences +from ._mlir_libs._aiertx import * diff --git a/test/python/aiertx_bindings.py b/test/python/aiertx_bindings.py new file mode 100644 index 0000000000..5cd100c836 --- /dev/null +++ b/test/python/aiertx_bindings.py @@ -0,0 +1,20 @@ +# This file is licensed under the Apache License v2.0 with LLVM Exceptions. +# See https://llvm.org/LICENSE.txt for license information. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# +# (c) Copyright 2023 AMD Inc. + +# RUN: %python %s | FileCheck %s + +from aie.aiertx import AIERTXControl +from util import construct_and_print_module +from aie.dialects.aiex import DDR_AIE_ADDR_OFFSET + + +# CHECK-LABEL: simple +@construct_and_print_module +def simple(module): + ctl = AIERTXControl(1, 4) + ctl.start_transaction() + ctl.dma_update_bd_addr(0, 0, DDR_AIE_ADDR_OFFSET, 0) + ctl.export_serialized_transaction() From 387b04771fbfbf7d64776cbcd2c239aa8dcdf3a0 Mon Sep 17 00:00:00 2001 From: Jeff Fifield Date: Fri, 6 Sep 2024 16:10:55 -0600 Subject: [PATCH 2/9] updates from main and fixes to make it build after cherry-pick --- include/aie/Targets/AIERTX.h | 53 ++++- lib/CAPI/Translation.cpp | 4 +- lib/Targets/AIERTX.cpp | 320 +++++++++++++++++++++++------ lib/Targets/AIETargetCDODirect.cpp | 20 +- lib/Targets/CMakeLists.txt | 2 +- python/AIERTXModule.cpp | 5 +- python/aiertx.py | 2 +- test/python/aiertx_bindings.py | 2 +- 8 files changed, 320 insertions(+), 88 deletions(-) diff --git a/include/aie/Targets/AIERTX.h b/include/aie/Targets/AIERTX.h index ba04460447..98dd07ffb5 100644 --- a/include/aie/Targets/AIERTX.h +++ b/include/aie/Targets/AIERTX.h @@ -1,6 +1,12 @@ +//===- AIERTX.h -------------------------------------------------*- C++ -*-===// // -// Created by maksim on 3/6/24. +// This file is licensed under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // +// Copyright (C) 2024, Advanced Micro Devices, Inc. All rights reserved. +// +//===----------------------------------------------------------------------===// #ifndef AIE_AIERTX_H #define AIE_AIERTX_H @@ -15,6 +21,7 @@ extern "C" { #include "xaiengine/xaie_txn.h" #include "xaiengine/xaiegbl.h" } + #include "llvm/Support/raw_ostream.h" #include @@ -70,7 +77,7 @@ static const std::map WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE = { {xilinx::AIE::WireBundle::Core, StrmSwPortType::CORE}, {xilinx::AIE::WireBundle::DMA, StrmSwPortType::DMA}, - // missing control from StrmSwPortType + {xilinx::AIE::WireBundle::Ctrl, StrmSwPortType::CTRL}, {xilinx::AIE::WireBundle::FIFO, StrmSwPortType::FIFO}, {xilinx::AIE::WireBundle::South, StrmSwPortType::SOUTH}, {xilinx::AIE::WireBundle::West, StrmSwPortType::WEST}, @@ -81,6 +88,8 @@ static const std::map {xilinx::AIE::WireBundle::Trace, StrmSwPortType::TRACE}, }; +#ifndef NDEBUG + // https://stackoverflow.com/a/32230306 template llvm::raw_ostream &showAIEXRTArgs(llvm::raw_ostream &out, const char *label, @@ -139,9 +148,32 @@ static_assert(XAIE_OK == 0); } \ } while (0) +#else + +#define TRY_XAIE_API_FATAL_ERROR(API, ...) \ + do { \ + if (auto r = API(__VA_ARGS__)) \ + llvm::report_fatal_error(llvm::Twine(#API " failed with ") + \ + AIERCTOSTR.at(r)); \ + } while (0) + +#define TRY_XAIE_API_EMIT_ERROR(OP, API, ...) \ + do { \ + if (auto r = API(__VA_ARGS__)) \ + return OP.emitOpError() << #API " failed with " << AIERCTOSTR.at(r); \ + } while (0) + +#define TRY_XAIE_API_LOGICAL_RESULT(API, ...) \ + do { \ + if (auto r = API(__VA_ARGS__)) { \ + llvm::errs() << #API " failed with " << AIERCTOSTR.at(r); \ + return failure(); \ + } \ + } while (0) + +#endif + #define XAIE_BASE_ADDR 0x40000000 -#define XAIE_COL_SHIFT 25 -#define XAIE_ROW_SHIFT 20 #define XAIE_SHIM_ROW 0 #define XAIE_MEM_TILE_ROW_START 1 #define XAIE_PARTITION_BASE_ADDR 0x0 @@ -157,10 +189,9 @@ namespace xilinx::AIE { struct AIERTXControl { XAie_Config configPtr; XAie_DevInst devInst; - const AIETargetModel &targetModel; + const BaseNPUTargetModel &targetModel; - AIERTXControl(size_t partitionStartCol, size_t partitionNumCols, - const xilinx::AIE::AIETargetModel &tm); + AIERTXControl(const xilinx::AIE::BaseNPUTargetModel &tm); mlir::LogicalResult setIOBackend(bool aieSim, bool xaieDebug); mlir::LogicalResult configureBdInBlock(XAie_DmaDesc &dmaTileBd, @@ -175,10 +206,16 @@ struct AIERTXControl { XAie_LocType tileLoc); mlir::LogicalResult initLocks(DeviceOp &targetOp); mlir::LogicalResult configureSwitches(DeviceOp &targetOp); - mlir::LogicalResult enableCoresInDevice(DeviceOp &targetOp); + mlir::LogicalResult addInitConfig(DeviceOp &targetOp); + mlir::LogicalResult addCoreEnable(DeviceOp &targetOp); mlir::LogicalResult configureLocksInBdBlock(XAie_DmaDesc &dmaTileBd, mlir::Block &block, XAie_LocType &tileLoc); + mlir::LogicalResult addAieElf(uint8_t col, uint8_t row, + const mlir::StringRef elfPath, bool aieSim); + mlir::LogicalResult addAieElfs(DeviceOp &targetOp, + const mlir::StringRef workDirPath, + bool aieSim); void startTransaction(); void dmaUpdateBdAddr(int col, int row, size_t addr, size_t bdId); void exportSerializedTransaction(); diff --git a/lib/CAPI/Translation.cpp b/lib/CAPI/Translation.cpp index 561bc903f4..be4043cec8 100644 --- a/lib/CAPI/Translation.cpp +++ b/lib/CAPI/Translation.cpp @@ -230,9 +230,9 @@ DEFINE_C_API_PTR_METHODS(AieRtxControl, xilinx::AIE::AIERTXControl) AieRtxControl getAieRtxControl(size_t partitionStartCol, size_t partitionNumCols) { - IPUTargetModel targetModel; + NPUTargetModel targetModel; AIERTXControl *ctl = - new AIERTXControl(partitionStartCol, partitionNumCols, targetModel); + new AIERTXControl(targetModel); return wrap(ctl); } diff --git a/lib/Targets/AIERTX.cpp b/lib/Targets/AIERTX.cpp index 028f329ada..d8057dcd67 100644 --- a/lib/Targets/AIERTX.cpp +++ b/lib/Targets/AIERTX.cpp @@ -1,8 +1,11 @@ //===- AIERTX.cpp -----------------------------------------------*- C++ -*-===// // -// Copyright (C) 2023, Advanced Micro Devices, Inc. All rights reserved. +// This file is licensed under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // +// Copyright (C) 2024, Advanced Micro Devices, Inc. All rights reserved. +// //===----------------------------------------------------------------------===// #include "aie/Targets/AIERTX.h" @@ -12,14 +15,18 @@ extern "C" { #include "xaiengine/xaie_core.h" #include "xaiengine/xaie_dma.h" +#include "xaiengine/xaie_elfloader.h" #include "xaiengine/xaie_interrupt.h" #include "xaiengine/xaie_locks.h" #include "xaiengine/xaie_plif.h" #include "xaiengine/xaie_ss.h" +#include "xaiengine/xaie_txn.h" #include "xaiengine/xaiegbl.h" #include "xaiengine/xaiegbl_defs.h" } +#include + using namespace mlir; #define DEBUG_TYPE "aie-aiertx" @@ -44,16 +51,35 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &os, } namespace xilinx::AIE { -AIERTXControl::AIERTXControl(size_t partitionStartCol, size_t partitionNumCols, - const AIETargetModel &tm) + +AIERTXControl::AIERTXControl(const AIE::BaseNPUTargetModel &tm) : targetModel(tm) { + // The first column in the NPU lacks a shim tile. AIE-RT exposes some of + // the internals about how this is modeled in a somewhat awkward way. + size_t partitionStartCol = tm.isVirtualized() ? 1 : 0; + size_t partitionNumCols = tm.columns(); + size_t deviceRows = tm.rows(); + size_t deviceCols = tm.columns() + partitionStartCol; + + // Don't put this in the target model, because it's XAIE specific. + unsigned char devGen; + switch (tm.getTargetArch()) { + case AIEArch::AIE1: // probably unreachable. + devGen = XAIE_DEV_GEN_AIE; + break; + case AIEArch::AIE2: + devGen = XAIE_DEV_GEN_AIEML; + break; + default: + assert(false); + } configPtr = XAie_Config{ - /*AieGen*/ XAIE_DEV_GEN_AIEML, + /*AieGen*/ devGen, /*BaseAddr*/ XAIE_BASE_ADDR, - /*ColShift*/ XAIE_COL_SHIFT, - /*RowShift*/ XAIE_ROW_SHIFT, - /*NumRows*/ static_cast(tm.rows()), - /*NumCols*/ static_cast(tm.columns()), + /*ColShift*/ static_cast(tm.getColumnShift()), + /*RowShift*/ static_cast(tm.getRowShift()), + /*NumRows*/ static_cast(deviceRows), + /*NumCols*/ static_cast(deviceCols), /*ShimRowNum*/ XAIE_SHIM_ROW, /*MemTileRowStart*/ XAIE_MEM_TILE_ROW_START, /*MemTileNumRows*/ static_cast(tm.getNumMemTileRows()), @@ -92,7 +118,8 @@ LogicalResult AIERTXControl::configureLocksInBdBlock(XAie_DmaDesc &dmaTileBd, XAie_LocType &tileLoc) { LLVM_DEBUG(llvm::dbgs() << "\nstart configuring bds\n"); std::optional acqValue, relValue, acqLockId, relLockId; - bool acqEn; + bool acqEn = false; + // switch (lock->getAc) for (auto op : block.getOps()) { // Only dyn_cast if you are going to check if it was of the type @@ -142,6 +169,8 @@ LogicalResult AIERTXControl::configureBdInBlock(XAie_DmaDesc &dmaTileBd, std::optional nextBdId) { std::optional packetType; std::optional packetID; + + // Below should go auto maybePacketOps = block.getOps(); if (!maybePacketOps.empty()) { assert(llvm::range_size(maybePacketOps) == 1 && @@ -157,7 +186,7 @@ LogicalResult AIERTXControl::configureBdInBlock(XAie_DmaDesc &dmaTileBd, // write them out like this so they show up with names in debug prints size_t smid = 0; size_t burstLen = 16; // (10):BLEN=16 (256Byte) (corresponds to - // 0x800000000 from targetipu) + // 0x800000000 from target) size_t qOs = 0; size_t cache = 0; size_t secure = 0; @@ -165,59 +194,107 @@ LogicalResult AIERTXControl::configureBdInBlock(XAie_DmaDesc &dmaTileBd, qOs, cache, secure); } - // deref here because this is a const iter and the various getters below - // aren't const (even though they probably should be...) // StringRef FifoMode = disable; // FIXME: when to enable FIFO mode? - ShapedType bufferType = bdOp.getBuffer().getType().cast<::mlir::MemRefType>(); - int bytes = bufferType.getElementTypeBitWidth() / 8; int baseAddr = 0; if (!targetModel.isShimNOCTile(tileLoc.Col, tileLoc.Row)) { auto bufferOp = cast(bdOp.getBuffer().getDefiningOp()); - assert(bufferOp.getAddress().has_value() && "buffer must have address"); + if (!bufferOp.getAddress()) + return bufferOp.emitError("buffer must have address assigned"); baseAddr = bufferOp.getAddress().value(); if (targetModel.isMemTile(tileLoc.Col, tileLoc.Row)) baseAddr += BASE_ADDR_A_INCR; } std::optional> dims = bdOp.getDimensions(); - int lenInBytes = bdOp.getLenValue() * bytes; - int basePlusOffset = baseAddr + bdOp.getOffsetValue(); + int lenInBytes = bdOp.getLenInBytes(); + int basePlusOffsetInBytes = baseAddr + bdOp.getOffsetInBytes(); if (!dims) { TRY_XAIE_API_EMIT_ERROR(bdOp, XAie_DmaSetAddrLen, &dmaTileBd, - basePlusOffset, lenInBytes); + basePlusOffsetInBytes, lenInBytes); } else { XAie_DmaTensor dmaTileBdTensor = {}; dmaTileBdTensor.NumDim = dims->size(); dmaTileBdTensor.Dim = static_cast( - calloc(dims->size(), sizeof(XAie_DmaDimDesc))); + calloc(dmaTileBdTensor.NumDim, sizeof(XAie_DmaDimDesc))); if (!dmaTileBdTensor.Dim) return bdOp.emitError("couldn't allocate array of XAie_DmaDimDesc"); - // TODO(max): rethink this? + // libxaie requires stride in multiples of 32b + double elementWidthIn32bWords = + static_cast(bdOp.getBufferElementTypeWidthInBytes()) / 4.0; for (size_t i = 0; i < dims->size(); i++) { // Pass down dimensions in reverse order; in the MLIR, this allows // us to specify step sizes/wraps in the same order as we would // access a multi-dim C array, with the highest dimension first. int j = dims->size() - i - 1; - // Assume AIE-ML architecture; we assert this above - // TODO(max): no we don't - dmaTileBdTensor.Dim[j].AieMlDimDesc = {dims.value()[i].getStride(), - dims.value()[i].getSize()}; + uint16_t size; + uint32_t stride; + if (j > 0) { + stride = static_cast(dims.value()[i].getStride() * + elementWidthIn32bWords); + size = dims.value()[i].getSize(); + } else { + stride = dims.value()[i].getStride(); + size = static_cast(dims.value()[i].getSize() * + elementWidthIn32bWords); + } + stride = stride > 0 ? stride : 1; + // Assume AIE-ML architecture (ie use AieMlDimDesc instead of AieDimDesc); + // asserted in AIETranslateToCDODirect). + dmaTileBdTensor.Dim[j].AieMlDimDesc = {stride, size}; } - // TODO: Probably need special handling for NOC - // TODO: Might need to adjust step sizes / wraps by -1 TRY_XAIE_API_EMIT_ERROR(bdOp, XAie_DmaSetMultiDimAddr, &dmaTileBd, - &dmaTileBdTensor, basePlusOffset, lenInBytes); + &dmaTileBdTensor, basePlusOffsetInBytes, + lenInBytes); } + // ND zero padding. + std::optional> padDims = + bdOp.getPadDimensions(); + + if (padDims) { + XAie_DmaPadTensor dmaPadTensor = {}; + dmaPadTensor.NumDim = padDims->size(); + dmaPadTensor.PadDesc = static_cast( + calloc(dmaPadTensor.NumDim, sizeof(XAie_PadDesc))); + if (!dmaPadTensor.PadDesc) + return bdOp.emitError("couldn't allocate array of XAie_PadDesc"); + // libxaie requires stride in multiples of 32b + double elementWidthIn32bWords = + static_cast(bdOp.getBufferElementTypeWidthInBytes()) / 4.0; + for (size_t i = 0; i < padDims->size(); i++) { + // Pass down dimensions in reverse order. + int j = padDims->size() - i - 1; + uint8_t before; + uint8_t after; + if (j > 0) { + before = static_cast(padDims.value()[i].getConstPadBefore()); + after = static_cast(padDims.value()[i].getConstPadAfter()); + } else { + before = static_cast(padDims.value()[i].getConstPadBefore() * + elementWidthIn32bWords); + after = static_cast(padDims.value()[i].getConstPadAfter() * + elementWidthIn32bWords); + } + dmaPadTensor.PadDesc[j] = {before, after}; + } + TRY_XAIE_API_EMIT_ERROR(bdOp, XAie_DmaSetPadding, &dmaTileBd, + &dmaPadTensor); + } if (nextBdId) { auto enableNextBd = 1; TRY_XAIE_API_EMIT_ERROR(bdOp, XAie_DmaSetNextBd, &dmaTileBd, nextBdId.value(), enableNextBd); } + if (auto packetInfo = bdOp.getPacket()) { + packetType = packetInfo->getPktType(); + packetID = packetInfo->getPktId(); + } + if (packetID) { - assert(packetType && "must have packetType with packetID"); - if (bdOp.getLenValue() == 0) + if (!packetType) + bdOp.emitError("must have packetType with packetID"); + if (bdOp.getLen() == 0) return bdOp.emitOpError( "For MM2S channels, if Buffer_Length=0 then Enable_Packet must be " "set to 0, otherwise behavior is undefined (3.7.8 arch spec)"); @@ -302,16 +379,7 @@ LogicalResult AIERTXControl::configureSwitches(DeviceOp &targetOp) { int32_t col = switchboxOp.colIndex(); int32_t row = switchboxOp.rowIndex(); XAie_LocType tileLoc = XAie_TileLoc(col, row); - assert(targetOp.getDevice() == AIEDevice::ipu && - "Only IPU currently supported"); - if (row == 0) { - // FIXME hack for TCT routing - // TODO Support both channels - auto slvPortNum = 0; - auto mstrPortNum = 0; - TRY_XAIE_API_EMIT_ERROR(switchboxOp, XAie_StrmConnCctEnable, &devInst, - tileLoc, CTRL, slvPortNum, SOUTH, mstrPortNum); - } + assert(targetModel.isNPU() && "Only NPU currently supported"); Block &b = switchboxOp.getConnections().front(); for (auto connectOp : b.getOps()) @@ -322,50 +390,60 @@ LogicalResult AIERTXControl::configureSwitches(DeviceOp &targetOp) { WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at(connectOp.getDestBundle()), connectOp.destIndex()); - for (auto connectOp : b.getOps()) { + for (auto masterSetOp : b.getOps()) { int mask = 0; int arbiter = -1; - for (auto val : connectOp.getAmsels()) { + for (auto val : masterSetOp.getAmsels()) { AMSelOp amsel = cast(val.getDefiningOp()); arbiter = amsel.arbiterIndex(); int msel = amsel.getMselValue(); mask |= (1 << msel); } - bool isdma = connectOp.getDestBundle() == WireBundle::DMA; + // the default is to keep header + bool keepHeader = true; + // the default for dma destinations is to drop the header + if (masterSetOp.getDestBundle() == WireBundle::DMA) + keepHeader = false; // assume a connection going south from row zero gets wired to shimdma - // by a shimmux. TODO: fix the assumption - if (!isdma && (switchboxOp.rowIndex() == 0)) - isdma = connectOp.getDestBundle() == WireBundle::South; - // Flag for overriding DROP_HEADER. TODO: Formalize this in tablegen - isdma &= !connectOp->hasAttr("keep_pkt_header"); - auto dropHeader = - isdma ? XAIE_SS_PKT_DROP_HEADER : XAIE_SS_PKT_DONOT_DROP_HEADER; + // by a shimmux. + if (switchboxOp.rowIndex() == 0 && + masterSetOp.getDestBundle() == WireBundle::South) + keepHeader = false; + + // "keep_pkt_header" attribute overrides the above defaults, if set + if (auto keep = masterSetOp.getKeepPktHeader()) + keepHeader = *keep; + + auto dropHeader = keepHeader ? XAIE_SS_PKT_DONOT_DROP_HEADER + : XAIE_SS_PKT_DROP_HEADER; TRY_XAIE_API_EMIT_ERROR( - connectOp, XAie_StrmPktSwMstrPortEnable, &devInst, tileLoc, - WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at(connectOp.getDestBundle()), - connectOp.destIndex(), dropHeader, arbiter, mask); + masterSetOp, XAie_StrmPktSwMstrPortEnable, &devInst, tileLoc, + WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at(masterSetOp.getDestBundle()), + masterSetOp.destIndex(), dropHeader, arbiter, mask); } - for (auto connectOp : b.getOps()) { + for (auto packetRulesOp : b.getOps()) { int slot = 0; - Block &block = connectOp.getRules().front(); + Block &block = packetRulesOp.getRules().front(); for (auto slotOp : block.getOps()) { AMSelOp amselOp = cast(slotOp.getAmsel().getDefiningOp()); int arbiter = amselOp.arbiterIndex(); int msel = amselOp.getMselValue(); - TRY_XAIE_API_EMIT_ERROR( - connectOp, XAie_StrmPktSwSlavePortEnable, &devInst, tileLoc, - WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at(connectOp.getSourceBundle()), - connectOp.sourceIndex()); + TRY_XAIE_API_EMIT_ERROR(packetRulesOp, XAie_StrmPktSwSlavePortEnable, + &devInst, tileLoc, + WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at( + packetRulesOp.getSourceBundle()), + packetRulesOp.sourceIndex()); auto packetInit = XAie_PacketInit(slotOp.valueInt(), /*PktType*/ 0); // TODO Need to better define packet id,type used here - TRY_XAIE_API_EMIT_ERROR( - connectOp, XAie_StrmPktSwSlaveSlotEnable, &devInst, tileLoc, - WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at(connectOp.getSourceBundle()), - connectOp.sourceIndex(), slot, packetInit, slotOp.maskInt(), msel, - arbiter); + TRY_XAIE_API_EMIT_ERROR(packetRulesOp, XAie_StrmPktSwSlaveSlotEnable, + &devInst, tileLoc, + WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at( + packetRulesOp.getSourceBundle()), + packetRulesOp.sourceIndex(), slot, packetInit, + slotOp.maskInt(), msel, arbiter); slot++; } } @@ -414,10 +492,75 @@ LogicalResult AIERTXControl::configureSwitches(DeviceOp &targetOp) { static_cast(configOp.getOutputDir()))); } } + return success(); } -LogicalResult AIERTXControl::enableCoresInDevice(DeviceOp &targetOp) { +LogicalResult AIERTXControl::addInitConfig(DeviceOp &targetOp) { + + if (failed(initLocks(targetOp))) { + return failure(); + } + + auto memOps = llvm::to_vector_of(targetOp.getOps()); + llvm::append_range(memOps, targetOp.getOps()); + llvm::append_range(memOps, targetOp.getOps()); + for (TileElement memOp : memOps) { + int col = memOp.getTileID().col; + int row = memOp.getTileID().row; + XAie_LocType tileLoc = XAie_TileLoc(col, row); + + // handle DMA ops separately + auto dmaOps = llvm::to_vector_of( + memOp.getOperation()->getRegion(0).getOps()); + if (!dmaOps.empty()) { + for (auto dmaOp : dmaOps) + for (auto &bdRegion : dmaOp.getBds()) { + Block &block = bdRegion.getBlocks().front(); + if (failed(configureLocksAndBd(block, tileLoc))) + return failure(); + } + } else { + for (Block &block : memOp.getOperation()->getRegion(0)) { + if (block.getOps().empty()) + continue; + if (failed(configureLocksAndBd(block, tileLoc))) + return failure(); + } + } + + if (!dmaOps.empty()) + for (auto dmaOp : dmaOps) { + auto &block = dmaOp.getBds().front().getBlocks().front(); + DMABDOp bd = *block.getOps().begin(); + if (failed(pushToBdQueueAndEnable( + *dmaOp.getOperation(), tileLoc, + dmaOp.getChannelIndex(), dmaOp.getChannelDir(), + bd.getBdId().value(), dmaOp.getRepeatCount()))) + return failure(); + } + else + for (Block &block : memOp.getOperation()->getRegion(0)) { + for (auto op : block.getOps()) { + DMABDOp bd = *op.getDest()->getOps().begin(); + int chNum = op.getChannelIndex(); + auto channelDir = op.getChannelDir(); + if (failed(pushToBdQueueAndEnable( + *bd.getOperation(), tileLoc, chNum, channelDir, + bd.getBdId().value(), op.getRepeatCount()))) + return failure(); + } + } + } + + if (failed(configureSwitches(targetOp))) { + return failure(); + } + + return success(); +} + +LogicalResult AIERTXControl::addCoreEnable(DeviceOp &targetOp) { // Start execution of all the cores. for (auto tileOp : targetOp.getOps()) { auto tileLoc = XAie_TileLoc(tileOp.colIndex(), tileOp.rowIndex()); @@ -427,6 +570,55 @@ LogicalResult AIERTXControl::enableCoresInDevice(DeviceOp &targetOp) { return success(); } +LogicalResult AIERTXControl::addAieElf(uint8_t col, uint8_t row, + const StringRef elfPath, bool aieSim) { + TRY_XAIE_API_LOGICAL_RESULT(XAie_CoreDisable, &devInst, + XAie_TileLoc(col, row)); + TRY_XAIE_API_LOGICAL_RESULT(XAie_DmaChannelResetAll, &devInst, + XAie_TileLoc(col, row), + XAie_DmaChReset::DMA_CHANNEL_RESET); + + // loadSym: Load symbols from .map file. This argument is not used when + // __AIESIM__ is not defined. + TRY_XAIE_API_LOGICAL_RESULT(XAie_LoadElf, &devInst, XAie_TileLoc(col, row), + elfPath.str().c_str(), /*loadSym*/ aieSim); + + TRY_XAIE_API_LOGICAL_RESULT(XAie_DmaChannelResetAll, &devInst, + XAie_TileLoc(col, row), + XAie_DmaChReset::DMA_CHANNEL_UNRESET); + + return success(); +} + +LogicalResult AIERTXControl::addAieElfs(DeviceOp &targetOp, + const StringRef workDirPath, + bool aieSim) { + for (auto tileOp : targetOp.getOps()) + if (tileOp.isShimNOCorPLTile()) { + // Resets no needed with V2 kernel driver + } else { + int col = tileOp.colIndex(); + int row = tileOp.rowIndex(); + if (auto coreOp = tileOp.getCoreOp()) { + std::string fileName; + if (auto fileAttr = coreOp.getElfFile()) + fileName = fileAttr->str(); + else + fileName = (llvm::Twine("core_") + std::to_string(col) + "_" + + std::to_string(row) + ".elf") + .str(); + auto ps = std::filesystem::path::preferred_separator; + if (failed(addAieElf( + col, row, + (llvm::Twine(workDirPath) + std::string(1, ps) + fileName) + .str(), + aieSim))) + return failure(); + } + } + return success(); +} + void AIERTXControl::dmaUpdateBdAddr(int col, int row, size_t addr, size_t bdId) { auto tileLoc = XAie_TileLoc(col, row); diff --git a/lib/Targets/AIETargetCDODirect.cpp b/lib/Targets/AIETargetCDODirect.cpp index 09824e1abe..7818055bf6 100644 --- a/lib/Targets/AIETargetCDODirect.cpp +++ b/lib/Targets/AIETargetCDODirect.cpp @@ -46,9 +46,8 @@ extern "C" { #define DEBUG_TYPE "aie-generate-cdo" using namespace mlir; - - - +using namespace xilinx; +using namespace xilinx::AIE; static void initializeCDOGenerator(byte_ordering endianness, bool cdoDebug) { // Enables AXI-MM prints for configs being added in CDO @@ -74,11 +73,12 @@ generateCDOBinary(const StringRef outputPath, return success(); } -static LogicalResult generateCDOBinariesSeparately(AIEControl &ctl, +static LogicalResult generateCDOBinariesSeparately(AIERTXControl &ctl, const StringRef workDirPath, DeviceOp &targetOp, bool aieSim, bool enableCores) { + auto ps = std::filesystem::path::preferred_separator; if (failed(generateCDOBinary( (llvm::Twine(workDirPath) + std::string(1, ps) + "aie_cdo_elfs.bin") @@ -104,10 +104,12 @@ static LogicalResult generateCDOBinariesSeparately(AIEControl &ctl, return success(); } -static LogicalResult generateCDOUnified(AIEControl &ctl, +static LogicalResult generateCDOUnified(AIERTXControl &ctl, const StringRef workDirPath, DeviceOp &targetOp, bool aieSim, bool enableCores) { +auto ps = std::filesystem::path::preferred_separator; + return generateCDOBinary( (llvm::Twine(workDirPath) + std::string(1, ps) + "aie_cdo.bin").str(), [&ctl, &targetOp, &workDirPath, &aieSim, &enableCores] { @@ -139,7 +141,7 @@ translateToCDODirect(ModuleOp m, llvm::StringRef workDirPath, // shim dma on tile (0,0) are hard-coded assumptions about NPU... assert(targetModel.isNPU() && "Only NPU currently supported"); - AIERTXControl ctl(targetOp.getTargetModel()); + AIERTXControl ctl(targetModel); if (failed(ctl.setIOBackend(aieSim, xaieDebug))) return failure(); initializeCDOGenerator(endianness, cdoDebug); @@ -317,7 +319,7 @@ parseTransactionBinary(const std::vector &data, return num_cols; } -static LogicalResult generateTxn(AIEControl &ctl, const StringRef workDirPath, +static LogicalResult generateTxn(AIERTXControl &ctl, const StringRef workDirPath, DeviceOp &targetOp, bool aieSim, bool enableElfs, bool enableInit, bool enableCores) { @@ -347,7 +349,9 @@ static LogicalResult translateToTxn(ModuleOp m, std::vector &output, if (!targetModel.isNPU()) return failure(); - AIEControl ctl(aieSim, xaieDebug, targetModel); + AIERTXControl ctl(targetModel); + if (failed(ctl.setIOBackend(aieSim, xaieDebug))) + return failure(); // start collecting transations XAie_StartTransaction(&ctl.devInst, XAIE_TRANSACTION_DISABLE_AUTO_FLUSH); diff --git a/lib/Targets/CMakeLists.txt b/lib/Targets/CMakeLists.txt index 110e6b90a8..29acfde613 100644 --- a/lib/Targets/CMakeLists.txt +++ b/lib/Targets/CMakeLists.txt @@ -25,7 +25,7 @@ target_include_directories(AIERTX SYSTEM PRIVATE ${BOOTGEN_SOURCE_DIR}) target_include_directories(obj.AIERTX SYSTEM PRIVATE ${BOOTGEN_SOURCE_DIR}) add_dependencies(obj.AIERTX xaienginecdo_static xaienginecdo_static-headers) -set(_sources +add_mlir_library(AIETargets AIETargets.cpp AIETargetBCF.cpp AIETargetCDODirect.cpp diff --git a/python/AIERTXModule.cpp b/python/AIERTXModule.cpp index 75c93f1404..d4e7371f0d 100644 --- a/python/AIERTXModule.cpp +++ b/python/AIERTXModule.cpp @@ -1,11 +1,10 @@ -//===- XRTModule.cpp -------------------------------------------000---*- C++ -//-*-===// +//===- AIERTXModule.cpp -----------------------------------------*- C++ -*-===// // // This file is licensed under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // -// Copyright (C) 2023, Advanced Micro Devices, Inc. +// Copyright (C) 2024, Advanced Micro Devices, Inc. All rights reserved. // //===----------------------------------------------------------------------===// diff --git a/python/aiertx.py b/python/aiertx.py index 7dc325af9b..b7004ab941 100644 --- a/python/aiertx.py +++ b/python/aiertx.py @@ -1,4 +1,4 @@ -# Copyright (C) 2022, Advanced Micro Devices, Inc. +# Copyright (C) 2024, Advanced Micro Devices, Inc. # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception # noinspection PyUnresolvedReferences diff --git a/test/python/aiertx_bindings.py b/test/python/aiertx_bindings.py index 5cd100c836..e7e05215aa 100644 --- a/test/python/aiertx_bindings.py +++ b/test/python/aiertx_bindings.py @@ -2,7 +2,7 @@ # See https://llvm.org/LICENSE.txt for license information. # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception # -# (c) Copyright 2023 AMD Inc. +# Copyright (C) 2024, Advanced Micro Devices, Inc. All rights reserved. # RUN: %python %s | FileCheck %s From 77f82e0b7916d8c1541e6638fcbc648182fee892 Mon Sep 17 00:00:00 2001 From: Jeff Fifield Date: Mon, 9 Sep 2024 15:22:31 -0600 Subject: [PATCH 3/9] fix --- include/aie-c/Translation.h | 3 +-- lib/CAPI/Translation.cpp | 13 ++++++++----- python/AIERTXModule.cpp | 7 +++---- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/include/aie-c/Translation.h b/include/aie-c/Translation.h index c8ed3eeba7..fda7235305 100644 --- a/include/aie-c/Translation.h +++ b/include/aie-c/Translation.h @@ -47,8 +47,7 @@ struct AieRtxControl { }; using AieRtxControl = struct AieRtxControl; -MLIR_CAPI_EXPORTED AieRtxControl getAieRtxControl(size_t partitionStartCol, - size_t partitionNumCols); +MLIR_CAPI_EXPORTED AieRtxControl getAieRtxControl(size_t partitionNumCols); MLIR_CAPI_EXPORTED void freeAieRtxControl(AieRtxControl aieCtl); MLIR_CAPI_EXPORTED void aieRtxStartTransaction(AieRtxControl aieCtl); MLIR_CAPI_EXPORTED void aieRtxDmaUpdateBdAddr(AieRtxControl aieCtl, int col, diff --git a/lib/CAPI/Translation.cpp b/lib/CAPI/Translation.cpp index be4043cec8..c3d6e1df90 100644 --- a/lib/CAPI/Translation.cpp +++ b/lib/CAPI/Translation.cpp @@ -228,11 +228,14 @@ MlirStringRef aieLLVMLink(MlirStringRef *modules, int nModules) { DEFINE_C_API_PTR_METHODS(AieRtxControl, xilinx::AIE::AIERTXControl) -AieRtxControl getAieRtxControl(size_t partitionStartCol, - size_t partitionNumCols) { - NPUTargetModel targetModel; - AIERTXControl *ctl = - new AIERTXControl(targetModel); +AieRtxControl getAieRtxControl(size_t partitionNumCols) { + std::vector devices{AIEDevice::npu1_1col, AIEDevice::npu1_2col, + AIEDevice::npu1_3col, AIEDevice::npu1_4col, + AIEDevice::npu1}; + const BaseNPUTargetModel &targetModel = + (const BaseNPUTargetModel &)xilinx::AIE::getTargetModel( + devices[partitionNumCols - 1]); + AIERTXControl *ctl = new AIERTXControl(targetModel); return wrap(ctl); } diff --git a/python/AIERTXModule.cpp b/python/AIERTXModule.cpp index d4e7371f0d..39f856b49d 100644 --- a/python/AIERTXModule.cpp +++ b/python/AIERTXModule.cpp @@ -20,8 +20,8 @@ using namespace py::literals; class PyAIERTXControl { public: - PyAIERTXControl(size_t partitionStartCol, size_t partitionNumCols) - : ctl(getAieRtxControl(partitionStartCol, partitionNumCols)) {} + PyAIERTXControl(size_t partitionNumCols) + : ctl(getAieRtxControl(partitionNumCols)) {} ~PyAIERTXControl() { freeAieRtxControl(ctl); } @@ -31,8 +31,7 @@ class PyAIERTXControl { PYBIND11_MODULE(_aiertx, m) { py::class_(m, "AIERTXControl", py::module_local()) - .def(py::init(), "partition_start_col"_a, - "partition_num_cols"_a) + .def(py::init(), "partition_num_cols"_a) .def("start_transaction", [](PyAIERTXControl &self) { aieRtxStartTransaction(self.ctl); }) .def("export_serialized_transaction", From 3934ec4f43cc53cb8a87ba13276f73d42a25142c Mon Sep 17 00:00:00 2001 From: Jeff Fifield Date: Mon, 9 Sep 2024 15:32:15 -0600 Subject: [PATCH 4/9] clang-format --- lib/Targets/AIERTX.cpp | 18 +++++++++--------- lib/Targets/AIETargetCDODirect.cpp | 9 ++++----- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/lib/Targets/AIERTX.cpp b/lib/Targets/AIERTX.cpp index d8057dcd67..e737131dd8 100644 --- a/lib/Targets/AIERTX.cpp +++ b/lib/Targets/AIERTX.cpp @@ -416,8 +416,8 @@ LogicalResult AIERTXControl::configureSwitches(DeviceOp &targetOp) { if (auto keep = masterSetOp.getKeepPktHeader()) keepHeader = *keep; - auto dropHeader = keepHeader ? XAIE_SS_PKT_DONOT_DROP_HEADER - : XAIE_SS_PKT_DROP_HEADER; + auto dropHeader = + keepHeader ? XAIE_SS_PKT_DONOT_DROP_HEADER : XAIE_SS_PKT_DROP_HEADER; TRY_XAIE_API_EMIT_ERROR( masterSetOp, XAie_StrmPktSwMstrPortEnable, &devInst, tileLoc, WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at(masterSetOp.getDestBundle()), @@ -534,9 +534,9 @@ LogicalResult AIERTXControl::addInitConfig(DeviceOp &targetOp) { auto &block = dmaOp.getBds().front().getBlocks().front(); DMABDOp bd = *block.getOps().begin(); if (failed(pushToBdQueueAndEnable( - *dmaOp.getOperation(), tileLoc, - dmaOp.getChannelIndex(), dmaOp.getChannelDir(), - bd.getBdId().value(), dmaOp.getRepeatCount()))) + *dmaOp.getOperation(), tileLoc, dmaOp.getChannelIndex(), + dmaOp.getChannelDir(), bd.getBdId().value(), + dmaOp.getRepeatCount()))) return failure(); } else @@ -545,9 +545,9 @@ LogicalResult AIERTXControl::addInitConfig(DeviceOp &targetOp) { DMABDOp bd = *op.getDest()->getOps().begin(); int chNum = op.getChannelIndex(); auto channelDir = op.getChannelDir(); - if (failed(pushToBdQueueAndEnable( - *bd.getOperation(), tileLoc, chNum, channelDir, - bd.getBdId().value(), op.getRepeatCount()))) + if (failed(pushToBdQueueAndEnable(*bd.getOperation(), tileLoc, chNum, + channelDir, bd.getBdId().value(), + op.getRepeatCount()))) return failure(); } } @@ -606,7 +606,7 @@ LogicalResult AIERTXControl::addAieElfs(DeviceOp &targetOp, else fileName = (llvm::Twine("core_") + std::to_string(col) + "_" + std::to_string(row) + ".elf") - .str(); + .str(); auto ps = std::filesystem::path::preferred_separator; if (failed(addAieElf( col, row, diff --git a/lib/Targets/AIETargetCDODirect.cpp b/lib/Targets/AIETargetCDODirect.cpp index 7818055bf6..ec2d51a107 100644 --- a/lib/Targets/AIETargetCDODirect.cpp +++ b/lib/Targets/AIETargetCDODirect.cpp @@ -108,7 +108,7 @@ static LogicalResult generateCDOUnified(AIERTXControl &ctl, const StringRef workDirPath, DeviceOp &targetOp, bool aieSim, bool enableCores) { -auto ps = std::filesystem::path::preferred_separator; + auto ps = std::filesystem::path::preferred_separator; return generateCDOBinary( (llvm::Twine(workDirPath) + std::string(1, ps) + "aie_cdo.bin").str(), @@ -319,10 +319,9 @@ parseTransactionBinary(const std::vector &data, return num_cols; } -static LogicalResult generateTxn(AIERTXControl &ctl, const StringRef workDirPath, - DeviceOp &targetOp, bool aieSim, - bool enableElfs, bool enableInit, - bool enableCores) { +static LogicalResult +generateTxn(AIERTXControl &ctl, const StringRef workDirPath, DeviceOp &targetOp, + bool aieSim, bool enableElfs, bool enableInit, bool enableCores) { if (enableElfs && !targetOp.getOps().empty() && failed(ctl.addAieElfs(targetOp, workDirPath, aieSim))) return failure(); From 870326ce6d74686b49d43cbb59df0d5f96931218 Mon Sep 17 00:00:00 2001 From: Jeff Fifield Date: Mon, 9 Sep 2024 15:39:58 -0600 Subject: [PATCH 5/9] fix again --- test/python/aiertx_bindings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/python/aiertx_bindings.py b/test/python/aiertx_bindings.py index e7e05215aa..730ba7444c 100644 --- a/test/python/aiertx_bindings.py +++ b/test/python/aiertx_bindings.py @@ -14,7 +14,7 @@ # CHECK-LABEL: simple @construct_and_print_module def simple(module): - ctl = AIERTXControl(1, 4) + ctl = AIERTXControl(4) ctl.start_transaction() ctl.dma_update_bd_addr(0, 0, DDR_AIE_ADDR_OFFSET, 0) ctl.export_serialized_transaction() From c6b86db736832679ffd9147ffb59ce0bd074d573 Mon Sep 17 00:00:00 2001 From: Jeff Fifield Date: Mon, 9 Sep 2024 16:37:23 -0600 Subject: [PATCH 6/9] Update bindings to use TargetModel --- include/aie-c/Translation.h | 4 +++- lib/CAPI/Translation.cpp | 9 +++------ python/AIEMLIRModule.cpp | 12 ++---------- python/AIERTXModule.cpp | 9 ++++++--- python/PyTypes.h | 25 +++++++++++++++++++++++++ test/python/aiertx_bindings.py | 5 +++-- 6 files changed, 42 insertions(+), 22 deletions(-) create mode 100644 python/PyTypes.h diff --git a/include/aie-c/Translation.h b/include/aie-c/Translation.h index fda7235305..e8cf280ee5 100644 --- a/include/aie-c/Translation.h +++ b/include/aie-c/Translation.h @@ -8,6 +8,8 @@ #ifndef AIE_C_TRANSLATION_H #define AIE_C_TRANSLATION_H +#include "aie-c/TargetModel.h" + #include "mlir-c/IR.h" #include "mlir-c/Support.h" #include "mlir/CAPI/Wrap.h" @@ -47,7 +49,7 @@ struct AieRtxControl { }; using AieRtxControl = struct AieRtxControl; -MLIR_CAPI_EXPORTED AieRtxControl getAieRtxControl(size_t partitionNumCols); +MLIR_CAPI_EXPORTED AieRtxControl getAieRtxControl(AieTargetModel tm); MLIR_CAPI_EXPORTED void freeAieRtxControl(AieRtxControl aieCtl); MLIR_CAPI_EXPORTED void aieRtxStartTransaction(AieRtxControl aieCtl); MLIR_CAPI_EXPORTED void aieRtxDmaUpdateBdAddr(AieRtxControl aieCtl, int col, diff --git a/lib/CAPI/Translation.cpp b/lib/CAPI/Translation.cpp index c3d6e1df90..8de5759088 100644 --- a/lib/CAPI/Translation.cpp +++ b/lib/CAPI/Translation.cpp @@ -228,13 +228,10 @@ MlirStringRef aieLLVMLink(MlirStringRef *modules, int nModules) { DEFINE_C_API_PTR_METHODS(AieRtxControl, xilinx::AIE::AIERTXControl) -AieRtxControl getAieRtxControl(size_t partitionNumCols) { - std::vector devices{AIEDevice::npu1_1col, AIEDevice::npu1_2col, - AIEDevice::npu1_3col, AIEDevice::npu1_4col, - AIEDevice::npu1}; +AieRtxControl getAieRtxControl(AieTargetModel tm) { + // unwrap the target model const BaseNPUTargetModel &targetModel = - (const BaseNPUTargetModel &)xilinx::AIE::getTargetModel( - devices[partitionNumCols - 1]); + *reinterpret_cast(tm.d); AIERTXControl *ctl = new AIERTXControl(targetModel); return wrap(ctl); } diff --git a/python/AIEMLIRModule.cpp b/python/AIEMLIRModule.cpp index 481451fe73..4775499e72 100644 --- a/python/AIEMLIRModule.cpp +++ b/python/AIEMLIRModule.cpp @@ -10,6 +10,8 @@ #include "aie-c/TargetModel.h" #include "aie-c/Translation.h" +#include "PyTypes.h" + #include "mlir-c/IR.h" #include "mlir-c/Support.h" #include "mlir/Bindings/Python/PybindAdaptors.h" @@ -28,16 +30,6 @@ using namespace mlir::python::adaptors; namespace py = pybind11; using namespace py::literals; -class PyAieTargetModel { -public: - PyAieTargetModel(AieTargetModel model) : model(model) {} - operator AieTargetModel() const { return model; } - AieTargetModel get() const { return model; } - -private: - AieTargetModel model; -}; - PYBIND11_MODULE(_aie, m) { aieRegisterAllPasses(); diff --git a/python/AIERTXModule.cpp b/python/AIERTXModule.cpp index 39f856b49d..e778bcf5b6 100644 --- a/python/AIERTXModule.cpp +++ b/python/AIERTXModule.cpp @@ -8,8 +8,11 @@ // //===----------------------------------------------------------------------===// +#include "aie-c/TargetModel.h" #include "aie-c/Translation.h" +#include "PyTypes.h" + #include #include @@ -20,8 +23,8 @@ using namespace py::literals; class PyAIERTXControl { public: - PyAIERTXControl(size_t partitionNumCols) - : ctl(getAieRtxControl(partitionNumCols)) {} + PyAIERTXControl(AieTargetModel targetModel) + : ctl(getAieRtxControl(targetModel)) {} ~PyAIERTXControl() { freeAieRtxControl(ctl); } @@ -31,7 +34,7 @@ class PyAIERTXControl { PYBIND11_MODULE(_aiertx, m) { py::class_(m, "AIERTXControl", py::module_local()) - .def(py::init(), "partition_num_cols"_a) + .def(py::init(), "target_model"_a) .def("start_transaction", [](PyAIERTXControl &self) { aieRtxStartTransaction(self.ctl); }) .def("export_serialized_transaction", diff --git a/python/PyTypes.h b/python/PyTypes.h new file mode 100644 index 0000000000..589131fb4e --- /dev/null +++ b/python/PyTypes.h @@ -0,0 +1,25 @@ +//===- PyTypes.h ------------------------------------------------*- C++ -*-===// +// +// This file is licensed under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// (c) Copyright 2024 Advanced Micro Devices, Inc. +// +//===----------------------------------------------------------------------===// +#ifndef AIE_PYTYPES_H +#define AIE_PYTYPES_H + +#include "aie-c/TargetModel.h" + +class PyAieTargetModel { +public: + PyAieTargetModel(AieTargetModel model) : model(model) {} + operator AieTargetModel() const { return model; } + AieTargetModel get() const { return model; } + +private: + AieTargetModel model; +}; + +#endif // AIE_PYTYPES_H \ No newline at end of file diff --git a/test/python/aiertx_bindings.py b/test/python/aiertx_bindings.py index 730ba7444c..670b1317c4 100644 --- a/test/python/aiertx_bindings.py +++ b/test/python/aiertx_bindings.py @@ -9,12 +9,13 @@ from aie.aiertx import AIERTXControl from util import construct_and_print_module from aie.dialects.aiex import DDR_AIE_ADDR_OFFSET - +from aie.dialects.aie import AIEDevice, get_target_model # CHECK-LABEL: simple @construct_and_print_module def simple(module): - ctl = AIERTXControl(4) + tm = get_target_model(AIEDevice.npu1_4col) + ctl = AIERTXControl(tm) ctl.start_transaction() ctl.dma_update_bd_addr(0, 0, DDR_AIE_ADDR_OFFSET, 0) ctl.export_serialized_transaction() From 0c7c9d5eb93c2e7b333f289f846034194ca780fb Mon Sep 17 00:00:00 2001 From: Jeff Fifield Date: Mon, 9 Sep 2024 16:46:19 -0600 Subject: [PATCH 7/9] format --- test/python/aiertx_bindings.py | 1 + 1 file changed, 1 insertion(+) diff --git a/test/python/aiertx_bindings.py b/test/python/aiertx_bindings.py index 670b1317c4..d38dc7ab20 100644 --- a/test/python/aiertx_bindings.py +++ b/test/python/aiertx_bindings.py @@ -11,6 +11,7 @@ from aie.dialects.aiex import DDR_AIE_ADDR_OFFSET from aie.dialects.aie import AIEDevice, get_target_model + # CHECK-LABEL: simple @construct_and_print_module def simple(module): From ca65f4bede89233d9601e9308462a943c06b33bb Mon Sep 17 00:00:00 2001 From: Jeff Fifield Date: Tue, 10 Sep 2024 12:24:56 -0600 Subject: [PATCH 8/9] Rename header file --- {python => include/aie/Bindings}/PyTypes.h | 6 +++--- python/AIEMLIRModule.cpp | 2 +- python/AIERTXModule.cpp | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) rename {python => include/aie/Bindings}/PyTypes.h (87%) diff --git a/python/PyTypes.h b/include/aie/Bindings/PyTypes.h similarity index 87% rename from python/PyTypes.h rename to include/aie/Bindings/PyTypes.h index 589131fb4e..f1c4694b99 100644 --- a/python/PyTypes.h +++ b/include/aie/Bindings/PyTypes.h @@ -7,8 +7,8 @@ // (c) Copyright 2024 Advanced Micro Devices, Inc. // //===----------------------------------------------------------------------===// -#ifndef AIE_PYTYPES_H -#define AIE_PYTYPES_H +#ifndef AIE_BINDINGS_PYTYPES_H +#define AIE_BINDINGS_PYTYPES_H #include "aie-c/TargetModel.h" @@ -22,4 +22,4 @@ class PyAieTargetModel { AieTargetModel model; }; -#endif // AIE_PYTYPES_H \ No newline at end of file +#endif // AIE_BINDINGS_PYTYPES_H \ No newline at end of file diff --git a/python/AIEMLIRModule.cpp b/python/AIEMLIRModule.cpp index 4775499e72..2d71249e72 100644 --- a/python/AIEMLIRModule.cpp +++ b/python/AIEMLIRModule.cpp @@ -10,7 +10,7 @@ #include "aie-c/TargetModel.h" #include "aie-c/Translation.h" -#include "PyTypes.h" +#include "aie/Bindings/PyTypes.h" #include "mlir-c/IR.h" #include "mlir-c/Support.h" diff --git a/python/AIERTXModule.cpp b/python/AIERTXModule.cpp index e778bcf5b6..a1564dbebe 100644 --- a/python/AIERTXModule.cpp +++ b/python/AIERTXModule.cpp @@ -11,7 +11,7 @@ #include "aie-c/TargetModel.h" #include "aie-c/Translation.h" -#include "PyTypes.h" +#include "aie/Bindings/PyTypes.h" #include #include From 31356387c8ff1b66f2c0b363a06d72681e9c39e5 Mon Sep 17 00:00:00 2001 From: Jeff Fifield Date: Tue, 10 Sep 2024 13:21:28 -0600 Subject: [PATCH 9/9] replace aiertx with aiert (drop the x) --- include/aie-c/Translation.h | 19 +++--- include/aie/Targets/{AIERTX.h => AIERT.h} | 20 +++---- lib/CAPI/Translation.cpp | 26 ++++---- lib/Targets/{AIERTX.cpp => AIERT.cpp} | 60 +++++++++---------- lib/Targets/AIETargetCDODirect.cpp | 17 +++--- lib/Targets/CMakeLists.txt | 14 ++--- python/{AIERTXModule.cpp => AIERTModule.cpp} | 27 ++++----- python/CMakeLists.txt | 12 ++-- python/{aiertx.py => aiert.py} | 2 +- .../{aiertx_bindings.py => aiert_bindings.py} | 4 +- 10 files changed, 100 insertions(+), 101 deletions(-) rename include/aie/Targets/{AIERTX.h => AIERT.h} (95%) rename lib/Targets/{AIERTX.cpp => AIERT.cpp} (92%) rename python/{AIERTXModule.cpp => AIERTModule.cpp} (55%) rename python/{aiertx.py => aiert.py} (81%) rename test/python/{aiertx_bindings.py => aiert_bindings.py} (91%) diff --git a/include/aie-c/Translation.h b/include/aie-c/Translation.h index e8cf280ee5..37f075729a 100644 --- a/include/aie-c/Translation.h +++ b/include/aie-c/Translation.h @@ -44,18 +44,17 @@ MLIR_CAPI_EXPORTED MlirLogicalResult aieTranslateToCtrlpkt( MLIR_CAPI_EXPORTED MlirOperation aieTranslateBinaryToTxn(MlirContext ctx, MlirStringRef binary); -struct AieRtxControl { +struct AieRtControl { void *ptr; }; -using AieRtxControl = struct AieRtxControl; - -MLIR_CAPI_EXPORTED AieRtxControl getAieRtxControl(AieTargetModel tm); -MLIR_CAPI_EXPORTED void freeAieRtxControl(AieRtxControl aieCtl); -MLIR_CAPI_EXPORTED void aieRtxStartTransaction(AieRtxControl aieCtl); -MLIR_CAPI_EXPORTED void aieRtxDmaUpdateBdAddr(AieRtxControl aieCtl, int col, - int row, size_t addr, - size_t bdId); -MLIR_CAPI_EXPORTED void aieRtxExportSerializedTransaction(AieRtxControl aieCtl); +using AieRtControl = struct AieRtControl; + +MLIR_CAPI_EXPORTED AieRtControl getAieRtControl(AieTargetModel tm); +MLIR_CAPI_EXPORTED void freeAieRtControl(AieRtControl aieCtl); +MLIR_CAPI_EXPORTED void aieRtStartTransaction(AieRtControl aieCtl); +MLIR_CAPI_EXPORTED void aieRtDmaUpdateBdAddr(AieRtControl aieCtl, int col, + int row, size_t addr, size_t bdId); +MLIR_CAPI_EXPORTED void aieRtExportSerializedTransaction(AieRtControl aieCtl); #ifdef __cplusplus } diff --git a/include/aie/Targets/AIERTX.h b/include/aie/Targets/AIERT.h similarity index 95% rename from include/aie/Targets/AIERTX.h rename to include/aie/Targets/AIERT.h index 98dd07ffb5..48950401ba 100644 --- a/include/aie/Targets/AIERTX.h +++ b/include/aie/Targets/AIERT.h @@ -1,4 +1,4 @@ -//===- AIERTX.h -------------------------------------------------*- C++ -*-===// +//===- AIERT.h --------------------------------------------------*- C++ -*-===// // // This file is licensed under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -8,8 +8,8 @@ // //===----------------------------------------------------------------------===// -#ifndef AIE_AIERTX_H -#define AIE_AIERTX_H +#ifndef AIE_AIERT_H +#define AIE_AIERT_H #include "aie/Dialect/AIE/IR/AIEDialect.h" #include "aie/Dialect/AIE/IR/AIEEnums.h" @@ -112,7 +112,7 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const XAie_Lock &lock); llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const XAie_Packet &packet); -#define SHOW_AIERTX_ARGS(os, ...) showAIEXRTArgs(os, #__VA_ARGS__, __VA_ARGS__) +#define SHOW_AIERT_ARGS(os, ...) showAIEXRTArgs(os, #__VA_ARGS__, __VA_ARGS__) // So that we can use the pattern if(auto r = TRY_XAIE_API...) { // r is nonzero // } @@ -121,7 +121,7 @@ static_assert(XAIE_OK == 0); #define TRY_XAIE_API_FATAL_ERROR(API, ...) \ do { \ LLVM_DEBUG(llvm::dbgs() << "trying XAIE API: " << #API << " with args: "); \ - LLVM_DEBUG(SHOW_AIERTX_ARGS(llvm::dbgs(), __VA_ARGS__)); \ + LLVM_DEBUG(SHOW_AIERT_ARGS(llvm::dbgs(), __VA_ARGS__)); \ LLVM_DEBUG(llvm::dbgs() << "\n"); \ if (auto r = API(__VA_ARGS__)) \ llvm::report_fatal_error(llvm::Twine(#API " failed with ") + \ @@ -131,7 +131,7 @@ static_assert(XAIE_OK == 0); #define TRY_XAIE_API_EMIT_ERROR(OP, API, ...) \ do { \ LLVM_DEBUG(llvm::dbgs() << "trying XAIE API: " << #API << " with args: "); \ - LLVM_DEBUG(SHOW_AIERTX_ARGS(llvm::dbgs(), __VA_ARGS__)); \ + LLVM_DEBUG(SHOW_AIERT_ARGS(llvm::dbgs(), __VA_ARGS__)); \ LLVM_DEBUG(llvm::dbgs() << "\n"); \ if (auto r = API(__VA_ARGS__)) \ return OP.emitOpError() << #API " failed with " << AIERCTOSTR.at(r); \ @@ -140,7 +140,7 @@ static_assert(XAIE_OK == 0); #define TRY_XAIE_API_LOGICAL_RESULT(API, ...) \ do { \ LLVM_DEBUG(llvm::dbgs() << "trying XAIE API: " << #API << " with args: "); \ - LLVM_DEBUG(SHOW_AIERTX_ARGS(llvm::dbgs(), __VA_ARGS__)); \ + LLVM_DEBUG(SHOW_AIERT_ARGS(llvm::dbgs(), __VA_ARGS__)); \ LLVM_DEBUG(llvm::dbgs() << "\n"); \ if (auto r = API(__VA_ARGS__)) { \ llvm::errs() << #API " failed with " << AIERCTOSTR.at(r); \ @@ -186,12 +186,12 @@ static_assert(XAIE_OK == 0); #define BASE_ADDR_A_INCR 0x80000 namespace xilinx::AIE { -struct AIERTXControl { +struct AIERTControl { XAie_Config configPtr; XAie_DevInst devInst; const BaseNPUTargetModel &targetModel; - AIERTXControl(const xilinx::AIE::BaseNPUTargetModel &tm); + AIERTControl(const xilinx::AIE::BaseNPUTargetModel &tm); mlir::LogicalResult setIOBackend(bool aieSim, bool xaieDebug); mlir::LogicalResult configureBdInBlock(XAie_DmaDesc &dmaTileBd, @@ -223,4 +223,4 @@ struct AIERTXControl { } // namespace xilinx::AIE -#endif // AIE_AIERTX_H +#endif // AIE_AIERT_H diff --git a/lib/CAPI/Translation.cpp b/lib/CAPI/Translation.cpp index 8de5759088..264bebf478 100644 --- a/lib/CAPI/Translation.cpp +++ b/lib/CAPI/Translation.cpp @@ -11,7 +11,7 @@ #include "aie-c/Translation.h" #include "aie/Dialect/AIE/IR/AIETargetModel.h" -#include "aie/Targets/AIERTX.h" +#include "aie/Targets/AIERT.h" #include "aie/Targets/AIETargets.h" #include "mlir-c/IR.h" @@ -226,33 +226,33 @@ MlirStringRef aieLLVMLink(MlirStringRef *modules, int nModules) { return mlirStringRefCreate(cStr, ll.size()); } -DEFINE_C_API_PTR_METHODS(AieRtxControl, xilinx::AIE::AIERTXControl) +DEFINE_C_API_PTR_METHODS(AieRtControl, xilinx::AIE::AIERTControl) -AieRtxControl getAieRtxControl(AieTargetModel tm) { +AieRtControl getAieRtControl(AieTargetModel tm) { // unwrap the target model const BaseNPUTargetModel &targetModel = *reinterpret_cast(tm.d); - AIERTXControl *ctl = new AIERTXControl(targetModel); + AIERTControl *ctl = new AIERTControl(targetModel); return wrap(ctl); } -void freeAieRtxControl(AieRtxControl aieCtl) { - AIERTXControl *ctl = unwrap(aieCtl); +void freeAieRtControl(AieRtControl aieCtl) { + AIERTControl *ctl = unwrap(aieCtl); delete ctl; } -void aieRtxDmaUpdateBdAddr(AieRtxControl aieCtl, int col, int row, size_t addr, - size_t bdId) { - AIERTXControl *ctl = unwrap(aieCtl); +void aieRtDmaUpdateBdAddr(AieRtControl aieCtl, int col, int row, size_t addr, + size_t bdId) { + AIERTControl *ctl = unwrap(aieCtl); ctl->dmaUpdateBdAddr(col, row, addr, bdId); } -void aieRtxStartTransaction(AieRtxControl aieCtl) { - AIERTXControl *ctl = unwrap(aieCtl); +void aieRtStartTransaction(AieRtControl aieCtl) { + AIERTControl *ctl = unwrap(aieCtl); ctl->startTransaction(); } -void aieRtxExportSerializedTransaction(AieRtxControl aieCtl) { - AIERTXControl *ctl = unwrap(aieCtl); +void aieRtExportSerializedTransaction(AieRtControl aieCtl) { + AIERTControl *ctl = unwrap(aieCtl); ctl->exportSerializedTransaction(); } \ No newline at end of file diff --git a/lib/Targets/AIERTX.cpp b/lib/Targets/AIERT.cpp similarity index 92% rename from lib/Targets/AIERTX.cpp rename to lib/Targets/AIERT.cpp index e737131dd8..c0ec5290ad 100644 --- a/lib/Targets/AIERTX.cpp +++ b/lib/Targets/AIERT.cpp @@ -1,4 +1,4 @@ -//===- AIERTX.cpp -----------------------------------------------*- C++ -*-===// +//===- AIERT.cpp ------------------------------------------------*- C++ -*-===// // // This file is licensed under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -8,7 +8,7 @@ // //===----------------------------------------------------------------------===// -#include "aie/Targets/AIERTX.h" +#include "aie/Targets/AIERT.h" #include "mlir/Support/LogicalResult.h" @@ -29,7 +29,7 @@ extern "C" { using namespace mlir; -#define DEBUG_TYPE "aie-aiertx" +#define DEBUG_TYPE "aie-aiert" llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const XAie_LocType &loc) { os << "XAie_LocType(col: " << std::to_string(loc.Col) @@ -52,7 +52,7 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &os, namespace xilinx::AIE { -AIERTXControl::AIERTXControl(const AIE::BaseNPUTargetModel &tm) +AIERTControl::AIERTControl(const AIE::BaseNPUTargetModel &tm) : targetModel(tm) { // The first column in the NPU lacks a shim tile. AIE-RT exposes some of // the internals about how this is modeled in a somewhat awkward way. @@ -98,7 +98,7 @@ AIERTXControl::AIERTXControl(const AIE::BaseNPUTargetModel &tm) TRY_XAIE_API_FATAL_ERROR(XAie_UpdateNpiAddr, &devInst, NPI_ADDR); } -LogicalResult AIERTXControl::setIOBackend(bool aieSim, bool xaieDebug) { +LogicalResult AIERTControl::setIOBackend(bool aieSim, bool xaieDebug) { // Quoting: The instance of a device must be always declared using this // macro. In the future, the same macro will be expanded to // allocate more memory from the user application for resource @@ -113,9 +113,9 @@ LogicalResult AIERTXControl::setIOBackend(bool aieSim, bool xaieDebug) { return success(); } -LogicalResult AIERTXControl::configureLocksInBdBlock(XAie_DmaDesc &dmaTileBd, - Block &block, - XAie_LocType &tileLoc) { +LogicalResult AIERTControl::configureLocksInBdBlock(XAie_DmaDesc &dmaTileBd, + Block &block, + XAie_LocType &tileLoc) { LLVM_DEBUG(llvm::dbgs() << "\nstart configuring bds\n"); std::optional acqValue, relValue, acqLockId, relLockId; bool acqEn = false; @@ -163,10 +163,10 @@ LogicalResult AIERTXControl::configureLocksInBdBlock(XAie_DmaDesc &dmaTileBd, return success(); } -LogicalResult AIERTXControl::configureBdInBlock(XAie_DmaDesc &dmaTileBd, - Block &block, - XAie_LocType &tileLoc, int bdId, - std::optional nextBdId) { +LogicalResult AIERTControl::configureBdInBlock(XAie_DmaDesc &dmaTileBd, + Block &block, + XAie_LocType &tileLoc, int bdId, + std::optional nextBdId) { std::optional packetType; std::optional packetID; @@ -309,9 +309,10 @@ LogicalResult AIERTXControl::configureBdInBlock(XAie_DmaDesc &dmaTileBd, return success(); }; -LogicalResult AIERTXControl::pushToBdQueueAndEnable( - Operation &op, XAie_LocType &tileLoc, int chNum, - const DMAChannelDir &channelDir, int bdId, int repeatCount) { +LogicalResult +AIERTControl::pushToBdQueueAndEnable(Operation &op, XAie_LocType &tileLoc, + int chNum, const DMAChannelDir &channelDir, + int bdId, int repeatCount) { XAie_DmaDirection direction = channelDir == DMAChannelDir::S2MM ? DMA_S2MM : DMA_MM2S; auto enTokenIssue = tileLoc.Row == 0 && direction == DMA_S2MM; @@ -325,8 +326,8 @@ LogicalResult AIERTXControl::pushToBdQueueAndEnable( return success(); }; -LogicalResult AIERTXControl::configureLocksAndBd(Block &block, - XAie_LocType tileLoc) { +LogicalResult AIERTControl::configureLocksAndBd(Block &block, + XAie_LocType tileLoc) { DMABDOp bd = *block.getOps().begin(); assert(bd.getBdId().has_value() && "DMABDOp must have assigned bd_id; did you forget to run " @@ -343,7 +344,7 @@ LogicalResult AIERTXControl::configureLocksAndBd(Block &block, return success(); } -LogicalResult AIERTXControl::initLocks(DeviceOp &targetOp) { +LogicalResult AIERTControl::initLocks(DeviceOp &targetOp) { for (auto tileOp : targetOp.getOps()) { auto tileLoc = XAie_TileLoc(tileOp.colIndex(), tileOp.rowIndex()); if (!tileOp.isShimTile() && tileOp.getCoreOp()) { @@ -372,7 +373,7 @@ LogicalResult AIERTXControl::initLocks(DeviceOp &targetOp) { return success(); } -LogicalResult AIERTXControl::configureSwitches(DeviceOp &targetOp) { +LogicalResult AIERTControl::configureSwitches(DeviceOp &targetOp) { // StreamSwitch (switchbox) configuration for (auto switchboxOp : targetOp.getOps()) { @@ -496,7 +497,7 @@ LogicalResult AIERTXControl::configureSwitches(DeviceOp &targetOp) { return success(); } -LogicalResult AIERTXControl::addInitConfig(DeviceOp &targetOp) { +LogicalResult AIERTControl::addInitConfig(DeviceOp &targetOp) { if (failed(initLocks(targetOp))) { return failure(); @@ -560,7 +561,7 @@ LogicalResult AIERTXControl::addInitConfig(DeviceOp &targetOp) { return success(); } -LogicalResult AIERTXControl::addCoreEnable(DeviceOp &targetOp) { +LogicalResult AIERTControl::addCoreEnable(DeviceOp &targetOp) { // Start execution of all the cores. for (auto tileOp : targetOp.getOps()) { auto tileLoc = XAie_TileLoc(tileOp.colIndex(), tileOp.rowIndex()); @@ -570,8 +571,8 @@ LogicalResult AIERTXControl::addCoreEnable(DeviceOp &targetOp) { return success(); } -LogicalResult AIERTXControl::addAieElf(uint8_t col, uint8_t row, - const StringRef elfPath, bool aieSim) { +LogicalResult AIERTControl::addAieElf(uint8_t col, uint8_t row, + const StringRef elfPath, bool aieSim) { TRY_XAIE_API_LOGICAL_RESULT(XAie_CoreDisable, &devInst, XAie_TileLoc(col, row)); TRY_XAIE_API_LOGICAL_RESULT(XAie_DmaChannelResetAll, &devInst, @@ -590,9 +591,9 @@ LogicalResult AIERTXControl::addAieElf(uint8_t col, uint8_t row, return success(); } -LogicalResult AIERTXControl::addAieElfs(DeviceOp &targetOp, - const StringRef workDirPath, - bool aieSim) { +LogicalResult AIERTControl::addAieElfs(DeviceOp &targetOp, + const StringRef workDirPath, + bool aieSim) { for (auto tileOp : targetOp.getOps()) if (tileOp.isShimNOCorPLTile()) { // Resets no needed with V2 kernel driver @@ -619,18 +620,17 @@ LogicalResult AIERTXControl::addAieElfs(DeviceOp &targetOp, return success(); } -void AIERTXControl::dmaUpdateBdAddr(int col, int row, size_t addr, - size_t bdId) { +void AIERTControl::dmaUpdateBdAddr(int col, int row, size_t addr, size_t bdId) { auto tileLoc = XAie_TileLoc(col, row); TRY_XAIE_API_FATAL_ERROR(XAie_DmaUpdateBdAddr, &devInst, tileLoc, addr, bdId); } -void AIERTXControl::startTransaction() { +void AIERTControl::startTransaction() { TRY_XAIE_API_FATAL_ERROR(XAie_StartTransaction, &devInst, XAIE_TRANSACTION_DISABLE_AUTO_FLUSH); } -void AIERTXControl::exportSerializedTransaction() { +void AIERTControl::exportSerializedTransaction() { XAie_TxnInst *txnInst = XAie_ExportTransactionInstance(&devInst); std::ios_base::fmtflags f(std::cout.flags()); for (size_t i = 0; i < txnInst->NumCmds; ++i) { diff --git a/lib/Targets/AIETargetCDODirect.cpp b/lib/Targets/AIETargetCDODirect.cpp index ec2d51a107..17e3bacd36 100644 --- a/lib/Targets/AIETargetCDODirect.cpp +++ b/lib/Targets/AIETargetCDODirect.cpp @@ -5,7 +5,7 @@ // //===----------------------------------------------------------------------===// -#include "aie/Targets/AIERTX.h" +#include "aie/Targets/AIERT.h" #include "aie/Targets/AIETargets.h" extern "C" { #include "cdo-driver/cdo_driver.h" @@ -73,7 +73,7 @@ generateCDOBinary(const StringRef outputPath, return success(); } -static LogicalResult generateCDOBinariesSeparately(AIERTXControl &ctl, +static LogicalResult generateCDOBinariesSeparately(AIERTControl &ctl, const StringRef workDirPath, DeviceOp &targetOp, bool aieSim, @@ -104,7 +104,7 @@ static LogicalResult generateCDOBinariesSeparately(AIERTXControl &ctl, return success(); } -static LogicalResult generateCDOUnified(AIERTXControl &ctl, +static LogicalResult generateCDOUnified(AIERTControl &ctl, const StringRef workDirPath, DeviceOp &targetOp, bool aieSim, bool enableCores) { @@ -141,7 +141,7 @@ translateToCDODirect(ModuleOp m, llvm::StringRef workDirPath, // shim dma on tile (0,0) are hard-coded assumptions about NPU... assert(targetModel.isNPU() && "Only NPU currently supported"); - AIERTXControl ctl(targetModel); + AIERTControl ctl(targetModel); if (failed(ctl.setIOBackend(aieSim, xaieDebug))) return failure(); initializeCDOGenerator(endianness, cdoDebug); @@ -319,9 +319,10 @@ parseTransactionBinary(const std::vector &data, return num_cols; } -static LogicalResult -generateTxn(AIERTXControl &ctl, const StringRef workDirPath, DeviceOp &targetOp, - bool aieSim, bool enableElfs, bool enableInit, bool enableCores) { +static LogicalResult generateTxn(AIERTControl &ctl, const StringRef workDirPath, + DeviceOp &targetOp, bool aieSim, + bool enableElfs, bool enableInit, + bool enableCores) { if (enableElfs && !targetOp.getOps().empty() && failed(ctl.addAieElfs(targetOp, workDirPath, aieSim))) return failure(); @@ -348,7 +349,7 @@ static LogicalResult translateToTxn(ModuleOp m, std::vector &output, if (!targetModel.isNPU()) return failure(); - AIERTXControl ctl(targetModel); + AIERTControl ctl(targetModel); if (failed(ctl.setIOBackend(aieSim, xaieDebug))) return failure(); diff --git a/lib/Targets/CMakeLists.txt b/lib/Targets/CMakeLists.txt index 29acfde613..3a1da83fc2 100644 --- a/lib/Targets/CMakeLists.txt +++ b/lib/Targets/CMakeLists.txt @@ -10,8 +10,8 @@ add_subdirectory(AIEVecToCpp) # for #include set(BOOTGEN_SOURCE_DIR ${PROJECT_SOURCE_DIR}/third_party/bootgen) -add_mlir_library(AIERTX - AIERTX.cpp +add_mlir_library(AIERT + AIERT.cpp PARTIAL_SOURCES_INTENDED ENABLE_AGGREGATION @@ -20,10 +20,10 @@ add_mlir_library(AIERTX ${CMAKE_CURRENT_SRC_DIR}/../../../include/aie/Targets ) -target_link_libraries(AIERTX PRIVATE xaienginecdo_static) -target_include_directories(AIERTX SYSTEM PRIVATE ${BOOTGEN_SOURCE_DIR}) -target_include_directories(obj.AIERTX SYSTEM PRIVATE ${BOOTGEN_SOURCE_DIR}) -add_dependencies(obj.AIERTX xaienginecdo_static xaienginecdo_static-headers) +target_link_libraries(AIERT PRIVATE xaienginecdo_static) +target_include_directories(AIERT SYSTEM PRIVATE ${BOOTGEN_SOURCE_DIR}) +target_include_directories(obj.AIERT SYSTEM PRIVATE ${BOOTGEN_SOURCE_DIR}) +add_dependencies(obj.AIERT xaienginecdo_static xaienginecdo_static-headers) add_mlir_library(AIETargets AIETargets.cpp @@ -59,7 +59,7 @@ add_mlir_library(AIETargets IPO LINK_LIBS PUBLIC - AIERTX + AIERT AIE AIEX AIEXUtils diff --git a/python/AIERTXModule.cpp b/python/AIERTModule.cpp similarity index 55% rename from python/AIERTXModule.cpp rename to python/AIERTModule.cpp index a1564dbebe..0f627a6ad4 100644 --- a/python/AIERTXModule.cpp +++ b/python/AIERTModule.cpp @@ -1,4 +1,4 @@ -//===- AIERTXModule.cpp -----------------------------------------*- C++ -*-===// +//===- AIERTModule.cpp -----------------------------------------*- C++ -*-===// // // This file is licensed under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -21,31 +21,30 @@ namespace py = pybind11; using namespace py::literals; -class PyAIERTXControl { +class PyAIERTControl { public: - PyAIERTXControl(AieTargetModel targetModel) - : ctl(getAieRtxControl(targetModel)) {} + PyAIERTControl(AieTargetModel targetModel) + : ctl(getAieRtControl(targetModel)) {} - ~PyAIERTXControl() { freeAieRtxControl(ctl); } + ~PyAIERTControl() { freeAieRtControl(ctl); } - AieRtxControl ctl; + AieRtControl ctl; }; -PYBIND11_MODULE(_aiertx, m) { +PYBIND11_MODULE(_aiert, m) { - py::class_(m, "AIERTXControl", py::module_local()) + py::class_(m, "AIERTControl", py::module_local()) .def(py::init(), "target_model"_a) .def("start_transaction", - [](PyAIERTXControl &self) { aieRtxStartTransaction(self.ctl); }) + [](PyAIERTControl &self) { aieRtStartTransaction(self.ctl); }) .def("export_serialized_transaction", - [](PyAIERTXControl &self) { - aieRtxExportSerializedTransaction(self.ctl); + [](PyAIERTControl &self) { + aieRtExportSerializedTransaction(self.ctl); }) .def( "dma_update_bd_addr", - [](PyAIERTXControl &self, int col, int row, size_t addr, - size_t bdId) { - aieRtxDmaUpdateBdAddr(self.ctl, col, row, addr, bdId); + [](PyAIERTControl &self, int col, int row, size_t addr, size_t bdId) { + aieRtDmaUpdateBdAddr(self.ctl, col, row, addr, bdId); }, "col"_a, "row"_a, "addr"_a, "bd_id"_a); } diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index 6d7280071d..0be594a828 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -103,10 +103,10 @@ if (AIE_ENABLE_XRT_PYTHON_BINDINGS) ) endif() -declare_mlir_python_sources(AIEPythonSources.AIERTX +declare_mlir_python_sources(AIEPythonSources.AIERT ADD_TO_PARENT AIEPythonSources SOURCES - aiertx.py + aiert.py ) ################################################################################ @@ -173,7 +173,7 @@ if (AIE_ENABLE_PYTHON_PASSES) list(APPEND _py_srcs ${CMAKE_CURRENT_SOURCE_DIR}/XRTModule.cpp) list(APPEND _py_libs xrt_coreutil uuid) endif() - list(APPEND _py_srcs ${CMAKE_CURRENT_SOURCE_DIR}/AIERTXModule.cpp) + list(APPEND _py_srcs ${CMAKE_CURRENT_SOURCE_DIR}/AIERTModule.cpp) declare_mlir_python_extension(AIEPythonExtensions.MLIR MODULE_NAME _aie @@ -297,14 +297,14 @@ else () target_link_directories(AIEPythonExtensions.XRT INTERFACE ${XRT_LIB_DIR}) endif() - declare_mlir_python_extension(AIEPythonExtensions.AIERTX - MODULE_NAME _aiertx + declare_mlir_python_extension(AIEPythonExtensions.AIERT + MODULE_NAME _aiert ADD_TO_PARENT AIEPythonExtensions ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR} PARTIAL_SOURCES_INTENDED SOURCES - AIERTXModule.cpp + AIERTModule.cpp PRIVATE_LINK_LIBS LLVMSupport diff --git a/python/aiertx.py b/python/aiert.py similarity index 81% rename from python/aiertx.py rename to python/aiert.py index b7004ab941..8c5613ee98 100644 --- a/python/aiertx.py +++ b/python/aiert.py @@ -2,4 +2,4 @@ # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception # noinspection PyUnresolvedReferences -from ._mlir_libs._aiertx import * +from ._mlir_libs._aiert import * diff --git a/test/python/aiertx_bindings.py b/test/python/aiert_bindings.py similarity index 91% rename from test/python/aiertx_bindings.py rename to test/python/aiert_bindings.py index d38dc7ab20..1c4652ff20 100644 --- a/test/python/aiertx_bindings.py +++ b/test/python/aiert_bindings.py @@ -6,7 +6,7 @@ # RUN: %python %s | FileCheck %s -from aie.aiertx import AIERTXControl +from aie.aiert import AIERTControl from util import construct_and_print_module from aie.dialects.aiex import DDR_AIE_ADDR_OFFSET from aie.dialects.aie import AIEDevice, get_target_model @@ -16,7 +16,7 @@ @construct_and_print_module def simple(module): tm = get_target_model(AIEDevice.npu1_4col) - ctl = AIERTXControl(tm) + ctl = AIERTControl(tm) ctl.start_transaction() ctl.dma_update_bd_addr(0, 0, DDR_AIE_ADDR_OFFSET, 0) ctl.export_serialized_transaction()