MLIR-AIE 1.4.5.dev
DmaDecomposition.h
Go to the documentation of this file.
1//===- DmaDecomposition.h -------------------------------------*- C++ -*-===//
2//
3// Copyright (C) 2026 Advanced Micro Devices, Inc.
4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5//
6//===----------------------------------------------------------------------===//
7//
8// Decomposition of oversized non-contiguous aiex.npu.dma_memcpy_nd access
9// patterns into one or more hardware-legal ND patterns. Shared by the
10// aie-decompose-large-dma-bd pass and (after integration) the op verifier.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef AIE_DIALECT_AIEX_UTILS_DMADECOMPOSITION_H
15#define AIE_DIALECT_AIEX_UTILS_DMADECOMPOSITION_H
16
17#include "mlir/IR/BuiltinTypes.h"
18#include "mlir/IR/Operation.h"
19#include "mlir/Support/LogicalResult.h"
20#include "llvm/ADT/ArrayRef.h"
21#include "llvm/ADT/SmallVector.h"
22
23namespace xilinx::AIE {
24class AIETargetModel;
25class DMABDOp;
26} // namespace xilinx::AIE
27
28namespace xilinx::AIEX {
29
30/// Number of ND addressing dimensions in the NPU DMA instruction encoding
31/// (d0..d2 wrap/stride + d3 iteration/repeat).
32static constexpr unsigned kNdDmaDims = 4;
33
34/// The most patterns decomposeNdDmaPattern splits one into. Each piece costs a
35/// descriptor, or a task and a queue push of its own, so a split past this is
36/// refused rather than unrolled into the instruction stream.
37static constexpr int64_t kMaxNdDmaPieces = 1024;
38
39/// Innermost-first ND access pattern (d0..d3 / repeat), matching the
40/// convention used by verifyStridesWraps and NpuDmaMemcpyNdOp verification.
41///
42/// A runtime-sequence task BD may give more than kNdDmaDims dimensions, all of
43/// the ones past d2 iteration dimensions; decomposeNdDmaPattern reduces it to
44/// kNdDmaDims-dimension patterns.
46 llvm::SmallVector<int64_t, kNdDmaDims> offsets;
47 llvm::SmallVector<int64_t, kNdDmaDims> sizes;
48 llvm::SmallVector<int64_t, kNdDmaDims> strides;
49 /// Elements added to the address the offsets give. Carries the position of
50 /// a pattern peeled off the dimensions past kNdDmaDims, which no dimension
51 /// of the peeled pattern can express.
52 int64_t baseOffset = 0;
53};
54
55/// Returns true when the pattern passes verifyStridesWraps for the given tile
56/// and memref element type. Diagnostics are suppressed so callers can probe
57/// legality without emitting errors.
58bool patternPassesVerification(mlir::Operation *forOp,
59 mlir::BaseMemRefType referencedBufType,
61 int tileCol, int tileRow,
62 const NdDmaPattern &pattern,
63 bool skipTransformationChecks = false);
64
65/// True when the pattern is fully constant, non-contiguous, currently illegal,
66/// and decomposeNdDmaPattern would produce at least one legal replacement.
67bool isDecomposableNdDmaPattern(mlir::Operation *forOp,
68 mlir::BaseMemRefType referencedBufType,
69 const xilinx::AIE::AIETargetModel &targetModel,
70 int tileCol, int tileRow,
71 llvm::ArrayRef<int64_t> offsetsInnermostFirst,
72 llvm::ArrayRef<int64_t> sizesInnermostFirst,
73 llvm::ArrayRef<int64_t> stridesInnermostFirst);
74
75/// Decompose an illegal pattern into one or more legal sub-patterns that move
76/// the same data. Prefers merging contiguous dimensions, then dimension
77/// factoring (single-op results); falls back to slicing (multiple ops). Returns
78/// failure when no legal decomposition into at most kMaxNdDmaPieces patterns
79/// exists.
80///
81/// A contiguous pattern is illegal only if its iteration dimension (d3) is
82/// longer than a BD's, and is sliced along it.
83///
84/// A pattern with more than kNdDmaDims dimensions drops size-one dimensions
85/// past d0, innermost first, merges the iteration dimensions past d2 where one
86/// continues the next, and peels any left past d3 into one pattern per index,
87/// outermost slowest. Element order is kept; the size of an execution is not,
88/// since a dropped dimension can move an iteration dimension inside and a
89/// peeled pattern executes a share of the original's.
90mlir::FailureOr<llvm::SmallVector<NdDmaPattern>> decomposeNdDmaPattern(
91 mlir::Operation *forOp, mlir::BaseMemRefType referencedBufType,
92 const NdDmaPattern &pattern, const xilinx::AIE::AIETargetModel &targetModel,
93 int tileCol, int tileRow);
94
95/// How aie-decompose-large-dma-bd splits a runtime task's descriptor.
97 /// The descriptor lowers as it is.
98 bool legal = false;
99 /// One pass over the descriptor, less the outer dimensions that only
100 /// re-read the same data.
102 /// The legal patterns `pass` splits into; empty when no split fits.
103 llvm::SmallVector<NdDmaPattern> pieces;
104};
105
106/// Plan the split of `bd`, a runtime task's descriptor, on tile (`tileCol`,
107/// `tileRow`). Fails when `bd` has padding or a non-constant offset, length,
108/// size or stride, which the pass leaves whole.
109mlir::FailureOr<TaskBdDecomposition>
110decomposeTaskBdPattern(xilinx::AIE::DMABDOp bd,
111 const xilinx::AIE::AIETargetModel &targetModel,
112 int tileCol, int tileRow);
113
114} // namespace xilinx::AIEX
115
116#endif // AIE_DIALECT_AIEX_UTILS_DMADECOMPOSITION_H
bool isDecomposableNdDmaPattern(mlir::Operation *forOp, mlir::BaseMemRefType referencedBufType, const xilinx::AIE::AIETargetModel &targetModel, int tileCol, int tileRow, llvm::ArrayRef< int64_t > offsetsInnermostFirst, llvm::ArrayRef< int64_t > sizesInnermostFirst, llvm::ArrayRef< int64_t > stridesInnermostFirst)
True when the pattern is fully constant, non-contiguous, currently illegal, and decomposeNdDmaPattern...
mlir::FailureOr< llvm::SmallVector< NdDmaPattern > > decomposeNdDmaPattern(mlir::Operation *forOp, mlir::BaseMemRefType referencedBufType, const NdDmaPattern &pattern, const xilinx::AIE::AIETargetModel &targetModel, int tileCol, int tileRow)
Decompose an illegal pattern into one or more legal sub-patterns that move the same data.
mlir::FailureOr< TaskBdDecomposition > decomposeTaskBdPattern(xilinx::AIE::DMABDOp bd, const xilinx::AIE::AIETargetModel &targetModel, int tileCol, int tileRow)
Plan the split of bd, a runtime task's descriptor, on tile (tileCol, tileRow).
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.
Innermost-first ND access pattern (d0..d3 / repeat), matching the convention used by verifyStridesWra...
llvm::SmallVector< int64_t, kNdDmaDims > sizes
int64_t baseOffset
Elements added to the address the offsets give.
llvm::SmallVector< int64_t, kNdDmaDims > offsets
llvm::SmallVector< int64_t, kNdDmaDims > strides
How aie-decompose-large-dma-bd splits a runtime task's descriptor.
bool legal
The descriptor lowers as it is.
llvm::SmallVector< NdDmaPattern > pieces
The legal patterns pass splits into; empty when no split fits.
NdDmaPattern pass
One pass over the descriptor, less the outer dimensions that only re-read the same data.