Skip to content

Commit

Permalink
implement getAsmResultNames
Browse files Browse the repository at this point in the history
  • Loading branch information
makslevental committed Nov 7, 2023
1 parent 5a4c101 commit 9892666
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 16 deletions.
48 changes: 35 additions & 13 deletions include/aie/Dialect/AIE/IR/AIE.td
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,10 @@ def AIE_DeviceOp: AIE_Op<"device", [
let hasVerifier = 1;
}

def AIE_TileOp: AIE_Op<"tile", [FlowEndPoint]>, Results<(outs Index:$result)> {
def AIE_TileOp: AIE_Op<"tile", [
FlowEndPoint,
DeclareOpInterfaceMethods<OpAsmOpInterface, ["getAsmResultNames"]>,
]>, Results<(outs Index:$result)> {
let arguments = (
ins ConfinedAttr<I32Attr, [IntMinValue<0>]>:$col,
ConfinedAttr<I32Attr, [IntMinValue<0>]>:$row
Expand Down Expand Up @@ -173,6 +176,17 @@ def AIE_TileOp: AIE_Op<"tile", [FlowEndPoint]>, Results<(outs Index:$result)> {
$_builder.getI32IntegerAttr(row));
}]>
];

let extraClassDefinition = [{
void $cppClass::getAsmResultNames(
function_ref<void(::mlir::Value, ::llvm::StringRef)> setNameFn) {
std::string nameWithoutDialect =
getOperationName().str().substr(getOperationName().find('.') + 1);
setNameFn(getResult(), nameWithoutDialect + "_" +
std::to_string(getCol()) + "_" +
std::to_string(getRow()));
}
}];
}

def AIE_EndOp: AIE_Op<"end", [Terminator]> {
Expand Down Expand Up @@ -213,6 +227,7 @@ def AIE_SwitchboxOp: AIE_Op<"switchbox", [
int colIndex();
int rowIndex();
TileOp getTileOp();
using ::xilinx::AIE::TileElement::Trait<SwitchboxOp>::getAsmResultNames;
}];

let builders = [
Expand Down Expand Up @@ -280,6 +295,7 @@ def AIE_ShimMuxOp: AIE_Op<"shimmux", [
int getNumSourceConnections(WireBundle bundle);
int getNumDestConnections(WireBundle bundle);
TileOp getTileOp();
using ::xilinx::AIE::TileElement::Trait<ShimMuxOp>::getAsmResultNames;
}];

let builders = [
Expand Down Expand Up @@ -327,7 +343,7 @@ def AIE_ShimDMAOp: AIE_Op<"shimDMA", [
int colIndex();
int rowIndex();
TileOp getTileOp();
static llvm::StringRef getDefaultDialect() { return "AIE"; }
using ::xilinx::AIE::TileElement::Trait<ShimDMAOp>::getAsmResultNames;
}];
}

Expand Down Expand Up @@ -378,6 +394,7 @@ def AIE_CoreOp: AIE_Op<"core", [
int rowIndex();
bool isMemWest() { return ((rowIndex() % 2) == 0); };
TileOp getTileOp();
using ::xilinx::AIE::TileElement::Trait<CoreOp>::getAsmResultNames;
}];

let builders = [
Expand Down Expand Up @@ -751,7 +768,7 @@ def AIE_DMABDPACKETOp: AIE_Op<"dmaBdPacket", []> {
let description = [{
This operation enables packet headers for a block descriptor for DMA operations. In particular, it specifies
the packet type (3-bits) and packet ID (5-bits).

This operation must be used in an MLIR block that lives inside a MemOp's region, and before AIE.dmaBd.
The block descriptor specifies what lock to use and the buffer configuration.

Expand All @@ -765,6 +782,7 @@ def AIE_DMABDPACKETOp: AIE_Op<"dmaBdPacket", []> {
AIE.useLock(%lck, "Release", 1)
br ^bd6 // point to the next Block, which is also a different Block Descriptor
```

}];

let arguments = (
Expand Down Expand Up @@ -802,7 +820,7 @@ def AIE_DMABDOp: AIE_Op<"dmaBd", []> {
let description = [{
This operation describes a block descriptor for DMA operations. In particular, it specifies
what buffer addresss to use, the transfer length, and the buffer type (A or B).

This operation must be used in an MLIR block that lives inside a MemOp's region.
The block descriptor specifies what lock to use and the buffer configuration.

Expand Down Expand Up @@ -836,7 +854,7 @@ def AIE_DMABDOp: AIE_Op<"dmaBd", []> {
wrap, the last element of the array gives the lowest-dimension.

Strides are always expressed in units of `i32`s; this is an architectural
requirement, as data is moved by the DMA at this fundamental size.
requirement, as data is moved by the DMA at this fundamental size.

We can model the access pattern strides and wraps generate by a series of
nested loops. In general, a set of strides and wraps like this...
Expand All @@ -852,14 +870,14 @@ def AIE_DMABDOp: AIE_Op<"dmaBd", []> {
for(int i = 0; i < wrap_2; i++)
for(int j = 0; j < wrap_1; j++)
for(int k = 0; k < wrap_0; k++)
// access/store element at/to buffer[ i * stride_2
// + j * stride_1
// access/store element at/to buffer[ i * stride_2
// + j * stride_1
// + k * stride_0]
```

The following example shows an access pattern that corresponds to
alternating between even and odd elements of the buffer/stream every 8
elements:
The following example shows an access pattern that corresponds to
alternating between even and odd elements of the buffer/stream every 8
elements:

```
AIE.dmaBd(<%buf : memref<128xi32>, 0, 128>, 0, [<8, 16>, <2, 1>, <8, 2>])
Expand Down Expand Up @@ -950,7 +968,7 @@ def AIE_DMAStartOp: AIE_Op<"dmaStart", [
];
}

// MemOps are not actually Callable, but we want to inline code into them, so we have to
// MemOps are not actually Callable, but we want to inline code into them, so we have to
// implement CallableOpInterface
def AIE_MemOp: AIE_Op<"mem", [
TileElement, FlowEndPoint, CallableOpInterface,
Expand Down Expand Up @@ -992,7 +1010,7 @@ def AIE_MemOp: AIE_Op<"mem", [
mlir::Region *getCallableRegion();
llvm::ArrayRef<mlir::Type> getArgumentTypes() { return getOperand().getType(); }
llvm::ArrayRef<mlir::Type> getResultTypes() { return getType(); }
static llvm::StringRef getDefaultDialect() { return "AIE"; }
using ::xilinx::AIE::TileElement::Trait<MemOp>::getAsmResultNames;
}];

let builders = [
Expand Down Expand Up @@ -1047,7 +1065,7 @@ def AIE_MemTileDMAOp: AIE_Op<"memTileDMA", [
mlir::Region *getCallableRegion();
llvm::ArrayRef<mlir::Type> getArgumentTypes() { return getOperand().getType(); }
llvm::ArrayRef<mlir::Type> getResultTypes() { return getType(); }
static llvm::StringRef getDefaultDialect() { return "AIE"; }
using ::xilinx::AIE::TileElement::Trait<MemTileDMAOp>::getAsmResultNames;
}];

let builders = [
Expand Down Expand Up @@ -1132,6 +1150,7 @@ def AIE_LockOp: AIE_Op<"lock", [TileElement]>, Results<(outs Index)> {
int colIndex();
int rowIndex();
TileOp getTileOp();
using ::xilinx::AIE::TileElement::Trait<LockOp>::getAsmResultNames;
}];

let builders = [
Expand Down Expand Up @@ -1229,6 +1248,7 @@ def AIE_BufferOp: AIE_Op<"buffer", [
// Return the number of bytes that need to be allocated for this buffer.
int64_t getAllocationSize();
TileOp getTileOp();
using ::xilinx::AIE::TileElement::Trait<BufferOp>::getAsmResultNames;
}];
}

Expand Down Expand Up @@ -1603,6 +1623,8 @@ def AIE_ObjectFifoRegisterExternalBuffersOp: AIE_Op<"objectFifo.registerExternal
let extraClassDeclaration = [{
TileOp getTileOp();
ObjectFifoCreateOp getObjectFifo();
// No results so just use default impl.
using ::mlir::OpAsmOpInterface::Trait<ObjectFifoRegisterExternalBuffersOp>::getAsmResultNames;
}];
}

Expand Down
19 changes: 17 additions & 2 deletions include/aie/Dialect/AIE/IR/AIEInterfaces.td
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

include "mlir/IR/OpBase.td"
include "mlir/IR/EnumAttr.td"
include "mlir/IR/OpAsmInterface.td"

// Op is a DMA-like operation with BD contraints
def HasValidBDs : NativeOpTrait<"HasValidBDs"> {
Expand Down Expand Up @@ -83,7 +84,10 @@ def Interconnect : OpInterface<"Interconnect"> {
];
}

def TileElement : OpInterface<"TileElement"> {

def TileElement : OpInterface<"TileElement", [
DeclareOpInterfaceMethods<OpAsmOpInterface>,
]> {
let description = [{
Interface for operations that exist in a TileOp.
}];
Expand All @@ -98,8 +102,19 @@ def TileElement : OpInterface<"TileElement"> {
ConcreteOp op = llvm::cast<ConcreteOp>(this->getOperation());
return op.getTileOp().getTileID();
}]
>
>,
];
let extraTraitClassDeclaration = [{
void getAsmResultNames(
llvm::function_ref<void(mlir::Value, llvm::StringRef)> setNameFn) {
ConcreteOp op = llvm::cast<ConcreteOp>(this->getOperation());
std::string nameWithoutDialect =
op.getOperationName().str().substr(op.getOperationName().find('.') + 1);
setNameFn(op.getResult(), nameWithoutDialect + "_" +
std::to_string(this->getTileID().first) + "_" +
std::to_string(this->getTileID().second));
}
}];
}

def AIETarget : OpInterface<"AIETarget"> {
Expand Down
57 changes: 56 additions & 1 deletion test/find-flows/shim.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,67 @@
//
//===----------------------------------------------------------------------===//

// RUN: aie-opt --aie-find-flows %s | FileCheck %s
// RUN: aie-opt --aie-find-flows -split-input-file %s | FileCheck %s

// CHECK: %[[VAL_0:.*]] = AIE.tile(2, 1)
// CHECK: %[[VAL_1:.*]] = AIE.tile(2, 0)
// CHECK: %[[VAL_6:.*]] = AIE.shimDMA(%[[VAL_1]])
// CHECK: AIE.flow(%[[VAL_0]], Core : 0, %[[VAL_6]], DMA : 0)
module {
AIE.device(xcvc1902) {
%t21 = AIE.tile(2, 1)
%t20 = AIE.tile(2, 0)
%c21 = AIE.core(%t21) {
AIE.end
}
%s21 = AIE.switchbox(%t21) {
AIE.connect<Core : 0, South : 0>
}
%s20 = AIE.switchbox(%t20) {
AIE.connect<North : 0, South : 2>
}
%mux = AIE.shimmux(%t20) {
AIE.connect<North : 2, DMA : 0>
}
%dma = AIE.shimDMA(%t20) {
AIE.end
}
AIE.wire(%s21 : South, %s20 : North)
AIE.wire(%s20 : South, %mux : North)
AIE.wire(%mux : DMA, %dma : DMA)
AIE.wire(%mux : South, %t20 : DMA)
AIE.wire(%s21 : Core, %c21 : Core)
AIE.wire(%s21 : Core, %t21 : Core)
}
}

// -----

// CHECK: %tile_2_1 = AIE.tile(2, 1)
// CHECK: %tile_2_0 = AIE.tile(2, 0)
// CHECK: %core_2_1 = AIE.core(%tile_2_1) {
// CHECK: AIE.end
// CHECK: }
// CHECK: %switchbox_2_1 = AIE.switchbox(%tile_2_1) {
// CHECK: AIE.connect<Core : 0, South : 0>
// CHECK: }
// CHECK: %switchbox_2_0 = AIE.switchbox(%tile_2_0) {
// CHECK: AIE.connect<North : 0, South : 2>
// CHECK: }
// CHECK: %shimmux_2_0 = AIE.shimmux(%tile_2_0) {
// CHECK: AIE.connect<North : 2, DMA : 0>
// CHECK: }
// CHECK: %shimDMA_2_0 = AIE.shimDMA(%tile_2_0) {
// CHECK: AIE.end
// CHECK: }
// CHECK: AIE.wire(%switchbox_2_1 : South, %switchbox_2_0 : North)
// CHECK: AIE.wire(%switchbox_2_0 : South, %shimmux_2_0 : North)
// CHECK: AIE.wire(%shimmux_2_0 : DMA, %shimDMA_2_0 : DMA)
// CHECK: AIE.wire(%shimmux_2_0 : South, %tile_2_0 : DMA)
// CHECK: AIE.wire(%switchbox_2_1 : Core, %core_2_1 : Core)
// CHECK: AIE.wire(%switchbox_2_1 : Core, %tile_2_1 : Core)
// CHECK: AIE.flow(%tile_2_1, Core : 0, %shimDMA_2_0, DMA : 0)

module {
AIE.device(xcvc1902) {
%t21 = AIE.tile(2, 1)
Expand Down

0 comments on commit 9892666

Please sign in to comment.