Skip to content

Commit

Permalink
change dimtuple -> bdlayout and change parsing to struct parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
makslevental committed Dec 20, 2023
1 parent 229c952 commit 7d012f7
Show file tree
Hide file tree
Showing 24 changed files with 182 additions and 171 deletions.
46 changes: 23 additions & 23 deletions include/aie/Dialect/AIE/IR/AIEAttrs.td
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ def WireBundle: I32EnumAttr<"WireBundle", "Bundle of wires",
def LockAction: I32EnumAttr<"LockAction", "lock acquire/release",
[
I32EnumAttrCase<"Acquire", 0>,
I32EnumAttrCase<"Release", 1>,
I32EnumAttrCase<"AcquireGreaterEqual", 2>,
I32EnumAttrCase<"Release", 1>,
]> {

let cppNamespace = "xilinx::AIE";
Expand Down Expand Up @@ -115,42 +115,42 @@ def DMAChannelDir: I32EnumAttr<"DMAChannelDir",
let cppNamespace = "xilinx::AIE";
}

def AIE_DimTupleAttr : AttrDef<AIE_Dialect, "DimTuple", []> {
let mnemonic = "DimTuple";
def DMABDBuffer: I32EnumAttr<"DMABDBuffer",
"DMA Block descriptor buffer type.",
[
I32EnumAttrCase<"A", 0>,
I32EnumAttrCase<"B", 1>
]> {
let cppNamespace = "xilinx::AIE";
}

def BDDimLayoutAttr : AttrDef<AIE_Dialect, "BDDimLayout", []> {
let mnemonic = "bd_dim_layout";
let summary = [{
Tuple encoding the stride and wrap of one dimension in an AIE2 n-dimensional
buffer descriptor;
}];

let parameters = (ins
"uint32_t" : $stepsize,
"uint16_t" : $wrap
"uint16_t" : $wrap,
"uint32_t" : $step
);

let assemblyFormat = "`<` $wrap `,` $stepsize `>`";
}

def DMABDBuffer: I32EnumAttr<"DMABDBuffer",
"DMA Block descriptor buffer type.",
[
I32EnumAttrCase<"A", 0>,
I32EnumAttrCase<"B", 1>
]> {
let cppNamespace = "xilinx::AIE";
let assemblyFormat = "`<` struct(params) `>`";
}

def AIE_DimTupleArrayAttr : ArrayOfAttr<
def BDDimLayoutArrayAttr : ArrayOfAttr<
/*dialect*/AIE_Dialect,
/*attrName*/"DimTupleArray",
/*attrMnemonic*/"DimTupleArray",
/*eltName*/AIE_DimTupleAttr.cppClassName
/*attrName*/"BDDimLayoutArray",
/*attrMnemonic*/"bd_dim_layout_arr",
/*eltName*/BDDimLayoutAttr.cppClassName
>;

def AIE_DimTupleArrayArrayAttr : ArrayOfAttr<
def BDDimLayoutArrayArrayAttr : ArrayOfAttr<
/*dialect*/AIE_Dialect,
/*attrName*/"DimTupleArrayArray",
/*attrMnemonic*/"DimTupleArrayArray",
/*eltName*/AIE_DimTupleArrayAttr.cppClassName
/*attrName*/"BDDimLayoutArrayArray",
/*attrMnemonic*/"bd_dim_layout_arr_arr",
/*eltName*/BDDimLayoutArrayAttr.cppClassName
>;

#endif // AIE_ATTRS
4 changes: 2 additions & 2 deletions include/aie/Dialect/AIE/IR/AIEDialect.h
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ const AIETargetModel &getTargetModel(mlir::Operation *op);
mlir::ParseResult
parseObjectFifoProducerTile(mlir::OpAsmParser &parser,
mlir::OpAsmParser::UnresolvedOperand &operand,
DimTupleArrayAttr &dimensions);
BDDimLayoutArrayAttr &dimensions);

void printObjectFifoProducerTile(mlir::OpAsmPrinter &printer,
mlir::Operation *op, mlir::Value tile,
Expand All @@ -221,7 +221,7 @@ void printObjectFifoProducerTile(mlir::OpAsmPrinter &printer,
mlir::ParseResult parseObjectFifoConsumerTiles(
mlir::OpAsmParser &parser,
llvm::SmallVector<mlir::OpAsmParser::UnresolvedOperand> &tiles,
DimTupleArrayArrayAttr &dimensions);
BDDimLayoutArrayArrayAttr &dimensions);

void printObjectFifoConsumerTiles(mlir::OpAsmPrinter &printer,
mlir::Operation *op, mlir::OperandRange tiles,
Expand Down
22 changes: 11 additions & 11 deletions include/aie/Dialect/AIE/IR/AIEOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -808,8 +808,8 @@ def AIE_DMABDOp: AIE_Op<"dma_bd", []> {
ins AnyMemRef:$buffer,
AIEI32Attr:$offset,
AIEI32Attr:$len,
DMABDBuffer:$AB,
OptionalAttr<AIE_DimTupleArrayAttr>:$dimensions
DefaultValuedAttr<DMABDBuffer, "xilinx::AIE::DMABDBuffer::A">:$AB,
OptionalAttr<BDDimLayoutArrayAttr>:$dimensions
);

let hasVerifier = 1;
Expand Down Expand Up @@ -877,8 +877,8 @@ def AIE_DMAStartOp: AIE_Op<"dma_start", [
}];

let extraClassDeclaration = [{
bool isRecv() { return getChannelDir() == DMAChannelDir::S2MM; }
bool isSend() { return getChannelDir() == DMAChannelDir::MM2S; }
bool isRecv() { return getChannelDir() == DMAChannelDir::S2MM; }
}];
}

Expand Down Expand Up @@ -1422,9 +1422,9 @@ def AIE_ObjectFifoCreateOp: AIE_Op<"objectfifo", [HasParent<"DeviceOp">, Symbol]
Index:$producerTile,
Variadic<Index>:$consumerTiles,
AIE_ObjectFifo_Depth:$elemNumber,
TypeAttrOf<AIE_ObjectFifoType>:$elem_type,
AIE_DimTupleArrayAttr:$dimensionsToStream,
AIE_DimTupleArrayArrayAttr:$dimensionsFromStreamPerConsumer
TypeAttrOf<AIE_ObjectFifoType>:$elemType,
BDDimLayoutArrayAttr:$dimensionsToStream,
BDDimLayoutArrayArrayAttr:$dimensionsFromStreamPerConsumer
);

let assemblyFormat = [{
Expand All @@ -1436,7 +1436,7 @@ def AIE_ObjectFifoCreateOp: AIE_Op<"objectfifo", [HasParent<"DeviceOp">, Symbol]
`}`
`,`
$elemNumber
`)` attr-dict `:` $elem_type
`)` attr-dict `:` $elemType
}];

let hasVerifier = 1;
Expand All @@ -1462,17 +1462,17 @@ def AIE_ObjectFifoCreateOp: AIE_Op<"objectfifo", [HasParent<"DeviceOp">, Symbol]
let builders = [
OpBuilder<(ins "mlir::StringAttr":$sym_name, "mlir::Value":$producerTile,
"mlir::ValueRange":$consumerTiles, "mlir::Attribute":$elemNumber, "mlir::Type":$elem_type,
CArg<"llvm::ArrayRef<AIE::DimTupleAttr>", "{}">:$dimensionsToStream,
CArg<"llvm::ArrayRef<AIE::DimTupleArrayAttr>", "{}">:$dimensionsFromStreamPerConsumer), [{
CArg<"llvm::ArrayRef<AIE::BDDimLayoutAttr>", "{}">:$dimensionsToStream,
CArg<"llvm::ArrayRef<AIE::BDDimLayoutArrayAttr>", "{}">:$dimensionsFromStreamPerConsumer), [{
odsState.addOperands(producerTile);
odsState.addOperands(consumerTiles);
odsState.addAttribute(getSymNameAttrName(odsState.name), sym_name);
odsState.addAttribute(getElemNumberAttrName(odsState.name), elemNumber);
odsState.addAttribute(getElemTypeAttrName(odsState.name), mlir::TypeAttr::get(elem_type));
odsState.addAttribute(getDimensionsToStreamAttrName(odsState.name),
odsBuilder.getAttr<DimTupleArrayAttr>(dimensionsToStream));
odsBuilder.getAttr<BDDimLayoutArrayAttr>(dimensionsToStream));
odsState.addAttribute(getDimensionsFromStreamPerConsumerAttrName(odsState.name),
odsBuilder.getAttr<DimTupleArrayArrayAttr>(dimensionsFromStreamPerConsumer));
odsBuilder.getAttr<BDDimLayoutArrayArrayAttr>(dimensionsFromStreamPerConsumer));
}]>
];
}
Expand Down
39 changes: 21 additions & 18 deletions lib/Dialect/AIE/IR/AIEDialect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -430,24 +430,25 @@ namespace xilinx::AIE {

ParseResult parseObjectFifoProducerTile(OpAsmParser &parser,
OpAsmParser::UnresolvedOperand &operand,
DimTupleArrayAttr &dimensions) {
std::vector<DimTupleAttr> emptyDims = {};
BDDimLayoutArrayAttr &dimensions) {
std::vector<BDDimLayoutAttr> emptyDims = {};
if (parser.parseOperand(operand))
return failure();
if (succeeded(parser.parseOptionalKeyword("toStream"))) {
if (parser.parseCustomAttributeWithFallback<DimTupleArrayAttr>(
if (parser.parseCustomAttributeWithFallback<BDDimLayoutArrayAttr>(
dimensions)) {
return failure();
}
} else {
dimensions =
DimTupleArrayAttr::get(parser.getContext(), ArrayRef(emptyDims));
BDDimLayoutArrayAttr::get(parser.getContext(), ArrayRef(emptyDims));
}
return success();
}

void printObjectFifoProducerTile(OpAsmPrinter &printer, Operation *op,
Value operand, DimTupleArrayAttr dimensions) {
Value operand,
BDDimLayoutArrayAttr dimensions) {
printer << operand;
if (!dimensions.empty()) {
printer << " toStream ";
Expand All @@ -457,10 +458,10 @@ void printObjectFifoProducerTile(OpAsmPrinter &printer, Operation *op,

ParseResult parseObjectFifoConsumerTiles(
OpAsmParser &parser, SmallVectorImpl<OpAsmParser::UnresolvedOperand> &tiles,
DimTupleArrayArrayAttr &dimensions) {
BDDimLayoutArrayArrayAttr &dimensions) {
// parseCommaSeparatedList doesn't handle the missing case for "none",
// so we handle it custom here.
std::vector<DimTupleArrayAttr> tileDims = {};
std::vector<BDDimLayoutArrayAttr> tileDims = {};

auto parseOneOperand = [&]() -> ParseResult {
if (parser.parseOperand(tiles.emplace_back(), true)) {
Expand All @@ -469,11 +470,13 @@ ParseResult parseObjectFifoConsumerTiles(
// By default, create empty dimensions array for each consumer; this way,
// we can be certain to have as many entries in the dimensions array as
// there are customer
DimTupleArrayAttr dimAttr = DimTupleArrayAttr::get(parser.getContext(), {});
BDDimLayoutArrayAttr dimAttr =
BDDimLayoutArrayAttr::get(parser.getContext(), {});

if (succeeded(parser.parseOptionalKeyword("fromStream"))) {
// If specified, parse actual data layout transform dimensions
if (parser.parseCustomAttributeWithFallback<DimTupleArrayAttr>(dimAttr)) {
if (parser.parseCustomAttributeWithFallback<BDDimLayoutArrayAttr>(
dimAttr)) {
return failure();
}
}
Expand All @@ -485,13 +488,13 @@ ParseResult parseObjectFifoConsumerTiles(
parseOneOperand, " in operand list"))
return failure();

dimensions = DimTupleArrayArrayAttr::get(parser.getContext(), tileDims);
dimensions = BDDimLayoutArrayArrayAttr::get(parser.getContext(), tileDims);
return success();
}

void printObjectFifoConsumerTiles(OpAsmPrinter &printer, Operation *op,
OperandRange tiles,
DimTupleArrayArrayAttr dimsPerTileAttr) {
BDDimLayoutArrayArrayAttr dimsPerTileAttr) {
size_t tileIdx = 0;
for (auto tile : tiles) {
printer << tile;
Expand Down Expand Up @@ -1366,7 +1369,7 @@ LogicalResult DMABDOp::verify() {
for (int64_t memrefDim : buffer.getShape())
memrefSize *= 4 * memrefDim;

ArrayRef<DimTupleAttr> dims = *getDimensions();
ArrayRef<BDDimLayoutAttr> dims = *getDimensions();
size_t maxNDims = 3;
if (isa_and_nonnull<MemTileDMAOp>((*this)->getParentOp())) {
maxNDims = 4;
Expand All @@ -1378,21 +1381,21 @@ LogicalResult DMABDOp::verify() {
" tile (got "
<< std::to_string(dims.size()) << " dimensions).";
}
for (DimTupleAttr dim : dims) {
maxIdx += dim.getStepsize() * (dim.getWrap() - 1);
if (0 == dim.getStepsize()) {
for (BDDimLayoutAttr dim : dims) {
maxIdx += dim.getStep() * (dim.getWrap() - 1);
if (0 == dim.getStep()) {
return emitOpError()
<< "Invalid step size; must be a positive integer.";
}
if (dim.getStepsize() > memrefSize) {
if (dim.getStep() > memrefSize) {
return emitOpError()
<< "Step size " << std::to_string(dim.getStepsize() * 4) << " "
<< "Step size " << std::to_string(dim.getStep() * 4) << " "
<< "bytes exceeds memref size " << std::to_string(memrefSize);
}
if (dim.getWrap() >= (1UL << 9) + 1) {
return emitOpError() << "Wrap may not exceed 1023.";
}
if (dim.getStepsize() >= (1UL << 19)) {
if (dim.getStep() >= (1UL << 19)) {
return emitOpError() << "Stepsize may not exceed " << (1 << 20);
}
}
Expand Down
39 changes: 21 additions & 18 deletions lib/Dialect/AIE/Transforms/AIEObjectFifoStatefulTransform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ struct AIEObjectFifoStatefulTransformPass
if (hasSharedMemory) {
// Even if just one of the consumers in the list of consumers wants to
// perform a memory transform, we need to use DMAs.
for (DimTupleArrayAttr dims :
for (BDDimLayoutArrayAttr dims :
createOp.getDimensionsFromStreamPerConsumer())
if (!dims.empty()) {
atLeastOneConsumerWantsTransform = true;
Expand Down Expand Up @@ -250,8 +250,8 @@ struct AIEObjectFifoStatefulTransformPass
ObjectFifoCreateOp
createObjectFifo(OpBuilder &builder, AIEObjectFifoType datatype,
std::string name, Value prodTile, Value consTile,
Attribute depth, DimTupleArrayAttr dimensionsToStream,
DimTupleArrayArrayAttr dimensionsFromStreamPerConsumer) {
Attribute depth, BDDimLayoutArrayAttr dimensionsToStream,
BDDimLayoutArrayArrayAttr dimensionsFromStreamPerConsumer) {
auto ofName = builder.getStringAttr(name);
auto fifo = builder.create<ObjectFifoCreateOp>(
builder.getUnknownLoc(), ofName, prodTile, consTile, depth, datatype,
Expand Down Expand Up @@ -418,7 +418,7 @@ struct AIEObjectFifoStatefulTransformPass
void createBd(OpBuilder &builder, LockOp acqLock, int acqMode,
LockAction acqLockAction, LockOp relLock, int relMode,
MyOp buff, int offset, int len, Block *succ,
DimTupleArrayAttr dims) {
BDDimLayoutArrayAttr dims) {
builder.create<UseLockOp>(builder.getUnknownLoc(), acqLock, acqMode,
acqLockAction);
if (!dims.getValue().empty())
Expand All @@ -440,7 +440,7 @@ struct AIEObjectFifoStatefulTransformPass
void createBdBlock(OpBuilder &builder, ObjectFifoCreateOp op, int lockMode,
int acqNum, int relNum, MyOp buff, int offset, int len,
DMAChannelDir channelDir, size_t blockIndex, Block *succ,
DimTupleArrayAttr dims) {
BDDimLayoutArrayAttr dims) {
LockOp acqLock;
LockOp relLock;
int acqMode = 1;
Expand Down Expand Up @@ -470,7 +470,7 @@ struct AIEObjectFifoStatefulTransformPass
/// createMemTileDMA() based on op tile row value.
void createDMA(DeviceOp &device, OpBuilder &builder, ObjectFifoCreateOp op,
DMAChannelDir channelDir, int channelIndex, int lockMode,
DimTupleArrayAttr dims) {
BDDimLayoutArrayAttr dims) {
if (op.getProducerTileOp().isShimTile()) {
createShimDMA(device, builder, op, channelDir, channelIndex, lockMode,
dims);
Expand All @@ -488,7 +488,7 @@ struct AIEObjectFifoStatefulTransformPass
void createAIETileDMA(DeviceOp &device, OpBuilder &builder,
ObjectFifoCreateOp op, DMAChannelDir channelDir,
int channelIndex, int lockMode,
DimTupleArrayAttr dims) {
BDDimLayoutArrayAttr dims) {
size_t numBlocks = op.size();
if (numBlocks == 0)
return;
Expand Down Expand Up @@ -570,7 +570,8 @@ struct AIEObjectFifoStatefulTransformPass
/// It uses creatBdBlock(), see there for lockMode input.
void createShimDMA(DeviceOp &device, OpBuilder &builder,
ObjectFifoCreateOp op, DMAChannelDir channelDir,
int channelIndex, int lockMode, DimTupleArrayAttr dims) {
int channelIndex, int lockMode,
BDDimLayoutArrayAttr dims) {
size_t numBlocks = externalBuffersPerFifo[op].size();
if (numBlocks == 0)
return;
Expand Down Expand Up @@ -646,7 +647,7 @@ struct AIEObjectFifoStatefulTransformPass
void createMemTileDMA(DeviceOp &device, OpBuilder &builder,
ObjectFifoCreateOp op, DMAChannelDir channelDir,
int channelIndex, int lockMode,
DimTupleArrayAttr dims) {
BDDimLayoutArrayAttr dims) {
size_t numBlocks = op.size();
if (numBlocks == 0)
return;
Expand Down Expand Up @@ -1191,7 +1192,7 @@ struct AIEObjectFifoStatefulTransformPass
std::vector<ObjectFifoCreateOp> splitConsumerFifos;
int consumerIndex = 0;
int consumerDepth = createOp.size();
ArrayRef<DimTupleArrayAttr> consumerDims =
ArrayRef<BDDimLayoutArrayAttr> consumerDims =
createOp.getDimensionsFromStreamPerConsumer();

// Only FIFOs using DMA are split into two ends;
Expand Down Expand Up @@ -1221,13 +1222,15 @@ struct AIEObjectFifoStatefulTransformPass
} else {
consumerFifoName = createOp.name().str() + "_cons";
}
DimTupleArrayAttr emptyDims =
DimTupleArrayAttr::get(builder.getContext(), {});
DimTupleArrayAttr singletonFromStreamDims = DimTupleArrayAttr::get(
builder.getContext(),
ArrayRef<DimTupleAttr>{consumerDims[consumerIndex]});
DimTupleArrayArrayAttr fromStreamDims = DimTupleArrayArrayAttr::get(
builder.getContext(), singletonFromStreamDims);
BDDimLayoutArrayAttr emptyDims =
BDDimLayoutArrayAttr::get(builder.getContext(), {});
BDDimLayoutArrayAttr singletonFromStreamDims =
BDDimLayoutArrayAttr::get(
builder.getContext(),
ArrayRef<BDDimLayoutAttr>{consumerDims[consumerIndex]});
BDDimLayoutArrayArrayAttr fromStreamDims =
BDDimLayoutArrayArrayAttr::get(builder.getContext(),
singletonFromStreamDims);

ObjectFifoCreateOp consumerFifo = createObjectFifo(
builder, datatype, consumerFifoName, consumerTile, consumerTile,
Expand Down Expand Up @@ -1323,7 +1326,7 @@ struct AIEObjectFifoStatefulTransformPass
// create consumer tile DMA
DMAChannel consumerChan =
dmaAnalysis.getSlaveDMAChannel(consumer.getProducerTile());
DimTupleArrayAttr consumerDims =
BDDimLayoutArrayAttr consumerDims =
consumer.getDimensionsFromStreamPerConsumer()[0];
createDMA(device, builder, consumer, consumerChan.direction,
consumerChan.channel, 1, consumerDims);
Expand Down
Loading

0 comments on commit 7d012f7

Please sign in to comment.