15#include "mlir/CAPI/IR.h"
16#include "mlir/IR/Builders.h"
17#include "mlir/IR/BuiltinOps.h"
18#include "mlir/Interfaces/DataLayoutInterfaces.h"
20#include "llvm/Support/MathExtras.h"
25 return AieTargetModel{
reinterpret_cast<std::uintptr_t
>(&tm)};
38 return unwrap(targetModel).getAddressGenGranularity();
42 return unwrap(targetModel).columns();
46 return unwrap(targetModel).rows();
51 return static_cast<uint32_t
>(unwrap(targetModel).getTileType(col, row));
55 return unwrap(targetModel).isCoreTile(col, row);
59 return unwrap(targetModel).isMemTile(col, row);
63 return unwrap(targetModel).isShimNOCTile(col, row);
67 return unwrap(targetModel).isShimPLTile(col, row);
72 return unwrap(targetModel).isShimNOCorPLTile(col, row);
76 int src_row,
int dst_col,
int dst_row) {
77 return unwrap(targetModel).isInternal(src_col, src_row, dst_col, dst_row);
81 int dst_col,
int dst_row) {
82 return unwrap(targetModel).isWest(src_col, src_row, dst_col, dst_row);
86 int dst_col,
int dst_row) {
87 return unwrap(targetModel).isEast(src_col, src_row, dst_col, dst_row);
91 int dst_col,
int dst_row) {
92 return unwrap(targetModel).isNorth(src_col, src_row, dst_col, dst_row);
96 int dst_col,
int dst_row) {
97 return unwrap(targetModel).isSouth(src_col, src_row, dst_col, dst_row);
101 int src_row,
int dst_col,
int dst_row) {
102 return unwrap(targetModel).isMemWest(src_col, src_row, dst_col, dst_row);
106 int src_row,
int dst_col,
int dst_row) {
107 return unwrap(targetModel).isMemEast(src_col, src_row, dst_col, dst_row);
111 int src_row,
int dst_col,
int dst_row) {
112 return unwrap(targetModel).isMemNorth(src_col, src_row, dst_col, dst_row);
116 int src_row,
int dst_col,
int dst_row) {
117 return unwrap(targetModel).isMemSouth(src_col, src_row, dst_col, dst_row);
121 int src_row,
int dst_col,
int dst_row) {
122 return unwrap(targetModel)
123 .isLegalMemAffinity(src_col, src_row, dst_col, dst_row);
127 return unwrap(targetModel).getMemSouthBaseAddress();
131 return unwrap(targetModel).getMemNorthBaseAddress();
135 return unwrap(targetModel).getMemEastBaseAddress();
139 return unwrap(targetModel).getMemWestBaseAddress();
143 return unwrap(targetModel).getLocalMemorySize();
147 return unwrap(targetModel).getDefaultCoreStackSize();
152 return unwrap(targetModel).getNumLocks(col, row);
156 return unwrap(targetModel).getNumBDs(col, row);
160 return unwrap(targetModel).getMaxLockValue();
164 return unwrap(targetModel).getMaxRepeatCount();
168 return unwrap(targetModel).getDmaTaskQueueDepth();
173 return unwrap(targetModel).getDmaBdWrapBits(col, row);
178 return unwrap(targetModel).getDmaBdStepBits(col, row);
183 return unwrap(targetModel).getDmaBdIterBits(col, row);
187 return unwrap(targetModel).getNumMemTileRows();
191 return unwrap(targetModel).getMemTileSize();
196 return unwrap(targetModel).getNumBanks(col, row);
199bool aieDmaBdFits(uint32_t device,
int col,
int row, MlirType elementType,
200 int64_t offset,
const int64_t *sizes,
const int64_t *strides,
202 Type elemType = unwrap(elementType);
203 MLIRContext *ctx = elemType.getContext();
204 ctx->getOrLoadDialect<xilinx::AIE::AIEDialect>();
205 OpBuilder builder(ctx);
206 Location loc = builder.getUnknownLoc();
207 OwningOpRef<ModuleOp> module = ModuleOp::create(loc);
208 builder.setInsertionPointToStart(module->getBody());
209 auto dev = xilinx::AIE::DeviceOp::create(
210 builder, loc,
static_cast<xilinx::AIE::AIEDevice
>(device),
211 xilinx::AIE::DeviceOp::getDefaultDeviceName());
214 int64_t elemBits = DataLayout::closest(dev).getTypeSizeInBits(elemType);
218 SmallVector<xilinx::AIE::BDDimLayoutAttr> dims;
219 for (
unsigned d = 0; d < xilinx::AIEX::kNdDmaDims; d++) {
220 if (sizes[d] < 0 || sizes[d] > UINT32_MAX || strides[d] < 0 ||
221 strides[d] > UINT32_MAX)
224 xilinx::AIE::BDDimLayoutAttr::get(ctx, sizes[d], strides[d]));
228 if (std::optional<SmallVector<xilinx::AIE::BDDimLayoutAttr>> normalized =
230 if (normalized->empty()) {
232 return !llvm::MulOverflow(len, elemBits, bits) &&
240 for (
unsigned d = 0; d < xilinx::AIEX::kNdDmaDims; d++) {
241 bool held = d < dims.size();
243 pattern.
sizes.push_back(held ? dims[dims.size() - 1 - d].getSize() : 1);
244 pattern.
strides.push_back(held ? dims[dims.size() - 1 - d].getStride() : 0);
249 dev, MemRefType::get({ShapedType::kDynamic}, elemType), tm, col, row,
255 int64_t lenBits = elemBits;
256 for (
int d = 0; d < 3; d++)
257 if (llvm::MulOverflow(lenBits, pattern.
sizes[d], lenBits))
264 AieTargetModel targetModel,
int col,
int row, uint32_t bundle) {
265 xilinx::AIE::WireBundle wireBundle =
266 static_cast<xilinx::AIE::WireBundle
>(bundle);
267 return unwrap(targetModel)
268 .getNumDestSwitchboxConnections(col, row, wireBundle);
272 AieTargetModel targetModel,
int col,
int row, uint32_t bundle) {
273 xilinx::AIE::WireBundle wireBundle =
274 static_cast<xilinx::AIE::WireBundle
>(bundle);
275 return unwrap(targetModel)
276 .getNumSourceSwitchboxConnections(col, row, wireBundle);
282 xilinx::AIE::WireBundle wireBundle =
283 static_cast<xilinx::AIE::WireBundle
>(bundle);
284 return unwrap(targetModel).getNumDestShimMuxConnections(col, row, wireBundle);
288 AieTargetModel targetModel,
int col,
int row, uint32_t bundle) {
289 xilinx::AIE::WireBundle wireBundle =
290 static_cast<xilinx::AIE::WireBundle
>(bundle);
291 return unwrap(targetModel)
292 .getNumSourceShimMuxConnections(col, row, wireBundle);
300 return static_cast<uint32_t
>(unwrap(targetModel).getTargetArch());
304 return unwrap(targetModel).getColumnShift();
308 return unwrap(targetModel).getRowShift();
bool aieTargetModelIsLegalMemAffinity(AieTargetModel targetModel, int src_col, int src_row, int dst_col, int dst_row)
uint32_t aieTargetModelGetNumSourceShimMuxConnections(AieTargetModel targetModel, int col, int row, uint32_t bundle)
int aieTargetModelRows(AieTargetModel targetModel)
Returns the number of rows in the target model.
uint32_t aieTargetModelGetTargetArch(AieTargetModel targetModel)
Returns the AIE architecture (as the underlying value of xilinx::AIE::AIEArch: AIE1=1,...
uint32_t aieTargetModelGetNumMemTileRows(AieTargetModel targetModel)
bool aieTargetModelIsShimNOCTile(AieTargetModel targetModel, int col, int row)
bool aieTargetModelIsCoreTile(AieTargetModel targetModel, int col, int row)
uint32_t aieTargetModelGetRowShift(AieTargetModel targetModel)
uint32_t aieTargetModelGetDefaultCoreStackSize(AieTargetModel targetModel)
bool aieTargetModelIsInternal(AieTargetModel targetModel, int src_col, int src_row, int dst_col, int dst_row)
uint32_t aieTargetModelGetLocalMemorySize(AieTargetModel targetModel)
bool aieTargetModelIsMemNorth(AieTargetModel targetModel, int src_col, int src_row, int dst_col, int dst_row)
bool aieDmaBdFits(uint32_t device, int col, int row, MlirType elementType, int64_t offset, const int64_t *sizes, const int64_t *strides, int64_t len)
Whether one DMA buffer descriptor of tile (col, row) on device holds the pattern, as aie-normalize-dm...
int aieTargetModelColumns(AieTargetModel targetModel)
Returns the number of columns in the target model.
uint32_t aieTargetModelGetNumBanks(AieTargetModel targetModel, int col, int row)
bool aieTargetModelIsWest(AieTargetModel targetModel, int src_col, int src_row, int dst_col, int dst_row)
bool aieTargetModelIsMemSouth(AieTargetModel targetModel, int src_col, int src_row, int dst_col, int dst_row)
uint32_t aieTargetModelGetDmaBdStepBits(AieTargetModel targetModel, int col, int row)
uint32_t aieTargetModelGetNumDestSwitchboxConnections(AieTargetModel targetModel, int col, int row, uint32_t bundle)
uint32_t aieTargetModelGetMaxRepeatCount(AieTargetModel targetModel)
Largest repeat count one DMA task queue push can carry (unsupported = 0).
uint32_t aieTargetModelGetMemTileSize(AieTargetModel targetModel)
uint32_t aieTargetModelGetDmaTaskQueueDepth(AieTargetModel targetModel)
How many tasks one DMA channel's task queue holds (unsupported = 0).
AieTargetModel aieGetTargetModel(uint32_t device)
bool aieTargetModelIsMemEast(AieTargetModel targetModel, int src_col, int src_row, int dst_col, int dst_row)
bool aieTargetModelIsSouth(AieTargetModel targetModel, int src_col, int src_row, int dst_col, int dst_row)
bool aieTargetModelIsShimPLTile(AieTargetModel targetModel, int col, int row)
bool aieTargetModelIsNorth(AieTargetModel targetModel, int src_col, int src_row, int dst_col, int dst_row)
uint32_t aieTargetModelGetMaxLockValue(AieTargetModel targetModel)
Largest value a lock register holds.
uint32_t aieTargetModelGetNumDestShimMuxConnections(AieTargetModel targetModel, int col, int row, uint32_t bundle)
uint32_t aieTargetModelGetNumBDs(AieTargetModel targetModel, int col, int row)
bool aieTargetModelIsNPU(AieTargetModel targetModel)
Returns true if this is an NPU target model.
uint32_t aieTargetModelGetNumLocks(AieTargetModel targetModel, int col, int row)
bool aieTargetModelIsMemTile(AieTargetModel targetModel, int col, int row)
bool aieTargetModelIsShimNOCorPLTile(AieTargetModel targetModel, int col, int row)
uint32_t aieTargetModelGetMemSouthBaseAddress(AieTargetModel targetModel)
uint32_t aieTargetModelGetTileType(AieTargetModel targetModel, int col, int row)
Returns the tile type for the given coordinates.
uint32_t aieTargetModelGetMemEastBaseAddress(AieTargetModel targetModel)
uint32_t aieTargetModelGetColumnShift(AieTargetModel targetModel)
bool aieTargetModelIsEast(AieTargetModel targetModel, int src_col, int src_row, int dst_col, int dst_row)
uint32_t aieTargetModelGetDmaBdIterBits(AieTargetModel targetModel, int col, int row)
uint32_t aieTargetModelGetDmaBdWrapBits(AieTargetModel targetModel, int col, int row)
Field widths of a DMA buffer descriptor, which differ by tile type.
bool aieTargetModelIsMemWest(AieTargetModel targetModel, int src_col, int src_row, int dst_col, int dst_row)
uint32_t aieTargetModelGetMemNorthBaseAddress(AieTargetModel targetModel)
uint32_t aieTargetModelGetNumSourceSwitchboxConnections(AieTargetModel targetModel, int col, int row, uint32_t bundle)
uint32_t aieTargetModelGetMemWestBaseAddress(AieTargetModel targetModel)
uint32_t aieGetTargetModelAddressGenGranularity(AieTargetModel targetModel)
Returns the data bus width for the target model.
virtual uint64_t getDmaBdMaxLen(AIETileType tileType) const =0
Return the maximum transfer length, measured in address-generation granules (see getAddressGenGranula...
virtual uint32_t getAddressGenGranularity() const =0
Return the data bus width of the device.
bool isLinearModeTransfer(const AIE::AIETargetModel &targetModel, int col, int row, llvm::ArrayRef< int64_t > sizes, llvm::ArrayRef< int64_t > strides)
bool patternPassesVerification(mlir::Operation *forOp, mlir::BaseMemRefType referencedBufType, const xilinx::AIE::AIETargetModel &tm, int tileCol, int tileRow, const NdDmaPattern &pattern, bool skipTransformationChecks=false)
Returns true when the pattern passes verifyStridesWraps for the given tile and memref element type.
std::optional< llvm::SmallVector< BDDimLayoutAttr > > normalizedBDDims(llvm::ArrayRef< BDDimLayoutAttr > dims, int64_t len)
const AIETargetModel & getTargetModel(mlir::Operation *op)
Innermost-first ND access pattern (d0..d3 / repeat), matching the convention used by verifyStridesWra...
llvm::SmallVector< int64_t, kNdDmaDims > sizes
llvm::SmallVector< int64_t, kNdDmaDims > offsets
llvm::SmallVector< int64_t, kNdDmaDims > strides